ia2comproxy: Introduce new proxy stub DLL for IAccessible2.
[wine.git] / dlls / kernel32 / sync.c
blob219800a46e5cb16f86d382e71f090bbdd004b8a6
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 <string.h>
22 #include <errno.h>
23 #include <stdarg.h>
24 #include <stdio.h>
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #define NONAMELESSUNION
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wincon.h"
32 #include "winerror.h"
33 #include "winnls.h"
34 #include "winternl.h"
35 #include "winioctl.h"
36 #include "ddk/wdm.h"
38 #include "wine/asm.h"
39 #include "kernel_private.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(sync);
45 static const struct _KUSER_SHARED_DATA *user_shared_data = (struct _KUSER_SHARED_DATA *)0x7ffe0000;
48 static void get_create_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
49 SECURITY_ATTRIBUTES *sa, const WCHAR *name )
51 attr->Length = sizeof(*attr);
52 attr->RootDirectory = 0;
53 attr->ObjectName = NULL;
54 attr->Attributes = OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
55 attr->SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
56 attr->SecurityQualityOfService = NULL;
57 if (name)
59 RtlInitUnicodeString( nameW, name );
60 attr->ObjectName = nameW;
61 BaseGetNamedObjectDirectory( &attr->RootDirectory );
65 static BOOL get_open_object_attributes( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nameW,
66 BOOL inherit, const WCHAR *name )
68 HANDLE dir;
70 if (!name)
72 SetLastError( ERROR_INVALID_PARAMETER );
73 return FALSE;
75 RtlInitUnicodeString( nameW, name );
76 BaseGetNamedObjectDirectory( &dir );
77 InitializeObjectAttributes( attr, nameW, inherit ? OBJ_INHERIT : 0, dir, NULL );
78 return TRUE;
81 /******************************************************************************
82 * GetTickCount64 (KERNEL32.@)
84 ULONGLONG WINAPI DECLSPEC_HOTPATCH GetTickCount64(void)
86 ULONG high, low;
90 high = user_shared_data->u.TickCount.High1Time;
91 low = user_shared_data->u.TickCount.LowPart;
93 while (high != user_shared_data->u.TickCount.High2Time);
94 /* note: we ignore TickCountMultiplier */
95 return (ULONGLONG)high << 32 | low;
98 /***********************************************************************
99 * GetTickCount (KERNEL32.@)
101 DWORD WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
103 /* note: we ignore TickCountMultiplier */
104 return user_shared_data->u.TickCount.LowPart;
107 /***********************************************************************
108 * RegisterWaitForSingleObject (KERNEL32.@)
110 BOOL WINAPI RegisterWaitForSingleObject( HANDLE *wait, HANDLE object, WAITORTIMERCALLBACK callback,
111 void *context, ULONG timeout, ULONG flags )
113 if (!set_ntstatus( RtlRegisterWait( wait, object, callback, context, timeout, flags ))) return FALSE;
114 return TRUE;
117 /***********************************************************************
118 * UnregisterWait (KERNEL32.@)
120 BOOL WINAPI UnregisterWait( HANDLE handle )
122 return set_ntstatus( RtlDeregisterWait( handle ));
125 /***********************************************************************
126 * MakeCriticalSectionGlobal (KERNEL32.@)
128 void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
130 /* let's assume that only one thread at a time will try to do this */
131 HANDLE sem = crit->LockSemaphore;
132 if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 );
133 crit->LockSemaphore = ConvertToGlobalHandle( sem );
134 if (crit->DebugInfo != (void *)(ULONG_PTR)-1)
135 RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
136 crit->DebugInfo = NULL;
140 /***********************************************************************
141 * ReinitializeCriticalSection (KERNEL32.@)
143 * Initialise an already used critical section.
145 * PARAMS
146 * crit [O] Critical section to initialise.
148 * RETURNS
149 * Nothing.
151 void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
153 if ( !crit->LockSemaphore )
154 RtlInitializeCriticalSection( crit );
158 /***********************************************************************
159 * UninitializeCriticalSection (KERNEL32.@)
161 * UnInitialise a critical section after use.
163 * PARAMS
164 * crit [O] Critical section to uninitialise (destroy).
166 * RETURNS
167 * Nothing.
169 void WINAPI UninitializeCriticalSection( CRITICAL_SECTION *crit )
171 RtlDeleteCriticalSection( crit );
175 /***********************************************************************
176 * OpenMutexA (KERNEL32.@)
178 HANDLE WINAPI DECLSPEC_HOTPATCH OpenMutexA( DWORD access, BOOL inherit, LPCSTR name )
180 WCHAR buffer[MAX_PATH];
182 if (!name) return OpenMutexW( access, inherit, NULL );
184 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
186 SetLastError( ERROR_FILENAME_EXCED_RANGE );
187 return 0;
189 return OpenMutexW( access, inherit, buffer );
196 * Semaphores
200 /***********************************************************************
201 * CreateSemaphoreA (KERNEL32.@)
203 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
205 return CreateSemaphoreExA( sa, initial, max, name, 0, SEMAPHORE_ALL_ACCESS );
209 /***********************************************************************
210 * CreateSemaphoreExA (KERNEL32.@)
212 HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreExA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max,
213 LPCSTR name, DWORD flags, DWORD access )
215 WCHAR buffer[MAX_PATH];
217 if (!name) return CreateSemaphoreExW( sa, initial, max, NULL, flags, access );
219 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
221 SetLastError( ERROR_FILENAME_EXCED_RANGE );
222 return 0;
224 return CreateSemaphoreExW( sa, initial, max, buffer, flags, access );
228 /***********************************************************************
229 * OpenSemaphoreA (KERNEL32.@)
231 HANDLE WINAPI DECLSPEC_HOTPATCH OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
233 WCHAR buffer[MAX_PATH];
235 if (!name) return OpenSemaphoreW( access, inherit, NULL );
237 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
239 SetLastError( ERROR_FILENAME_EXCED_RANGE );
240 return 0;
242 return OpenSemaphoreW( access, inherit, buffer );
247 * Jobs
250 /******************************************************************************
251 * CreateJobObjectW (KERNEL32.@)
253 HANDLE WINAPI CreateJobObjectW( LPSECURITY_ATTRIBUTES sa, LPCWSTR name )
255 HANDLE ret = 0;
256 UNICODE_STRING nameW;
257 OBJECT_ATTRIBUTES attr;
258 NTSTATUS status;
260 get_create_object_attributes( &attr, &nameW, sa, name );
262 status = NtCreateJobObject( &ret, JOB_OBJECT_ALL_ACCESS, &attr );
263 if (status == STATUS_OBJECT_NAME_EXISTS)
264 SetLastError( ERROR_ALREADY_EXISTS );
265 else
266 SetLastError( RtlNtStatusToDosError(status) );
267 return ret;
270 /******************************************************************************
271 * CreateJobObjectA (KERNEL32.@)
273 HANDLE WINAPI CreateJobObjectA( LPSECURITY_ATTRIBUTES attr, LPCSTR name )
275 WCHAR buffer[MAX_PATH];
277 if (!name) return CreateJobObjectW( attr, NULL );
279 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
281 SetLastError( ERROR_FILENAME_EXCED_RANGE );
282 return 0;
284 return CreateJobObjectW( attr, buffer );
287 /******************************************************************************
288 * OpenJobObjectW (KERNEL32.@)
290 HANDLE WINAPI OpenJobObjectW( DWORD access, BOOL inherit, LPCWSTR name )
292 HANDLE ret;
293 UNICODE_STRING nameW;
294 OBJECT_ATTRIBUTES attr;
296 if (!get_open_object_attributes( &attr, &nameW, inherit, name )) return 0;
298 if (!set_ntstatus( NtOpenJobObject( &ret, access, &attr ))) return 0;
299 return ret;
302 /******************************************************************************
303 * OpenJobObjectA (KERNEL32.@)
305 HANDLE WINAPI OpenJobObjectA( DWORD access, BOOL inherit, LPCSTR name )
307 WCHAR buffer[MAX_PATH];
309 if (!name) return OpenJobObjectW( access, inherit, NULL );
311 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
313 SetLastError( ERROR_FILENAME_EXCED_RANGE );
314 return 0;
316 return OpenJobObjectW( access, inherit, buffer );
319 /******************************************************************************
320 * TerminateJobObject (KERNEL32.@)
322 BOOL WINAPI TerminateJobObject( HANDLE job, UINT exit_code )
324 return set_ntstatus( NtTerminateJobObject( job, exit_code ));
327 /******************************************************************************
328 * QueryInformationJobObject (KERNEL32.@)
330 BOOL WINAPI QueryInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info,
331 DWORD len, DWORD *ret_len )
333 return set_ntstatus( NtQueryInformationJobObject( job, class, info, len, ret_len ));
336 /******************************************************************************
337 * SetInformationJobObject (KERNEL32.@)
339 BOOL WINAPI SetInformationJobObject( HANDLE job, JOBOBJECTINFOCLASS class, LPVOID info, DWORD len )
341 return set_ntstatus( NtSetInformationJobObject( job, class, info, len ));
344 /******************************************************************************
345 * AssignProcessToJobObject (KERNEL32.@)
347 BOOL WINAPI AssignProcessToJobObject( HANDLE job, HANDLE process )
349 return set_ntstatus( NtAssignProcessToJobObject( job, process ));
354 * Timers
358 /***********************************************************************
359 * CreateWaitableTimerA (KERNEL32.@)
361 HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
363 return CreateWaitableTimerExA( sa, name, manual ? CREATE_WAITABLE_TIMER_MANUAL_RESET : 0,
364 TIMER_ALL_ACCESS );
368 /***********************************************************************
369 * CreateWaitableTimerExA (KERNEL32.@)
371 HANDLE WINAPI CreateWaitableTimerExA( SECURITY_ATTRIBUTES *sa, LPCSTR name, DWORD flags, DWORD access )
373 WCHAR buffer[MAX_PATH];
375 if (!name) return CreateWaitableTimerExW( sa, NULL, flags, access );
377 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
379 SetLastError( ERROR_FILENAME_EXCED_RANGE );
380 return 0;
382 return CreateWaitableTimerExW( sa, buffer, flags, access );
386 /***********************************************************************
387 * OpenWaitableTimerA (KERNEL32.@)
389 HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
391 WCHAR buffer[MAX_PATH];
393 if (!name) return OpenWaitableTimerW( access, inherit, NULL );
395 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
397 SetLastError( ERROR_FILENAME_EXCED_RANGE );
398 return 0;
400 return OpenWaitableTimerW( access, inherit, buffer );
404 /***********************************************************************
405 * DeleteTimerQueue (KERNEL32.@)
407 BOOL WINAPI DeleteTimerQueue(HANDLE TimerQueue)
409 return DeleteTimerQueueEx(TimerQueue, NULL);
412 /***********************************************************************
413 * CancelTimerQueueTimer (KERNEL32.@)
415 BOOL WINAPI CancelTimerQueueTimer(HANDLE queue, HANDLE timer)
417 return DeleteTimerQueueTimer( queue, timer, NULL );
423 * Mappings
427 /***********************************************************************
428 * CreateFileMappingA (KERNEL32.@)
430 HANDLE WINAPI CreateFileMappingA( HANDLE file, SECURITY_ATTRIBUTES *sa, DWORD protect,
431 DWORD size_high, DWORD size_low, LPCSTR name )
433 WCHAR buffer[MAX_PATH];
435 if (!name) return CreateFileMappingW( file, sa, protect, size_high, size_low, NULL );
437 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
439 SetLastError( ERROR_FILENAME_EXCED_RANGE );
440 return 0;
442 return CreateFileMappingW( file, sa, protect, size_high, size_low, buffer );
446 /***********************************************************************
447 * OpenFileMappingA (KERNEL32.@)
449 HANDLE WINAPI OpenFileMappingA( DWORD access, BOOL inherit, LPCSTR name )
451 WCHAR buffer[MAX_PATH];
453 if (!name) return OpenFileMappingW( access, inherit, NULL );
455 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
457 SetLastError( ERROR_FILENAME_EXCED_RANGE );
458 return 0;
460 return OpenFileMappingW( access, inherit, buffer );
465 * Pipes
469 /***********************************************************************
470 * CreateNamedPipeA (KERNEL32.@)
472 HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode,
473 DWORD dwPipeMode, DWORD nMaxInstances,
474 DWORD nOutBufferSize, DWORD nInBufferSize,
475 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
477 WCHAR buffer[MAX_PATH];
479 if (!name) return CreateNamedPipeW( NULL, dwOpenMode, dwPipeMode, nMaxInstances,
480 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
482 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
484 SetLastError( ERROR_FILENAME_EXCED_RANGE );
485 return INVALID_HANDLE_VALUE;
487 return CreateNamedPipeW( buffer, dwOpenMode, dwPipeMode, nMaxInstances,
488 nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
492 /***********************************************************************
493 * WaitNamedPipeA (KERNEL32.@)
495 BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
497 WCHAR buffer[MAX_PATH];
499 if (!name) return WaitNamedPipeW( NULL, nTimeOut );
501 if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
503 SetLastError( ERROR_FILENAME_EXCED_RANGE );
504 return FALSE;
506 return WaitNamedPipeW( buffer, nTimeOut );
510 /***********************************************************************
511 * GetNamedPipeClientProcessId (KERNEL32.@)
513 BOOL WINAPI GetNamedPipeClientProcessId( HANDLE pipe, ULONG *id )
515 IO_STATUS_BLOCK iosb;
517 return set_ntstatus( NtFsControlFile( pipe, NULL, NULL, NULL, &iosb,
518 FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE, (void *)"ClientProcessId",
519 sizeof("ClientProcessId"), id, sizeof(*id) ));
522 /***********************************************************************
523 * GetNamedPipeServerProcessId (KERNEL32.@)
525 BOOL WINAPI GetNamedPipeServerProcessId( HANDLE pipe, ULONG *id )
527 IO_STATUS_BLOCK iosb;
529 return set_ntstatus( NtFsControlFile( pipe, NULL, NULL, NULL, &iosb,
530 FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE, (void *)"ServerProcessId",
531 sizeof("ServerProcessId"), id, sizeof(*id) ));
534 /***********************************************************************
535 * GetNamedPipeClientSessionId (KERNEL32.@)
537 BOOL WINAPI GetNamedPipeClientSessionId( HANDLE pipe, ULONG *id )
539 FIXME( "%p, %p\n", pipe, id );
541 if (!id) return FALSE;
542 *id = NtCurrentTeb()->Peb->SessionId;
543 return TRUE;
546 /***********************************************************************
547 * GetNamedPipeServerSessionId (KERNEL32.@)
549 BOOL WINAPI GetNamedPipeServerSessionId( HANDLE pipe, ULONG *id )
551 FIXME( "%p, %p\n", pipe, id );
553 if (!id) return FALSE;
554 *id = NtCurrentTeb()->Peb->SessionId;
555 return TRUE;
558 /***********************************************************************
559 * GetNamedPipeHandleStateA (KERNEL32.@)
561 BOOL WINAPI GetNamedPipeHandleStateA(
562 HANDLE hNamedPipe, LPDWORD lpState, LPDWORD lpCurInstances,
563 LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout,
564 LPSTR lpUsername, DWORD nUsernameMaxSize)
566 WCHAR *username = NULL;
567 BOOL ret;
569 WARN("%p %p %p %p %p %p %ld: semi-stub\n", hNamedPipe, lpState, lpCurInstances,
570 lpMaxCollectionCount, lpCollectDataTimeout, lpUsername, nUsernameMaxSize);
572 if (lpUsername && nUsernameMaxSize &&
573 !(username = HeapAlloc(GetProcessHeap(), 0, nUsernameMaxSize * sizeof(WCHAR)))) return FALSE;
575 ret = GetNamedPipeHandleStateW(hNamedPipe, lpState, lpCurInstances, lpMaxCollectionCount,
576 lpCollectDataTimeout, username, nUsernameMaxSize);
577 if (ret && username)
578 WideCharToMultiByte(CP_ACP, 0, username, -1, lpUsername, nUsernameMaxSize, NULL, NULL);
580 HeapFree(GetProcessHeap(), 0, username);
581 return ret;
584 /***********************************************************************
585 * CallNamedPipeA (KERNEL32.@)
587 BOOL WINAPI CallNamedPipeA(
588 LPCSTR lpNamedPipeName, LPVOID lpInput, DWORD dwInputSize,
589 LPVOID lpOutput, DWORD dwOutputSize,
590 LPDWORD lpBytesRead, DWORD nTimeout)
592 DWORD len;
593 LPWSTR str = NULL;
594 BOOL ret;
596 TRACE("%s %p %ld %p %ld %p %ld\n",
597 debugstr_a(lpNamedPipeName), lpInput, dwInputSize,
598 lpOutput, dwOutputSize, lpBytesRead, nTimeout);
600 if( lpNamedPipeName )
602 len = MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, NULL, 0 );
603 str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
604 MultiByteToWideChar( CP_ACP, 0, lpNamedPipeName, -1, str, len );
606 ret = CallNamedPipeW( str, lpInput, dwInputSize, lpOutput,
607 dwOutputSize, lpBytesRead, nTimeout );
608 if( lpNamedPipeName )
609 HeapFree( GetProcessHeap(), 0, str );
611 return ret;
614 /******************************************************************************
615 * CreateMailslotA [KERNEL32.@]
617 * See CreateMailslotW.
619 HANDLE WINAPI CreateMailslotA( LPCSTR lpName, DWORD nMaxMessageSize,
620 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
622 DWORD len;
623 HANDLE handle;
624 LPWSTR name = NULL;
626 TRACE("%s %ld %ld %p\n", debugstr_a(lpName),
627 nMaxMessageSize, lReadTimeout, sa);
629 if( lpName )
631 len = MultiByteToWideChar( CP_ACP, 0, lpName, -1, NULL, 0 );
632 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
633 MultiByteToWideChar( CP_ACP, 0, lpName, -1, name, len );
636 handle = CreateMailslotW( name, nMaxMessageSize, lReadTimeout, sa );
638 HeapFree( GetProcessHeap(), 0, name );
640 return handle;
644 /******************************************************************************
645 * CreateMailslotW [KERNEL32.@]
647 * Create a mailslot with specified name.
649 * PARAMS
650 * lpName [I] Pointer to string for mailslot name
651 * nMaxMessageSize [I] Maximum message size
652 * lReadTimeout [I] Milliseconds before read time-out
653 * sa [I] Pointer to security structure
655 * RETURNS
656 * Success: Handle to mailslot
657 * Failure: INVALID_HANDLE_VALUE
659 HANDLE WINAPI CreateMailslotW( LPCWSTR lpName, DWORD nMaxMessageSize,
660 DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa )
662 HANDLE handle = INVALID_HANDLE_VALUE;
663 OBJECT_ATTRIBUTES attr;
664 UNICODE_STRING nameW;
665 LARGE_INTEGER timeout;
666 IO_STATUS_BLOCK iosb;
668 TRACE("%s %ld %ld %p\n", debugstr_w(lpName),
669 nMaxMessageSize, lReadTimeout, sa);
671 if (!RtlDosPathNameToNtPathName_U( lpName, &nameW, NULL, NULL ))
673 SetLastError( ERROR_PATH_NOT_FOUND );
674 return INVALID_HANDLE_VALUE;
677 if (nameW.Length >= MAX_PATH * sizeof(WCHAR) )
679 SetLastError( ERROR_FILENAME_EXCED_RANGE );
680 RtlFreeUnicodeString( &nameW );
681 return INVALID_HANDLE_VALUE;
684 attr.Length = sizeof(attr);
685 attr.RootDirectory = 0;
686 attr.Attributes = OBJ_CASE_INSENSITIVE;
687 attr.ObjectName = &nameW;
688 attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL;
689 attr.SecurityQualityOfService = NULL;
691 if (lReadTimeout != MAILSLOT_WAIT_FOREVER)
692 timeout.QuadPart = (ULONGLONG) lReadTimeout * -10000;
693 else
694 timeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
696 if (!set_ntstatus( NtCreateMailslotFile( &handle, GENERIC_READ | SYNCHRONIZE, &attr,
697 &iosb, 0, 0, nMaxMessageSize, &timeout )))
698 handle = INVALID_HANDLE_VALUE;
700 RtlFreeUnicodeString( &nameW );
701 return handle;
705 /******************************************************************************
706 * GetMailslotInfo [KERNEL32.@]
708 * Retrieve information about a mailslot.
710 * PARAMS
711 * hMailslot [I] Mailslot handle
712 * lpMaxMessageSize [O] Address of maximum message size
713 * lpNextSize [O] Address of size of next message
714 * lpMessageCount [O] Address of number of messages
715 * lpReadTimeout [O] Address of read time-out
717 * RETURNS
718 * Success: TRUE
719 * Failure: FALSE
721 BOOL WINAPI GetMailslotInfo( HANDLE hMailslot, LPDWORD lpMaxMessageSize,
722 LPDWORD lpNextSize, LPDWORD lpMessageCount,
723 LPDWORD lpReadTimeout )
725 FILE_MAILSLOT_QUERY_INFORMATION info;
726 IO_STATUS_BLOCK iosb;
728 TRACE("%p %p %p %p %p\n",hMailslot, lpMaxMessageSize,
729 lpNextSize, lpMessageCount, lpReadTimeout);
731 if (!set_ntstatus( NtQueryInformationFile( hMailslot, &iosb, &info, sizeof info,
732 FileMailslotQueryInformation )))
733 return FALSE;
735 if( lpMaxMessageSize )
736 *lpMaxMessageSize = info.MaximumMessageSize;
737 if( lpNextSize )
738 *lpNextSize = info.NextMessageSize;
739 if( lpMessageCount )
740 *lpMessageCount = info.MessagesAvailable;
741 if( lpReadTimeout )
743 if (info.ReadTimeout.QuadPart == (((LONGLONG)0x7fffffff << 32) | 0xffffffff))
744 *lpReadTimeout = MAILSLOT_WAIT_FOREVER;
745 else
746 *lpReadTimeout = info.ReadTimeout.QuadPart / -10000;
748 return TRUE;
752 /******************************************************************************
753 * SetMailslotInfo [KERNEL32.@]
755 * Set the read timeout of a mailslot.
757 * PARAMS
758 * hMailslot [I] Mailslot handle
759 * dwReadTimeout [I] Timeout in milliseconds.
761 * RETURNS
762 * Success: TRUE
763 * Failure: FALSE
765 BOOL WINAPI SetMailslotInfo( HANDLE hMailslot, DWORD dwReadTimeout)
767 FILE_MAILSLOT_SET_INFORMATION info;
768 IO_STATUS_BLOCK iosb;
770 TRACE("%p %ld\n", hMailslot, dwReadTimeout);
772 if (dwReadTimeout != MAILSLOT_WAIT_FOREVER)
773 info.ReadTimeout.QuadPart = (ULONGLONG)dwReadTimeout * -10000;
774 else
775 info.ReadTimeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
776 return set_ntstatus( NtSetInformationFile( hMailslot, &iosb, &info, sizeof info,
777 FileMailslotSetInformation ));
781 /******************************************************************************
782 * BindIoCompletionCallback (KERNEL32.@)
784 BOOL WINAPI BindIoCompletionCallback( HANDLE handle, LPOVERLAPPED_COMPLETION_ROUTINE func, ULONG flags )
786 return set_ntstatus( RtlSetIoCompletionCallback( handle, (PRTL_OVERLAPPED_COMPLETION_ROUTINE)func, flags ));
790 #ifdef __i386__
792 /***********************************************************************
793 * InterlockedCompareExchange (KERNEL32.@)
795 /* LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ); */
796 __ASM_STDCALL_FUNC(InterlockedCompareExchange, 12,
797 "movl 12(%esp),%eax\n\t"
798 "movl 8(%esp),%ecx\n\t"
799 "movl 4(%esp),%edx\n\t"
800 "lock; cmpxchgl %ecx,(%edx)\n\t"
801 "ret $12")
803 /***********************************************************************
804 * InterlockedExchange (KERNEL32.@)
806 /* LONG WINAPI InterlockedExchange( PLONG dest, LONG val ); */
807 __ASM_STDCALL_FUNC(InterlockedExchange, 8,
808 "movl 8(%esp),%eax\n\t"
809 "movl 4(%esp),%edx\n\t"
810 "lock; xchgl %eax,(%edx)\n\t"
811 "ret $8")
813 /***********************************************************************
814 * InterlockedExchangeAdd (KERNEL32.@)
816 /* LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ); */
817 __ASM_STDCALL_FUNC(InterlockedExchangeAdd, 8,
818 "movl 8(%esp),%eax\n\t"
819 "movl 4(%esp),%edx\n\t"
820 "lock; xaddl %eax,(%edx)\n\t"
821 "ret $8")
823 /***********************************************************************
824 * InterlockedIncrement (KERNEL32.@)
826 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
827 __ASM_STDCALL_FUNC(InterlockedIncrement, 4,
828 "movl 4(%esp),%edx\n\t"
829 "movl $1,%eax\n\t"
830 "lock; xaddl %eax,(%edx)\n\t"
831 "incl %eax\n\t"
832 "ret $4")
834 /***********************************************************************
835 * InterlockedDecrement (KERNEL32.@)
837 __ASM_STDCALL_FUNC(InterlockedDecrement, 4,
838 "movl 4(%esp),%edx\n\t"
839 "movl $-1,%eax\n\t"
840 "lock; xaddl %eax,(%edx)\n\t"
841 "decl %eax\n\t"
842 "ret $4")
844 #endif /* __i386__ */