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 /* continue on wide print exceptions to force resending an ANSI one. */
408 if (state
.NewState
== DbgExceptionStateChange
)
410 DBGKM_EXCEPTION
*info
= &state
.StateInfo
.Exception
;
411 DWORD code
= info
->ExceptionRecord
.ExceptionCode
;
412 if (code
== DBG_PRINTEXCEPTION_WIDE_C
&& info
->ExceptionRecord
.NumberParameters
>= 2)
414 DbgUiContinue( &state
.AppClientId
, DBG_EXCEPTION_NOT_HANDLED
);
418 DbgUiConvertStateChangeStructure( &state
, event
);
420 case STATUS_USER_APC
:
423 SetLastError( ERROR_SEM_TIMEOUT
);
426 return set_ntstatus( status
);
431 /******************************************************************************
432 * WaitForDebugEventEx (kernelbase.@)
434 BOOL WINAPI DECLSPEC_HOTPATCH
WaitForDebugEventEx( DEBUG_EVENT
*event
, DWORD timeout
)
438 DBGUI_WAIT_STATE_CHANGE state
;
442 status
= DbgUiWaitStateChange( &state
, get_nt_timeout( &time
, timeout
) );
446 DbgUiConvertStateChangeStructure( &state
, event
);
448 case STATUS_USER_APC
:
451 SetLastError( ERROR_SEM_TIMEOUT
);
454 return set_ntstatus( status
);
460 /***********************************************************************
461 * WaitOnAddress (kernelbase.@)
463 BOOL WINAPI DECLSPEC_HOTPATCH
WaitOnAddress( volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
467 if (timeout
!= INFINITE
)
469 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
470 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, &to
));
472 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, NULL
));
476 /***********************************************************************
478 ***********************************************************************/
481 /***********************************************************************
482 * CreateEventA (kernelbase.@)
484 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
485 BOOL initial_state
, LPCSTR name
)
489 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
490 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
491 return CreateEventExA( sa
, name
, flags
, EVENT_ALL_ACCESS
);
495 /***********************************************************************
496 * CreateEventW (kernelbase.@)
498 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventW( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
499 BOOL initial_state
, LPCWSTR name
)
503 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
504 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
505 return CreateEventExW( sa
, name
, flags
, EVENT_ALL_ACCESS
);
509 /***********************************************************************
510 * CreateEventExA (kernelbase.@)
512 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
513 DWORD flags
, DWORD access
)
515 WCHAR buffer
[MAX_PATH
];
517 if (!name
) return CreateEventExW( sa
, NULL
, flags
, access
);
519 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
521 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
524 return CreateEventExW( sa
, buffer
, flags
, access
);
528 /***********************************************************************
529 * CreateEventExW (kernelbase.@)
531 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
532 DWORD flags
, DWORD access
)
535 UNICODE_STRING nameW
;
536 OBJECT_ATTRIBUTES attr
;
539 /* one buggy program needs this
540 * ("Van Dale Groot woordenboek der Nederlandse taal")
544 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
548 SetLastError( ERROR_INVALID_PARAMETER
);
553 status
= NtCreateEvent( &ret
, access
, &attr
,
554 (flags
& CREATE_EVENT_MANUAL_RESET
) ? NotificationEvent
: SynchronizationEvent
,
555 (flags
& CREATE_EVENT_INITIAL_SET
) != 0 );
556 if (status
== STATUS_OBJECT_NAME_EXISTS
)
557 SetLastError( ERROR_ALREADY_EXISTS
);
559 SetLastError( RtlNtStatusToDosError(status
) );
564 /***********************************************************************
565 * OpenEventA (kernelbase.@)
567 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventA( DWORD access
, BOOL inherit
, LPCSTR name
)
569 WCHAR buffer
[MAX_PATH
];
571 if (!name
) return OpenEventW( access
, inherit
, NULL
);
573 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
575 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
578 return OpenEventW( access
, inherit
, buffer
);
582 /***********************************************************************
583 * OpenEventW (kernelbase.@)
585 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
588 UNICODE_STRING nameW
;
589 OBJECT_ATTRIBUTES attr
;
591 if (!is_version_nt()) access
= EVENT_ALL_ACCESS
;
593 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
595 if (!set_ntstatus( NtOpenEvent( &ret
, access
, &attr
))) return 0;
599 /***********************************************************************
600 * PulseEvent (kernelbase.@)
602 BOOL WINAPI DECLSPEC_HOTPATCH
PulseEvent( HANDLE handle
)
604 return set_ntstatus( NtPulseEvent( handle
, NULL
));
608 /***********************************************************************
609 * SetEvent (kernelbase.@)
611 BOOL WINAPI DECLSPEC_HOTPATCH
SetEvent( HANDLE handle
)
613 return set_ntstatus( NtSetEvent( handle
, NULL
));
617 /***********************************************************************
618 * ResetEvent (kernelbase.@)
620 BOOL WINAPI DECLSPEC_HOTPATCH
ResetEvent( HANDLE handle
)
622 return set_ntstatus( NtResetEvent( handle
, NULL
));
626 /***********************************************************************
628 ***********************************************************************/
631 /***********************************************************************
632 * CreateMutexA (kernelbase.@)
634 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexA( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCSTR name
)
636 return CreateMutexExA( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
640 /***********************************************************************
641 * CreateMutexW (kernelbase.@)
643 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexW( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCWSTR name
)
645 return CreateMutexExW( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
649 /***********************************************************************
650 * CreateMutexExA (kernelbase.@)
652 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
653 DWORD flags
, DWORD access
)
658 if (!name
) return CreateMutexExW( sa
, NULL
, flags
, access
);
660 RtlInitAnsiString( &nameA
, name
);
661 status
= RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString
, &nameA
, FALSE
);
662 if (status
!= STATUS_SUCCESS
)
664 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
667 return CreateMutexExW( sa
, NtCurrentTeb()->StaticUnicodeString
.Buffer
, flags
, access
);
671 /***********************************************************************
672 * CreateMutexExW (kernelbase.@)
674 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
675 DWORD flags
, DWORD access
)
678 UNICODE_STRING nameW
;
679 OBJECT_ATTRIBUTES attr
;
682 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
684 status
= NtCreateMutant( &ret
, access
, &attr
, (flags
& CREATE_MUTEX_INITIAL_OWNER
) != 0 );
685 if (status
== STATUS_OBJECT_NAME_EXISTS
)
686 SetLastError( ERROR_ALREADY_EXISTS
);
688 SetLastError( RtlNtStatusToDosError(status
) );
693 /***********************************************************************
694 * OpenMutexW (kernelbase.@)
696 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
699 UNICODE_STRING nameW
;
700 OBJECT_ATTRIBUTES attr
;
702 if (!is_version_nt()) access
= MUTEX_ALL_ACCESS
;
704 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
706 if (!set_ntstatus( NtOpenMutant( &ret
, access
, &attr
))) return 0;
711 /***********************************************************************
712 * ReleaseMutex (kernelbase.@)
714 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseMutex( HANDLE handle
)
716 return set_ntstatus( NtReleaseMutant( handle
, NULL
));
720 /***********************************************************************
722 ***********************************************************************/
725 /***********************************************************************
726 * CreateSemaphoreW (kernelbase.@)
728 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreW( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
729 LONG max
, LPCWSTR name
)
731 return CreateSemaphoreExW( sa
, initial
, max
, name
, 0, SEMAPHORE_ALL_ACCESS
);
735 /***********************************************************************
736 * CreateSemaphoreExW (kernelbase.@)
738 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreExW( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
,
739 LPCWSTR name
, DWORD flags
, DWORD access
)
742 UNICODE_STRING nameW
;
743 OBJECT_ATTRIBUTES attr
;
746 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
748 status
= NtCreateSemaphore( &ret
, access
, &attr
, initial
, max
);
749 if (status
== STATUS_OBJECT_NAME_EXISTS
)
750 SetLastError( ERROR_ALREADY_EXISTS
);
752 SetLastError( RtlNtStatusToDosError(status
) );
757 /***********************************************************************
758 * OpenSemaphoreW (kernelbase.@)
760 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
763 UNICODE_STRING nameW
;
764 OBJECT_ATTRIBUTES attr
;
766 if (!is_version_nt()) access
= SEMAPHORE_ALL_ACCESS
;
768 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
770 if (!set_ntstatus( NtOpenSemaphore( &ret
, access
, &attr
))) return 0;
775 /***********************************************************************
776 * ReleaseSemaphore (kernelbase.@)
778 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseSemaphore( HANDLE handle
, LONG count
, LONG
*previous
)
780 return set_ntstatus( NtReleaseSemaphore( handle
, count
, (PULONG
)previous
));
784 /***********************************************************************
786 ***********************************************************************/
789 /***********************************************************************
790 * CreateWaitableTimerW (kernelbase.@)
792 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerW( SECURITY_ATTRIBUTES
*sa
, BOOL manual
, LPCWSTR name
)
794 return CreateWaitableTimerExW( sa
, name
, manual
? CREATE_WAITABLE_TIMER_MANUAL_RESET
: 0,
799 /***********************************************************************
800 * CreateWaitableTimerExW (kernelbase.@)
802 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
803 DWORD flags
, DWORD access
)
807 UNICODE_STRING nameW
;
808 OBJECT_ATTRIBUTES attr
;
810 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
812 status
= NtCreateTimer( &handle
, access
, &attr
,
813 (flags
& CREATE_WAITABLE_TIMER_MANUAL_RESET
) ? NotificationTimer
: SynchronizationTimer
);
814 if (status
== STATUS_OBJECT_NAME_EXISTS
)
815 SetLastError( ERROR_ALREADY_EXISTS
);
817 SetLastError( RtlNtStatusToDosError(status
) );
822 /***********************************************************************
823 * OpenWaitableTimerW (kernelbase.@)
825 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenWaitableTimerW( DWORD access
, BOOL inherit
, LPCWSTR name
)
828 UNICODE_STRING nameW
;
829 OBJECT_ATTRIBUTES attr
;
831 if (!is_version_nt()) access
= TIMER_ALL_ACCESS
;
833 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
835 if (!set_ntstatus( NtOpenTimer( &handle
, access
, &attr
))) return 0;
840 /***********************************************************************
841 * SetWaitableTimer (kernelbase.@)
843 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimer( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
844 PTIMERAPCROUTINE callback
, LPVOID arg
, BOOL resume
)
846 NTSTATUS status
= NtSetTimer( handle
, when
, (PTIMER_APC_ROUTINE
)callback
,
847 arg
, resume
, period
, NULL
);
848 return set_ntstatus( status
) || status
== STATUS_TIMER_RESUME_IGNORED
;
852 /***********************************************************************
853 * SetWaitableTimerEx (kernelbase.@)
855 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimerEx( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
856 PTIMERAPCROUTINE callback
, LPVOID arg
,
857 REASON_CONTEXT
*context
, ULONG tolerabledelay
)
860 if (!once
++) FIXME( "(%p, %p, %ld, %p, %p, %p, %ld) semi-stub\n",
861 handle
, when
, period
, callback
, arg
, context
, tolerabledelay
);
863 return SetWaitableTimer( handle
, when
, period
, callback
, arg
, FALSE
);
867 /***********************************************************************
868 * CancelWaitableTimer (kernelbase.@)
870 BOOL WINAPI DECLSPEC_HOTPATCH
CancelWaitableTimer( HANDLE handle
)
872 return set_ntstatus( NtCancelTimer( handle
, NULL
));
876 /***********************************************************************
878 ***********************************************************************/
881 /***********************************************************************
882 * CreateTimerQueue (kernelbase.@)
884 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateTimerQueue(void)
888 if (!set_ntstatus( RtlCreateTimerQueue( &q
))) return NULL
;
893 /***********************************************************************
894 * CreateTimerQueueTimer (kernelbase.@)
896 BOOL WINAPI DECLSPEC_HOTPATCH
CreateTimerQueueTimer( PHANDLE timer
, HANDLE queue
,
897 WAITORTIMERCALLBACK callback
, PVOID arg
,
898 DWORD when
, DWORD period
, ULONG flags
)
900 return set_ntstatus( RtlCreateTimer( queue
, timer
, callback
, arg
, when
, period
, flags
));
904 /***********************************************************************
905 * ChangeTimerQueueTimer (kernelbase.@)
907 BOOL WINAPI DECLSPEC_HOTPATCH
ChangeTimerQueueTimer( HANDLE queue
, HANDLE timer
,
908 ULONG when
, ULONG period
)
910 return set_ntstatus( RtlUpdateTimer( queue
, timer
, when
, period
));
914 /***********************************************************************
915 * DeleteTimerQueueEx (kernelbase.@)
917 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueEx( HANDLE queue
, HANDLE event
)
919 return set_ntstatus( RtlDeleteTimerQueueEx( queue
, event
));
923 /***********************************************************************
924 * DeleteTimerQueueTimer (kernelbase.@)
926 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueTimer( HANDLE queue
, HANDLE timer
, HANDLE event
)
928 return set_ntstatus( RtlDeleteTimer( queue
, timer
, event
));
932 /***********************************************************************
934 ***********************************************************************/
937 /***********************************************************************
938 * InitializeCriticalSectionAndSpinCount (kernelbase.@)
940 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION
*crit
, DWORD count
)
942 return !RtlInitializeCriticalSectionAndSpinCount( crit
, count
);
945 /***********************************************************************
946 * InitializeCriticalSectionEx (kernelbase.@)
948 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionEx( CRITICAL_SECTION
*crit
, DWORD spincount
,
951 NTSTATUS ret
= RtlInitializeCriticalSectionEx( crit
, spincount
, flags
);
952 if (ret
) RtlRaiseStatus( ret
);
957 /***********************************************************************
959 ***********************************************************************/
961 /***********************************************************************
962 * CreateFileMappingW (kernelbase.@)
964 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingW( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, DWORD protect
,
965 DWORD size_high
, DWORD size_low
, LPCWSTR name
)
967 static const int sec_flags
= (SEC_FILE
| SEC_IMAGE
| SEC_RESERVE
| SEC_COMMIT
|
968 SEC_NOCACHE
| SEC_WRITECOMBINE
| SEC_LARGE_PAGES
);
971 DWORD access
, sec_type
;
973 UNICODE_STRING nameW
;
974 OBJECT_ATTRIBUTES attr
;
976 sec_type
= protect
& sec_flags
;
977 protect
&= ~sec_flags
;
978 if (!sec_type
) sec_type
= SEC_COMMIT
;
980 /* Win9x compatibility */
981 if (!protect
&& !is_version_nt()) protect
= PAGE_READONLY
;
987 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
990 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
;
992 case PAGE_EXECUTE_READ
:
993 case PAGE_EXECUTE_WRITECOPY
:
994 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_EXECUTE
;
996 case PAGE_EXECUTE_READWRITE
:
997 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
;
1000 SetLastError( ERROR_INVALID_PARAMETER
);
1004 size
.u
.LowPart
= size_low
;
1005 size
.u
.HighPart
= size_high
;
1007 if (file
== INVALID_HANDLE_VALUE
)
1012 SetLastError( ERROR_INVALID_PARAMETER
);
1017 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
1019 status
= NtCreateSection( &ret
, access
, &attr
, &size
, protect
, sec_type
, file
);
1020 if (status
== STATUS_OBJECT_NAME_EXISTS
)
1021 SetLastError( ERROR_ALREADY_EXISTS
);
1023 SetLastError( RtlNtStatusToDosError(status
) );
1028 /***********************************************************************
1029 * CreateFileMappingFromApp (kernelbase.@)
1031 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingFromApp( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, ULONG protect
,
1032 ULONG64 size
, LPCWSTR name
)
1034 return CreateFileMappingW( file
, sa
, protect
, size
<< 32, size
, name
);
1037 /***********************************************************************
1038 * OpenFileMappingW (kernelbase.@)
1040 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingW( DWORD access
, BOOL inherit
, LPCWSTR name
)
1042 OBJECT_ATTRIBUTES attr
;
1043 UNICODE_STRING nameW
;
1046 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
1048 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
1050 if (!is_version_nt())
1052 /* win9x doesn't do access checks, so try with full access first */
1053 if (!NtOpenSection( &ret
, access
| SECTION_MAP_READ
| SECTION_MAP_WRITE
, &attr
)) return ret
;
1056 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
1061 /***********************************************************************
1062 * OpenFileMappingFromApp (kernelbase.@)
1064 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingFromApp( ULONG access
, BOOL inherit
, LPCWSTR name
)
1066 OBJECT_ATTRIBUTES attr
;
1067 UNICODE_STRING nameW
;
1070 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
1072 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
1074 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
1079 /***********************************************************************
1080 * Condition variables
1081 ***********************************************************************/
1084 /***********************************************************************
1085 * SleepConditionVariableCS (kernelbase.@)
1087 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableCS( CONDITION_VARIABLE
*variable
,
1088 CRITICAL_SECTION
*crit
, DWORD timeout
)
1092 return set_ntstatus( RtlSleepConditionVariableCS( variable
, crit
, get_nt_timeout( &time
, timeout
)));
1096 /***********************************************************************
1097 * SleepConditionVariableSRW (kernelbase.@)
1099 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableSRW( RTL_CONDITION_VARIABLE
*variable
,
1100 RTL_SRWLOCK
*lock
, DWORD timeout
, ULONG flags
)
1104 return set_ntstatus( RtlSleepConditionVariableSRW( variable
, lock
,
1105 get_nt_timeout( &time
, timeout
), flags
));
1109 /***********************************************************************
1111 ***********************************************************************/
1114 /******************************************************************************
1115 * CreateIoCompletionPort (kernelbase.@)
1117 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateIoCompletionPort( HANDLE handle
, HANDLE port
,
1118 ULONG_PTR key
, DWORD threads
)
1120 FILE_COMPLETION_INFORMATION info
;
1121 IO_STATUS_BLOCK iosb
;
1124 TRACE( "(%p, %p, %08Ix, %08lx)\n", handle
, port
, key
, threads
);
1128 if (!set_ntstatus( NtCreateIoCompletion( &ret
, IO_COMPLETION_ALL_ACCESS
, NULL
, threads
)))
1131 else if (handle
== INVALID_HANDLE_VALUE
)
1133 SetLastError( ERROR_INVALID_PARAMETER
);
1137 if (handle
!= INVALID_HANDLE_VALUE
)
1139 info
.CompletionPort
= ret
;
1140 info
.CompletionKey
= key
;
1141 if (!set_ntstatus( NtSetInformationFile( handle
, &iosb
, &info
, sizeof(info
), FileCompletionInformation
)))
1143 if (!port
) CloseHandle( ret
);
1151 /******************************************************************************
1152 * GetQueuedCompletionStatus (kernelbase.@)
1154 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatus( HANDLE port
, LPDWORD count
, PULONG_PTR key
,
1155 LPOVERLAPPED
*overlapped
, DWORD timeout
)
1158 IO_STATUS_BLOCK iosb
;
1159 LARGE_INTEGER wait_time
;
1161 TRACE( "(%p,%p,%p,%p,%ld)\n", port
, count
, key
, overlapped
, timeout
);
1164 status
= NtRemoveIoCompletion( port
, key
, (PULONG_PTR
)overlapped
, &iosb
,
1165 get_nt_timeout( &wait_time
, timeout
) );
1166 if (status
== STATUS_SUCCESS
)
1168 *count
= iosb
.Information
;
1169 if (iosb
.Status
>= 0) return TRUE
;
1170 SetLastError( RtlNtStatusToDosError(iosb
.Status
) );
1174 if (status
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1175 else SetLastError( RtlNtStatusToDosError(status
) );
1179 /******************************************************************************
1180 * GetQueuedCompletionStatusEx (kernelbase.@)
1182 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatusEx( HANDLE port
, OVERLAPPED_ENTRY
*entries
,
1183 ULONG count
, ULONG
*written
,
1184 DWORD timeout
, BOOL alertable
)
1189 TRACE( "%p %p %lu %p %lu %u\n", port
, entries
, count
, written
, timeout
, alertable
);
1191 ret
= NtRemoveIoCompletionEx( port
, (FILE_IO_COMPLETION_INFORMATION
*)entries
, count
,
1192 written
, get_nt_timeout( &time
, timeout
), alertable
);
1193 if (ret
== STATUS_SUCCESS
) return TRUE
;
1194 else if (ret
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1195 else if (ret
== STATUS_USER_APC
) SetLastError( WAIT_IO_COMPLETION
);
1196 else SetLastError( RtlNtStatusToDosError(ret
) );
1201 /******************************************************************************
1202 * PostQueuedCompletionStatus (kernelbase.@)
1204 BOOL WINAPI DECLSPEC_HOTPATCH
PostQueuedCompletionStatus( HANDLE port
, DWORD count
,
1205 ULONG_PTR key
, LPOVERLAPPED overlapped
)
1207 TRACE( "%p %ld %08Ix %p\n", port
, count
, key
, overlapped
);
1209 return set_ntstatus( NtSetIoCompletion( port
, key
, (ULONG_PTR
)overlapped
, STATUS_SUCCESS
, count
));
1213 /***********************************************************************
1215 ***********************************************************************/
1218 /***********************************************************************
1219 * CallNamedPipeW (kernelbase.@)
1221 BOOL WINAPI DECLSPEC_HOTPATCH
CallNamedPipeW( LPCWSTR name
, LPVOID input
, DWORD in_size
,
1222 LPVOID output
, DWORD out_size
,
1223 LPDWORD read_size
, DWORD timeout
)
1229 TRACE( "%s %p %ld %p %ld %p %ld\n", debugstr_w(name
),
1230 input
, in_size
, output
, out_size
, read_size
, timeout
);
1232 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1233 if (pipe
== INVALID_HANDLE_VALUE
)
1235 if (!WaitNamedPipeW( name
, timeout
)) return FALSE
;
1236 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1237 if (pipe
== INVALID_HANDLE_VALUE
) return FALSE
;
1240 mode
= PIPE_READMODE_MESSAGE
;
1241 ret
= SetNamedPipeHandleState( pipe
, &mode
, NULL
, NULL
);
1242 if (ret
) ret
= TransactNamedPipe( pipe
, input
, in_size
, output
, out_size
, read_size
, NULL
);
1243 CloseHandle( pipe
);
1248 /***********************************************************************
1249 * ConnectNamedPipe (kernelbase.@)
1251 BOOL WINAPI DECLSPEC_HOTPATCH
ConnectNamedPipe( HANDLE pipe
, LPOVERLAPPED overlapped
)
1254 IO_STATUS_BLOCK status_block
;
1255 LPVOID cvalue
= NULL
;
1257 TRACE( "(%p,%p)\n", pipe
, overlapped
);
1261 overlapped
->Internal
= STATUS_PENDING
;
1262 overlapped
->InternalHigh
= 0;
1263 if (((ULONG_PTR
)overlapped
->hEvent
& 1) == 0) cvalue
= overlapped
;
1266 status
= NtFsControlFile( pipe
, overlapped
? overlapped
->hEvent
: NULL
, NULL
, cvalue
,
1267 overlapped
? (IO_STATUS_BLOCK
*)overlapped
: &status_block
,
1268 FSCTL_PIPE_LISTEN
, NULL
, 0, NULL
, 0 );
1269 if (status
== STATUS_PENDING
&& !overlapped
)
1271 WaitForSingleObject( pipe
, INFINITE
);
1272 status
= status_block
.Status
;
1274 return set_ntstatus( status
);
1277 /***********************************************************************
1278 * CreateNamedPipeW (kernelbase.@)
1280 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateNamedPipeW( LPCWSTR name
, DWORD open_mode
, DWORD pipe_mode
,
1281 DWORD instances
, DWORD out_buff
, DWORD in_buff
,
1282 DWORD timeout
, LPSECURITY_ATTRIBUTES sa
)
1285 UNICODE_STRING nt_name
;
1286 OBJECT_ATTRIBUTES attr
;
1287 DWORD access
, options
, sharing
;
1288 BOOLEAN pipe_type
, read_mode
, non_block
;
1290 IO_STATUS_BLOCK iosb
;
1293 TRACE( "(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n", debugstr_w(name
),
1294 open_mode
, pipe_mode
, instances
, out_buff
, in_buff
, timeout
, sa
);
1296 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
))
1298 SetLastError( ERROR_PATH_NOT_FOUND
);
1299 return INVALID_HANDLE_VALUE
;
1301 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) )
1303 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
1304 RtlFreeUnicodeString( &nt_name
);
1305 return INVALID_HANDLE_VALUE
;
1308 attr
.Length
= sizeof(attr
);
1309 attr
.RootDirectory
= 0;
1310 attr
.ObjectName
= &nt_name
;
1311 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1312 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1313 attr
.SecurityQualityOfService
= NULL
;
1315 switch (open_mode
& 3)
1317 case PIPE_ACCESS_INBOUND
:
1318 sharing
= FILE_SHARE_WRITE
;
1319 access
= GENERIC_READ
;
1321 case PIPE_ACCESS_OUTBOUND
:
1322 sharing
= FILE_SHARE_READ
;
1323 access
= GENERIC_WRITE
;
1325 case PIPE_ACCESS_DUPLEX
:
1326 sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
1327 access
= GENERIC_READ
| GENERIC_WRITE
;
1330 SetLastError( ERROR_INVALID_PARAMETER
);
1331 return INVALID_HANDLE_VALUE
;
1333 access
|= SYNCHRONIZE
;
1335 if (open_mode
& WRITE_DAC
) access
|= WRITE_DAC
;
1336 if (open_mode
& WRITE_OWNER
) access
|= WRITE_OWNER
;
1337 if (open_mode
& ACCESS_SYSTEM_SECURITY
) access
|= ACCESS_SYSTEM_SECURITY
;
1338 if (open_mode
& FILE_FLAG_WRITE_THROUGH
) options
|= FILE_WRITE_THROUGH
;
1339 if (!(open_mode
& FILE_FLAG_OVERLAPPED
)) options
|= FILE_SYNCHRONOUS_IO_NONALERT
;
1340 pipe_type
= (pipe_mode
& PIPE_TYPE_MESSAGE
) != 0;
1341 read_mode
= (pipe_mode
& PIPE_READMODE_MESSAGE
) != 0;
1342 non_block
= (pipe_mode
& PIPE_NOWAIT
) != 0;
1343 if (instances
>= PIPE_UNLIMITED_INSTANCES
) instances
= ~0U;
1345 time
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1346 status
= NtCreateNamedPipeFile( &handle
, access
, &attr
, &iosb
, sharing
,
1347 FILE_OPEN_IF
, options
, pipe_type
,
1348 read_mode
, non_block
, instances
, in_buff
, out_buff
, &time
);
1349 RtlFreeUnicodeString( &nt_name
);
1350 if (!set_ntstatus( status
)) return INVALID_HANDLE_VALUE
;
1351 SetLastError( iosb
.Information
== FILE_CREATED
? ERROR_SUCCESS
: ERROR_ALREADY_EXISTS
);
1356 /******************************************************************
1357 * CreatePipe (kernelbase.@)
1359 BOOL WINAPI DECLSPEC_HOTPATCH
CreatePipe( HANDLE
*read_pipe
, HANDLE
*write_pipe
,
1360 SECURITY_ATTRIBUTES
*sa
, DWORD size
)
1362 static unsigned int index
;
1364 UNICODE_STRING nt_name
;
1365 OBJECT_ATTRIBUTES attr
;
1366 IO_STATUS_BLOCK iosb
;
1367 LARGE_INTEGER timeout
;
1369 *read_pipe
= *write_pipe
= INVALID_HANDLE_VALUE
;
1371 attr
.Length
= sizeof(attr
);
1372 attr
.RootDirectory
= 0;
1373 attr
.ObjectName
= &nt_name
;
1374 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1375 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1376 attr
.SecurityQualityOfService
= NULL
;
1378 if (!size
) size
= 4096;
1380 timeout
.QuadPart
= (ULONGLONG
)NMPWAIT_USE_DEFAULT_WAIT
* -10000;
1382 /* generate a unique pipe name (system wide) */
1385 swprintf( name
, ARRAY_SIZE(name
), L
"\\??\\pipe\\Win32.Pipes.%08lu.%08u",
1386 GetCurrentProcessId(), ++index
);
1387 RtlInitUnicodeString( &nt_name
, name
);
1388 if (!NtCreateNamedPipeFile( read_pipe
, GENERIC_READ
| FILE_WRITE_ATTRIBUTES
| SYNCHRONIZE
,
1389 &attr
, &iosb
, FILE_SHARE_WRITE
, FILE_OPEN_IF
,
1390 FILE_SYNCHRONOUS_IO_NONALERT
,
1391 FALSE
, FALSE
, FALSE
, 1, size
, size
, &timeout
))
1394 if (!set_ntstatus( NtOpenFile( write_pipe
, GENERIC_WRITE
| FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1395 &iosb
, 0, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
)))
1397 NtClose( *read_pipe
);
1404 /***********************************************************************
1405 * DisconnectNamedPipe (kernelbase.@)
1407 BOOL WINAPI DECLSPEC_HOTPATCH
DisconnectNamedPipe( HANDLE pipe
)
1409 IO_STATUS_BLOCK io_block
;
1411 TRACE( "(%p)\n", pipe
);
1412 return set_ntstatus( NtFsControlFile( pipe
, 0, NULL
, NULL
, &io_block
,
1413 FSCTL_PIPE_DISCONNECT
, NULL
, 0, NULL
, 0 ));
1417 /***********************************************************************
1418 * GetNamedPipeHandleStateW (kernelbase.@)
1420 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeHandleStateW( HANDLE pipe
, DWORD
*state
, DWORD
*instances
,
1421 DWORD
*max_count
, DWORD
*timeout
,
1422 WCHAR
*user
, DWORD size
)
1426 FIXME( "%p %p %p %p %p %p %ld: semi-stub\n", pipe
, state
, instances
, max_count
, timeout
, user
, size
);
1428 if (max_count
) *max_count
= 0;
1429 if (timeout
) *timeout
= 0;
1430 if (user
&& size
&& !GetEnvironmentVariableW( L
"WINEUSERNAME", user
, size
)) user
[0] = 0;
1434 FILE_PIPE_INFORMATION info
;
1436 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
), FilePipeInformation
)))
1439 *state
= (info
.ReadMode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
) |
1440 (info
.CompletionMode
? PIPE_NOWAIT
: PIPE_WAIT
);
1444 FILE_PIPE_LOCAL_INFORMATION info
;
1446 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
),
1447 FilePipeLocalInformation
)))
1449 *instances
= info
.CurrentInstances
;
1455 /***********************************************************************
1456 * GetNamedPipeInfo (kernelbase.@)
1458 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeInfo( HANDLE pipe
, LPDWORD flags
, LPDWORD out_size
,
1459 LPDWORD in_size
, LPDWORD instances
)
1461 FILE_PIPE_LOCAL_INFORMATION info
;
1462 IO_STATUS_BLOCK iosb
;
1464 if (!set_ntstatus( NtQueryInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeLocalInformation
)))
1469 *flags
= (info
.NamedPipeEnd
& FILE_PIPE_SERVER_END
) ? PIPE_SERVER_END
: PIPE_CLIENT_END
;
1470 *flags
|= (info
.NamedPipeType
& FILE_PIPE_TYPE_MESSAGE
) ? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
;
1472 if (out_size
) *out_size
= info
.OutboundQuota
;
1473 if (in_size
) *in_size
= info
.InboundQuota
;
1474 if (instances
) *instances
= info
.MaximumInstances
;
1479 /***********************************************************************
1480 * PeekNamedPipe (kernelbase.@)
1482 BOOL WINAPI DECLSPEC_HOTPATCH
PeekNamedPipe( HANDLE pipe
, LPVOID out_buffer
, DWORD size
,
1483 LPDWORD read_size
, LPDWORD avail
, LPDWORD message
)
1485 FILE_PIPE_PEEK_BUFFER local_buffer
;
1486 FILE_PIPE_PEEK_BUFFER
*buffer
= &local_buffer
;
1490 if (size
&& !(buffer
= HeapAlloc( GetProcessHeap(), 0,
1491 FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ))))
1493 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1497 status
= NtFsControlFile( pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0,
1498 buffer
, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ) );
1499 if (status
== STATUS_BUFFER_OVERFLOW
) status
= STATUS_SUCCESS
;
1502 ULONG count
= io
.Information
- FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
);
1503 if (avail
) *avail
= buffer
->ReadDataAvailable
;
1504 if (read_size
) *read_size
= count
;
1505 if (message
) *message
= buffer
->MessageLength
- count
;
1506 if (out_buffer
) memcpy( out_buffer
, buffer
->Data
, count
);
1508 else SetLastError( RtlNtStatusToDosError(status
) );
1510 if (buffer
!= &local_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
1515 /***********************************************************************
1516 * SetNamedPipeHandleState (kernelbase.@)
1518 BOOL WINAPI DECLSPEC_HOTPATCH
SetNamedPipeHandleState( HANDLE pipe
, LPDWORD mode
,
1519 LPDWORD count
, LPDWORD timeout
)
1521 FILE_PIPE_INFORMATION info
;
1522 IO_STATUS_BLOCK iosb
;
1523 NTSTATUS status
= STATUS_SUCCESS
;
1525 TRACE( "%p %p/%ld %p %p\n", pipe
, mode
, mode
? *mode
: 0, count
, timeout
);
1526 if (count
|| timeout
) FIXME( "Unsupported arguments\n" );
1530 if (*mode
& ~(PIPE_READMODE_MESSAGE
| PIPE_NOWAIT
)) status
= STATUS_INVALID_PARAMETER
;
1533 info
.CompletionMode
= (*mode
& PIPE_NOWAIT
) ?
1534 FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION
;
1535 info
.ReadMode
= (*mode
& PIPE_READMODE_MESSAGE
) ?
1536 FILE_PIPE_MESSAGE_MODE
: FILE_PIPE_BYTE_STREAM_MODE
;
1537 status
= NtSetInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeInformation
);
1540 return set_ntstatus( status
);
1543 /***********************************************************************
1544 * TransactNamedPipe (kernelbase.@)
1546 BOOL WINAPI DECLSPEC_HOTPATCH
TransactNamedPipe( HANDLE handle
, LPVOID write_buf
, DWORD write_size
,
1547 LPVOID read_buf
, DWORD read_size
, LPDWORD bytes_read
,
1548 LPOVERLAPPED overlapped
)
1550 IO_STATUS_BLOCK default_iosb
, *iosb
= &default_iosb
;
1551 HANDLE event
= NULL
;
1552 void *cvalue
= NULL
;
1555 TRACE( "%p %p %lu %p %lu %p %p\n", handle
,
1556 write_buf
, write_size
, read_buf
, read_size
, bytes_read
, overlapped
);
1560 event
= overlapped
->hEvent
;
1561 iosb
= (IO_STATUS_BLOCK
*)overlapped
;
1562 if (((ULONG_PTR
)event
& 1) == 0) cvalue
= overlapped
;
1566 iosb
->Information
= 0;
1569 status
= NtFsControlFile( handle
, event
, NULL
, cvalue
, iosb
, FSCTL_PIPE_TRANSCEIVE
,
1570 write_buf
, write_size
, read_buf
, read_size
);
1571 if (status
== STATUS_PENDING
&& !overlapped
)
1573 WaitForSingleObject(handle
, INFINITE
);
1574 status
= iosb
->Status
;
1577 if (bytes_read
) *bytes_read
= overlapped
&& status
? 0 : iosb
->Information
;
1578 return set_ntstatus( status
);
1582 /***********************************************************************
1583 * WaitNamedPipeW (kernelbase.@)
1585 BOOL WINAPI DECLSPEC_HOTPATCH
WaitNamedPipeW( LPCWSTR name
, DWORD timeout
)
1587 static const int prefix_len
= sizeof(L
"\\??\\PIPE\\") - sizeof(WCHAR
);
1589 UNICODE_STRING nt_name
, pipe_dev_name
;
1590 FILE_PIPE_WAIT_FOR_BUFFER
*pipe_wait
;
1591 IO_STATUS_BLOCK iosb
;
1592 OBJECT_ATTRIBUTES attr
;
1596 TRACE( "%s 0x%08lx\n", debugstr_w(name
), timeout
);
1598 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
)) return FALSE
;
1600 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) ||
1601 nt_name
.Length
< prefix_len
||
1602 wcsnicmp( nt_name
.Buffer
, L
"\\??\\PIPE\\", prefix_len
/ sizeof(WCHAR
) ))
1604 RtlFreeUnicodeString( &nt_name
);
1605 SetLastError( ERROR_PATH_NOT_FOUND
);
1609 wait_size
= offsetof( FILE_PIPE_WAIT_FOR_BUFFER
, Name
[(nt_name
.Length
- prefix_len
) / sizeof(WCHAR
)] );
1610 if (!(pipe_wait
= HeapAlloc( GetProcessHeap(), 0, wait_size
)))
1612 RtlFreeUnicodeString( &nt_name
);
1613 SetLastError( ERROR_OUTOFMEMORY
);
1617 pipe_dev_name
.Buffer
= nt_name
.Buffer
;
1618 pipe_dev_name
.Length
= prefix_len
;
1619 pipe_dev_name
.MaximumLength
= prefix_len
;
1620 InitializeObjectAttributes( &attr
,&pipe_dev_name
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1621 status
= NtOpenFile( &pipe_dev
, FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1622 &iosb
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1623 FILE_SYNCHRONOUS_IO_NONALERT
);
1624 if (status
!= STATUS_SUCCESS
)
1626 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1627 RtlFreeUnicodeString( &nt_name
);
1628 SetLastError( ERROR_PATH_NOT_FOUND
);
1632 pipe_wait
->TimeoutSpecified
= !(timeout
== NMPWAIT_USE_DEFAULT_WAIT
);
1633 if (timeout
== NMPWAIT_WAIT_FOREVER
)
1634 pipe_wait
->Timeout
.QuadPart
= ((ULONGLONG
)0x7fffffff << 32) | 0xffffffff;
1636 pipe_wait
->Timeout
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1637 pipe_wait
->NameLength
= nt_name
.Length
- prefix_len
;
1638 memcpy( pipe_wait
->Name
, nt_name
.Buffer
+ prefix_len
/sizeof(WCHAR
), pipe_wait
->NameLength
);
1639 RtlFreeUnicodeString( &nt_name
);
1641 status
= NtFsControlFile( pipe_dev
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_WAIT
,
1642 pipe_wait
, wait_size
, NULL
, 0 );
1644 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1645 NtClose( pipe_dev
);
1646 return set_ntstatus( status
);
1651 /***********************************************************************
1652 * Interlocked functions
1653 ***********************************************************************/
1656 /***********************************************************************
1657 * InitOnceBeginInitialize (kernelbase.@)
1659 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceBeginInitialize( INIT_ONCE
*once
, DWORD flags
,
1660 BOOL
*pending
, void **context
)
1662 NTSTATUS status
= RtlRunOnceBeginInitialize( once
, flags
, context
);
1663 if (status
>= 0) *pending
= (status
== STATUS_PENDING
);
1664 else SetLastError( RtlNtStatusToDosError(status
) );
1669 /***********************************************************************
1670 * InitOnceComplete (kernelbase.@)
1672 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceComplete( INIT_ONCE
*once
, DWORD flags
, void *context
)
1674 return set_ntstatus( RtlRunOnceComplete( once
, flags
, context
));
1678 /***********************************************************************
1679 * InitOnceExecuteOnce (kernelbase.@)
1681 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceExecuteOnce( INIT_ONCE
*once
, PINIT_ONCE_FN func
,
1682 void *param
, void **context
)
1684 return !RtlRunOnceExecuteOnce( once
, (PRTL_RUN_ONCE_INIT_FN
)func
, param
, context
);
1689 /***********************************************************************
1690 * InterlockedCompareExchange (kernelbase.@)
1692 __ASM_STDCALL_FUNC(InterlockedCompareExchange
, 12,
1693 "movl 12(%esp),%eax\n\t"
1694 "movl 8(%esp),%ecx\n\t"
1695 "movl 4(%esp),%edx\n\t"
1696 "lock; cmpxchgl %ecx,(%edx)\n\t"
1699 /***********************************************************************
1700 * InterlockedExchange (kernelbase.@)
1702 __ASM_STDCALL_FUNC(InterlockedExchange
, 8,
1703 "movl 8(%esp),%eax\n\t"
1704 "movl 4(%esp),%edx\n\t"
1705 "lock; xchgl %eax,(%edx)\n\t"
1708 /***********************************************************************
1709 * InterlockedExchangeAdd (kernelbase.@)
1711 __ASM_STDCALL_FUNC(InterlockedExchangeAdd
, 8,
1712 "movl 8(%esp),%eax\n\t"
1713 "movl 4(%esp),%edx\n\t"
1714 "lock; xaddl %eax,(%edx)\n\t"
1717 /***********************************************************************
1718 * InterlockedIncrement (kernelbase.@)
1720 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
1721 "movl 4(%esp),%edx\n\t"
1723 "lock; xaddl %eax,(%edx)\n\t"
1727 /***********************************************************************
1728 * InterlockedDecrement (kernelbase.@)
1730 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
1731 "movl 4(%esp),%edx\n\t"
1733 "lock; xaddl %eax,(%edx)\n\t"
1737 #endif /* __i386__ */