|  | /* | 
|  | *	Process synchronisation | 
|  | * | 
|  | * Copyright 1999, 2000 Juergen Schmied | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
|  | */ | 
|  |  | 
|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  | #include <time.h> | 
|  | #include "wine/debug.h" | 
|  |  | 
|  | #include "winerror.h" | 
|  | #include "wine/unicode.h" | 
|  | #include "wine/server.h" | 
|  | #include "ntddk.h" | 
|  | #include "ntdll_misc.h" | 
|  |  | 
|  | WINE_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; | 
|  | } |