2 * Kernel synchronization objects
4 * Copyright 1998 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define WIN32_NO_STATUS
27 #define NONAMELESSUNION
37 #include "kernelbase.h"
39 #include "wine/exception.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(sync
);
44 static const struct _KUSER_SHARED_DATA
*user_shared_data
= (struct _KUSER_SHARED_DATA
*)0x7ffe0000;
46 /* check if current version is NT or Win95 */
47 static inline BOOL
is_version_nt(void)
49 return !(GetVersion() & 0x80000000);
52 /* helper for kernel32->ntdll timeout format conversion */
53 static inline LARGE_INTEGER
*get_nt_timeout( LARGE_INTEGER
*time
, DWORD timeout
)
55 if (timeout
== INFINITE
) return NULL
;
56 time
->QuadPart
= (ULONGLONG
)timeout
* -10000;
61 /***********************************************************************
62 * BaseGetNamedObjectDirectory (kernelbase.@)
64 NTSTATUS WINAPI
BaseGetNamedObjectDirectory( HANDLE
*dir
)
69 OBJECT_ATTRIBUTES attr
;
70 NTSTATUS status
= STATUS_SUCCESS
;
76 swprintf( buffer
, ARRAY_SIZE(buffer
), L
"\\Sessions\\%u\\BaseNamedObjects",
77 NtCurrentTeb()->Peb
->SessionId
);
78 RtlInitUnicodeString( &str
, buffer
);
79 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
80 status
= NtOpenDirectoryObject( &dir
, DIRECTORY_CREATE_OBJECT
|DIRECTORY_TRAVERSE
, &attr
);
81 if (!status
&& InterlockedCompareExchangePointer( &handle
, dir
, 0 ) != 0)
83 /* someone beat us here... */
91 static void get_create_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
92 SECURITY_ATTRIBUTES
*sa
, const WCHAR
*name
)
94 attr
->Length
= sizeof(*attr
);
95 attr
->RootDirectory
= 0;
96 attr
->ObjectName
= NULL
;
97 attr
->Attributes
= OBJ_OPENIF
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
98 attr
->SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
99 attr
->SecurityQualityOfService
= NULL
;
102 RtlInitUnicodeString( nameW
, name
);
103 attr
->ObjectName
= nameW
;
104 BaseGetNamedObjectDirectory( &attr
->RootDirectory
);
108 static BOOL
get_open_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
109 BOOL inherit
, const WCHAR
*name
)
115 SetLastError( ERROR_INVALID_PARAMETER
);
118 RtlInitUnicodeString( nameW
, name
);
119 BaseGetNamedObjectDirectory( &dir
);
120 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
125 /***********************************************************************
127 ***********************************************************************/
130 /*********************************************************************
131 * GetSystemTimes (kernelbase.@)
133 BOOL WINAPI DECLSPEC_HOTPATCH
GetSystemTimes( FILETIME
*idle
, FILETIME
*kernel
, FILETIME
*user
)
135 LARGE_INTEGER idle_time
, kernel_time
, user_time
;
136 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
*info
;
138 DWORD i
, cpus
= NtCurrentTeb()->Peb
->NumberOfProcessors
;
140 if (!(info
= HeapAlloc( GetProcessHeap(), 0, sizeof(*info
) * cpus
)))
142 SetLastError( ERROR_OUTOFMEMORY
);
145 if (!set_ntstatus( NtQuerySystemInformation( SystemProcessorPerformanceInformation
, info
,
146 sizeof(*info
) * cpus
, &ret_size
)))
148 HeapFree( GetProcessHeap(), 0, info
);
151 idle_time
.QuadPart
= 0;
152 kernel_time
.QuadPart
= 0;
153 user_time
.QuadPart
= 0;
154 for (i
= 0; i
< cpus
; i
++)
156 idle_time
.QuadPart
+= info
[i
].IdleTime
.QuadPart
;
157 kernel_time
.QuadPart
+= info
[i
].KernelTime
.QuadPart
;
158 user_time
.QuadPart
+= info
[i
].UserTime
.QuadPart
;
162 idle
->dwLowDateTime
= idle_time
.u
.LowPart
;
163 idle
->dwHighDateTime
= idle_time
.u
.HighPart
;
167 kernel
->dwLowDateTime
= kernel_time
.u
.LowPart
;
168 kernel
->dwHighDateTime
= kernel_time
.u
.HighPart
;
172 user
->dwLowDateTime
= user_time
.u
.LowPart
;
173 user
->dwHighDateTime
= user_time
.u
.HighPart
;
175 HeapFree( GetProcessHeap(), 0, info
);
180 /******************************************************************************
181 * GetTickCount (kernelbase.@)
183 ULONG WINAPI DECLSPEC_HOTPATCH
GetTickCount(void)
185 /* note: we ignore TickCountMultiplier */
186 return user_shared_data
->u
.TickCount
.LowPart
;
190 /******************************************************************************
191 * GetTickCount64 (kernelbase.@)
193 ULONGLONG WINAPI DECLSPEC_HOTPATCH
GetTickCount64(void)
199 high
= user_shared_data
->u
.TickCount
.High1Time
;
200 low
= user_shared_data
->u
.TickCount
.LowPart
;
202 while (high
!= user_shared_data
->u
.TickCount
.High2Time
);
203 /* note: we ignore TickCountMultiplier */
204 return (ULONGLONG
)high
<< 32 | low
;
208 /***********************************************************************
210 ***********************************************************************/
213 static HANDLE
normalize_std_handle( HANDLE handle
)
215 if ((handle
== (HANDLE
)STD_INPUT_HANDLE
) ||
216 (handle
== (HANDLE
)STD_OUTPUT_HANDLE
) ||
217 (handle
== (HANDLE
)STD_ERROR_HANDLE
))
218 return GetStdHandle( HandleToULong(handle
) );
224 /***********************************************************************
225 * RegisterWaitForSingleObjectEx (kernelbase.@)
227 HANDLE WINAPI DECLSPEC_HOTPATCH
RegisterWaitForSingleObjectEx( HANDLE handle
, WAITORTIMERCALLBACK callback
,
228 PVOID context
, ULONG timeout
, ULONG flags
)
232 TRACE( "%p %p %p %ld %ld\n", handle
, callback
, context
, timeout
, flags
);
234 handle
= normalize_std_handle( handle
);
235 if (!set_ntstatus( RtlRegisterWait( &ret
, handle
, callback
, context
, timeout
, flags
))) return NULL
;
240 /***********************************************************************
241 * SignalObjectAndWait (kernelbase.@)
243 DWORD WINAPI DECLSPEC_HOTPATCH
SignalObjectAndWait( HANDLE signal
, HANDLE wait
,
244 DWORD timeout
, BOOL alertable
)
249 TRACE( "%p %p %ld %d\n", signal
, wait
, timeout
, alertable
);
251 status
= NtSignalAndWaitForSingleObject( signal
, wait
, alertable
, get_nt_timeout( &time
, timeout
) );
254 SetLastError( RtlNtStatusToDosError(status
) );
255 status
= WAIT_FAILED
;
261 /***********************************************************************
262 * Sleep (kernelbase.@)
264 void WINAPI DECLSPEC_HOTPATCH
Sleep( DWORD timeout
)
268 NtDelayExecution( FALSE
, get_nt_timeout( &time
, timeout
) );
272 /******************************************************************************
273 * SleepEx (kernelbase.@)
275 DWORD WINAPI DECLSPEC_HOTPATCH
SleepEx( DWORD timeout
, BOOL alertable
)
280 status
= NtDelayExecution( alertable
, get_nt_timeout( &time
, timeout
) );
281 if (status
== STATUS_USER_APC
) return WAIT_IO_COMPLETION
;
286 /***********************************************************************
287 * UnregisterWaitEx (kernelbase.@)
289 BOOL WINAPI DECLSPEC_HOTPATCH
UnregisterWaitEx( HANDLE handle
, HANDLE event
)
291 return set_ntstatus( RtlDeregisterWaitEx( handle
, event
));
295 /***********************************************************************
296 * WaitForSingleObject (kernelbase.@)
298 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
300 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
304 /***********************************************************************
305 * WaitForSingleObjectEx (kernelbase.@)
307 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
, BOOL alertable
)
309 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
313 /***********************************************************************
314 * WaitForMultipleObjects (kernelbase.@)
316 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
317 BOOL wait_all
, DWORD timeout
)
319 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
323 /***********************************************************************
324 * WaitForMultipleObjectsEx (kernelbase.@)
326 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
327 BOOL wait_all
, DWORD timeout
, BOOL alertable
)
330 HANDLE hloc
[MAXIMUM_WAIT_OBJECTS
];
334 if (count
> MAXIMUM_WAIT_OBJECTS
)
336 SetLastError(ERROR_INVALID_PARAMETER
);
339 for (i
= 0; i
< count
; i
++) hloc
[i
] = normalize_std_handle( handles
[i
] );
341 status
= NtWaitForMultipleObjects( count
, hloc
, !wait_all
, alertable
,
342 get_nt_timeout( &time
, timeout
) );
343 if (HIWORD(status
)) /* is it an error code? */
345 SetLastError( RtlNtStatusToDosError(status
) );
346 status
= WAIT_FAILED
;
352 /******************************************************************************
353 * WaitForDebugEvent (kernelbase.@)
355 BOOL WINAPI DECLSPEC_HOTPATCH
WaitForDebugEvent( DEBUG_EVENT
*event
, DWORD timeout
)
359 DBGUI_WAIT_STATE_CHANGE state
;
363 status
= DbgUiWaitStateChange( &state
, get_nt_timeout( &time
, timeout
) );
367 DbgUiConvertStateChangeStructure( &state
, event
);
369 case STATUS_USER_APC
:
372 SetLastError( ERROR_SEM_TIMEOUT
);
375 return set_ntstatus( status
);
381 /***********************************************************************
382 * WaitOnAddress (kernelbase.@)
384 BOOL WINAPI DECLSPEC_HOTPATCH
WaitOnAddress( volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
388 if (timeout
!= INFINITE
)
390 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
391 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, &to
));
393 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, NULL
));
397 /***********************************************************************
399 ***********************************************************************/
402 /***********************************************************************
403 * CreateEventA (kernelbase.@)
405 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
406 BOOL initial_state
, LPCSTR name
)
410 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
411 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
412 return CreateEventExA( sa
, name
, flags
, EVENT_ALL_ACCESS
);
416 /***********************************************************************
417 * CreateEventW (kernelbase.@)
419 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventW( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
420 BOOL initial_state
, LPCWSTR name
)
424 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
425 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
426 return CreateEventExW( sa
, name
, flags
, EVENT_ALL_ACCESS
);
430 /***********************************************************************
431 * CreateEventExA (kernelbase.@)
433 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
434 DWORD flags
, DWORD access
)
436 WCHAR buffer
[MAX_PATH
];
438 if (!name
) return CreateEventExW( sa
, NULL
, flags
, access
);
440 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
442 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
445 return CreateEventExW( sa
, buffer
, flags
, access
);
449 /***********************************************************************
450 * CreateEventExW (kernelbase.@)
452 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
453 DWORD flags
, DWORD access
)
456 UNICODE_STRING nameW
;
457 OBJECT_ATTRIBUTES attr
;
460 /* one buggy program needs this
461 * ("Van Dale Groot woordenboek der Nederlandse taal")
465 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
469 SetLastError( ERROR_INVALID_PARAMETER
);
474 status
= NtCreateEvent( &ret
, access
, &attr
,
475 (flags
& CREATE_EVENT_MANUAL_RESET
) ? NotificationEvent
: SynchronizationEvent
,
476 (flags
& CREATE_EVENT_INITIAL_SET
) != 0 );
477 if (status
== STATUS_OBJECT_NAME_EXISTS
)
478 SetLastError( ERROR_ALREADY_EXISTS
);
480 SetLastError( RtlNtStatusToDosError(status
) );
485 /***********************************************************************
486 * OpenEventA (kernelbase.@)
488 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventA( DWORD access
, BOOL inherit
, LPCSTR name
)
490 WCHAR buffer
[MAX_PATH
];
492 if (!name
) return OpenEventW( access
, inherit
, NULL
);
494 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
496 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
499 return OpenEventW( access
, inherit
, buffer
);
503 /***********************************************************************
504 * OpenEventW (kernelbase.@)
506 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
509 UNICODE_STRING nameW
;
510 OBJECT_ATTRIBUTES attr
;
512 if (!is_version_nt()) access
= EVENT_ALL_ACCESS
;
514 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
516 if (!set_ntstatus( NtOpenEvent( &ret
, access
, &attr
))) return 0;
520 /***********************************************************************
521 * PulseEvent (kernelbase.@)
523 BOOL WINAPI DECLSPEC_HOTPATCH
PulseEvent( HANDLE handle
)
525 return set_ntstatus( NtPulseEvent( handle
, NULL
));
529 /***********************************************************************
530 * SetEvent (kernelbase.@)
532 BOOL WINAPI DECLSPEC_HOTPATCH
SetEvent( HANDLE handle
)
534 return set_ntstatus( NtSetEvent( handle
, NULL
));
538 /***********************************************************************
539 * ResetEvent (kernelbase.@)
541 BOOL WINAPI DECLSPEC_HOTPATCH
ResetEvent( HANDLE handle
)
543 return set_ntstatus( NtResetEvent( handle
, NULL
));
547 /***********************************************************************
549 ***********************************************************************/
552 /***********************************************************************
553 * CreateMutexA (kernelbase.@)
555 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexA( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCSTR name
)
557 return CreateMutexExA( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
561 /***********************************************************************
562 * CreateMutexW (kernelbase.@)
564 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexW( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCWSTR name
)
566 return CreateMutexExW( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
570 /***********************************************************************
571 * CreateMutexExA (kernelbase.@)
573 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
574 DWORD flags
, DWORD access
)
579 if (!name
) return CreateMutexExW( sa
, NULL
, flags
, access
);
581 RtlInitAnsiString( &nameA
, name
);
582 status
= RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString
, &nameA
, FALSE
);
583 if (status
!= STATUS_SUCCESS
)
585 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
588 return CreateMutexExW( sa
, NtCurrentTeb()->StaticUnicodeString
.Buffer
, flags
, access
);
592 /***********************************************************************
593 * CreateMutexExW (kernelbase.@)
595 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
596 DWORD flags
, DWORD access
)
599 UNICODE_STRING nameW
;
600 OBJECT_ATTRIBUTES attr
;
603 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
605 status
= NtCreateMutant( &ret
, access
, &attr
, (flags
& CREATE_MUTEX_INITIAL_OWNER
) != 0 );
606 if (status
== STATUS_OBJECT_NAME_EXISTS
)
607 SetLastError( ERROR_ALREADY_EXISTS
);
609 SetLastError( RtlNtStatusToDosError(status
) );
614 /***********************************************************************
615 * OpenMutexW (kernelbase.@)
617 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
620 UNICODE_STRING nameW
;
621 OBJECT_ATTRIBUTES attr
;
623 if (!is_version_nt()) access
= MUTEX_ALL_ACCESS
;
625 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
627 if (!set_ntstatus( NtOpenMutant( &ret
, access
, &attr
))) return 0;
632 /***********************************************************************
633 * ReleaseMutex (kernelbase.@)
635 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseMutex( HANDLE handle
)
637 return set_ntstatus( NtReleaseMutant( handle
, NULL
));
641 /***********************************************************************
643 ***********************************************************************/
646 /***********************************************************************
647 * CreateSemaphoreW (kernelbase.@)
649 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreW( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
650 LONG max
, LPCWSTR name
)
652 return CreateSemaphoreExW( sa
, initial
, max
, name
, 0, SEMAPHORE_ALL_ACCESS
);
656 /***********************************************************************
657 * CreateSemaphoreExW (kernelbase.@)
659 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreExW( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
,
660 LPCWSTR name
, DWORD flags
, DWORD access
)
663 UNICODE_STRING nameW
;
664 OBJECT_ATTRIBUTES attr
;
667 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
669 status
= NtCreateSemaphore( &ret
, access
, &attr
, initial
, max
);
670 if (status
== STATUS_OBJECT_NAME_EXISTS
)
671 SetLastError( ERROR_ALREADY_EXISTS
);
673 SetLastError( RtlNtStatusToDosError(status
) );
678 /***********************************************************************
679 * OpenSemaphoreW (kernelbase.@)
681 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
684 UNICODE_STRING nameW
;
685 OBJECT_ATTRIBUTES attr
;
687 if (!is_version_nt()) access
= SEMAPHORE_ALL_ACCESS
;
689 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
691 if (!set_ntstatus( NtOpenSemaphore( &ret
, access
, &attr
))) return 0;
696 /***********************************************************************
697 * ReleaseSemaphore (kernelbase.@)
699 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseSemaphore( HANDLE handle
, LONG count
, LONG
*previous
)
701 return set_ntstatus( NtReleaseSemaphore( handle
, count
, (PULONG
)previous
));
705 /***********************************************************************
707 ***********************************************************************/
710 /***********************************************************************
711 * CreateWaitableTimerW (kernelbase.@)
713 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerW( SECURITY_ATTRIBUTES
*sa
, BOOL manual
, LPCWSTR name
)
715 return CreateWaitableTimerExW( sa
, name
, manual
? CREATE_WAITABLE_TIMER_MANUAL_RESET
: 0,
720 /***********************************************************************
721 * CreateWaitableTimerExW (kernelbase.@)
723 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
724 DWORD flags
, DWORD access
)
728 UNICODE_STRING nameW
;
729 OBJECT_ATTRIBUTES attr
;
731 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
733 status
= NtCreateTimer( &handle
, access
, &attr
,
734 (flags
& CREATE_WAITABLE_TIMER_MANUAL_RESET
) ? NotificationTimer
: SynchronizationTimer
);
735 if (status
== STATUS_OBJECT_NAME_EXISTS
)
736 SetLastError( ERROR_ALREADY_EXISTS
);
738 SetLastError( RtlNtStatusToDosError(status
) );
743 /***********************************************************************
744 * OpenWaitableTimerW (kernelbase.@)
746 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenWaitableTimerW( DWORD access
, BOOL inherit
, LPCWSTR name
)
749 UNICODE_STRING nameW
;
750 OBJECT_ATTRIBUTES attr
;
752 if (!is_version_nt()) access
= TIMER_ALL_ACCESS
;
754 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
756 if (!set_ntstatus( NtOpenTimer( &handle
, access
, &attr
))) return 0;
761 /***********************************************************************
762 * SetWaitableTimer (kernelbase.@)
764 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimer( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
765 PTIMERAPCROUTINE callback
, LPVOID arg
, BOOL resume
)
767 NTSTATUS status
= NtSetTimer( handle
, when
, (PTIMER_APC_ROUTINE
)callback
,
768 arg
, resume
, period
, NULL
);
769 return set_ntstatus( status
) || status
== STATUS_TIMER_RESUME_IGNORED
;
773 /***********************************************************************
774 * SetWaitableTimerEx (kernelbase.@)
776 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimerEx( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
777 PTIMERAPCROUTINE callback
, LPVOID arg
,
778 REASON_CONTEXT
*context
, ULONG tolerabledelay
)
781 if (!once
++) FIXME( "(%p, %p, %ld, %p, %p, %p, %ld) semi-stub\n",
782 handle
, when
, period
, callback
, arg
, context
, tolerabledelay
);
784 return SetWaitableTimer( handle
, when
, period
, callback
, arg
, FALSE
);
788 /***********************************************************************
789 * CancelWaitableTimer (kernelbase.@)
791 BOOL WINAPI DECLSPEC_HOTPATCH
CancelWaitableTimer( HANDLE handle
)
793 return set_ntstatus( NtCancelTimer( handle
, NULL
));
797 /***********************************************************************
799 ***********************************************************************/
802 /***********************************************************************
803 * CreateTimerQueue (kernelbase.@)
805 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateTimerQueue(void)
809 if (!set_ntstatus( RtlCreateTimerQueue( &q
))) return NULL
;
814 /***********************************************************************
815 * CreateTimerQueueTimer (kernelbase.@)
817 BOOL WINAPI DECLSPEC_HOTPATCH
CreateTimerQueueTimer( PHANDLE timer
, HANDLE queue
,
818 WAITORTIMERCALLBACK callback
, PVOID arg
,
819 DWORD when
, DWORD period
, ULONG flags
)
821 return set_ntstatus( RtlCreateTimer( queue
, timer
, callback
, arg
, when
, period
, flags
));
825 /***********************************************************************
826 * ChangeTimerQueueTimer (kernelbase.@)
828 BOOL WINAPI DECLSPEC_HOTPATCH
ChangeTimerQueueTimer( HANDLE queue
, HANDLE timer
,
829 ULONG when
, ULONG period
)
831 return set_ntstatus( RtlUpdateTimer( queue
, timer
, when
, period
));
835 /***********************************************************************
836 * DeleteTimerQueueEx (kernelbase.@)
838 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueEx( HANDLE queue
, HANDLE event
)
840 return set_ntstatus( RtlDeleteTimerQueueEx( queue
, event
));
844 /***********************************************************************
845 * DeleteTimerQueueTimer (kernelbase.@)
847 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueTimer( HANDLE queue
, HANDLE timer
, HANDLE event
)
849 return set_ntstatus( RtlDeleteTimer( queue
, timer
, event
));
853 /***********************************************************************
855 ***********************************************************************/
858 /***********************************************************************
859 * InitializeCriticalSectionAndSpinCount (kernelbase.@)
861 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION
*crit
, DWORD count
)
863 return !RtlInitializeCriticalSectionAndSpinCount( crit
, count
);
866 /***********************************************************************
867 * InitializeCriticalSectionEx (kernelbase.@)
869 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionEx( CRITICAL_SECTION
*crit
, DWORD spincount
,
872 NTSTATUS ret
= RtlInitializeCriticalSectionEx( crit
, spincount
, flags
);
873 if (ret
) RtlRaiseStatus( ret
);
878 /***********************************************************************
880 ***********************************************************************/
882 /***********************************************************************
883 * CreateFileMappingW (kernelbase.@)
885 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingW( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, DWORD protect
,
886 DWORD size_high
, DWORD size_low
, LPCWSTR name
)
888 static const int sec_flags
= (SEC_FILE
| SEC_IMAGE
| SEC_RESERVE
| SEC_COMMIT
|
889 SEC_NOCACHE
| SEC_WRITECOMBINE
| SEC_LARGE_PAGES
);
892 DWORD access
, sec_type
;
894 UNICODE_STRING nameW
;
895 OBJECT_ATTRIBUTES attr
;
897 sec_type
= protect
& sec_flags
;
898 protect
&= ~sec_flags
;
899 if (!sec_type
) sec_type
= SEC_COMMIT
;
901 /* Win9x compatibility */
902 if (!protect
&& !is_version_nt()) protect
= PAGE_READONLY
;
908 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
911 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
;
913 case PAGE_EXECUTE_READ
:
914 case PAGE_EXECUTE_WRITECOPY
:
915 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_EXECUTE
;
917 case PAGE_EXECUTE_READWRITE
:
918 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
;
921 SetLastError( ERROR_INVALID_PARAMETER
);
925 size
.u
.LowPart
= size_low
;
926 size
.u
.HighPart
= size_high
;
928 if (file
== INVALID_HANDLE_VALUE
)
933 SetLastError( ERROR_INVALID_PARAMETER
);
938 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
940 status
= NtCreateSection( &ret
, access
, &attr
, &size
, protect
, sec_type
, file
);
941 if (status
== STATUS_OBJECT_NAME_EXISTS
)
942 SetLastError( ERROR_ALREADY_EXISTS
);
944 SetLastError( RtlNtStatusToDosError(status
) );
949 /***********************************************************************
950 * CreateFileMappingFromApp (kernelbase.@)
952 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingFromApp( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, ULONG protect
,
953 ULONG64 size
, LPCWSTR name
)
955 return CreateFileMappingW( file
, sa
, protect
, size
<< 32, size
, name
);
958 /***********************************************************************
959 * OpenFileMappingW (kernelbase.@)
961 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingW( DWORD access
, BOOL inherit
, LPCWSTR name
)
963 OBJECT_ATTRIBUTES attr
;
964 UNICODE_STRING nameW
;
967 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
969 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
971 if (!is_version_nt())
973 /* win9x doesn't do access checks, so try with full access first */
974 if (!NtOpenSection( &ret
, access
| SECTION_MAP_READ
| SECTION_MAP_WRITE
, &attr
)) return ret
;
977 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
982 /***********************************************************************
983 * OpenFileMappingFromApp (kernelbase.@)
985 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingFromApp( ULONG access
, BOOL inherit
, LPCWSTR name
)
987 OBJECT_ATTRIBUTES attr
;
988 UNICODE_STRING nameW
;
991 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
993 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
995 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
1000 /***********************************************************************
1001 * Condition variables
1002 ***********************************************************************/
1005 /***********************************************************************
1006 * SleepConditionVariableCS (kernelbase.@)
1008 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableCS( CONDITION_VARIABLE
*variable
,
1009 CRITICAL_SECTION
*crit
, DWORD timeout
)
1013 return set_ntstatus( RtlSleepConditionVariableCS( variable
, crit
, get_nt_timeout( &time
, timeout
)));
1017 /***********************************************************************
1018 * SleepConditionVariableSRW (kernelbase.@)
1020 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableSRW( RTL_CONDITION_VARIABLE
*variable
,
1021 RTL_SRWLOCK
*lock
, DWORD timeout
, ULONG flags
)
1025 return set_ntstatus( RtlSleepConditionVariableSRW( variable
, lock
,
1026 get_nt_timeout( &time
, timeout
), flags
));
1030 /***********************************************************************
1032 ***********************************************************************/
1035 /******************************************************************************
1036 * CreateIoCompletionPort (kernelbase.@)
1038 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateIoCompletionPort( HANDLE handle
, HANDLE port
,
1039 ULONG_PTR key
, DWORD threads
)
1041 FILE_COMPLETION_INFORMATION info
;
1042 IO_STATUS_BLOCK iosb
;
1045 TRACE( "(%p, %p, %08Ix, %08lx)\n", handle
, port
, key
, threads
);
1049 if (!set_ntstatus( NtCreateIoCompletion( &ret
, IO_COMPLETION_ALL_ACCESS
, NULL
, threads
)))
1052 else if (handle
== INVALID_HANDLE_VALUE
)
1054 SetLastError( ERROR_INVALID_PARAMETER
);
1058 if (handle
!= INVALID_HANDLE_VALUE
)
1060 info
.CompletionPort
= ret
;
1061 info
.CompletionKey
= key
;
1062 if (!set_ntstatus( NtSetInformationFile( handle
, &iosb
, &info
, sizeof(info
), FileCompletionInformation
)))
1064 if (!port
) CloseHandle( ret
);
1072 /******************************************************************************
1073 * GetQueuedCompletionStatus (kernelbase.@)
1075 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatus( HANDLE port
, LPDWORD count
, PULONG_PTR key
,
1076 LPOVERLAPPED
*overlapped
, DWORD timeout
)
1079 IO_STATUS_BLOCK iosb
;
1080 LARGE_INTEGER wait_time
;
1082 TRACE( "(%p,%p,%p,%p,%ld)\n", port
, count
, key
, overlapped
, timeout
);
1085 status
= NtRemoveIoCompletion( port
, key
, (PULONG_PTR
)overlapped
, &iosb
,
1086 get_nt_timeout( &wait_time
, timeout
) );
1087 if (status
== STATUS_SUCCESS
)
1089 *count
= iosb
.Information
;
1090 if (iosb
.u
.Status
>= 0) return TRUE
;
1091 SetLastError( RtlNtStatusToDosError(iosb
.u
.Status
) );
1095 if (status
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1096 else SetLastError( RtlNtStatusToDosError(status
) );
1100 /******************************************************************************
1101 * GetQueuedCompletionStatusEx (kernelbase.@)
1103 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatusEx( HANDLE port
, OVERLAPPED_ENTRY
*entries
,
1104 ULONG count
, ULONG
*written
,
1105 DWORD timeout
, BOOL alertable
)
1110 TRACE( "%p %p %lu %p %lu %u\n", port
, entries
, count
, written
, timeout
, alertable
);
1112 ret
= NtRemoveIoCompletionEx( port
, (FILE_IO_COMPLETION_INFORMATION
*)entries
, count
,
1113 written
, get_nt_timeout( &time
, timeout
), alertable
);
1114 if (ret
== STATUS_SUCCESS
) return TRUE
;
1115 else if (ret
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1116 else if (ret
== STATUS_USER_APC
) SetLastError( WAIT_IO_COMPLETION
);
1117 else SetLastError( RtlNtStatusToDosError(ret
) );
1122 /******************************************************************************
1123 * PostQueuedCompletionStatus (kernelbase.@)
1125 BOOL WINAPI DECLSPEC_HOTPATCH
PostQueuedCompletionStatus( HANDLE port
, DWORD count
,
1126 ULONG_PTR key
, LPOVERLAPPED overlapped
)
1128 TRACE( "%p %ld %08Ix %p\n", port
, count
, key
, overlapped
);
1130 return set_ntstatus( NtSetIoCompletion( port
, key
, (ULONG_PTR
)overlapped
, STATUS_SUCCESS
, count
));
1134 /***********************************************************************
1136 ***********************************************************************/
1139 /***********************************************************************
1140 * CallNamedPipeW (kernelbase.@)
1142 BOOL WINAPI DECLSPEC_HOTPATCH
CallNamedPipeW( LPCWSTR name
, LPVOID input
, DWORD in_size
,
1143 LPVOID output
, DWORD out_size
,
1144 LPDWORD read_size
, DWORD timeout
)
1150 TRACE( "%s %p %ld %p %ld %p %ld\n", debugstr_w(name
),
1151 input
, in_size
, output
, out_size
, read_size
, timeout
);
1153 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1154 if (pipe
== INVALID_HANDLE_VALUE
)
1156 if (!WaitNamedPipeW( name
, timeout
)) return FALSE
;
1157 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1158 if (pipe
== INVALID_HANDLE_VALUE
) return FALSE
;
1161 mode
= PIPE_READMODE_MESSAGE
;
1162 ret
= SetNamedPipeHandleState( pipe
, &mode
, NULL
, NULL
);
1163 if (ret
) ret
= TransactNamedPipe( pipe
, input
, in_size
, output
, out_size
, read_size
, NULL
);
1164 CloseHandle( pipe
);
1169 /***********************************************************************
1170 * ConnectNamedPipe (kernelbase.@)
1172 BOOL WINAPI DECLSPEC_HOTPATCH
ConnectNamedPipe( HANDLE pipe
, LPOVERLAPPED overlapped
)
1175 IO_STATUS_BLOCK status_block
;
1176 LPVOID cvalue
= NULL
;
1178 TRACE( "(%p,%p)\n", pipe
, overlapped
);
1182 overlapped
->Internal
= STATUS_PENDING
;
1183 overlapped
->InternalHigh
= 0;
1184 if (((ULONG_PTR
)overlapped
->hEvent
& 1) == 0) cvalue
= overlapped
;
1187 status
= NtFsControlFile( pipe
, overlapped
? overlapped
->hEvent
: NULL
, NULL
, cvalue
,
1188 overlapped
? (IO_STATUS_BLOCK
*)overlapped
: &status_block
,
1189 FSCTL_PIPE_LISTEN
, NULL
, 0, NULL
, 0 );
1190 if (status
== STATUS_PENDING
&& !overlapped
)
1192 WaitForSingleObject( pipe
, INFINITE
);
1193 status
= status_block
.u
.Status
;
1195 return set_ntstatus( status
);
1198 /***********************************************************************
1199 * CreateNamedPipeW (kernelbase.@)
1201 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateNamedPipeW( LPCWSTR name
, DWORD open_mode
, DWORD pipe_mode
,
1202 DWORD instances
, DWORD out_buff
, DWORD in_buff
,
1203 DWORD timeout
, LPSECURITY_ATTRIBUTES sa
)
1206 UNICODE_STRING nt_name
;
1207 OBJECT_ATTRIBUTES attr
;
1208 DWORD access
, options
, sharing
;
1209 BOOLEAN pipe_type
, read_mode
, non_block
;
1211 IO_STATUS_BLOCK iosb
;
1214 TRACE( "(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n", debugstr_w(name
),
1215 open_mode
, pipe_mode
, instances
, out_buff
, in_buff
, timeout
, sa
);
1217 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
))
1219 SetLastError( ERROR_PATH_NOT_FOUND
);
1220 return INVALID_HANDLE_VALUE
;
1222 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) )
1224 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
1225 RtlFreeUnicodeString( &nt_name
);
1226 return INVALID_HANDLE_VALUE
;
1229 attr
.Length
= sizeof(attr
);
1230 attr
.RootDirectory
= 0;
1231 attr
.ObjectName
= &nt_name
;
1232 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1233 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1234 attr
.SecurityQualityOfService
= NULL
;
1236 switch (open_mode
& 3)
1238 case PIPE_ACCESS_INBOUND
:
1239 sharing
= FILE_SHARE_WRITE
;
1240 access
= GENERIC_READ
;
1242 case PIPE_ACCESS_OUTBOUND
:
1243 sharing
= FILE_SHARE_READ
;
1244 access
= GENERIC_WRITE
;
1246 case PIPE_ACCESS_DUPLEX
:
1247 sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
1248 access
= GENERIC_READ
| GENERIC_WRITE
;
1251 SetLastError( ERROR_INVALID_PARAMETER
);
1252 return INVALID_HANDLE_VALUE
;
1254 access
|= SYNCHRONIZE
;
1256 if (open_mode
& WRITE_DAC
) access
|= WRITE_DAC
;
1257 if (open_mode
& WRITE_OWNER
) access
|= WRITE_OWNER
;
1258 if (open_mode
& ACCESS_SYSTEM_SECURITY
) access
|= ACCESS_SYSTEM_SECURITY
;
1259 if (open_mode
& FILE_FLAG_WRITE_THROUGH
) options
|= FILE_WRITE_THROUGH
;
1260 if (!(open_mode
& FILE_FLAG_OVERLAPPED
)) options
|= FILE_SYNCHRONOUS_IO_NONALERT
;
1261 pipe_type
= (pipe_mode
& PIPE_TYPE_MESSAGE
) != 0;
1262 read_mode
= (pipe_mode
& PIPE_READMODE_MESSAGE
) != 0;
1263 non_block
= (pipe_mode
& PIPE_NOWAIT
) != 0;
1264 if (instances
>= PIPE_UNLIMITED_INSTANCES
) instances
= ~0U;
1266 time
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1268 status
= NtCreateNamedPipeFile( &handle
, access
, &attr
, &iosb
, sharing
,
1269 FILE_OVERWRITE_IF
, options
, pipe_type
,
1270 read_mode
, non_block
, instances
, in_buff
, out_buff
, &time
);
1271 RtlFreeUnicodeString( &nt_name
);
1272 if (!set_ntstatus( status
)) return INVALID_HANDLE_VALUE
;
1277 /******************************************************************
1278 * CreatePipe (kernelbase.@)
1280 BOOL WINAPI DECLSPEC_HOTPATCH
CreatePipe( HANDLE
*read_pipe
, HANDLE
*write_pipe
,
1281 SECURITY_ATTRIBUTES
*sa
, DWORD size
)
1283 static unsigned int index
;
1285 UNICODE_STRING nt_name
;
1286 OBJECT_ATTRIBUTES attr
;
1287 IO_STATUS_BLOCK iosb
;
1288 LARGE_INTEGER timeout
;
1290 *read_pipe
= *write_pipe
= INVALID_HANDLE_VALUE
;
1292 attr
.Length
= sizeof(attr
);
1293 attr
.RootDirectory
= 0;
1294 attr
.ObjectName
= &nt_name
;
1295 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1296 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1297 attr
.SecurityQualityOfService
= NULL
;
1299 if (!size
) size
= 4096;
1301 timeout
.QuadPart
= (ULONGLONG
)NMPWAIT_USE_DEFAULT_WAIT
* -10000;
1303 /* generate a unique pipe name (system wide) */
1306 swprintf( name
, ARRAY_SIZE(name
), L
"\\??\\pipe\\Win32.Pipes.%08lu.%08u",
1307 GetCurrentProcessId(), ++index
);
1308 RtlInitUnicodeString( &nt_name
, name
);
1309 if (!NtCreateNamedPipeFile( read_pipe
, GENERIC_READ
| FILE_WRITE_ATTRIBUTES
| SYNCHRONIZE
,
1310 &attr
, &iosb
, FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
1311 FILE_SYNCHRONOUS_IO_NONALERT
,
1312 FALSE
, FALSE
, FALSE
, 1, size
, size
, &timeout
))
1315 if (!set_ntstatus( NtOpenFile( write_pipe
, GENERIC_WRITE
| FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1316 &iosb
, 0, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
)))
1318 NtClose( *read_pipe
);
1325 /***********************************************************************
1326 * DisconnectNamedPipe (kernelbase.@)
1328 BOOL WINAPI DECLSPEC_HOTPATCH
DisconnectNamedPipe( HANDLE pipe
)
1330 IO_STATUS_BLOCK io_block
;
1332 TRACE( "(%p)\n", pipe
);
1333 return set_ntstatus( NtFsControlFile( pipe
, 0, NULL
, NULL
, &io_block
,
1334 FSCTL_PIPE_DISCONNECT
, NULL
, 0, NULL
, 0 ));
1338 /***********************************************************************
1339 * GetNamedPipeHandleStateW (kernelbase.@)
1341 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeHandleStateW( HANDLE pipe
, DWORD
*state
, DWORD
*instances
,
1342 DWORD
*max_count
, DWORD
*timeout
,
1343 WCHAR
*user
, DWORD size
)
1347 FIXME( "%p %p %p %p %p %p %ld: semi-stub\n", pipe
, state
, instances
, max_count
, timeout
, user
, size
);
1349 if (max_count
) *max_count
= 0;
1350 if (timeout
) *timeout
= 0;
1351 if (user
&& size
&& !GetEnvironmentVariableW( L
"WINEUSERNAME", user
, size
)) user
[0] = 0;
1355 FILE_PIPE_INFORMATION info
;
1357 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
), FilePipeInformation
)))
1360 *state
= (info
.ReadMode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
) |
1361 (info
.CompletionMode
? PIPE_NOWAIT
: PIPE_WAIT
);
1365 FILE_PIPE_LOCAL_INFORMATION info
;
1367 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
),
1368 FilePipeLocalInformation
)))
1370 *instances
= info
.CurrentInstances
;
1376 /***********************************************************************
1377 * GetNamedPipeInfo (kernelbase.@)
1379 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeInfo( HANDLE pipe
, LPDWORD flags
, LPDWORD out_size
,
1380 LPDWORD in_size
, LPDWORD instances
)
1382 FILE_PIPE_LOCAL_INFORMATION info
;
1383 IO_STATUS_BLOCK iosb
;
1385 if (!set_ntstatus( NtQueryInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeLocalInformation
)))
1390 *flags
= (info
.NamedPipeEnd
& FILE_PIPE_SERVER_END
) ? PIPE_SERVER_END
: PIPE_CLIENT_END
;
1391 *flags
|= (info
.NamedPipeType
& FILE_PIPE_TYPE_MESSAGE
) ? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
;
1393 if (out_size
) *out_size
= info
.OutboundQuota
;
1394 if (in_size
) *in_size
= info
.InboundQuota
;
1395 if (instances
) *instances
= info
.MaximumInstances
;
1400 /***********************************************************************
1401 * PeekNamedPipe (kernelbase.@)
1403 BOOL WINAPI DECLSPEC_HOTPATCH
PeekNamedPipe( HANDLE pipe
, LPVOID out_buffer
, DWORD size
,
1404 LPDWORD read_size
, LPDWORD avail
, LPDWORD message
)
1406 FILE_PIPE_PEEK_BUFFER local_buffer
;
1407 FILE_PIPE_PEEK_BUFFER
*buffer
= &local_buffer
;
1411 if (size
&& !(buffer
= HeapAlloc( GetProcessHeap(), 0,
1412 FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ))))
1414 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1418 status
= NtFsControlFile( pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0,
1419 buffer
, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ) );
1420 if (status
== STATUS_BUFFER_OVERFLOW
) status
= STATUS_SUCCESS
;
1423 ULONG count
= io
.Information
- FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
);
1424 if (avail
) *avail
= buffer
->ReadDataAvailable
;
1425 if (read_size
) *read_size
= count
;
1426 if (message
) *message
= buffer
->MessageLength
- count
;
1427 if (out_buffer
) memcpy( out_buffer
, buffer
->Data
, count
);
1429 else SetLastError( RtlNtStatusToDosError(status
) );
1431 if (buffer
!= &local_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
1436 /***********************************************************************
1437 * SetNamedPipeHandleState (kernelbase.@)
1439 BOOL WINAPI DECLSPEC_HOTPATCH
SetNamedPipeHandleState( HANDLE pipe
, LPDWORD mode
,
1440 LPDWORD count
, LPDWORD timeout
)
1442 FILE_PIPE_INFORMATION info
;
1443 IO_STATUS_BLOCK iosb
;
1444 NTSTATUS status
= STATUS_SUCCESS
;
1446 TRACE( "%p %p/%ld %p %p\n", pipe
, mode
, mode
? *mode
: 0, count
, timeout
);
1447 if (count
|| timeout
) FIXME( "Unsupported arguments\n" );
1451 if (*mode
& ~(PIPE_READMODE_MESSAGE
| PIPE_NOWAIT
)) status
= STATUS_INVALID_PARAMETER
;
1454 info
.CompletionMode
= (*mode
& PIPE_NOWAIT
) ?
1455 FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION
;
1456 info
.ReadMode
= (*mode
& PIPE_READMODE_MESSAGE
) ?
1457 FILE_PIPE_MESSAGE_MODE
: FILE_PIPE_BYTE_STREAM_MODE
;
1458 status
= NtSetInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeInformation
);
1461 return set_ntstatus( status
);
1464 /***********************************************************************
1465 * TransactNamedPipe (kernelbase.@)
1467 BOOL WINAPI DECLSPEC_HOTPATCH
TransactNamedPipe( HANDLE handle
, LPVOID write_buf
, DWORD write_size
,
1468 LPVOID read_buf
, DWORD read_size
, LPDWORD bytes_read
,
1469 LPOVERLAPPED overlapped
)
1471 IO_STATUS_BLOCK default_iosb
, *iosb
= &default_iosb
;
1472 HANDLE event
= NULL
;
1473 void *cvalue
= NULL
;
1476 TRACE( "%p %p %lu %p %lu %p %p\n", handle
,
1477 write_buf
, write_size
, read_buf
, read_size
, bytes_read
, overlapped
);
1481 event
= overlapped
->hEvent
;
1482 iosb
= (IO_STATUS_BLOCK
*)overlapped
;
1483 if (((ULONG_PTR
)event
& 1) == 0) cvalue
= overlapped
;
1487 iosb
->Information
= 0;
1490 status
= NtFsControlFile( handle
, event
, NULL
, cvalue
, iosb
, FSCTL_PIPE_TRANSCEIVE
,
1491 write_buf
, write_size
, read_buf
, read_size
);
1492 if (status
== STATUS_PENDING
&& !overlapped
)
1494 WaitForSingleObject(handle
, INFINITE
);
1495 status
= iosb
->u
.Status
;
1498 if (bytes_read
) *bytes_read
= overlapped
&& status
? 0 : iosb
->Information
;
1499 return set_ntstatus( status
);
1503 /***********************************************************************
1504 * WaitNamedPipeW (kernelbase.@)
1506 BOOL WINAPI DECLSPEC_HOTPATCH
WaitNamedPipeW( LPCWSTR name
, DWORD timeout
)
1508 static const int prefix_len
= sizeof(L
"\\??\\PIPE\\") - sizeof(WCHAR
);
1510 UNICODE_STRING nt_name
, pipe_dev_name
;
1511 FILE_PIPE_WAIT_FOR_BUFFER
*pipe_wait
;
1512 IO_STATUS_BLOCK iosb
;
1513 OBJECT_ATTRIBUTES attr
;
1517 TRACE( "%s 0x%08lx\n", debugstr_w(name
), timeout
);
1519 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
)) return FALSE
;
1521 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) ||
1522 nt_name
.Length
< prefix_len
||
1523 wcsnicmp( nt_name
.Buffer
, L
"\\??\\PIPE\\", prefix_len
/ sizeof(WCHAR
) ))
1525 RtlFreeUnicodeString( &nt_name
);
1526 SetLastError( ERROR_PATH_NOT_FOUND
);
1530 wait_size
= offsetof( FILE_PIPE_WAIT_FOR_BUFFER
, Name
[(nt_name
.Length
- prefix_len
) / sizeof(WCHAR
)] );
1531 if (!(pipe_wait
= HeapAlloc( GetProcessHeap(), 0, wait_size
)))
1533 RtlFreeUnicodeString( &nt_name
);
1534 SetLastError( ERROR_OUTOFMEMORY
);
1538 pipe_dev_name
.Buffer
= nt_name
.Buffer
;
1539 pipe_dev_name
.Length
= prefix_len
;
1540 pipe_dev_name
.MaximumLength
= prefix_len
;
1541 InitializeObjectAttributes( &attr
,&pipe_dev_name
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1542 status
= NtOpenFile( &pipe_dev
, FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1543 &iosb
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1544 FILE_SYNCHRONOUS_IO_NONALERT
);
1545 if (status
!= STATUS_SUCCESS
)
1547 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1548 RtlFreeUnicodeString( &nt_name
);
1549 SetLastError( ERROR_PATH_NOT_FOUND
);
1553 pipe_wait
->TimeoutSpecified
= !(timeout
== NMPWAIT_USE_DEFAULT_WAIT
);
1554 if (timeout
== NMPWAIT_WAIT_FOREVER
)
1555 pipe_wait
->Timeout
.QuadPart
= ((ULONGLONG
)0x7fffffff << 32) | 0xffffffff;
1557 pipe_wait
->Timeout
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1558 pipe_wait
->NameLength
= nt_name
.Length
- prefix_len
;
1559 memcpy( pipe_wait
->Name
, nt_name
.Buffer
+ prefix_len
/sizeof(WCHAR
), pipe_wait
->NameLength
);
1560 RtlFreeUnicodeString( &nt_name
);
1562 status
= NtFsControlFile( pipe_dev
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_WAIT
,
1563 pipe_wait
, wait_size
, NULL
, 0 );
1565 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1566 NtClose( pipe_dev
);
1567 return set_ntstatus( status
);
1572 /***********************************************************************
1573 * Interlocked functions
1574 ***********************************************************************/
1577 /***********************************************************************
1578 * InitOnceBeginInitialize (kernelbase.@)
1580 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceBeginInitialize( INIT_ONCE
*once
, DWORD flags
,
1581 BOOL
*pending
, void **context
)
1583 NTSTATUS status
= RtlRunOnceBeginInitialize( once
, flags
, context
);
1584 if (status
>= 0) *pending
= (status
== STATUS_PENDING
);
1585 else SetLastError( RtlNtStatusToDosError(status
) );
1590 /***********************************************************************
1591 * InitOnceComplete (kernelbase.@)
1593 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceComplete( INIT_ONCE
*once
, DWORD flags
, void *context
)
1595 return set_ntstatus( RtlRunOnceComplete( once
, flags
, context
));
1599 /***********************************************************************
1600 * InitOnceExecuteOnce (kernelbase.@)
1602 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceExecuteOnce( INIT_ONCE
*once
, PINIT_ONCE_FN func
,
1603 void *param
, void **context
)
1605 return !RtlRunOnceExecuteOnce( once
, (PRTL_RUN_ONCE_INIT_FN
)func
, param
, context
);
1610 /***********************************************************************
1611 * InterlockedCompareExchange (kernelbase.@)
1613 __ASM_STDCALL_FUNC(InterlockedCompareExchange
, 12,
1614 "movl 12(%esp),%eax\n\t"
1615 "movl 8(%esp),%ecx\n\t"
1616 "movl 4(%esp),%edx\n\t"
1617 "lock; cmpxchgl %ecx,(%edx)\n\t"
1620 /***********************************************************************
1621 * InterlockedExchange (kernelbase.@)
1623 __ASM_STDCALL_FUNC(InterlockedExchange
, 8,
1624 "movl 8(%esp),%eax\n\t"
1625 "movl 4(%esp),%edx\n\t"
1626 "lock; xchgl %eax,(%edx)\n\t"
1629 /***********************************************************************
1630 * InterlockedExchangeAdd (kernelbase.@)
1632 __ASM_STDCALL_FUNC(InterlockedExchangeAdd
, 8,
1633 "movl 8(%esp),%eax\n\t"
1634 "movl 4(%esp),%edx\n\t"
1635 "lock; xaddl %eax,(%edx)\n\t"
1638 /***********************************************************************
1639 * InterlockedIncrement (kernelbase.@)
1641 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
1642 "movl 4(%esp),%edx\n\t"
1644 "lock; xaddl %eax,(%edx)\n\t"
1648 /***********************************************************************
1649 * InterlockedDecrement (kernelbase.@)
1651 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
1652 "movl 4(%esp),%edx\n\t"
1654 "lock; xaddl %eax,(%edx)\n\t"
1658 #endif /* __i386__ */