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
22 #include "wine/port.h"
33 #define WIN32_NO_STATUS
34 #define NONAMELESSUNION
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
;
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
)
79 SetLastError( ERROR_INVALID_PARAMETER
);
82 RtlInitUnicodeString( nameW
, name
);
83 BaseGetNamedObjectDirectory( &dir
);
84 InitializeObjectAttributes( attr
, nameW
, inherit
? OBJ_INHERIT
: 0, dir
, NULL
);
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();
106 /******************************************************************************
107 * GetTickCount64 (KERNEL32.@)
109 ULONGLONG WINAPI DECLSPEC_HOTPATCH
GetTickCount64(void)
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.
173 * crit [O] Critical section to initialise.
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.
191 * crit [O] Critical section to uninitialise (destroy).
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
);
216 return OpenMutexW( access
, inherit
, buffer
);
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
);
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
);
269 return OpenSemaphoreW( access
, inherit
, buffer
);
277 /******************************************************************************
278 * CreateJobObjectW (KERNEL32.@)
280 HANDLE WINAPI
CreateJobObjectW( LPSECURITY_ATTRIBUTES sa
, LPCWSTR name
)
283 UNICODE_STRING nameW
;
284 OBJECT_ATTRIBUTES attr
;
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
);
293 SetLastError( RtlNtStatusToDosError(status
) );
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
);
311 return CreateJobObjectW( attr
, buffer
);
314 /******************************************************************************
315 * OpenJobObjectW (KERNEL32.@)
317 HANDLE WINAPI
OpenJobObjectW( DWORD access
, BOOL inherit
, LPCWSTR name
)
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;
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
);
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
));
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,
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
);
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
);
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
);
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
);
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
);
487 return OpenFileMappingW( access
, inherit
, buffer
);
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
);
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
;
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
;
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
;
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
);
605 WideCharToMultiByte(CP_ACP
, 0, username
, -1, lpUsername
, nUsernameMaxSize
, NULL
, NULL
);
607 HeapFree(GetProcessHeap(), 0, username
);
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
)
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
);
641 /******************************************************************************
642 * CreateMailslotA [KERNEL32.@]
644 * See CreateMailslotW.
646 HANDLE WINAPI
CreateMailslotA( LPCSTR lpName
, DWORD nMaxMessageSize
,
647 DWORD lReadTimeout
, LPSECURITY_ATTRIBUTES sa
)
653 TRACE("%s %d %d %p\n", debugstr_a(lpName
),
654 nMaxMessageSize
, lReadTimeout
, sa
);
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
);
671 /******************************************************************************
672 * CreateMailslotW [KERNEL32.@]
674 * Create a mailslot with specified name.
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
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;
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
);
732 /******************************************************************************
733 * GetMailslotInfo [KERNEL32.@]
735 * Retrieve information about a mailslot.
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
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
)))
762 if( lpMaxMessageSize
)
763 *lpMaxMessageSize
= info
.MaximumMessageSize
;
765 *lpNextSize
= info
.NextMessageSize
;
767 *lpMessageCount
= info
.MessagesAvailable
;
770 if (info
.ReadTimeout
.QuadPart
== (((LONGLONG
)0x7fffffff << 32) | 0xffffffff))
771 *lpReadTimeout
= MAILSLOT_WAIT_FOREVER
;
773 *lpReadTimeout
= info
.ReadTimeout
.QuadPart
/ -10000;
779 /******************************************************************************
780 * SetMailslotInfo [KERNEL32.@]
782 * Set the read timeout of a mailslot.
785 * hMailslot [I] Mailslot handle
786 * dwReadTimeout [I] Timeout in milliseconds.
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;
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
));
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"
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"
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"
850 /***********************************************************************
851 * InterlockedIncrement (KERNEL32.@)
853 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
854 __ASM_STDCALL_FUNC(InterlockedIncrement
, 4,
855 "movl 4(%esp),%edx\n\t"
857 "lock; xaddl %eax,(%edx)\n\t"
861 /***********************************************************************
862 * InterlockedDecrement (KERNEL32.@)
864 __ASM_STDCALL_FUNC(InterlockedDecrement
, 4,
865 "movl 4(%esp),%edx\n\t"
867 "lock; xaddl %eax,(%edx)\n\t"
871 #endif /* __i386__ */