2 * Kernel synchronization objects
4 * Copyright 1998 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define WIN32_NO_STATUS
27 #define NONAMELESSUNION
37 #include "kernelbase.h"
39 #include "wine/exception.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(sync
);
44 static const struct _KUSER_SHARED_DATA
*user_shared_data
= (struct _KUSER_SHARED_DATA
*)0x7ffe0000;
46 /* check if current version is NT or Win95 */
47 static inline BOOL
is_version_nt(void)
49 return !(GetVersion() & 0x80000000);
52 /* helper for kernel32->ntdll timeout format conversion */
53 static inline LARGE_INTEGER
*get_nt_timeout( LARGE_INTEGER
*time
, DWORD timeout
)
55 if (timeout
== INFINITE
) return NULL
;
56 time
->QuadPart
= (ULONGLONG
)timeout
* -10000;
61 /***********************************************************************
62 * BaseGetNamedObjectDirectory (kernelbase.@)
64 NTSTATUS WINAPI
BaseGetNamedObjectDirectory( HANDLE
*dir
)
69 OBJECT_ATTRIBUTES attr
;
70 NTSTATUS status
= STATUS_SUCCESS
;
76 swprintf( buffer
, ARRAY_SIZE(buffer
), L
"\\Sessions\\%u\\BaseNamedObjects",
77 NtCurrentTeb()->Peb
->SessionId
);
78 RtlInitUnicodeString( &str
, buffer
);
79 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
80 status
= NtOpenDirectoryObject( &dir
, DIRECTORY_CREATE_OBJECT
|DIRECTORY_TRAVERSE
, &attr
);
81 if (!status
&& InterlockedCompareExchangePointer( &handle
, dir
, 0 ) != 0)
83 /* someone beat us here... */
91 static void get_create_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
92 SECURITY_ATTRIBUTES
*sa
, const WCHAR
*name
)
94 attr
->Length
= sizeof(*attr
);
95 attr
->RootDirectory
= 0;
96 attr
->ObjectName
= NULL
;
97 attr
->Attributes
= OBJ_OPENIF
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
98 attr
->SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
99 attr
->SecurityQualityOfService
= NULL
;
102 RtlInitUnicodeString( nameW
, name
);
103 attr
->ObjectName
= nameW
;
104 BaseGetNamedObjectDirectory( &attr
->RootDirectory
);
108 static BOOL
get_open_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
109 BOOL inherit
, const WCHAR
*name
)
115 SetLastError( ERROR_INVALID_PARAMETER
);
118 RtlInitUnicodeString( nameW
, name
);
119 BaseGetNamedObjectDirectory( &dir
);
120 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
125 /***********************************************************************
127 ***********************************************************************/
130 /*********************************************************************
131 * GetSystemTimes (kernelbase.@)
133 BOOL WINAPI DECLSPEC_HOTPATCH
GetSystemTimes( FILETIME
*idle
, FILETIME
*kernel
, FILETIME
*user
)
135 LARGE_INTEGER idle_time
, kernel_time
, user_time
;
136 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
*info
;
138 DWORD i
, cpus
= NtCurrentTeb()->Peb
->NumberOfProcessors
;
140 if (!(info
= HeapAlloc( GetProcessHeap(), 0, sizeof(*info
) * cpus
)))
142 SetLastError( ERROR_OUTOFMEMORY
);
145 if (!set_ntstatus( NtQuerySystemInformation( SystemProcessorPerformanceInformation
, info
,
146 sizeof(*info
) * cpus
, &ret_size
)))
148 HeapFree( GetProcessHeap(), 0, info
);
151 idle_time
.QuadPart
= 0;
152 kernel_time
.QuadPart
= 0;
153 user_time
.QuadPart
= 0;
154 for (i
= 0; i
< cpus
; i
++)
156 idle_time
.QuadPart
+= info
[i
].IdleTime
.QuadPart
;
157 kernel_time
.QuadPart
+= info
[i
].KernelTime
.QuadPart
;
158 user_time
.QuadPart
+= info
[i
].UserTime
.QuadPart
;
162 idle
->dwLowDateTime
= idle_time
.u
.LowPart
;
163 idle
->dwHighDateTime
= idle_time
.u
.HighPart
;
167 kernel
->dwLowDateTime
= kernel_time
.u
.LowPart
;
168 kernel
->dwHighDateTime
= kernel_time
.u
.HighPart
;
172 user
->dwLowDateTime
= user_time
.u
.LowPart
;
173 user
->dwHighDateTime
= user_time
.u
.HighPart
;
175 HeapFree( GetProcessHeap(), 0, info
);
180 /******************************************************************************
181 * GetTickCount (kernelbase.@)
183 ULONG WINAPI DECLSPEC_HOTPATCH
GetTickCount(void)
185 /* note: we ignore TickCountMultiplier */
186 return user_shared_data
->u
.TickCount
.LowPart
;
190 /******************************************************************************
191 * GetTickCount64 (kernelbase.@)
193 ULONGLONG WINAPI DECLSPEC_HOTPATCH
GetTickCount64(void)
199 high
= user_shared_data
->u
.TickCount
.High1Time
;
200 low
= user_shared_data
->u
.TickCount
.LowPart
;
202 while (high
!= user_shared_data
->u
.TickCount
.High2Time
);
203 /* note: we ignore TickCountMultiplier */
204 return (ULONGLONG
)high
<< 32 | low
;
208 /******************************************************************************
209 * QueryInterruptTime (kernelbase.@)
211 void WINAPI DECLSPEC_HOTPATCH
QueryInterruptTime( ULONGLONG
*time
)
217 high
= user_shared_data
->InterruptTime
.High1Time
;
218 low
= user_shared_data
->InterruptTime
.LowPart
;
220 while (high
!= user_shared_data
->InterruptTime
.High2Time
);
221 *time
= (ULONGLONG
)high
<< 32 | low
;
225 /******************************************************************************
226 * QueryInterruptTimePrecise (kernelbase.@)
228 void WINAPI DECLSPEC_HOTPATCH
QueryInterruptTimePrecise( ULONGLONG
*time
)
231 if (!once
++) FIXME( "(%p) semi-stub\n", time
);
233 QueryInterruptTime( time
);
237 /***********************************************************************
238 * QueryUnbiasedInterruptTimePrecise (kernelbase.@)
240 void WINAPI DECLSPEC_HOTPATCH
QueryUnbiasedInterruptTimePrecise( ULONGLONG
*time
)
243 if (!once
++) FIXME( "(%p): semi-stub.\n", time
);
245 RtlQueryUnbiasedInterruptTime( time
);
249 /***********************************************************************
251 ***********************************************************************/
254 static HANDLE
normalize_std_handle( HANDLE handle
)
256 if ((handle
== (HANDLE
)STD_INPUT_HANDLE
) ||
257 (handle
== (HANDLE
)STD_OUTPUT_HANDLE
) ||
258 (handle
== (HANDLE
)STD_ERROR_HANDLE
))
259 return GetStdHandle( HandleToULong(handle
) );
265 /***********************************************************************
266 * RegisterWaitForSingleObjectEx (kernelbase.@)
268 HANDLE WINAPI DECLSPEC_HOTPATCH
RegisterWaitForSingleObjectEx( HANDLE handle
, WAITORTIMERCALLBACK callback
,
269 PVOID context
, ULONG timeout
, ULONG flags
)
273 TRACE( "%p %p %p %ld %ld\n", handle
, callback
, context
, timeout
, flags
);
275 handle
= normalize_std_handle( handle
);
276 if (!set_ntstatus( RtlRegisterWait( &ret
, handle
, callback
, context
, timeout
, flags
))) return NULL
;
281 /***********************************************************************
282 * SignalObjectAndWait (kernelbase.@)
284 DWORD WINAPI DECLSPEC_HOTPATCH
SignalObjectAndWait( HANDLE signal
, HANDLE wait
,
285 DWORD timeout
, BOOL alertable
)
290 TRACE( "%p %p %ld %d\n", signal
, wait
, timeout
, alertable
);
292 status
= NtSignalAndWaitForSingleObject( signal
, wait
, alertable
, get_nt_timeout( &time
, timeout
) );
295 SetLastError( RtlNtStatusToDosError(status
) );
296 status
= WAIT_FAILED
;
302 /***********************************************************************
303 * Sleep (kernelbase.@)
305 void WINAPI DECLSPEC_HOTPATCH
Sleep( DWORD timeout
)
309 NtDelayExecution( FALSE
, get_nt_timeout( &time
, timeout
) );
313 /******************************************************************************
314 * SleepEx (kernelbase.@)
316 DWORD WINAPI DECLSPEC_HOTPATCH
SleepEx( DWORD timeout
, BOOL alertable
)
321 status
= NtDelayExecution( alertable
, get_nt_timeout( &time
, timeout
) );
322 if (status
== STATUS_USER_APC
) return WAIT_IO_COMPLETION
;
327 /***********************************************************************
328 * UnregisterWaitEx (kernelbase.@)
330 BOOL WINAPI DECLSPEC_HOTPATCH
UnregisterWaitEx( HANDLE handle
, HANDLE event
)
332 return set_ntstatus( RtlDeregisterWaitEx( handle
, event
));
336 /***********************************************************************
337 * WaitForSingleObject (kernelbase.@)
339 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
341 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
345 /***********************************************************************
346 * WaitForSingleObjectEx (kernelbase.@)
348 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
, BOOL alertable
)
350 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
354 /***********************************************************************
355 * WaitForMultipleObjects (kernelbase.@)
357 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
358 BOOL wait_all
, DWORD timeout
)
360 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
364 /***********************************************************************
365 * WaitForMultipleObjectsEx (kernelbase.@)
367 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
368 BOOL wait_all
, DWORD timeout
, BOOL alertable
)
371 HANDLE hloc
[MAXIMUM_WAIT_OBJECTS
];
375 if (count
> MAXIMUM_WAIT_OBJECTS
)
377 SetLastError(ERROR_INVALID_PARAMETER
);
380 for (i
= 0; i
< count
; i
++) hloc
[i
] = normalize_std_handle( handles
[i
] );
382 status
= NtWaitForMultipleObjects( count
, hloc
, !wait_all
, alertable
,
383 get_nt_timeout( &time
, timeout
) );
384 if (HIWORD(status
)) /* is it an error code? */
386 SetLastError( RtlNtStatusToDosError(status
) );
387 status
= WAIT_FAILED
;
393 /******************************************************************************
394 * WaitForDebugEvent (kernelbase.@)
396 BOOL WINAPI DECLSPEC_HOTPATCH
WaitForDebugEvent( DEBUG_EVENT
*event
, DWORD timeout
)
400 DBGUI_WAIT_STATE_CHANGE state
;
404 status
= DbgUiWaitStateChange( &state
, get_nt_timeout( &time
, timeout
) );
408 DbgUiConvertStateChangeStructure( &state
, event
);
410 case STATUS_USER_APC
:
413 SetLastError( ERROR_SEM_TIMEOUT
);
416 return set_ntstatus( status
);
422 /***********************************************************************
423 * WaitOnAddress (kernelbase.@)
425 BOOL WINAPI DECLSPEC_HOTPATCH
WaitOnAddress( volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
429 if (timeout
!= INFINITE
)
431 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
432 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, &to
));
434 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, NULL
));
438 /***********************************************************************
440 ***********************************************************************/
443 /***********************************************************************
444 * CreateEventA (kernelbase.@)
446 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
447 BOOL initial_state
, LPCSTR name
)
451 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
452 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
453 return CreateEventExA( sa
, name
, flags
, EVENT_ALL_ACCESS
);
457 /***********************************************************************
458 * CreateEventW (kernelbase.@)
460 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventW( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
461 BOOL initial_state
, LPCWSTR name
)
465 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
466 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
467 return CreateEventExW( sa
, name
, flags
, EVENT_ALL_ACCESS
);
471 /***********************************************************************
472 * CreateEventExA (kernelbase.@)
474 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
475 DWORD flags
, DWORD access
)
477 WCHAR buffer
[MAX_PATH
];
479 if (!name
) return CreateEventExW( sa
, NULL
, flags
, access
);
481 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
483 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
486 return CreateEventExW( sa
, buffer
, flags
, access
);
490 /***********************************************************************
491 * CreateEventExW (kernelbase.@)
493 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
494 DWORD flags
, DWORD access
)
497 UNICODE_STRING nameW
;
498 OBJECT_ATTRIBUTES attr
;
501 /* one buggy program needs this
502 * ("Van Dale Groot woordenboek der Nederlandse taal")
506 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
510 SetLastError( ERROR_INVALID_PARAMETER
);
515 status
= NtCreateEvent( &ret
, access
, &attr
,
516 (flags
& CREATE_EVENT_MANUAL_RESET
) ? NotificationEvent
: SynchronizationEvent
,
517 (flags
& CREATE_EVENT_INITIAL_SET
) != 0 );
518 if (status
== STATUS_OBJECT_NAME_EXISTS
)
519 SetLastError( ERROR_ALREADY_EXISTS
);
521 SetLastError( RtlNtStatusToDosError(status
) );
526 /***********************************************************************
527 * OpenEventA (kernelbase.@)
529 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventA( DWORD access
, BOOL inherit
, LPCSTR name
)
531 WCHAR buffer
[MAX_PATH
];
533 if (!name
) return OpenEventW( access
, inherit
, NULL
);
535 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
537 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
540 return OpenEventW( access
, inherit
, buffer
);
544 /***********************************************************************
545 * OpenEventW (kernelbase.@)
547 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
550 UNICODE_STRING nameW
;
551 OBJECT_ATTRIBUTES attr
;
553 if (!is_version_nt()) access
= EVENT_ALL_ACCESS
;
555 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
557 if (!set_ntstatus( NtOpenEvent( &ret
, access
, &attr
))) return 0;
561 /***********************************************************************
562 * PulseEvent (kernelbase.@)
564 BOOL WINAPI DECLSPEC_HOTPATCH
PulseEvent( HANDLE handle
)
566 return set_ntstatus( NtPulseEvent( handle
, NULL
));
570 /***********************************************************************
571 * SetEvent (kernelbase.@)
573 BOOL WINAPI DECLSPEC_HOTPATCH
SetEvent( HANDLE handle
)
575 return set_ntstatus( NtSetEvent( handle
, NULL
));
579 /***********************************************************************
580 * ResetEvent (kernelbase.@)
582 BOOL WINAPI DECLSPEC_HOTPATCH
ResetEvent( HANDLE handle
)
584 return set_ntstatus( NtResetEvent( handle
, NULL
));
588 /***********************************************************************
590 ***********************************************************************/
593 /***********************************************************************
594 * CreateMutexA (kernelbase.@)
596 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexA( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCSTR name
)
598 return CreateMutexExA( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
602 /***********************************************************************
603 * CreateMutexW (kernelbase.@)
605 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexW( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCWSTR name
)
607 return CreateMutexExW( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
611 /***********************************************************************
612 * CreateMutexExA (kernelbase.@)
614 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
615 DWORD flags
, DWORD access
)
620 if (!name
) return CreateMutexExW( sa
, NULL
, flags
, access
);
622 RtlInitAnsiString( &nameA
, name
);
623 status
= RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString
, &nameA
, FALSE
);
624 if (status
!= STATUS_SUCCESS
)
626 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
629 return CreateMutexExW( sa
, NtCurrentTeb()->StaticUnicodeString
.Buffer
, flags
, access
);
633 /***********************************************************************
634 * CreateMutexExW (kernelbase.@)
636 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
637 DWORD flags
, DWORD access
)
640 UNICODE_STRING nameW
;
641 OBJECT_ATTRIBUTES attr
;
644 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
646 status
= NtCreateMutant( &ret
, access
, &attr
, (flags
& CREATE_MUTEX_INITIAL_OWNER
) != 0 );
647 if (status
== STATUS_OBJECT_NAME_EXISTS
)
648 SetLastError( ERROR_ALREADY_EXISTS
);
650 SetLastError( RtlNtStatusToDosError(status
) );
655 /***********************************************************************
656 * OpenMutexW (kernelbase.@)
658 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
661 UNICODE_STRING nameW
;
662 OBJECT_ATTRIBUTES attr
;
664 if (!is_version_nt()) access
= MUTEX_ALL_ACCESS
;
666 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
668 if (!set_ntstatus( NtOpenMutant( &ret
, access
, &attr
))) return 0;
673 /***********************************************************************
674 * ReleaseMutex (kernelbase.@)
676 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseMutex( HANDLE handle
)
678 return set_ntstatus( NtReleaseMutant( handle
, NULL
));
682 /***********************************************************************
684 ***********************************************************************/
687 /***********************************************************************
688 * CreateSemaphoreW (kernelbase.@)
690 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreW( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
691 LONG max
, LPCWSTR name
)
693 return CreateSemaphoreExW( sa
, initial
, max
, name
, 0, SEMAPHORE_ALL_ACCESS
);
697 /***********************************************************************
698 * CreateSemaphoreExW (kernelbase.@)
700 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreExW( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
,
701 LPCWSTR name
, DWORD flags
, DWORD access
)
704 UNICODE_STRING nameW
;
705 OBJECT_ATTRIBUTES attr
;
708 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
710 status
= NtCreateSemaphore( &ret
, access
, &attr
, initial
, max
);
711 if (status
== STATUS_OBJECT_NAME_EXISTS
)
712 SetLastError( ERROR_ALREADY_EXISTS
);
714 SetLastError( RtlNtStatusToDosError(status
) );
719 /***********************************************************************
720 * OpenSemaphoreW (kernelbase.@)
722 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
725 UNICODE_STRING nameW
;
726 OBJECT_ATTRIBUTES attr
;
728 if (!is_version_nt()) access
= SEMAPHORE_ALL_ACCESS
;
730 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
732 if (!set_ntstatus( NtOpenSemaphore( &ret
, access
, &attr
))) return 0;
737 /***********************************************************************
738 * ReleaseSemaphore (kernelbase.@)
740 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseSemaphore( HANDLE handle
, LONG count
, LONG
*previous
)
742 return set_ntstatus( NtReleaseSemaphore( handle
, count
, (PULONG
)previous
));
746 /***********************************************************************
748 ***********************************************************************/
751 /***********************************************************************
752 * CreateWaitableTimerW (kernelbase.@)
754 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerW( SECURITY_ATTRIBUTES
*sa
, BOOL manual
, LPCWSTR name
)
756 return CreateWaitableTimerExW( sa
, name
, manual
? CREATE_WAITABLE_TIMER_MANUAL_RESET
: 0,
761 /***********************************************************************
762 * CreateWaitableTimerExW (kernelbase.@)
764 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
765 DWORD flags
, DWORD access
)
769 UNICODE_STRING nameW
;
770 OBJECT_ATTRIBUTES attr
;
772 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
774 status
= NtCreateTimer( &handle
, access
, &attr
,
775 (flags
& CREATE_WAITABLE_TIMER_MANUAL_RESET
) ? NotificationTimer
: SynchronizationTimer
);
776 if (status
== STATUS_OBJECT_NAME_EXISTS
)
777 SetLastError( ERROR_ALREADY_EXISTS
);
779 SetLastError( RtlNtStatusToDosError(status
) );
784 /***********************************************************************
785 * OpenWaitableTimerW (kernelbase.@)
787 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenWaitableTimerW( DWORD access
, BOOL inherit
, LPCWSTR name
)
790 UNICODE_STRING nameW
;
791 OBJECT_ATTRIBUTES attr
;
793 if (!is_version_nt()) access
= TIMER_ALL_ACCESS
;
795 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
797 if (!set_ntstatus( NtOpenTimer( &handle
, access
, &attr
))) return 0;
802 /***********************************************************************
803 * SetWaitableTimer (kernelbase.@)
805 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimer( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
806 PTIMERAPCROUTINE callback
, LPVOID arg
, BOOL resume
)
808 NTSTATUS status
= NtSetTimer( handle
, when
, (PTIMER_APC_ROUTINE
)callback
,
809 arg
, resume
, period
, NULL
);
810 return set_ntstatus( status
) || status
== STATUS_TIMER_RESUME_IGNORED
;
814 /***********************************************************************
815 * SetWaitableTimerEx (kernelbase.@)
817 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimerEx( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
818 PTIMERAPCROUTINE callback
, LPVOID arg
,
819 REASON_CONTEXT
*context
, ULONG tolerabledelay
)
822 if (!once
++) FIXME( "(%p, %p, %ld, %p, %p, %p, %ld) semi-stub\n",
823 handle
, when
, period
, callback
, arg
, context
, tolerabledelay
);
825 return SetWaitableTimer( handle
, when
, period
, callback
, arg
, FALSE
);
829 /***********************************************************************
830 * CancelWaitableTimer (kernelbase.@)
832 BOOL WINAPI DECLSPEC_HOTPATCH
CancelWaitableTimer( HANDLE handle
)
834 return set_ntstatus( NtCancelTimer( handle
, NULL
));
838 /***********************************************************************
840 ***********************************************************************/
843 /***********************************************************************
844 * CreateTimerQueue (kernelbase.@)
846 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateTimerQueue(void)
850 if (!set_ntstatus( RtlCreateTimerQueue( &q
))) return NULL
;
855 /***********************************************************************
856 * CreateTimerQueueTimer (kernelbase.@)
858 BOOL WINAPI DECLSPEC_HOTPATCH
CreateTimerQueueTimer( PHANDLE timer
, HANDLE queue
,
859 WAITORTIMERCALLBACK callback
, PVOID arg
,
860 DWORD when
, DWORD period
, ULONG flags
)
862 return set_ntstatus( RtlCreateTimer( queue
, timer
, callback
, arg
, when
, period
, flags
));
866 /***********************************************************************
867 * ChangeTimerQueueTimer (kernelbase.@)
869 BOOL WINAPI DECLSPEC_HOTPATCH
ChangeTimerQueueTimer( HANDLE queue
, HANDLE timer
,
870 ULONG when
, ULONG period
)
872 return set_ntstatus( RtlUpdateTimer( queue
, timer
, when
, period
));
876 /***********************************************************************
877 * DeleteTimerQueueEx (kernelbase.@)
879 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueEx( HANDLE queue
, HANDLE event
)
881 return set_ntstatus( RtlDeleteTimerQueueEx( queue
, event
));
885 /***********************************************************************
886 * DeleteTimerQueueTimer (kernelbase.@)
888 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueTimer( HANDLE queue
, HANDLE timer
, HANDLE event
)
890 return set_ntstatus( RtlDeleteTimer( queue
, timer
, event
));
894 /***********************************************************************
896 ***********************************************************************/
899 /***********************************************************************
900 * InitializeCriticalSectionAndSpinCount (kernelbase.@)
902 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION
*crit
, DWORD count
)
904 return !RtlInitializeCriticalSectionAndSpinCount( crit
, count
);
907 /***********************************************************************
908 * InitializeCriticalSectionEx (kernelbase.@)
910 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionEx( CRITICAL_SECTION
*crit
, DWORD spincount
,
913 NTSTATUS ret
= RtlInitializeCriticalSectionEx( crit
, spincount
, flags
);
914 if (ret
) RtlRaiseStatus( ret
);
919 /***********************************************************************
921 ***********************************************************************/
923 /***********************************************************************
924 * CreateFileMappingW (kernelbase.@)
926 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingW( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, DWORD protect
,
927 DWORD size_high
, DWORD size_low
, LPCWSTR name
)
929 static const int sec_flags
= (SEC_FILE
| SEC_IMAGE
| SEC_RESERVE
| SEC_COMMIT
|
930 SEC_NOCACHE
| SEC_WRITECOMBINE
| SEC_LARGE_PAGES
);
933 DWORD access
, sec_type
;
935 UNICODE_STRING nameW
;
936 OBJECT_ATTRIBUTES attr
;
938 sec_type
= protect
& sec_flags
;
939 protect
&= ~sec_flags
;
940 if (!sec_type
) sec_type
= SEC_COMMIT
;
942 /* Win9x compatibility */
943 if (!protect
&& !is_version_nt()) protect
= PAGE_READONLY
;
949 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
952 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
;
954 case PAGE_EXECUTE_READ
:
955 case PAGE_EXECUTE_WRITECOPY
:
956 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_EXECUTE
;
958 case PAGE_EXECUTE_READWRITE
:
959 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
;
962 SetLastError( ERROR_INVALID_PARAMETER
);
966 size
.u
.LowPart
= size_low
;
967 size
.u
.HighPart
= size_high
;
969 if (file
== INVALID_HANDLE_VALUE
)
974 SetLastError( ERROR_INVALID_PARAMETER
);
979 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
981 status
= NtCreateSection( &ret
, access
, &attr
, &size
, protect
, sec_type
, file
);
982 if (status
== STATUS_OBJECT_NAME_EXISTS
)
983 SetLastError( ERROR_ALREADY_EXISTS
);
985 SetLastError( RtlNtStatusToDosError(status
) );
990 /***********************************************************************
991 * CreateFileMappingFromApp (kernelbase.@)
993 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingFromApp( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, ULONG protect
,
994 ULONG64 size
, LPCWSTR name
)
996 return CreateFileMappingW( file
, sa
, protect
, size
<< 32, size
, name
);
999 /***********************************************************************
1000 * OpenFileMappingW (kernelbase.@)
1002 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingW( DWORD access
, BOOL inherit
, LPCWSTR name
)
1004 OBJECT_ATTRIBUTES attr
;
1005 UNICODE_STRING nameW
;
1008 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
1010 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
1012 if (!is_version_nt())
1014 /* win9x doesn't do access checks, so try with full access first */
1015 if (!NtOpenSection( &ret
, access
| SECTION_MAP_READ
| SECTION_MAP_WRITE
, &attr
)) return ret
;
1018 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
1023 /***********************************************************************
1024 * OpenFileMappingFromApp (kernelbase.@)
1026 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingFromApp( ULONG access
, BOOL inherit
, LPCWSTR name
)
1028 OBJECT_ATTRIBUTES attr
;
1029 UNICODE_STRING nameW
;
1032 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
1034 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
1036 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
1041 /***********************************************************************
1042 * Condition variables
1043 ***********************************************************************/
1046 /***********************************************************************
1047 * SleepConditionVariableCS (kernelbase.@)
1049 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableCS( CONDITION_VARIABLE
*variable
,
1050 CRITICAL_SECTION
*crit
, DWORD timeout
)
1054 return set_ntstatus( RtlSleepConditionVariableCS( variable
, crit
, get_nt_timeout( &time
, timeout
)));
1058 /***********************************************************************
1059 * SleepConditionVariableSRW (kernelbase.@)
1061 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableSRW( RTL_CONDITION_VARIABLE
*variable
,
1062 RTL_SRWLOCK
*lock
, DWORD timeout
, ULONG flags
)
1066 return set_ntstatus( RtlSleepConditionVariableSRW( variable
, lock
,
1067 get_nt_timeout( &time
, timeout
), flags
));
1071 /***********************************************************************
1073 ***********************************************************************/
1076 /******************************************************************************
1077 * CreateIoCompletionPort (kernelbase.@)
1079 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateIoCompletionPort( HANDLE handle
, HANDLE port
,
1080 ULONG_PTR key
, DWORD threads
)
1082 FILE_COMPLETION_INFORMATION info
;
1083 IO_STATUS_BLOCK iosb
;
1086 TRACE( "(%p, %p, %08Ix, %08lx)\n", handle
, port
, key
, threads
);
1090 if (!set_ntstatus( NtCreateIoCompletion( &ret
, IO_COMPLETION_ALL_ACCESS
, NULL
, threads
)))
1093 else if (handle
== INVALID_HANDLE_VALUE
)
1095 SetLastError( ERROR_INVALID_PARAMETER
);
1099 if (handle
!= INVALID_HANDLE_VALUE
)
1101 info
.CompletionPort
= ret
;
1102 info
.CompletionKey
= key
;
1103 if (!set_ntstatus( NtSetInformationFile( handle
, &iosb
, &info
, sizeof(info
), FileCompletionInformation
)))
1105 if (!port
) CloseHandle( ret
);
1113 /******************************************************************************
1114 * GetQueuedCompletionStatus (kernelbase.@)
1116 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatus( HANDLE port
, LPDWORD count
, PULONG_PTR key
,
1117 LPOVERLAPPED
*overlapped
, DWORD timeout
)
1120 IO_STATUS_BLOCK iosb
;
1121 LARGE_INTEGER wait_time
;
1123 TRACE( "(%p,%p,%p,%p,%ld)\n", port
, count
, key
, overlapped
, timeout
);
1126 status
= NtRemoveIoCompletion( port
, key
, (PULONG_PTR
)overlapped
, &iosb
,
1127 get_nt_timeout( &wait_time
, timeout
) );
1128 if (status
== STATUS_SUCCESS
)
1130 *count
= iosb
.Information
;
1131 if (iosb
.u
.Status
>= 0) return TRUE
;
1132 SetLastError( RtlNtStatusToDosError(iosb
.u
.Status
) );
1136 if (status
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1137 else SetLastError( RtlNtStatusToDosError(status
) );
1141 /******************************************************************************
1142 * GetQueuedCompletionStatusEx (kernelbase.@)
1144 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatusEx( HANDLE port
, OVERLAPPED_ENTRY
*entries
,
1145 ULONG count
, ULONG
*written
,
1146 DWORD timeout
, BOOL alertable
)
1151 TRACE( "%p %p %lu %p %lu %u\n", port
, entries
, count
, written
, timeout
, alertable
);
1153 ret
= NtRemoveIoCompletionEx( port
, (FILE_IO_COMPLETION_INFORMATION
*)entries
, count
,
1154 written
, get_nt_timeout( &time
, timeout
), alertable
);
1155 if (ret
== STATUS_SUCCESS
) return TRUE
;
1156 else if (ret
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1157 else if (ret
== STATUS_USER_APC
) SetLastError( WAIT_IO_COMPLETION
);
1158 else SetLastError( RtlNtStatusToDosError(ret
) );
1163 /******************************************************************************
1164 * PostQueuedCompletionStatus (kernelbase.@)
1166 BOOL WINAPI DECLSPEC_HOTPATCH
PostQueuedCompletionStatus( HANDLE port
, DWORD count
,
1167 ULONG_PTR key
, LPOVERLAPPED overlapped
)
1169 TRACE( "%p %ld %08Ix %p\n", port
, count
, key
, overlapped
);
1171 return set_ntstatus( NtSetIoCompletion( port
, key
, (ULONG_PTR
)overlapped
, STATUS_SUCCESS
, count
));
1175 /***********************************************************************
1177 ***********************************************************************/
1180 /***********************************************************************
1181 * CallNamedPipeW (kernelbase.@)
1183 BOOL WINAPI DECLSPEC_HOTPATCH
CallNamedPipeW( LPCWSTR name
, LPVOID input
, DWORD in_size
,
1184 LPVOID output
, DWORD out_size
,
1185 LPDWORD read_size
, DWORD timeout
)
1191 TRACE( "%s %p %ld %p %ld %p %ld\n", debugstr_w(name
),
1192 input
, in_size
, output
, out_size
, read_size
, timeout
);
1194 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1195 if (pipe
== INVALID_HANDLE_VALUE
)
1197 if (!WaitNamedPipeW( name
, timeout
)) return FALSE
;
1198 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1199 if (pipe
== INVALID_HANDLE_VALUE
) return FALSE
;
1202 mode
= PIPE_READMODE_MESSAGE
;
1203 ret
= SetNamedPipeHandleState( pipe
, &mode
, NULL
, NULL
);
1204 if (ret
) ret
= TransactNamedPipe( pipe
, input
, in_size
, output
, out_size
, read_size
, NULL
);
1205 CloseHandle( pipe
);
1210 /***********************************************************************
1211 * ConnectNamedPipe (kernelbase.@)
1213 BOOL WINAPI DECLSPEC_HOTPATCH
ConnectNamedPipe( HANDLE pipe
, LPOVERLAPPED overlapped
)
1216 IO_STATUS_BLOCK status_block
;
1217 LPVOID cvalue
= NULL
;
1219 TRACE( "(%p,%p)\n", pipe
, overlapped
);
1223 overlapped
->Internal
= STATUS_PENDING
;
1224 overlapped
->InternalHigh
= 0;
1225 if (((ULONG_PTR
)overlapped
->hEvent
& 1) == 0) cvalue
= overlapped
;
1228 status
= NtFsControlFile( pipe
, overlapped
? overlapped
->hEvent
: NULL
, NULL
, cvalue
,
1229 overlapped
? (IO_STATUS_BLOCK
*)overlapped
: &status_block
,
1230 FSCTL_PIPE_LISTEN
, NULL
, 0, NULL
, 0 );
1231 if (status
== STATUS_PENDING
&& !overlapped
)
1233 WaitForSingleObject( pipe
, INFINITE
);
1234 status
= status_block
.u
.Status
;
1236 return set_ntstatus( status
);
1239 /***********************************************************************
1240 * CreateNamedPipeW (kernelbase.@)
1242 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateNamedPipeW( LPCWSTR name
, DWORD open_mode
, DWORD pipe_mode
,
1243 DWORD instances
, DWORD out_buff
, DWORD in_buff
,
1244 DWORD timeout
, LPSECURITY_ATTRIBUTES sa
)
1247 UNICODE_STRING nt_name
;
1248 OBJECT_ATTRIBUTES attr
;
1249 DWORD access
, options
, sharing
;
1250 BOOLEAN pipe_type
, read_mode
, non_block
;
1252 IO_STATUS_BLOCK iosb
;
1255 TRACE( "(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n", debugstr_w(name
),
1256 open_mode
, pipe_mode
, instances
, out_buff
, in_buff
, timeout
, sa
);
1258 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
))
1260 SetLastError( ERROR_PATH_NOT_FOUND
);
1261 return INVALID_HANDLE_VALUE
;
1263 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) )
1265 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
1266 RtlFreeUnicodeString( &nt_name
);
1267 return INVALID_HANDLE_VALUE
;
1270 attr
.Length
= sizeof(attr
);
1271 attr
.RootDirectory
= 0;
1272 attr
.ObjectName
= &nt_name
;
1273 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1274 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1275 attr
.SecurityQualityOfService
= NULL
;
1277 switch (open_mode
& 3)
1279 case PIPE_ACCESS_INBOUND
:
1280 sharing
= FILE_SHARE_WRITE
;
1281 access
= GENERIC_READ
;
1283 case PIPE_ACCESS_OUTBOUND
:
1284 sharing
= FILE_SHARE_READ
;
1285 access
= GENERIC_WRITE
;
1287 case PIPE_ACCESS_DUPLEX
:
1288 sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
1289 access
= GENERIC_READ
| GENERIC_WRITE
;
1292 SetLastError( ERROR_INVALID_PARAMETER
);
1293 return INVALID_HANDLE_VALUE
;
1295 access
|= SYNCHRONIZE
;
1297 if (open_mode
& WRITE_DAC
) access
|= WRITE_DAC
;
1298 if (open_mode
& WRITE_OWNER
) access
|= WRITE_OWNER
;
1299 if (open_mode
& ACCESS_SYSTEM_SECURITY
) access
|= ACCESS_SYSTEM_SECURITY
;
1300 if (open_mode
& FILE_FLAG_WRITE_THROUGH
) options
|= FILE_WRITE_THROUGH
;
1301 if (!(open_mode
& FILE_FLAG_OVERLAPPED
)) options
|= FILE_SYNCHRONOUS_IO_NONALERT
;
1302 pipe_type
= (pipe_mode
& PIPE_TYPE_MESSAGE
) != 0;
1303 read_mode
= (pipe_mode
& PIPE_READMODE_MESSAGE
) != 0;
1304 non_block
= (pipe_mode
& PIPE_NOWAIT
) != 0;
1305 if (instances
>= PIPE_UNLIMITED_INSTANCES
) instances
= ~0U;
1307 time
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1308 status
= NtCreateNamedPipeFile( &handle
, access
, &attr
, &iosb
, sharing
,
1309 FILE_OPEN_IF
, options
, pipe_type
,
1310 read_mode
, non_block
, instances
, in_buff
, out_buff
, &time
);
1311 RtlFreeUnicodeString( &nt_name
);
1312 if (!set_ntstatus( status
)) return INVALID_HANDLE_VALUE
;
1313 SetLastError( iosb
.Information
== FILE_CREATED
? ERROR_SUCCESS
: ERROR_ALREADY_EXISTS
);
1318 /******************************************************************
1319 * CreatePipe (kernelbase.@)
1321 BOOL WINAPI DECLSPEC_HOTPATCH
CreatePipe( HANDLE
*read_pipe
, HANDLE
*write_pipe
,
1322 SECURITY_ATTRIBUTES
*sa
, DWORD size
)
1324 static unsigned int index
;
1326 UNICODE_STRING nt_name
;
1327 OBJECT_ATTRIBUTES attr
;
1328 IO_STATUS_BLOCK iosb
;
1329 LARGE_INTEGER timeout
;
1331 *read_pipe
= *write_pipe
= INVALID_HANDLE_VALUE
;
1333 attr
.Length
= sizeof(attr
);
1334 attr
.RootDirectory
= 0;
1335 attr
.ObjectName
= &nt_name
;
1336 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1337 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1338 attr
.SecurityQualityOfService
= NULL
;
1340 if (!size
) size
= 4096;
1342 timeout
.QuadPart
= (ULONGLONG
)NMPWAIT_USE_DEFAULT_WAIT
* -10000;
1344 /* generate a unique pipe name (system wide) */
1347 swprintf( name
, ARRAY_SIZE(name
), L
"\\??\\pipe\\Win32.Pipes.%08lu.%08u",
1348 GetCurrentProcessId(), ++index
);
1349 RtlInitUnicodeString( &nt_name
, name
);
1350 if (!NtCreateNamedPipeFile( read_pipe
, GENERIC_READ
| FILE_WRITE_ATTRIBUTES
| SYNCHRONIZE
,
1351 &attr
, &iosb
, FILE_SHARE_WRITE
, FILE_OPEN_IF
,
1352 FILE_SYNCHRONOUS_IO_NONALERT
,
1353 FALSE
, FALSE
, FALSE
, 1, size
, size
, &timeout
))
1356 if (!set_ntstatus( NtOpenFile( write_pipe
, GENERIC_WRITE
| FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1357 &iosb
, 0, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
)))
1359 NtClose( *read_pipe
);
1366 /***********************************************************************
1367 * DisconnectNamedPipe (kernelbase.@)
1369 BOOL WINAPI DECLSPEC_HOTPATCH
DisconnectNamedPipe( HANDLE pipe
)
1371 IO_STATUS_BLOCK io_block
;
1373 TRACE( "(%p)\n", pipe
);
1374 return set_ntstatus( NtFsControlFile( pipe
, 0, NULL
, NULL
, &io_block
,
1375 FSCTL_PIPE_DISCONNECT
, NULL
, 0, NULL
, 0 ));
1379 /***********************************************************************
1380 * GetNamedPipeHandleStateW (kernelbase.@)
1382 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeHandleStateW( HANDLE pipe
, DWORD
*state
, DWORD
*instances
,
1383 DWORD
*max_count
, DWORD
*timeout
,
1384 WCHAR
*user
, DWORD size
)
1388 FIXME( "%p %p %p %p %p %p %ld: semi-stub\n", pipe
, state
, instances
, max_count
, timeout
, user
, size
);
1390 if (max_count
) *max_count
= 0;
1391 if (timeout
) *timeout
= 0;
1392 if (user
&& size
&& !GetEnvironmentVariableW( L
"WINEUSERNAME", user
, size
)) user
[0] = 0;
1396 FILE_PIPE_INFORMATION info
;
1398 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
), FilePipeInformation
)))
1401 *state
= (info
.ReadMode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
) |
1402 (info
.CompletionMode
? PIPE_NOWAIT
: PIPE_WAIT
);
1406 FILE_PIPE_LOCAL_INFORMATION info
;
1408 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
),
1409 FilePipeLocalInformation
)))
1411 *instances
= info
.CurrentInstances
;
1417 /***********************************************************************
1418 * GetNamedPipeInfo (kernelbase.@)
1420 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeInfo( HANDLE pipe
, LPDWORD flags
, LPDWORD out_size
,
1421 LPDWORD in_size
, LPDWORD instances
)
1423 FILE_PIPE_LOCAL_INFORMATION info
;
1424 IO_STATUS_BLOCK iosb
;
1426 if (!set_ntstatus( NtQueryInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeLocalInformation
)))
1431 *flags
= (info
.NamedPipeEnd
& FILE_PIPE_SERVER_END
) ? PIPE_SERVER_END
: PIPE_CLIENT_END
;
1432 *flags
|= (info
.NamedPipeType
& FILE_PIPE_TYPE_MESSAGE
) ? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
;
1434 if (out_size
) *out_size
= info
.OutboundQuota
;
1435 if (in_size
) *in_size
= info
.InboundQuota
;
1436 if (instances
) *instances
= info
.MaximumInstances
;
1441 /***********************************************************************
1442 * PeekNamedPipe (kernelbase.@)
1444 BOOL WINAPI DECLSPEC_HOTPATCH
PeekNamedPipe( HANDLE pipe
, LPVOID out_buffer
, DWORD size
,
1445 LPDWORD read_size
, LPDWORD avail
, LPDWORD message
)
1447 FILE_PIPE_PEEK_BUFFER local_buffer
;
1448 FILE_PIPE_PEEK_BUFFER
*buffer
= &local_buffer
;
1452 if (size
&& !(buffer
= HeapAlloc( GetProcessHeap(), 0,
1453 FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ))))
1455 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1459 status
= NtFsControlFile( pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0,
1460 buffer
, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ) );
1461 if (status
== STATUS_BUFFER_OVERFLOW
) status
= STATUS_SUCCESS
;
1464 ULONG count
= io
.Information
- FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
);
1465 if (avail
) *avail
= buffer
->ReadDataAvailable
;
1466 if (read_size
) *read_size
= count
;
1467 if (message
) *message
= buffer
->MessageLength
- count
;
1468 if (out_buffer
) memcpy( out_buffer
, buffer
->Data
, count
);
1470 else SetLastError( RtlNtStatusToDosError(status
) );
1472 if (buffer
!= &local_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
1477 /***********************************************************************
1478 * SetNamedPipeHandleState (kernelbase.@)
1480 BOOL WINAPI DECLSPEC_HOTPATCH
SetNamedPipeHandleState( HANDLE pipe
, LPDWORD mode
,
1481 LPDWORD count
, LPDWORD timeout
)
1483 FILE_PIPE_INFORMATION info
;
1484 IO_STATUS_BLOCK iosb
;
1485 NTSTATUS status
= STATUS_SUCCESS
;
1487 TRACE( "%p %p/%ld %p %p\n", pipe
, mode
, mode
? *mode
: 0, count
, timeout
);
1488 if (count
|| timeout
) FIXME( "Unsupported arguments\n" );
1492 if (*mode
& ~(PIPE_READMODE_MESSAGE
| PIPE_NOWAIT
)) status
= STATUS_INVALID_PARAMETER
;
1495 info
.CompletionMode
= (*mode
& PIPE_NOWAIT
) ?
1496 FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION
;
1497 info
.ReadMode
= (*mode
& PIPE_READMODE_MESSAGE
) ?
1498 FILE_PIPE_MESSAGE_MODE
: FILE_PIPE_BYTE_STREAM_MODE
;
1499 status
= NtSetInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeInformation
);
1502 return set_ntstatus( status
);
1505 /***********************************************************************
1506 * TransactNamedPipe (kernelbase.@)
1508 BOOL WINAPI DECLSPEC_HOTPATCH
TransactNamedPipe( HANDLE handle
, LPVOID write_buf
, DWORD write_size
,
1509 LPVOID read_buf
, DWORD read_size
, LPDWORD bytes_read
,
1510 LPOVERLAPPED overlapped
)
1512 IO_STATUS_BLOCK default_iosb
, *iosb
= &default_iosb
;
1513 HANDLE event
= NULL
;
1514 void *cvalue
= NULL
;
1517 TRACE( "%p %p %lu %p %lu %p %p\n", handle
,
1518 write_buf
, write_size
, read_buf
, read_size
, bytes_read
, overlapped
);
1522 event
= overlapped
->hEvent
;
1523 iosb
= (IO_STATUS_BLOCK
*)overlapped
;
1524 if (((ULONG_PTR
)event
& 1) == 0) cvalue
= overlapped
;
1528 iosb
->Information
= 0;
1531 status
= NtFsControlFile( handle
, event
, NULL
, cvalue
, iosb
, FSCTL_PIPE_TRANSCEIVE
,
1532 write_buf
, write_size
, read_buf
, read_size
);
1533 if (status
== STATUS_PENDING
&& !overlapped
)
1535 WaitForSingleObject(handle
, INFINITE
);
1536 status
= iosb
->u
.Status
;
1539 if (bytes_read
) *bytes_read
= overlapped
&& status
? 0 : iosb
->Information
;
1540 return set_ntstatus( status
);
1544 /***********************************************************************
1545 * WaitNamedPipeW (kernelbase.@)
1547 BOOL WINAPI DECLSPEC_HOTPATCH
WaitNamedPipeW( LPCWSTR name
, DWORD timeout
)
1549 static const int prefix_len
= sizeof(L
"\\??\\PIPE\\") - sizeof(WCHAR
);
1551 UNICODE_STRING nt_name
, pipe_dev_name
;
1552 FILE_PIPE_WAIT_FOR_BUFFER
*pipe_wait
;
1553 IO_STATUS_BLOCK iosb
;
1554 OBJECT_ATTRIBUTES attr
;
1558 TRACE( "%s 0x%08lx\n", debugstr_w(name
), timeout
);
1560 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
)) return FALSE
;
1562 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) ||
1563 nt_name
.Length
< prefix_len
||
1564 wcsnicmp( nt_name
.Buffer
, L
"\\??\\PIPE\\", prefix_len
/ sizeof(WCHAR
) ))
1566 RtlFreeUnicodeString( &nt_name
);
1567 SetLastError( ERROR_PATH_NOT_FOUND
);
1571 wait_size
= offsetof( FILE_PIPE_WAIT_FOR_BUFFER
, Name
[(nt_name
.Length
- prefix_len
) / sizeof(WCHAR
)] );
1572 if (!(pipe_wait
= HeapAlloc( GetProcessHeap(), 0, wait_size
)))
1574 RtlFreeUnicodeString( &nt_name
);
1575 SetLastError( ERROR_OUTOFMEMORY
);
1579 pipe_dev_name
.Buffer
= nt_name
.Buffer
;
1580 pipe_dev_name
.Length
= prefix_len
;
1581 pipe_dev_name
.MaximumLength
= prefix_len
;
1582 InitializeObjectAttributes( &attr
,&pipe_dev_name
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1583 status
= NtOpenFile( &pipe_dev
, FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1584 &iosb
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1585 FILE_SYNCHRONOUS_IO_NONALERT
);
1586 if (status
!= STATUS_SUCCESS
)
1588 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1589 RtlFreeUnicodeString( &nt_name
);
1590 SetLastError( ERROR_PATH_NOT_FOUND
);
1594 pipe_wait
->TimeoutSpecified
= !(timeout
== NMPWAIT_USE_DEFAULT_WAIT
);
1595 if (timeout
== NMPWAIT_WAIT_FOREVER
)
1596 pipe_wait
->Timeout
.QuadPart
= ((ULONGLONG
)0x7fffffff << 32) | 0xffffffff;
1598 pipe_wait
->Timeout
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1599 pipe_wait
->NameLength
= nt_name
.Length
- prefix_len
;
1600 memcpy( pipe_wait
->Name
, nt_name
.Buffer
+ prefix_len
/sizeof(WCHAR
), pipe_wait
->NameLength
);
1601 RtlFreeUnicodeString( &nt_name
);
1603 status
= NtFsControlFile( pipe_dev
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_WAIT
,
1604 pipe_wait
, wait_size
, NULL
, 0 );
1606 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1607 NtClose( pipe_dev
);
1608 return set_ntstatus( status
);
1613 /***********************************************************************
1614 * Interlocked functions
1615 ***********************************************************************/
1618 /***********************************************************************
1619 * InitOnceBeginInitialize (kernelbase.@)
1621 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceBeginInitialize( INIT_ONCE
*once
, DWORD flags
,
1622 BOOL
*pending
, void **context
)
1624 NTSTATUS status
= RtlRunOnceBeginInitialize( once
, flags
, context
);
1625 if (status
>= 0) *pending
= (status
== STATUS_PENDING
);
1626 else SetLastError( RtlNtStatusToDosError(status
) );
1631 /***********************************************************************
1632 * InitOnceComplete (kernelbase.@)
1634 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceComplete( INIT_ONCE
*once
, DWORD flags
, void *context
)
1636 return set_ntstatus( RtlRunOnceComplete( once
, flags
, context
));
1640 /***********************************************************************
1641 * InitOnceExecuteOnce (kernelbase.@)
1643 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceExecuteOnce( INIT_ONCE
*once
, PINIT_ONCE_FN func
,
1644 void *param
, void **context
)
1646 return !RtlRunOnceExecuteOnce( once
, (PRTL_RUN_ONCE_INIT_FN
)func
, param
, context
);
1651 /***********************************************************************
1652 * InterlockedCompareExchange (kernelbase.@)
1654 __ASM_STDCALL_FUNC(InterlockedCompareExchange
, 12,
1655 "movl 12(%esp),%eax\n\t"
1656 "movl 8(%esp),%ecx\n\t"
1657 "movl 4(%esp),%edx\n\t"
1658 "lock; cmpxchgl %ecx,(%edx)\n\t"
1661 /***********************************************************************
1662 * InterlockedExchange (kernelbase.@)
1664 __ASM_STDCALL_FUNC(InterlockedExchange
, 8,
1665 "movl 8(%esp),%eax\n\t"
1666 "movl 4(%esp),%edx\n\t"
1667 "lock; xchgl %eax,(%edx)\n\t"
1670 /***********************************************************************
1671 * InterlockedExchangeAdd (kernelbase.@)
1673 __ASM_STDCALL_FUNC(InterlockedExchangeAdd
, 8,
1674 "movl 8(%esp),%eax\n\t"
1675 "movl 4(%esp),%edx\n\t"
1676 "lock; xaddl %eax,(%edx)\n\t"
1679 /***********************************************************************
1680 * InterlockedIncrement (kernelbase.@)
1682 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
1683 "movl 4(%esp),%edx\n\t"
1685 "lock; xaddl %eax,(%edx)\n\t"
1689 /***********************************************************************
1690 * InterlockedDecrement (kernelbase.@)
1692 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
1693 "movl 4(%esp),%edx\n\t"
1695 "lock; xaddl %eax,(%edx)\n\t"
1699 #endif /* __i386__ */