231 lines
6.2 KiB
C
231 lines
6.2 KiB
C
/*
|
|
* Process synchronisation
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include "debugtools.h"
|
|
|
|
#include "winerror.h"
|
|
#include "wine/unicode.h"
|
|
#include "server.h"
|
|
#include "ntddk.h"
|
|
#include "ntdll_misc.h"
|
|
|
|
DEFAULT_DEBUG_CHANNEL(ntdll);
|
|
|
|
/* copy a key name into the request buffer */
|
|
static inline NTSTATUS copy_nameU( LPWSTR Dest, const OBJECT_ATTRIBUTES *attr )
|
|
{
|
|
if (attr && attr->ObjectName && attr->ObjectName->Buffer)
|
|
{
|
|
if ((attr->ObjectName->Length) > MAX_PATH) return STATUS_BUFFER_OVERFLOW;
|
|
strcpyW( Dest, attr->ObjectName->Buffer );
|
|
}
|
|
else Dest[0] = 0;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* Semaphores
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* NtCreateSemaphore
|
|
*/
|
|
NTSTATUS WINAPI NtCreateSemaphore(
|
|
OUT PHANDLE SemaphoreHandle,
|
|
IN ACCESS_MASK DesiredAccess,
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
|
IN ULONG InitialCount,
|
|
IN ULONG MaximumCount)
|
|
{
|
|
struct create_semaphore_request *req = get_req_buffer();
|
|
NTSTATUS ret;
|
|
|
|
if ((MaximumCount <= 0) || (InitialCount < 0) || (InitialCount > MaximumCount))
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
*SemaphoreHandle = 0;
|
|
req->initial = InitialCount;
|
|
req->max = MaximumCount;
|
|
req->inherit = ObjectAttributes && (ObjectAttributes->Attributes & OBJ_INHERIT);
|
|
if (!(ret = copy_nameU( req->name, ObjectAttributes )) &&
|
|
!(ret = server_call_noerr( REQ_CREATE_SEMAPHORE ))) *SemaphoreHandle = req->handle;
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* NtOpenSemaphore
|
|
*/
|
|
NTSTATUS WINAPI NtOpenSemaphore(
|
|
OUT PHANDLE SemaphoreHandle,
|
|
IN ACCESS_MASK DesiredAcces,
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
|
{
|
|
struct open_semaphore_request *req = get_req_buffer();
|
|
NTSTATUS ret;
|
|
|
|
*SemaphoreHandle = 0;
|
|
req->access = DesiredAcces;
|
|
req->inherit = ObjectAttributes && (ObjectAttributes->Attributes & OBJ_INHERIT);
|
|
if (!(ret = copy_nameU( req->name, ObjectAttributes )) &&
|
|
!(ret = server_call_noerr( REQ_OPEN_SEMAPHORE ))) *SemaphoreHandle = req->handle;
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* NtQuerySemaphore
|
|
*/
|
|
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
|
|
*/
|
|
NTSTATUS WINAPI NtReleaseSemaphore(
|
|
IN HANDLE SemaphoreHandle,
|
|
IN ULONG ReleaseCount,
|
|
IN PULONG PreviousCount)
|
|
{
|
|
struct release_semaphore_request *req = get_req_buffer();
|
|
NTSTATUS ret;
|
|
|
|
if (ReleaseCount < 0) return STATUS_INVALID_PARAMETER;
|
|
|
|
req->handle = SemaphoreHandle;
|
|
req->count = ReleaseCount;
|
|
if (!(ret = server_call_noerr( REQ_RELEASE_SEMAPHORE )))
|
|
{
|
|
if (PreviousCount) *PreviousCount = req->prev_count;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Events
|
|
*/
|
|
|
|
/**************************************************************************
|
|
* NtCreateEvent
|
|
*/
|
|
NTSTATUS WINAPI NtCreateEvent(
|
|
OUT PHANDLE EventHandle,
|
|
IN ACCESS_MASK DesiredAccess,
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|
IN BOOLEAN ManualReset,
|
|
IN BOOLEAN InitialState)
|
|
{
|
|
struct create_event_request *req = get_req_buffer();
|
|
NTSTATUS ret;
|
|
|
|
*EventHandle = 0;
|
|
req->manual_reset = ManualReset;
|
|
req->initial_state = InitialState;
|
|
req->inherit = ObjectAttributes && (ObjectAttributes->Attributes & OBJ_INHERIT);
|
|
if (!(ret = copy_nameU( req->name, ObjectAttributes )) &&
|
|
!(ret = server_call_noerr( REQ_CREATE_EVENT ))) *EventHandle = req->handle;
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* NtOpenEvent
|
|
*/
|
|
NTSTATUS WINAPI NtOpenEvent(
|
|
OUT PHANDLE EventHandle,
|
|
IN ACCESS_MASK DesiredAccess,
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
|
{
|
|
struct open_event_request *req = get_req_buffer();
|
|
NTSTATUS ret;
|
|
|
|
*EventHandle = 0;
|
|
req->access = DesiredAccess;
|
|
req->inherit = ObjectAttributes && (ObjectAttributes->Attributes & OBJ_INHERIT);
|
|
if (!(ret = copy_nameU( req->name, ObjectAttributes )) &&
|
|
!(ret = server_call_noerr( REQ_OPEN_EVENT ))) *EventHandle = req->handle;
|
|
return ret;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* NtSetEvent
|
|
*/
|
|
NTSTATUS WINAPI NtSetEvent(
|
|
IN HANDLE EventHandle,
|
|
PULONG NumberOfThreadsReleased)
|
|
{
|
|
struct event_op_request *req = get_req_buffer();
|
|
FIXME("(0x%08x,%p)\n", EventHandle, NumberOfThreadsReleased);
|
|
req->handle = EventHandle;
|
|
req->op = SET_EVENT;
|
|
return server_call_noerr( REQ_EVENT_OP );
|
|
}
|
|
|
|
/******************************************************************************
|
|
* NtResetEvent
|
|
*/
|
|
NTSTATUS WINAPI NtResetEvent(
|
|
IN HANDLE EventHandle,
|
|
PULONG NumberOfThreadsReleased)
|
|
{
|
|
struct event_op_request *req = get_req_buffer();
|
|
FIXME("(0x%08x,%p)\n", EventHandle, NumberOfThreadsReleased);
|
|
req->handle = EventHandle;
|
|
req->op = RESET_EVENT;
|
|
return server_call_noerr( REQ_EVENT_OP );
|
|
}
|
|
|
|
/******************************************************************************
|
|
* NtClearEvent
|
|
*
|
|
* FIXME
|
|
* same as NtResetEvent ???
|
|
*/
|
|
NTSTATUS WINAPI NtClearEvent (
|
|
IN HANDLE EventHandle)
|
|
{
|
|
return NtResetEvent( EventHandle, NULL );
|
|
}
|
|
|
|
/******************************************************************************
|
|
* NtPulseEvent
|
|
*
|
|
* FIXME
|
|
* PulseCount
|
|
*/
|
|
NTSTATUS WINAPI NtPulseEvent(
|
|
IN HANDLE EventHandle,
|
|
IN PULONG PulseCount)
|
|
{
|
|
struct event_op_request *req = get_req_buffer();
|
|
FIXME("(0x%08x,%p)\n", EventHandle, PulseCount);
|
|
req->handle = EventHandle;
|
|
req->op = PULSE_EVENT;
|
|
return server_call_noerr( REQ_EVENT_OP );
|
|
}
|
|
|
|
/******************************************************************************
|
|
* NtQueryEvent
|
|
*/
|
|
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;
|
|
}
|