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
38 #include "kernel_private.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(sync
);
44 static const struct _KUSER_SHARED_DATA
*user_shared_data
= (struct _KUSER_SHARED_DATA
*)0x7ffe0000;
47 static void get_create_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
48 SECURITY_ATTRIBUTES
*sa
, const WCHAR
*name
)
50 attr
->Length
= sizeof(*attr
);
51 attr
->RootDirectory
= 0;
52 attr
->ObjectName
= NULL
;
53 attr
->Attributes
= OBJ_OPENIF
| ((sa
&& sa
->bInheritHandle
) ? OBJ_INHERIT
: 0);
54 attr
->SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
55 attr
->SecurityQualityOfService
= NULL
;
58 RtlInitUnicodeString( nameW
, name
);
59 attr
->ObjectName
= nameW
;
60 BaseGetNamedObjectDirectory( &attr
->RootDirectory
);
64 static BOOL
get_open_object_attributes( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*nameW
,
65 BOOL inherit
, const WCHAR
*name
)
71 SetLastError( ERROR_INVALID_PARAMETER
);
74 RtlInitUnicodeString( nameW
, name
);
75 BaseGetNamedObjectDirectory( &dir
);
76 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
80 /******************************************************************************
81 * GetTickCount64 (KERNEL32.@)
83 ULONGLONG WINAPI DECLSPEC_HOTPATCH
GetTickCount64(void)
89 high
= user_shared_data
->TickCount
.High1Time
;
90 low
= user_shared_data
->TickCount
.LowPart
;
92 while (high
!= user_shared_data
->TickCount
.High2Time
);
93 /* note: we ignore TickCountMultiplier */
94 return (ULONGLONG
)high
<< 32 | low
;
97 /***********************************************************************
98 * GetTickCount (KERNEL32.@)
100 DWORD WINAPI DECLSPEC_HOTPATCH
GetTickCount(void)
102 /* note: we ignore TickCountMultiplier */
103 return user_shared_data
->TickCount
.LowPart
;
106 /***********************************************************************
107 * RegisterWaitForSingleObject (KERNEL32.@)
109 BOOL WINAPI
RegisterWaitForSingleObject( HANDLE
*wait
, HANDLE object
, WAITORTIMERCALLBACK callback
,
110 void *context
, ULONG timeout
, ULONG flags
)
112 if (!set_ntstatus( RtlRegisterWait( wait
, object
, callback
, context
, timeout
, flags
))) return FALSE
;
116 /***********************************************************************
117 * UnregisterWait (KERNEL32.@)
119 BOOL WINAPI
UnregisterWait( HANDLE handle
)
121 return set_ntstatus( RtlDeregisterWait( handle
));
124 /***********************************************************************
125 * MakeCriticalSectionGlobal (KERNEL32.@)
127 void WINAPI
MakeCriticalSectionGlobal( CRITICAL_SECTION
*crit
)
129 /* let's assume that only one thread at a time will try to do this */
130 HANDLE sem
= crit
->LockSemaphore
;
131 if (!sem
) NtCreateSemaphore( &sem
, SEMAPHORE_ALL_ACCESS
, NULL
, 0, 1 );
132 crit
->LockSemaphore
= ConvertToGlobalHandle( sem
);
133 if (crit
->DebugInfo
!= (void *)(ULONG_PTR
)-1)
134 RtlFreeHeap( GetProcessHeap(), 0, crit
->DebugInfo
);
135 crit
->DebugInfo
= NULL
;
139 /***********************************************************************
140 * ReinitializeCriticalSection (KERNEL32.@)
142 * Initialise an already used critical section.
145 * crit [O] Critical section to initialise.
150 void WINAPI
ReinitializeCriticalSection( CRITICAL_SECTION
*crit
)
152 if ( !crit
->LockSemaphore
)
153 RtlInitializeCriticalSection( crit
);
157 /***********************************************************************
158 * UninitializeCriticalSection (KERNEL32.@)
160 * UnInitialise a critical section after use.
163 * crit [O] Critical section to uninitialise (destroy).
168 void WINAPI
UninitializeCriticalSection( CRITICAL_SECTION
*crit
)
170 RtlDeleteCriticalSection( crit
);
174 /***********************************************************************
175 * OpenMutexA (KERNEL32.@)
177 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenMutexA( DWORD access
, BOOL inherit
, LPCSTR name
)
179 WCHAR buffer
[MAX_PATH
];
181 if (!name
) return OpenMutexW( access
, inherit
, NULL
);
183 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
185 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
188 return OpenMutexW( access
, inherit
, buffer
);
199 /***********************************************************************
200 * CreateSemaphoreA (KERNEL32.@)
202 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreA( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
, LPCSTR name
)
204 return CreateSemaphoreExA( sa
, initial
, max
, name
, 0, SEMAPHORE_ALL_ACCESS
);
208 /***********************************************************************
209 * CreateSemaphoreExA (KERNEL32.@)
211 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateSemaphoreExA( SECURITY_ATTRIBUTES
*sa
, LONG initial
, LONG max
,
212 LPCSTR name
, DWORD flags
, DWORD access
)
214 WCHAR buffer
[MAX_PATH
];
216 if (!name
) return CreateSemaphoreExW( sa
, initial
, max
, NULL
, flags
, access
);
218 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
220 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
223 return CreateSemaphoreExW( sa
, initial
, max
, buffer
, flags
, access
);
227 /***********************************************************************
228 * OpenSemaphoreA (KERNEL32.@)
230 HANDLE WINAPI DECLSPEC_HOTPATCH
OpenSemaphoreA( DWORD access
, BOOL inherit
, LPCSTR name
)
232 WCHAR buffer
[MAX_PATH
];
234 if (!name
) return OpenSemaphoreW( access
, inherit
, NULL
);
236 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
238 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
241 return OpenSemaphoreW( access
, inherit
, buffer
);
249 /******************************************************************************
250 * CreateJobObjectW (KERNEL32.@)
252 HANDLE WINAPI
CreateJobObjectW( LPSECURITY_ATTRIBUTES sa
, LPCWSTR name
)
255 UNICODE_STRING nameW
;
256 OBJECT_ATTRIBUTES attr
;
259 get_create_object_attributes( &attr
, &nameW
, sa
, name
);
261 status
= NtCreateJobObject( &ret
, JOB_OBJECT_ALL_ACCESS
, &attr
);
262 if (status
== STATUS_OBJECT_NAME_EXISTS
)
263 SetLastError( ERROR_ALREADY_EXISTS
);
265 SetLastError( RtlNtStatusToDosError(status
) );
269 /******************************************************************************
270 * CreateJobObjectA (KERNEL32.@)
272 HANDLE WINAPI
CreateJobObjectA( LPSECURITY_ATTRIBUTES attr
, LPCSTR name
)
274 WCHAR buffer
[MAX_PATH
];
276 if (!name
) return CreateJobObjectW( attr
, NULL
);
278 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
280 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
283 return CreateJobObjectW( attr
, buffer
);
286 /******************************************************************************
287 * OpenJobObjectW (KERNEL32.@)
289 HANDLE WINAPI
OpenJobObjectW( DWORD access
, BOOL inherit
, LPCWSTR name
)
292 UNICODE_STRING nameW
;
293 OBJECT_ATTRIBUTES attr
;
295 if (!get_open_object_attributes( &attr
, &nameW
, inherit
, name
)) return 0;
297 if (!set_ntstatus( NtOpenJobObject( &ret
, access
, &attr
))) return 0;
301 /******************************************************************************
302 * OpenJobObjectA (KERNEL32.@)
304 HANDLE WINAPI
OpenJobObjectA( DWORD access
, BOOL inherit
, LPCSTR name
)
306 WCHAR buffer
[MAX_PATH
];
308 if (!name
) return OpenJobObjectW( access
, inherit
, NULL
);
310 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
312 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
315 return OpenJobObjectW( access
, inherit
, buffer
);
318 /******************************************************************************
319 * TerminateJobObject (KERNEL32.@)
321 BOOL WINAPI
TerminateJobObject( HANDLE job
, UINT exit_code
)
323 return set_ntstatus( NtTerminateJobObject( job
, exit_code
));
326 /******************************************************************************
327 * QueryInformationJobObject (KERNEL32.@)
329 BOOL WINAPI
QueryInformationJobObject( HANDLE job
, JOBOBJECTINFOCLASS
class, LPVOID info
,
330 DWORD len
, DWORD
*ret_len
)
332 return set_ntstatus( NtQueryInformationJobObject( job
, class, info
, len
, ret_len
));
335 /******************************************************************************
336 * SetInformationJobObject (KERNEL32.@)
338 BOOL WINAPI
SetInformationJobObject( HANDLE job
, JOBOBJECTINFOCLASS
class, LPVOID info
, DWORD len
)
340 return set_ntstatus( NtSetInformationJobObject( job
, class, info
, len
));
343 /******************************************************************************
344 * AssignProcessToJobObject (KERNEL32.@)
346 BOOL WINAPI
AssignProcessToJobObject( HANDLE job
, HANDLE process
)
348 return set_ntstatus( NtAssignProcessToJobObject( job
, process
));
357 /***********************************************************************
358 * CreateWaitableTimerA (KERNEL32.@)
360 HANDLE WINAPI
CreateWaitableTimerA( SECURITY_ATTRIBUTES
*sa
, BOOL manual
, LPCSTR name
)
362 return CreateWaitableTimerExA( sa
, name
, manual
? CREATE_WAITABLE_TIMER_MANUAL_RESET
: 0,
367 /***********************************************************************
368 * CreateWaitableTimerExA (KERNEL32.@)
370 HANDLE WINAPI
CreateWaitableTimerExA( SECURITY_ATTRIBUTES
*sa
, LPCSTR name
, DWORD flags
, DWORD access
)
372 WCHAR buffer
[MAX_PATH
];
374 if (!name
) return CreateWaitableTimerExW( sa
, NULL
, flags
, access
);
376 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
378 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
381 return CreateWaitableTimerExW( sa
, buffer
, flags
, access
);
385 /***********************************************************************
386 * OpenWaitableTimerA (KERNEL32.@)
388 HANDLE WINAPI
OpenWaitableTimerA( DWORD access
, BOOL inherit
, LPCSTR name
)
390 WCHAR buffer
[MAX_PATH
];
392 if (!name
) return OpenWaitableTimerW( access
, inherit
, NULL
);
394 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
396 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
399 return OpenWaitableTimerW( access
, inherit
, buffer
);
403 /***********************************************************************
404 * DeleteTimerQueue (KERNEL32.@)
406 BOOL WINAPI
DeleteTimerQueue(HANDLE TimerQueue
)
408 return DeleteTimerQueueEx(TimerQueue
, NULL
);
411 /***********************************************************************
412 * CancelTimerQueueTimer (KERNEL32.@)
414 BOOL WINAPI
CancelTimerQueueTimer(HANDLE queue
, HANDLE timer
)
416 return DeleteTimerQueueTimer( queue
, timer
, NULL
);
426 /***********************************************************************
427 * CreateFileMappingA (KERNEL32.@)
429 HANDLE WINAPI
CreateFileMappingA( HANDLE file
, SECURITY_ATTRIBUTES
*sa
, DWORD protect
,
430 DWORD size_high
, DWORD size_low
, LPCSTR name
)
432 WCHAR buffer
[MAX_PATH
];
434 if (!name
) return CreateFileMappingW( file
, sa
, protect
, size_high
, size_low
, NULL
);
436 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
438 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
441 return CreateFileMappingW( file
, sa
, protect
, size_high
, size_low
, buffer
);
445 /***********************************************************************
446 * OpenFileMappingA (KERNEL32.@)
448 HANDLE WINAPI
OpenFileMappingA( DWORD access
, BOOL inherit
, LPCSTR name
)
450 WCHAR buffer
[MAX_PATH
];
452 if (!name
) return OpenFileMappingW( access
, inherit
, NULL
);
454 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
456 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
459 return OpenFileMappingW( access
, inherit
, buffer
);
468 /***********************************************************************
469 * CreateNamedPipeA (KERNEL32.@)
471 HANDLE WINAPI
CreateNamedPipeA( LPCSTR name
, DWORD dwOpenMode
,
472 DWORD dwPipeMode
, DWORD nMaxInstances
,
473 DWORD nOutBufferSize
, DWORD nInBufferSize
,
474 DWORD nDefaultTimeOut
, LPSECURITY_ATTRIBUTES attr
)
476 WCHAR buffer
[MAX_PATH
];
478 if (!name
) return CreateNamedPipeW( NULL
, dwOpenMode
, dwPipeMode
, nMaxInstances
,
479 nOutBufferSize
, nInBufferSize
, nDefaultTimeOut
, attr
);
481 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
483 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
484 return INVALID_HANDLE_VALUE
;
486 return CreateNamedPipeW( buffer
, dwOpenMode
, dwPipeMode
, nMaxInstances
,
487 nOutBufferSize
, nInBufferSize
, nDefaultTimeOut
, attr
);
491 /***********************************************************************
492 * WaitNamedPipeA (KERNEL32.@)
494 BOOL WINAPI
WaitNamedPipeA (LPCSTR name
, DWORD nTimeOut
)
496 WCHAR buffer
[MAX_PATH
];
498 if (!name
) return WaitNamedPipeW( NULL
, nTimeOut
);
500 if (!MultiByteToWideChar( CP_ACP
, 0, name
, -1, buffer
, MAX_PATH
))
502 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
505 return WaitNamedPipeW( buffer
, nTimeOut
);
509 /***********************************************************************
510 * GetNamedPipeClientProcessId (KERNEL32.@)
512 BOOL WINAPI
GetNamedPipeClientProcessId( HANDLE pipe
, ULONG
*id
)
514 IO_STATUS_BLOCK iosb
;
516 return set_ntstatus( NtFsControlFile( pipe
, NULL
, NULL
, NULL
, &iosb
,
517 FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE
, (void *)"ClientProcessId",
518 sizeof("ClientProcessId"), id
, sizeof(*id
) ));
521 /***********************************************************************
522 * GetNamedPipeServerProcessId (KERNEL32.@)
524 BOOL WINAPI
GetNamedPipeServerProcessId( HANDLE pipe
, ULONG
*id
)
526 IO_STATUS_BLOCK iosb
;
528 return set_ntstatus( NtFsControlFile( pipe
, NULL
, NULL
, NULL
, &iosb
,
529 FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE
, (void *)"ServerProcessId",
530 sizeof("ServerProcessId"), id
, sizeof(*id
) ));
533 /***********************************************************************
534 * GetNamedPipeClientSessionId (KERNEL32.@)
536 BOOL WINAPI
GetNamedPipeClientSessionId( HANDLE pipe
, ULONG
*id
)
538 FIXME( "%p, %p\n", pipe
, id
);
540 if (!id
) return FALSE
;
541 *id
= NtCurrentTeb()->Peb
->SessionId
;
545 /***********************************************************************
546 * GetNamedPipeServerSessionId (KERNEL32.@)
548 BOOL WINAPI
GetNamedPipeServerSessionId( HANDLE pipe
, ULONG
*id
)
550 FIXME( "%p, %p\n", pipe
, id
);
552 if (!id
) return FALSE
;
553 *id
= NtCurrentTeb()->Peb
->SessionId
;
557 /***********************************************************************
558 * GetNamedPipeHandleStateA (KERNEL32.@)
560 BOOL WINAPI
GetNamedPipeHandleStateA(
561 HANDLE hNamedPipe
, LPDWORD lpState
, LPDWORD lpCurInstances
,
562 LPDWORD lpMaxCollectionCount
, LPDWORD lpCollectDataTimeout
,
563 LPSTR lpUsername
, DWORD nUsernameMaxSize
)
565 WCHAR
*username
= NULL
;
568 WARN("%p %p %p %p %p %p %ld: semi-stub\n", hNamedPipe
, lpState
, lpCurInstances
,
569 lpMaxCollectionCount
, lpCollectDataTimeout
, lpUsername
, nUsernameMaxSize
);
571 if (lpUsername
&& nUsernameMaxSize
&&
572 !(username
= HeapAlloc(GetProcessHeap(), 0, nUsernameMaxSize
* sizeof(WCHAR
)))) return FALSE
;
574 ret
= GetNamedPipeHandleStateW(hNamedPipe
, lpState
, lpCurInstances
, lpMaxCollectionCount
,
575 lpCollectDataTimeout
, username
, nUsernameMaxSize
);
577 WideCharToMultiByte(CP_ACP
, 0, username
, -1, lpUsername
, nUsernameMaxSize
, NULL
, NULL
);
579 HeapFree(GetProcessHeap(), 0, username
);
583 /***********************************************************************
584 * CallNamedPipeA (KERNEL32.@)
586 BOOL WINAPI
CallNamedPipeA(
587 LPCSTR lpNamedPipeName
, LPVOID lpInput
, DWORD dwInputSize
,
588 LPVOID lpOutput
, DWORD dwOutputSize
,
589 LPDWORD lpBytesRead
, DWORD nTimeout
)
595 TRACE("%s %p %ld %p %ld %p %ld\n",
596 debugstr_a(lpNamedPipeName
), lpInput
, dwInputSize
,
597 lpOutput
, dwOutputSize
, lpBytesRead
, nTimeout
);
599 if( lpNamedPipeName
)
601 len
= MultiByteToWideChar( CP_ACP
, 0, lpNamedPipeName
, -1, NULL
, 0 );
602 str
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
603 MultiByteToWideChar( CP_ACP
, 0, lpNamedPipeName
, -1, str
, len
);
605 ret
= CallNamedPipeW( str
, lpInput
, dwInputSize
, lpOutput
,
606 dwOutputSize
, lpBytesRead
, nTimeout
);
607 if( lpNamedPipeName
)
608 HeapFree( GetProcessHeap(), 0, str
);
613 /******************************************************************************
614 * CreateMailslotA [KERNEL32.@]
616 * See CreateMailslotW.
618 HANDLE WINAPI
CreateMailslotA( LPCSTR lpName
, DWORD nMaxMessageSize
,
619 DWORD lReadTimeout
, LPSECURITY_ATTRIBUTES sa
)
625 TRACE("%s %ld %ld %p\n", debugstr_a(lpName
),
626 nMaxMessageSize
, lReadTimeout
, sa
);
630 len
= MultiByteToWideChar( CP_ACP
, 0, lpName
, -1, NULL
, 0 );
631 name
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
632 MultiByteToWideChar( CP_ACP
, 0, lpName
, -1, name
, len
);
635 handle
= CreateMailslotW( name
, nMaxMessageSize
, lReadTimeout
, sa
);
637 HeapFree( GetProcessHeap(), 0, name
);
643 /******************************************************************************
644 * CreateMailslotW [KERNEL32.@]
646 * Create a mailslot with specified name.
649 * lpName [I] Pointer to string for mailslot name
650 * nMaxMessageSize [I] Maximum message size
651 * lReadTimeout [I] Milliseconds before read time-out
652 * sa [I] Pointer to security structure
655 * Success: Handle to mailslot
656 * Failure: INVALID_HANDLE_VALUE
658 HANDLE WINAPI
CreateMailslotW( LPCWSTR lpName
, DWORD nMaxMessageSize
,
659 DWORD lReadTimeout
, LPSECURITY_ATTRIBUTES sa
)
661 HANDLE handle
= INVALID_HANDLE_VALUE
;
662 OBJECT_ATTRIBUTES attr
;
663 UNICODE_STRING nameW
;
664 LARGE_INTEGER timeout
;
665 IO_STATUS_BLOCK iosb
;
667 TRACE("%s %ld %ld %p\n", debugstr_w(lpName
),
668 nMaxMessageSize
, lReadTimeout
, sa
);
670 if (!RtlDosPathNameToNtPathName_U( lpName
, &nameW
, NULL
, NULL
))
672 SetLastError( ERROR_PATH_NOT_FOUND
);
673 return INVALID_HANDLE_VALUE
;
676 if (nameW
.Length
>= MAX_PATH
* sizeof(WCHAR
) )
678 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
679 RtlFreeUnicodeString( &nameW
);
680 return INVALID_HANDLE_VALUE
;
683 attr
.Length
= sizeof(attr
);
684 attr
.RootDirectory
= 0;
685 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
686 attr
.ObjectName
= &nameW
;
687 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
688 attr
.SecurityQualityOfService
= NULL
;
690 if (lReadTimeout
!= MAILSLOT_WAIT_FOREVER
)
691 timeout
.QuadPart
= (ULONGLONG
) lReadTimeout
* -10000;
693 timeout
.QuadPart
= ((LONGLONG
)0x7fffffff << 32) | 0xffffffff;
695 if (!set_ntstatus( NtCreateMailslotFile( &handle
, GENERIC_READ
| SYNCHRONIZE
, &attr
,
696 &iosb
, 0, 0, nMaxMessageSize
, &timeout
)))
697 handle
= INVALID_HANDLE_VALUE
;
699 RtlFreeUnicodeString( &nameW
);
704 /******************************************************************************
705 * GetMailslotInfo [KERNEL32.@]
707 * Retrieve information about a mailslot.
710 * hMailslot [I] Mailslot handle
711 * lpMaxMessageSize [O] Address of maximum message size
712 * lpNextSize [O] Address of size of next message
713 * lpMessageCount [O] Address of number of messages
714 * lpReadTimeout [O] Address of read time-out
720 BOOL WINAPI
GetMailslotInfo( HANDLE hMailslot
, LPDWORD lpMaxMessageSize
,
721 LPDWORD lpNextSize
, LPDWORD lpMessageCount
,
722 LPDWORD lpReadTimeout
)
724 FILE_MAILSLOT_QUERY_INFORMATION info
;
725 IO_STATUS_BLOCK iosb
;
727 TRACE("%p %p %p %p %p\n",hMailslot
, lpMaxMessageSize
,
728 lpNextSize
, lpMessageCount
, lpReadTimeout
);
730 if (!set_ntstatus( NtQueryInformationFile( hMailslot
, &iosb
, &info
, sizeof info
,
731 FileMailslotQueryInformation
)))
734 if( lpMaxMessageSize
)
735 *lpMaxMessageSize
= info
.MaximumMessageSize
;
737 *lpNextSize
= info
.NextMessageSize
;
739 *lpMessageCount
= info
.MessagesAvailable
;
742 if (info
.ReadTimeout
.QuadPart
== (((LONGLONG
)0x7fffffff << 32) | 0xffffffff))
743 *lpReadTimeout
= MAILSLOT_WAIT_FOREVER
;
745 *lpReadTimeout
= info
.ReadTimeout
.QuadPart
/ -10000;
751 /******************************************************************************
752 * SetMailslotInfo [KERNEL32.@]
754 * Set the read timeout of a mailslot.
757 * hMailslot [I] Mailslot handle
758 * dwReadTimeout [I] Timeout in milliseconds.
764 BOOL WINAPI
SetMailslotInfo( HANDLE hMailslot
, DWORD dwReadTimeout
)
766 FILE_MAILSLOT_SET_INFORMATION info
;
767 IO_STATUS_BLOCK iosb
;
769 TRACE("%p %ld\n", hMailslot
, dwReadTimeout
);
771 if (dwReadTimeout
!= MAILSLOT_WAIT_FOREVER
)
772 info
.ReadTimeout
.QuadPart
= (ULONGLONG
)dwReadTimeout
* -10000;
774 info
.ReadTimeout
.QuadPart
= ((LONGLONG
)0x7fffffff << 32) | 0xffffffff;
775 return set_ntstatus( NtSetInformationFile( hMailslot
, &iosb
, &info
, sizeof info
,
776 FileMailslotSetInformation
));
780 /******************************************************************************
781 * BindIoCompletionCallback (KERNEL32.@)
783 BOOL WINAPI
BindIoCompletionCallback( HANDLE handle
, LPOVERLAPPED_COMPLETION_ROUTINE func
, ULONG flags
)
785 return set_ntstatus( RtlSetIoCompletionCallback( handle
, (PRTL_OVERLAPPED_COMPLETION_ROUTINE
)func
, flags
));
791 /***********************************************************************
792 * InterlockedCompareExchange (KERNEL32.@)
794 /* LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ); */
795 __ASM_STDCALL_FUNC(InterlockedCompareExchange
, 12,
796 "movl 12(%esp),%eax\n\t"
797 "movl 8(%esp),%ecx\n\t"
798 "movl 4(%esp),%edx\n\t"
799 "lock; cmpxchgl %ecx,(%edx)\n\t"
802 /***********************************************************************
803 * InterlockedExchange (KERNEL32.@)
805 /* LONG WINAPI InterlockedExchange( PLONG dest, LONG val ); */
806 __ASM_STDCALL_FUNC(InterlockedExchange
, 8,
807 "movl 8(%esp),%eax\n\t"
808 "movl 4(%esp),%edx\n\t"
809 "lock; xchgl %eax,(%edx)\n\t"
812 /***********************************************************************
813 * InterlockedExchangeAdd (KERNEL32.@)
815 /* LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ); */
816 __ASM_STDCALL_FUNC(InterlockedExchangeAdd
, 8,
817 "movl 8(%esp),%eax\n\t"
818 "movl 4(%esp),%edx\n\t"
819 "lock; xaddl %eax,(%edx)\n\t"
822 /***********************************************************************
823 * InterlockedIncrement (KERNEL32.@)
825 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
826 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
827 "movl 4(%esp),%edx\n\t"
829 "lock; xaddl %eax,(%edx)\n\t"
833 /***********************************************************************
834 * InterlockedDecrement (KERNEL32.@)
836 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
837 "movl 4(%esp),%edx\n\t"
839 "lock; xaddl %eax,(%edx)\n\t"
843 #endif /* __i386__ */