3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/nt/mutant.c
23 * PURPOSE: Synchronization primitives
24 * PROGRAMMER: David Welch (welch@cwcom.net)
29 /* INCLUDES *****************************************************************/
32 #include <ddk/ntddk.h>
33 #include <ntos/synch.h>
36 #include <internal/debug.h>
38 POBJECT_TYPE ExMutantObjectType
= NULL
;
40 static GENERIC_MAPPING ExpMutantMapping
= {
41 STANDARD_RIGHTS_READ
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
42 STANDARD_RIGHTS_WRITE
| SYNCHRONIZE
,
43 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
46 /* FUNCTIONS *****************************************************************/
50 NtpCreateMutant(PVOID ObjectBody
,
53 POBJECT_ATTRIBUTES ObjectAttributes
)
55 DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
56 ObjectBody
, Parent
, RemainingPath
);
58 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
60 return(STATUS_UNSUCCESSFUL
);
63 return(STATUS_SUCCESS
);
68 NtpDeleteMutant(PVOID ObjectBody
)
70 DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody
);
72 KeReleaseMutant((PKMUTANT
)ObjectBody
,
80 NtInitializeMutantImplementation(VOID
)
82 ExMutantObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
84 RtlCreateUnicodeString(&ExMutantObjectType
->TypeName
, L
"Mutant");
86 ExMutantObjectType
->Tag
= TAG('M', 'T', 'N', 'T');
87 ExMutantObjectType
->MaxObjects
= ULONG_MAX
;
88 ExMutantObjectType
->MaxHandles
= ULONG_MAX
;
89 ExMutantObjectType
->TotalObjects
= 0;
90 ExMutantObjectType
->TotalHandles
= 0;
91 ExMutantObjectType
->PagedPoolCharge
= 0;
92 ExMutantObjectType
->NonpagedPoolCharge
= sizeof(KMUTANT
);
93 ExMutantObjectType
->Mapping
= &ExpMutantMapping
;
94 ExMutantObjectType
->Dump
= NULL
;
95 ExMutantObjectType
->Open
= NULL
;
96 ExMutantObjectType
->Close
= NULL
;
97 ExMutantObjectType
->Delete
= NtpDeleteMutant
;
98 ExMutantObjectType
->Parse
= NULL
;
99 ExMutantObjectType
->Security
= NULL
;
100 ExMutantObjectType
->QueryName
= NULL
;
101 ExMutantObjectType
->OkayToClose
= NULL
;
102 ExMutantObjectType
->Create
= NtpCreateMutant
;
103 ExMutantObjectType
->DuplicationNotify
= NULL
;
108 NtCreateMutant(OUT PHANDLE MutantHandle
,
109 IN ACCESS_MASK DesiredAccess
,
110 IN POBJECT_ATTRIBUTES ObjectAttributes
,
111 IN BOOLEAN InitialOwner
)
116 Status
= ObCreateObject(MutantHandle
,
121 if (!NT_SUCCESS(Status
))
125 KeInitializeMutant(Mutant
,
127 ObDereferenceObject(Mutant
);
129 return(STATUS_SUCCESS
);
134 NtOpenMutant(OUT PHANDLE MutantHandle
,
135 IN ACCESS_MASK DesiredAccess
,
136 IN POBJECT_ATTRIBUTES ObjectAttributes
)
138 return(ObOpenObjectByName(ObjectAttributes
,
149 NtQueryMutant(IN HANDLE MutantHandle
,
150 IN CINT MutantInformationClass
,
151 OUT PVOID MutantInformation
,
153 OUT PULONG ResultLength
)
155 PMUTANT_BASIC_INFORMATION Info
;
159 Info
= (PMUTANT_BASIC_INFORMATION
)MutantInformation
;
161 if (MutantInformationClass
> MutantBasicInformation
)
162 return(STATUS_INVALID_INFO_CLASS
);
164 if (Length
< sizeof(MUTANT_BASIC_INFORMATION
))
165 return(STATUS_INFO_LENGTH_MISMATCH
);
167 Status
= ObReferenceObjectByHandle(MutantHandle
,
173 if (!NT_SUCCESS(Status
))
178 Info
->Count
= KeReadStateMutant(Mutant
);
179 Info
->Owned
= (Mutant
->OwnerThread
!= NULL
);
180 Info
->Abandoned
= Mutant
->Abandoned
;
182 ObDereferenceObject(Mutant
);
184 return(STATUS_SUCCESS
);
189 NtReleaseMutant(IN HANDLE MutantHandle
,
190 IN PULONG ReleaseCount OPTIONAL
)
196 Status
= ObReferenceObjectByHandle(MutantHandle
,
202 if (!NT_SUCCESS(Status
))
207 Count
= KeReleaseMutant(Mutant
,
211 ObDereferenceObject(Mutant
);
213 if (ReleaseCount
!= NULL
)
215 *ReleaseCount
= Count
;
218 return(STATUS_SUCCESS
);