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
27 #define WIN32_NO_STATUS
28 #define NONAMELESSUNION
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
;
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
)
72 SetLastError( ERROR_INVALID_PARAMETER
);
75 RtlInitUnicodeString( nameW
, name
);
76 BaseGetNamedObjectDirectory( &dir
);
77 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
81 /******************************************************************************
82 * GetTickCount64 (KERNEL32.@)
84 ULONGLONG WINAPI DECLSPEC_HOTPATCH
GetTickCount64(void)
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
;
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.
146 * crit [O] Critical section to initialise.
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.
164 * crit [O] Critical section to uninitialise (destroy).
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
);
189 return OpenMutexW( access
, inherit
, buffer
);
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
);
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
);
242 return OpenSemaphoreW( access
, inherit
, buffer
);
250 /******************************************************************************
251 * CreateJobObjectW (KERNEL32.@)
253 HANDLE WINAPI
CreateJobObjectW( LPSECURITY_ATTRIBUTES sa
, LPCWSTR name
)
256 UNICODE_STRING nameW
;
257 OBJECT_ATTRIBUTES attr
;
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
);
266 SetLastError( RtlNtStatusToDosError(status
) );
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
);
284 return CreateJobObjectW( attr
, buffer
);
287 /******************************************************************************
288 * OpenJobObjectW (KERNEL32.@)
290 HANDLE WINAPI
OpenJobObjectW( DWORD access
, BOOL inherit
, LPCWSTR name
)
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;
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
);
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
));
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,
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
);
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
);
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
);
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
);
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
);
460 return OpenFileMappingW( access
, inherit
, buffer
);
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
);
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
;
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
;
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
;
569 WARN("%p %p %p %p %p %p %d: 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
);
578 WideCharToMultiByte(CP_ACP
, 0, username
, -1, lpUsername
, nUsernameMaxSize
, NULL
, NULL
);
580 HeapFree(GetProcessHeap(), 0, username
);
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
)
596 TRACE("%s %p %d %p %d %p %d\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
);
614 /******************************************************************************
615 * CreateMailslotA [KERNEL32.@]
617 * See CreateMailslotW.
619 HANDLE WINAPI
CreateMailslotA( LPCSTR lpName
, DWORD nMaxMessageSize
,
620 DWORD lReadTimeout
, LPSECURITY_ATTRIBUTES sa
)
626 TRACE("%s %d %d %p\n", debugstr_a(lpName
),
627 nMaxMessageSize
, lReadTimeout
, sa
);
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
);
644 /******************************************************************************
645 * CreateMailslotW [KERNEL32.@]
647 * Create a mailslot with specified name.
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
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 %d %d %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;
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
);
705 /******************************************************************************
706 * GetMailslotInfo [KERNEL32.@]
708 * Retrieve information about a mailslot.
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
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
)))
735 if( lpMaxMessageSize
)
736 *lpMaxMessageSize
= info
.MaximumMessageSize
;
738 *lpNextSize
= info
.NextMessageSize
;
740 *lpMessageCount
= info
.MessagesAvailable
;
743 if (info
.ReadTimeout
.QuadPart
== (((LONGLONG
)0x7fffffff << 32) | 0xffffffff))
744 *lpReadTimeout
= MAILSLOT_WAIT_FOREVER
;
746 *lpReadTimeout
= info
.ReadTimeout
.QuadPart
/ -10000;
752 /******************************************************************************
753 * SetMailslotInfo [KERNEL32.@]
755 * Set the read timeout of a mailslot.
758 * hMailslot [I] Mailslot handle
759 * dwReadTimeout [I] Timeout in milliseconds.
765 BOOL WINAPI
SetMailslotInfo( HANDLE hMailslot
, DWORD dwReadTimeout
)
767 FILE_MAILSLOT_SET_INFORMATION info
;
768 IO_STATUS_BLOCK iosb
;
770 TRACE("%p %d\n", hMailslot
, dwReadTimeout
);
772 if (dwReadTimeout
!= MAILSLOT_WAIT_FOREVER
)
773 info
.ReadTimeout
.QuadPart
= (ULONGLONG
)dwReadTimeout
* -10000;
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
));
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"
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"
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"
823 /***********************************************************************
824 * InterlockedIncrement (KERNEL32.@)
826 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
827 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
828 "movl 4(%esp),%edx\n\t"
830 "lock; xaddl %eax,(%edx)\n\t"
834 /***********************************************************************
835 * InterlockedDecrement (KERNEL32.@)
837 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
838 "movl 4(%esp),%edx\n\t"
840 "lock; xaddl %eax,(%edx)\n\t"
844 #endif /* __i386__ */