/* * Process synchronisation */ #include #include #include #include #include "debugtools.h" #include "winerror.h" #include "wine/unicode.h" #include "wine/server.h" #include "ntddk.h" #include "ntdll_misc.h" DEFAULT_DEBUG_CHANNEL(ntdll); /* * Semaphores */ /****************************************************************************** * NtCreateSemaphore (NTDLL.@) */ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK access, IN const OBJECT_ATTRIBUTES *attr OPTIONAL, IN ULONG InitialCount, IN ULONG MaximumCount ) { DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; if ((MaximumCount <= 0) || (InitialCount > MaximumCount)) return STATUS_INVALID_PARAMETER; SERVER_START_REQ( create_semaphore ) { req->initial = InitialCount; req->max = MaximumCount; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); ret = wine_server_call( req ); *SemaphoreHandle = reply->handle; } SERVER_END_REQ; return ret; } /****************************************************************************** * NtOpenSemaphore (NTDLL.@) */ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK access, IN const OBJECT_ATTRIBUTES *attr ) { DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; SERVER_START_REQ( open_semaphore ) { req->access = access; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); ret = wine_server_call( req ); *SemaphoreHandle = reply->handle; } SERVER_END_REQ; return ret; } /****************************************************************************** * NtQuerySemaphore (NTDLL.@) */ NTSTATUS WINAPI NtQuerySemaphore( HANDLE SemaphoreHandle, PVOID SemaphoreInformationClass, OUT PVOID SemaphoreInformation, ULONG Length, PULONG ReturnLength) { FIXME("(0x%08x,%p,%p,0x%08lx,%p) stub!\n", SemaphoreHandle, SemaphoreInformationClass, SemaphoreInformation, Length, ReturnLength); return STATUS_SUCCESS; } /****************************************************************************** * NtReleaseSemaphore (NTDLL.@) */ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous ) { NTSTATUS ret; SERVER_START_REQ( release_semaphore ) { req->handle = handle; req->count = count; if (!(ret = wine_server_call( req ))) { if (previous) *previous = reply->prev_count; } } SERVER_END_REQ; return ret; } /* * Events */ /************************************************************************** * NtCreateEvent (NTDLL.@) * ZwCreateEvent (NTDLL.@) */ NTSTATUS WINAPI NtCreateEvent( OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN const OBJECT_ATTRIBUTES *attr, IN BOOLEAN ManualReset, IN BOOLEAN InitialState) { DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; SERVER_START_REQ( create_event ) { req->manual_reset = ManualReset; req->initial_state = InitialState; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); ret = wine_server_call( req ); *EventHandle = reply->handle; } SERVER_END_REQ; return ret; } /****************************************************************************** * NtOpenEvent (NTDLL.@) * ZwOpenEvent (NTDLL.@) */ NTSTATUS WINAPI NtOpenEvent( OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN const OBJECT_ATTRIBUTES *attr ) { DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; SERVER_START_REQ( open_event ) { req->access = DesiredAccess; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); ret = wine_server_call( req ); *EventHandle = reply->handle; } SERVER_END_REQ; return ret; } /****************************************************************************** * NtSetEvent (NTDLL.@) * ZwSetEvent (NTDLL.@) */ NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) { NTSTATUS ret; /* FIXME: set NumberOfThreadsReleased */ SERVER_START_REQ( event_op ) { req->handle = handle; req->op = SET_EVENT; ret = wine_server_call( req ); } SERVER_END_REQ; return ret; } /****************************************************************************** * NtResetEvent (NTDLL.@) */ NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) { NTSTATUS ret; /* resetting an event can't release any thread... */ if (NumberOfThreadsReleased) *NumberOfThreadsReleased = 0; SERVER_START_REQ( event_op ) { req->handle = handle; req->op = RESET_EVENT; ret = wine_server_call( req ); } SERVER_END_REQ; return ret; } /****************************************************************************** * NtClearEvent (NTDLL.@) * * FIXME * same as NtResetEvent ??? */ NTSTATUS WINAPI NtClearEvent ( HANDLE handle ) { return NtResetEvent( handle, NULL ); } /****************************************************************************** * NtPulseEvent (NTDLL.@) * * FIXME * PulseCount */ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount ) { NTSTATUS ret; FIXME("(0x%08x,%p)\n", handle, PulseCount); SERVER_START_REQ( event_op ) { req->handle = handle; req->op = PULSE_EVENT; ret = wine_server_call( req ); } SERVER_END_REQ; return ret; } /****************************************************************************** * NtQueryEvent (NTDLL.@) */ NTSTATUS WINAPI NtQueryEvent ( IN HANDLE EventHandle, IN UINT EventInformationClass, OUT PVOID EventInformation, IN ULONG EventInformationLength, OUT PULONG ReturnLength) { FIXME("(0x%08x)\n", EventHandle); return STATUS_SUCCESS; }