user32: Move *RegisterDeviceNotification*() to input.c.
[wine.git] / dlls / kernel32 / sync.c
blob4032315750b02e63cd5028ded9b6b3d82b981390
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 "wincon.h"
38 #include "winerror.h"
39 #include "winnls.h"
40 #include "winternl.h"
41 #include "winioctl.h"
42 #include "ddk/wdm.h"
44 #include "wine/asm.h"
45 #include "wine/unicode.h"
46 #include "kernel_private.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(sync);
52 static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000;
55 static void get_create_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
56 SECURITY_ATTRIBUTES *sa, const WCHAR *name )
58 attr->Length = sizeof(*attr);
59 attr->RootDirectory = 0;
60 attr->ObjectName = NULL;
61 attr->Attributes = OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
62 attr->SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
63 attr->SecurityQualityOfService = NULL;
64 if (name)
66 RtlInitUnicodeString( nameW, name );
67 attr->ObjectName = nameW;
68 BaseGetNamedObjectDirectory( &attr->RootDirectory );
72 static BOOL get_open_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
73 BOOL inherit, const WCHAR *name )
75 HANDLE dir;
77 if (!name)
79 SetLastError( ERROR_INVALID_PARAMETER );
80 return FALSE;
82 RtlInitUnicodeString( nameW, name );
83 BaseGetNamedObjectDirectory( &dir );
84 InitializeObjectAttributes( attr, nameW, inherit ? OBJ_INHERIT : 0, dir, NULL );
85 return TRUE;
88 static HANDLE normalize_handle_if_console(HANDLE handle)
90 if ((handle == (HANDLE)STD_INPUT_HANDLE) ||
91 (handle == (HANDLE)STD_OUTPUT_HANDLE) ||
92 (handle == (HANDLE)STD_ERROR_HANDLE))
93 handle = GetStdHandle( HandleToULong(handle) );
95 /* yes, even screen buffer console handles are waitable, and are
96 * handled as a handle to the console itself !!
98 if (is_console_handle(handle))
100 if (VerifyConsoleIoHandle(handle))
101 handle = GetConsoleInputWaitHandle();
103 return handle;
106 /******************************************************************************
107 * GetTickCount64 (KERNEL32.@)
109 ULONGLONG WINAPI DECLSPEC_HOTPATCH GetTickCount64(void)
111 ULONG high, low;
115 high = user_shared_data->u.TickCount.High1Time;
116 low = user_shared_data->u.TickCount.LowPart;
118 while (high != user_shared_data->u.TickCount.High2Time);
119 /* note: we ignore TickCountMultiplier */
120 return (ULONGLONG)high << 32 | low;
123 /***********************************************************************
124 * GetTickCount (KERNEL32.@)
126 DWORD WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
128 /* note: we ignore TickCountMultiplier */
129 return user_shared_data->u.TickCount.LowPart;
132 /***********************************************************************
133 * RegisterWaitForSingleObject (KERNEL32.@)
135 BOOL WINAPI RegisterWaitForSingleObject( HANDLE *wait, HANDLE object, WAITORTIMERCALLBACK callback,
136 void *context, ULONG timeout, ULONG flags )
138 TRACE( "%p %p %p %p %d %d\n", wait, object, callback, context, timeout, flags );
140 object = normalize_handle_if_console( object );
141 return set_ntstatus( RtlRegisterWait( wait, object, callback, context, timeout, flags ));
144 /***********************************************************************
145 * UnregisterWait (KERNEL32.@)
147 BOOL WINAPI UnregisterWait( HANDLE handle )
149 return set_ntstatus( RtlDeregisterWait( handle ));
152 /***********************************************************************
153 * MakeCriticalSectionGlobal (KERNEL32.@)
155 void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
157 /* let's assume that only one thread at a time will try to do this */
158 HANDLE sem = crit->LockSemaphore;
159 if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 );
160 crit->LockSemaphore = ConvertToGlobalHandle( sem );
161 if (crit->DebugInfo != (void *)(ULONG_PTR)-1)
162 RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
163 crit->DebugInfo = NULL;
167 /***********************************************************************
168 * ReinitializeCriticalSection (KERNEL32.@)
170 * Initialise an already used critical section.
172 * PARAMS
173 * crit [O] Critical section to initialise.
175 * RETURNS
176 * Nothing.
178 void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
180 if ( !crit->LockSemaphore )
181 RtlInitializeCriticalSection( crit );
185 /***********************************************************************
186 * UninitializeCriticalSection (KERNEL32.@)
188 * UnInitialise a critical section after use.
190 * PARAMS
191 * crit [O] Critical section to uninitialise (destroy).
193 * RETURNS
194 * Nothing.
196 void WINAPI UninitializeCriticalSection( CRITICAL_SECTION *crit )
198 RtlDeleteCriticalSection( crit );
202 /***********************************************************************
203 * OpenMutexA (KERNEL32.@)
205 HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
207 WCHAR buffer[MAX_PATH];
209 if (!name) return OpenMutexW( access, inherit, NULL );
211 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
213 SetLastError( ERROR_FILENAME_EXCED_RANGE );
214 return 0;
216 return OpenMutexW( access, inherit, buffer );
223 * Semaphores
227 /***********************************************************************
228 * CreateSemaphoreA (KERNEL32.@)
230 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
232 return CreateSemaphoreExA( sa, initial, max, name, 0, SEMAPHORE_ALL_ACCESS );
236 /***********************************************************************
237 * CreateSemaphoreExA (KERNEL32.@)
239 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreExA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max,
240 LPCSTR name, DWORD flags, DWORD access )
242 WCHAR buffer[MAX_PATH];
244 if (!name) return CreateSemaphoreExW( sa, initial, max, NULL, flags, access );
246 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
248 SetLastError( ERROR_FILENAME_EXCED_RANGE );
249 return 0;
251 return CreateSemaphoreExW( sa, initial, max, buffer, flags, access );
255 /***********************************************************************
256 * OpenSemaphoreA (KERNEL32.@)
258 HANDLE WINAPI DECLSPEC_HOTPATCH OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
260 WCHAR buffer[MAX_PATH];
262 if (!name) return OpenSemaphoreW( access, inherit, NULL );
264 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
266 SetLastError( ERROR_FILENAME_EXCED_RANGE );
267 return 0;
269 return OpenSemaphoreW( access, inherit, buffer );
274 * Jobs
277 /******************************************************************************
278 * CreateJobObjectW (KERNEL32.@)
280 HANDLE WINAPI CreateJobObjectW( LPSECURITY_ATTRIBUTES sa, LPCWSTR name )
282 HANDLE ret = 0;
283 UNICODE_STRING nameW;
284 OBJECT_ATTRIBUTES attr;
285 NTSTATUS status;
287 get_create_object_attributes( &attr, &nameW, sa, name );
289 status = NtCreateJobObject( &ret, JOB_OBJECT_ALL_ACCESS, &attr );
290 if (status == STATUS_OBJECT_NAME_EXISTS)
291 SetLastError( ERROR_ALREADY_EXISTS );
292 else
293 SetLastError( RtlNtStatusToDosError(status) );
294 return ret;
297 /******************************************************************************
298 * CreateJobObjectA (KERNEL32.@)
300 HANDLE WINAPI CreateJobObjectA( LPSECURITY_ATTRIBUTES attr, LPCSTR name )
302 WCHAR buffer[MAX_PATH];
304 if (!name) return CreateJobObjectW( attr, NULL );
306 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
308 SetLastError( ERROR_FILENAME_EXCED_RANGE );
309 return 0;
311 return CreateJobObjectW( attr, buffer );
314 /******************************************************************************
315 * OpenJobObjectW (KERNEL32.@)
317 HANDLE WINAPI OpenJobObjectW( DWORD access, BOOL inherit, LPCWSTR name )
319 HANDLE ret;
320 UNICODE_STRING nameW;
321 OBJECT_ATTRIBUTES attr;
323 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
325 if (!set_ntstatus( NtOpenJobObject( &ret, access, &attr ))) return 0;
326 return ret;
329 /******************************************************************************
330 * OpenJobObjectA (KERNEL32.@)
332 HANDLE WINAPI OpenJobObjectA( DWORD access, BOOL inherit, LPCSTR name )
334 WCHAR buffer[MAX_PATH];
336 if (!name) return OpenJobObjectW( access, inherit, NULL );
338 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
340 SetLastError( ERROR_FILENAME_EXCED_RANGE );
341 return 0;
343 return OpenJobObjectW( access, inherit, buffer );
346 /******************************************************************************
347 * TerminateJobObject (KERNEL32.@)
349 BOOL WINAPI TerminateJobObject( HANDLE job, UINT exit_code )
351 return set_ntstatus( NtTerminateJobObject( job, exit_code ));
354 /******************************************************************************
355 * QueryInformationJobObject (KERNEL32.@)
357 BOOL WINAPI QueryInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info,
358 DWORD len, DWORD *ret_len )
360 return set_ntstatus( NtQueryInformationJobObject( job, class, info, len, ret_len ));
363 /******************************************************************************
364 * SetInformationJobObject (KERNEL32.@)
366 BOOL WINAPI SetInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, DWORD len )
368 return set_ntstatus( NtSetInformationJobObject( job, class, info, len ));
371 /******************************************************************************
372 * AssignProcessToJobObject (KERNEL32.@)
374 BOOL WINAPI AssignProcessToJobObject( HANDLE job, HANDLE process )
376 return set_ntstatus( NtAssignProcessToJobObject( job, process ));
381 * Timers
385 /***********************************************************************
386 * CreateWaitableTimerA (KERNEL32.@)
388 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
390 return CreateWaitableTimerExA( sa, name, manual ? CREATE_WAITABLE_TIMER_MANUAL_RESET : 0,
391 TIMER_ALL_ACCESS );
395 /***********************************************************************
396 * CreateWaitableTimerExA (KERNEL32.@)
398 HANDLE WINAPI CreateWaitableTimerExA( SECURITY_ATTRIBUTES *sa, LPCSTR name, DWORD flags, DWORD access )
400 WCHAR buffer[MAX_PATH];
402 if (!name) return CreateWaitableTimerExW( sa, NULL, flags, access );
404 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
406 SetLastError( ERROR_FILENAME_EXCED_RANGE );
407 return 0;
409 return CreateWaitableTimerExW( sa, buffer, flags, access );
413 /***********************************************************************
414 * OpenWaitableTimerA (KERNEL32.@)
416 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
418 WCHAR buffer[MAX_PATH];
420 if (!name) return OpenWaitableTimerW( access, inherit, NULL );
422 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
424 SetLastError( ERROR_FILENAME_EXCED_RANGE );
425 return 0;
427 return OpenWaitableTimerW( access, inherit, buffer );
431 /***********************************************************************
432 * DeleteTimerQueue (KERNEL32.@)
434 BOOL WINAPI DeleteTimerQueue(HANDLE TimerQueue)
436 return DeleteTimerQueueEx(TimerQueue, NULL);
439 /***********************************************************************
440 * CancelTimerQueueTimer (KERNEL32.@)
442 BOOL WINAPI CancelTimerQueueTimer(HANDLE queue, HANDLE timer)
444 return DeleteTimerQueueTimer( queue, timer, NULL );
450 * Mappings
454 /***********************************************************************
455 * CreateFileMappingA (KERNEL32.@)
457 HANDLE WINAPI CreateFileMappingA( HANDLE file, SECURITY_ATTRIBUTES *sa, DWORD protect,
458 DWORD size_high, DWORD size_low, LPCSTR name )
460 WCHAR buffer[MAX_PATH];
462 if (!name) return CreateFileMappingW( file, sa, protect, size_high, size_low, NULL );
464 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
466 SetLastError( ERROR_FILENAME_EXCED_RANGE );
467 return 0;
469 return CreateFileMappingW( file, sa, protect, size_high, size_low, buffer );
473 /***********************************************************************
474 * OpenFileMappingA (KERNEL32.@)
476 HANDLE WINAPI OpenFileMappingA( DWORD access, BOOL inherit, LPCSTR name )
478 WCHAR buffer[MAX_PATH];
480 if (!name) return OpenFileMappingW( access, inherit, NULL );
482 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
484 SetLastError( ERROR_FILENAME_EXCED_RANGE );
485 return 0;
487 return OpenFileMappingW( access, inherit, buffer );
492 * Pipes
496 /***********************************************************************
497 * CreateNamedPipeA (KERNEL32.@)
499 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
500 DWORD dwPipeMode, DWORD nMaxInstances,
501 DWORD nOutBufferSize, DWORD nInBufferSize,
502 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
504 WCHAR buffer[MAX_PATH];
506 if (!name) return CreateNamedPipeW( NULL, dwOpenMode, dwPipeMode, nMaxInstances,
507 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
509 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
511 SetLastError( ERROR_FILENAME_EXCED_RANGE );
512 return INVALID_HANDLE_VALUE;
514 return CreateNamedPipeW( buffer, dwOpenMode, dwPipeMode, nMaxInstances,
515 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
519 /***********************************************************************
520 * WaitNamedPipeA (KERNEL32.@)
522 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
524 WCHAR buffer[MAX_PATH];
526 if (!name) return WaitNamedPipeW( NULL, nTimeOut );
528 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
530 SetLastError( ERROR_FILENAME_EXCED_RANGE );
531 return FALSE;
533 return WaitNamedPipeW( buffer, nTimeOut );
537 /***********************************************************************
538 * GetNamedPipeClientProcessId (KERNEL32.@)
540 BOOL WINAPI GetNamedPipeClientProcessId( HANDLE pipe, ULONG *id )
542 IO_STATUS_BLOCK iosb;
544 return set_ntstatus( NtFsControlFile( pipe, NULL, NULL, NULL, &iosb,
545 FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE, (void *)"ClientProcessId",
546 sizeof("ClientProcessId"), id, sizeof(*id) ));
549 /***********************************************************************
550 * GetNamedPipeServerProcessId (KERNEL32.@)
552 BOOL WINAPI GetNamedPipeServerProcessId( HANDLE pipe, ULONG *id )
554 IO_STATUS_BLOCK iosb;
556 return set_ntstatus( NtFsControlFile( pipe, NULL, NULL, NULL, &iosb,
557 FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE, (void *)"ServerProcessId",
558 sizeof("ServerProcessId"), id, sizeof(*id) ));
561 /***********************************************************************
562 * GetNamedPipeClientSessionId (KERNEL32.@)
564 BOOL WINAPI GetNamedPipeClientSessionId( HANDLE pipe, ULONG *id )
566 FIXME( "%p, %p\n", pipe, id );
568 if (!id) return FALSE;
569 *id = NtCurrentTeb()->Peb->SessionId;
570 return TRUE;
573 /***********************************************************************
574 * GetNamedPipeServerSessionId (KERNEL32.@)
576 BOOL WINAPI GetNamedPipeServerSessionId( HANDLE pipe, ULONG *id )
578 FIXME( "%p, %p\n", pipe, id );
580 if (!id) return FALSE;
581 *id = NtCurrentTeb()->Peb->SessionId;
582 return TRUE;
585 /***********************************************************************
586 * GetNamedPipeHandleStateA (KERNEL32.@)
588 BOOL WINAPI GetNamedPipeHandleStateA(
589 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
590 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
591 LPSTR lpUsername, DWORD nUsernameMaxSize)
593 WCHAR *username = NULL;
594 BOOL ret;
596 WARN("%p %p %p %p %p %p %d: semi-stub\n", hNamedPipe, lpState, lpCurInstances,
597 lpMaxCollectionCount, lpCollectDataTimeout, lpUsername, nUsernameMaxSize);
599 if (lpUsername && nUsernameMaxSize &&
600 !(username = HeapAlloc(GetProcessHeap(), 0, nUsernameMaxSize * sizeof(WCHAR)))) return FALSE;
602 ret = GetNamedPipeHandleStateW(hNamedPipe, lpState, lpCurInstances, lpMaxCollectionCount,
603 lpCollectDataTimeout, username, nUsernameMaxSize);
604 if (ret && username)
605 WideCharToMultiByte(CP_ACP, 0, username, -1, lpUsername, nUsernameMaxSize, NULL, NULL);
607 HeapFree(GetProcessHeap(), 0, username);
608 return ret;
611 /***********************************************************************
612 * CallNamedPipeA (KERNEL32.@)
614 BOOL WINAPI CallNamedPipeA(
615 LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD dwInputSize,
616 LPVOID lpOutput, DWORD dwOutputSize,
617 LPDWORD lpBytesRead, DWORD nTimeout)
619 DWORD len;
620 LPWSTR str = NULL;
621 BOOL ret;
623 TRACE("%s %p %d %p %d %p %d\n",
624 debugstr_a(lpNamedPipeName), lpInput, dwInputSize,
625 lpOutput, dwOutputSize, lpBytesRead, nTimeout);
627 if( lpNamedPipeName )
629 len = MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, NULL, 0 );
630 str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
631 MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, str, len );
633 ret = CallNamedPipeW( str, lpInput, dwInputSize, lpOutput,
634 dwOutputSize, lpBytesRead, nTimeout );
635 if( lpNamedPipeName )
636 HeapFree( GetProcessHeap(), 0, str );
638 return ret;
641 /******************************************************************************
642 * CreateMailslotA [KERNEL32.@]
644 * See CreateMailslotW.
646 HANDLE WINAPI CreateMailslotA( LPCSTR lpName, DWORD nMaxMessageSize,
647 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
649 DWORD len;
650 HANDLE handle;
651 LPWSTR name = NULL;
653 TRACE("%s %d %d %p\n", debugstr_a(lpName),
654 nMaxMessageSize, lReadTimeout, sa);
656 if( lpName )
658 len = MultiByteToWideChar( CP_ACP, 0, lpName, -1, NULL, 0 );
659 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
660 MultiByteToWideChar( CP_ACP, 0, lpName, -1, name, len );
663 handle = CreateMailslotW( name, nMaxMessageSize, lReadTimeout, sa );
665 HeapFree( GetProcessHeap(), 0, name );
667 return handle;
671 /******************************************************************************
672 * CreateMailslotW [KERNEL32.@]
674 * Create a mailslot with specified name.
676 * PARAMS
677 * lpName [I] Pointer to string for mailslot name
678 * nMaxMessageSize [I] Maximum message size
679 * lReadTimeout [I] Milliseconds before read time-out
680 * sa [I] Pointer to security structure
682 * RETURNS
683 * Success: Handle to mailslot
684 * Failure: INVALID_HANDLE_VALUE
686 HANDLE WINAPI CreateMailslotW( LPCWSTR lpName, DWORD nMaxMessageSize,
687 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
689 HANDLE handle = INVALID_HANDLE_VALUE;
690 OBJECT_ATTRIBUTES attr;
691 UNICODE_STRING nameW;
692 LARGE_INTEGER timeout;
693 IO_STATUS_BLOCK iosb;
695 TRACE("%s %d %d %p\n", debugstr_w(lpName),
696 nMaxMessageSize, lReadTimeout, sa);
698 if (!RtlDosPathNameToNtPathName_U( lpName, &nameW, NULL, NULL ))
700 SetLastError( ERROR_PATH_NOT_FOUND );
701 return INVALID_HANDLE_VALUE;
704 if (nameW.Length >= MAX_PATH * sizeof(WCHAR) )
706 SetLastError( ERROR_FILENAME_EXCED_RANGE );
707 RtlFreeUnicodeString( &nameW );
708 return INVALID_HANDLE_VALUE;
711 attr.Length = sizeof(attr);
712 attr.RootDirectory = 0;
713 attr.Attributes = OBJ_CASE_INSENSITIVE;
714 attr.ObjectName = &nameW;
715 attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
716 attr.SecurityQualityOfService = NULL;
718 if (lReadTimeout != MAILSLOT_WAIT_FOREVER)
719 timeout.QuadPart = (ULONGLONG) lReadTimeout * -10000;
720 else
721 timeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
723 if (!set_ntstatus( NtCreateMailslotFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr,
724 &iosb, 0, 0, nMaxMessageSize, &timeout )))
725 handle = INVALID_HANDLE_VALUE;
727 RtlFreeUnicodeString( &nameW );
728 return handle;
732 /******************************************************************************
733 * GetMailslotInfo [KERNEL32.@]
735 * Retrieve information about a mailslot.
737 * PARAMS
738 * hMailslot [I] Mailslot handle
739 * lpMaxMessageSize [O] Address of maximum message size
740 * lpNextSize [O] Address of size of next message
741 * lpMessageCount [O] Address of number of messages
742 * lpReadTimeout [O] Address of read time-out
744 * RETURNS
745 * Success: TRUE
746 * Failure: FALSE
748 BOOL WINAPI GetMailslotInfo( HANDLE hMailslot, LPDWORD lpMaxMessageSize,
749 LPDWORD lpNextSize, LPDWORD lpMessageCount,
750 LPDWORD lpReadTimeout )
752 FILE_MAILSLOT_QUERY_INFORMATION info;
753 IO_STATUS_BLOCK iosb;
755 TRACE("%p %p %p %p %p\n",hMailslot, lpMaxMessageSize,
756 lpNextSize, lpMessageCount, lpReadTimeout);
758 if (!set_ntstatus( NtQueryInformationFile( hMailslot, &iosb, &info, sizeof info,
759 FileMailslotQueryInformation )))
760 return FALSE;
762 if( lpMaxMessageSize )
763 *lpMaxMessageSize = info.MaximumMessageSize;
764 if( lpNextSize )
765 *lpNextSize = info.NextMessageSize;
766 if( lpMessageCount )
767 *lpMessageCount = info.MessagesAvailable;
768 if( lpReadTimeout )
770 if (info.ReadTimeout.QuadPart == (((LONGLONG)0x7fffffff << 32) | 0xffffffff))
771 *lpReadTimeout = MAILSLOT_WAIT_FOREVER;
772 else
773 *lpReadTimeout = info.ReadTimeout.QuadPart / -10000;
775 return TRUE;
779 /******************************************************************************
780 * SetMailslotInfo [KERNEL32.@]
782 * Set the read timeout of a mailslot.
784 * PARAMS
785 * hMailslot [I] Mailslot handle
786 * dwReadTimeout [I] Timeout in milliseconds.
788 * RETURNS
789 * Success: TRUE
790 * Failure: FALSE
792 BOOL WINAPI SetMailslotInfo( HANDLE hMailslot, DWORD dwReadTimeout)
794 FILE_MAILSLOT_SET_INFORMATION info;
795 IO_STATUS_BLOCK iosb;
797 TRACE("%p %d\n", hMailslot, dwReadTimeout);
799 if (dwReadTimeout != MAILSLOT_WAIT_FOREVER)
800 info.ReadTimeout.QuadPart = (ULONGLONG)dwReadTimeout * -10000;
801 else
802 info.ReadTimeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
803 return set_ntstatus( NtSetInformationFile( hMailslot, &iosb, &info, sizeof info,
804 FileMailslotSetInformation ));
808 /******************************************************************************
809 * BindIoCompletionCallback (KERNEL32.@)
811 BOOL WINAPI BindIoCompletionCallback( HANDLE handle, LPOVERLAPPED_COMPLETION_ROUTINE func, ULONG flags )
813 return set_ntstatus( RtlSetIoCompletionCallback( handle, (PRTL_OVERLAPPED_COMPLETION_ROUTINE)func, flags ));
817 #ifdef __i386__
819 /***********************************************************************
820 * InterlockedCompareExchange (KERNEL32.@)
822 /* LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ); */
823 __ASM_STDCALL_FUNC(InterlockedCompareExchange, 12,
824 "movl 12(%esp),%eax\n\t"
825 "movl 8(%esp),%ecx\n\t"
826 "movl 4(%esp),%edx\n\t"
827 "lock; cmpxchgl %ecx,(%edx)\n\t"
828 "ret $12")
830 /***********************************************************************
831 * InterlockedExchange (KERNEL32.@)
833 /* LONG WINAPI InterlockedExchange( PLONG dest, LONG val ); */
834 __ASM_STDCALL_FUNC(InterlockedExchange, 8,
835 "movl 8(%esp),%eax\n\t"
836 "movl 4(%esp),%edx\n\t"
837 "lock; xchgl %eax,(%edx)\n\t"
838 "ret $8")
840 /***********************************************************************
841 * InterlockedExchangeAdd (KERNEL32.@)
843 /* LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ); */
844 __ASM_STDCALL_FUNC(InterlockedExchangeAdd, 8,
845 "movl 8(%esp),%eax\n\t"
846 "movl 4(%esp),%edx\n\t"
847 "lock; xaddl %eax,(%edx)\n\t"
848 "ret $8")
850 /***********************************************************************
851 * InterlockedIncrement (KERNEL32.@)
853 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
854 __ASM_STDCALL_FUNC(InterlockedIncrement, 4,
855 "movl 4(%esp),%edx\n\t"
856 "movl $1,%eax\n\t"
857 "lock; xaddl %eax,(%edx)\n\t"
858 "incl %eax\n\t"
859 "ret $4")
861 /***********************************************************************
862 * InterlockedDecrement (KERNEL32.@)
864 __ASM_STDCALL_FUNC(InterlockedDecrement, 4,
865 "movl 4(%esp),%edx\n\t"
866 "movl $-1,%eax\n\t"
867 "lock; xaddl %eax,(%edx)\n\t"
868 "decl %eax\n\t"
869 "ret $4")
871 #endif /* __i386__ */