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
36 #include "kernelbase.h"
38 #include "wine/exception.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(sync
);
43 static const struct _KUSER_SHARED_DATA
*user_shared_data
= (struct _KUSER_SHARED_DATA
*)0x7ffe0000;
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
)
68 OBJECT_ATTRIBUTES attr
;
69 NTSTATUS status
= STATUS_SUCCESS
;
75 swprintf( buffer
, ARRAY_SIZE(buffer
), L
"\\Sessions\\%u\\BaseNamedObjects",
76 NtCurrentTeb()->Peb
->SessionId
);
77 RtlInitUnicodeString( &str
, buffer
);
78 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
79 status
= NtOpenDirectoryObject( &dir
, DIRECTORY_CREATE_OBJECT
|DIRECTORY_TRAVERSE
, &attr
);
80 if (!status
&& InterlockedCompareExchangePointer( &handle
, dir
, 0 ) != 0)
82 /* someone beat us here... */
90 static void get_create_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
91 SECURITY_ATTRIBUTES
*sa
, const WCHAR
*name
)
93 attr
->Length
= sizeof(*attr
);
94 attr
->RootDirectory
= 0;
95 attr
->ObjectName
= NULL
;
96 attr
->Attributes
= OBJ_OPENIF
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
97 attr
->SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
98 attr
->SecurityQualityOfService
= NULL
;
101 RtlInitUnicodeString( nameW
, name
);
102 attr
->ObjectName
= nameW
;
103 BaseGetNamedObjectDirectory( &attr
->RootDirectory
);
107 static BOOL
get_open_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
108 BOOL inherit
, const WCHAR
*name
)
114 SetLastError( ERROR_INVALID_PARAMETER
);
117 RtlInitUnicodeString( nameW
, name
);
118 BaseGetNamedObjectDirectory( &dir
);
119 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
124 /***********************************************************************
126 ***********************************************************************/
129 /*********************************************************************
130 * GetSystemTimes (kernelbase.@)
132 BOOL WINAPI DECLSPEC_HOTPATCH
GetSystemTimes( FILETIME
*idle
, FILETIME
*kernel
, FILETIME
*user
)
134 LARGE_INTEGER idle_time
, kernel_time
, user_time
;
135 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
*info
;
137 DWORD i
, cpus
= NtCurrentTeb()->Peb
->NumberOfProcessors
;
139 if (!(info
= HeapAlloc( GetProcessHeap(), 0, sizeof(*info
) * cpus
)))
141 SetLastError( ERROR_OUTOFMEMORY
);
144 if (!set_ntstatus( NtQuerySystemInformation( SystemProcessorPerformanceInformation
, info
,
145 sizeof(*info
) * cpus
, &ret_size
)))
147 HeapFree( GetProcessHeap(), 0, info
);
150 idle_time
.QuadPart
= 0;
151 kernel_time
.QuadPart
= 0;
152 user_time
.QuadPart
= 0;
153 for (i
= 0; i
< cpus
; i
++)
155 idle_time
.QuadPart
+= info
[i
].IdleTime
.QuadPart
;
156 kernel_time
.QuadPart
+= info
[i
].KernelTime
.QuadPart
;
157 user_time
.QuadPart
+= info
[i
].UserTime
.QuadPart
;
161 idle
->dwLowDateTime
= idle_time
.u
.LowPart
;
162 idle
->dwHighDateTime
= idle_time
.u
.HighPart
;
166 kernel
->dwLowDateTime
= kernel_time
.u
.LowPart
;
167 kernel
->dwHighDateTime
= kernel_time
.u
.HighPart
;
171 user
->dwLowDateTime
= user_time
.u
.LowPart
;
172 user
->dwHighDateTime
= user_time
.u
.HighPart
;
174 HeapFree( GetProcessHeap(), 0, info
);
179 /******************************************************************************
180 * GetTickCount (kernelbase.@)
182 ULONG WINAPI DECLSPEC_HOTPATCH
GetTickCount(void)
184 /* note: we ignore TickCountMultiplier */
185 return user_shared_data
->TickCount
.LowPart
;
189 /******************************************************************************
190 * GetTickCount64 (kernelbase.@)
192 ULONGLONG WINAPI DECLSPEC_HOTPATCH
GetTickCount64(void)
198 high
= user_shared_data
->TickCount
.High1Time
;
199 low
= user_shared_data
->TickCount
.LowPart
;
201 while (high
!= user_shared_data
->TickCount
.High2Time
);
202 /* note: we ignore TickCountMultiplier */
203 return (ULONGLONG
)high
<< 32 | low
;
207 /******************************************************************************
208 * QueryInterruptTime (kernelbase.@)
210 void WINAPI DECLSPEC_HOTPATCH
QueryInterruptTime( ULONGLONG
*time
)
216 high
= user_shared_data
->InterruptTime
.High1Time
;
217 low
= user_shared_data
->InterruptTime
.LowPart
;
219 while (high
!= user_shared_data
->InterruptTime
.High2Time
);
220 *time
= (ULONGLONG
)high
<< 32 | low
;
224 /******************************************************************************
225 * QueryInterruptTimePrecise (kernelbase.@)
227 void WINAPI DECLSPEC_HOTPATCH
QueryInterruptTimePrecise( ULONGLONG
*time
)
230 if (!once
++) FIXME( "(%p) semi-stub\n", time
);
232 QueryInterruptTime( time
);
236 /***********************************************************************
237 * QueryUnbiasedInterruptTimePrecise (kernelbase.@)
239 void WINAPI DECLSPEC_HOTPATCH
QueryUnbiasedInterruptTimePrecise( ULONGLONG
*time
)
242 if (!once
++) FIXME( "(%p): semi-stub.\n", time
);
244 RtlQueryUnbiasedInterruptTime( time
);
248 /***********************************************************************
250 ***********************************************************************/
253 static HANDLE
normalize_std_handle( HANDLE handle
)
255 if ((handle
== (HANDLE
)STD_INPUT_HANDLE
) ||
256 (handle
== (HANDLE
)STD_OUTPUT_HANDLE
) ||
257 (handle
== (HANDLE
)STD_ERROR_HANDLE
))
258 return GetStdHandle( HandleToULong(handle
) );
264 /***********************************************************************
265 * RegisterWaitForSingleObjectEx (kernelbase.@)
267 HANDLE WINAPI DECLSPEC_HOTPATCH
RegisterWaitForSingleObjectEx( HANDLE handle
, WAITORTIMERCALLBACK callback
,
268 PVOID context
, ULONG timeout
, ULONG flags
)
272 TRACE( "%p %p %p %ld %ld\n", handle
, callback
, context
, timeout
, flags
);
274 handle
= normalize_std_handle( handle
);
275 if (!set_ntstatus( RtlRegisterWait( &ret
, handle
, callback
, context
, timeout
, flags
))) return NULL
;
280 /***********************************************************************
281 * SignalObjectAndWait (kernelbase.@)
283 DWORD WINAPI DECLSPEC_HOTPATCH
SignalObjectAndWait( HANDLE signal
, HANDLE wait
,
284 DWORD timeout
, BOOL alertable
)
289 TRACE( "%p %p %ld %d\n", signal
, wait
, timeout
, alertable
);
291 status
= NtSignalAndWaitForSingleObject( signal
, wait
, alertable
, get_nt_timeout( &time
, timeout
) );
294 SetLastError( RtlNtStatusToDosError(status
) );
295 status
= WAIT_FAILED
;
301 /***********************************************************************
302 * Sleep (kernelbase.@)
304 void WINAPI DECLSPEC_HOTPATCH
Sleep( DWORD timeout
)
308 NtDelayExecution( FALSE
, get_nt_timeout( &time
, timeout
) );
312 /******************************************************************************
313 * SleepEx (kernelbase.@)
315 DWORD WINAPI DECLSPEC_HOTPATCH
SleepEx( DWORD timeout
, BOOL alertable
)
320 status
= NtDelayExecution( alertable
, get_nt_timeout( &time
, timeout
) );
321 if (status
== STATUS_USER_APC
) return WAIT_IO_COMPLETION
;
326 /***********************************************************************
327 * UnregisterWaitEx (kernelbase.@)
329 BOOL WINAPI DECLSPEC_HOTPATCH
UnregisterWaitEx( HANDLE handle
, HANDLE event
)
331 return set_ntstatus( RtlDeregisterWaitEx( handle
, event
));
335 /***********************************************************************
336 * WaitForSingleObject (kernelbase.@)
338 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
340 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
344 /***********************************************************************
345 * WaitForSingleObjectEx (kernelbase.@)
347 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
, BOOL alertable
)
349 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
353 /***********************************************************************
354 * WaitForMultipleObjects (kernelbase.@)
356 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
357 BOOL wait_all
, DWORD timeout
)
359 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
363 /***********************************************************************
364 * WaitForMultipleObjectsEx (kernelbase.@)
366 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
367 BOOL wait_all
, DWORD timeout
, BOOL alertable
)
370 HANDLE hloc
[MAXIMUM_WAIT_OBJECTS
];
374 if (count
> MAXIMUM_WAIT_OBJECTS
)
376 SetLastError(ERROR_INVALID_PARAMETER
);
379 for (i
= 0; i
< count
; i
++) hloc
[i
] = normalize_std_handle( handles
[i
] );
381 status
= NtWaitForMultipleObjects( count
, hloc
, !wait_all
, alertable
,
382 get_nt_timeout( &time
, timeout
) );
383 if (HIWORD(status
)) /* is it an error code? */
385 SetLastError( RtlNtStatusToDosError(status
) );
386 status
= WAIT_FAILED
;
392 /******************************************************************************
393 * WaitForDebugEvent (kernelbase.@)
395 BOOL WINAPI DECLSPEC_HOTPATCH
WaitForDebugEvent( DEBUG_EVENT
*event
, DWORD timeout
)
399 DBGUI_WAIT_STATE_CHANGE state
;
403 status
= DbgUiWaitStateChange( &state
, get_nt_timeout( &time
, timeout
) );
407 DbgUiConvertStateChangeStructure( &state
, event
);
409 case STATUS_USER_APC
:
412 SetLastError( ERROR_SEM_TIMEOUT
);
415 return set_ntstatus( status
);
421 /***********************************************************************
422 * WaitOnAddress (kernelbase.@)
424 BOOL WINAPI DECLSPEC_HOTPATCH
WaitOnAddress( volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
428 if (timeout
!= INFINITE
)
430 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
431 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, &to
));
433 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, NULL
));
437 /***********************************************************************
439 ***********************************************************************/
442 /***********************************************************************
443 * CreateEventA (kernelbase.@)
445 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
446 BOOL initial_state
, LPCSTR name
)
450 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
451 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
452 return CreateEventExA( sa
, name
, flags
, EVENT_ALL_ACCESS
);
456 /***********************************************************************
457 * CreateEventW (kernelbase.@)
459 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventW( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
460 BOOL initial_state
, LPCWSTR name
)
464 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
465 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
466 return CreateEventExW( sa
, name
, flags
, EVENT_ALL_ACCESS
);
470 /***********************************************************************
471 * CreateEventExA (kernelbase.@)
473 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
474 DWORD flags
, DWORD access
)
476 WCHAR buffer
[MAX_PATH
];
478 if (!name
) return CreateEventExW( sa
, NULL
, flags
, access
);
480 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
482 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
485 return CreateEventExW( sa
, buffer
, flags
, access
);
489 /***********************************************************************
490 * CreateEventExW (kernelbase.@)
492 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
493 DWORD flags
, DWORD access
)
496 UNICODE_STRING nameW
;
497 OBJECT_ATTRIBUTES attr
;
500 /* one buggy program needs this
501 * ("Van Dale Groot woordenboek der Nederlandse taal")
505 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
509 SetLastError( ERROR_INVALID_PARAMETER
);
514 status
= NtCreateEvent( &ret
, access
, &attr
,
515 (flags
& CREATE_EVENT_MANUAL_RESET
) ? NotificationEvent
: SynchronizationEvent
,
516 (flags
& CREATE_EVENT_INITIAL_SET
) != 0 );
517 if (status
== STATUS_OBJECT_NAME_EXISTS
)
518 SetLastError( ERROR_ALREADY_EXISTS
);
520 SetLastError( RtlNtStatusToDosError(status
) );
525 /***********************************************************************
526 * OpenEventA (kernelbase.@)
528 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventA( DWORD access
, BOOL inherit
, LPCSTR name
)
530 WCHAR buffer
[MAX_PATH
];
532 if (!name
) return OpenEventW( access
, inherit
, NULL
);
534 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
536 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
539 return OpenEventW( access
, inherit
, buffer
);
543 /***********************************************************************
544 * OpenEventW (kernelbase.@)
546 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
549 UNICODE_STRING nameW
;
550 OBJECT_ATTRIBUTES attr
;
552 if (!is_version_nt()) access
= EVENT_ALL_ACCESS
;
554 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
556 if (!set_ntstatus( NtOpenEvent( &ret
, access
, &attr
))) return 0;
560 /***********************************************************************
561 * PulseEvent (kernelbase.@)
563 BOOL WINAPI DECLSPEC_HOTPATCH
PulseEvent( HANDLE handle
)
565 return set_ntstatus( NtPulseEvent( handle
, NULL
));
569 /***********************************************************************
570 * SetEvent (kernelbase.@)
572 BOOL WINAPI DECLSPEC_HOTPATCH
SetEvent( HANDLE handle
)
574 return set_ntstatus( NtSetEvent( handle
, NULL
));
578 /***********************************************************************
579 * ResetEvent (kernelbase.@)
581 BOOL WINAPI DECLSPEC_HOTPATCH
ResetEvent( HANDLE handle
)
583 return set_ntstatus( NtResetEvent( handle
, NULL
));
587 /***********************************************************************
589 ***********************************************************************/
592 /***********************************************************************
593 * CreateMutexA (kernelbase.@)
595 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexA( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCSTR name
)
597 return CreateMutexExA( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
601 /***********************************************************************
602 * CreateMutexW (kernelbase.@)
604 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexW( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCWSTR name
)
606 return CreateMutexExW( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
610 /***********************************************************************
611 * CreateMutexExA (kernelbase.@)
613 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
614 DWORD flags
, DWORD access
)
619 if (!name
) return CreateMutexExW( sa
, NULL
, flags
, access
);
621 RtlInitAnsiString( &nameA
, name
);
622 status
= RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString
, &nameA
, FALSE
);
623 if (status
!= STATUS_SUCCESS
)
625 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
628 return CreateMutexExW( sa
, NtCurrentTeb()->StaticUnicodeString
.Buffer
, flags
, access
);
632 /***********************************************************************
633 * CreateMutexExW (kernelbase.@)
635 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
636 DWORD flags
, DWORD access
)
639 UNICODE_STRING nameW
;
640 OBJECT_ATTRIBUTES attr
;
643 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
645 status
= NtCreateMutant( &ret
, access
, &attr
, (flags
& CREATE_MUTEX_INITIAL_OWNER
) != 0 );
646 if (status
== STATUS_OBJECT_NAME_EXISTS
)
647 SetLastError( ERROR_ALREADY_EXISTS
);
649 SetLastError( RtlNtStatusToDosError(status
) );
654 /***********************************************************************
655 * OpenMutexW (kernelbase.@)
657 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
660 UNICODE_STRING nameW
;
661 OBJECT_ATTRIBUTES attr
;
663 if (!is_version_nt()) access
= MUTEX_ALL_ACCESS
;
665 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
667 if (!set_ntstatus( NtOpenMutant( &ret
, access
, &attr
))) return 0;
672 /***********************************************************************
673 * ReleaseMutex (kernelbase.@)
675 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseMutex( HANDLE handle
)
677 return set_ntstatus( NtReleaseMutant( handle
, NULL
));
681 /***********************************************************************
683 ***********************************************************************/
686 /***********************************************************************
687 * CreateSemaphoreW (kernelbase.@)
689 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreW( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
690 LONG max
, LPCWSTR name
)
692 return CreateSemaphoreExW( sa
, initial
, max
, name
, 0, SEMAPHORE_ALL_ACCESS
);
696 /***********************************************************************
697 * CreateSemaphoreExW (kernelbase.@)
699 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreExW( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
,
700 LPCWSTR name
, DWORD flags
, DWORD access
)
703 UNICODE_STRING nameW
;
704 OBJECT_ATTRIBUTES attr
;
707 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
709 status
= NtCreateSemaphore( &ret
, access
, &attr
, initial
, max
);
710 if (status
== STATUS_OBJECT_NAME_EXISTS
)
711 SetLastError( ERROR_ALREADY_EXISTS
);
713 SetLastError( RtlNtStatusToDosError(status
) );
718 /***********************************************************************
719 * OpenSemaphoreW (kernelbase.@)
721 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
724 UNICODE_STRING nameW
;
725 OBJECT_ATTRIBUTES attr
;
727 if (!is_version_nt()) access
= SEMAPHORE_ALL_ACCESS
;
729 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
731 if (!set_ntstatus( NtOpenSemaphore( &ret
, access
, &attr
))) return 0;
736 /***********************************************************************
737 * ReleaseSemaphore (kernelbase.@)
739 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseSemaphore( HANDLE handle
, LONG count
, LONG
*previous
)
741 return set_ntstatus( NtReleaseSemaphore( handle
, count
, (PULONG
)previous
));
745 /***********************************************************************
747 ***********************************************************************/
750 /***********************************************************************
751 * CreateWaitableTimerW (kernelbase.@)
753 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerW( SECURITY_ATTRIBUTES
*sa
, BOOL manual
, LPCWSTR name
)
755 return CreateWaitableTimerExW( sa
, name
, manual
? CREATE_WAITABLE_TIMER_MANUAL_RESET
: 0,
760 /***********************************************************************
761 * CreateWaitableTimerExW (kernelbase.@)
763 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
764 DWORD flags
, DWORD access
)
768 UNICODE_STRING nameW
;
769 OBJECT_ATTRIBUTES attr
;
771 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
773 status
= NtCreateTimer( &handle
, access
, &attr
,
774 (flags
& CREATE_WAITABLE_TIMER_MANUAL_RESET
) ? NotificationTimer
: SynchronizationTimer
);
775 if (status
== STATUS_OBJECT_NAME_EXISTS
)
776 SetLastError( ERROR_ALREADY_EXISTS
);
778 SetLastError( RtlNtStatusToDosError(status
) );
783 /***********************************************************************
784 * OpenWaitableTimerW (kernelbase.@)
786 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenWaitableTimerW( DWORD access
, BOOL inherit
, LPCWSTR name
)
789 UNICODE_STRING nameW
;
790 OBJECT_ATTRIBUTES attr
;
792 if (!is_version_nt()) access
= TIMER_ALL_ACCESS
;
794 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
796 if (!set_ntstatus( NtOpenTimer( &handle
, access
, &attr
))) return 0;
801 /***********************************************************************
802 * SetWaitableTimer (kernelbase.@)
804 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimer( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
805 PTIMERAPCROUTINE callback
, LPVOID arg
, BOOL resume
)
807 NTSTATUS status
= NtSetTimer( handle
, when
, (PTIMER_APC_ROUTINE
)callback
,
808 arg
, resume
, period
, NULL
);
809 return set_ntstatus( status
) || status
== STATUS_TIMER_RESUME_IGNORED
;
813 /***********************************************************************
814 * SetWaitableTimerEx (kernelbase.@)
816 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimerEx( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
817 PTIMERAPCROUTINE callback
, LPVOID arg
,
818 REASON_CONTEXT
*context
, ULONG tolerabledelay
)
821 if (!once
++) FIXME( "(%p, %p, %ld, %p, %p, %p, %ld) semi-stub\n",
822 handle
, when
, period
, callback
, arg
, context
, tolerabledelay
);
824 return SetWaitableTimer( handle
, when
, period
, callback
, arg
, FALSE
);
828 /***********************************************************************
829 * CancelWaitableTimer (kernelbase.@)
831 BOOL WINAPI DECLSPEC_HOTPATCH
CancelWaitableTimer( HANDLE handle
)
833 return set_ntstatus( NtCancelTimer( handle
, NULL
));
837 /***********************************************************************
839 ***********************************************************************/
842 /***********************************************************************
843 * CreateTimerQueue (kernelbase.@)
845 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateTimerQueue(void)
849 if (!set_ntstatus( RtlCreateTimerQueue( &q
))) return NULL
;
854 /***********************************************************************
855 * CreateTimerQueueTimer (kernelbase.@)
857 BOOL WINAPI DECLSPEC_HOTPATCH
CreateTimerQueueTimer( PHANDLE timer
, HANDLE queue
,
858 WAITORTIMERCALLBACK callback
, PVOID arg
,
859 DWORD when
, DWORD period
, ULONG flags
)
861 return set_ntstatus( RtlCreateTimer( queue
, timer
, callback
, arg
, when
, period
, flags
));
865 /***********************************************************************
866 * ChangeTimerQueueTimer (kernelbase.@)
868 BOOL WINAPI DECLSPEC_HOTPATCH
ChangeTimerQueueTimer( HANDLE queue
, HANDLE timer
,
869 ULONG when
, ULONG period
)
871 return set_ntstatus( RtlUpdateTimer( queue
, timer
, when
, period
));
875 /***********************************************************************
876 * DeleteTimerQueueEx (kernelbase.@)
878 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueEx( HANDLE queue
, HANDLE event
)
880 return set_ntstatus( RtlDeleteTimerQueueEx( queue
, event
));
884 /***********************************************************************
885 * DeleteTimerQueueTimer (kernelbase.@)
887 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueTimer( HANDLE queue
, HANDLE timer
, HANDLE event
)
889 return set_ntstatus( RtlDeleteTimer( queue
, timer
, event
));
893 /***********************************************************************
895 ***********************************************************************/
898 /***********************************************************************
899 * InitializeCriticalSectionAndSpinCount (kernelbase.@)
901 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION
*crit
, DWORD count
)
903 return !RtlInitializeCriticalSectionAndSpinCount( crit
, count
);
906 /***********************************************************************
907 * InitializeCriticalSectionEx (kernelbase.@)
909 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionEx( CRITICAL_SECTION
*crit
, DWORD spincount
,
912 NTSTATUS ret
= RtlInitializeCriticalSectionEx( crit
, spincount
, flags
);
913 if (ret
) RtlRaiseStatus( ret
);
918 /***********************************************************************
920 ***********************************************************************/
922 /***********************************************************************
923 * CreateFileMappingW (kernelbase.@)
925 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingW( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, DWORD protect
,
926 DWORD size_high
, DWORD size_low
, LPCWSTR name
)
928 static const int sec_flags
= (SEC_FILE
| SEC_IMAGE
| SEC_RESERVE
| SEC_COMMIT
|
929 SEC_NOCACHE
| SEC_WRITECOMBINE
| SEC_LARGE_PAGES
);
932 DWORD access
, sec_type
;
934 UNICODE_STRING nameW
;
935 OBJECT_ATTRIBUTES attr
;
937 sec_type
= protect
& sec_flags
;
938 protect
&= ~sec_flags
;
939 if (!sec_type
) sec_type
= SEC_COMMIT
;
941 /* Win9x compatibility */
942 if (!protect
&& !is_version_nt()) protect
= PAGE_READONLY
;
948 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
951 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
;
953 case PAGE_EXECUTE_READ
:
954 case PAGE_EXECUTE_WRITECOPY
:
955 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_EXECUTE
;
957 case PAGE_EXECUTE_READWRITE
:
958 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
;
961 SetLastError( ERROR_INVALID_PARAMETER
);
965 size
.u
.LowPart
= size_low
;
966 size
.u
.HighPart
= size_high
;
968 if (file
== INVALID_HANDLE_VALUE
)
973 SetLastError( ERROR_INVALID_PARAMETER
);
978 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
980 status
= NtCreateSection( &ret
, access
, &attr
, &size
, protect
, sec_type
, file
);
981 if (status
== STATUS_OBJECT_NAME_EXISTS
)
982 SetLastError( ERROR_ALREADY_EXISTS
);
984 SetLastError( RtlNtStatusToDosError(status
) );
989 /***********************************************************************
990 * CreateFileMappingFromApp (kernelbase.@)
992 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingFromApp( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, ULONG protect
,
993 ULONG64 size
, LPCWSTR name
)
995 return CreateFileMappingW( file
, sa
, protect
, size
<< 32, size
, name
);
998 /***********************************************************************
999 * OpenFileMappingW (kernelbase.@)
1001 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingW( DWORD access
, BOOL inherit
, LPCWSTR name
)
1003 OBJECT_ATTRIBUTES attr
;
1004 UNICODE_STRING nameW
;
1007 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
1009 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
1011 if (!is_version_nt())
1013 /* win9x doesn't do access checks, so try with full access first */
1014 if (!NtOpenSection( &ret
, access
| SECTION_MAP_READ
| SECTION_MAP_WRITE
, &attr
)) return ret
;
1017 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
1022 /***********************************************************************
1023 * OpenFileMappingFromApp (kernelbase.@)
1025 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingFromApp( ULONG access
, BOOL inherit
, LPCWSTR name
)
1027 OBJECT_ATTRIBUTES attr
;
1028 UNICODE_STRING nameW
;
1031 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
1033 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
1035 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
1040 /***********************************************************************
1041 * Condition variables
1042 ***********************************************************************/
1045 /***********************************************************************
1046 * SleepConditionVariableCS (kernelbase.@)
1048 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableCS( CONDITION_VARIABLE
*variable
,
1049 CRITICAL_SECTION
*crit
, DWORD timeout
)
1053 return set_ntstatus( RtlSleepConditionVariableCS( variable
, crit
, get_nt_timeout( &time
, timeout
)));
1057 /***********************************************************************
1058 * SleepConditionVariableSRW (kernelbase.@)
1060 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableSRW( RTL_CONDITION_VARIABLE
*variable
,
1061 RTL_SRWLOCK
*lock
, DWORD timeout
, ULONG flags
)
1065 return set_ntstatus( RtlSleepConditionVariableSRW( variable
, lock
,
1066 get_nt_timeout( &time
, timeout
), flags
));
1070 /***********************************************************************
1072 ***********************************************************************/
1075 /******************************************************************************
1076 * CreateIoCompletionPort (kernelbase.@)
1078 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateIoCompletionPort( HANDLE handle
, HANDLE port
,
1079 ULONG_PTR key
, DWORD threads
)
1081 FILE_COMPLETION_INFORMATION info
;
1082 IO_STATUS_BLOCK iosb
;
1085 TRACE( "(%p, %p, %08Ix, %08lx)\n", handle
, port
, key
, threads
);
1089 if (!set_ntstatus( NtCreateIoCompletion( &ret
, IO_COMPLETION_ALL_ACCESS
, NULL
, threads
)))
1092 else if (handle
== INVALID_HANDLE_VALUE
)
1094 SetLastError( ERROR_INVALID_PARAMETER
);
1098 if (handle
!= INVALID_HANDLE_VALUE
)
1100 info
.CompletionPort
= ret
;
1101 info
.CompletionKey
= key
;
1102 if (!set_ntstatus( NtSetInformationFile( handle
, &iosb
, &info
, sizeof(info
), FileCompletionInformation
)))
1104 if (!port
) CloseHandle( ret
);
1112 /******************************************************************************
1113 * GetQueuedCompletionStatus (kernelbase.@)
1115 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatus( HANDLE port
, LPDWORD count
, PULONG_PTR key
,
1116 LPOVERLAPPED
*overlapped
, DWORD timeout
)
1119 IO_STATUS_BLOCK iosb
;
1120 LARGE_INTEGER wait_time
;
1122 TRACE( "(%p,%p,%p,%p,%ld)\n", port
, count
, key
, overlapped
, timeout
);
1125 status
= NtRemoveIoCompletion( port
, key
, (PULONG_PTR
)overlapped
, &iosb
,
1126 get_nt_timeout( &wait_time
, timeout
) );
1127 if (status
== STATUS_SUCCESS
)
1129 *count
= iosb
.Information
;
1130 if (iosb
.Status
>= 0) return TRUE
;
1131 SetLastError( RtlNtStatusToDosError(iosb
.Status
) );
1135 if (status
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1136 else SetLastError( RtlNtStatusToDosError(status
) );
1140 /******************************************************************************
1141 * GetQueuedCompletionStatusEx (kernelbase.@)
1143 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatusEx( HANDLE port
, OVERLAPPED_ENTRY
*entries
,
1144 ULONG count
, ULONG
*written
,
1145 DWORD timeout
, BOOL alertable
)
1150 TRACE( "%p %p %lu %p %lu %u\n", port
, entries
, count
, written
, timeout
, alertable
);
1152 ret
= NtRemoveIoCompletionEx( port
, (FILE_IO_COMPLETION_INFORMATION
*)entries
, count
,
1153 written
, get_nt_timeout( &time
, timeout
), alertable
);
1154 if (ret
== STATUS_SUCCESS
) return TRUE
;
1155 else if (ret
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1156 else if (ret
== STATUS_USER_APC
) SetLastError( WAIT_IO_COMPLETION
);
1157 else SetLastError( RtlNtStatusToDosError(ret
) );
1162 /******************************************************************************
1163 * PostQueuedCompletionStatus (kernelbase.@)
1165 BOOL WINAPI DECLSPEC_HOTPATCH
PostQueuedCompletionStatus( HANDLE port
, DWORD count
,
1166 ULONG_PTR key
, LPOVERLAPPED overlapped
)
1168 TRACE( "%p %ld %08Ix %p\n", port
, count
, key
, overlapped
);
1170 return set_ntstatus( NtSetIoCompletion( port
, key
, (ULONG_PTR
)overlapped
, STATUS_SUCCESS
, count
));
1174 /***********************************************************************
1176 ***********************************************************************/
1179 /***********************************************************************
1180 * CallNamedPipeW (kernelbase.@)
1182 BOOL WINAPI DECLSPEC_HOTPATCH
CallNamedPipeW( LPCWSTR name
, LPVOID input
, DWORD in_size
,
1183 LPVOID output
, DWORD out_size
,
1184 LPDWORD read_size
, DWORD timeout
)
1190 TRACE( "%s %p %ld %p %ld %p %ld\n", debugstr_w(name
),
1191 input
, in_size
, output
, out_size
, read_size
, timeout
);
1193 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1194 if (pipe
== INVALID_HANDLE_VALUE
)
1196 if (!WaitNamedPipeW( name
, timeout
)) return FALSE
;
1197 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1198 if (pipe
== INVALID_HANDLE_VALUE
) return FALSE
;
1201 mode
= PIPE_READMODE_MESSAGE
;
1202 ret
= SetNamedPipeHandleState( pipe
, &mode
, NULL
, NULL
);
1203 if (ret
) ret
= TransactNamedPipe( pipe
, input
, in_size
, output
, out_size
, read_size
, NULL
);
1204 CloseHandle( pipe
);
1209 /***********************************************************************
1210 * ConnectNamedPipe (kernelbase.@)
1212 BOOL WINAPI DECLSPEC_HOTPATCH
ConnectNamedPipe( HANDLE pipe
, LPOVERLAPPED overlapped
)
1215 IO_STATUS_BLOCK status_block
;
1216 LPVOID cvalue
= NULL
;
1218 TRACE( "(%p,%p)\n", pipe
, overlapped
);
1222 overlapped
->Internal
= STATUS_PENDING
;
1223 overlapped
->InternalHigh
= 0;
1224 if (((ULONG_PTR
)overlapped
->hEvent
& 1) == 0) cvalue
= overlapped
;
1227 status
= NtFsControlFile( pipe
, overlapped
? overlapped
->hEvent
: NULL
, NULL
, cvalue
,
1228 overlapped
? (IO_STATUS_BLOCK
*)overlapped
: &status_block
,
1229 FSCTL_PIPE_LISTEN
, NULL
, 0, NULL
, 0 );
1230 if (status
== STATUS_PENDING
&& !overlapped
)
1232 WaitForSingleObject( pipe
, INFINITE
);
1233 status
= status_block
.Status
;
1235 return set_ntstatus( status
);
1238 /***********************************************************************
1239 * CreateNamedPipeW (kernelbase.@)
1241 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateNamedPipeW( LPCWSTR name
, DWORD open_mode
, DWORD pipe_mode
,
1242 DWORD instances
, DWORD out_buff
, DWORD in_buff
,
1243 DWORD timeout
, LPSECURITY_ATTRIBUTES sa
)
1246 UNICODE_STRING nt_name
;
1247 OBJECT_ATTRIBUTES attr
;
1248 DWORD access
, options
, sharing
;
1249 BOOLEAN pipe_type
, read_mode
, non_block
;
1251 IO_STATUS_BLOCK iosb
;
1254 TRACE( "(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n", debugstr_w(name
),
1255 open_mode
, pipe_mode
, instances
, out_buff
, in_buff
, timeout
, sa
);
1257 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
))
1259 SetLastError( ERROR_PATH_NOT_FOUND
);
1260 return INVALID_HANDLE_VALUE
;
1262 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) )
1264 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
1265 RtlFreeUnicodeString( &nt_name
);
1266 return INVALID_HANDLE_VALUE
;
1269 attr
.Length
= sizeof(attr
);
1270 attr
.RootDirectory
= 0;
1271 attr
.ObjectName
= &nt_name
;
1272 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1273 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1274 attr
.SecurityQualityOfService
= NULL
;
1276 switch (open_mode
& 3)
1278 case PIPE_ACCESS_INBOUND
:
1279 sharing
= FILE_SHARE_WRITE
;
1280 access
= GENERIC_READ
;
1282 case PIPE_ACCESS_OUTBOUND
:
1283 sharing
= FILE_SHARE_READ
;
1284 access
= GENERIC_WRITE
;
1286 case PIPE_ACCESS_DUPLEX
:
1287 sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
1288 access
= GENERIC_READ
| GENERIC_WRITE
;
1291 SetLastError( ERROR_INVALID_PARAMETER
);
1292 return INVALID_HANDLE_VALUE
;
1294 access
|= SYNCHRONIZE
;
1296 if (open_mode
& WRITE_DAC
) access
|= WRITE_DAC
;
1297 if (open_mode
& WRITE_OWNER
) access
|= WRITE_OWNER
;
1298 if (open_mode
& ACCESS_SYSTEM_SECURITY
) access
|= ACCESS_SYSTEM_SECURITY
;
1299 if (open_mode
& FILE_FLAG_WRITE_THROUGH
) options
|= FILE_WRITE_THROUGH
;
1300 if (!(open_mode
& FILE_FLAG_OVERLAPPED
)) options
|= FILE_SYNCHRONOUS_IO_NONALERT
;
1301 pipe_type
= (pipe_mode
& PIPE_TYPE_MESSAGE
) != 0;
1302 read_mode
= (pipe_mode
& PIPE_READMODE_MESSAGE
) != 0;
1303 non_block
= (pipe_mode
& PIPE_NOWAIT
) != 0;
1304 if (instances
>= PIPE_UNLIMITED_INSTANCES
) instances
= ~0U;
1306 time
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1307 status
= NtCreateNamedPipeFile( &handle
, access
, &attr
, &iosb
, sharing
,
1308 FILE_OPEN_IF
, options
, pipe_type
,
1309 read_mode
, non_block
, instances
, in_buff
, out_buff
, &time
);
1310 RtlFreeUnicodeString( &nt_name
);
1311 if (!set_ntstatus( status
)) return INVALID_HANDLE_VALUE
;
1312 SetLastError( iosb
.Information
== FILE_CREATED
? ERROR_SUCCESS
: ERROR_ALREADY_EXISTS
);
1317 /******************************************************************
1318 * CreatePipe (kernelbase.@)
1320 BOOL WINAPI DECLSPEC_HOTPATCH
CreatePipe( HANDLE
*read_pipe
, HANDLE
*write_pipe
,
1321 SECURITY_ATTRIBUTES
*sa
, DWORD size
)
1323 static unsigned int index
;
1325 UNICODE_STRING nt_name
;
1326 OBJECT_ATTRIBUTES attr
;
1327 IO_STATUS_BLOCK iosb
;
1328 LARGE_INTEGER timeout
;
1330 *read_pipe
= *write_pipe
= INVALID_HANDLE_VALUE
;
1332 attr
.Length
= sizeof(attr
);
1333 attr
.RootDirectory
= 0;
1334 attr
.ObjectName
= &nt_name
;
1335 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1336 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1337 attr
.SecurityQualityOfService
= NULL
;
1339 if (!size
) size
= 4096;
1341 timeout
.QuadPart
= (ULONGLONG
)NMPWAIT_USE_DEFAULT_WAIT
* -10000;
1343 /* generate a unique pipe name (system wide) */
1346 swprintf( name
, ARRAY_SIZE(name
), L
"\\??\\pipe\\Win32.Pipes.%08lu.%08u",
1347 GetCurrentProcessId(), ++index
);
1348 RtlInitUnicodeString( &nt_name
, name
);
1349 if (!NtCreateNamedPipeFile( read_pipe
, GENERIC_READ
| FILE_WRITE_ATTRIBUTES
| SYNCHRONIZE
,
1350 &attr
, &iosb
, FILE_SHARE_WRITE
, FILE_OPEN_IF
,
1351 FILE_SYNCHRONOUS_IO_NONALERT
,
1352 FALSE
, FALSE
, FALSE
, 1, size
, size
, &timeout
))
1355 if (!set_ntstatus( NtOpenFile( write_pipe
, GENERIC_WRITE
| FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1356 &iosb
, 0, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
)))
1358 NtClose( *read_pipe
);
1365 /***********************************************************************
1366 * DisconnectNamedPipe (kernelbase.@)
1368 BOOL WINAPI DECLSPEC_HOTPATCH
DisconnectNamedPipe( HANDLE pipe
)
1370 IO_STATUS_BLOCK io_block
;
1372 TRACE( "(%p)\n", pipe
);
1373 return set_ntstatus( NtFsControlFile( pipe
, 0, NULL
, NULL
, &io_block
,
1374 FSCTL_PIPE_DISCONNECT
, NULL
, 0, NULL
, 0 ));
1378 /***********************************************************************
1379 * GetNamedPipeHandleStateW (kernelbase.@)
1381 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeHandleStateW( HANDLE pipe
, DWORD
*state
, DWORD
*instances
,
1382 DWORD
*max_count
, DWORD
*timeout
,
1383 WCHAR
*user
, DWORD size
)
1387 FIXME( "%p %p %p %p %p %p %ld: semi-stub\n", pipe
, state
, instances
, max_count
, timeout
, user
, size
);
1389 if (max_count
) *max_count
= 0;
1390 if (timeout
) *timeout
= 0;
1391 if (user
&& size
&& !GetEnvironmentVariableW( L
"WINEUSERNAME", user
, size
)) user
[0] = 0;
1395 FILE_PIPE_INFORMATION info
;
1397 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
), FilePipeInformation
)))
1400 *state
= (info
.ReadMode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
) |
1401 (info
.CompletionMode
? PIPE_NOWAIT
: PIPE_WAIT
);
1405 FILE_PIPE_LOCAL_INFORMATION info
;
1407 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
),
1408 FilePipeLocalInformation
)))
1410 *instances
= info
.CurrentInstances
;
1416 /***********************************************************************
1417 * GetNamedPipeInfo (kernelbase.@)
1419 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeInfo( HANDLE pipe
, LPDWORD flags
, LPDWORD out_size
,
1420 LPDWORD in_size
, LPDWORD instances
)
1422 FILE_PIPE_LOCAL_INFORMATION info
;
1423 IO_STATUS_BLOCK iosb
;
1425 if (!set_ntstatus( NtQueryInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeLocalInformation
)))
1430 *flags
= (info
.NamedPipeEnd
& FILE_PIPE_SERVER_END
) ? PIPE_SERVER_END
: PIPE_CLIENT_END
;
1431 *flags
|= (info
.NamedPipeType
& FILE_PIPE_TYPE_MESSAGE
) ? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
;
1433 if (out_size
) *out_size
= info
.OutboundQuota
;
1434 if (in_size
) *in_size
= info
.InboundQuota
;
1435 if (instances
) *instances
= info
.MaximumInstances
;
1440 /***********************************************************************
1441 * PeekNamedPipe (kernelbase.@)
1443 BOOL WINAPI DECLSPEC_HOTPATCH
PeekNamedPipe( HANDLE pipe
, LPVOID out_buffer
, DWORD size
,
1444 LPDWORD read_size
, LPDWORD avail
, LPDWORD message
)
1446 FILE_PIPE_PEEK_BUFFER local_buffer
;
1447 FILE_PIPE_PEEK_BUFFER
*buffer
= &local_buffer
;
1451 if (size
&& !(buffer
= HeapAlloc( GetProcessHeap(), 0,
1452 FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ))))
1454 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1458 status
= NtFsControlFile( pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0,
1459 buffer
, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ) );
1460 if (status
== STATUS_BUFFER_OVERFLOW
) status
= STATUS_SUCCESS
;
1463 ULONG count
= io
.Information
- FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
);
1464 if (avail
) *avail
= buffer
->ReadDataAvailable
;
1465 if (read_size
) *read_size
= count
;
1466 if (message
) *message
= buffer
->MessageLength
- count
;
1467 if (out_buffer
) memcpy( out_buffer
, buffer
->Data
, count
);
1469 else SetLastError( RtlNtStatusToDosError(status
) );
1471 if (buffer
!= &local_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
1476 /***********************************************************************
1477 * SetNamedPipeHandleState (kernelbase.@)
1479 BOOL WINAPI DECLSPEC_HOTPATCH
SetNamedPipeHandleState( HANDLE pipe
, LPDWORD mode
,
1480 LPDWORD count
, LPDWORD timeout
)
1482 FILE_PIPE_INFORMATION info
;
1483 IO_STATUS_BLOCK iosb
;
1484 NTSTATUS status
= STATUS_SUCCESS
;
1486 TRACE( "%p %p/%ld %p %p\n", pipe
, mode
, mode
? *mode
: 0, count
, timeout
);
1487 if (count
|| timeout
) FIXME( "Unsupported arguments\n" );
1491 if (*mode
& ~(PIPE_READMODE_MESSAGE
| PIPE_NOWAIT
)) status
= STATUS_INVALID_PARAMETER
;
1494 info
.CompletionMode
= (*mode
& PIPE_NOWAIT
) ?
1495 FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION
;
1496 info
.ReadMode
= (*mode
& PIPE_READMODE_MESSAGE
) ?
1497 FILE_PIPE_MESSAGE_MODE
: FILE_PIPE_BYTE_STREAM_MODE
;
1498 status
= NtSetInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeInformation
);
1501 return set_ntstatus( status
);
1504 /***********************************************************************
1505 * TransactNamedPipe (kernelbase.@)
1507 BOOL WINAPI DECLSPEC_HOTPATCH
TransactNamedPipe( HANDLE handle
, LPVOID write_buf
, DWORD write_size
,
1508 LPVOID read_buf
, DWORD read_size
, LPDWORD bytes_read
,
1509 LPOVERLAPPED overlapped
)
1511 IO_STATUS_BLOCK default_iosb
, *iosb
= &default_iosb
;
1512 HANDLE event
= NULL
;
1513 void *cvalue
= NULL
;
1516 TRACE( "%p %p %lu %p %lu %p %p\n", handle
,
1517 write_buf
, write_size
, read_buf
, read_size
, bytes_read
, overlapped
);
1521 event
= overlapped
->hEvent
;
1522 iosb
= (IO_STATUS_BLOCK
*)overlapped
;
1523 if (((ULONG_PTR
)event
& 1) == 0) cvalue
= overlapped
;
1527 iosb
->Information
= 0;
1530 status
= NtFsControlFile( handle
, event
, NULL
, cvalue
, iosb
, FSCTL_PIPE_TRANSCEIVE
,
1531 write_buf
, write_size
, read_buf
, read_size
);
1532 if (status
== STATUS_PENDING
&& !overlapped
)
1534 WaitForSingleObject(handle
, INFINITE
);
1535 status
= iosb
->Status
;
1538 if (bytes_read
) *bytes_read
= overlapped
&& status
? 0 : iosb
->Information
;
1539 return set_ntstatus( status
);
1543 /***********************************************************************
1544 * WaitNamedPipeW (kernelbase.@)
1546 BOOL WINAPI DECLSPEC_HOTPATCH
WaitNamedPipeW( LPCWSTR name
, DWORD timeout
)
1548 static const int prefix_len
= sizeof(L
"\\??\\PIPE\\") - sizeof(WCHAR
);
1550 UNICODE_STRING nt_name
, pipe_dev_name
;
1551 FILE_PIPE_WAIT_FOR_BUFFER
*pipe_wait
;
1552 IO_STATUS_BLOCK iosb
;
1553 OBJECT_ATTRIBUTES attr
;
1557 TRACE( "%s 0x%08lx\n", debugstr_w(name
), timeout
);
1559 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
)) return FALSE
;
1561 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) ||
1562 nt_name
.Length
< prefix_len
||
1563 wcsnicmp( nt_name
.Buffer
, L
"\\??\\PIPE\\", prefix_len
/ sizeof(WCHAR
) ))
1565 RtlFreeUnicodeString( &nt_name
);
1566 SetLastError( ERROR_PATH_NOT_FOUND
);
1570 wait_size
= offsetof( FILE_PIPE_WAIT_FOR_BUFFER
, Name
[(nt_name
.Length
- prefix_len
) / sizeof(WCHAR
)] );
1571 if (!(pipe_wait
= HeapAlloc( GetProcessHeap(), 0, wait_size
)))
1573 RtlFreeUnicodeString( &nt_name
);
1574 SetLastError( ERROR_OUTOFMEMORY
);
1578 pipe_dev_name
.Buffer
= nt_name
.Buffer
;
1579 pipe_dev_name
.Length
= prefix_len
;
1580 pipe_dev_name
.MaximumLength
= prefix_len
;
1581 InitializeObjectAttributes( &attr
,&pipe_dev_name
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1582 status
= NtOpenFile( &pipe_dev
, FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1583 &iosb
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1584 FILE_SYNCHRONOUS_IO_NONALERT
);
1585 if (status
!= STATUS_SUCCESS
)
1587 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1588 RtlFreeUnicodeString( &nt_name
);
1589 SetLastError( ERROR_PATH_NOT_FOUND
);
1593 pipe_wait
->TimeoutSpecified
= !(timeout
== NMPWAIT_USE_DEFAULT_WAIT
);
1594 if (timeout
== NMPWAIT_WAIT_FOREVER
)
1595 pipe_wait
->Timeout
.QuadPart
= ((ULONGLONG
)0x7fffffff << 32) | 0xffffffff;
1597 pipe_wait
->Timeout
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1598 pipe_wait
->NameLength
= nt_name
.Length
- prefix_len
;
1599 memcpy( pipe_wait
->Name
, nt_name
.Buffer
+ prefix_len
/sizeof(WCHAR
), pipe_wait
->NameLength
);
1600 RtlFreeUnicodeString( &nt_name
);
1602 status
= NtFsControlFile( pipe_dev
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_WAIT
,
1603 pipe_wait
, wait_size
, NULL
, 0 );
1605 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1606 NtClose( pipe_dev
);
1607 return set_ntstatus( status
);
1612 /***********************************************************************
1613 * Interlocked functions
1614 ***********************************************************************/
1617 /***********************************************************************
1618 * InitOnceBeginInitialize (kernelbase.@)
1620 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceBeginInitialize( INIT_ONCE
*once
, DWORD flags
,
1621 BOOL
*pending
, void **context
)
1623 NTSTATUS status
= RtlRunOnceBeginInitialize( once
, flags
, context
);
1624 if (status
>= 0) *pending
= (status
== STATUS_PENDING
);
1625 else SetLastError( RtlNtStatusToDosError(status
) );
1630 /***********************************************************************
1631 * InitOnceComplete (kernelbase.@)
1633 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceComplete( INIT_ONCE
*once
, DWORD flags
, void *context
)
1635 return set_ntstatus( RtlRunOnceComplete( once
, flags
, context
));
1639 /***********************************************************************
1640 * InitOnceExecuteOnce (kernelbase.@)
1642 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceExecuteOnce( INIT_ONCE
*once
, PINIT_ONCE_FN func
,
1643 void *param
, void **context
)
1645 return !RtlRunOnceExecuteOnce( once
, (PRTL_RUN_ONCE_INIT_FN
)func
, param
, context
);
1650 /***********************************************************************
1651 * InterlockedCompareExchange (kernelbase.@)
1653 __ASM_STDCALL_FUNC(InterlockedCompareExchange
, 12,
1654 "movl 12(%esp),%eax\n\t"
1655 "movl 8(%esp),%ecx\n\t"
1656 "movl 4(%esp),%edx\n\t"
1657 "lock; cmpxchgl %ecx,(%edx)\n\t"
1660 /***********************************************************************
1661 * InterlockedExchange (kernelbase.@)
1663 __ASM_STDCALL_FUNC(InterlockedExchange
, 8,
1664 "movl 8(%esp),%eax\n\t"
1665 "movl 4(%esp),%edx\n\t"
1666 "lock; xchgl %eax,(%edx)\n\t"
1669 /***********************************************************************
1670 * InterlockedExchangeAdd (kernelbase.@)
1672 __ASM_STDCALL_FUNC(InterlockedExchangeAdd
, 8,
1673 "movl 8(%esp),%eax\n\t"
1674 "movl 4(%esp),%edx\n\t"
1675 "lock; xaddl %eax,(%edx)\n\t"
1678 /***********************************************************************
1679 * InterlockedIncrement (kernelbase.@)
1681 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
1682 "movl 4(%esp),%edx\n\t"
1684 "lock; xaddl %eax,(%edx)\n\t"
1688 /***********************************************************************
1689 * InterlockedDecrement (kernelbase.@)
1691 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
1692 "movl 4(%esp),%edx\n\t"
1694 "lock; xaddl %eax,(%edx)\n\t"
1698 #endif /* __i386__ */