kernel32/tests: Add a test to check some fields in fake dlls.
[wine.git] / dlls / kernel32 / sync.c
blob6d47d7004cdd00e7d056452d535de6a75fa4ef93
1 /*
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
21 #include "config.h"
22 #include "wine/port.h"
24 #include <string.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28 #include <errno.h>
29 #include <stdarg.h>
30 #include <stdio.h>
32 #include "ntstatus.h"
33 #define WIN32_NO_STATUS
34 #define NONAMELESSUNION
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winerror.h"
38 #include "winnls.h"
39 #include "winternl.h"
40 #include "winioctl.h"
41 #include "ddk/wdm.h"
43 #include "wine/library.h"
44 #include "wine/unicode.h"
45 #include "kernel_private.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(sync);
51 /* check if current version is NT or Win95 */
52 static inline BOOL is_version_nt(void)
54 return !(GetVersion() & 0x80000000);
57 /* returns directory handle to \\BaseNamedObjects */
58 static HANDLE get_BaseNamedObjects_handle(void)
60 static HANDLE handle = NULL;
61 static const WCHAR basenameW[] = {'\\','S','e','s','s','i','o','n','s','\\','%','u',
62 '\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',0};
63 WCHAR buffer[64];
64 UNICODE_STRING str;
65 OBJECT_ATTRIBUTES attr;
67 if (!handle)
69 HANDLE dir;
71 sprintfW( buffer, basenameW, NtCurrentTeb()->Peb->SessionId );
72 RtlInitUnicodeString( &str, buffer );
73 InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
74 NtOpenDirectoryObject(&dir, DIRECTORY_CREATE_OBJECT|DIRECTORY_TRAVERSE,
75 &attr);
76 if (InterlockedCompareExchangePointer( &handle, dir, 0 ) != 0)
78 /* someone beat us here... */
79 CloseHandle( dir );
82 return handle;
85 static void get_create_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
86 SECURITY_ATTRIBUTES *sa, const WCHAR *name )
88 attr->Length = sizeof(*attr);
89 attr->RootDirectory = 0;
90 attr->ObjectName = NULL;
91 attr->Attributes = OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
92 attr->SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
93 attr->SecurityQualityOfService = NULL;
94 if (name)
96 RtlInitUnicodeString( nameW, name );
97 attr->ObjectName = nameW;
98 attr->RootDirectory = get_BaseNamedObjects_handle();
102 static BOOL get_open_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
103 BOOL inherit, const WCHAR *name )
105 if (!name)
107 SetLastError( ERROR_INVALID_PARAMETER );
108 return FALSE;
110 RtlInitUnicodeString( nameW, name );
111 InitializeObjectAttributes( attr, nameW, inherit ? OBJ_INHERIT : 0,
112 get_BaseNamedObjects_handle(), NULL );
113 return TRUE;
116 /* helper for kernel32->ntdll timeout format conversion */
117 static inline PLARGE_INTEGER get_nt_timeout( PLARGE_INTEGER pTime, DWORD timeout )
119 if (timeout == INFINITE) return NULL;
120 pTime->QuadPart = (ULONGLONG)timeout * -10000;
121 return pTime;
124 /***********************************************************************
125 * Sleep (KERNEL32.@)
127 VOID WINAPI DECLSPEC_HOTPATCH Sleep( DWORD timeout )
129 SleepEx( timeout, FALSE );
132 /******************************************************************************
133 * SleepEx (KERNEL32.@)
135 DWORD WINAPI SleepEx( DWORD timeout, BOOL alertable )
137 NTSTATUS status;
138 LARGE_INTEGER time;
140 status = NtDelayExecution( alertable, get_nt_timeout( &time, timeout ) );
141 if (status == STATUS_USER_APC) return WAIT_IO_COMPLETION;
142 return 0;
146 /***********************************************************************
147 * SwitchToThread (KERNEL32.@)
149 BOOL WINAPI SwitchToThread(void)
151 return (NtYieldExecution() != STATUS_NO_YIELD_PERFORMED);
155 /***********************************************************************
156 * WaitForSingleObject (KERNEL32.@)
158 DWORD WINAPI WaitForSingleObject( HANDLE handle, DWORD timeout )
160 return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, FALSE );
164 /***********************************************************************
165 * WaitForSingleObjectEx (KERNEL32.@)
167 DWORD WINAPI WaitForSingleObjectEx( HANDLE handle, DWORD timeout,
168 BOOL alertable )
170 return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, alertable );
174 /***********************************************************************
175 * WaitForMultipleObjects (KERNEL32.@)
177 DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles,
178 BOOL wait_all, DWORD timeout )
180 return WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE );
183 static HANDLE normalize_handle_if_console(HANDLE handle)
185 if ((handle == (HANDLE)STD_INPUT_HANDLE) ||
186 (handle == (HANDLE)STD_OUTPUT_HANDLE) ||
187 (handle == (HANDLE)STD_ERROR_HANDLE))
188 handle = GetStdHandle( HandleToULong(handle) );
190 /* yes, even screen buffer console handles are waitable, and are
191 * handled as a handle to the console itself !!
193 if (is_console_handle(handle))
195 if (VerifyConsoleIoHandle(handle))
196 handle = GetConsoleInputWaitHandle();
198 return handle;
201 /***********************************************************************
202 * WaitForMultipleObjectsEx (KERNEL32.@)
204 DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
205 BOOL wait_all, DWORD timeout,
206 BOOL alertable )
208 NTSTATUS status;
209 HANDLE hloc[MAXIMUM_WAIT_OBJECTS];
210 LARGE_INTEGER time;
211 unsigned int i;
213 if (count > MAXIMUM_WAIT_OBJECTS)
215 SetLastError(ERROR_INVALID_PARAMETER);
216 return WAIT_FAILED;
218 for (i = 0; i < count; i++)
219 hloc[i] = normalize_handle_if_console(handles[i]);
221 status = NtWaitForMultipleObjects( count, hloc, !wait_all, alertable,
222 get_nt_timeout( &time, timeout ) );
224 if (HIWORD(status)) /* is it an error code? */
226 SetLastError( RtlNtStatusToDosError(status) );
227 status = WAIT_FAILED;
229 return status;
233 /***********************************************************************
234 * RegisterWaitForSingleObject (KERNEL32.@)
236 BOOL WINAPI RegisterWaitForSingleObject(PHANDLE phNewWaitObject, HANDLE hObject,
237 WAITORTIMERCALLBACK Callback, PVOID Context,
238 ULONG dwMilliseconds, ULONG dwFlags)
240 NTSTATUS status;
242 TRACE("%p %p %p %p %d %d\n",
243 phNewWaitObject,hObject,Callback,Context,dwMilliseconds,dwFlags);
245 hObject = normalize_handle_if_console(hObject);
246 status = RtlRegisterWait( phNewWaitObject, hObject, Callback, Context, dwMilliseconds, dwFlags );
247 if (status != STATUS_SUCCESS)
249 SetLastError( RtlNtStatusToDosError(status) );
250 return FALSE;
252 return TRUE;
255 /***********************************************************************
256 * RegisterWaitForSingleObjectEx (KERNEL32.@)
258 HANDLE WINAPI RegisterWaitForSingleObjectEx( HANDLE hObject,
259 WAITORTIMERCALLBACK Callback, PVOID Context,
260 ULONG dwMilliseconds, ULONG dwFlags )
262 NTSTATUS status;
263 HANDLE hNewWaitObject;
265 TRACE("%p %p %p %d %d\n",
266 hObject,Callback,Context,dwMilliseconds,dwFlags);
268 hObject = normalize_handle_if_console(hObject);
269 status = RtlRegisterWait( &hNewWaitObject, hObject, Callback, Context, dwMilliseconds, dwFlags );
270 if (status != STATUS_SUCCESS)
272 SetLastError( RtlNtStatusToDosError(status) );
273 return NULL;
275 return hNewWaitObject;
278 /***********************************************************************
279 * UnregisterWait (KERNEL32.@)
281 BOOL WINAPI UnregisterWait( HANDLE WaitHandle )
283 NTSTATUS status;
285 TRACE("%p\n",WaitHandle);
287 status = RtlDeregisterWait( WaitHandle );
288 if (status != STATUS_SUCCESS)
290 SetLastError( RtlNtStatusToDosError(status) );
291 return FALSE;
293 return TRUE;
296 /***********************************************************************
297 * UnregisterWaitEx (KERNEL32.@)
299 BOOL WINAPI UnregisterWaitEx( HANDLE WaitHandle, HANDLE CompletionEvent )
301 NTSTATUS status;
303 TRACE("%p %p\n",WaitHandle, CompletionEvent);
305 status = RtlDeregisterWaitEx( WaitHandle, CompletionEvent );
306 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
307 return !status;
310 /***********************************************************************
311 * SignalObjectAndWait (KERNEL32.@)
313 * Makes it possible to atomically signal any of the synchronization
314 * objects (semaphore, mutex, event) and wait on another.
316 DWORD WINAPI SignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectToWaitOn,
317 DWORD dwMilliseconds, BOOL bAlertable )
319 NTSTATUS status;
320 LARGE_INTEGER timeout;
322 TRACE("%p %p %d %d\n", hObjectToSignal,
323 hObjectToWaitOn, dwMilliseconds, bAlertable);
325 status = NtSignalAndWaitForSingleObject( hObjectToSignal, hObjectToWaitOn, bAlertable,
326 get_nt_timeout( &timeout, dwMilliseconds ) );
327 if (HIWORD(status))
329 SetLastError( RtlNtStatusToDosError(status) );
330 status = WAIT_FAILED;
332 return status;
335 /***********************************************************************
336 * InitializeCriticalSection (KERNEL32.@)
338 * Initialise a critical section before use.
340 * PARAMS
341 * crit [O] Critical section to initialise.
343 * RETURNS
344 * Nothing. If the function fails an exception is raised.
346 void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit )
348 InitializeCriticalSectionEx( crit, 0, 0 );
351 /***********************************************************************
352 * InitializeCriticalSectionAndSpinCount (KERNEL32.@)
354 * Initialise a critical section with a spin count.
356 * PARAMS
357 * crit [O] Critical section to initialise.
358 * spincount [I] Number of times to spin upon contention.
360 * RETURNS
361 * Success: TRUE.
362 * Failure: Nothing. If the function fails an exception is raised.
364 * NOTES
365 * spincount is ignored on uni-processor systems.
367 BOOL WINAPI InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION *crit, DWORD spincount )
369 return InitializeCriticalSectionEx( crit, spincount, 0 );
372 /***********************************************************************
373 * InitializeCriticalSectionEx (KERNEL32.@)
375 * Initialise a critical section with a spin count and flags.
377 * PARAMS
378 * crit [O] Critical section to initialise.
379 * spincount [I] Number of times to spin upon contention.
380 * flags [I] CRITICAL_SECTION_ flags from winbase.h.
382 * RETURNS
383 * Success: TRUE.
384 * Failure: Nothing. If the function fails an exception is raised.
386 * NOTES
387 * spincount is ignored on uni-processor systems.
389 BOOL WINAPI InitializeCriticalSectionEx( CRITICAL_SECTION *crit, DWORD spincount, DWORD flags )
391 NTSTATUS ret = RtlInitializeCriticalSectionEx( crit, spincount, flags );
392 if (ret) RtlRaiseStatus( ret );
393 return !ret;
396 /***********************************************************************
397 * MakeCriticalSectionGlobal (KERNEL32.@)
399 void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
401 /* let's assume that only one thread at a time will try to do this */
402 HANDLE sem = crit->LockSemaphore;
403 if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 );
404 crit->LockSemaphore = ConvertToGlobalHandle( sem );
405 RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
406 crit->DebugInfo = NULL;
410 /***********************************************************************
411 * ReinitializeCriticalSection (KERNEL32.@)
413 * Initialise an already used critical section.
415 * PARAMS
416 * crit [O] Critical section to initialise.
418 * RETURNS
419 * Nothing.
421 void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
423 if ( !crit->LockSemaphore )
424 RtlInitializeCriticalSection( crit );
428 /***********************************************************************
429 * UninitializeCriticalSection (KERNEL32.@)
431 * UnInitialise a critical section after use.
433 * PARAMS
434 * crit [O] Critical section to uninitialise (destroy).
436 * RETURNS
437 * Nothing.
439 void WINAPI UninitializeCriticalSection( CRITICAL_SECTION *crit )
441 RtlDeleteCriticalSection( crit );
445 /***********************************************************************
446 * CreateEventA (KERNEL32.@)
448 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
449 BOOL initial_state, LPCSTR name )
451 DWORD flags = 0;
453 if (manual_reset) flags |= CREATE_EVENT_MANUAL_RESET;
454 if (initial_state) flags |= CREATE_EVENT_INITIAL_SET;
455 return CreateEventExA( sa, name, flags, EVENT_ALL_ACCESS );
459 /***********************************************************************
460 * CreateEventW (KERNEL32.@)
462 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset,
463 BOOL initial_state, LPCWSTR name )
465 DWORD flags = 0;
467 if (manual_reset) flags |= CREATE_EVENT_MANUAL_RESET;
468 if (initial_state) flags |= CREATE_EVENT_INITIAL_SET;
469 return CreateEventExW( sa, name, flags, EVENT_ALL_ACCESS );
473 /***********************************************************************
474 * CreateEventExA (KERNEL32.@)
476 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventExA( SECURITY_ATTRIBUTES *sa, LPCSTR name, DWORD flags, DWORD access )
478 WCHAR buffer[MAX_PATH];
480 if (!name) return CreateEventExW( sa, NULL, flags, access );
482 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
484 SetLastError( ERROR_FILENAME_EXCED_RANGE );
485 return 0;
487 return CreateEventExW( sa, buffer, flags, access );
491 /***********************************************************************
492 * CreateEventExW (KERNEL32.@)
494 HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventExW( SECURITY_ATTRIBUTES *sa, LPCWSTR name, DWORD flags, DWORD access )
496 HANDLE ret = 0;
497 UNICODE_STRING nameW;
498 OBJECT_ATTRIBUTES attr;
499 NTSTATUS status;
501 /* one buggy program needs this
502 * ("Van Dale Groot woordenboek der Nederlandse taal")
504 if (sa && IsBadReadPtr(sa,sizeof(SECURITY_ATTRIBUTES)))
506 ERR("Bad security attributes pointer %p\n",sa);
507 SetLastError( ERROR_INVALID_PARAMETER);
508 return 0;
511 get_create_object_attributes( &attr, &nameW, sa, name );
513 status = NtCreateEvent( &ret, access, &attr,
514 (flags & CREATE_EVENT_MANUAL_RESET) ? NotificationEvent : SynchronizationEvent,
515 (flags & CREATE_EVENT_INITIAL_SET) != 0 );
516 if (status == STATUS_OBJECT_NAME_EXISTS)
517 SetLastError( ERROR_ALREADY_EXISTS );
518 else
519 SetLastError( RtlNtStatusToDosError(status) );
520 return ret;
524 /***********************************************************************
525 * OpenEventA (KERNEL32.@)
527 HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventA( DWORD access, BOOL inherit, LPCSTR name )
529 WCHAR buffer[MAX_PATH];
531 if (!name) return OpenEventW( access, inherit, NULL );
533 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
535 SetLastError( ERROR_FILENAME_EXCED_RANGE );
536 return 0;
538 return OpenEventW( access, inherit, buffer );
542 /***********************************************************************
543 * OpenEventW (KERNEL32.@)
545 HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW( DWORD access, BOOL inherit, LPCWSTR name )
547 HANDLE ret;
548 UNICODE_STRING nameW;
549 OBJECT_ATTRIBUTES attr;
550 NTSTATUS status;
552 if (!is_version_nt()) access = EVENT_ALL_ACCESS;
554 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
556 status = NtOpenEvent( &ret, access, &attr );
557 if (status != STATUS_SUCCESS)
559 SetLastError( RtlNtStatusToDosError(status) );
560 return 0;
562 return ret;
565 /***********************************************************************
566 * PulseEvent (KERNEL32.@)
568 BOOL WINAPI DECLSPEC_HOTPATCH PulseEvent( HANDLE handle )
570 NTSTATUS status;
572 if ((status = NtPulseEvent( handle, NULL )))
573 SetLastError( RtlNtStatusToDosError(status) );
574 return !status;
578 /***********************************************************************
579 * SetEvent (KERNEL32.@)
581 BOOL WINAPI DECLSPEC_HOTPATCH SetEvent( HANDLE handle )
583 NTSTATUS status;
585 if ((status = NtSetEvent( handle, NULL )))
586 SetLastError( RtlNtStatusToDosError(status) );
587 return !status;
591 /***********************************************************************
592 * ResetEvent (KERNEL32.@)
594 BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent( HANDLE handle )
596 NTSTATUS status;
598 if ((status = NtResetEvent( handle, NULL )))
599 SetLastError( RtlNtStatusToDosError(status) );
600 return !status;
604 /***********************************************************************
605 * CreateMutexA (KERNEL32.@)
607 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name )
609 return CreateMutexExA( sa, name, owner ? CREATE_MUTEX_INITIAL_OWNER : 0, MUTEX_ALL_ACCESS );
613 /***********************************************************************
614 * CreateMutexW (KERNEL32.@)
616 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name )
618 return CreateMutexExW( sa, name, owner ? CREATE_MUTEX_INITIAL_OWNER : 0, MUTEX_ALL_ACCESS );
622 /***********************************************************************
623 * CreateMutexExA (KERNEL32.@)
625 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexExA( SECURITY_ATTRIBUTES *sa, LPCSTR name, DWORD flags, DWORD access )
627 ANSI_STRING nameA;
628 NTSTATUS status;
630 if (!name) return CreateMutexExW( sa, NULL, flags, access );
632 RtlInitAnsiString( &nameA, name );
633 status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString, &nameA, FALSE );
634 if (status != STATUS_SUCCESS)
636 SetLastError( ERROR_FILENAME_EXCED_RANGE );
637 return 0;
639 return CreateMutexExW( sa, NtCurrentTeb()->StaticUnicodeString.Buffer, flags, access );
643 /***********************************************************************
644 * CreateMutexExW (KERNEL32.@)
646 HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexExW( SECURITY_ATTRIBUTES *sa, LPCWSTR name, DWORD flags, DWORD access )
648 HANDLE ret = 0;
649 UNICODE_STRING nameW;
650 OBJECT_ATTRIBUTES attr;
651 NTSTATUS status;
653 get_create_object_attributes( &attr, &nameW, sa, name );
655 status = NtCreateMutant( &ret, access, &attr, (flags & CREATE_MUTEX_INITIAL_OWNER) != 0 );
656 if (status == STATUS_OBJECT_NAME_EXISTS)
657 SetLastError( ERROR_ALREADY_EXISTS );
658 else
659 SetLastError( RtlNtStatusToDosError(status) );
660 return ret;
664 /***********************************************************************
665 * OpenMutexA (KERNEL32.@)
667 HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
669 WCHAR buffer[MAX_PATH];
671 if (!name) return OpenMutexW( access, inherit, NULL );
673 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
675 SetLastError( ERROR_FILENAME_EXCED_RANGE );
676 return 0;
678 return OpenMutexW( access, inherit, buffer );
682 /***********************************************************************
683 * OpenMutexW (KERNEL32.@)
685 HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name )
687 HANDLE ret;
688 UNICODE_STRING nameW;
689 OBJECT_ATTRIBUTES attr;
690 NTSTATUS status;
692 if (!is_version_nt()) access = MUTEX_ALL_ACCESS;
694 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
696 status = NtOpenMutant( &ret, access, &attr );
697 if (status != STATUS_SUCCESS)
699 SetLastError( RtlNtStatusToDosError(status) );
700 return 0;
702 return ret;
706 /***********************************************************************
707 * ReleaseMutex (KERNEL32.@)
709 BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex( HANDLE handle )
711 NTSTATUS status;
713 status = NtReleaseMutant(handle, NULL);
714 if (status != STATUS_SUCCESS)
716 SetLastError( RtlNtStatusToDosError(status) );
717 return FALSE;
719 return TRUE;
724 * Semaphores
728 /***********************************************************************
729 * CreateSemaphoreA (KERNEL32.@)
731 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
733 return CreateSemaphoreExA( sa, initial, max, name, 0, SEMAPHORE_ALL_ACCESS );
737 /***********************************************************************
738 * CreateSemaphoreW (KERNEL32.@)
740 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCWSTR name )
742 return CreateSemaphoreExW( sa, initial, max, name, 0, SEMAPHORE_ALL_ACCESS );
746 /***********************************************************************
747 * CreateSemaphoreExA (KERNEL32.@)
749 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreExA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max,
750 LPCSTR name, DWORD flags, DWORD access )
752 WCHAR buffer[MAX_PATH];
754 if (!name) return CreateSemaphoreExW( sa, initial, max, NULL, flags, access );
756 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
758 SetLastError( ERROR_FILENAME_EXCED_RANGE );
759 return 0;
761 return CreateSemaphoreExW( sa, initial, max, buffer, flags, access );
765 /***********************************************************************
766 * CreateSemaphoreExW (KERNEL32.@)
768 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreExW( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max,
769 LPCWSTR name, DWORD flags, DWORD access )
771 HANDLE ret = 0;
772 UNICODE_STRING nameW;
773 OBJECT_ATTRIBUTES attr;
774 NTSTATUS status;
776 get_create_object_attributes( &attr, &nameW, sa, name );
778 status = NtCreateSemaphore( &ret, access, &attr, initial, max );
779 if (status == STATUS_OBJECT_NAME_EXISTS)
780 SetLastError( ERROR_ALREADY_EXISTS );
781 else
782 SetLastError( RtlNtStatusToDosError(status) );
783 return ret;
787 /***********************************************************************
788 * OpenSemaphoreA (KERNEL32.@)
790 HANDLE WINAPI DECLSPEC_HOTPATCH OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
792 WCHAR buffer[MAX_PATH];
794 if (!name) return OpenSemaphoreW( access, inherit, NULL );
796 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
798 SetLastError( ERROR_FILENAME_EXCED_RANGE );
799 return 0;
801 return OpenSemaphoreW( access, inherit, buffer );
805 /***********************************************************************
806 * OpenSemaphoreW (KERNEL32.@)
808 HANDLE WINAPI DECLSPEC_HOTPATCH OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
810 HANDLE ret;
811 UNICODE_STRING nameW;
812 OBJECT_ATTRIBUTES attr;
813 NTSTATUS status;
815 if (!is_version_nt()) access = SEMAPHORE_ALL_ACCESS;
817 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
819 status = NtOpenSemaphore( &ret, access, &attr );
820 if (status != STATUS_SUCCESS)
822 SetLastError( RtlNtStatusToDosError(status) );
823 return 0;
825 return ret;
829 /***********************************************************************
830 * ReleaseSemaphore (KERNEL32.@)
832 BOOL WINAPI DECLSPEC_HOTPATCH ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
834 NTSTATUS status = NtReleaseSemaphore( handle, count, (PULONG)previous );
835 if (status) SetLastError( RtlNtStatusToDosError(status) );
836 return !status;
841 * Jobs
844 /******************************************************************************
845 * CreateJobObjectW (KERNEL32.@)
847 HANDLE WINAPI CreateJobObjectW( LPSECURITY_ATTRIBUTES sa, LPCWSTR name )
849 HANDLE ret = 0;
850 UNICODE_STRING nameW;
851 OBJECT_ATTRIBUTES attr;
852 NTSTATUS status;
854 get_create_object_attributes( &attr, &nameW, sa, name );
856 status = NtCreateJobObject( &ret, JOB_OBJECT_ALL_ACCESS, &attr );
857 if (status == STATUS_OBJECT_NAME_EXISTS)
858 SetLastError( ERROR_ALREADY_EXISTS );
859 else
860 SetLastError( RtlNtStatusToDosError(status) );
861 return ret;
864 /******************************************************************************
865 * CreateJobObjectA (KERNEL32.@)
867 HANDLE WINAPI CreateJobObjectA( LPSECURITY_ATTRIBUTES attr, LPCSTR name )
869 WCHAR buffer[MAX_PATH];
871 if (!name) return CreateJobObjectW( attr, NULL );
873 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
875 SetLastError( ERROR_FILENAME_EXCED_RANGE );
876 return 0;
878 return CreateJobObjectW( attr, buffer );
881 /******************************************************************************
882 * OpenJobObjectW (KERNEL32.@)
884 HANDLE WINAPI OpenJobObjectW( DWORD access, BOOL inherit, LPCWSTR name )
886 HANDLE ret;
887 UNICODE_STRING nameW;
888 OBJECT_ATTRIBUTES attr;
889 NTSTATUS status;
891 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
893 status = NtOpenJobObject( &ret, access, &attr );
894 if (status != STATUS_SUCCESS)
896 SetLastError( RtlNtStatusToDosError(status) );
897 return 0;
899 return ret;
902 /******************************************************************************
903 * OpenJobObjectA (KERNEL32.@)
905 HANDLE WINAPI OpenJobObjectA( DWORD access, BOOL inherit, LPCSTR name )
907 WCHAR buffer[MAX_PATH];
909 if (!name) return OpenJobObjectW( access, inherit, NULL );
911 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
913 SetLastError( ERROR_FILENAME_EXCED_RANGE );
914 return 0;
916 return OpenJobObjectW( access, inherit, buffer );
919 /******************************************************************************
920 * TerminateJobObject (KERNEL32.@)
922 BOOL WINAPI TerminateJobObject( HANDLE job, UINT exit_code )
924 NTSTATUS status = NtTerminateJobObject( job, exit_code );
925 if (status) SetLastError( RtlNtStatusToDosError(status) );
926 return !status;
929 /******************************************************************************
930 * QueryInformationJobObject (KERNEL32.@)
932 BOOL WINAPI QueryInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info,
933 DWORD len, DWORD *ret_len )
935 NTSTATUS status = NtQueryInformationJobObject( job, class, info, len, ret_len );
936 if (status) SetLastError( RtlNtStatusToDosError(status) );
937 return !status;
940 /******************************************************************************
941 * SetInformationJobObject (KERNEL32.@)
943 BOOL WINAPI SetInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, DWORD len )
945 NTSTATUS status = NtSetInformationJobObject( job, class, info, len );
946 if (status) SetLastError( RtlNtStatusToDosError(status) );
947 return !status;
950 /******************************************************************************
951 * AssignProcessToJobObject (KERNEL32.@)
953 BOOL WINAPI AssignProcessToJobObject( HANDLE job, HANDLE process )
955 NTSTATUS status = NtAssignProcessToJobObject( job, process );
956 if (status) SetLastError( RtlNtStatusToDosError(status) );
957 return !status;
960 /******************************************************************************
961 * IsProcessInJob (KERNEL32.@)
963 BOOL WINAPI IsProcessInJob( HANDLE process, HANDLE job, PBOOL result )
965 NTSTATUS status = NtIsProcessInJob( process, job );
966 switch(status)
968 case STATUS_PROCESS_IN_JOB:
969 *result = TRUE;
970 return TRUE;
971 case STATUS_PROCESS_NOT_IN_JOB:
972 *result = FALSE;
973 return TRUE;
974 default:
975 SetLastError( RtlNtStatusToDosError(status) );
976 return FALSE;
982 * Timers
986 /***********************************************************************
987 * CreateWaitableTimerA (KERNEL32.@)
989 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
991 return CreateWaitableTimerExA( sa, name, manual ? CREATE_WAITABLE_TIMER_MANUAL_RESET : 0,
992 TIMER_ALL_ACCESS );
996 /***********************************************************************
997 * CreateWaitableTimerW (KERNEL32.@)
999 HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name )
1001 return CreateWaitableTimerExW( sa, name, manual ? CREATE_WAITABLE_TIMER_MANUAL_RESET : 0,
1002 TIMER_ALL_ACCESS );
1006 /***********************************************************************
1007 * CreateWaitableTimerExA (KERNEL32.@)
1009 HANDLE WINAPI CreateWaitableTimerExA( SECURITY_ATTRIBUTES *sa, LPCSTR name, DWORD flags, DWORD access )
1011 WCHAR buffer[MAX_PATH];
1013 if (!name) return CreateWaitableTimerExW( sa, NULL, flags, access );
1015 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
1017 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1018 return 0;
1020 return CreateWaitableTimerExW( sa, buffer, flags, access );
1024 /***********************************************************************
1025 * CreateWaitableTimerExW (KERNEL32.@)
1027 HANDLE WINAPI CreateWaitableTimerExW( SECURITY_ATTRIBUTES *sa, LPCWSTR name, DWORD flags, DWORD access )
1029 HANDLE handle;
1030 NTSTATUS status;
1031 UNICODE_STRING nameW;
1032 OBJECT_ATTRIBUTES attr;
1034 get_create_object_attributes( &attr, &nameW, sa, name );
1036 status = NtCreateTimer( &handle, access, &attr,
1037 (flags & CREATE_WAITABLE_TIMER_MANUAL_RESET) ? NotificationTimer : SynchronizationTimer );
1038 if (status == STATUS_OBJECT_NAME_EXISTS)
1039 SetLastError( ERROR_ALREADY_EXISTS );
1040 else
1041 SetLastError( RtlNtStatusToDosError(status) );
1042 return handle;
1046 /***********************************************************************
1047 * OpenWaitableTimerA (KERNEL32.@)
1049 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
1051 WCHAR buffer[MAX_PATH];
1053 if (!name) return OpenWaitableTimerW( access, inherit, NULL );
1055 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
1057 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1058 return 0;
1060 return OpenWaitableTimerW( access, inherit, buffer );
1064 /***********************************************************************
1065 * OpenWaitableTimerW (KERNEL32.@)
1067 HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
1069 HANDLE handle;
1070 UNICODE_STRING nameW;
1071 OBJECT_ATTRIBUTES attr;
1072 NTSTATUS status;
1074 if (!is_version_nt()) access = TIMER_ALL_ACCESS;
1076 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
1078 status = NtOpenTimer(&handle, access, &attr);
1079 if (status != STATUS_SUCCESS)
1081 SetLastError( RtlNtStatusToDosError(status) );
1082 return 0;
1084 return handle;
1088 /***********************************************************************
1089 * SetWaitableTimer (KERNEL32.@)
1091 BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period,
1092 PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume )
1094 NTSTATUS status = NtSetTimer(handle, when, (PTIMER_APC_ROUTINE)callback,
1095 arg, resume, period, NULL);
1097 if (status != STATUS_SUCCESS)
1099 SetLastError( RtlNtStatusToDosError(status) );
1100 if (status != STATUS_TIMER_RESUME_IGNORED) return FALSE;
1102 return TRUE;
1105 /***********************************************************************
1106 * SetWaitableTimerEx (KERNEL32.@)
1108 BOOL WINAPI SetWaitableTimerEx( HANDLE handle, const LARGE_INTEGER *when, LONG period,
1109 PTIMERAPCROUTINE callback, LPVOID arg, REASON_CONTEXT *context, ULONG tolerabledelay )
1111 static int once;
1112 if (!once++)
1114 FIXME("(%p, %p, %d, %p, %p, %p, %d) semi-stub\n",
1115 handle, when, period, callback, arg, context, tolerabledelay);
1117 return SetWaitableTimer(handle, when, period, callback, arg, FALSE);
1120 /***********************************************************************
1121 * CancelWaitableTimer (KERNEL32.@)
1123 BOOL WINAPI CancelWaitableTimer( HANDLE handle )
1125 NTSTATUS status;
1127 status = NtCancelTimer(handle, NULL);
1128 if (status != STATUS_SUCCESS)
1130 SetLastError( RtlNtStatusToDosError(status) );
1131 return FALSE;
1133 return TRUE;
1137 /***********************************************************************
1138 * CreateTimerQueue (KERNEL32.@)
1140 HANDLE WINAPI CreateTimerQueue(void)
1142 HANDLE q;
1143 NTSTATUS status = RtlCreateTimerQueue(&q);
1145 if (status != STATUS_SUCCESS)
1147 SetLastError( RtlNtStatusToDosError(status) );
1148 return NULL;
1151 return q;
1155 /***********************************************************************
1156 * DeleteTimerQueueEx (KERNEL32.@)
1158 BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
1160 NTSTATUS status = RtlDeleteTimerQueueEx(TimerQueue, CompletionEvent);
1162 if (status != STATUS_SUCCESS)
1164 SetLastError( RtlNtStatusToDosError(status) );
1165 return FALSE;
1168 return TRUE;
1171 /***********************************************************************
1172 * DeleteTimerQueue (KERNEL32.@)
1174 BOOL WINAPI DeleteTimerQueue(HANDLE TimerQueue)
1176 return DeleteTimerQueueEx(TimerQueue, NULL);
1179 /***********************************************************************
1180 * CreateTimerQueueTimer (KERNEL32.@)
1182 * Creates a timer-queue timer. This timer expires at the specified due
1183 * time (in ms), then after every specified period (in ms). When the timer
1184 * expires, the callback function is called.
1186 * RETURNS
1187 * nonzero on success or zero on failure
1189 BOOL WINAPI CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue,
1190 WAITORTIMERCALLBACK Callback, PVOID Parameter,
1191 DWORD DueTime, DWORD Period, ULONG Flags )
1193 NTSTATUS status = RtlCreateTimer(phNewTimer, TimerQueue, Callback,
1194 Parameter, DueTime, Period, Flags);
1196 if (status != STATUS_SUCCESS)
1198 SetLastError( RtlNtStatusToDosError(status) );
1199 return FALSE;
1202 return TRUE;
1205 /***********************************************************************
1206 * ChangeTimerQueueTimer (KERNEL32.@)
1208 * Changes the times at which the timer expires.
1210 * RETURNS
1211 * nonzero on success or zero on failure
1213 BOOL WINAPI ChangeTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer,
1214 ULONG DueTime, ULONG Period )
1216 NTSTATUS status = RtlUpdateTimer(TimerQueue, Timer, DueTime, Period);
1218 if (status != STATUS_SUCCESS)
1220 SetLastError( RtlNtStatusToDosError(status) );
1221 return FALSE;
1224 return TRUE;
1227 /***********************************************************************
1228 * CancelTimerQueueTimer (KERNEL32.@)
1230 BOOL WINAPI CancelTimerQueueTimer(HANDLE queue, HANDLE timer)
1232 FIXME("stub: %p %p\n", queue, timer);
1233 return FALSE;
1236 /***********************************************************************
1237 * DeleteTimerQueueTimer (KERNEL32.@)
1239 * Cancels a timer-queue timer.
1241 * RETURNS
1242 * nonzero on success or zero on failure
1244 BOOL WINAPI DeleteTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer,
1245 HANDLE CompletionEvent )
1247 NTSTATUS status = RtlDeleteTimer(TimerQueue, Timer, CompletionEvent);
1248 if (status != STATUS_SUCCESS)
1250 SetLastError( RtlNtStatusToDosError(status) );
1251 return FALSE;
1253 return TRUE;
1258 * Mappings
1262 /***********************************************************************
1263 * CreateFileMappingA (KERNEL32.@)
1265 HANDLE WINAPI CreateFileMappingA( HANDLE file, SECURITY_ATTRIBUTES *sa, DWORD protect,
1266 DWORD size_high, DWORD size_low, LPCSTR name )
1268 WCHAR buffer[MAX_PATH];
1270 if (!name) return CreateFileMappingW( file, sa, protect, size_high, size_low, NULL );
1272 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
1274 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1275 return 0;
1277 return CreateFileMappingW( file, sa, protect, size_high, size_low, buffer );
1281 /***********************************************************************
1282 * CreateFileMappingW (KERNEL32.@)
1284 HANDLE WINAPI CreateFileMappingW( HANDLE file, LPSECURITY_ATTRIBUTES sa, DWORD protect,
1285 DWORD size_high, DWORD size_low, LPCWSTR name )
1287 static const int sec_flags = (SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_COMMIT |
1288 SEC_NOCACHE | SEC_WRITECOMBINE | SEC_LARGE_PAGES);
1289 HANDLE ret;
1290 NTSTATUS status;
1291 DWORD access, sec_type;
1292 LARGE_INTEGER size;
1293 UNICODE_STRING nameW;
1294 OBJECT_ATTRIBUTES attr;
1296 sec_type = protect & sec_flags;
1297 protect &= ~sec_flags;
1298 if (!sec_type) sec_type = SEC_COMMIT;
1300 /* Win9x compatibility */
1301 if (!protect && !is_version_nt()) protect = PAGE_READONLY;
1303 switch(protect)
1305 case PAGE_READONLY:
1306 case PAGE_WRITECOPY:
1307 access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ;
1308 break;
1309 case PAGE_READWRITE:
1310 access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE;
1311 break;
1312 case PAGE_EXECUTE_READ:
1313 case PAGE_EXECUTE_WRITECOPY:
1314 access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE;
1315 break;
1316 case PAGE_EXECUTE_READWRITE:
1317 access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE;
1318 break;
1319 default:
1320 SetLastError( ERROR_INVALID_PARAMETER );
1321 return 0;
1324 size.u.LowPart = size_low;
1325 size.u.HighPart = size_high;
1327 if (file == INVALID_HANDLE_VALUE)
1329 file = 0;
1330 if (!size.QuadPart)
1332 SetLastError( ERROR_INVALID_PARAMETER );
1333 return 0;
1337 get_create_object_attributes( &attr, &nameW, sa, name );
1339 status = NtCreateSection( &ret, access, &attr, &size, protect, sec_type, file );
1340 if (status == STATUS_OBJECT_NAME_EXISTS)
1341 SetLastError( ERROR_ALREADY_EXISTS );
1342 else
1343 SetLastError( RtlNtStatusToDosError(status) );
1344 return ret;
1348 /***********************************************************************
1349 * OpenFileMappingA (KERNEL32.@)
1351 HANDLE WINAPI OpenFileMappingA( DWORD access, BOOL inherit, LPCSTR name )
1353 WCHAR buffer[MAX_PATH];
1355 if (!name) return OpenFileMappingW( access, inherit, NULL );
1357 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
1359 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1360 return 0;
1362 return OpenFileMappingW( access, inherit, buffer );
1366 /***********************************************************************
1367 * OpenFileMappingW (KERNEL32.@)
1369 HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name )
1371 OBJECT_ATTRIBUTES attr;
1372 UNICODE_STRING nameW;
1373 HANDLE ret;
1374 NTSTATUS status;
1376 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
1378 if (access == FILE_MAP_COPY) access = SECTION_MAP_READ;
1380 if (!is_version_nt())
1382 /* win9x doesn't do access checks, so try with full access first */
1383 if (!NtOpenSection( &ret, access | SECTION_MAP_READ | SECTION_MAP_WRITE, &attr )) return ret;
1386 status = NtOpenSection( &ret, access, &attr );
1387 if (status != STATUS_SUCCESS)
1389 SetLastError( RtlNtStatusToDosError(status) );
1390 return 0;
1392 return ret;
1397 * Pipes
1401 /***********************************************************************
1402 * CreateNamedPipeA (KERNEL32.@)
1404 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
1405 DWORD dwPipeMode, DWORD nMaxInstances,
1406 DWORD nOutBufferSize, DWORD nInBufferSize,
1407 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
1409 WCHAR buffer[MAX_PATH];
1411 if (!name) return CreateNamedPipeW( NULL, dwOpenMode, dwPipeMode, nMaxInstances,
1412 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
1414 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
1416 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1417 return INVALID_HANDLE_VALUE;
1419 return CreateNamedPipeW( buffer, dwOpenMode, dwPipeMode, nMaxInstances,
1420 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
1424 /***********************************************************************
1425 * CreateNamedPipeW (KERNEL32.@)
1427 HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode,
1428 DWORD dwPipeMode, DWORD nMaxInstances,
1429 DWORD nOutBufferSize, DWORD nInBufferSize,
1430 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES sa )
1432 HANDLE handle;
1433 UNICODE_STRING nt_name;
1434 OBJECT_ATTRIBUTES attr;
1435 DWORD access, options, sharing;
1436 BOOLEAN pipe_type, read_mode, non_block;
1437 NTSTATUS status;
1438 IO_STATUS_BLOCK iosb;
1439 LARGE_INTEGER timeout;
1441 TRACE("(%s, %#08x, %#08x, %d, %d, %d, %d, %p)\n",
1442 debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
1443 nOutBufferSize, nInBufferSize, nDefaultTimeOut, sa );
1445 if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
1447 SetLastError( ERROR_PATH_NOT_FOUND );
1448 return INVALID_HANDLE_VALUE;
1450 if (nt_name.Length >= MAX_PATH * sizeof(WCHAR) )
1452 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1453 RtlFreeUnicodeString( &nt_name );
1454 return INVALID_HANDLE_VALUE;
1457 attr.Length = sizeof(attr);
1458 attr.RootDirectory = 0;
1459 attr.ObjectName = &nt_name;
1460 attr.Attributes = OBJ_CASE_INSENSITIVE |
1461 ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
1462 attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
1463 attr.SecurityQualityOfService = NULL;
1465 switch(dwOpenMode & 3)
1467 case PIPE_ACCESS_INBOUND:
1468 sharing = FILE_SHARE_WRITE;
1469 access = GENERIC_READ;
1470 break;
1471 case PIPE_ACCESS_OUTBOUND:
1472 sharing = FILE_SHARE_READ;
1473 access = GENERIC_WRITE;
1474 break;
1475 case PIPE_ACCESS_DUPLEX:
1476 sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
1477 access = GENERIC_READ | GENERIC_WRITE;
1478 break;
1479 default:
1480 SetLastError( ERROR_INVALID_PARAMETER );
1481 return INVALID_HANDLE_VALUE;
1483 access |= SYNCHRONIZE;
1484 options = 0;
1485 if (dwOpenMode & WRITE_DAC) access |= WRITE_DAC;
1486 if (dwOpenMode & WRITE_OWNER) access |= WRITE_OWNER;
1487 if (dwOpenMode & ACCESS_SYSTEM_SECURITY) access |= ACCESS_SYSTEM_SECURITY;
1488 if (dwOpenMode & FILE_FLAG_WRITE_THROUGH) options |= FILE_WRITE_THROUGH;
1489 if (!(dwOpenMode & FILE_FLAG_OVERLAPPED)) options |= FILE_SYNCHRONOUS_IO_NONALERT;
1490 pipe_type = (dwPipeMode & PIPE_TYPE_MESSAGE) != 0;
1491 read_mode = (dwPipeMode & PIPE_READMODE_MESSAGE) != 0;
1492 non_block = (dwPipeMode & PIPE_NOWAIT) != 0;
1493 if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES) nMaxInstances = ~0U;
1495 timeout.QuadPart = (ULONGLONG)nDefaultTimeOut * -10000;
1497 SetLastError(0);
1499 status = NtCreateNamedPipeFile(&handle, access, &attr, &iosb, sharing,
1500 FILE_OVERWRITE_IF, options, pipe_type,
1501 read_mode, non_block, nMaxInstances,
1502 nInBufferSize, nOutBufferSize, &timeout);
1504 RtlFreeUnicodeString( &nt_name );
1505 if (status)
1507 handle = INVALID_HANDLE_VALUE;
1508 SetLastError( RtlNtStatusToDosError(status) );
1510 return handle;
1514 /***********************************************************************
1515 * PeekNamedPipe (KERNEL32.@)
1517 BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
1518 LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage )
1520 FILE_PIPE_PEEK_BUFFER local_buffer;
1521 FILE_PIPE_PEEK_BUFFER *buffer = &local_buffer;
1522 IO_STATUS_BLOCK io;
1523 NTSTATUS status;
1525 if (cbBuffer && !(buffer = HeapAlloc( GetProcessHeap(), 0,
1526 FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data[cbBuffer] ))))
1528 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
1529 return FALSE;
1532 status = NtFsControlFile( hPipe, 0, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0,
1533 buffer, FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data[cbBuffer] ) );
1534 if (status == STATUS_BUFFER_OVERFLOW) status = STATUS_SUCCESS;
1535 if (!status)
1537 ULONG read_size = io.Information - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data );
1538 if (lpcbAvail) *lpcbAvail = buffer->ReadDataAvailable;
1539 if (lpcbRead) *lpcbRead = read_size;
1540 if (lpcbMessage) *lpcbMessage = buffer->MessageLength - read_size;
1541 if (lpvBuffer) memcpy( lpvBuffer, buffer->Data, read_size );
1543 else SetLastError( RtlNtStatusToDosError(status) );
1545 if (buffer != &local_buffer) HeapFree( GetProcessHeap(), 0, buffer );
1546 return !status;
1549 /***********************************************************************
1550 * WaitNamedPipeA (KERNEL32.@)
1552 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
1554 WCHAR buffer[MAX_PATH];
1556 if (!name) return WaitNamedPipeW( NULL, nTimeOut );
1558 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
1560 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1561 return FALSE;
1563 return WaitNamedPipeW( buffer, nTimeOut );
1567 /***********************************************************************
1568 * WaitNamedPipeW (KERNEL32.@)
1570 * Waits for a named pipe instance to become available
1572 * PARAMS
1573 * name [I] Pointer to a named pipe name to wait for
1574 * nTimeOut [I] How long to wait in ms
1576 * RETURNS
1577 * TRUE: Success, named pipe can be opened with CreateFile
1578 * FALSE: Failure, GetLastError can be called for further details
1580 BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
1582 static const WCHAR leadin[] = {'\\','?','?','\\','P','I','P','E','\\'};
1583 NTSTATUS status;
1584 UNICODE_STRING nt_name, pipe_dev_name;
1585 FILE_PIPE_WAIT_FOR_BUFFER *pipe_wait;
1586 IO_STATUS_BLOCK iosb;
1587 OBJECT_ATTRIBUTES attr;
1588 ULONG sz_pipe_wait;
1589 HANDLE pipe_dev;
1591 TRACE("%s 0x%08x\n",debugstr_w(name),nTimeOut);
1593 if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
1594 return FALSE;
1596 if (nt_name.Length >= MAX_PATH * sizeof(WCHAR) ||
1597 nt_name.Length < sizeof(leadin) ||
1598 strncmpiW( nt_name.Buffer, leadin, ARRAY_SIZE( leadin )) != 0)
1600 RtlFreeUnicodeString( &nt_name );
1601 SetLastError( ERROR_PATH_NOT_FOUND );
1602 return FALSE;
1605 sz_pipe_wait = sizeof(*pipe_wait) + nt_name.Length - sizeof(leadin) - sizeof(WCHAR);
1606 if (!(pipe_wait = HeapAlloc( GetProcessHeap(), 0, sz_pipe_wait)))
1608 RtlFreeUnicodeString( &nt_name );
1609 SetLastError( ERROR_OUTOFMEMORY );
1610 return FALSE;
1613 pipe_dev_name.Buffer = nt_name.Buffer;
1614 pipe_dev_name.Length = sizeof(leadin);
1615 pipe_dev_name.MaximumLength = sizeof(leadin);
1616 InitializeObjectAttributes(&attr,&pipe_dev_name, OBJ_CASE_INSENSITIVE, NULL, NULL);
1617 status = NtOpenFile( &pipe_dev, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr,
1618 &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE,
1619 FILE_SYNCHRONOUS_IO_NONALERT);
1620 if (status != STATUS_SUCCESS)
1622 HeapFree( GetProcessHeap(), 0, pipe_wait);
1623 RtlFreeUnicodeString( &nt_name );
1624 SetLastError( ERROR_PATH_NOT_FOUND );
1625 return FALSE;
1628 pipe_wait->TimeoutSpecified = !(nTimeOut == NMPWAIT_USE_DEFAULT_WAIT);
1629 if (nTimeOut == NMPWAIT_WAIT_FOREVER)
1630 pipe_wait->Timeout.QuadPart = ((ULONGLONG)0x7fffffff << 32) | 0xffffffff;
1631 else
1632 pipe_wait->Timeout.QuadPart = (ULONGLONG)nTimeOut * -10000;
1633 pipe_wait->NameLength = nt_name.Length - sizeof(leadin);
1634 memcpy( pipe_wait->Name, nt_name.Buffer + ARRAY_SIZE( leadin ), pipe_wait->NameLength );
1635 RtlFreeUnicodeString( &nt_name );
1637 status = NtFsControlFile( pipe_dev, NULL, NULL, NULL, &iosb, FSCTL_PIPE_WAIT,
1638 pipe_wait, sz_pipe_wait, NULL, 0 );
1640 HeapFree( GetProcessHeap(), 0, pipe_wait );
1641 NtClose( pipe_dev );
1643 if(status != STATUS_SUCCESS)
1645 SetLastError(RtlNtStatusToDosError(status));
1646 return FALSE;
1648 else
1649 return TRUE;
1653 /***********************************************************************
1654 * ConnectNamedPipe (KERNEL32.@)
1656 * Connects to a named pipe
1658 * Parameters
1659 * hPipe: A handle to a named pipe returned by CreateNamedPipe
1660 * overlapped: Optional OVERLAPPED struct
1662 * Return values
1663 * TRUE: Success
1664 * FALSE: Failure, GetLastError can be called for further details
1666 BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
1668 NTSTATUS status;
1669 IO_STATUS_BLOCK status_block;
1670 LPVOID cvalue = NULL;
1672 TRACE("(%p,%p)\n", hPipe, overlapped);
1674 if(overlapped)
1676 overlapped->Internal = STATUS_PENDING;
1677 overlapped->InternalHigh = 0;
1678 if (((ULONG_PTR)overlapped->hEvent & 1) == 0) cvalue = overlapped;
1681 status = NtFsControlFile(hPipe, overlapped ? overlapped->hEvent : NULL, NULL, cvalue,
1682 overlapped ? (IO_STATUS_BLOCK *)overlapped : &status_block,
1683 FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
1684 if (status == STATUS_PENDING && !overlapped)
1686 WaitForSingleObject(hPipe, INFINITE);
1687 status = status_block.u.Status;
1690 if (status == STATUS_SUCCESS) return TRUE;
1691 SetLastError( RtlNtStatusToDosError(status) );
1692 return FALSE;
1695 /***********************************************************************
1696 * DisconnectNamedPipe (KERNEL32.@)
1698 * Disconnects from a named pipe
1700 * Parameters
1701 * hPipe: A handle to a named pipe returned by CreateNamedPipe
1703 * Return values
1704 * TRUE: Success
1705 * FALSE: Failure, GetLastError can be called for further details
1707 BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
1709 NTSTATUS status;
1710 IO_STATUS_BLOCK io_block;
1712 TRACE("(%p)\n",hPipe);
1714 status = NtFsControlFile(hPipe, 0, NULL, NULL, &io_block, FSCTL_PIPE_DISCONNECT,
1715 NULL, 0, NULL, 0);
1716 if (status == STATUS_SUCCESS) return TRUE;
1717 SetLastError( RtlNtStatusToDosError(status) );
1718 return FALSE;
1721 /***********************************************************************
1722 * TransactNamedPipe (KERNEL32.@)
1724 BOOL WINAPI TransactNamedPipe(
1725 HANDLE handle, LPVOID write_buf, DWORD write_size, LPVOID read_buf,
1726 DWORD read_size, LPDWORD bytes_read, LPOVERLAPPED overlapped)
1728 IO_STATUS_BLOCK default_iosb, *iosb = &default_iosb;
1729 HANDLE event = NULL;
1730 void *cvalue = NULL;
1731 NTSTATUS status;
1733 TRACE("%p %p %u %p %u %p %p\n", handle, write_buf, write_size, read_buf,
1734 read_size, bytes_read, overlapped);
1736 if (overlapped)
1738 event = overlapped->hEvent;
1739 iosb = (IO_STATUS_BLOCK *)overlapped;
1740 if (((ULONG_PTR)event & 1) == 0) cvalue = overlapped;
1742 else
1744 iosb->Information = 0;
1747 status = NtFsControlFile(handle, event, NULL, cvalue, iosb, FSCTL_PIPE_TRANSCEIVE,
1748 write_buf, write_size, read_buf, read_size);
1749 if (status == STATUS_PENDING && !overlapped)
1751 WaitForSingleObject(handle, INFINITE);
1752 status = iosb->u.Status;
1755 if (bytes_read) *bytes_read = overlapped && status ? 0 : iosb->Information;
1757 if (status)
1759 SetLastError(RtlNtStatusToDosError(status));
1760 return FALSE;
1762 return TRUE;
1765 /***********************************************************************
1766 * GetNamedPipeInfo (KERNEL32.@)
1768 BOOL WINAPI GetNamedPipeInfo(
1769 HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
1770 LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
1772 FILE_PIPE_LOCAL_INFORMATION fpli;
1773 IO_STATUS_BLOCK iosb;
1774 NTSTATUS status;
1776 status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli),
1777 FilePipeLocalInformation);
1778 if (status)
1780 SetLastError( RtlNtStatusToDosError(status) );
1781 return FALSE;
1784 if (lpFlags)
1786 *lpFlags = (fpli.NamedPipeEnd & FILE_PIPE_SERVER_END) ?
1787 PIPE_SERVER_END : PIPE_CLIENT_END;
1788 *lpFlags |= (fpli.NamedPipeType & FILE_PIPE_TYPE_MESSAGE) ?
1789 PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
1792 if (lpOutputBufferSize) *lpOutputBufferSize = fpli.OutboundQuota;
1793 if (lpInputBufferSize) *lpInputBufferSize = fpli.InboundQuota;
1794 if (lpMaxInstances) *lpMaxInstances = fpli.MaximumInstances;
1796 return TRUE;
1799 /***********************************************************************
1800 * GetNamedPipeClientProcessId (KERNEL32.@)
1802 BOOL WINAPI GetNamedPipeClientProcessId( HANDLE pipe, ULONG *id )
1804 IO_STATUS_BLOCK iosb;
1805 NTSTATUS status;
1807 TRACE( "%p %p\n", pipe, id );
1809 status = NtFsControlFile( pipe, NULL, NULL, NULL, &iosb, FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE,
1810 (void *)"ClientProcessId", sizeof("ClientProcessId"), id, sizeof(*id) );
1811 if (status)
1813 SetLastError( RtlNtStatusToDosError(status) );
1814 return FALSE;
1816 return TRUE;
1819 /***********************************************************************
1820 * GetNamedPipeServerProcessId (KERNEL32.@)
1822 BOOL WINAPI GetNamedPipeServerProcessId( HANDLE pipe, ULONG *id )
1824 IO_STATUS_BLOCK iosb;
1825 NTSTATUS status;
1827 TRACE( "%p, %p\n", pipe, id );
1829 status = NtFsControlFile( pipe, NULL, NULL, NULL, &iosb, FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE,
1830 (void *)"ServerProcessId", sizeof("ServerProcessId"), id, sizeof(*id) );
1831 if (status)
1833 SetLastError( RtlNtStatusToDosError(status) );
1834 return FALSE;
1836 return TRUE;
1839 /***********************************************************************
1840 * GetNamedPipeClientSessionId (KERNEL32.@)
1842 BOOL WINAPI GetNamedPipeClientSessionId( HANDLE pipe, ULONG *id )
1844 FIXME( "%p, %p\n", pipe, id );
1846 if (!id) return FALSE;
1847 *id = NtCurrentTeb()->Peb->SessionId;
1848 return TRUE;
1851 /***********************************************************************
1852 * GetNamedPipeServerSessionId (KERNEL32.@)
1854 BOOL WINAPI GetNamedPipeServerSessionId( HANDLE pipe, ULONG *id )
1856 FIXME( "%p, %p\n", pipe, id );
1858 if (!id) return FALSE;
1859 *id = NtCurrentTeb()->Peb->SessionId;
1860 return TRUE;
1863 /***********************************************************************
1864 * GetNamedPipeHandleStateA (KERNEL32.@)
1866 BOOL WINAPI GetNamedPipeHandleStateA(
1867 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1868 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1869 LPSTR lpUsername, DWORD nUsernameMaxSize)
1871 WCHAR *username = NULL;
1872 BOOL ret;
1874 WARN("%p %p %p %p %p %p %d: semi-stub\n", hNamedPipe, lpState, lpCurInstances,
1875 lpMaxCollectionCount, lpCollectDataTimeout, lpUsername, nUsernameMaxSize);
1877 if (lpUsername && nUsernameMaxSize &&
1878 !(username = HeapAlloc(GetProcessHeap(), 0, nUsernameMaxSize * sizeof(WCHAR)))) return FALSE;
1880 ret = GetNamedPipeHandleStateW(hNamedPipe, lpState, lpCurInstances, lpMaxCollectionCount,
1881 lpCollectDataTimeout, username, nUsernameMaxSize);
1882 if (ret && username)
1883 WideCharToMultiByte(CP_ACP, 0, username, -1, lpUsername, nUsernameMaxSize, NULL, NULL);
1885 HeapFree(GetProcessHeap(), 0, username);
1886 return ret;
1889 /***********************************************************************
1890 * GetNamedPipeHandleStateW (KERNEL32.@)
1892 BOOL WINAPI GetNamedPipeHandleStateW(
1893 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1894 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1895 LPWSTR lpUsername, DWORD nUsernameMaxSize)
1897 IO_STATUS_BLOCK iosb;
1898 NTSTATUS status;
1900 FIXME("%p %p %p %p %p %p %d: semi-stub\n", hNamedPipe, lpState, lpCurInstances,
1901 lpMaxCollectionCount, lpCollectDataTimeout, lpUsername, nUsernameMaxSize);
1903 if (lpMaxCollectionCount)
1904 *lpMaxCollectionCount = 0;
1906 if (lpCollectDataTimeout)
1907 *lpCollectDataTimeout = 0;
1909 if (lpUsername && nUsernameMaxSize)
1911 const char *username = wine_get_user_name();
1912 int len = MultiByteToWideChar(CP_UNIXCP, 0, username, -1, lpUsername, nUsernameMaxSize);
1913 if (!len) *lpUsername = 0;
1916 if (lpState)
1918 FILE_PIPE_INFORMATION fpi;
1919 status = NtQueryInformationFile(hNamedPipe, &iosb, &fpi, sizeof(fpi),
1920 FilePipeInformation);
1921 if (status)
1923 SetLastError( RtlNtStatusToDosError(status) );
1924 return FALSE;
1927 *lpState = (fpi.ReadMode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE) |
1928 (fpi.CompletionMode ? PIPE_NOWAIT : PIPE_WAIT);
1931 if (lpCurInstances)
1933 FILE_PIPE_LOCAL_INFORMATION fpli;
1934 status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli),
1935 FilePipeLocalInformation);
1936 if (status)
1938 SetLastError( RtlNtStatusToDosError(status) );
1939 return FALSE;
1942 *lpCurInstances = fpli.CurrentInstances;
1945 return TRUE;
1948 /***********************************************************************
1949 * SetNamedPipeHandleState (KERNEL32.@)
1951 BOOL WINAPI SetNamedPipeHandleState(
1952 HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
1953 LPDWORD lpCollectDataTimeout)
1955 /* should be a fixme, but this function is called a lot by the RPC
1956 * runtime, and it slows down InstallShield a fair bit. */
1957 WARN("semi-stub: %p %p/%d %p %p\n",
1958 hNamedPipe, lpMode, lpMode ? *lpMode : 0, lpMaxCollectionCount, lpCollectDataTimeout);
1960 if (lpMode)
1962 FILE_PIPE_INFORMATION fpi;
1963 IO_STATUS_BLOCK iosb;
1964 NTSTATUS status;
1966 if (*lpMode & ~(PIPE_READMODE_MESSAGE | PIPE_NOWAIT))
1967 status = STATUS_INVALID_PARAMETER;
1968 else
1970 fpi.CompletionMode = (*lpMode & PIPE_NOWAIT) ?
1971 FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION;
1972 fpi.ReadMode = (*lpMode & PIPE_READMODE_MESSAGE) ?
1973 FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE;
1974 status = NtSetInformationFile(hNamedPipe, &iosb, &fpi, sizeof(fpi), FilePipeInformation);
1977 if (status)
1979 SetLastError( RtlNtStatusToDosError(status) );
1980 return FALSE;
1984 return TRUE;
1987 /***********************************************************************
1988 * CallNamedPipeA (KERNEL32.@)
1990 BOOL WINAPI CallNamedPipeA(
1991 LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD dwInputSize,
1992 LPVOID lpOutput, DWORD dwOutputSize,
1993 LPDWORD lpBytesRead, DWORD nTimeout)
1995 DWORD len;
1996 LPWSTR str = NULL;
1997 BOOL ret;
1999 TRACE("%s %p %d %p %d %p %d\n",
2000 debugstr_a(lpNamedPipeName), lpInput, dwInputSize,
2001 lpOutput, dwOutputSize, lpBytesRead, nTimeout);
2003 if( lpNamedPipeName )
2005 len = MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, NULL, 0 );
2006 str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2007 MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, str, len );
2009 ret = CallNamedPipeW( str, lpInput, dwInputSize, lpOutput,
2010 dwOutputSize, lpBytesRead, nTimeout );
2011 if( lpNamedPipeName )
2012 HeapFree( GetProcessHeap(), 0, str );
2014 return ret;
2017 /***********************************************************************
2018 * CallNamedPipeW (KERNEL32.@)
2020 BOOL WINAPI CallNamedPipeW(
2021 LPCWSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
2022 LPVOID lpOutput, DWORD lpOutputSize,
2023 LPDWORD lpBytesRead, DWORD nTimeout)
2025 HANDLE pipe;
2026 BOOL ret;
2027 DWORD mode;
2029 TRACE("%s %p %d %p %d %p %d\n",
2030 debugstr_w(lpNamedPipeName), lpInput, lpInputSize,
2031 lpOutput, lpOutputSize, lpBytesRead, nTimeout);
2033 pipe = CreateFileW(lpNamedPipeName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
2034 if (pipe == INVALID_HANDLE_VALUE)
2036 ret = WaitNamedPipeW(lpNamedPipeName, nTimeout);
2037 if (!ret)
2038 return FALSE;
2039 pipe = CreateFileW(lpNamedPipeName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
2040 if (pipe == INVALID_HANDLE_VALUE)
2041 return FALSE;
2044 mode = PIPE_READMODE_MESSAGE;
2045 ret = SetNamedPipeHandleState(pipe, &mode, NULL, NULL);
2046 if (!ret)
2048 CloseHandle(pipe);
2049 return FALSE;
2052 ret = TransactNamedPipe(pipe, lpInput, lpInputSize, lpOutput, lpOutputSize, lpBytesRead, NULL);
2053 CloseHandle(pipe);
2054 if (!ret)
2055 return FALSE;
2057 return TRUE;
2060 /******************************************************************
2061 * CreatePipe (KERNEL32.@)
2064 BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
2065 LPSECURITY_ATTRIBUTES sa, DWORD size )
2067 static unsigned index /* = 0 */;
2068 WCHAR name[64];
2069 HANDLE hr, hw;
2070 unsigned in_index = index;
2071 UNICODE_STRING nt_name;
2072 OBJECT_ATTRIBUTES attr;
2073 NTSTATUS status;
2074 IO_STATUS_BLOCK iosb;
2075 LARGE_INTEGER timeout;
2077 *hReadPipe = *hWritePipe = INVALID_HANDLE_VALUE;
2079 attr.Length = sizeof(attr);
2080 attr.RootDirectory = 0;
2081 attr.ObjectName = &nt_name;
2082 attr.Attributes = OBJ_CASE_INSENSITIVE |
2083 ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
2084 attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
2085 attr.SecurityQualityOfService = NULL;
2087 if (!size) size = 4096;
2089 timeout.QuadPart = (ULONGLONG)NMPWAIT_USE_DEFAULT_WAIT * -10000;
2090 /* generate a unique pipe name (system wide) */
2093 static const WCHAR nameFmt[] = { '\\','?','?','\\','p','i','p','e',
2094 '\\','W','i','n','3','2','.','P','i','p','e','s','.','%','0','8','l',
2095 'u','.','%','0','8','u','\0' };
2097 snprintfW(name, ARRAY_SIZE(name), nameFmt, GetCurrentProcessId(), ++index);
2098 RtlInitUnicodeString(&nt_name, name);
2099 status = NtCreateNamedPipeFile(&hr, GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
2100 &attr, &iosb, FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
2101 FILE_SYNCHRONOUS_IO_NONALERT,
2102 FALSE, FALSE, FALSE,
2103 1, size, size, &timeout);
2104 if (status)
2106 SetLastError( RtlNtStatusToDosError(status) );
2107 hr = INVALID_HANDLE_VALUE;
2109 } while (hr == INVALID_HANDLE_VALUE && index != in_index);
2110 /* from completion sakeness, I think system resources might be exhausted before this happens !! */
2111 if (hr == INVALID_HANDLE_VALUE) return FALSE;
2113 status = NtOpenFile(&hw, GENERIC_WRITE | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, 0,
2114 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
2116 if (status)
2118 SetLastError( RtlNtStatusToDosError(status) );
2119 NtClose(hr);
2120 return FALSE;
2123 *hReadPipe = hr;
2124 *hWritePipe = hw;
2125 return TRUE;
2129 /******************************************************************************
2130 * CreateMailslotA [KERNEL32.@]
2132 * See CreateMailslotW.
2134 HANDLE WINAPI CreateMailslotA( LPCSTR lpName, DWORD nMaxMessageSize,
2135 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
2137 DWORD len;
2138 HANDLE handle;
2139 LPWSTR name = NULL;
2141 TRACE("%s %d %d %p\n", debugstr_a(lpName),
2142 nMaxMessageSize, lReadTimeout, sa);
2144 if( lpName )
2146 len = MultiByteToWideChar( CP_ACP, 0, lpName, -1, NULL, 0 );
2147 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2148 MultiByteToWideChar( CP_ACP, 0, lpName, -1, name, len );
2151 handle = CreateMailslotW( name, nMaxMessageSize, lReadTimeout, sa );
2153 HeapFree( GetProcessHeap(), 0, name );
2155 return handle;
2159 /******************************************************************************
2160 * CreateMailslotW [KERNEL32.@]
2162 * Create a mailslot with specified name.
2164 * PARAMS
2165 * lpName [I] Pointer to string for mailslot name
2166 * nMaxMessageSize [I] Maximum message size
2167 * lReadTimeout [I] Milliseconds before read time-out
2168 * sa [I] Pointer to security structure
2170 * RETURNS
2171 * Success: Handle to mailslot
2172 * Failure: INVALID_HANDLE_VALUE
2174 HANDLE WINAPI CreateMailslotW( LPCWSTR lpName, DWORD nMaxMessageSize,
2175 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
2177 HANDLE handle = INVALID_HANDLE_VALUE;
2178 OBJECT_ATTRIBUTES attr;
2179 UNICODE_STRING nameW;
2180 LARGE_INTEGER timeout;
2181 IO_STATUS_BLOCK iosb;
2182 NTSTATUS status;
2184 TRACE("%s %d %d %p\n", debugstr_w(lpName),
2185 nMaxMessageSize, lReadTimeout, sa);
2187 if (!RtlDosPathNameToNtPathName_U( lpName, &nameW, NULL, NULL ))
2189 SetLastError( ERROR_PATH_NOT_FOUND );
2190 return INVALID_HANDLE_VALUE;
2193 if (nameW.Length >= MAX_PATH * sizeof(WCHAR) )
2195 SetLastError( ERROR_FILENAME_EXCED_RANGE );
2196 RtlFreeUnicodeString( &nameW );
2197 return INVALID_HANDLE_VALUE;
2200 attr.Length = sizeof(attr);
2201 attr.RootDirectory = 0;
2202 attr.Attributes = OBJ_CASE_INSENSITIVE;
2203 attr.ObjectName = &nameW;
2204 attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
2205 attr.SecurityQualityOfService = NULL;
2207 if (lReadTimeout != MAILSLOT_WAIT_FOREVER)
2208 timeout.QuadPart = (ULONGLONG) lReadTimeout * -10000;
2209 else
2210 timeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
2212 status = NtCreateMailslotFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr,
2213 &iosb, 0, 0, nMaxMessageSize, &timeout );
2214 if (status)
2216 SetLastError( RtlNtStatusToDosError(status) );
2217 handle = INVALID_HANDLE_VALUE;
2220 RtlFreeUnicodeString( &nameW );
2221 return handle;
2225 /******************************************************************************
2226 * GetMailslotInfo [KERNEL32.@]
2228 * Retrieve information about a mailslot.
2230 * PARAMS
2231 * hMailslot [I] Mailslot handle
2232 * lpMaxMessageSize [O] Address of maximum message size
2233 * lpNextSize [O] Address of size of next message
2234 * lpMessageCount [O] Address of number of messages
2235 * lpReadTimeout [O] Address of read time-out
2237 * RETURNS
2238 * Success: TRUE
2239 * Failure: FALSE
2241 BOOL WINAPI GetMailslotInfo( HANDLE hMailslot, LPDWORD lpMaxMessageSize,
2242 LPDWORD lpNextSize, LPDWORD lpMessageCount,
2243 LPDWORD lpReadTimeout )
2245 FILE_MAILSLOT_QUERY_INFORMATION info;
2246 IO_STATUS_BLOCK iosb;
2247 NTSTATUS status;
2249 TRACE("%p %p %p %p %p\n",hMailslot, lpMaxMessageSize,
2250 lpNextSize, lpMessageCount, lpReadTimeout);
2252 status = NtQueryInformationFile( hMailslot, &iosb, &info, sizeof info,
2253 FileMailslotQueryInformation );
2255 if( status != STATUS_SUCCESS )
2257 SetLastError( RtlNtStatusToDosError(status) );
2258 return FALSE;
2261 if( lpMaxMessageSize )
2262 *lpMaxMessageSize = info.MaximumMessageSize;
2263 if( lpNextSize )
2264 *lpNextSize = info.NextMessageSize;
2265 if( lpMessageCount )
2266 *lpMessageCount = info.MessagesAvailable;
2267 if( lpReadTimeout )
2269 if (info.ReadTimeout.QuadPart == (((LONGLONG)0x7fffffff << 32) | 0xffffffff))
2270 *lpReadTimeout = MAILSLOT_WAIT_FOREVER;
2271 else
2272 *lpReadTimeout = info.ReadTimeout.QuadPart / -10000;
2274 return TRUE;
2278 /******************************************************************************
2279 * SetMailslotInfo [KERNEL32.@]
2281 * Set the read timeout of a mailslot.
2283 * PARAMS
2284 * hMailslot [I] Mailslot handle
2285 * dwReadTimeout [I] Timeout in milliseconds.
2287 * RETURNS
2288 * Success: TRUE
2289 * Failure: FALSE
2291 BOOL WINAPI SetMailslotInfo( HANDLE hMailslot, DWORD dwReadTimeout)
2293 FILE_MAILSLOT_SET_INFORMATION info;
2294 IO_STATUS_BLOCK iosb;
2295 NTSTATUS status;
2297 TRACE("%p %d\n", hMailslot, dwReadTimeout);
2299 if (dwReadTimeout != MAILSLOT_WAIT_FOREVER)
2300 info.ReadTimeout.QuadPart = (ULONGLONG)dwReadTimeout * -10000;
2301 else
2302 info.ReadTimeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
2303 status = NtSetInformationFile( hMailslot, &iosb, &info, sizeof info,
2304 FileMailslotSetInformation );
2305 if( status != STATUS_SUCCESS )
2307 SetLastError( RtlNtStatusToDosError(status) );
2308 return FALSE;
2310 return TRUE;
2314 /******************************************************************************
2315 * CreateIoCompletionPort (KERNEL32.@)
2317 HANDLE WINAPI CreateIoCompletionPort(HANDLE hFileHandle, HANDLE hExistingCompletionPort,
2318 ULONG_PTR CompletionKey, DWORD dwNumberOfConcurrentThreads)
2320 NTSTATUS status;
2321 HANDLE ret = 0;
2323 TRACE("(%p, %p, %08lx, %08x)\n",
2324 hFileHandle, hExistingCompletionPort, CompletionKey, dwNumberOfConcurrentThreads);
2326 if (hExistingCompletionPort && hFileHandle == INVALID_HANDLE_VALUE)
2328 SetLastError( ERROR_INVALID_PARAMETER);
2329 return NULL;
2332 if (hExistingCompletionPort)
2333 ret = hExistingCompletionPort;
2334 else
2336 status = NtCreateIoCompletion( &ret, IO_COMPLETION_ALL_ACCESS, NULL, dwNumberOfConcurrentThreads );
2337 if (status != STATUS_SUCCESS) goto fail;
2340 if (hFileHandle != INVALID_HANDLE_VALUE)
2342 FILE_COMPLETION_INFORMATION info;
2343 IO_STATUS_BLOCK iosb;
2345 info.CompletionPort = ret;
2346 info.CompletionKey = CompletionKey;
2347 status = NtSetInformationFile( hFileHandle, &iosb, &info, sizeof(info), FileCompletionInformation );
2348 if (status != STATUS_SUCCESS) goto fail;
2351 return ret;
2353 fail:
2354 if (ret && !hExistingCompletionPort)
2355 CloseHandle( ret );
2356 SetLastError( RtlNtStatusToDosError(status) );
2357 return 0;
2360 /******************************************************************************
2361 * GetQueuedCompletionStatus (KERNEL32.@)
2363 BOOL WINAPI GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred,
2364 PULONG_PTR pCompletionKey, LPOVERLAPPED *lpOverlapped,
2365 DWORD dwMilliseconds )
2367 NTSTATUS status;
2368 IO_STATUS_BLOCK iosb;
2369 LARGE_INTEGER wait_time;
2371 TRACE("(%p,%p,%p,%p,%d)\n",
2372 CompletionPort,lpNumberOfBytesTransferred,pCompletionKey,lpOverlapped,dwMilliseconds);
2374 *lpOverlapped = NULL;
2376 status = NtRemoveIoCompletion( CompletionPort, pCompletionKey, (PULONG_PTR)lpOverlapped,
2377 &iosb, get_nt_timeout( &wait_time, dwMilliseconds ) );
2378 if (status == STATUS_SUCCESS)
2380 *lpNumberOfBytesTransferred = iosb.Information;
2381 if (iosb.u.Status >= 0) return TRUE;
2382 SetLastError( RtlNtStatusToDosError(iosb.u.Status) );
2383 return FALSE;
2386 if (status == STATUS_TIMEOUT) SetLastError( WAIT_TIMEOUT );
2387 else SetLastError( RtlNtStatusToDosError(status) );
2388 return FALSE;
2391 /******************************************************************************
2392 * GetQueuedCompletionStatusEx (KERNEL32.@)
2394 BOOL WINAPI GetQueuedCompletionStatusEx( HANDLE port, OVERLAPPED_ENTRY *entries, ULONG count,
2395 ULONG *written, DWORD timeout, BOOL alertable )
2397 LARGE_INTEGER time;
2398 NTSTATUS ret;
2400 TRACE("%p %p %u %p %u %u\n", port, entries, count, written, timeout, alertable);
2402 ret = NtRemoveIoCompletionEx( port, (FILE_IO_COMPLETION_INFORMATION *)entries, count,
2403 written, get_nt_timeout( &time, timeout ), alertable );
2404 if (ret == STATUS_SUCCESS) return TRUE;
2405 else if (ret == STATUS_TIMEOUT) SetLastError( WAIT_TIMEOUT );
2406 else if (ret == STATUS_USER_APC) SetLastError( WAIT_IO_COMPLETION );
2407 else SetLastError( RtlNtStatusToDosError(ret) );
2408 return FALSE;
2411 /******************************************************************************
2412 * PostQueuedCompletionStatus (KERNEL32.@)
2414 BOOL WINAPI PostQueuedCompletionStatus( HANDLE CompletionPort, DWORD dwNumberOfBytes,
2415 ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped)
2417 NTSTATUS status;
2419 TRACE("%p %d %08lx %p\n", CompletionPort, dwNumberOfBytes, dwCompletionKey, lpOverlapped );
2421 status = NtSetIoCompletion( CompletionPort, dwCompletionKey, (ULONG_PTR)lpOverlapped,
2422 STATUS_SUCCESS, dwNumberOfBytes );
2424 if (status == STATUS_SUCCESS) return TRUE;
2425 SetLastError( RtlNtStatusToDosError(status) );
2426 return FALSE;
2429 /******************************************************************************
2430 * BindIoCompletionCallback (KERNEL32.@)
2432 BOOL WINAPI BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags)
2434 NTSTATUS status;
2436 TRACE("(%p, %p, %d)\n", FileHandle, Function, Flags);
2438 status = RtlSetIoCompletionCallback( FileHandle, (PRTL_OVERLAPPED_COMPLETION_ROUTINE)Function, Flags );
2439 if (status == STATUS_SUCCESS) return TRUE;
2440 SetLastError( RtlNtStatusToDosError(status) );
2441 return FALSE;
2445 /***********************************************************************
2446 * CreateMemoryResourceNotification (KERNEL32.@)
2448 HANDLE WINAPI CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE type)
2450 static const WCHAR lowmemW[] =
2451 {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
2452 '\\','L','o','w','M','e','m','o','r','y','C','o','n','d','i','t','i','o','n',0};
2453 static const WCHAR highmemW[] =
2454 {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
2455 '\\','H','i','g','h','M','e','m','o','r','y','C','o','n','d','i','t','i','o','n',0};
2456 HANDLE ret;
2457 UNICODE_STRING nameW;
2458 OBJECT_ATTRIBUTES attr;
2459 NTSTATUS status;
2461 switch (type)
2463 case LowMemoryResourceNotification:
2464 RtlInitUnicodeString( &nameW, lowmemW );
2465 break;
2466 case HighMemoryResourceNotification:
2467 RtlInitUnicodeString( &nameW, highmemW );
2468 break;
2469 default:
2470 SetLastError( ERROR_INVALID_PARAMETER );
2471 return 0;
2474 attr.Length = sizeof(attr);
2475 attr.RootDirectory = 0;
2476 attr.ObjectName = &nameW;
2477 attr.Attributes = 0;
2478 attr.SecurityDescriptor = NULL;
2479 attr.SecurityQualityOfService = NULL;
2480 status = NtOpenEvent( &ret, EVENT_ALL_ACCESS, &attr );
2481 if (status != STATUS_SUCCESS)
2483 SetLastError( RtlNtStatusToDosError(status) );
2484 return 0;
2486 return ret;
2489 /***********************************************************************
2490 * QueryMemoryResourceNotification (KERNEL32.@)
2492 BOOL WINAPI QueryMemoryResourceNotification(HANDLE handle, PBOOL state)
2494 switch (WaitForSingleObject( handle, 0 ))
2496 case WAIT_OBJECT_0:
2497 *state = TRUE;
2498 return TRUE;
2499 case WAIT_TIMEOUT:
2500 *state = FALSE;
2501 return TRUE;
2503 SetLastError( ERROR_INVALID_PARAMETER );
2504 return FALSE;
2507 /***********************************************************************
2508 * InitOnceBeginInitialize (KERNEL32.@)
2510 BOOL WINAPI InitOnceBeginInitialize( INIT_ONCE *once, DWORD flags, BOOL *pending, void **context )
2512 NTSTATUS status = RtlRunOnceBeginInitialize( once, flags, context );
2513 if (status >= 0) *pending = (status == STATUS_PENDING);
2514 else SetLastError( RtlNtStatusToDosError(status) );
2515 return status >= 0;
2518 /***********************************************************************
2519 * InitOnceComplete (KERNEL32.@)
2521 BOOL WINAPI InitOnceComplete( INIT_ONCE *once, DWORD flags, void *context )
2523 NTSTATUS status = RtlRunOnceComplete( once, flags, context );
2524 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
2525 return !status;
2528 /***********************************************************************
2529 * InitOnceExecuteOnce (KERNEL32.@)
2531 BOOL WINAPI InitOnceExecuteOnce( INIT_ONCE *once, PINIT_ONCE_FN func, void *param, void **context )
2533 return !RtlRunOnceExecuteOnce( once, (PRTL_RUN_ONCE_INIT_FN)func, param, context );
2536 #ifdef __i386__
2538 /***********************************************************************
2539 * InterlockedCompareExchange (KERNEL32.@)
2541 /* LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ); */
2542 __ASM_STDCALL_FUNC(InterlockedCompareExchange, 12,
2543 "movl 12(%esp),%eax\n\t"
2544 "movl 8(%esp),%ecx\n\t"
2545 "movl 4(%esp),%edx\n\t"
2546 "lock; cmpxchgl %ecx,(%edx)\n\t"
2547 "ret $12")
2549 /***********************************************************************
2550 * InterlockedExchange (KERNEL32.@)
2552 /* LONG WINAPI InterlockedExchange( PLONG dest, LONG val ); */
2553 __ASM_STDCALL_FUNC(InterlockedExchange, 8,
2554 "movl 8(%esp),%eax\n\t"
2555 "movl 4(%esp),%edx\n\t"
2556 "lock; xchgl %eax,(%edx)\n\t"
2557 "ret $8")
2559 /***********************************************************************
2560 * InterlockedExchangeAdd (KERNEL32.@)
2562 /* LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ); */
2563 __ASM_STDCALL_FUNC(InterlockedExchangeAdd, 8,
2564 "movl 8(%esp),%eax\n\t"
2565 "movl 4(%esp),%edx\n\t"
2566 "lock; xaddl %eax,(%edx)\n\t"
2567 "ret $8")
2569 /***********************************************************************
2570 * InterlockedIncrement (KERNEL32.@)
2572 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
2573 __ASM_STDCALL_FUNC(InterlockedIncrement, 4,
2574 "movl 4(%esp),%edx\n\t"
2575 "movl $1,%eax\n\t"
2576 "lock; xaddl %eax,(%edx)\n\t"
2577 "incl %eax\n\t"
2578 "ret $4")
2580 /***********************************************************************
2581 * InterlockedDecrement (KERNEL32.@)
2583 __ASM_STDCALL_FUNC(InterlockedDecrement, 4,
2584 "movl 4(%esp),%edx\n\t"
2585 "movl $-1,%eax\n\t"
2586 "lock; xaddl %eax,(%edx)\n\t"
2587 "decl %eax\n\t"
2588 "ret $4")
2590 #endif /* __i386__ */
2592 /***********************************************************************
2593 * SleepConditionVariableCS (KERNEL32.@)
2595 BOOL WINAPI SleepConditionVariableCS( CONDITION_VARIABLE *variable, CRITICAL_SECTION *crit, DWORD timeout )
2597 NTSTATUS status;
2598 LARGE_INTEGER time;
2600 status = RtlSleepConditionVariableCS( variable, crit, get_nt_timeout( &time, timeout ) );
2602 if (status != STATUS_SUCCESS)
2604 SetLastError( RtlNtStatusToDosError(status) );
2605 return FALSE;
2607 return TRUE;
2610 /***********************************************************************
2611 * SleepConditionVariableSRW (KERNEL32.@)
2613 BOOL WINAPI SleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, RTL_SRWLOCK *lock, DWORD timeout, ULONG flags )
2615 NTSTATUS status;
2616 LARGE_INTEGER time;
2618 status = RtlSleepConditionVariableSRW( variable, lock, get_nt_timeout( &time, timeout ), flags );
2620 if (status != STATUS_SUCCESS)
2622 SetLastError( RtlNtStatusToDosError(status) );
2623 return FALSE;
2625 return TRUE;