12c4e4e02bb2fe479fabaaefe6ae6cd5d8b692c3
[reactos.git] / reactos / ntoskrnl / nt / mutant.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /*
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)
25 * UPDATE HISTORY:
26 * Created 22/05/98
27 */
28
29 /* INCLUDES *****************************************************************/
30
31 #include <limits.h>
32 #define NTOS_MODE_KERNEL
33 #include <ntos.h>
34 #include <ntos/synch.h>
35 #include <internal/ob.h>
36
37 #define NDEBUG
38 #include <internal/debug.h>
39
40 POBJECT_TYPE ExMutantObjectType = NULL;
41
42 static GENERIC_MAPPING ExpMutantMapping = {
43 STANDARD_RIGHTS_READ | SYNCHRONIZE | MUTANT_QUERY_STATE,
44 STANDARD_RIGHTS_WRITE | SYNCHRONIZE,
45 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
46 MUTANT_ALL_ACCESS};
47
48 /* FUNCTIONS *****************************************************************/
49
50
51 NTSTATUS STDCALL
52 NtpCreateMutant(PVOID ObjectBody,
53 PVOID Parent,
54 PWSTR RemainingPath,
55 POBJECT_ATTRIBUTES ObjectAttributes)
56 {
57 DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
58 ObjectBody, Parent, RemainingPath);
59
60 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
61 {
62 return(STATUS_UNSUCCESSFUL);
63 }
64
65 return(STATUS_SUCCESS);
66 }
67
68
69 VOID STDCALL
70 NtpDeleteMutant(PVOID ObjectBody)
71 {
72 DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody);
73
74 KeReleaseMutant((PKMUTANT)ObjectBody,
75 MUTANT_INCREMENT,
76 TRUE,
77 FALSE);
78 }
79
80
81 VOID INIT_FUNCTION
82 NtInitializeMutantImplementation(VOID)
83 {
84 ExMutantObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
85
86 RtlCreateUnicodeString(&ExMutantObjectType->TypeName, L"Mutant");
87
88 ExMutantObjectType->Tag = TAG('M', 'T', 'N', 'T');
89 ExMutantObjectType->MaxObjects = ULONG_MAX;
90 ExMutantObjectType->MaxHandles = ULONG_MAX;
91 ExMutantObjectType->TotalObjects = 0;
92 ExMutantObjectType->TotalHandles = 0;
93 ExMutantObjectType->PagedPoolCharge = 0;
94 ExMutantObjectType->NonpagedPoolCharge = sizeof(KMUTANT);
95 ExMutantObjectType->Mapping = &ExpMutantMapping;
96 ExMutantObjectType->Dump = NULL;
97 ExMutantObjectType->Open = NULL;
98 ExMutantObjectType->Close = NULL;
99 ExMutantObjectType->Delete = NtpDeleteMutant;
100 ExMutantObjectType->Parse = NULL;
101 ExMutantObjectType->Security = NULL;
102 ExMutantObjectType->QueryName = NULL;
103 ExMutantObjectType->OkayToClose = NULL;
104 ExMutantObjectType->Create = NtpCreateMutant;
105 ExMutantObjectType->DuplicationNotify = NULL;
106
107 ObpCreateTypeObject(ExMutantObjectType);
108 }
109
110
111 NTSTATUS STDCALL
112 NtCreateMutant(OUT PHANDLE MutantHandle,
113 IN ACCESS_MASK DesiredAccess,
114 IN POBJECT_ATTRIBUTES ObjectAttributes,
115 IN BOOLEAN InitialOwner)
116 {
117 PKMUTEX Mutant;
118 NTSTATUS Status;
119
120 Status = ObCreateObject(ExGetPreviousMode(),
121 ExMutantObjectType,
122 ObjectAttributes,
123 ExGetPreviousMode(),
124 NULL,
125 sizeof(KMUTANT),
126 0,
127 0,
128 (PVOID*)&Mutant);
129 if (!NT_SUCCESS(Status))
130 {
131 return(Status);
132 }
133
134 KeInitializeMutant(Mutant,
135 InitialOwner);
136
137 Status = ObInsertObject ((PVOID)Mutant,
138 NULL,
139 DesiredAccess,
140 0,
141 NULL,
142 MutantHandle);
143
144 ObDereferenceObject(Mutant);
145
146 return Status;
147 }
148
149
150 NTSTATUS STDCALL
151 NtOpenMutant(OUT PHANDLE MutantHandle,
152 IN ACCESS_MASK DesiredAccess,
153 IN POBJECT_ATTRIBUTES ObjectAttributes)
154 {
155 return(ObOpenObjectByName(ObjectAttributes,
156 ExMutantObjectType,
157 NULL,
158 ExGetPreviousMode(),
159 DesiredAccess,
160 NULL,
161 MutantHandle));
162 }
163
164
165 NTSTATUS STDCALL
166 NtQueryMutant(IN HANDLE MutantHandle,
167 IN CINT MutantInformationClass,
168 OUT PVOID MutantInformation,
169 IN ULONG Length,
170 OUT PULONG ResultLength)
171 {
172 PMUTANT_BASIC_INFORMATION Info;
173 PKMUTANT Mutant;
174 NTSTATUS Status;
175
176 Info = (PMUTANT_BASIC_INFORMATION)MutantInformation;
177
178 if (MutantInformationClass > MutantBasicInformation)
179 return(STATUS_INVALID_INFO_CLASS);
180
181 if (Length < sizeof(MUTANT_BASIC_INFORMATION))
182 return(STATUS_INFO_LENGTH_MISMATCH);
183
184 Status = ObReferenceObjectByHandle(MutantHandle,
185 MUTANT_QUERY_STATE,
186 ExMutantObjectType,
187 ExGetPreviousMode(),
188 (PVOID*)&Mutant,
189 NULL);
190 if (!NT_SUCCESS(Status))
191 {
192 return(Status);
193 }
194
195 Info->Count = KeReadStateMutant(Mutant);
196 Info->Owned = (Mutant->OwnerThread != NULL);
197 Info->Abandoned = Mutant->Abandoned;
198
199 ObDereferenceObject(Mutant);
200
201 return(STATUS_SUCCESS);
202 }
203
204
205 NTSTATUS STDCALL
206 NtReleaseMutant(IN HANDLE MutantHandle,
207 IN PULONG ReleaseCount OPTIONAL)
208 {
209 PKMUTANT Mutant;
210 NTSTATUS Status;
211 ULONG Count;
212
213 Status = ObReferenceObjectByHandle(MutantHandle,
214 MUTANT_ALL_ACCESS,
215 ExMutantObjectType,
216 ExGetPreviousMode(),
217 (PVOID*)&Mutant,
218 NULL);
219 if (!NT_SUCCESS(Status))
220 {
221 return(Status);
222 }
223
224 Count = KeReleaseMutant(Mutant,
225 MUTANT_INCREMENT,
226 0,
227 FALSE);
228 ObDereferenceObject(Mutant);
229
230 if (ReleaseCount != NULL)
231 {
232 *ReleaseCount = Count;
233 }
234
235 return(STATUS_SUCCESS);
236 }
237
238 /* EOF */