diff --git a/reactos/include/ddk/kefuncs.h b/reactos/include/ddk/kefuncs.h index 28280c76491..266c5187aef 100644 --- a/reactos/include/ddk/kefuncs.h +++ b/reactos/include/ddk/kefuncs.h @@ -125,6 +125,9 @@ NTSTATUS STDCALL KeInitializeInterrupt(PKINTERRUPT InterruptObject, KAFFINITY ProcessorEnableMask, BOOLEAN FloatingSave); +VOID STDCALL KeInitializeMutant(IN PKMUTANT Mutant, + IN BOOLEAN InitialOwner); + VOID STDCALL KeInitializeMutex (PKMUTEX Mutex, ULONG Level); @@ -228,6 +231,9 @@ KeReadStateEvent ( PKEVENT Event ); +LONG STDCALL +KeReadStateMutant(IN PKMUTANT Mutant); + LONG STDCALL KeReadStateMutex ( @@ -256,6 +262,15 @@ KeRegisterBugCheckCallback ( PUCHAR Component ); +LONG +STDCALL +KeReleaseMutant( + IN PKMUTANT Mutant, + ULONG Param2, + ULONG Param3, + IN BOOLEAN Wait + ); + LONG STDCALL KeReleaseMutex ( diff --git a/reactos/include/ddk/zwtypes.h b/reactos/include/ddk/zwtypes.h index 5229ba71b95..4ed56327645 100644 --- a/reactos/include/ddk/zwtypes.h +++ b/reactos/include/ddk/zwtypes.h @@ -143,6 +143,21 @@ typedef struct _ATOM_TABLE_INFORMATION } ATOM_TABLE_INFORMATION, *PATOM_TABLE_INFORMATION; +// mutant information + +typedef enum _MUTANT_INFORMATION_CLASS +{ + MutantBasicInformation = 0 +} MUTANT_INFORMATION_CLASS; + +typedef struct _MUTANT_BASIC_INFORMATION +{ + LONG Count; + BOOLEAN Owned; + BOOLEAN Abandoned; +} MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION; + + // semaphore information typedef enum _SEMAPHORE_INFORMATION_CLASS diff --git a/reactos/ntoskrnl/ke/mutex.c b/reactos/ntoskrnl/ke/mutex.c index d6280abe128..b2c24cc70e5 100644 --- a/reactos/ntoskrnl/ke/mutex.c +++ b/reactos/ntoskrnl/ke/mutex.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: mutex.c,v 1.8 2001/04/09 02:45:04 dwelch Exp $ +/* $Id: mutex.c,v 1.9 2001/11/04 00:17:24 ekohl Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/mutex.c @@ -36,25 +36,28 @@ /* FUNCTIONS *****************************************************************/ -VOID STDCALL -KeInitializeMutex (PKMUTEX Mutex, - ULONG Level) +VOID STDCALL +KeInitializeMutex(IN PKMUTEX Mutex, + IN ULONG Level) { - KeInitializeDispatcherHeader(&Mutex->Header, - InternalMutexType, - sizeof(KMUTEX) / sizeof(ULONG), - 1); + KeInitializeDispatcherHeader(&Mutex->Header, + InternalMutexType, + sizeof(KMUTEX) / sizeof(ULONG), + 1); + Mutex->OwnerThread = NULL; + Mutex->Abandoned = FALSE; + Mutex->ApcDisable = 1; } -LONG STDCALL -KeReadStateMutex (PKMUTEX Mutex) +LONG STDCALL +KeReadStateMutex(IN PKMUTEX Mutex) { - return(Mutex->Header.SignalState); + return(Mutex->Header.SignalState); } -LONG STDCALL -KeReleaseMutex (PKMUTEX Mutex, - BOOLEAN Wait) +LONG STDCALL +KeReleaseMutex(IN PKMUTEX Mutex, + IN BOOLEAN Wait) { KeAcquireDispatcherDatabaseLock(Wait); Mutex->Header.SignalState++; @@ -67,14 +70,58 @@ KeReleaseMutex (PKMUTEX Mutex, return(0); } -NTSTATUS STDCALL -KeWaitForMutexObject (PKMUTEX Mutex, - KWAIT_REASON WaitReason, - KPROCESSOR_MODE WaitMode, - BOOLEAN Alertable, - PLARGE_INTEGER Timeout) +NTSTATUS STDCALL +KeWaitForMutexObject(PKMUTEX Mutex, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout) { - return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout)); + return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout)); +} + + +VOID STDCALL +KeInitializeMutant(IN PKMUTANT Mutant, + IN BOOLEAN InitialOwner) +{ + KeInitializeDispatcherHeader(&Mutant->Header, + InternalMutexType, + sizeof(KMUTANT) / sizeof(ULONG), + 1); + if (InitialOwner == TRUE) + { + Mutant->OwnerThread = KeGetCurrentThread(); + } + else + { + Mutant->OwnerThread = NULL; + } + Mutant->Abandoned = FALSE; + Mutant->ApcDisable = 0; +} + +LONG STDCALL +KeReadStateMutant(IN PKMUTANT Mutant) +{ + return(Mutant->Header.SignalState); +} + +LONG STDCALL +KeReleaseMutant(IN PKMUTANT Mutant, + ULONG Param2, + ULONG Param3, + IN BOOLEAN Wait) +{ + KeAcquireDispatcherDatabaseLock(Wait); + Mutant->Header.SignalState++; + assert(Mutant->Header.SignalState <= 1); + if (Mutant->Header.SignalState == 1) + { + KeDispatcherObjectWake(&Mutant->Header); + } + KeReleaseDispatcherDatabaseLock(Wait); + return(0); } /* EOF */ diff --git a/reactos/ntoskrnl/nt/mutant.c b/reactos/ntoskrnl/nt/mutant.c index 432fddc70d3..a0726377be8 100644 --- a/reactos/ntoskrnl/nt/mutant.c +++ b/reactos/ntoskrnl/nt/mutant.c @@ -1,3 +1,21 @@ +/* + * ReactOS kernel + * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -10,59 +28,195 @@ /* INCLUDES *****************************************************************/ +#include #include +#include +#include #include +POBJECT_TYPE ExMutantObjectType = NULL; + +static GENERIC_MAPPING ExpMutantMapping = { + STANDARD_RIGHTS_READ | SYNCHRONIZE | MUTANT_QUERY_STATE, + STANDARD_RIGHTS_WRITE | SYNCHRONIZE, + STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE, + MUTANT_ALL_ACCESS}; + /* FUNCTIONS *****************************************************************/ -NTSTATUS -STDCALL -NtCreateMutant ( - OUT PHANDLE MutantHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN BOOLEAN InitialOwner - ) + +NTSTATUS STDCALL +NtpCreateMutant(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) { - UNIMPLEMENTED; + DPRINT("NtpCreateEvent(ObjectBody %x, Parent %x, RemainingPath %S)\n", + ObjectBody, Parent, RemainingPath); + + if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL) + { + return(STATUS_UNSUCCESSFUL); + } + + if (Parent != NULL && RemainingPath != NULL) + { + ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1); + } + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL -NtOpenMutant ( - OUT PHANDLE MutantHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes - ) +VOID STDCALL +NtpDeleteMutant(PVOID ObjectBody) { - UNIMPLEMENTED; + KeReleaseMutant((PKMUTANT)ObjectBody, + 0, + 0, + FALSE); } -NTSTATUS -STDCALL -NtQueryMutant ( - IN HANDLE MutantHandle, - IN CINT MutantInformationClass, - OUT PVOID MutantInformation, - IN ULONG Length, - OUT PULONG ResultLength - ) +VOID +NtInitializeMutantImplementation(VOID) { - UNIMPLEMENTED; + ExMutantObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); + + RtlCreateUnicodeString(&ExMutantObjectType->TypeName, L"Mutant"); + + ExMutantObjectType->Tag = TAG('M', 'T', 'N', 'T'); + ExMutantObjectType->MaxObjects = ULONG_MAX; + ExMutantObjectType->MaxHandles = ULONG_MAX; + ExMutantObjectType->TotalObjects = 0; + ExMutantObjectType->TotalHandles = 0; + ExMutantObjectType->PagedPoolCharge = 0; + ExMutantObjectType->NonpagedPoolCharge = sizeof(KMUTANT); + ExMutantObjectType->Mapping = &ExpMutantMapping; + ExMutantObjectType->Dump = NULL; + ExMutantObjectType->Open = NULL; + ExMutantObjectType->Close = NULL; + ExMutantObjectType->Delete = NtpDeleteMutant; + ExMutantObjectType->Parse = NULL; + ExMutantObjectType->Security = NULL; + ExMutantObjectType->QueryName = NULL; + ExMutantObjectType->OkayToClose = NULL; + ExMutantObjectType->Create = NtpCreateMutant; } -NTSTATUS -STDCALL -NtReleaseMutant ( - IN HANDLE MutantHandle, - IN PULONG ReleaseCount OPTIONAL - ) +NTSTATUS STDCALL +NtCreateMutant(OUT PHANDLE MutantHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN InitialOwner) { - UNIMPLEMENTED; + PKMUTEX Mutant; + NTSTATUS Status; + + Status = ObCreateObject(MutantHandle, + DesiredAccess, + ObjectAttributes, + ExMutantObjectType, + (PVOID*)&Mutant); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + KeInitializeMutant(Mutant, + InitialOwner); + ObDereferenceObject(Mutant); + + return(STATUS_SUCCESS); +} + + +NTSTATUS STDCALL +NtOpenMutant(OUT PHANDLE MutantHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) +{ + return(ObOpenObjectByName(ObjectAttributes, + ExMutantObjectType, + NULL, + UserMode, + DesiredAccess, + NULL, + MutantHandle)); +} + + +NTSTATUS STDCALL +NtQueryMutant(IN HANDLE MutantHandle, + IN CINT MutantInformationClass, + OUT PVOID MutantInformation, + IN ULONG Length, + OUT PULONG ResultLength) +{ + PMUTANT_BASIC_INFORMATION Info; + PKMUTANT Mutant; + NTSTATUS Status; + + Info = (PMUTANT_BASIC_INFORMATION)MutantInformation; + + if (MutantInformationClass > MutantBasicInformation) + return(STATUS_INVALID_INFO_CLASS); + + if (Length < sizeof(MUTANT_BASIC_INFORMATION)) + return(STATUS_INFO_LENGTH_MISMATCH); + + Status = ObReferenceObjectByHandle(MutantHandle, + MUTANT_QUERY_STATE, + ExMutantObjectType, + UserMode, + (PVOID*)&Mutant, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Info->Count = KeReadStateMutant(Mutant); + Info->Owned = (Mutant->OwnerThread != NULL); + Info->Abandoned = Mutant->Abandoned; + + ObDereferenceObject(Mutant); + + return(STATUS_SUCCESS); +} + + +NTSTATUS STDCALL +NtReleaseMutant(IN HANDLE MutantHandle, + IN PULONG ReleaseCount OPTIONAL) +{ + PKMUTANT Mutant; + NTSTATUS Status; + ULONG Count; + + Status = ObReferenceObjectByHandle(MutantHandle, + MUTANT_ALL_ACCESS, + ExMutantObjectType, + UserMode, + (PVOID*)&Mutant, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Count = KeReleaseMutant(Mutant, + 0, + 0, + FALSE); + ObDereferenceObject(Mutant); + + if (ReleaseCount != NULL) + { + *ReleaseCount = Count; + } + + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/ntoskrnl/nt/nt.c b/reactos/ntoskrnl/nt/nt.c index 97a9f23ebb5..3b2b40ea523 100644 --- a/reactos/ntoskrnl/nt/nt.c +++ b/reactos/ntoskrnl/nt/nt.c @@ -1,4 +1,4 @@ -/* $Id: nt.c,v 1.7 2001/03/16 16:05:34 dwelch Exp $ +/* $Id: nt.c,v 1.8 2001/11/04 00:18:40 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -22,6 +22,7 @@ VOID NtInit(VOID) { NtInitializeEventImplementation(); NtInitializeEventPairImplementation(); + NtInitializeMutantImplementation(); NtInitializeSemaphoreImplementation(); NtInitializeTimerImplementation(); NiInitPort(); diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 29f90c2951c..36ed8b246bc 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.def,v 1.117 2001/10/10 22:07:15 hbirr Exp $ +; $Id: ntoskrnl.def,v 1.118 2001/11/04 00:16:13 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -6,16 +6,16 @@ ; EXPORTS CcRosInitializeFileCache@12 -CcMdlReadComplete@8 ;CcRosRequestCacheSegment@20 ;CcRosReleaseCacheSegment@12 CcRosReleaseFileCache@8 CcCopyRead@24 CcCopyWrite@20 CcMapData@24 +CcMdlReadComplete@8 CcSetDirtyPinnedData@8 -CcUnpinData@4 CcSetFileSizes@8 +CcUnpinData@4 DbgBreakPoint@0 DbgBreakPointWithStatus@4 ;DbgLoadImageSymbols@12 @@ -352,7 +352,7 @@ KeInitializeDeviceQueue@4 KeInitializeDpc@12 KeInitializeEvent@12 KeInitializeInterrupt@44 -;KeInitializeMutant@8 +KeInitializeMutant@8 KeInitializeMutex@8 ;KeInitializeQueue KeInitializeSemaphore@12 @@ -377,13 +377,13 @@ KeQueryTickCount@4 KeQueryTimeIncrement@0 ;KeRaiseUserException KeReadStateEvent@4 -;KeReadStateMutant +KeReadStateMutant@4 KeReadStateMutex@4 ;KeReadStateQueue KeReadStateSemaphore@4 KeReadStateTimer@4 KeRegisterBugCheckCallback@20 -;KeReleaseMutant +KeReleaseMutant@16 KeReleaseMutex@8 KeReleaseSemaphore@16 KeReleaseSpinLockFromDpcLevel@4 diff --git a/reactos/ntoskrnl/ntoskrnl.edf b/reactos/ntoskrnl/ntoskrnl.edf index 9c00c018d3e..18f4fdd9820 100644 --- a/reactos/ntoskrnl/ntoskrnl.edf +++ b/reactos/ntoskrnl/ntoskrnl.edf @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.edf,v 1.103 2001/10/10 22:07:15 hbirr Exp $ +; $Id: ntoskrnl.edf,v 1.104 2001/11/04 00:16:13 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -352,7 +352,7 @@ KeInitializeDeviceQueue=KeInitializeDeviceQueue@4 KeInitializeDpc=KeInitializeDpc@12 KeInitializeEvent=KeInitializeEvent@12 KeInitializeInterrupt=KeInitializeInterrupt@44 -;KeInitializeMutant +KeInitializeMutant=KeInitializeMutant@8 KeInitializeMutex=KeInitializeMutex@8 ;KeInitializeQueue KeInitializeSemaphore=KeInitializeSemaphore@12 @@ -377,13 +377,13 @@ KeQueryTickCount=KeQueryTickCount@4 KeQueryTimeIncrement=KeQueryTimeIncrement@0 ;KeRaiseUserException KeReadStateEvent=KeReadStateEvent@4 -;KeReadStateMutant +KeReadStateMutant=KeReadStateMutant@4 KeReadStateMutex=KeReadStateMutex@4 ;KeReadStateQueue KeReadStateSemaphore=KeReadStateSemaphore@4 KeReadStateTimer=KeReadStateTimer@4 KeRegisterBugCheckCallback=KeRegisterBugCheckCallback@20 -;KeReleaseMutant +KeReleaseMutant=KeReleaseMutant@16 KeReleaseMutex=KeReleaseMutex@8 KeReleaseSemaphore=KeReleaseSemaphore@16 KeReleaseSpinLockFromDpcLevel=KeReleaseSpinLockFromDpcLevel@4