kernel32: Implement GetNamedPipeClient/ServerProcessId.
[wine.git] / dlls / kernel32 / sync.c
blob04e9779664f3868b6ce4b65c135040234704afe4
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)
1536 ULONG read_size = io.Information - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data );
1537 if (lpcbAvail) *lpcbAvail = buffer->ReadDataAvailable;
1538 if (lpcbRead) *lpcbRead = read_size;
1539 if (lpcbMessage) *lpcbMessage = buffer->MessageLength - read_size;
1540 if (lpvBuffer) memcpy( lpvBuffer, buffer->Data, read_size );
1542 else SetLastError( RtlNtStatusToDosError(status) );
1544 if (buffer != &local_buffer) HeapFree( GetProcessHeap(), 0, buffer );
1545 return !status;
1548 /***********************************************************************
1549 * WaitNamedPipeA (KERNEL32.@)
1551 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
1553 WCHAR buffer[MAX_PATH];
1555 if (!name) return WaitNamedPipeW( NULL, nTimeOut );
1557 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
1559 SetLastError( ERROR_FILENAME_EXCED_RANGE );
1560 return FALSE;
1562 return WaitNamedPipeW( buffer, nTimeOut );
1566 /***********************************************************************
1567 * WaitNamedPipeW (KERNEL32.@)
1569 * Waits for a named pipe instance to become available
1571 * PARAMS
1572 * name [I] Pointer to a named pipe name to wait for
1573 * nTimeOut [I] How long to wait in ms
1575 * RETURNS
1576 * TRUE: Success, named pipe can be opened with CreateFile
1577 * FALSE: Failure, GetLastError can be called for further details
1579 BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
1581 static const WCHAR leadin[] = {'\\','?','?','\\','P','I','P','E','\\'};
1582 NTSTATUS status;
1583 UNICODE_STRING nt_name, pipe_dev_name;
1584 FILE_PIPE_WAIT_FOR_BUFFER *pipe_wait;
1585 IO_STATUS_BLOCK iosb;
1586 OBJECT_ATTRIBUTES attr;
1587 ULONG sz_pipe_wait;
1588 HANDLE pipe_dev;
1590 TRACE("%s 0x%08x\n",debugstr_w(name),nTimeOut);
1592 if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
1593 return FALSE;
1595 if (nt_name.Length >= MAX_PATH * sizeof(WCHAR) ||
1596 nt_name.Length < sizeof(leadin) ||
1597 strncmpiW( nt_name.Buffer, leadin, sizeof(leadin)/sizeof(WCHAR)) != 0)
1599 RtlFreeUnicodeString( &nt_name );
1600 SetLastError( ERROR_PATH_NOT_FOUND );
1601 return FALSE;
1604 sz_pipe_wait = sizeof(*pipe_wait) + nt_name.Length - sizeof(leadin) - sizeof(WCHAR);
1605 if (!(pipe_wait = HeapAlloc( GetProcessHeap(), 0, sz_pipe_wait)))
1607 RtlFreeUnicodeString( &nt_name );
1608 SetLastError( ERROR_OUTOFMEMORY );
1609 return FALSE;
1612 pipe_dev_name.Buffer = nt_name.Buffer;
1613 pipe_dev_name.Length = sizeof(leadin);
1614 pipe_dev_name.MaximumLength = sizeof(leadin);
1615 InitializeObjectAttributes(&attr,&pipe_dev_name, OBJ_CASE_INSENSITIVE, NULL, NULL);
1616 status = NtOpenFile( &pipe_dev, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr,
1617 &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE,
1618 FILE_SYNCHRONOUS_IO_NONALERT);
1619 if (status != STATUS_SUCCESS)
1621 HeapFree( GetProcessHeap(), 0, pipe_wait);
1622 RtlFreeUnicodeString( &nt_name );
1623 SetLastError( ERROR_PATH_NOT_FOUND );
1624 return FALSE;
1627 pipe_wait->TimeoutSpecified = !(nTimeOut == NMPWAIT_USE_DEFAULT_WAIT);
1628 if (nTimeOut == NMPWAIT_WAIT_FOREVER)
1629 pipe_wait->Timeout.QuadPart = ((ULONGLONG)0x7fffffff << 32) | 0xffffffff;
1630 else
1631 pipe_wait->Timeout.QuadPart = (ULONGLONG)nTimeOut * -10000;
1632 pipe_wait->NameLength = nt_name.Length - sizeof(leadin);
1633 memcpy(pipe_wait->Name, nt_name.Buffer + sizeof(leadin)/sizeof(WCHAR),
1634 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);
1685 if (status == STATUS_SUCCESS) return TRUE;
1686 SetLastError( RtlNtStatusToDosError(status) );
1687 return FALSE;
1690 /***********************************************************************
1691 * DisconnectNamedPipe (KERNEL32.@)
1693 * Disconnects from a named pipe
1695 * Parameters
1696 * hPipe: A handle to a named pipe returned by CreateNamedPipe
1698 * Return values
1699 * TRUE: Success
1700 * FALSE: Failure, GetLastError can be called for further details
1702 BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
1704 NTSTATUS status;
1705 IO_STATUS_BLOCK io_block;
1707 TRACE("(%p)\n",hPipe);
1709 status = NtFsControlFile(hPipe, 0, NULL, NULL, &io_block, FSCTL_PIPE_DISCONNECT,
1710 NULL, 0, NULL, 0);
1711 if (status == STATUS_SUCCESS) return TRUE;
1712 SetLastError( RtlNtStatusToDosError(status) );
1713 return FALSE;
1716 /***********************************************************************
1717 * TransactNamedPipe (KERNEL32.@)
1719 BOOL WINAPI TransactNamedPipe(
1720 HANDLE handle, LPVOID write_buf, DWORD write_size, LPVOID read_buf,
1721 DWORD read_size, LPDWORD bytes_read, LPOVERLAPPED overlapped)
1723 IO_STATUS_BLOCK default_iosb, *iosb = &default_iosb;
1724 HANDLE event = NULL;
1725 void *cvalue = NULL;
1726 NTSTATUS status;
1728 TRACE("%p %p %u %p %u %p %p\n", handle, write_buf, write_size, read_buf,
1729 read_size, bytes_read, overlapped);
1731 if (overlapped)
1733 event = overlapped->hEvent;
1734 iosb = (IO_STATUS_BLOCK *)overlapped;
1735 if (((ULONG_PTR)event & 1) == 0) cvalue = overlapped;
1737 else
1739 iosb->Information = 0;
1742 status = NtFsControlFile(handle, event, NULL, cvalue, iosb, FSCTL_PIPE_TRANSCEIVE,
1743 write_buf, write_size, read_buf, read_size);
1745 if (bytes_read) *bytes_read = overlapped && status ? 0 : iosb->Information;
1747 if (status)
1749 SetLastError(RtlNtStatusToDosError(status));
1750 return FALSE;
1752 return TRUE;
1755 /***********************************************************************
1756 * GetNamedPipeInfo (KERNEL32.@)
1758 BOOL WINAPI GetNamedPipeInfo(
1759 HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutputBufferSize,
1760 LPDWORD lpInputBufferSize, LPDWORD lpMaxInstances)
1762 FILE_PIPE_LOCAL_INFORMATION fpli;
1763 IO_STATUS_BLOCK iosb;
1764 NTSTATUS status;
1766 status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli),
1767 FilePipeLocalInformation);
1768 if (status)
1770 SetLastError( RtlNtStatusToDosError(status) );
1771 return FALSE;
1774 if (lpFlags)
1776 *lpFlags = (fpli.NamedPipeEnd & FILE_PIPE_SERVER_END) ?
1777 PIPE_SERVER_END : PIPE_CLIENT_END;
1778 *lpFlags |= (fpli.NamedPipeType & FILE_PIPE_TYPE_MESSAGE) ?
1779 PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE;
1782 if (lpOutputBufferSize) *lpOutputBufferSize = fpli.OutboundQuota;
1783 if (lpInputBufferSize) *lpInputBufferSize = fpli.InboundQuota;
1784 if (lpMaxInstances) *lpMaxInstances = fpli.MaximumInstances;
1786 return TRUE;
1789 /***********************************************************************
1790 * GetNamedPipeClientProcessId (KERNEL32.@)
1792 BOOL WINAPI GetNamedPipeClientProcessId( HANDLE pipe, ULONG *id )
1794 IO_STATUS_BLOCK iosb;
1795 NTSTATUS status;
1797 TRACE( "%p %p\n", pipe, id );
1799 status = NtFsControlFile( pipe, NULL, NULL, NULL, &iosb, FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE,
1800 (void *)"ClientProcessId", sizeof("ClientProcessId"), id, sizeof(*id) );
1801 if (status)
1803 SetLastError( RtlNtStatusToDosError(status) );
1804 return FALSE;
1806 return TRUE;
1809 /***********************************************************************
1810 * GetNamedPipeServerProcessId (KERNEL32.@)
1812 BOOL WINAPI GetNamedPipeServerProcessId( HANDLE pipe, ULONG *id )
1814 IO_STATUS_BLOCK iosb;
1815 NTSTATUS status;
1817 TRACE( "%p, %p\n", pipe, id );
1819 status = NtFsControlFile( pipe, NULL, NULL, NULL, &iosb, FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE,
1820 (void *)"ServerProcessId", sizeof("ServerProcessId"), id, sizeof(*id) );
1821 if (status)
1823 SetLastError( RtlNtStatusToDosError(status) );
1824 return FALSE;
1826 return TRUE;
1829 /***********************************************************************
1830 * GetNamedPipeHandleStateA (KERNEL32.@)
1832 BOOL WINAPI GetNamedPipeHandleStateA(
1833 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1834 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1835 LPSTR lpUsername, DWORD nUsernameMaxSize)
1837 WCHAR *username = NULL;
1838 BOOL ret;
1840 WARN("%p %p %p %p %p %p %d: semi-stub\n", hNamedPipe, lpState, lpCurInstances,
1841 lpMaxCollectionCount, lpCollectDataTimeout, lpUsername, nUsernameMaxSize);
1843 if (lpUsername && nUsernameMaxSize &&
1844 !(username = HeapAlloc(GetProcessHeap(), 0, nUsernameMaxSize * sizeof(WCHAR)))) return FALSE;
1846 ret = GetNamedPipeHandleStateW(hNamedPipe, lpState, lpCurInstances, lpMaxCollectionCount,
1847 lpCollectDataTimeout, username, nUsernameMaxSize);
1848 if (ret && username)
1849 WideCharToMultiByte(CP_ACP, 0, username, -1, lpUsername, nUsernameMaxSize, NULL, NULL);
1851 HeapFree(GetProcessHeap(), 0, username);
1852 return ret;
1855 /***********************************************************************
1856 * GetNamedPipeHandleStateW (KERNEL32.@)
1858 BOOL WINAPI GetNamedPipeHandleStateW(
1859 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
1860 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
1861 LPWSTR lpUsername, DWORD nUsernameMaxSize)
1863 IO_STATUS_BLOCK iosb;
1864 NTSTATUS status;
1866 FIXME("%p %p %p %p %p %p %d: semi-stub\n", hNamedPipe, lpState, lpCurInstances,
1867 lpMaxCollectionCount, lpCollectDataTimeout, lpUsername, nUsernameMaxSize);
1869 if (lpMaxCollectionCount)
1870 *lpMaxCollectionCount = 0;
1872 if (lpCollectDataTimeout)
1873 *lpCollectDataTimeout = 0;
1875 if (lpUsername && nUsernameMaxSize)
1877 const char *username = wine_get_user_name();
1878 int len = MultiByteToWideChar(CP_UNIXCP, 0, username, -1, lpUsername, nUsernameMaxSize);
1879 if (!len) *lpUsername = 0;
1882 if (lpState)
1884 FILE_PIPE_INFORMATION fpi;
1885 status = NtQueryInformationFile(hNamedPipe, &iosb, &fpi, sizeof(fpi),
1886 FilePipeInformation);
1887 if (status)
1889 SetLastError( RtlNtStatusToDosError(status) );
1890 return FALSE;
1893 *lpState = (fpi.ReadMode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE) |
1894 (fpi.CompletionMode ? PIPE_NOWAIT : PIPE_WAIT);
1897 if (lpCurInstances)
1899 FILE_PIPE_LOCAL_INFORMATION fpli;
1900 status = NtQueryInformationFile(hNamedPipe, &iosb, &fpli, sizeof(fpli),
1901 FilePipeLocalInformation);
1902 if (status)
1904 SetLastError( RtlNtStatusToDosError(status) );
1905 return FALSE;
1908 *lpCurInstances = fpli.CurrentInstances;
1911 return TRUE;
1914 /***********************************************************************
1915 * SetNamedPipeHandleState (KERNEL32.@)
1917 BOOL WINAPI SetNamedPipeHandleState(
1918 HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount,
1919 LPDWORD lpCollectDataTimeout)
1921 /* should be a fixme, but this function is called a lot by the RPC
1922 * runtime, and it slows down InstallShield a fair bit. */
1923 WARN("semi-stub: %p %p/%d %p %p\n",
1924 hNamedPipe, lpMode, lpMode ? *lpMode : 0, lpMaxCollectionCount, lpCollectDataTimeout);
1926 if (lpMode)
1928 FILE_PIPE_INFORMATION fpi;
1929 IO_STATUS_BLOCK iosb;
1930 NTSTATUS status;
1932 if (*lpMode & ~(PIPE_READMODE_MESSAGE | PIPE_NOWAIT))
1933 status = STATUS_INVALID_PARAMETER;
1934 else
1936 fpi.CompletionMode = (*lpMode & PIPE_NOWAIT) ?
1937 FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION;
1938 fpi.ReadMode = (*lpMode & PIPE_READMODE_MESSAGE) ?
1939 FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE;
1940 status = NtSetInformationFile(hNamedPipe, &iosb, &fpi, sizeof(fpi), FilePipeInformation);
1943 if (status)
1945 SetLastError( RtlNtStatusToDosError(status) );
1946 return FALSE;
1950 return TRUE;
1953 /***********************************************************************
1954 * CallNamedPipeA (KERNEL32.@)
1956 BOOL WINAPI CallNamedPipeA(
1957 LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD dwInputSize,
1958 LPVOID lpOutput, DWORD dwOutputSize,
1959 LPDWORD lpBytesRead, DWORD nTimeout)
1961 DWORD len;
1962 LPWSTR str = NULL;
1963 BOOL ret;
1965 TRACE("%s %p %d %p %d %p %d\n",
1966 debugstr_a(lpNamedPipeName), lpInput, dwInputSize,
1967 lpOutput, dwOutputSize, lpBytesRead, nTimeout);
1969 if( lpNamedPipeName )
1971 len = MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, NULL, 0 );
1972 str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1973 MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, str, len );
1975 ret = CallNamedPipeW( str, lpInput, dwInputSize, lpOutput,
1976 dwOutputSize, lpBytesRead, nTimeout );
1977 if( lpNamedPipeName )
1978 HeapFree( GetProcessHeap(), 0, str );
1980 return ret;
1983 /***********************************************************************
1984 * CallNamedPipeW (KERNEL32.@)
1986 BOOL WINAPI CallNamedPipeW(
1987 LPCWSTR lpNamedPipeName, LPVOID lpInput, DWORD lpInputSize,
1988 LPVOID lpOutput, DWORD lpOutputSize,
1989 LPDWORD lpBytesRead, DWORD nTimeout)
1991 HANDLE pipe;
1992 BOOL ret;
1993 DWORD mode;
1995 TRACE("%s %p %d %p %d %p %d\n",
1996 debugstr_w(lpNamedPipeName), lpInput, lpInputSize,
1997 lpOutput, lpOutputSize, lpBytesRead, nTimeout);
1999 pipe = CreateFileW(lpNamedPipeName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
2000 if (pipe == INVALID_HANDLE_VALUE)
2002 ret = WaitNamedPipeW(lpNamedPipeName, nTimeout);
2003 if (!ret)
2004 return FALSE;
2005 pipe = CreateFileW(lpNamedPipeName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
2006 if (pipe == INVALID_HANDLE_VALUE)
2007 return FALSE;
2010 mode = PIPE_READMODE_MESSAGE;
2011 ret = SetNamedPipeHandleState(pipe, &mode, NULL, NULL);
2012 if (!ret)
2014 CloseHandle(pipe);
2015 return FALSE;
2018 ret = TransactNamedPipe(pipe, lpInput, lpInputSize, lpOutput, lpOutputSize, lpBytesRead, NULL);
2019 CloseHandle(pipe);
2020 if (!ret)
2021 return FALSE;
2023 return TRUE;
2026 /******************************************************************
2027 * CreatePipe (KERNEL32.@)
2030 BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
2031 LPSECURITY_ATTRIBUTES sa, DWORD size )
2033 static unsigned index /* = 0 */;
2034 WCHAR name[64];
2035 HANDLE hr, hw;
2036 unsigned in_index = index;
2037 UNICODE_STRING nt_name;
2038 OBJECT_ATTRIBUTES attr;
2039 NTSTATUS status;
2040 IO_STATUS_BLOCK iosb;
2041 LARGE_INTEGER timeout;
2043 *hReadPipe = *hWritePipe = INVALID_HANDLE_VALUE;
2045 attr.Length = sizeof(attr);
2046 attr.RootDirectory = 0;
2047 attr.ObjectName = &nt_name;
2048 attr.Attributes = OBJ_CASE_INSENSITIVE |
2049 ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
2050 attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
2051 attr.SecurityQualityOfService = NULL;
2053 if (!size) size = 4096;
2055 timeout.QuadPart = (ULONGLONG)NMPWAIT_USE_DEFAULT_WAIT * -10000;
2056 /* generate a unique pipe name (system wide) */
2059 static const WCHAR nameFmt[] = { '\\','?','?','\\','p','i','p','e',
2060 '\\','W','i','n','3','2','.','P','i','p','e','s','.','%','0','8','l',
2061 'u','.','%','0','8','u','\0' };
2063 snprintfW(name, sizeof(name) / sizeof(name[0]), nameFmt,
2064 GetCurrentProcessId(), ++index);
2065 RtlInitUnicodeString(&nt_name, name);
2066 status = NtCreateNamedPipeFile(&hr, GENERIC_READ | SYNCHRONIZE, &attr, &iosb,
2067 FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
2068 FILE_SYNCHRONOUS_IO_NONALERT,
2069 FALSE, FALSE, FALSE,
2070 1, size, size, &timeout);
2071 if (status)
2073 SetLastError( RtlNtStatusToDosError(status) );
2074 hr = INVALID_HANDLE_VALUE;
2076 } while (hr == INVALID_HANDLE_VALUE && index != in_index);
2077 /* from completion sakeness, I think system resources might be exhausted before this happens !! */
2078 if (hr == INVALID_HANDLE_VALUE) return FALSE;
2080 status = NtOpenFile(&hw, GENERIC_WRITE | SYNCHRONIZE, &attr, &iosb, 0,
2081 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
2083 if (status)
2085 SetLastError( RtlNtStatusToDosError(status) );
2086 NtClose(hr);
2087 return FALSE;
2090 *hReadPipe = hr;
2091 *hWritePipe = hw;
2092 return TRUE;
2096 /******************************************************************************
2097 * CreateMailslotA [KERNEL32.@]
2099 * See CreateMailslotW.
2101 HANDLE WINAPI CreateMailslotA( LPCSTR lpName, DWORD nMaxMessageSize,
2102 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
2104 DWORD len;
2105 HANDLE handle;
2106 LPWSTR name = NULL;
2108 TRACE("%s %d %d %p\n", debugstr_a(lpName),
2109 nMaxMessageSize, lReadTimeout, sa);
2111 if( lpName )
2113 len = MultiByteToWideChar( CP_ACP, 0, lpName, -1, NULL, 0 );
2114 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2115 MultiByteToWideChar( CP_ACP, 0, lpName, -1, name, len );
2118 handle = CreateMailslotW( name, nMaxMessageSize, lReadTimeout, sa );
2120 HeapFree( GetProcessHeap(), 0, name );
2122 return handle;
2126 /******************************************************************************
2127 * CreateMailslotW [KERNEL32.@]
2129 * Create a mailslot with specified name.
2131 * PARAMS
2132 * lpName [I] Pointer to string for mailslot name
2133 * nMaxMessageSize [I] Maximum message size
2134 * lReadTimeout [I] Milliseconds before read time-out
2135 * sa [I] Pointer to security structure
2137 * RETURNS
2138 * Success: Handle to mailslot
2139 * Failure: INVALID_HANDLE_VALUE
2141 HANDLE WINAPI CreateMailslotW( LPCWSTR lpName, DWORD nMaxMessageSize,
2142 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
2144 HANDLE handle = INVALID_HANDLE_VALUE;
2145 OBJECT_ATTRIBUTES attr;
2146 UNICODE_STRING nameW;
2147 LARGE_INTEGER timeout;
2148 IO_STATUS_BLOCK iosb;
2149 NTSTATUS status;
2151 TRACE("%s %d %d %p\n", debugstr_w(lpName),
2152 nMaxMessageSize, lReadTimeout, sa);
2154 if (!RtlDosPathNameToNtPathName_U( lpName, &nameW, NULL, NULL ))
2156 SetLastError( ERROR_PATH_NOT_FOUND );
2157 return INVALID_HANDLE_VALUE;
2160 if (nameW.Length >= MAX_PATH * sizeof(WCHAR) )
2162 SetLastError( ERROR_FILENAME_EXCED_RANGE );
2163 RtlFreeUnicodeString( &nameW );
2164 return INVALID_HANDLE_VALUE;
2167 attr.Length = sizeof(attr);
2168 attr.RootDirectory = 0;
2169 attr.Attributes = OBJ_CASE_INSENSITIVE;
2170 attr.ObjectName = &nameW;
2171 attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
2172 attr.SecurityQualityOfService = NULL;
2174 if (lReadTimeout != MAILSLOT_WAIT_FOREVER)
2175 timeout.QuadPart = (ULONGLONG) lReadTimeout * -10000;
2176 else
2177 timeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
2179 status = NtCreateMailslotFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr,
2180 &iosb, 0, 0, nMaxMessageSize, &timeout );
2181 if (status)
2183 SetLastError( RtlNtStatusToDosError(status) );
2184 handle = INVALID_HANDLE_VALUE;
2187 RtlFreeUnicodeString( &nameW );
2188 return handle;
2192 /******************************************************************************
2193 * GetMailslotInfo [KERNEL32.@]
2195 * Retrieve information about a mailslot.
2197 * PARAMS
2198 * hMailslot [I] Mailslot handle
2199 * lpMaxMessageSize [O] Address of maximum message size
2200 * lpNextSize [O] Address of size of next message
2201 * lpMessageCount [O] Address of number of messages
2202 * lpReadTimeout [O] Address of read time-out
2204 * RETURNS
2205 * Success: TRUE
2206 * Failure: FALSE
2208 BOOL WINAPI GetMailslotInfo( HANDLE hMailslot, LPDWORD lpMaxMessageSize,
2209 LPDWORD lpNextSize, LPDWORD lpMessageCount,
2210 LPDWORD lpReadTimeout )
2212 FILE_MAILSLOT_QUERY_INFORMATION info;
2213 IO_STATUS_BLOCK iosb;
2214 NTSTATUS status;
2216 TRACE("%p %p %p %p %p\n",hMailslot, lpMaxMessageSize,
2217 lpNextSize, lpMessageCount, lpReadTimeout);
2219 status = NtQueryInformationFile( hMailslot, &iosb, &info, sizeof info,
2220 FileMailslotQueryInformation );
2222 if( status != STATUS_SUCCESS )
2224 SetLastError( RtlNtStatusToDosError(status) );
2225 return FALSE;
2228 if( lpMaxMessageSize )
2229 *lpMaxMessageSize = info.MaximumMessageSize;
2230 if( lpNextSize )
2231 *lpNextSize = info.NextMessageSize;
2232 if( lpMessageCount )
2233 *lpMessageCount = info.MessagesAvailable;
2234 if( lpReadTimeout )
2236 if (info.ReadTimeout.QuadPart == (((LONGLONG)0x7fffffff << 32) | 0xffffffff))
2237 *lpReadTimeout = MAILSLOT_WAIT_FOREVER;
2238 else
2239 *lpReadTimeout = info.ReadTimeout.QuadPart / -10000;
2241 return TRUE;
2245 /******************************************************************************
2246 * SetMailslotInfo [KERNEL32.@]
2248 * Set the read timeout of a mailslot.
2250 * PARAMS
2251 * hMailslot [I] Mailslot handle
2252 * dwReadTimeout [I] Timeout in milliseconds.
2254 * RETURNS
2255 * Success: TRUE
2256 * Failure: FALSE
2258 BOOL WINAPI SetMailslotInfo( HANDLE hMailslot, DWORD dwReadTimeout)
2260 FILE_MAILSLOT_SET_INFORMATION info;
2261 IO_STATUS_BLOCK iosb;
2262 NTSTATUS status;
2264 TRACE("%p %d\n", hMailslot, dwReadTimeout);
2266 if (dwReadTimeout != MAILSLOT_WAIT_FOREVER)
2267 info.ReadTimeout.QuadPart = (ULONGLONG)dwReadTimeout * -10000;
2268 else
2269 info.ReadTimeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
2270 status = NtSetInformationFile( hMailslot, &iosb, &info, sizeof info,
2271 FileMailslotSetInformation );
2272 if( status != STATUS_SUCCESS )
2274 SetLastError( RtlNtStatusToDosError(status) );
2275 return FALSE;
2277 return TRUE;
2281 /******************************************************************************
2282 * CreateIoCompletionPort (KERNEL32.@)
2284 HANDLE WINAPI CreateIoCompletionPort(HANDLE hFileHandle, HANDLE hExistingCompletionPort,
2285 ULONG_PTR CompletionKey, DWORD dwNumberOfConcurrentThreads)
2287 NTSTATUS status;
2288 HANDLE ret = 0;
2290 TRACE("(%p, %p, %08lx, %08x)\n",
2291 hFileHandle, hExistingCompletionPort, CompletionKey, dwNumberOfConcurrentThreads);
2293 if (hExistingCompletionPort && hFileHandle == INVALID_HANDLE_VALUE)
2295 SetLastError( ERROR_INVALID_PARAMETER);
2296 return NULL;
2299 if (hExistingCompletionPort)
2300 ret = hExistingCompletionPort;
2301 else
2303 status = NtCreateIoCompletion( &ret, IO_COMPLETION_ALL_ACCESS, NULL, dwNumberOfConcurrentThreads );
2304 if (status != STATUS_SUCCESS) goto fail;
2307 if (hFileHandle != INVALID_HANDLE_VALUE)
2309 FILE_COMPLETION_INFORMATION info;
2310 IO_STATUS_BLOCK iosb;
2312 info.CompletionPort = ret;
2313 info.CompletionKey = CompletionKey;
2314 status = NtSetInformationFile( hFileHandle, &iosb, &info, sizeof(info), FileCompletionInformation );
2315 if (status != STATUS_SUCCESS) goto fail;
2318 return ret;
2320 fail:
2321 if (ret && !hExistingCompletionPort)
2322 CloseHandle( ret );
2323 SetLastError( RtlNtStatusToDosError(status) );
2324 return 0;
2327 /******************************************************************************
2328 * GetQueuedCompletionStatus (KERNEL32.@)
2330 BOOL WINAPI GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred,
2331 PULONG_PTR pCompletionKey, LPOVERLAPPED *lpOverlapped,
2332 DWORD dwMilliseconds )
2334 NTSTATUS status;
2335 IO_STATUS_BLOCK iosb;
2336 LARGE_INTEGER wait_time;
2338 TRACE("(%p,%p,%p,%p,%d)\n",
2339 CompletionPort,lpNumberOfBytesTransferred,pCompletionKey,lpOverlapped,dwMilliseconds);
2341 *lpOverlapped = NULL;
2343 status = NtRemoveIoCompletion( CompletionPort, pCompletionKey, (PULONG_PTR)lpOverlapped,
2344 &iosb, get_nt_timeout( &wait_time, dwMilliseconds ) );
2345 if (status == STATUS_SUCCESS)
2347 *lpNumberOfBytesTransferred = iosb.Information;
2348 if (iosb.u.Status >= 0) return TRUE;
2349 SetLastError( RtlNtStatusToDosError(iosb.u.Status) );
2350 return FALSE;
2353 if (status == STATUS_TIMEOUT) SetLastError( WAIT_TIMEOUT );
2354 else SetLastError( RtlNtStatusToDosError(status) );
2355 return FALSE;
2359 /******************************************************************************
2360 * PostQueuedCompletionStatus (KERNEL32.@)
2362 BOOL WINAPI PostQueuedCompletionStatus( HANDLE CompletionPort, DWORD dwNumberOfBytes,
2363 ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped)
2365 NTSTATUS status;
2367 TRACE("%p %d %08lx %p\n", CompletionPort, dwNumberOfBytes, dwCompletionKey, lpOverlapped );
2369 status = NtSetIoCompletion( CompletionPort, dwCompletionKey, (ULONG_PTR)lpOverlapped,
2370 STATUS_SUCCESS, dwNumberOfBytes );
2372 if (status == STATUS_SUCCESS) return TRUE;
2373 SetLastError( RtlNtStatusToDosError(status) );
2374 return FALSE;
2377 /******************************************************************************
2378 * BindIoCompletionCallback (KERNEL32.@)
2380 BOOL WINAPI BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags)
2382 NTSTATUS status;
2384 TRACE("(%p, %p, %d)\n", FileHandle, Function, Flags);
2386 status = RtlSetIoCompletionCallback( FileHandle, (PRTL_OVERLAPPED_COMPLETION_ROUTINE)Function, Flags );
2387 if (status == STATUS_SUCCESS) return TRUE;
2388 SetLastError( RtlNtStatusToDosError(status) );
2389 return FALSE;
2393 /***********************************************************************
2394 * CreateMemoryResourceNotification (KERNEL32.@)
2396 HANDLE WINAPI CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE type)
2398 static const WCHAR lowmemW[] =
2399 {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
2400 '\\','L','o','w','M','e','m','o','r','y','C','o','n','d','i','t','i','o','n',0};
2401 static const WCHAR highmemW[] =
2402 {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
2403 '\\','H','i','g','h','M','e','m','o','r','y','C','o','n','d','i','t','i','o','n',0};
2404 HANDLE ret;
2405 UNICODE_STRING nameW;
2406 OBJECT_ATTRIBUTES attr;
2407 NTSTATUS status;
2409 switch (type)
2411 case LowMemoryResourceNotification:
2412 RtlInitUnicodeString( &nameW, lowmemW );
2413 break;
2414 case HighMemoryResourceNotification:
2415 RtlInitUnicodeString( &nameW, highmemW );
2416 break;
2417 default:
2418 SetLastError( ERROR_INVALID_PARAMETER );
2419 return 0;
2422 attr.Length = sizeof(attr);
2423 attr.RootDirectory = 0;
2424 attr.ObjectName = &nameW;
2425 attr.Attributes = 0;
2426 attr.SecurityDescriptor = NULL;
2427 attr.SecurityQualityOfService = NULL;
2428 status = NtOpenEvent( &ret, EVENT_ALL_ACCESS, &attr );
2429 if (status != STATUS_SUCCESS)
2431 SetLastError( RtlNtStatusToDosError(status) );
2432 return 0;
2434 return ret;
2437 /***********************************************************************
2438 * QueryMemoryResourceNotification (KERNEL32.@)
2440 BOOL WINAPI QueryMemoryResourceNotification(HANDLE handle, PBOOL state)
2442 switch (WaitForSingleObject( handle, 0 ))
2444 case WAIT_OBJECT_0:
2445 *state = TRUE;
2446 return TRUE;
2447 case WAIT_TIMEOUT:
2448 *state = FALSE;
2449 return TRUE;
2451 SetLastError( ERROR_INVALID_PARAMETER );
2452 return FALSE;
2455 /***********************************************************************
2456 * InitOnceBeginInitialize (KERNEL32.@)
2458 BOOL WINAPI InitOnceBeginInitialize( INIT_ONCE *once, DWORD flags, BOOL *pending, void **context )
2460 NTSTATUS status = RtlRunOnceBeginInitialize( once, flags, context );
2461 if (status >= 0) *pending = (status == STATUS_PENDING);
2462 else SetLastError( RtlNtStatusToDosError(status) );
2463 return status >= 0;
2466 /***********************************************************************
2467 * InitOnceComplete (KERNEL32.@)
2469 BOOL WINAPI InitOnceComplete( INIT_ONCE *once, DWORD flags, void *context )
2471 NTSTATUS status = RtlRunOnceComplete( once, flags, context );
2472 if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
2473 return !status;
2476 /***********************************************************************
2477 * InitOnceExecuteOnce (KERNEL32.@)
2479 BOOL WINAPI InitOnceExecuteOnce( INIT_ONCE *once, PINIT_ONCE_FN func, void *param, void **context )
2481 return !RtlRunOnceExecuteOnce( once, (PRTL_RUN_ONCE_INIT_FN)func, param, context );
2484 #ifdef __i386__
2486 /***********************************************************************
2487 * InterlockedCompareExchange (KERNEL32.@)
2489 /* LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ); */
2490 __ASM_STDCALL_FUNC(InterlockedCompareExchange, 12,
2491 "movl 12(%esp),%eax\n\t"
2492 "movl 8(%esp),%ecx\n\t"
2493 "movl 4(%esp),%edx\n\t"
2494 "lock; cmpxchgl %ecx,(%edx)\n\t"
2495 "ret $12")
2497 /***********************************************************************
2498 * InterlockedExchange (KERNEL32.@)
2500 /* LONG WINAPI InterlockedExchange( PLONG dest, LONG val ); */
2501 __ASM_STDCALL_FUNC(InterlockedExchange, 8,
2502 "movl 8(%esp),%eax\n\t"
2503 "movl 4(%esp),%edx\n\t"
2504 "lock; xchgl %eax,(%edx)\n\t"
2505 "ret $8")
2507 /***********************************************************************
2508 * InterlockedExchangeAdd (KERNEL32.@)
2510 /* LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ); */
2511 __ASM_STDCALL_FUNC(InterlockedExchangeAdd, 8,
2512 "movl 8(%esp),%eax\n\t"
2513 "movl 4(%esp),%edx\n\t"
2514 "lock; xaddl %eax,(%edx)\n\t"
2515 "ret $8")
2517 /***********************************************************************
2518 * InterlockedIncrement (KERNEL32.@)
2520 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
2521 __ASM_STDCALL_FUNC(InterlockedIncrement, 4,
2522 "movl 4(%esp),%edx\n\t"
2523 "movl $1,%eax\n\t"
2524 "lock; xaddl %eax,(%edx)\n\t"
2525 "incl %eax\n\t"
2526 "ret $4")
2528 /***********************************************************************
2529 * InterlockedDecrement (KERNEL32.@)
2531 __ASM_STDCALL_FUNC(InterlockedDecrement, 4,
2532 "movl 4(%esp),%edx\n\t"
2533 "movl $-1,%eax\n\t"
2534 "lock; xaddl %eax,(%edx)\n\t"
2535 "decl %eax\n\t"
2536 "ret $4")
2538 #endif /* __i386__ */
2540 /***********************************************************************
2541 * SleepConditionVariableCS (KERNEL32.@)
2543 BOOL WINAPI SleepConditionVariableCS( CONDITION_VARIABLE *variable, CRITICAL_SECTION *crit, DWORD timeout )
2545 NTSTATUS status;
2546 LARGE_INTEGER time;
2548 status = RtlSleepConditionVariableCS( variable, crit, get_nt_timeout( &time, timeout ) );
2550 if (status != STATUS_SUCCESS)
2552 SetLastError( RtlNtStatusToDosError(status) );
2553 return FALSE;
2555 return TRUE;
2558 /***********************************************************************
2559 * SleepConditionVariableSRW (KERNEL32.@)
2561 BOOL WINAPI SleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, RTL_SRWLOCK *lock, DWORD timeout, ULONG flags )
2563 NTSTATUS status;
2564 LARGE_INTEGER time;
2566 status = RtlSleepConditionVariableSRW( variable, lock, get_nt_timeout( &time, timeout ), flags );
2568 if (status != STATUS_SUCCESS)
2570 SetLastError( RtlNtStatusToDosError(status) );
2571 return FALSE;
2573 return TRUE;