/*
* 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 "debugstr.h"
-#include "debugtools.h"
+#include "wine/debug.h"
#include "winerror.h"
-#include "server.h"
-#include "ntddk.h"
+#include "wine/unicode.h"
+#include "wine/server.h"
+#include "winternl.h"
#include "ntdll_misc.h"
-DEFAULT_DEBUG_CHANNEL(ntdll)
-
-#define nt_server_call(kind) (ret=ErrorCodeToStatus(server_call_noerr(kind)))
+WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
-/* helper to make the server functions return STATUS_ codes */
-static NTSTATUS ErrorCodeToStatus (DWORD Error)
-{
- TRACE("err=%lu\n", Error);
- switch (Error)
- {
- case NO_ERROR: return STATUS_SUCCESS;
- default:
- FIXME("Error code %lu not implemented\n", Error);
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-/* copy a key name into the request buffer */
-static inline NTSTATUS copy_nameU( LPWSTR Dest, PUNICODE_STRING Name )
-{
- if (Name->Buffer)
- {
- if ((Name->Length) > MAX_PATH) return STATUS_BUFFER_OVERFLOW;
- lstrcpyW( Dest, Name->Buffer );
- }
- else Dest[0] = 0;
- return STATUS_SUCCESS;
-}
/*
* Semaphores
*/
/******************************************************************************
- * NtCreateSemaphore
+ * NtCreateSemaphore (NTDLL.@)
*/
-NTSTATUS WINAPI NtCreateSemaphore(
- OUT PHANDLE SemaphoreHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
- IN ULONG InitialCount,
- IN ULONG MaximumCount)
+NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle,
+ IN ACCESS_MASK access,
+ IN const OBJECT_ATTRIBUTES *attr OPTIONAL,
+ IN ULONG InitialCount,
+ IN ULONG MaximumCount )
{
- struct create_semaphore_request *req = get_req_buffer();
- HRESULT ret;
-
- FIXME("(%p,0x%08lx,%p,0x%08lx,0x%08lx) stub!\n",
- SemaphoreHandle, DesiredAccess, ObjectAttributes, InitialCount, MaximumCount);
- dump_ObjectAttributes(ObjectAttributes);
-
- if ((MaximumCount <= 0) || (InitialCount < 0) || (InitialCount > MaximumCount))
- return STATUS_INVALID_PARAMETER;
-
- *SemaphoreHandle = 0;
- req->initial = InitialCount;
- req->max = MaximumCount;
- req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
- copy_nameU( req->name, ObjectAttributes->ObjectName );
- if (nt_server_call( REQ_CREATE_SEMAPHORE ) != STATUS_SUCCESS) return ret;
- *SemaphoreHandle = req->handle;
- return ret;
+ 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
- *
- * FIXME
+ * NtOpenSemaphore (NTDLL.@)
*/
-NTSTATUS WINAPI NtOpenSemaphore(
- IN HANDLE SemaphoreHandle,
- IN ACCESS_MASK DesiredAcces,
- IN POBJECT_ATTRIBUTES ObjectAttributes)
+NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle,
+ IN ACCESS_MASK access,
+ IN const OBJECT_ATTRIBUTES *attr )
{
- struct open_semaphore_request *req = get_req_buffer();
- HRESULT ret;
-
- FIXME("(0x%08x,0x%08lx,%p) stub!\n",
- SemaphoreHandle, DesiredAcces, ObjectAttributes);
- dump_ObjectAttributes(ObjectAttributes);
-
- req->access = DesiredAcces;
- req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
- copy_nameU( req->name, ObjectAttributes->ObjectName );
- if (nt_server_call( REQ_OPEN_SEMAPHORE ) != STATUS_SUCCESS) return -1;
- return req->handle;
+ 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
+ * NtQuerySemaphore (NTDLL.@)
*/
NTSTATUS WINAPI NtQuerySemaphore(
HANDLE SemaphoreHandle,
PVOID SemaphoreInformationClass,
OUT PVOID SemaphoreInformation,
ULONG Length,
- PULONG ReturnLength)
+ PULONG ReturnLength)
{
FIXME("(0x%08x,%p,%p,0x%08lx,%p) stub!\n",
SemaphoreHandle, SemaphoreInformationClass, SemaphoreInformation, Length, ReturnLength);
return STATUS_SUCCESS;
}
+
/******************************************************************************
- * NtReleaseSemaphore
+ * NtReleaseSemaphore (NTDLL.@)
*/
-NTSTATUS WINAPI NtReleaseSemaphore(
- IN HANDLE SemaphoreHandle,
- IN ULONG ReleaseCount,
- IN PULONG PreviousCount)
+NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous )
{
- struct release_semaphore_request *req = get_req_buffer();
- HRESULT ret;
-
- FIXME("(0x%08x,0x%08lx,%p,) stub!\n",
- SemaphoreHandle, ReleaseCount, PreviousCount);
-
- if (ReleaseCount < 0) return STATUS_INVALID_PARAMETER;
-
- req->handle = SemaphoreHandle;
- req->count = ReleaseCount;
- if (nt_server_call( REQ_RELEASE_SEMAPHORE ) == STATUS_SUCCESS)
- {
- if (PreviousCount) *PreviousCount = req->prev_count;
- }
- return ret;
+ 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
+ * NtCreateEvent (NTDLL.@)
+ * ZwCreateEvent (NTDLL.@)
*/
NTSTATUS WINAPI NtCreateEvent(
OUT PHANDLE EventHandle,
IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN const OBJECT_ATTRIBUTES *attr,
IN BOOLEAN ManualReset,
IN BOOLEAN InitialState)
{
- struct create_event_request *req = get_req_buffer();
- HRESULT ret;
-
- FIXME("(%p,0x%08lx,%p,%08x,%08x): empty stub\n",
- EventHandle,DesiredAccess,ObjectAttributes,ManualReset,InitialState);
- dump_ObjectAttributes(ObjectAttributes);
-
- *EventHandle = 0;
- req->manual_reset = ManualReset;
- req->initial_state = InitialState;
- req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
- copy_nameU( req->name, ObjectAttributes->ObjectName );
- if (nt_server_call( REQ_CREATE_EVENT ) != STATUS_SUCCESS) return ret;
- *EventHandle = req->handle;
- return STATUS_SUCCESS;
+ 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
+ * NtOpenEvent (NTDLL.@)
+ * ZwOpenEvent (NTDLL.@)
*/
NTSTATUS WINAPI NtOpenEvent(
OUT PHANDLE EventHandle,
IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes)
+ IN const OBJECT_ATTRIBUTES *attr )
{
- struct open_event_request *req = get_req_buffer();
- HRESULT ret;
-
- FIXME("(%p,0x%08lx,%p),stub!\n",
- EventHandle,DesiredAccess,ObjectAttributes);
- dump_ObjectAttributes(ObjectAttributes);
-
- *EventHandle = 0;
- req->access = DesiredAccess;
- req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
- copy_nameU( req->name, ObjectAttributes->ObjectName );
- if (nt_server_call( REQ_OPEN_EVENT ) != STATUS_SUCCESS) return ret;
- *EventHandle = req->handle;
- return ret;
+ 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;
}
-/***********************************************************************
- * EVENT_Operation
- *
- * Execute an event operation (set,reset,pulse).
- */
-static NTSTATUS EVENT_Operation(
- HANDLE handle,
- PULONG NumberOfThreadsReleased,
- enum event_op op )
-{
- struct event_op_request *req = get_req_buffer();
- HRESULT ret;
-
- req->handle = handle;
- req->op = op;
- nt_server_call( REQ_EVENT_OP );
- return ret;
-}
/******************************************************************************
- * NtSetEvent
+ * NtSetEvent (NTDLL.@)
+ * ZwSetEvent (NTDLL.@)
*/
-NTSTATUS WINAPI NtSetEvent(
- IN HANDLE EventHandle,
- PULONG NumberOfThreadsReleased)
+NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased )
{
- FIXME("(0x%08x,%p)\n", EventHandle, NumberOfThreadsReleased);
-
- return EVENT_Operation(EventHandle, NumberOfThreadsReleased, SET_EVENT);
+ 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
+ * NtResetEvent (NTDLL.@)
*/
-NTSTATUS WINAPI NtResetEvent(
- IN HANDLE EventHandle,
- PULONG NumberOfThreadsReleased)
+NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased )
{
- FIXME("(0x%08x,%p)\n", EventHandle, NumberOfThreadsReleased);
-
- return EVENT_Operation(EventHandle, NumberOfThreadsReleased, RESET_EVENT);
+ 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
+ * NtClearEvent (NTDLL.@)
*
* FIXME
* same as NtResetEvent ???
*/
-NTSTATUS WINAPI NtClearEvent (
- IN HANDLE EventHandle)
+NTSTATUS WINAPI NtClearEvent ( HANDLE handle )
{
- FIXME("(0x%08x)\n", EventHandle);
- return EVENT_Operation(EventHandle, NULL, RESET_EVENT);
+ return NtResetEvent( handle, NULL );
}
/******************************************************************************
- * NtPulseEvent
+ * NtPulseEvent (NTDLL.@)
*
* FIXME
* PulseCount
*/
-NTSTATUS WINAPI NtPulseEvent(
- IN HANDLE EventHandle,
- IN PULONG PulseCount)
+NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount )
{
- FIXME("(0x%08x,%p)\n", EventHandle, PulseCount);
-
- return EVENT_Operation(EventHandle, NULL, PULSE_EVENT);
+ 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
+ * NtQueryEvent (NTDLL.@)
*/
NTSTATUS WINAPI NtQueryEvent (
IN HANDLE EventHandle,