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