2 * Kernel synchronization objects
4 * Copyright 1998 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define WIN32_NO_STATUS
27 #define NONAMELESSUNION
37 #include "kernelbase.h"
39 #include "wine/exception.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(sync
);
44 static const struct _KUSER_SHARED_DATA
*user_shared_data
= (struct _KUSER_SHARED_DATA
*)0x7ffe0000;
46 /* check if current version is NT or Win95 */
47 static inline BOOL
is_version_nt(void)
49 return !(GetVersion() & 0x80000000);
52 /* helper for kernel32->ntdll timeout format conversion */
53 static inline LARGE_INTEGER
*get_nt_timeout( LARGE_INTEGER
*time
, DWORD timeout
)
55 if (timeout
== INFINITE
) return NULL
;
56 time
->QuadPart
= (ULONGLONG
)timeout
* -10000;
61 /***********************************************************************
62 * BaseGetNamedObjectDirectory (kernelbase.@)
64 NTSTATUS WINAPI
BaseGetNamedObjectDirectory( HANDLE
*dir
)
69 OBJECT_ATTRIBUTES attr
;
70 NTSTATUS status
= STATUS_SUCCESS
;
76 swprintf( buffer
, ARRAY_SIZE(buffer
), L
"\\Sessions\\%u\\BaseNamedObjects",
77 NtCurrentTeb()->Peb
->SessionId
);
78 RtlInitUnicodeString( &str
, buffer
);
79 InitializeObjectAttributes(&attr
, &str
, 0, 0, NULL
);
80 status
= NtOpenDirectoryObject( &dir
, DIRECTORY_CREATE_OBJECT
|DIRECTORY_TRAVERSE
, &attr
);
81 if (!status
&& InterlockedCompareExchangePointer( &handle
, dir
, 0 ) != 0)
83 /* someone beat us here... */
91 static void get_create_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
92 SECURITY_ATTRIBUTES
*sa
, const WCHAR
*name
)
94 attr
->Length
= sizeof(*attr
);
95 attr
->RootDirectory
= 0;
96 attr
->ObjectName
= NULL
;
97 attr
->Attributes
= OBJ_OPENIF
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
98 attr
->SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
99 attr
->SecurityQualityOfService
= NULL
;
102 RtlInitUnicodeString( nameW
, name
);
103 attr
->ObjectName
= nameW
;
104 BaseGetNamedObjectDirectory( &attr
->RootDirectory
);
108 static BOOL
get_open_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
109 BOOL inherit
, const WCHAR
*name
)
115 SetLastError( ERROR_INVALID_PARAMETER
);
118 RtlInitUnicodeString( nameW
, name
);
119 BaseGetNamedObjectDirectory( &dir
);
120 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
125 /***********************************************************************
127 ***********************************************************************/
130 /*********************************************************************
131 * GetSystemTimes (kernelbase.@)
133 BOOL WINAPI DECLSPEC_HOTPATCH
GetSystemTimes( FILETIME
*idle
, FILETIME
*kernel
, FILETIME
*user
)
135 LARGE_INTEGER idle_time
, kernel_time
, user_time
;
136 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
*info
;
138 DWORD i
, cpus
= NtCurrentTeb()->Peb
->NumberOfProcessors
;
140 if (!(info
= HeapAlloc( GetProcessHeap(), 0, sizeof(*info
) * cpus
)))
142 SetLastError( ERROR_OUTOFMEMORY
);
145 if (!set_ntstatus( NtQuerySystemInformation( SystemProcessorPerformanceInformation
, info
,
146 sizeof(*info
) * cpus
, &ret_size
)))
148 HeapFree( GetProcessHeap(), 0, info
);
151 idle_time
.QuadPart
= 0;
152 kernel_time
.QuadPart
= 0;
153 user_time
.QuadPart
= 0;
154 for (i
= 0; i
< cpus
; i
++)
156 idle_time
.QuadPart
+= info
[i
].IdleTime
.QuadPart
;
157 kernel_time
.QuadPart
+= info
[i
].KernelTime
.QuadPart
;
158 user_time
.QuadPart
+= info
[i
].UserTime
.QuadPart
;
162 idle
->dwLowDateTime
= idle_time
.u
.LowPart
;
163 idle
->dwHighDateTime
= idle_time
.u
.HighPart
;
167 kernel
->dwLowDateTime
= kernel_time
.u
.LowPart
;
168 kernel
->dwHighDateTime
= kernel_time
.u
.HighPart
;
172 user
->dwLowDateTime
= user_time
.u
.LowPart
;
173 user
->dwHighDateTime
= user_time
.u
.HighPart
;
175 HeapFree( GetProcessHeap(), 0, info
);
180 /******************************************************************************
181 * GetTickCount (kernelbase.@)
183 ULONG WINAPI DECLSPEC_HOTPATCH
GetTickCount(void)
185 /* note: we ignore TickCountMultiplier */
186 return user_shared_data
->u
.TickCount
.LowPart
;
190 /******************************************************************************
191 * GetTickCount64 (kernelbase.@)
193 ULONGLONG WINAPI DECLSPEC_HOTPATCH
GetTickCount64(void)
199 high
= user_shared_data
->u
.TickCount
.High1Time
;
200 low
= user_shared_data
->u
.TickCount
.LowPart
;
202 while (high
!= user_shared_data
->u
.TickCount
.High2Time
);
203 /* note: we ignore TickCountMultiplier */
204 return (ULONGLONG
)high
<< 32 | low
;
208 /***********************************************************************
210 ***********************************************************************/
213 static HANDLE
normalize_std_handle( HANDLE handle
)
215 if ((handle
== (HANDLE
)STD_INPUT_HANDLE
) ||
216 (handle
== (HANDLE
)STD_OUTPUT_HANDLE
) ||
217 (handle
== (HANDLE
)STD_ERROR_HANDLE
))
218 return GetStdHandle( HandleToULong(handle
) );
224 /***********************************************************************
225 * RegisterWaitForSingleObjectEx (kernelbase.@)
227 HANDLE WINAPI DECLSPEC_HOTPATCH
RegisterWaitForSingleObjectEx( HANDLE handle
, WAITORTIMERCALLBACK callback
,
228 PVOID context
, ULONG timeout
, ULONG flags
)
232 TRACE( "%p %p %p %ld %ld\n", handle
, callback
, context
, timeout
, flags
);
234 handle
= normalize_std_handle( handle
);
235 if (!set_ntstatus( RtlRegisterWait( &ret
, handle
, callback
, context
, timeout
, flags
))) return NULL
;
240 /***********************************************************************
241 * SignalObjectAndWait (kernelbase.@)
243 DWORD WINAPI DECLSPEC_HOTPATCH
SignalObjectAndWait( HANDLE signal
, HANDLE wait
,
244 DWORD timeout
, BOOL alertable
)
249 TRACE( "%p %p %ld %d\n", signal
, wait
, timeout
, alertable
);
251 status
= NtSignalAndWaitForSingleObject( signal
, wait
, alertable
, get_nt_timeout( &time
, timeout
) );
254 SetLastError( RtlNtStatusToDosError(status
) );
255 status
= WAIT_FAILED
;
261 /***********************************************************************
262 * Sleep (kernelbase.@)
264 void WINAPI DECLSPEC_HOTPATCH
Sleep( DWORD timeout
)
268 NtDelayExecution( FALSE
, get_nt_timeout( &time
, timeout
) );
272 /******************************************************************************
273 * SleepEx (kernelbase.@)
275 DWORD WINAPI DECLSPEC_HOTPATCH
SleepEx( DWORD timeout
, BOOL alertable
)
280 status
= NtDelayExecution( alertable
, get_nt_timeout( &time
, timeout
) );
281 if (status
== STATUS_USER_APC
) return WAIT_IO_COMPLETION
;
286 /***********************************************************************
287 * UnregisterWaitEx (kernelbase.@)
289 BOOL WINAPI DECLSPEC_HOTPATCH
UnregisterWaitEx( HANDLE handle
, HANDLE event
)
291 return set_ntstatus( RtlDeregisterWaitEx( handle
, event
));
295 /***********************************************************************
296 * WaitForSingleObject (kernelbase.@)
298 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObject( HANDLE handle
, DWORD timeout
)
300 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, FALSE
);
304 /***********************************************************************
305 * WaitForSingleObjectEx (kernelbase.@)
307 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForSingleObjectEx( HANDLE handle
, DWORD timeout
, BOOL alertable
)
309 return WaitForMultipleObjectsEx( 1, &handle
, FALSE
, timeout
, alertable
);
313 /***********************************************************************
314 * WaitForMultipleObjects (kernelbase.@)
316 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjects( DWORD count
, const HANDLE
*handles
,
317 BOOL wait_all
, DWORD timeout
)
319 return WaitForMultipleObjectsEx( count
, handles
, wait_all
, timeout
, FALSE
);
323 /***********************************************************************
324 * WaitForMultipleObjectsEx (kernelbase.@)
326 DWORD WINAPI DECLSPEC_HOTPATCH
WaitForMultipleObjectsEx( DWORD count
, const HANDLE
*handles
,
327 BOOL wait_all
, DWORD timeout
, BOOL alertable
)
330 HANDLE hloc
[MAXIMUM_WAIT_OBJECTS
];
334 if (count
> MAXIMUM_WAIT_OBJECTS
)
336 SetLastError(ERROR_INVALID_PARAMETER
);
339 for (i
= 0; i
< count
; i
++) hloc
[i
] = normalize_std_handle( handles
[i
] );
341 status
= NtWaitForMultipleObjects( count
, hloc
, !wait_all
, alertable
,
342 get_nt_timeout( &time
, timeout
) );
343 if (HIWORD(status
)) /* is it an error code? */
345 SetLastError( RtlNtStatusToDosError(status
) );
346 status
= WAIT_FAILED
;
352 /******************************************************************************
353 * WaitForDebugEvent (kernelbase.@)
355 BOOL WINAPI DECLSPEC_HOTPATCH
WaitForDebugEvent( DEBUG_EVENT
*event
, DWORD timeout
)
359 DBGUI_WAIT_STATE_CHANGE state
;
363 status
= DbgUiWaitStateChange( &state
, get_nt_timeout( &time
, timeout
) );
367 DbgUiConvertStateChangeStructure( &state
, event
);
369 case STATUS_USER_APC
:
372 SetLastError( ERROR_SEM_TIMEOUT
);
375 return set_ntstatus( status
);
381 /***********************************************************************
382 * WaitOnAddress (kernelbase.@)
384 BOOL WINAPI DECLSPEC_HOTPATCH
WaitOnAddress( volatile void *addr
, void *cmp
, SIZE_T size
, DWORD timeout
)
388 if (timeout
!= INFINITE
)
390 to
.QuadPart
= -(LONGLONG
)timeout
* 10000;
391 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, &to
));
393 return set_ntstatus( RtlWaitOnAddress( (const void *)addr
, cmp
, size
, NULL
));
397 /***********************************************************************
399 ***********************************************************************/
402 /***********************************************************************
403 * CreateEventA (kernelbase.@)
405 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventA( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
406 BOOL initial_state
, LPCSTR name
)
410 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
411 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
412 return CreateEventExA( sa
, name
, flags
, EVENT_ALL_ACCESS
);
416 /***********************************************************************
417 * CreateEventW (kernelbase.@)
419 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventW( SECURITY_ATTRIBUTES
*sa
, BOOL manual_reset
,
420 BOOL initial_state
, LPCWSTR name
)
424 if (manual_reset
) flags
|= CREATE_EVENT_MANUAL_RESET
;
425 if (initial_state
) flags
|= CREATE_EVENT_INITIAL_SET
;
426 return CreateEventExW( sa
, name
, flags
, EVENT_ALL_ACCESS
);
430 /***********************************************************************
431 * CreateEventExA (kernelbase.@)
433 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
434 DWORD flags
, DWORD access
)
436 WCHAR buffer
[MAX_PATH
];
438 if (!name
) return CreateEventExW( sa
, NULL
, flags
, access
);
440 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
442 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
445 return CreateEventExW( sa
, buffer
, flags
, access
);
449 /***********************************************************************
450 * CreateEventExW (kernelbase.@)
452 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateEventExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
453 DWORD flags
, DWORD access
)
456 UNICODE_STRING nameW
;
457 OBJECT_ATTRIBUTES attr
;
460 /* one buggy program needs this
461 * ("Van Dale Groot woordenboek der Nederlandse taal")
465 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
469 SetLastError( ERROR_INVALID_PARAMETER
);
474 status
= NtCreateEvent( &ret
, access
, &attr
,
475 (flags
& CREATE_EVENT_MANUAL_RESET
) ? NotificationEvent
: SynchronizationEvent
,
476 (flags
& CREATE_EVENT_INITIAL_SET
) != 0 );
477 if (status
== STATUS_OBJECT_NAME_EXISTS
)
478 SetLastError( ERROR_ALREADY_EXISTS
);
480 SetLastError( RtlNtStatusToDosError(status
) );
485 /***********************************************************************
486 * OpenEventA (kernelbase.@)
488 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventA( DWORD access
, BOOL inherit
, LPCSTR name
)
490 WCHAR buffer
[MAX_PATH
];
492 if (!name
) return OpenEventW( access
, inherit
, NULL
);
494 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
496 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
499 return OpenEventW( access
, inherit
, buffer
);
503 /***********************************************************************
504 * OpenEventW (kernelbase.@)
506 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenEventW( DWORD access
, BOOL inherit
, LPCWSTR name
)
509 UNICODE_STRING nameW
;
510 OBJECT_ATTRIBUTES attr
;
512 if (!is_version_nt()) access
= EVENT_ALL_ACCESS
;
514 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
516 if (!set_ntstatus( NtOpenEvent( &ret
, access
, &attr
))) return 0;
520 /***********************************************************************
521 * PulseEvent (kernelbase.@)
523 BOOL WINAPI DECLSPEC_HOTPATCH
PulseEvent( HANDLE handle
)
525 return set_ntstatus( NtPulseEvent( handle
, NULL
));
529 /***********************************************************************
530 * SetEvent (kernelbase.@)
532 BOOL WINAPI DECLSPEC_HOTPATCH
SetEvent( HANDLE handle
)
534 return set_ntstatus( NtSetEvent( handle
, NULL
));
538 /***********************************************************************
539 * ResetEvent (kernelbase.@)
541 BOOL WINAPI DECLSPEC_HOTPATCH
ResetEvent( HANDLE handle
)
543 return set_ntstatus( NtResetEvent( handle
, NULL
));
547 /***********************************************************************
549 ***********************************************************************/
552 /***********************************************************************
553 * CreateMutexA (kernelbase.@)
555 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexA( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCSTR name
)
557 return CreateMutexExA( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
561 /***********************************************************************
562 * CreateMutexW (kernelbase.@)
564 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexW( SECURITY_ATTRIBUTES
*sa
, BOOL owner
, LPCWSTR name
)
566 return CreateMutexExW( sa
, name
, owner
? CREATE_MUTEX_INITIAL_OWNER
: 0, MUTEX_ALL_ACCESS
);
570 /***********************************************************************
571 * CreateMutexExA (kernelbase.@)
573 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
,
574 DWORD flags
, DWORD access
)
579 if (!name
) return CreateMutexExW( sa
, NULL
, flags
, access
);
581 RtlInitAnsiString( &nameA
, name
);
582 status
= RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString
, &nameA
, FALSE
);
583 if (status
!= STATUS_SUCCESS
)
585 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
588 return CreateMutexExW( sa
, NtCurrentTeb()->StaticUnicodeString
.Buffer
, flags
, access
);
592 /***********************************************************************
593 * CreateMutexExW (kernelbase.@)
595 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateMutexExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
596 DWORD flags
, DWORD access
)
599 UNICODE_STRING nameW
;
600 OBJECT_ATTRIBUTES attr
;
603 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
605 status
= NtCreateMutant( &ret
, access
, &attr
, (flags
& CREATE_MUTEX_INITIAL_OWNER
) != 0 );
606 if (status
== STATUS_OBJECT_NAME_EXISTS
)
607 SetLastError( ERROR_ALREADY_EXISTS
);
609 SetLastError( RtlNtStatusToDosError(status
) );
614 /***********************************************************************
615 * OpenMutexW (kernelbase.@)
617 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexW( DWORD access
, BOOL inherit
, LPCWSTR name
)
620 UNICODE_STRING nameW
;
621 OBJECT_ATTRIBUTES attr
;
623 if (!is_version_nt()) access
= MUTEX_ALL_ACCESS
;
625 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
627 if (!set_ntstatus( NtOpenMutant( &ret
, access
, &attr
))) return 0;
632 /***********************************************************************
633 * ReleaseMutex (kernelbase.@)
635 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseMutex( HANDLE handle
)
637 return set_ntstatus( NtReleaseMutant( handle
, NULL
));
641 /***********************************************************************
643 ***********************************************************************/
646 /***********************************************************************
647 * CreateSemaphoreW (kernelbase.@)
649 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreW( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
650 LONG max
, LPCWSTR name
)
652 return CreateSemaphoreExW( sa
, initial
, max
, name
, 0, SEMAPHORE_ALL_ACCESS
);
656 /***********************************************************************
657 * CreateSemaphoreExW (kernelbase.@)
659 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreExW( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
,
660 LPCWSTR name
, DWORD flags
, DWORD access
)
663 UNICODE_STRING nameW
;
664 OBJECT_ATTRIBUTES attr
;
667 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
669 status
= NtCreateSemaphore( &ret
, access
, &attr
, initial
, max
);
670 if (status
== STATUS_OBJECT_NAME_EXISTS
)
671 SetLastError( ERROR_ALREADY_EXISTS
);
673 SetLastError( RtlNtStatusToDosError(status
) );
678 /***********************************************************************
679 * OpenSemaphoreW (kernelbase.@)
681 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreW( DWORD access
, BOOL inherit
, LPCWSTR name
)
684 UNICODE_STRING nameW
;
685 OBJECT_ATTRIBUTES attr
;
687 if (!is_version_nt()) access
= SEMAPHORE_ALL_ACCESS
;
689 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
691 if (!set_ntstatus( NtOpenSemaphore( &ret
, access
, &attr
))) return 0;
696 /***********************************************************************
697 * ReleaseSemaphore (kernelbase.@)
699 BOOL WINAPI DECLSPEC_HOTPATCH
ReleaseSemaphore( HANDLE handle
, LONG count
, LONG
*previous
)
701 return set_ntstatus( NtReleaseSemaphore( handle
, count
, (PULONG
)previous
));
705 /***********************************************************************
707 ***********************************************************************/
710 /***********************************************************************
711 * CreateWaitableTimerW (kernelbase.@)
713 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerW( SECURITY_ATTRIBUTES
*sa
, BOOL manual
, LPCWSTR name
)
715 return CreateWaitableTimerExW( sa
, name
, manual
? CREATE_WAITABLE_TIMER_MANUAL_RESET
: 0,
720 /***********************************************************************
721 * CreateWaitableTimerExW (kernelbase.@)
723 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateWaitableTimerExW( SECURITY_ATTRIBUTES
*sa
, LPCWSTR name
,
724 DWORD flags
, DWORD access
)
728 UNICODE_STRING nameW
;
729 OBJECT_ATTRIBUTES attr
;
731 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
733 status
= NtCreateTimer( &handle
, access
, &attr
,
734 (flags
& CREATE_WAITABLE_TIMER_MANUAL_RESET
) ? NotificationTimer
: SynchronizationTimer
);
735 if (status
== STATUS_OBJECT_NAME_EXISTS
)
736 SetLastError( ERROR_ALREADY_EXISTS
);
738 SetLastError( RtlNtStatusToDosError(status
) );
743 /***********************************************************************
744 * OpenWaitableTimerW (kernelbase.@)
746 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenWaitableTimerW( DWORD access
, BOOL inherit
, LPCWSTR name
)
749 UNICODE_STRING nameW
;
750 OBJECT_ATTRIBUTES attr
;
752 if (!is_version_nt()) access
= TIMER_ALL_ACCESS
;
754 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
756 if (!set_ntstatus( NtOpenTimer( &handle
, access
, &attr
))) return 0;
761 /***********************************************************************
762 * SetWaitableTimer (kernelbase.@)
764 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimer( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
765 PTIMERAPCROUTINE callback
, LPVOID arg
, BOOL resume
)
767 NTSTATUS status
= NtSetTimer( handle
, when
, (PTIMER_APC_ROUTINE
)callback
,
768 arg
, resume
, period
, NULL
);
769 return set_ntstatus( status
) || status
== STATUS_TIMER_RESUME_IGNORED
;
773 /***********************************************************************
774 * SetWaitableTimerEx (kernelbase.@)
776 BOOL WINAPI DECLSPEC_HOTPATCH
SetWaitableTimerEx( HANDLE handle
, const LARGE_INTEGER
*when
, LONG period
,
777 PTIMERAPCROUTINE callback
, LPVOID arg
,
778 REASON_CONTEXT
*context
, ULONG tolerabledelay
)
781 if (!once
++) FIXME( "(%p, %p, %ld, %p, %p, %p, %ld) semi-stub\n",
782 handle
, when
, period
, callback
, arg
, context
, tolerabledelay
);
784 return SetWaitableTimer( handle
, when
, period
, callback
, arg
, FALSE
);
788 /***********************************************************************
789 * CancelWaitableTimer (kernelbase.@)
791 BOOL WINAPI DECLSPEC_HOTPATCH
CancelWaitableTimer( HANDLE handle
)
793 return set_ntstatus( NtCancelTimer( handle
, NULL
));
797 /***********************************************************************
799 ***********************************************************************/
802 /***********************************************************************
803 * CreateTimerQueue (kernelbase.@)
805 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateTimerQueue(void)
809 if (!set_ntstatus( RtlCreateTimerQueue( &q
))) return NULL
;
814 /***********************************************************************
815 * CreateTimerQueueTimer (kernelbase.@)
817 BOOL WINAPI DECLSPEC_HOTPATCH
CreateTimerQueueTimer( PHANDLE timer
, HANDLE queue
,
818 WAITORTIMERCALLBACK callback
, PVOID arg
,
819 DWORD when
, DWORD period
, ULONG flags
)
821 return set_ntstatus( RtlCreateTimer( queue
, timer
, callback
, arg
, when
, period
, flags
));
825 /***********************************************************************
826 * ChangeTimerQueueTimer (kernelbase.@)
828 BOOL WINAPI DECLSPEC_HOTPATCH
ChangeTimerQueueTimer( HANDLE queue
, HANDLE timer
,
829 ULONG when
, ULONG period
)
831 return set_ntstatus( RtlUpdateTimer( queue
, timer
, when
, period
));
835 /***********************************************************************
836 * DeleteTimerQueueEx (kernelbase.@)
838 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueEx( HANDLE queue
, HANDLE event
)
840 return set_ntstatus( RtlDeleteTimerQueueEx( queue
, event
));
844 /***********************************************************************
845 * DeleteTimerQueueTimer (kernelbase.@)
847 BOOL WINAPI DECLSPEC_HOTPATCH
DeleteTimerQueueTimer( HANDLE queue
, HANDLE timer
, HANDLE event
)
849 return set_ntstatus( RtlDeleteTimer( queue
, timer
, event
));
853 /***********************************************************************
855 ***********************************************************************/
858 /***********************************************************************
859 * InitializeCriticalSectionAndSpinCount (kernelbase.@)
861 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION
*crit
, DWORD count
)
863 return !RtlInitializeCriticalSectionAndSpinCount( crit
, count
);
866 /***********************************************************************
867 * InitializeCriticalSectionEx (kernelbase.@)
869 BOOL WINAPI DECLSPEC_HOTPATCH
InitializeCriticalSectionEx( CRITICAL_SECTION
*crit
, DWORD spincount
,
872 NTSTATUS ret
= RtlInitializeCriticalSectionEx( crit
, spincount
, flags
);
873 if (ret
) RtlRaiseStatus( ret
);
878 /***********************************************************************
880 ***********************************************************************/
883 /***********************************************************************
884 * CreateFileMappingW (kernelbase.@)
886 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateFileMappingW( HANDLE file
, LPSECURITY_ATTRIBUTES sa
, DWORD protect
,
887 DWORD size_high
, DWORD size_low
, LPCWSTR name
)
889 static const int sec_flags
= (SEC_FILE
| SEC_IMAGE
| SEC_RESERVE
| SEC_COMMIT
|
890 SEC_NOCACHE
| SEC_WRITECOMBINE
| SEC_LARGE_PAGES
);
893 DWORD access
, sec_type
;
895 UNICODE_STRING nameW
;
896 OBJECT_ATTRIBUTES attr
;
898 sec_type
= protect
& sec_flags
;
899 protect
&= ~sec_flags
;
900 if (!sec_type
) sec_type
= SEC_COMMIT
;
902 /* Win9x compatibility */
903 if (!protect
&& !is_version_nt()) protect
= PAGE_READONLY
;
909 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
912 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
;
914 case PAGE_EXECUTE_READ
:
915 case PAGE_EXECUTE_WRITECOPY
:
916 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_EXECUTE
;
918 case PAGE_EXECUTE_READWRITE
:
919 access
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
;
922 SetLastError( ERROR_INVALID_PARAMETER
);
926 size
.u
.LowPart
= size_low
;
927 size
.u
.HighPart
= size_high
;
929 if (file
== INVALID_HANDLE_VALUE
)
934 SetLastError( ERROR_INVALID_PARAMETER
);
939 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
941 status
= NtCreateSection( &ret
, access
, &attr
, &size
, protect
, sec_type
, file
);
942 if (status
== STATUS_OBJECT_NAME_EXISTS
)
943 SetLastError( ERROR_ALREADY_EXISTS
);
945 SetLastError( RtlNtStatusToDosError(status
) );
950 /***********************************************************************
951 * OpenFileMappingW (kernelbase.@)
953 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenFileMappingW( DWORD access
, BOOL inherit
, LPCWSTR name
)
955 OBJECT_ATTRIBUTES attr
;
956 UNICODE_STRING nameW
;
959 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
961 if (access
== FILE_MAP_COPY
) access
= SECTION_MAP_READ
;
963 if (!is_version_nt())
965 /* win9x doesn't do access checks, so try with full access first */
966 if (!NtOpenSection( &ret
, access
| SECTION_MAP_READ
| SECTION_MAP_WRITE
, &attr
)) return ret
;
969 if (!set_ntstatus( NtOpenSection( &ret
, access
, &attr
))) return 0;
974 /***********************************************************************
975 * Condition variables
976 ***********************************************************************/
979 /***********************************************************************
980 * SleepConditionVariableCS (kernelbase.@)
982 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableCS( CONDITION_VARIABLE
*variable
,
983 CRITICAL_SECTION
*crit
, DWORD timeout
)
987 return set_ntstatus( RtlSleepConditionVariableCS( variable
, crit
, get_nt_timeout( &time
, timeout
)));
991 /***********************************************************************
992 * SleepConditionVariableSRW (kernelbase.@)
994 BOOL WINAPI DECLSPEC_HOTPATCH
SleepConditionVariableSRW( RTL_CONDITION_VARIABLE
*variable
,
995 RTL_SRWLOCK
*lock
, DWORD timeout
, ULONG flags
)
999 return set_ntstatus( RtlSleepConditionVariableSRW( variable
, lock
,
1000 get_nt_timeout( &time
, timeout
), flags
));
1004 /***********************************************************************
1006 ***********************************************************************/
1009 /******************************************************************************
1010 * CreateIoCompletionPort (kernelbase.@)
1012 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateIoCompletionPort( HANDLE handle
, HANDLE port
,
1013 ULONG_PTR key
, DWORD threads
)
1015 FILE_COMPLETION_INFORMATION info
;
1016 IO_STATUS_BLOCK iosb
;
1019 TRACE( "(%p, %p, %08Ix, %08lx)\n", handle
, port
, key
, threads
);
1023 if (!set_ntstatus( NtCreateIoCompletion( &ret
, IO_COMPLETION_ALL_ACCESS
, NULL
, threads
)))
1026 else if (handle
== INVALID_HANDLE_VALUE
)
1028 SetLastError( ERROR_INVALID_PARAMETER
);
1032 if (handle
!= INVALID_HANDLE_VALUE
)
1034 info
.CompletionPort
= ret
;
1035 info
.CompletionKey
= key
;
1036 if (!set_ntstatus( NtSetInformationFile( handle
, &iosb
, &info
, sizeof(info
), FileCompletionInformation
)))
1038 if (!port
) CloseHandle( ret
);
1046 /******************************************************************************
1047 * GetQueuedCompletionStatus (kernelbase.@)
1049 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatus( HANDLE port
, LPDWORD count
, PULONG_PTR key
,
1050 LPOVERLAPPED
*overlapped
, DWORD timeout
)
1053 IO_STATUS_BLOCK iosb
;
1054 LARGE_INTEGER wait_time
;
1056 TRACE( "(%p,%p,%p,%p,%ld)\n", port
, count
, key
, overlapped
, timeout
);
1059 status
= NtRemoveIoCompletion( port
, key
, (PULONG_PTR
)overlapped
, &iosb
,
1060 get_nt_timeout( &wait_time
, timeout
) );
1061 if (status
== STATUS_SUCCESS
)
1063 *count
= iosb
.Information
;
1064 if (iosb
.u
.Status
>= 0) return TRUE
;
1065 SetLastError( RtlNtStatusToDosError(iosb
.u
.Status
) );
1069 if (status
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1070 else SetLastError( RtlNtStatusToDosError(status
) );
1074 /******************************************************************************
1075 * GetQueuedCompletionStatusEx (kernelbase.@)
1077 BOOL WINAPI DECLSPEC_HOTPATCH
GetQueuedCompletionStatusEx( HANDLE port
, OVERLAPPED_ENTRY
*entries
,
1078 ULONG count
, ULONG
*written
,
1079 DWORD timeout
, BOOL alertable
)
1084 TRACE( "%p %p %lu %p %lu %u\n", port
, entries
, count
, written
, timeout
, alertable
);
1086 ret
= NtRemoveIoCompletionEx( port
, (FILE_IO_COMPLETION_INFORMATION
*)entries
, count
,
1087 written
, get_nt_timeout( &time
, timeout
), alertable
);
1088 if (ret
== STATUS_SUCCESS
) return TRUE
;
1089 else if (ret
== STATUS_TIMEOUT
) SetLastError( WAIT_TIMEOUT
);
1090 else if (ret
== STATUS_USER_APC
) SetLastError( WAIT_IO_COMPLETION
);
1091 else SetLastError( RtlNtStatusToDosError(ret
) );
1096 /******************************************************************************
1097 * PostQueuedCompletionStatus (kernelbase.@)
1099 BOOL WINAPI DECLSPEC_HOTPATCH
PostQueuedCompletionStatus( HANDLE port
, DWORD count
,
1100 ULONG_PTR key
, LPOVERLAPPED overlapped
)
1102 TRACE( "%p %ld %08Ix %p\n", port
, count
, key
, overlapped
);
1104 return set_ntstatus( NtSetIoCompletion( port
, key
, (ULONG_PTR
)overlapped
, STATUS_SUCCESS
, count
));
1108 /***********************************************************************
1110 ***********************************************************************/
1113 /***********************************************************************
1114 * CallNamedPipeW (kernelbase.@)
1116 BOOL WINAPI DECLSPEC_HOTPATCH
CallNamedPipeW( LPCWSTR name
, LPVOID input
, DWORD in_size
,
1117 LPVOID output
, DWORD out_size
,
1118 LPDWORD read_size
, DWORD timeout
)
1124 TRACE( "%s %p %ld %p %ld %p %ld\n", debugstr_w(name
),
1125 input
, in_size
, output
, out_size
, read_size
, timeout
);
1127 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1128 if (pipe
== INVALID_HANDLE_VALUE
)
1130 if (!WaitNamedPipeW( name
, timeout
)) return FALSE
;
1131 pipe
= CreateFileW( name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1132 if (pipe
== INVALID_HANDLE_VALUE
) return FALSE
;
1135 mode
= PIPE_READMODE_MESSAGE
;
1136 ret
= SetNamedPipeHandleState( pipe
, &mode
, NULL
, NULL
);
1137 if (ret
) ret
= TransactNamedPipe( pipe
, input
, in_size
, output
, out_size
, read_size
, NULL
);
1138 CloseHandle( pipe
);
1143 /***********************************************************************
1144 * ConnectNamedPipe (kernelbase.@)
1146 BOOL WINAPI DECLSPEC_HOTPATCH
ConnectNamedPipe( HANDLE pipe
, LPOVERLAPPED overlapped
)
1149 IO_STATUS_BLOCK status_block
;
1150 LPVOID cvalue
= NULL
;
1152 TRACE( "(%p,%p)\n", pipe
, overlapped
);
1156 overlapped
->Internal
= STATUS_PENDING
;
1157 overlapped
->InternalHigh
= 0;
1158 if (((ULONG_PTR
)overlapped
->hEvent
& 1) == 0) cvalue
= overlapped
;
1161 status
= NtFsControlFile( pipe
, overlapped
? overlapped
->hEvent
: NULL
, NULL
, cvalue
,
1162 overlapped
? (IO_STATUS_BLOCK
*)overlapped
: &status_block
,
1163 FSCTL_PIPE_LISTEN
, NULL
, 0, NULL
, 0 );
1164 if (status
== STATUS_PENDING
&& !overlapped
)
1166 WaitForSingleObject( pipe
, INFINITE
);
1167 status
= status_block
.u
.Status
;
1169 return set_ntstatus( status
);
1172 /***********************************************************************
1173 * CreateNamedPipeW (kernelbase.@)
1175 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateNamedPipeW( LPCWSTR name
, DWORD open_mode
, DWORD pipe_mode
,
1176 DWORD instances
, DWORD out_buff
, DWORD in_buff
,
1177 DWORD timeout
, LPSECURITY_ATTRIBUTES sa
)
1180 UNICODE_STRING nt_name
;
1181 OBJECT_ATTRIBUTES attr
;
1182 DWORD access
, options
, sharing
;
1183 BOOLEAN pipe_type
, read_mode
, non_block
;
1185 IO_STATUS_BLOCK iosb
;
1188 TRACE( "(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n", debugstr_w(name
),
1189 open_mode
, pipe_mode
, instances
, out_buff
, in_buff
, timeout
, sa
);
1191 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
))
1193 SetLastError( ERROR_PATH_NOT_FOUND
);
1194 return INVALID_HANDLE_VALUE
;
1196 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) )
1198 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
1199 RtlFreeUnicodeString( &nt_name
);
1200 return INVALID_HANDLE_VALUE
;
1203 attr
.Length
= sizeof(attr
);
1204 attr
.RootDirectory
= 0;
1205 attr
.ObjectName
= &nt_name
;
1206 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1207 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1208 attr
.SecurityQualityOfService
= NULL
;
1210 switch (open_mode
& 3)
1212 case PIPE_ACCESS_INBOUND
:
1213 sharing
= FILE_SHARE_WRITE
;
1214 access
= GENERIC_READ
;
1216 case PIPE_ACCESS_OUTBOUND
:
1217 sharing
= FILE_SHARE_READ
;
1218 access
= GENERIC_WRITE
;
1220 case PIPE_ACCESS_DUPLEX
:
1221 sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
1222 access
= GENERIC_READ
| GENERIC_WRITE
;
1225 SetLastError( ERROR_INVALID_PARAMETER
);
1226 return INVALID_HANDLE_VALUE
;
1228 access
|= SYNCHRONIZE
;
1230 if (open_mode
& WRITE_DAC
) access
|= WRITE_DAC
;
1231 if (open_mode
& WRITE_OWNER
) access
|= WRITE_OWNER
;
1232 if (open_mode
& ACCESS_SYSTEM_SECURITY
) access
|= ACCESS_SYSTEM_SECURITY
;
1233 if (open_mode
& FILE_FLAG_WRITE_THROUGH
) options
|= FILE_WRITE_THROUGH
;
1234 if (!(open_mode
& FILE_FLAG_OVERLAPPED
)) options
|= FILE_SYNCHRONOUS_IO_NONALERT
;
1235 pipe_type
= (pipe_mode
& PIPE_TYPE_MESSAGE
) != 0;
1236 read_mode
= (pipe_mode
& PIPE_READMODE_MESSAGE
) != 0;
1237 non_block
= (pipe_mode
& PIPE_NOWAIT
) != 0;
1238 if (instances
>= PIPE_UNLIMITED_INSTANCES
) instances
= ~0U;
1240 time
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1242 status
= NtCreateNamedPipeFile( &handle
, access
, &attr
, &iosb
, sharing
,
1243 FILE_OVERWRITE_IF
, options
, pipe_type
,
1244 read_mode
, non_block
, instances
, in_buff
, out_buff
, &time
);
1245 RtlFreeUnicodeString( &nt_name
);
1246 if (!set_ntstatus( status
)) return INVALID_HANDLE_VALUE
;
1251 /******************************************************************
1252 * CreatePipe (kernelbase.@)
1254 BOOL WINAPI DECLSPEC_HOTPATCH
CreatePipe( HANDLE
*read_pipe
, HANDLE
*write_pipe
,
1255 SECURITY_ATTRIBUTES
*sa
, DWORD size
)
1257 static unsigned int index
;
1259 UNICODE_STRING nt_name
;
1260 OBJECT_ATTRIBUTES attr
;
1261 IO_STATUS_BLOCK iosb
;
1262 LARGE_INTEGER timeout
;
1264 *read_pipe
= *write_pipe
= INVALID_HANDLE_VALUE
;
1266 attr
.Length
= sizeof(attr
);
1267 attr
.RootDirectory
= 0;
1268 attr
.ObjectName
= &nt_name
;
1269 attr
.Attributes
= OBJ_CASE_INSENSITIVE
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
1270 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
1271 attr
.SecurityQualityOfService
= NULL
;
1273 if (!size
) size
= 4096;
1275 timeout
.QuadPart
= (ULONGLONG
)NMPWAIT_USE_DEFAULT_WAIT
* -10000;
1277 /* generate a unique pipe name (system wide) */
1280 swprintf( name
, ARRAY_SIZE(name
), L
"\\??\\pipe\\Win32.Pipes.%08lu.%08u",
1281 GetCurrentProcessId(), ++index
);
1282 RtlInitUnicodeString( &nt_name
, name
);
1283 if (!NtCreateNamedPipeFile( read_pipe
, GENERIC_READ
| FILE_WRITE_ATTRIBUTES
| SYNCHRONIZE
,
1284 &attr
, &iosb
, FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
1285 FILE_SYNCHRONOUS_IO_NONALERT
,
1286 FALSE
, FALSE
, FALSE
, 1, size
, size
, &timeout
))
1289 if (!set_ntstatus( NtOpenFile( write_pipe
, GENERIC_WRITE
| FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1290 &iosb
, 0, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
)))
1292 NtClose( *read_pipe
);
1299 /***********************************************************************
1300 * DisconnectNamedPipe (kernelbase.@)
1302 BOOL WINAPI DECLSPEC_HOTPATCH
DisconnectNamedPipe( HANDLE pipe
)
1304 IO_STATUS_BLOCK io_block
;
1306 TRACE( "(%p)\n", pipe
);
1307 return set_ntstatus( NtFsControlFile( pipe
, 0, NULL
, NULL
, &io_block
,
1308 FSCTL_PIPE_DISCONNECT
, NULL
, 0, NULL
, 0 ));
1312 /***********************************************************************
1313 * GetNamedPipeHandleStateW (kernelbase.@)
1315 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeHandleStateW( HANDLE pipe
, DWORD
*state
, DWORD
*instances
,
1316 DWORD
*max_count
, DWORD
*timeout
,
1317 WCHAR
*user
, DWORD size
)
1321 FIXME( "%p %p %p %p %p %p %ld: semi-stub\n", pipe
, state
, instances
, max_count
, timeout
, user
, size
);
1323 if (max_count
) *max_count
= 0;
1324 if (timeout
) *timeout
= 0;
1325 if (user
&& size
&& !GetEnvironmentVariableW( L
"WINEUSERNAME", user
, size
)) user
[0] = 0;
1329 FILE_PIPE_INFORMATION info
;
1331 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
), FilePipeInformation
)))
1334 *state
= (info
.ReadMode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
) |
1335 (info
.CompletionMode
? PIPE_NOWAIT
: PIPE_WAIT
);
1339 FILE_PIPE_LOCAL_INFORMATION info
;
1341 if (!set_ntstatus( NtQueryInformationFile( pipe
, &io
, &info
, sizeof(info
),
1342 FilePipeLocalInformation
)))
1344 *instances
= info
.CurrentInstances
;
1350 /***********************************************************************
1351 * GetNamedPipeInfo (kernelbase.@)
1353 BOOL WINAPI DECLSPEC_HOTPATCH
GetNamedPipeInfo( HANDLE pipe
, LPDWORD flags
, LPDWORD out_size
,
1354 LPDWORD in_size
, LPDWORD instances
)
1356 FILE_PIPE_LOCAL_INFORMATION info
;
1357 IO_STATUS_BLOCK iosb
;
1359 if (!set_ntstatus( NtQueryInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeLocalInformation
)))
1364 *flags
= (info
.NamedPipeEnd
& FILE_PIPE_SERVER_END
) ? PIPE_SERVER_END
: PIPE_CLIENT_END
;
1365 *flags
|= (info
.NamedPipeType
& FILE_PIPE_TYPE_MESSAGE
) ? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
;
1367 if (out_size
) *out_size
= info
.OutboundQuota
;
1368 if (in_size
) *in_size
= info
.InboundQuota
;
1369 if (instances
) *instances
= info
.MaximumInstances
;
1374 /***********************************************************************
1375 * PeekNamedPipe (kernelbase.@)
1377 BOOL WINAPI DECLSPEC_HOTPATCH
PeekNamedPipe( HANDLE pipe
, LPVOID out_buffer
, DWORD size
,
1378 LPDWORD read_size
, LPDWORD avail
, LPDWORD message
)
1380 FILE_PIPE_PEEK_BUFFER local_buffer
;
1381 FILE_PIPE_PEEK_BUFFER
*buffer
= &local_buffer
;
1385 if (size
&& !(buffer
= HeapAlloc( GetProcessHeap(), 0,
1386 FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ))))
1388 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1392 status
= NtFsControlFile( pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0,
1393 buffer
, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
[size
] ) );
1394 if (status
== STATUS_BUFFER_OVERFLOW
) status
= STATUS_SUCCESS
;
1397 ULONG count
= io
.Information
- FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER
, Data
);
1398 if (avail
) *avail
= buffer
->ReadDataAvailable
;
1399 if (read_size
) *read_size
= count
;
1400 if (message
) *message
= buffer
->MessageLength
- count
;
1401 if (out_buffer
) memcpy( out_buffer
, buffer
->Data
, count
);
1403 else SetLastError( RtlNtStatusToDosError(status
) );
1405 if (buffer
!= &local_buffer
) HeapFree( GetProcessHeap(), 0, buffer
);
1410 /***********************************************************************
1411 * SetNamedPipeHandleState (kernelbase.@)
1413 BOOL WINAPI DECLSPEC_HOTPATCH
SetNamedPipeHandleState( HANDLE pipe
, LPDWORD mode
,
1414 LPDWORD count
, LPDWORD timeout
)
1416 FILE_PIPE_INFORMATION info
;
1417 IO_STATUS_BLOCK iosb
;
1418 NTSTATUS status
= STATUS_SUCCESS
;
1420 TRACE( "%p %p/%ld %p %p\n", pipe
, mode
, mode
? *mode
: 0, count
, timeout
);
1421 if (count
|| timeout
) FIXME( "Unsupported arguments\n" );
1425 if (*mode
& ~(PIPE_READMODE_MESSAGE
| PIPE_NOWAIT
)) status
= STATUS_INVALID_PARAMETER
;
1428 info
.CompletionMode
= (*mode
& PIPE_NOWAIT
) ?
1429 FILE_PIPE_COMPLETE_OPERATION
: FILE_PIPE_QUEUE_OPERATION
;
1430 info
.ReadMode
= (*mode
& PIPE_READMODE_MESSAGE
) ?
1431 FILE_PIPE_MESSAGE_MODE
: FILE_PIPE_BYTE_STREAM_MODE
;
1432 status
= NtSetInformationFile( pipe
, &iosb
, &info
, sizeof(info
), FilePipeInformation
);
1435 return set_ntstatus( status
);
1438 /***********************************************************************
1439 * TransactNamedPipe (kernelbase.@)
1441 BOOL WINAPI DECLSPEC_HOTPATCH
TransactNamedPipe( HANDLE handle
, LPVOID write_buf
, DWORD write_size
,
1442 LPVOID read_buf
, DWORD read_size
, LPDWORD bytes_read
,
1443 LPOVERLAPPED overlapped
)
1445 IO_STATUS_BLOCK default_iosb
, *iosb
= &default_iosb
;
1446 HANDLE event
= NULL
;
1447 void *cvalue
= NULL
;
1450 TRACE( "%p %p %lu %p %lu %p %p\n", handle
,
1451 write_buf
, write_size
, read_buf
, read_size
, bytes_read
, overlapped
);
1455 event
= overlapped
->hEvent
;
1456 iosb
= (IO_STATUS_BLOCK
*)overlapped
;
1457 if (((ULONG_PTR
)event
& 1) == 0) cvalue
= overlapped
;
1461 iosb
->Information
= 0;
1464 status
= NtFsControlFile( handle
, event
, NULL
, cvalue
, iosb
, FSCTL_PIPE_TRANSCEIVE
,
1465 write_buf
, write_size
, read_buf
, read_size
);
1466 if (status
== STATUS_PENDING
&& !overlapped
)
1468 WaitForSingleObject(handle
, INFINITE
);
1469 status
= iosb
->u
.Status
;
1472 if (bytes_read
) *bytes_read
= overlapped
&& status
? 0 : iosb
->Information
;
1473 return set_ntstatus( status
);
1477 /***********************************************************************
1478 * WaitNamedPipeW (kernelbase.@)
1480 BOOL WINAPI DECLSPEC_HOTPATCH
WaitNamedPipeW( LPCWSTR name
, DWORD timeout
)
1482 static const int prefix_len
= sizeof(L
"\\??\\PIPE\\") - sizeof(WCHAR
);
1484 UNICODE_STRING nt_name
, pipe_dev_name
;
1485 FILE_PIPE_WAIT_FOR_BUFFER
*pipe_wait
;
1486 IO_STATUS_BLOCK iosb
;
1487 OBJECT_ATTRIBUTES attr
;
1491 TRACE( "%s 0x%08lx\n", debugstr_w(name
), timeout
);
1493 if (!RtlDosPathNameToNtPathName_U( name
, &nt_name
, NULL
, NULL
)) return FALSE
;
1495 if (nt_name
.Length
>= MAX_PATH
* sizeof(WCHAR
) ||
1496 nt_name
.Length
< prefix_len
||
1497 wcsnicmp( nt_name
.Buffer
, L
"\\??\\PIPE\\", prefix_len
/ sizeof(WCHAR
) ))
1499 RtlFreeUnicodeString( &nt_name
);
1500 SetLastError( ERROR_PATH_NOT_FOUND
);
1504 wait_size
= offsetof( FILE_PIPE_WAIT_FOR_BUFFER
, Name
[(nt_name
.Length
- prefix_len
) / sizeof(WCHAR
)] );
1505 if (!(pipe_wait
= HeapAlloc( GetProcessHeap(), 0, wait_size
)))
1507 RtlFreeUnicodeString( &nt_name
);
1508 SetLastError( ERROR_OUTOFMEMORY
);
1512 pipe_dev_name
.Buffer
= nt_name
.Buffer
;
1513 pipe_dev_name
.Length
= prefix_len
;
1514 pipe_dev_name
.MaximumLength
= prefix_len
;
1515 InitializeObjectAttributes( &attr
,&pipe_dev_name
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1516 status
= NtOpenFile( &pipe_dev
, FILE_READ_ATTRIBUTES
| SYNCHRONIZE
, &attr
,
1517 &iosb
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1518 FILE_SYNCHRONOUS_IO_NONALERT
);
1519 if (status
!= STATUS_SUCCESS
)
1521 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1522 RtlFreeUnicodeString( &nt_name
);
1523 SetLastError( ERROR_PATH_NOT_FOUND
);
1527 pipe_wait
->TimeoutSpecified
= !(timeout
== NMPWAIT_USE_DEFAULT_WAIT
);
1528 if (timeout
== NMPWAIT_WAIT_FOREVER
)
1529 pipe_wait
->Timeout
.QuadPart
= ((ULONGLONG
)0x7fffffff << 32) | 0xffffffff;
1531 pipe_wait
->Timeout
.QuadPart
= (ULONGLONG
)timeout
* -10000;
1532 pipe_wait
->NameLength
= nt_name
.Length
- prefix_len
;
1533 memcpy( pipe_wait
->Name
, nt_name
.Buffer
+ prefix_len
/sizeof(WCHAR
), pipe_wait
->NameLength
);
1534 RtlFreeUnicodeString( &nt_name
);
1536 status
= NtFsControlFile( pipe_dev
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_WAIT
,
1537 pipe_wait
, wait_size
, NULL
, 0 );
1539 HeapFree( GetProcessHeap(), 0, pipe_wait
);
1540 NtClose( pipe_dev
);
1541 return set_ntstatus( status
);
1546 /***********************************************************************
1547 * Interlocked functions
1548 ***********************************************************************/
1551 /***********************************************************************
1552 * InitOnceBeginInitialize (kernelbase.@)
1554 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceBeginInitialize( INIT_ONCE
*once
, DWORD flags
,
1555 BOOL
*pending
, void **context
)
1557 NTSTATUS status
= RtlRunOnceBeginInitialize( once
, flags
, context
);
1558 if (status
>= 0) *pending
= (status
== STATUS_PENDING
);
1559 else SetLastError( RtlNtStatusToDosError(status
) );
1564 /***********************************************************************
1565 * InitOnceComplete (kernelbase.@)
1567 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceComplete( INIT_ONCE
*once
, DWORD flags
, void *context
)
1569 return set_ntstatus( RtlRunOnceComplete( once
, flags
, context
));
1573 /***********************************************************************
1574 * InitOnceExecuteOnce (kernelbase.@)
1576 BOOL WINAPI DECLSPEC_HOTPATCH
InitOnceExecuteOnce( INIT_ONCE
*once
, PINIT_ONCE_FN func
,
1577 void *param
, void **context
)
1579 return !RtlRunOnceExecuteOnce( once
, (PRTL_RUN_ONCE_INIT_FN
)func
, param
, context
);
1584 /***********************************************************************
1585 * InterlockedCompareExchange (kernelbase.@)
1587 __ASM_STDCALL_FUNC(InterlockedCompareExchange
, 12,
1588 "movl 12(%esp),%eax\n\t"
1589 "movl 8(%esp),%ecx\n\t"
1590 "movl 4(%esp),%edx\n\t"
1591 "lock; cmpxchgl %ecx,(%edx)\n\t"
1594 /***********************************************************************
1595 * InterlockedExchange (kernelbase.@)
1597 __ASM_STDCALL_FUNC(InterlockedExchange
, 8,
1598 "movl 8(%esp),%eax\n\t"
1599 "movl 4(%esp),%edx\n\t"
1600 "lock; xchgl %eax,(%edx)\n\t"
1603 /***********************************************************************
1604 * InterlockedExchangeAdd (kernelbase.@)
1606 __ASM_STDCALL_FUNC(InterlockedExchangeAdd
, 8,
1607 "movl 8(%esp),%eax\n\t"
1608 "movl 4(%esp),%edx\n\t"
1609 "lock; xaddl %eax,(%edx)\n\t"
1612 /***********************************************************************
1613 * InterlockedIncrement (kernelbase.@)
1615 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
1616 "movl 4(%esp),%edx\n\t"
1618 "lock; xaddl %eax,(%edx)\n\t"
1622 /***********************************************************************
1623 * InterlockedDecrement (kernelbase.@)
1625 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
1626 "movl 4(%esp),%edx\n\t"
1628 "lock; xaddl %eax,(%edx)\n\t"
1632 #endif /* __i386__ */