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/server.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(sync
);
45 /* check if current version is NT or Win95 */
46 static inline BOOL
is_version_nt(void)
48 return !(GetVersion() & 0x80000000);
51 /* helper for kernel32->ntdll timeout format conversion */
52 static inline LARGE_INTEGER
*get_nt_timeout( LARGE_INTEGER
*time
, DWORD timeout
)
54 if (timeout
== INFINITE
) return NULL
;
55 time
->QuadPart
= (ULONGLONG
)timeout
* -10000;
60 /***********************************************************************
61 * BaseGetNamedObjectDirectory (kernelbase.@)
63 NTSTATUS WINAPI
BaseGetNamedObjectDirectory( HANDLE
*dir
)
66 static const WCHAR basenameW
[] = {'\\','S','e','s','s','i','o','n','s','\\','%','u',
67 '\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',0};
70 OBJECT_ATTRIBUTES attr
;
71 NTSTATUS status
= STATUS_SUCCESS
;
77 swprintf( buffer
, ARRAY_SIZE(buffer
), basenameW
, 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 static HANDLE
normalize_handle_if_console( HANDLE handle
)
132 static HANDLE wait_event
;
134 if ((handle
== (HANDLE
)STD_INPUT_HANDLE
) ||
135 (handle
== (HANDLE
)STD_OUTPUT_HANDLE
) ||
136 (handle
== (HANDLE
)STD_ERROR_HANDLE
))
137 handle
= GetStdHandle( HandleToULong(handle
) );
139 /* even screen buffer console handles are waitable, and are
140 * handled as a handle to the console itself
142 if (is_console_handle( handle
))
146 SERVER_START_REQ( get_console_wait_event
)
148 req
->handle
= wine_server_obj_handle( console_handle_map( handle
));
149 if (!wine_server_call( req
)) event
= wine_server_ptr_handle( reply
->event
);
154 if (InterlockedCompareExchangePointer( &wait_event
, event
, 0 )) NtClose( event
);
162 /***********************************************************************
163 * RegisterWaitForSingleObjectEx (kernelbase.@)
165 HANDLE WINAPI DECLSPEC_HOTPATCH
RegisterWaitForSingleObjectEx( HANDLE handle
, WAITORTIMERCALLBACK callback
,
166 PVOID context
, ULONG timeout
, ULONG flags
)
170 TRACE( "%p %p %p %d %d\n", handle
, callback
, context
, timeout
, flags
);
172 handle
= normalize_handle_if_console( handle
);
173 if (!set_ntstatus( RtlRegisterWait( &ret
, handle
, callback
, context
, timeout
, flags
))) return NULL
;
178 /***********************************************************************
179 * SignalObjectAndWait (kernelbase.@)
181 DWORD WINAPI DECLSPEC_HOTPATCH
SignalObjectAndWait( HANDLE signal
, HANDLE wait
,
182 DWORD timeout
, BOOL alertable
)
187 TRACE( "%p %p %d %d\n", signal
, wait
, timeout
, alertable
);
189 status
= NtSignalAndWaitForSingleObject( signal
, wait
, alertable
, get_nt_timeout( &time
, timeout
) );
192 SetLastError( RtlNtStatusToDosError(status
) );
193 status
= WAIT_FAILED
;
199 /***********************************************************************
200 * Sleep (kernelbase.@)
202 void WINAPI DECLSPEC_HOTPATCH
Sleep( DWORD timeout
)
206 NtDelayExecution( FALSE
, get_nt_timeout( &time
, timeout
) );
210 /******************************************************************************
211 * SleepEx (kernelbase.@)
213 DWORD WINAPI DECLSPEC_HOTPATCH
SleepEx( DWORD timeout
, BOOL alertable
)
218 status
= NtDelayExecution( alertable
, get_nt_timeout( &time
, timeout
) );
219 if (status
== STATUS_USER_APC
) return WAIT_IO_COMPLETION
;
224 /***********************************************************************
225 * UnregisterWaitEx (kernelbase.@)
227 BOOL WINAPI DECLSPEC_HOTPATCH
UnregisterWaitEx( HANDLE handle
, HANDLE event
)
229 return set_ntstatus( RtlDeregisterWaitEx( handle
, event
));
233 /***********************************************************************
234 * WaitForSingleObject (kernelbase.@)
236 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
238 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
242 /***********************************************************************
243 * WaitForSingleObjectEx (kernelbase.@)
245 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
, BOOL alertable
)
247 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
251 /***********************************************************************
252 * WaitForMultipleObjects (kernelbase.@)
254 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
255 BOOL wait_all
, DWORD timeout
)
257 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
261 /***********************************************************************
262 * WaitForMultipleObjectsEx (kernelbase.@)
264 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
265 BOOL wait_all
, DWORD timeout
, BOOL alertable
)
268 HANDLE hloc
[MAXIMUM_WAIT_OBJECTS
];
272 if (count
> MAXIMUM_WAIT_OBJECTS
)
274 SetLastError(ERROR_INVALID_PARAMETER
);
277 for (i
= 0; i
< count
; i
++) hloc
[i
] = normalize_handle_if_console( handles
[i
] );
279 status
= NtWaitForMultipleObjects( count
, hloc
, !wait_all
, alertable
,
280 get_nt_timeout( &time
, timeout
) );
281 if (HIWORD(status
)) /* is it an error code? */
283 SetLastError( RtlNtStatusToDosError(status
) );
284 status
= WAIT_FAILED
;
290 /***********************************************************************
292 ***********************************************************************/
295 /***********************************************************************
296 * CreateEventA (kernelbase.@)
298 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
299 BOOL initial_state
, LPCSTR name
)
303 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
304 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
305 return CreateEventExA( sa
, name
, flags
, EVENT_ALL_ACCESS
);
309 /***********************************************************************
310 * CreateEventW (kernelbase.@)
312 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventW( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
313 BOOL initial_state
, LPCWSTR name
)
317 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
318 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
319 return CreateEventExW( sa
, name
, flags
, EVENT_ALL_ACCESS
);
323 /***********************************************************************
324 * CreateEventExA (kernelbase.@)
326 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
327 DWORD flags
, DWORD access
)
329 WCHAR buffer
[MAX_PATH
];
331 if (!name
) return CreateEventExW( sa
, NULL
, flags
, access
);
333 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
335 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
338 return CreateEventExW( sa
, buffer
, flags
, access
);
342 /***********************************************************************
343 * CreateEventExW (kernelbase.@)
345 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
346 DWORD flags
, DWORD access
)
349 UNICODE_STRING nameW
;
350 OBJECT_ATTRIBUTES attr
;
353 /* one buggy program needs this
354 * ("Van Dale Groot woordenboek der Nederlandse taal")
358 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
362 SetLastError( ERROR_INVALID_PARAMETER
);
367 status
= NtCreateEvent( &ret
, access
, &attr
,
368 (flags
& CREATE_EVENT_MANUAL_RESET
) ? NotificationEvent
: SynchronizationEvent
,
369 (flags
& CREATE_EVENT_INITIAL_SET
) != 0 );
370 if (status
== STATUS_OBJECT_NAME_EXISTS
)
371 SetLastError( ERROR_ALREADY_EXISTS
);
373 SetLastError( RtlNtStatusToDosError(status
) );
378 /***********************************************************************
379 * OpenEventA (kernelbase.@)
381 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventA( DWORD access
, BOOL inherit
, LPCSTR name
)
383 WCHAR buffer
[MAX_PATH
];
385 if (!name
) return OpenEventW( access
, inherit
, NULL
);
387 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
389 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
392 return OpenEventW( access
, inherit
, buffer
);
396 /***********************************************************************
397 * OpenEventW (kernelbase.@)
399 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
402 UNICODE_STRING nameW
;
403 OBJECT_ATTRIBUTES attr
;
405 if (!is_version_nt()) access
= EVENT_ALL_ACCESS
;
407 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
409 if (!set_ntstatus( NtOpenEvent( &ret
, access
, &attr
))) return 0;
413 /***********************************************************************
414 * PulseEvent (kernelbase.@)
416 BOOL WINAPI DECLSPEC_HOTPATCH
PulseEvent( HANDLE handle
)
418 return set_ntstatus( NtPulseEvent( handle
, NULL
));
422 /***********************************************************************
423 * SetEvent (kernelbase.@)
425 BOOL WINAPI DECLSPEC_HOTPATCH
SetEvent( HANDLE handle
)
427 return set_ntstatus( NtSetEvent( handle
, NULL
));
431 /***********************************************************************
432 * ResetEvent (kernelbase.@)
434 BOOL WINAPI DECLSPEC_HOTPATCH
ResetEvent( HANDLE handle
)
436 return set_ntstatus( NtResetEvent( handle
, NULL
));
440 /***********************************************************************
442 ***********************************************************************/
445 /***********************************************************************
446 * CreateMutexA (kernelbase.@)
448 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexA( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCSTR name
)
450 return CreateMutexExA( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
454 /***********************************************************************
455 * CreateMutexW (kernelbase.@)
457 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexW( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCWSTR name
)
459 return CreateMutexExW( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
463 /***********************************************************************
464 * CreateMutexExA (kernelbase.@)
466 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
467 DWORD flags
, DWORD access
)
472 if (!name
) return CreateMutexExW( sa
, NULL
, flags
, access
);
474 RtlInitAnsiString( &nameA
, name
);
475 status
= RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString
, &nameA
, FALSE
);
476 if (status
!= STATUS_SUCCESS
)
478 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
481 return CreateMutexExW( sa
, NtCurrentTeb()->StaticUnicodeString
.Buffer
, flags
, access
);
485 /***********************************************************************
486 * CreateMutexExW (kernelbase.@)
488 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
489 DWORD flags
, DWORD access
)
492 UNICODE_STRING nameW
;
493 OBJECT_ATTRIBUTES attr
;
496 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
498 status
= NtCreateMutant( &ret
, access
, &attr
, (flags
& CREATE_MUTEX_INITIAL_OWNER
) != 0 );
499 if (status
== STATUS_OBJECT_NAME_EXISTS
)
500 SetLastError( ERROR_ALREADY_EXISTS
);
502 SetLastError( RtlNtStatusToDosError(status
) );
507 /***********************************************************************
508 * OpenMutexW (kernelbase.@)
510 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
513 UNICODE_STRING nameW
;
514 OBJECT_ATTRIBUTES attr
;
516 if (!is_version_nt()) access
= MUTEX_ALL_ACCESS
;
518 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
520 if (!set_ntstatus( NtOpenMutant( &ret
, access
, &attr
))) return 0;
525 /***********************************************************************
526 * ReleaseMutex (kernelbase.@)
528 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseMutex( HANDLE handle
)
530 return set_ntstatus( NtReleaseMutant( handle
, NULL
));
534 /***********************************************************************
536 ***********************************************************************/
539 /***********************************************************************
540 * CreateSemaphoreW (kernelbase.@)
542 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreW( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
543 LONG max
, LPCWSTR name
)
545 return CreateSemaphoreExW( sa
, initial
, max
, name
, 0, SEMAPHORE_ALL_ACCESS
);
549 /***********************************************************************
550 * CreateSemaphoreExW (kernelbase.@)
552 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreExW( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
,
553 LPCWSTR name
, DWORD flags
, DWORD access
)
556 UNICODE_STRING nameW
;
557 OBJECT_ATTRIBUTES attr
;
560 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
562 status
= NtCreateSemaphore( &ret
, access
, &attr
, initial
, max
);
563 if (status
== STATUS_OBJECT_NAME_EXISTS
)
564 SetLastError( ERROR_ALREADY_EXISTS
);
566 SetLastError( RtlNtStatusToDosError(status
) );
571 /***********************************************************************
572 * OpenSemaphoreW (kernelbase.@)
574 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
577 UNICODE_STRING nameW
;
578 OBJECT_ATTRIBUTES attr
;
580 if (!is_version_nt()) access
= SEMAPHORE_ALL_ACCESS
;
582 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
584 if (!set_ntstatus( NtOpenSemaphore( &ret
, access
, &attr
))) return 0;
589 /***********************************************************************
590 * ReleaseSemaphore (kernelbase.@)
592 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseSemaphore( HANDLE handle
, LONG count
, LONG
*previous
)
594 return set_ntstatus( NtReleaseSemaphore( handle
, count
, (PULONG
)previous
));
598 /***********************************************************************
600 ***********************************************************************/
603 /***********************************************************************
604 * CreateWaitableTimerW (kernelbase.@)
606 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerW( SECURITY_ATTRIBUTES
*sa
, BOOL manual
, LPCWSTR name
)
608 return CreateWaitableTimerExW( sa
, name
, manual
? CREATE_WAITABLE_TIMER_MANUAL_RESET
: 0,
613 /***********************************************************************
614 * CreateWaitableTimerExW (kernelbase.@)
616 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
617 DWORD flags
, DWORD access
)
621 UNICODE_STRING nameW
;
622 OBJECT_ATTRIBUTES attr
;
624 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
626 status
= NtCreateTimer( &handle
, access
, &attr
,
627 (flags
& CREATE_WAITABLE_TIMER_MANUAL_RESET
) ? NotificationTimer
: SynchronizationTimer
);
628 if (status
== STATUS_OBJECT_NAME_EXISTS
)
629 SetLastError( ERROR_ALREADY_EXISTS
);
631 SetLastError( RtlNtStatusToDosError(status
) );
636 /***********************************************************************
637 * OpenWaitableTimerW (kernelbase.@)
639 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenWaitableTimerW( DWORD access
, BOOL inherit
, LPCWSTR name
)
642 UNICODE_STRING nameW
;
643 OBJECT_ATTRIBUTES attr
;
645 if (!is_version_nt()) access
= TIMER_ALL_ACCESS
;
647 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
649 if (!set_ntstatus( NtOpenTimer( &handle
, access
, &attr
))) return 0;
654 /***********************************************************************
655 * SetWaitableTimer (kernelbase.@)
657 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimer( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
658 PTIMERAPCROUTINE callback
, LPVOID arg
, BOOL resume
)
660 NTSTATUS status
= NtSetTimer( handle
, when
, (PTIMER_APC_ROUTINE
)callback
,
661 arg
, resume
, period
, NULL
);
662 return set_ntstatus( status
) || status
== STATUS_TIMER_RESUME_IGNORED
;
666 /***********************************************************************
667 * SetWaitableTimerEx (kernelbase.@)
669 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimerEx( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
670 PTIMERAPCROUTINE callback
, LPVOID arg
,
671 REASON_CONTEXT
*context
, ULONG tolerabledelay
)
674 if (!once
++) FIXME( "(%p, %p, %d, %p, %p, %p, %d) semi-stub\n",
675 handle
, when
, period
, callback
, arg
, context
, tolerabledelay
);
677 return SetWaitableTimer( handle
, when
, period
, callback
, arg
, FALSE
);
681 /***********************************************************************
682 * CancelWaitableTimer (kernelbase.@)
684 BOOL WINAPI DECLSPEC_HOTPATCH
CancelWaitableTimer( HANDLE handle
)
686 return set_ntstatus( NtCancelTimer( handle
, NULL
));
690 /***********************************************************************
692 ***********************************************************************/
695 /***********************************************************************
696 * CreateTimerQueue (kernelbase.@)
698 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateTimerQueue(void)
702 if (!set_ntstatus( RtlCreateTimerQueue( &q
))) return NULL
;
707 /***********************************************************************
708 * CreateTimerQueueTimer (kernelbase.@)
710 BOOL WINAPI DECLSPEC_HOTPATCH
CreateTimerQueueTimer( PHANDLE timer
, HANDLE queue
,
711 WAITORTIMERCALLBACK callback
, PVOID arg
,
712 DWORD when
, DWORD period
, ULONG flags
)
714 return set_ntstatus( RtlCreateTimer( timer
, queue
, callback
, arg
, when
, period
, flags
));
718 /***********************************************************************
719 * ChangeTimerQueueTimer (kernelbase.@)
721 BOOL WINAPI DECLSPEC_HOTPATCH
ChangeTimerQueueTimer( HANDLE queue
, HANDLE timer
,
722 ULONG when
, ULONG period
)
724 return set_ntstatus( RtlUpdateTimer( queue
, timer
, when
, period
));
728 /***********************************************************************
729 * DeleteTimerQueueEx (kernelbase.@)
731 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueEx( HANDLE queue
, HANDLE event
)
733 return set_ntstatus( RtlDeleteTimerQueueEx( queue
, event
));
737 /***********************************************************************
738 * DeleteTimerQueueTimer (kernelbase.@)
740 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueTimer( HANDLE queue
, HANDLE timer
, HANDLE event
)
742 return set_ntstatus( RtlDeleteTimer( queue
, timer
, event
));
746 /***********************************************************************
748 ***********************************************************************/
751 /***********************************************************************
752 * InitializeCriticalSectionAndSpinCount (kernelbase.@)
754 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION
*crit
, DWORD count
)
756 return !RtlInitializeCriticalSectionAndSpinCount( crit
, count
);
759 /***********************************************************************
760 * InitializeCriticalSectionEx (kernelbase.@)
762 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionEx( CRITICAL_SECTION
*crit
, DWORD spincount
,
765 NTSTATUS ret
= RtlInitializeCriticalSectionEx( crit
, spincount
, flags
);
766 if (ret
) RtlRaiseStatus( ret
);
771 /***********************************************************************
773 ***********************************************************************/
776 /***********************************************************************
777 * CreateFileMappingW (kernelbase.@)
779 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingW( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, DWORD protect
,
780 DWORD size_high
, DWORD size_low
, LPCWSTR name
)
782 static const int sec_flags
= (SEC_FILE
| SEC_IMAGE
| SEC_RESERVE
| SEC_COMMIT
|
783 SEC_NOCACHE
| SEC_WRITECOMBINE
| SEC_LARGE_PAGES
);
786 DWORD access
, sec_type
;
788 UNICODE_STRING nameW
;
789 OBJECT_ATTRIBUTES attr
;
791 sec_type
= protect
& sec_flags
;
792 protect
&= ~sec_flags
;
793 if (!sec_type
) sec_type
= SEC_COMMIT
;
795 /* Win9x compatibility */
796 if (!protect
&& !is_version_nt()) protect
= PAGE_READONLY
;
802 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
805 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
;
807 case PAGE_EXECUTE_READ
:
808 case PAGE_EXECUTE_WRITECOPY
:
809 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_EXECUTE
;
811 case PAGE_EXECUTE_READWRITE
:
812 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
;
815 SetLastError( ERROR_INVALID_PARAMETER
);
819 size
.u
.LowPart
= size_low
;
820 size
.u
.HighPart
= size_high
;
822 if (file
== INVALID_HANDLE_VALUE
)
827 SetLastError( ERROR_INVALID_PARAMETER
);
832 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
834 status
= NtCreateSection( &ret
, access
, &attr
, &size
, protect
, sec_type
, file
);
835 if (status
== STATUS_OBJECT_NAME_EXISTS
)
836 SetLastError( ERROR_ALREADY_EXISTS
);
838 SetLastError( RtlNtStatusToDosError(status
) );
843 /***********************************************************************
844 * OpenFileMappingW (kernelbase.@)
846 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingW( DWORD access
, BOOL inherit
, LPCWSTR name
)
848 OBJECT_ATTRIBUTES attr
;
849 UNICODE_STRING nameW
;
852 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
854 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
856 if (!is_version_nt())
858 /* win9x doesn't do access checks, so try with full access first */
859 if (!NtOpenSection( &ret
, access
| SECTION_MAP_READ
| SECTION_MAP_WRITE
, &attr
)) return ret
;
862 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
867 /***********************************************************************
868 * Condition variables
869 ***********************************************************************/
872 /***********************************************************************
873 * SleepConditionVariableCS (kernelbase.@)
875 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableCS( CONDITION_VARIABLE
*variable
,
876 CRITICAL_SECTION
*crit
, DWORD timeout
)
880 return set_ntstatus( RtlSleepConditionVariableCS( variable
, crit
, get_nt_timeout( &time
, timeout
)));
884 /***********************************************************************
885 * SleepConditionVariableSRW (kernelbase.@)
887 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableSRW( RTL_CONDITION_VARIABLE
*variable
,
888 RTL_SRWLOCK
*lock
, DWORD timeout
, ULONG flags
)
892 return set_ntstatus( RtlSleepConditionVariableSRW( variable
, lock
,
893 get_nt_timeout( &time
, timeout
), flags
));
897 /***********************************************************************
899 ***********************************************************************/
902 /******************************************************************************
903 * CreateIoCompletionPort (kernelbase.@)
905 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateIoCompletionPort( HANDLE handle
, HANDLE port
,
906 ULONG_PTR key
, DWORD threads
)
908 FILE_COMPLETION_INFORMATION info
;
909 IO_STATUS_BLOCK iosb
;
912 TRACE( "(%p, %p, %08lx, %08x)\n", handle
, port
, key
, threads
);
916 if (!set_ntstatus( NtCreateIoCompletion( &ret
, IO_COMPLETION_ALL_ACCESS
, NULL
, threads
)))
919 else if (handle
== INVALID_HANDLE_VALUE
)
921 SetLastError( ERROR_INVALID_PARAMETER
);
925 if (handle
!= INVALID_HANDLE_VALUE
)
927 info
.CompletionPort
= ret
;
928 info
.CompletionKey
= key
;
929 if (!set_ntstatus( NtSetInformationFile( handle
, &iosb
, &info
, sizeof(info
), FileCompletionInformation
)))
931 if (!port
) CloseHandle( ret
);
939 /******************************************************************************
940 * GetQueuedCompletionStatus (kernelbase.@)
942 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatus( HANDLE port
, LPDWORD count
, PULONG_PTR key
,
943 LPOVERLAPPED
*overlapped
, DWORD timeout
)
946 IO_STATUS_BLOCK iosb
;
947 LARGE_INTEGER wait_time
;
949 TRACE( "(%p,%p,%p,%p,%d)\n", port
, count
, key
, overlapped
, timeout
);
952 status
= NtRemoveIoCompletion( port
, key
, (PULONG_PTR
)overlapped
, &iosb
,
953 get_nt_timeout( &wait_time
, timeout
) );
954 if (status
== STATUS_SUCCESS
)
956 *count
= iosb
.Information
;
957 if (iosb
.u
.Status
>= 0) return TRUE
;
958 SetLastError( RtlNtStatusToDosError(iosb
.u
.Status
) );
962 if (status
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
963 else SetLastError( RtlNtStatusToDosError(status
) );
967 /******************************************************************************
968 * GetQueuedCompletionStatusEx (kernelbase.@)
970 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatusEx( HANDLE port
, OVERLAPPED_ENTRY
*entries
,
971 ULONG count
, ULONG
*written
,
972 DWORD timeout
, BOOL alertable
)
977 TRACE( "%p %p %u %p %u %u\n", port
, entries
, count
, written
, timeout
, alertable
);
979 ret
= NtRemoveIoCompletionEx( port
, (FILE_IO_COMPLETION_INFORMATION
*)entries
, count
,
980 written
, get_nt_timeout( &time
, timeout
), alertable
);
981 if (ret
== STATUS_SUCCESS
) return TRUE
;
982 else if (ret
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
983 else if (ret
== STATUS_USER_APC
) SetLastError( WAIT_IO_COMPLETION
);
984 else SetLastError( RtlNtStatusToDosError(ret
) );
989 /******************************************************************************
990 * PostQueuedCompletionStatus (kernelbase.@)
992 BOOL WINAPI DECLSPEC_HOTPATCH
PostQueuedCompletionStatus( HANDLE port
, DWORD count
,
993 ULONG_PTR key
, LPOVERLAPPED overlapped
)
995 TRACE( "%p %d %08lx %p\n", port
, count
, key
, overlapped
);
997 return set_ntstatus( NtSetIoCompletion( port
, key
, (ULONG_PTR
)overlapped
, STATUS_SUCCESS
, count
));
1001 /***********************************************************************
1003 ***********************************************************************/
1006 /***********************************************************************
1007 * CallNamedPipeW (kernelbase.@)
1009 BOOL WINAPI DECLSPEC_HOTPATCH
CallNamedPipeW( LPCWSTR name
, LPVOID input
, DWORD in_size
,
1010 LPVOID output
, DWORD out_size
,
1011 LPDWORD read_size
, DWORD timeout
)
1017 TRACE( "%s %p %d %p %d %p %d\n", debugstr_w(name
),
1018 input
, in_size
, output
, out_size
, read_size
, timeout
);
1020 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1021 if (pipe
== INVALID_HANDLE_VALUE
)
1023 if (!WaitNamedPipeW( name
, timeout
)) return FALSE
;
1024 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1025 if (pipe
== INVALID_HANDLE_VALUE
) return FALSE
;
1028 mode
= PIPE_READMODE_MESSAGE
;
1029 ret
= SetNamedPipeHandleState( pipe
, &mode
, NULL
, NULL
);
1030 if (ret
) ret
= TransactNamedPipe( pipe
, input
, in_size
, output
, out_size
, read_size
, NULL
);
1031 CloseHandle( pipe
);
1036 /***********************************************************************
1037 * ConnectNamedPipe (kernelbase.@)
1039 BOOL WINAPI DECLSPEC_HOTPATCH
ConnectNamedPipe( HANDLE pipe
, LPOVERLAPPED overlapped
)
1042 IO_STATUS_BLOCK status_block
;
1043 LPVOID cvalue
= NULL
;
1045 TRACE( "(%p,%p)\n", pipe
, overlapped
);
1049 overlapped
->Internal
= STATUS_PENDING
;
1050 overlapped
->InternalHigh
= 0;
1051 if (((ULONG_PTR
)overlapped
->hEvent
& 1) == 0) cvalue
= overlapped
;
1054 status
= NtFsControlFile( pipe
, overlapped
? overlapped
->hEvent
: NULL
, NULL
, cvalue
,
1055 overlapped
? (IO_STATUS_BLOCK
*)overlapped
: &status_block
,
1056 FSCTL_PIPE_LISTEN
, NULL
, 0, NULL
, 0 );
1057 if (status
== STATUS_PENDING
&& !overlapped
)
1059 WaitForSingleObject( pipe
, INFINITE
);
1060 status
= status_block
.u
.Status
;
1062 return set_ntstatus( status
);
1065 /***********************************************************************
1066 * CreateNamedPipeW (kernelbase.@)
1068 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateNamedPipeW( LPCWSTR name
, DWORD open_mode
, DWORD pipe_mode
,
1069 DWORD instances
, DWORD out_buff
, DWORD in_buff
,
1070 DWORD timeout
, LPSECURITY_ATTRIBUTES sa
)
1073 UNICODE_STRING nt_name
;
1074 OBJECT_ATTRIBUTES attr
;
1075 DWORD access
, options
, sharing
;
1076 BOOLEAN pipe_type
, read_mode
, non_block
;
1078 IO_STATUS_BLOCK iosb
;
1081 TRACE( "(%s, %#08x, %#08x, %d, %d, %d, %d, %p)\n", debugstr_w(name
),
1082 open_mode
, pipe_mode
, instances
, out_buff
, in_buff
, timeout
, sa
);
1084 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
))
1086 SetLastError( ERROR_PATH_NOT_FOUND
);
1087 return INVALID_HANDLE_VALUE
;
1089 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) )
1091 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
1092 RtlFreeUnicodeString( &nt_name
);
1093 return INVALID_HANDLE_VALUE
;
1096 attr
.Length
= sizeof(attr
);
1097 attr
.RootDirectory
= 0;
1098 attr
.ObjectName
= &nt_name
;
1099 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1100 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1101 attr
.SecurityQualityOfService
= NULL
;
1103 switch (open_mode
& 3)
1105 case PIPE_ACCESS_INBOUND
:
1106 sharing
= FILE_SHARE_WRITE
;
1107 access
= GENERIC_READ
;
1109 case PIPE_ACCESS_OUTBOUND
:
1110 sharing
= FILE_SHARE_READ
;
1111 access
= GENERIC_WRITE
;
1113 case PIPE_ACCESS_DUPLEX
:
1114 sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
1115 access
= GENERIC_READ
| GENERIC_WRITE
;
1118 SetLastError( ERROR_INVALID_PARAMETER
);
1119 return INVALID_HANDLE_VALUE
;
1121 access
|= SYNCHRONIZE
;
1123 if (open_mode
& WRITE_DAC
) access
|= WRITE_DAC
;
1124 if (open_mode
& WRITE_OWNER
) access
|= WRITE_OWNER
;
1125 if (open_mode
& ACCESS_SYSTEM_SECURITY
) access
|= ACCESS_SYSTEM_SECURITY
;
1126 if (open_mode
& FILE_FLAG_WRITE_THROUGH
) options
|= FILE_WRITE_THROUGH
;
1127 if (!(open_mode
& FILE_FLAG_OVERLAPPED
)) options
|= FILE_SYNCHRONOUS_IO_NONALERT
;
1128 pipe_type
= (pipe_mode
& PIPE_TYPE_MESSAGE
) != 0;
1129 read_mode
= (pipe_mode
& PIPE_READMODE_MESSAGE
) != 0;
1130 non_block
= (pipe_mode
& PIPE_NOWAIT
) != 0;
1131 if (instances
>= PIPE_UNLIMITED_INSTANCES
) instances
= ~0U;
1133 time
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1135 status
= NtCreateNamedPipeFile( &handle
, access
, &attr
, &iosb
, sharing
,
1136 FILE_OVERWRITE_IF
, options
, pipe_type
,
1137 read_mode
, non_block
, instances
, in_buff
, out_buff
, &time
);
1138 RtlFreeUnicodeString( &nt_name
);
1139 if (!set_ntstatus( status
)) return INVALID_HANDLE_VALUE
;
1144 /******************************************************************
1145 * CreatePipe (kernelbase.@)
1147 BOOL WINAPI DECLSPEC_HOTPATCH
CreatePipe( HANDLE
*read_pipe
, HANDLE
*write_pipe
,
1148 SECURITY_ATTRIBUTES
*sa
, DWORD size
)
1150 static unsigned int index
;
1152 UNICODE_STRING nt_name
;
1153 OBJECT_ATTRIBUTES attr
;
1154 IO_STATUS_BLOCK iosb
;
1155 LARGE_INTEGER timeout
;
1157 *read_pipe
= *write_pipe
= INVALID_HANDLE_VALUE
;
1159 attr
.Length
= sizeof(attr
);
1160 attr
.RootDirectory
= 0;
1161 attr
.ObjectName
= &nt_name
;
1162 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1163 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1164 attr
.SecurityQualityOfService
= NULL
;
1166 if (!size
) size
= 4096;
1168 timeout
.QuadPart
= (ULONGLONG
)NMPWAIT_USE_DEFAULT_WAIT
* -10000;
1170 /* generate a unique pipe name (system wide) */
1173 static const WCHAR fmtW
[] = { '\\','?','?','\\','p','i','p','e','\\',
1174 'W','i','n','3','2','.','P','i','p','e','s','.','%','0','8','l','u','.','%','0','8','u','\0' };
1176 swprintf( name
, ARRAY_SIZE(name
), fmtW
, GetCurrentProcessId(), ++index
);
1177 RtlInitUnicodeString( &nt_name
, name
);
1178 if (!NtCreateNamedPipeFile( read_pipe
, GENERIC_READ
| FILE_WRITE_ATTRIBUTES
| SYNCHRONIZE
,
1179 &attr
, &iosb
, FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
1180 FILE_SYNCHRONOUS_IO_NONALERT
,
1181 FALSE
, FALSE
, FALSE
, 1, size
, size
, &timeout
))
1184 if (!set_ntstatus( NtOpenFile( write_pipe
, GENERIC_WRITE
| FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1185 &iosb
, 0, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
)))
1187 NtClose( *read_pipe
);
1194 /***********************************************************************
1195 * DisconnectNamedPipe (kernelbase.@)
1197 BOOL WINAPI DECLSPEC_HOTPATCH
DisconnectNamedPipe( HANDLE pipe
)
1199 IO_STATUS_BLOCK io_block
;
1201 TRACE( "(%p)\n", pipe
);
1202 return set_ntstatus( NtFsControlFile( pipe
, 0, NULL
, NULL
, &io_block
,
1203 FSCTL_PIPE_DISCONNECT
, NULL
, 0, NULL
, 0 ));
1207 /***********************************************************************
1208 * GetNamedPipeInfo (kernelbase.@)
1210 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeInfo( HANDLE pipe
, LPDWORD flags
, LPDWORD out_size
,
1211 LPDWORD in_size
, LPDWORD instances
)
1213 FILE_PIPE_LOCAL_INFORMATION info
;
1214 IO_STATUS_BLOCK iosb
;
1216 if (!set_ntstatus( NtQueryInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeLocalInformation
)))
1221 *flags
= (info
.NamedPipeEnd
& FILE_PIPE_SERVER_END
) ? PIPE_SERVER_END
: PIPE_CLIENT_END
;
1222 *flags
|= (info
.NamedPipeType
& FILE_PIPE_TYPE_MESSAGE
) ? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
;
1224 if (out_size
) *out_size
= info
.OutboundQuota
;
1225 if (in_size
) *in_size
= info
.InboundQuota
;
1226 if (instances
) *instances
= info
.MaximumInstances
;
1231 /***********************************************************************
1232 * PeekNamedPipe (kernelbase.@)
1234 BOOL WINAPI DECLSPEC_HOTPATCH
PeekNamedPipe( HANDLE pipe
, LPVOID out_buffer
, DWORD size
,
1235 LPDWORD read_size
, LPDWORD avail
, LPDWORD message
)
1237 FILE_PIPE_PEEK_BUFFER local_buffer
;
1238 FILE_PIPE_PEEK_BUFFER
*buffer
= &local_buffer
;
1242 if (size
&& !(buffer
= HeapAlloc( GetProcessHeap(), 0,
1243 FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ))))
1245 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1249 status
= NtFsControlFile( pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0,
1250 buffer
, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ) );
1251 if (status
== STATUS_BUFFER_OVERFLOW
) status
= STATUS_SUCCESS
;
1254 ULONG count
= io
.Information
- FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
);
1255 if (avail
) *avail
= buffer
->ReadDataAvailable
;
1256 if (read_size
) *read_size
= count
;
1257 if (message
) *message
= buffer
->MessageLength
- count
;
1258 if (out_buffer
) memcpy( out_buffer
, buffer
->Data
, count
);
1260 else SetLastError( RtlNtStatusToDosError(status
) );
1262 if (buffer
!= &local_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
1267 /***********************************************************************
1268 * SetNamedPipeHandleState (kernelbase.@)
1270 BOOL WINAPI DECLSPEC_HOTPATCH
SetNamedPipeHandleState( HANDLE pipe
, LPDWORD mode
,
1271 LPDWORD count
, LPDWORD timeout
)
1273 FILE_PIPE_INFORMATION info
;
1274 IO_STATUS_BLOCK iosb
;
1275 NTSTATUS status
= STATUS_SUCCESS
;
1277 TRACE( "%p %p/%d %p %p\n", pipe
, mode
, mode
? *mode
: 0, count
, timeout
);
1278 if (count
|| timeout
) FIXME( "Unsupported arguments\n" );
1282 if (*mode
& ~(PIPE_READMODE_MESSAGE
| PIPE_NOWAIT
)) status
= STATUS_INVALID_PARAMETER
;
1285 info
.CompletionMode
= (*mode
& PIPE_NOWAIT
) ?
1286 FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION
;
1287 info
.ReadMode
= (*mode
& PIPE_READMODE_MESSAGE
) ?
1288 FILE_PIPE_MESSAGE_MODE
: FILE_PIPE_BYTE_STREAM_MODE
;
1289 status
= NtSetInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeInformation
);
1292 return set_ntstatus( status
);
1295 /***********************************************************************
1296 * TransactNamedPipe (kernelbase.@)
1298 BOOL WINAPI DECLSPEC_HOTPATCH
TransactNamedPipe( HANDLE handle
, LPVOID write_buf
, DWORD write_size
,
1299 LPVOID read_buf
, DWORD read_size
, LPDWORD bytes_read
,
1300 LPOVERLAPPED overlapped
)
1302 IO_STATUS_BLOCK default_iosb
, *iosb
= &default_iosb
;
1303 HANDLE event
= NULL
;
1304 void *cvalue
= NULL
;
1307 TRACE( "%p %p %u %p %u %p %p\n", handle
,
1308 write_buf
, write_size
, read_buf
, read_size
, bytes_read
, overlapped
);
1312 event
= overlapped
->hEvent
;
1313 iosb
= (IO_STATUS_BLOCK
*)overlapped
;
1314 if (((ULONG_PTR
)event
& 1) == 0) cvalue
= overlapped
;
1318 iosb
->Information
= 0;
1321 status
= NtFsControlFile( handle
, event
, NULL
, cvalue
, iosb
, FSCTL_PIPE_TRANSCEIVE
,
1322 write_buf
, write_size
, read_buf
, read_size
);
1323 if (status
== STATUS_PENDING
&& !overlapped
)
1325 WaitForSingleObject(handle
, INFINITE
);
1326 status
= iosb
->u
.Status
;
1329 if (bytes_read
) *bytes_read
= overlapped
&& status
? 0 : iosb
->Information
;
1330 return set_ntstatus( status
);
1334 /***********************************************************************
1335 * WaitNamedPipeW (kernelbase.@)
1337 BOOL WINAPI DECLSPEC_HOTPATCH
WaitNamedPipeW( LPCWSTR name
, DWORD timeout
)
1339 static const WCHAR leadin
[] = {'\\','?','?','\\','P','I','P','E','\\'};
1341 UNICODE_STRING nt_name
, pipe_dev_name
;
1342 FILE_PIPE_WAIT_FOR_BUFFER
*pipe_wait
;
1343 IO_STATUS_BLOCK iosb
;
1344 OBJECT_ATTRIBUTES attr
;
1348 TRACE( "%s 0x%08x\n", debugstr_w(name
), timeout
);
1350 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
)) return FALSE
;
1352 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) ||
1353 nt_name
.Length
< sizeof(leadin
) ||
1354 wcsnicmp( nt_name
.Buffer
, leadin
, ARRAY_SIZE( leadin
)) != 0)
1356 RtlFreeUnicodeString( &nt_name
);
1357 SetLastError( ERROR_PATH_NOT_FOUND
);
1361 wait_size
= sizeof(*pipe_wait
) + nt_name
.Length
- sizeof(leadin
) - sizeof(WCHAR
);
1362 if (!(pipe_wait
= HeapAlloc( GetProcessHeap(), 0, wait_size
)))
1364 RtlFreeUnicodeString( &nt_name
);
1365 SetLastError( ERROR_OUTOFMEMORY
);
1369 pipe_dev_name
.Buffer
= nt_name
.Buffer
;
1370 pipe_dev_name
.Length
= sizeof(leadin
);
1371 pipe_dev_name
.MaximumLength
= sizeof(leadin
);
1372 InitializeObjectAttributes( &attr
,&pipe_dev_name
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1373 status
= NtOpenFile( &pipe_dev
, FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1374 &iosb
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1375 FILE_SYNCHRONOUS_IO_NONALERT
);
1376 if (status
!= STATUS_SUCCESS
)
1378 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1379 RtlFreeUnicodeString( &nt_name
);
1380 SetLastError( ERROR_PATH_NOT_FOUND
);
1384 pipe_wait
->TimeoutSpecified
= !(timeout
== NMPWAIT_USE_DEFAULT_WAIT
);
1385 if (timeout
== NMPWAIT_WAIT_FOREVER
)
1386 pipe_wait
->Timeout
.QuadPart
= ((ULONGLONG
)0x7fffffff << 32) | 0xffffffff;
1388 pipe_wait
->Timeout
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1389 pipe_wait
->NameLength
= nt_name
.Length
- sizeof(leadin
);
1390 memcpy( pipe_wait
->Name
, nt_name
.Buffer
+ ARRAY_SIZE( leadin
), pipe_wait
->NameLength
);
1391 RtlFreeUnicodeString( &nt_name
);
1393 status
= NtFsControlFile( pipe_dev
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_WAIT
,
1394 pipe_wait
, wait_size
, NULL
, 0 );
1396 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1397 NtClose( pipe_dev
);
1398 return set_ntstatus( status
);
1403 /***********************************************************************
1404 * Interlocked functions
1405 ***********************************************************************/
1408 /***********************************************************************
1409 * InitOnceBeginInitialize (kernelbase.@)
1411 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceBeginInitialize( INIT_ONCE
*once
, DWORD flags
,
1412 BOOL
*pending
, void **context
)
1414 NTSTATUS status
= RtlRunOnceBeginInitialize( once
, flags
, context
);
1415 if (status
>= 0) *pending
= (status
== STATUS_PENDING
);
1416 else SetLastError( RtlNtStatusToDosError(status
) );
1421 /***********************************************************************
1422 * InitOnceComplete (kernelbase.@)
1424 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceComplete( INIT_ONCE
*once
, DWORD flags
, void *context
)
1426 return set_ntstatus( RtlRunOnceComplete( once
, flags
, context
));
1430 /***********************************************************************
1431 * InitOnceExecuteOnce (kernelbase.@)
1433 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceExecuteOnce( INIT_ONCE
*once
, PINIT_ONCE_FN func
,
1434 void *param
, void **context
)
1436 return !RtlRunOnceExecuteOnce( once
, (PRTL_RUN_ONCE_INIT_FN
)func
, param
, context
);
1441 /***********************************************************************
1442 * InterlockedCompareExchange (kernelbase.@)
1444 __ASM_STDCALL_FUNC(InterlockedCompareExchange
, 12,
1445 "movl 12(%esp),%eax\n\t"
1446 "movl 8(%esp),%ecx\n\t"
1447 "movl 4(%esp),%edx\n\t"
1448 "lock; cmpxchgl %ecx,(%edx)\n\t"
1451 /***********************************************************************
1452 * InterlockedExchange (kernelbase.@)
1454 __ASM_STDCALL_FUNC(InterlockedExchange
, 8,
1455 "movl 8(%esp),%eax\n\t"
1456 "movl 4(%esp),%edx\n\t"
1457 "lock; xchgl %eax,(%edx)\n\t"
1460 /***********************************************************************
1461 * InterlockedExchangeAdd (kernelbase.@)
1463 __ASM_STDCALL_FUNC(InterlockedExchangeAdd
, 8,
1464 "movl 8(%esp),%eax\n\t"
1465 "movl 4(%esp),%edx\n\t"
1466 "lock; xaddl %eax,(%edx)\n\t"
1469 /***********************************************************************
1470 * InterlockedIncrement (kernelbase.@)
1472 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
1473 "movl 4(%esp),%edx\n\t"
1475 "lock; xaddl %eax,(%edx)\n\t"
1479 /***********************************************************************
1480 * InterlockedDecrement (kernelbase.@)
1482 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
1483 "movl 4(%esp),%edx\n\t"
1485 "lock; xaddl %eax,(%edx)\n\t"
1489 #endif /* __i386__ */