From 44158dd6905149fafe750ccbe5ecb48a2af39b25 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Thu, 2 Dec 2004 18:05:37 +0000 Subject: [PATCH] - moved event, semaphore, mutex implementation from kernel32 to ntdll - added mutant implementation in ntdll, and use it for mutex implementation in kernel32 - added access parameter on event, semaphore, timer creation in wineserver (as ntdll interface requires it) - added missing definitions in include/winternl.h --- dlls/kernel/sync.c | 272 ++++++++++++++++++--------------- dlls/ntdll/ntdll.spec | 18 +-- dlls/ntdll/sync.c | 127 +++++++++++++-- include/wine/server_protocol.h | 7 +- include/winternl.h | 19 ++- server/event.c | 2 +- server/mutex.c | 8 +- server/protocol.def | 6 + server/semaphore.c | 2 +- server/timer.c | 2 +- server/trace.c | 11 +- 11 files changed, 321 insertions(+), 153 deletions(-) diff --git a/dlls/kernel/sync.c b/dlls/kernel/sync.c index 1845129c816..f7204fb6291 100644 --- a/dlls/kernel/sync.c +++ b/dlls/kernel/sync.c @@ -403,12 +403,10 @@ HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset, BOOL initial_state, LPCWSTR name ) { HANDLE ret; - DWORD len = name ? strlenW(name) : 0; - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; - } + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + /* one buggy program needs this * ("Van Dale Groot woordenboek der Nederlandse taal") */ @@ -418,17 +416,21 @@ HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset, SetLastError( ERROR_INVALID_PARAMETER); return 0; } - SERVER_START_REQ( create_event ) + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL; + attr.SecurityQualityOfService = NULL; + if (name) { - req->manual_reset = manual_reset; - req->initial_state = initial_state; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - SetLastError(0); - wine_server_call_err( req ); - ret = reply->handle; + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; } - SERVER_END_REQ; + + status = NtCreateEvent( &ret, EVENT_ALL_ACCESS, &attr, manual_reset, initial_state ); + SetLastError( RtlNtStatusToDosError(status) ); return ret; } @@ -466,23 +468,30 @@ HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name ) HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name ) { HANDLE ret; - DWORD len = name ? strlenW(name) : 0; - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; - } + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + if (!is_version_nt()) access = EVENT_ALL_ACCESS; - SERVER_START_REQ( open_event ) + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = inherit ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (name) { - req->access = access; - req->inherit = inherit; - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - wine_server_call_err( req ); - ret = reply->handle; + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; + } + + status = NtOpenEvent( &ret, access, &attr ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return 0; } - SERVER_END_REQ; return ret; } @@ -598,22 +607,24 @@ HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name ) HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name ) { HANDLE ret; - DWORD len = name ? strlenW(name) : 0; - if (len >= MAX_PATH) + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL; + attr.SecurityQualityOfService = NULL; + if (name) { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; } - SERVER_START_REQ( create_mutex ) - { - req->owned = owner; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - SetLastError(0); - wine_server_call_err( req ); - ret = reply->handle; - } - SERVER_END_REQ; + + status = NtCreateMutant( &ret, MUTEX_ALL_ACCESS, &attr, owner ); + SetLastError( RtlNtStatusToDosError(status) ); return ret; } @@ -642,23 +653,30 @@ HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name ) HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name ) { HANDLE ret; - DWORD len = name ? strlenW(name) : 0; - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; - } + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + if (!is_version_nt()) access = MUTEX_ALL_ACCESS; - SERVER_START_REQ( open_mutex ) + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = inherit ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (name) { - req->access = access; - req->inherit = inherit; - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - wine_server_call_err( req ); - ret = reply->handle; + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; + } + + status = NtOpenMutant( &ret, access, &attr ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return 0; } - SERVER_END_REQ; return ret; } @@ -668,14 +686,15 @@ HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name ) */ BOOL WINAPI ReleaseMutex( HANDLE handle ) { - BOOL ret; - SERVER_START_REQ( release_mutex ) + NTSTATUS status; + + status = NtReleaseMutant(handle, NULL); + if (status != STATUS_SUCCESS) { - req->handle = handle; - ret = !wine_server_call_err( req ); + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; } - SERVER_END_REQ; - return ret; + return TRUE; } @@ -706,35 +725,27 @@ HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, * CreateSemaphoreW (KERNEL32.@) */ HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial, - LONG max, LPCWSTR name ) + LONG max, LPCWSTR name ) { HANDLE ret; - DWORD len = name ? strlenW(name) : 0; + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; - /* Check parameters */ - - if ((max <= 0) || (initial < 0) || (initial > max)) + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL; + attr.SecurityQualityOfService = NULL; + if (name) { - SetLastError( ERROR_INVALID_PARAMETER ); - return 0; - } - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; } - SERVER_START_REQ( create_semaphore ) - { - req->initial = (unsigned int)initial; - req->max = (unsigned int)max; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - SetLastError(0); - wine_server_call_err( req ); - ret = reply->handle; - } - SERVER_END_REQ; + status = NtCreateSemaphore( &ret, SEMAPHORE_ALL_ACCESS, &attr, initial, max ); + SetLastError( RtlNtStatusToDosError(status) ); return ret; } @@ -763,23 +774,30 @@ HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name ) HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name ) { HANDLE ret; - DWORD len = name ? strlenW(name) : 0; - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; - } + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + if (!is_version_nt()) access = SEMAPHORE_ALL_ACCESS; - SERVER_START_REQ( open_semaphore ) + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = inherit ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (name) { - req->access = access; - req->inherit = inherit; - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - wine_server_call_err( req ); - ret = reply->handle; + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; + } + + status = NtOpenSemaphore( &ret, access, &attr ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return 0; } - SERVER_END_REQ; return ret; } @@ -823,25 +841,26 @@ HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR */ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name ) { - HANDLE handle; - NTSTATUS status; - UNICODE_STRING us; - DWORD attr = 0; - OBJECT_ATTRIBUTES oa; + HANDLE handle; + NTSTATUS status; + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; - if (name) RtlInitUnicodeString(&us, name); - if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle) - attr |= OBJ_INHERIT; - InitializeObjectAttributes(&oa, name ? &us : NULL, attr, - NULL /* FIXME */, NULL /* FIXME */); - status = NtCreateTimer(&handle, TIMER_ALL_ACCESS, &oa, - manual ? NotificationTimer : SynchronizationTimer); - - if (status != STATUS_SUCCESS) + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = sa ? sa->lpSecurityDescriptor : NULL; + attr.SecurityQualityOfService = NULL; + if (name) { - SetLastError( RtlNtStatusToDosError(status) ); - return 0; + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; } + + status = NtCreateTimer(&handle, TIMER_ALL_ACCESS, &attr, + manual ? NotificationTimer : SynchronizationTimer); + SetLastError( RtlNtStatusToDosError(status) ); return handle; } @@ -869,17 +888,26 @@ HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name ) */ HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name ) { - NTSTATUS status; - ULONG attr = 0; - UNICODE_STRING us; - HANDLE handle; - OBJECT_ATTRIBUTES oa; + HANDLE handle; + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; - if (inherit) attr |= OBJ_INHERIT; + if (!is_version_nt()) access = SEMAPHORE_ALL_ACCESS; - if (name) RtlInitUnicodeString(&us, name); - InitializeObjectAttributes(&oa, name ? &us : NULL, attr, NULL /* FIXME */, NULL /* FIXME */); - status = NtOpenTimer(&handle, access, &oa); + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = inherit ? OBJ_INHERIT : 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (name) + { + RtlInitUnicodeString( &nameW, name ); + attr.ObjectName = &nameW; + } + + status = NtOpenTimer(&handle, access, &attr); if (status != STATUS_SUCCESS) { SetLastError( RtlNtStatusToDosError(status) ); diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 577261b207d..ca926a23d52 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -89,7 +89,7 @@ @ stub NtCreateIoCompletion @ stdcall NtCreateKey(ptr long ptr long ptr long long) @ stdcall NtCreateMailslotFile(long long long long long long long long) -@ stub NtCreateMutant +@ stdcall NtCreateMutant(ptr long ptr long) @ stdcall NtCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr) @ stdcall NtCreatePagingFile(long long long long) @ stdcall NtCreatePort(ptr ptr long long long) @@ -143,7 +143,7 @@ @ stdcall NtOpenFile(ptr long ptr ptr long long) @ stub NtOpenIoCompletion @ stdcall NtOpenKey(ptr long ptr) -@ stub NtOpenMutant +@ stdcall NtOpenMutant(ptr long ptr) @ stub NtOpenObjectAuditAlarm @ stub NtOpenProcess @ stdcall NtOpenProcessToken(long long long) @@ -176,7 +176,7 @@ @ stub NtQueryIntervalProfile @ stub NtQueryIoCompletion @ stdcall NtQueryKey (long long ptr long ptr) -@ stub NtQueryMutant +@ stdcall NtQueryMutant(long long ptr long ptr) @ stdcall NtQueryObject(long long long long long) @ stub NtQueryOpenSubKeys @ stdcall NtQueryPerformanceCounter (long long) @@ -200,7 +200,7 @@ @ stdcall NtReadVirtualMemory(long ptr ptr long ptr) @ stub NtRegisterNewDevice @ stdcall NtRegisterThreadTerminatePort(ptr) -@ stub NtReleaseMutant +@ stdcall NtReleaseMutant(long ptr) @ stub NtReleaseProcessMutant @ stdcall NtReleaseSemaphore(long long ptr) @ stub NtRemoveIoCompletion @@ -674,8 +674,8 @@ @ stub ZwCreateIoCompletion @ stdcall ZwCreateKey(ptr long ptr long ptr long long) NtCreateKey @ stdcall ZwCreateMailslotFile(long long long long long long long long) NtCreateMailslotFile -@ stub ZwCreateMutant -@ stub ZwCreateNamedPipeFile +@ stdcall ZwCreateMutant(ptr long ptr long) NtCreateMutant +@ stdcall ZwCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr) NtCreateNamedPipeFile @ stdcall ZwCreatePagingFile(long long long long) NtCreatePagingFile @ stdcall ZwCreatePort(ptr ptr long long long) NtCreatePort @ stub ZwCreateProcess @@ -726,7 +726,7 @@ @ stdcall ZwOpenFile(ptr long ptr ptr long long) NtOpenFile @ stub ZwOpenIoCompletion @ stdcall ZwOpenKey(ptr long ptr) NtOpenKey -@ stub ZwOpenMutant +@ stdcall ZwOpenMutant(ptr long ptr) NtOpenMutant @ stub ZwOpenObjectAuditAlarm @ stub ZwOpenProcess @ stdcall ZwOpenProcessToken(long long long) NtOpenProcessToken @@ -758,7 +758,7 @@ @ stub ZwQueryIntervalProfile @ stub ZwQueryIoCompletion @ stdcall ZwQueryKey(long long ptr long ptr) NtQueryKey -@ stub ZwQueryMutant +@ stdcall ZwQueryMutant(long long ptr long ptr) NtQueryMutant @ stdcall ZwQueryObject(long long long long long) NtQueryObject @ stub ZwQueryOpenSubKeys @ stdcall ZwQueryPerformanceCounter (long long) NtQueryPerformanceCounter @@ -781,7 +781,7 @@ @ stdcall ZwReadVirtualMemory(long ptr ptr long ptr) NtReadVirtualMemory @ stub ZwRegisterNewDevice @ stdcall ZwRegisterThreadTerminatePort(ptr) NtRegisterThreadTerminatePort -@ stub ZwReleaseMutant +@ stdcall ZwReleaseMutant(long ptr) NtReleaseMutant @ stub ZwReleaseProcessMutant @ stdcall ZwReleaseSemaphore(long long ptr) NtReleaseSemaphore @ stub ZwRemoveIoCompletion diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 6b4fe325ffe..324cdf9ce86 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -71,17 +71,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK access, IN const OBJECT_ATTRIBUTES *attr OPTIONAL, - IN ULONG InitialCount, - IN ULONG MaximumCount ) + IN LONG InitialCount, + IN LONG MaximumCount ) { DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - if ((MaximumCount <= 0) || (InitialCount > MaximumCount)) + if (MaximumCount <= 0 || InitialCount < 0 || InitialCount > MaximumCount) return STATUS_INVALID_PARAMETER; + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; SERVER_START_REQ( create_semaphore ) { + req->access = access; req->initial = InitialCount; req->max = MaximumCount; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); @@ -103,6 +105,8 @@ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle, DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + SERVER_START_REQ( open_semaphore ) { req->access = access; @@ -167,8 +171,11 @@ NTSTATUS WINAPI NtCreateEvent( DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + SERVER_START_REQ( create_event ) { + req->access = DesiredAccess; req->manual_reset = ManualReset; req->initial_state = InitialState; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); @@ -192,6 +199,8 @@ NTSTATUS WINAPI NtOpenEvent( DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + SERVER_START_REQ( open_event ) { req->access = DesiredAccess; @@ -293,6 +302,94 @@ NTSTATUS WINAPI NtQueryEvent ( return STATUS_SUCCESS; } +/* + * Mutants (known as Mutexes in Kernel32) + */ + +/****************************************************************************** + * NtCreateMutant [NTDLL.@] + * ZwCreateMutant [NTDLL.@] + */ +NTSTATUS WINAPI NtCreateMutant(OUT HANDLE* MutantHandle, + IN ACCESS_MASK access, + IN const OBJECT_ATTRIBUTES* attr OPTIONAL, + IN BOOLEAN InitialOwner) +{ + NTSTATUS status; + DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; + + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + + SERVER_START_REQ( create_mutex ) + { + req->access = access; + req->owned = InitialOwner; + req->inherit = attr && (attr->Attributes & OBJ_INHERIT); + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + status = wine_server_call( req ); + *MutantHandle = reply->handle; + } + SERVER_END_REQ; + return status; +} + +/************************************************************************** + * NtOpenMutant [NTDLL.@] + * ZwOpenMutant [NTDLL.@] + */ +NTSTATUS WINAPI NtOpenMutant(OUT HANDLE* MutantHandle, + IN ACCESS_MASK access, + IN const OBJECT_ATTRIBUTES* attr ) +{ + NTSTATUS status; + DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; + + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + + SERVER_START_REQ( open_mutex ) + { + req->access = access; + req->inherit = attr && (attr->Attributes & OBJ_INHERIT); + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + status = wine_server_call( req ); + *MutantHandle = reply->handle; + } + SERVER_END_REQ; + return status; +} + +/************************************************************************** + * NtReleaseMutant [NTDLL.@] + * ZwReleaseMutant [NTDLL.@] + */ +NTSTATUS WINAPI NtReleaseMutant( IN HANDLE handle, OUT PLONG prev_count OPTIONAL) +{ + NTSTATUS status; + + SERVER_START_REQ( release_mutex ) + { + req->handle = handle; + status = wine_server_call( req ); + if (prev_count) *prev_count = reply->prev_count; + } + SERVER_END_REQ; + return status; +} + +/****************************************************************** + * NtQueryMutant [NTDLL.@] + * ZwQueryMutant [NTDLL.@] + */ +NTSTATUS WINAPI NtQueryMutant(IN HANDLE handle, + IN MUTANT_INFORMATION_CLASS MutantInformationClass, + OUT PVOID MutantInformation, + IN ULONG MutantInformationLength, + OUT PULONG ResultLength OPTIONAL ) +{ + FIXME("(%p %u %p %lu %p): stub!\n", + handle, MutantInformationClass, MutantInformation, MutantInformationLength, ResultLength); + return STATUS_NOT_IMPLEMENTED; +} /* * Timers @@ -304,20 +401,23 @@ NTSTATUS WINAPI NtQueryEvent ( */ NTSTATUS WINAPI NtCreateTimer(OUT HANDLE *handle, IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES *oa OPTIONAL, + IN const OBJECT_ATTRIBUTES *attr OPTIONAL, IN TIMER_TYPE timer_type) { - DWORD len = (oa && oa->ObjectName) ? oa->ObjectName->Length : 0; + DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0; NTSTATUS status; + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + if (timer_type != NotificationTimer && timer_type != SynchronizationTimer) return STATUS_INVALID_PARAMETER; SERVER_START_REQ( create_timer ) { + req->access = access; req->manual = (timer_type == NotificationTimer) ? TRUE : FALSE; - req->inherit = oa && (oa->Attributes & OBJ_INHERIT); - if (len) wine_server_add_data( req, oa->ObjectName->Buffer, len ); + req->inherit = attr && (attr->Attributes & OBJ_INHERIT); + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); status = wine_server_call( req ); *handle = reply->handle; } @@ -332,19 +432,18 @@ NTSTATUS WINAPI NtCreateTimer(OUT HANDLE *handle, */ NTSTATUS WINAPI NtOpenTimer(OUT PHANDLE handle, IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES* oa ) + IN const OBJECT_ATTRIBUTES* attr ) { - DWORD len = (oa && oa->ObjectName) ? oa->ObjectName->Length : 0; - NTSTATUS status; + DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0; + NTSTATUS status; - if (oa && oa->Length >= MAX_PATH * sizeof(WCHAR)) - return STATUS_NAME_TOO_LONG; + if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; SERVER_START_REQ( open_timer ) { req->access = access; - req->inherit = oa && (oa->Attributes & OBJ_INHERIT); - if (len) wine_server_add_data( req, oa->ObjectName->Buffer, len ); + req->inherit = attr && (attr->Attributes & OBJ_INHERIT); + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); status = wine_server_call( req ); *handle = reply->handle; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 192cfacd582..987dee1bc3b 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -620,6 +620,7 @@ struct select_reply struct create_event_request { struct request_header __header; + unsigned int access; int manual_reset; int initial_state; int inherit; @@ -664,6 +665,7 @@ struct open_event_reply struct create_mutex_request { struct request_header __header; + unsigned int access; int owned; int inherit; /* VARARG(name,unicode_str); */ @@ -684,6 +686,7 @@ struct release_mutex_request struct release_mutex_reply { struct reply_header __header; + unsigned int prev_count; }; @@ -706,6 +709,7 @@ struct open_mutex_reply struct create_semaphore_request { struct request_header __header; + unsigned int access; unsigned int initial; unsigned int max; int inherit; @@ -1869,6 +1873,7 @@ struct set_registry_notification_reply struct create_timer_request { struct request_header __header; + unsigned int access; int inherit; int manual; /* VARARG(name,unicode_str); */ @@ -3643,6 +3648,6 @@ union generic_reply struct set_global_windows_reply set_global_windows_reply; }; -#define SERVER_PROTOCOL_VERSION 150 +#define SERVER_PROTOCOL_VERSION 151 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/include/winternl.h b/include/winternl.h index 0094bee0c9e..e65d929bada 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -621,6 +621,19 @@ typedef enum MemoryBasicInformation = 0 } MEMORY_INFORMATION_CLASS; +typedef enum _MUTANT_INFORMATION_CLASS +{ + MutantBasicInformation +} MUTANT_INFORMATION_CLASS, *PMUTANT_INFORMATION_CLASS; + +typedef struct _MUTANT_BASIC_INFORMATION { + LONG CurrentCount; + BOOLEAN OwnedByCaller; + BOOLEAN AbandonedState; +} MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION; + + + /* return type of RtlDetermineDosPathNameType_U (FIXME: not the correct names) */ typedef enum { @@ -1312,9 +1325,10 @@ NTSTATUS WINAPI NtCreateEvent(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES *,BOO NTSTATUS WINAPI NtCreateFile(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG); NTSTATUS WINAPI NtCreateIoCompletion(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,ULONG); NTSTATUS WINAPI NtCreateKey(PHKEY,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,const UNICODE_STRING*,ULONG,PULONG); +NTSTATUS WINAPI NtCreateMutant(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,BOOLEAN); NTSTATUS WINAPI NtCreateNamedPipeFile(PHANDLE,ULONG,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,PLARGE_INTEGER); NTSTATUS WINAPI NtCreateSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const LARGE_INTEGER*,ULONG,ULONG,HANDLE); -NTSTATUS WINAPI NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,ULONG); +NTSTATUS WINAPI NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,LONG,LONG); NTSTATUS WINAPI NtCreateTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*, TIMER_TYPE); NTSTATUS WINAPI NtDelayExecution(BOOLEAN,const LARGE_INTEGER*); NTSTATUS WINAPI NtDeleteFile(POBJECT_ATTRIBUTES); @@ -1342,8 +1356,10 @@ NTSTATUS WINAPI NtOpenEvent(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES *); NTSTATUS WINAPI NtOpenFile(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG); NTSTATUS WINAPI NtOpenIoCompletion(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); NTSTATUS WINAPI NtOpenKey(PHKEY,ACCESS_MASK,const OBJECT_ATTRIBUTES *); +NTSTATUS WINAPI NtOpenMutant(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSTATUS WINAPI NtOpenProcessToken(HANDLE,DWORD,HANDLE *); NTSTATUS WINAPI NtOpenSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*); +NTSTATUS WINAPI NtOpenSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSTATUS WINAPI NtOpenThread(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const CLIENT_ID*); NTSTATUS WINAPI NtOpenThreadToken(HANDLE,DWORD,BOOLEAN,HANDLE *); NTSTATUS WINAPI NtOpenTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*); @@ -1373,6 +1389,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULON void WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL); NTSTATUS WINAPI NtReadFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,PLARGE_INTEGER,PULONG); NTSTATUS WINAPI NtReadVirtualMemory(HANDLE,const void*,void*,SIZE_T,SIZE_T*); +NTSTATUS WINAPI NtReleaseMutant(HANDLE,PLONG); NTSTATUS WINAPI NtReleaseSemaphore(HANDLE,ULONG,PULONG); NTSTATUS WINAPI NtRemoveIoCompletion(HANDLE,PULONG,PULONG,PIO_STATUS_BLOCK,PLARGE_INTEGER); NTSTATUS WINAPI NtReplaceKey(POBJECT_ATTRIBUTES,HKEY,POBJECT_ATTRIBUTES); diff --git a/server/event.c b/server/event.c index bc1b5a4c6bf..e1487d3062c 100644 --- a/server/event.c +++ b/server/event.c @@ -132,7 +132,7 @@ DECL_HANDLER(create_event) if ((event = create_event( get_req_data(), get_req_data_size(), req->manual_reset, req->initial_state ))) { - reply->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, event, req->access, req->inherit ); release_object( event ); } } diff --git a/server/mutex.c b/server/mutex.c index 1bb07eb0cdd..af13dd9ee80 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -156,7 +156,7 @@ DECL_HANDLER(create_mutex) reply->handle = 0; if ((mutex = create_mutex( get_req_data(), get_req_data_size(), req->owned ))) { - reply->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, mutex, req->access, req->inherit ); release_object( mutex ); } } @@ -177,7 +177,11 @@ DECL_HANDLER(release_mutex) MUTEX_MODIFY_STATE, &mutex_ops ))) { if (!mutex->count || (mutex->owner != current)) set_error( STATUS_MUTANT_NOT_OWNED ); - else if (!--mutex->count) do_release( mutex ); + else + { + reply->prev_count = mutex->count; + if (!--mutex->count) do_release( mutex ); + } release_object( mutex ); } } diff --git a/server/protocol.def b/server/protocol.def index e4b8e98f23d..7f21d4bfb8d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -491,6 +491,7 @@ enum apc_type { APC_NONE, APC_USER, APC_TIMER, APC_ASYNC, APC_ASYNC_IO }; /* Create an event */ @REQ(create_event) + unsigned int access; /* wanted access rights */ int manual_reset; /* manual reset event */ int initial_state; /* initial state of the event */ int inherit; /* inherit flag */ @@ -519,6 +520,7 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; /* Create a mutex */ @REQ(create_mutex) + unsigned int access; /* wanted access rights */ int owned; /* initially owned? */ int inherit; /* inherit flag */ VARARG(name,unicode_str); /* object name */ @@ -530,6 +532,8 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; /* Release a mutex */ @REQ(release_mutex) obj_handle_t handle; /* handle to the mutex */ +@REPLY + unsigned int prev_count; /* value of internal counter, before release */ @END @@ -545,6 +549,7 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; /* Create a semaphore */ @REQ(create_semaphore) + unsigned int access; /* wanted access rights */ unsigned int initial; /* initial count */ unsigned int max; /* maximum count */ int inherit; /* inherit flag */ @@ -1337,6 +1342,7 @@ enum char_info_mode /* Create a waitable timer */ @REQ(create_timer) + unsigned int access; /* wanted access rights */ int inherit; /* inherit flag */ int manual; /* manual reset */ VARARG(name,unicode_str); /* object name */ diff --git a/server/semaphore.c b/server/semaphore.c index 599ce6808ad..27aba0d6f7b 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -139,7 +139,7 @@ DECL_HANDLER(create_semaphore) if ((sem = create_semaphore( get_req_data(), get_req_data_size(), req->initial, req->max ))) { - reply->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, sem, req->access, req->inherit ); release_object( sem ); } } diff --git a/server/timer.c b/server/timer.c index bc7eb4598b6..ef07f2a04d1 100644 --- a/server/timer.c +++ b/server/timer.c @@ -204,7 +204,7 @@ DECL_HANDLER(create_timer) reply->handle = 0; if ((timer = create_timer( get_req_data(), get_req_data_size(), req->manual ))) { - reply->handle = alloc_handle( current->process, timer, TIMER_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, timer, req->access, req->inherit ); release_object( timer ); } } diff --git a/server/trace.c b/server/trace.c index 99c20f58992..8e458b29569 100644 --- a/server/trace.c +++ b/server/trace.c @@ -752,6 +752,7 @@ static void dump_select_request( const struct select_request *req ) static void dump_create_event_request( const struct create_event_request *req ) { + fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " manual_reset=%d,", req->manual_reset ); fprintf( stderr, " initial_state=%d,", req->initial_state ); fprintf( stderr, " inherit=%d,", req->inherit ); @@ -785,6 +786,7 @@ static void dump_open_event_reply( const struct open_event_reply *req ) static void dump_create_mutex_request( const struct create_mutex_request *req ) { + fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " owned=%d,", req->owned ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); @@ -801,6 +803,11 @@ static void dump_release_mutex_request( const struct release_mutex_request *req fprintf( stderr, " handle=%p", req->handle ); } +static void dump_release_mutex_reply( const struct release_mutex_reply *req ) +{ + fprintf( stderr, " prev_count=%08x", req->prev_count ); +} + static void dump_open_mutex_request( const struct open_mutex_request *req ) { fprintf( stderr, " access=%08x,", req->access ); @@ -816,6 +823,7 @@ static void dump_open_mutex_reply( const struct open_mutex_reply *req ) static void dump_create_semaphore_request( const struct create_semaphore_request *req ) { + fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " initial=%08x,", req->initial ); fprintf( stderr, " max=%08x,", req->max ); fprintf( stderr, " inherit=%d,", req->inherit ); @@ -1633,6 +1641,7 @@ static void dump_set_registry_notification_request( const struct set_registry_no static void dump_create_timer_request( const struct create_timer_request *req ) { + fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " manual=%d,", req->manual ); fprintf( stderr, " name=" ); @@ -2765,7 +2774,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)0, (dump_func)dump_open_event_reply, (dump_func)dump_create_mutex_reply, - (dump_func)0, + (dump_func)dump_release_mutex_reply, (dump_func)dump_open_mutex_reply, (dump_func)dump_create_semaphore_reply, (dump_func)dump_release_semaphore_reply,