1 /* $Id: ntsem.c 12779 2005-01-04 04:45:00Z gdalsnes $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/sem.c
6 * PURPOSE: Synchronization primitives
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS ******************************************************************/
19 POBJECT_TYPE ExSemaphoreObjectType
;
21 static GENERIC_MAPPING ExSemaphoreMapping
= {
22 STANDARD_RIGHTS_READ
| SEMAPHORE_QUERY_STATE
,
23 STANDARD_RIGHTS_WRITE
| SEMAPHORE_MODIFY_STATE
,
24 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| SEMAPHORE_QUERY_STATE
,
25 SEMAPHORE_ALL_ACCESS
};
27 static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass
[] =
29 ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
), /* SemaphoreBasicInformation */
32 /* FUNCTIONS *****************************************************************/
35 ExpCreateSemaphore(PVOID ObjectBody
,
38 POBJECT_ATTRIBUTES ObjectAttributes
)
40 DPRINT("NtpCreateSemaphore(ObjectBody %x, Parent %x, RemainingPath %S)\n",
41 ObjectBody
, Parent
, RemainingPath
);
43 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
45 return(STATUS_UNSUCCESSFUL
);
48 return(STATUS_SUCCESS
);
52 ExpInitializeSemaphoreImplementation(VOID
)
54 ExSemaphoreObjectType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
56 RtlpCreateUnicodeString(&ExSemaphoreObjectType
->TypeName
, L
"Semaphore", NonPagedPool
);
58 ExSemaphoreObjectType
->Tag
= TAG('S', 'E', 'M', 'T');
59 ExSemaphoreObjectType
->PeakObjects
= 0;
60 ExSemaphoreObjectType
->PeakHandles
= 0;
61 ExSemaphoreObjectType
->TotalObjects
= 0;
62 ExSemaphoreObjectType
->TotalHandles
= 0;
63 ExSemaphoreObjectType
->PagedPoolCharge
= 0;
64 ExSemaphoreObjectType
->NonpagedPoolCharge
= sizeof(KSEMAPHORE
);
65 ExSemaphoreObjectType
->Mapping
= &ExSemaphoreMapping
;
66 ExSemaphoreObjectType
->Dump
= NULL
;
67 ExSemaphoreObjectType
->Open
= NULL
;
68 ExSemaphoreObjectType
->Close
= NULL
;
69 ExSemaphoreObjectType
->Delete
= NULL
;
70 ExSemaphoreObjectType
->Parse
= NULL
;
71 ExSemaphoreObjectType
->Security
= NULL
;
72 ExSemaphoreObjectType
->QueryName
= NULL
;
73 ExSemaphoreObjectType
->OkayToClose
= NULL
;
74 ExSemaphoreObjectType
->Create
= ExpCreateSemaphore
;
75 ExSemaphoreObjectType
->DuplicationNotify
= NULL
;
77 ObpCreateTypeObject(ExSemaphoreObjectType
);
84 NtCreateSemaphore(OUT PHANDLE SemaphoreHandle
,
85 IN ACCESS_MASK DesiredAccess
,
86 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
90 PKSEMAPHORE Semaphore
;
92 KPROCESSOR_MODE PreviousMode
;
93 NTSTATUS Status
= STATUS_SUCCESS
;
97 PreviousMode
= ExGetPreviousMode();
99 if(PreviousMode
== UserMode
)
103 ProbeForWrite(SemaphoreHandle
,
109 Status
= _SEH_GetExceptionCode();
113 if(!NT_SUCCESS(Status
))
119 Status
= ObCreateObject(PreviousMode
,
120 ExSemaphoreObjectType
,
128 if (NT_SUCCESS(Status
))
130 KeInitializeSemaphore(Semaphore
,
134 Status
= ObInsertObject ((PVOID
)Semaphore
,
141 ObDereferenceObject(Semaphore
);
143 if(NT_SUCCESS(Status
))
147 *SemaphoreHandle
= hSemaphore
;
151 Status
= _SEH_GetExceptionCode();
165 NtOpenSemaphore(OUT PHANDLE SemaphoreHandle
,
166 IN ACCESS_MASK DesiredAccess
,
167 IN POBJECT_ATTRIBUTES ObjectAttributes
)
170 KPROCESSOR_MODE PreviousMode
;
171 NTSTATUS Status
= STATUS_SUCCESS
;
175 PreviousMode
= ExGetPreviousMode();
177 if(PreviousMode
== UserMode
)
181 ProbeForWrite(SemaphoreHandle
,
187 Status
= _SEH_GetExceptionCode();
191 if(!NT_SUCCESS(Status
))
197 Status
= ObOpenObjectByName(ObjectAttributes
,
198 ExSemaphoreObjectType
,
204 if(NT_SUCCESS(Status
))
208 *SemaphoreHandle
= hSemaphore
;
212 Status
= _SEH_GetExceptionCode();
225 NtQuerySemaphore(IN HANDLE SemaphoreHandle
,
226 IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass
,
227 OUT PVOID SemaphoreInformation
,
228 IN ULONG SemaphoreInformationLength
,
229 OUT PULONG ReturnLength OPTIONAL
)
231 PKSEMAPHORE Semaphore
;
232 KPROCESSOR_MODE PreviousMode
;
233 NTSTATUS Status
= STATUS_SUCCESS
;
237 PreviousMode
= ExGetPreviousMode();
239 DefaultQueryInfoBufferCheck(SemaphoreInformationClass
,
240 ExSemaphoreInfoClass
,
241 SemaphoreInformation
,
242 SemaphoreInformationLength
,
246 if(!NT_SUCCESS(Status
))
248 DPRINT1("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
252 Status
= ObReferenceObjectByHandle(SemaphoreHandle
,
253 SEMAPHORE_QUERY_STATE
,
254 ExSemaphoreObjectType
,
258 if(NT_SUCCESS(Status
))
260 switch(SemaphoreInformationClass
)
262 case SemaphoreBasicInformation
:
264 PSEMAPHORE_BASIC_INFORMATION BasicInfo
= (PSEMAPHORE_BASIC_INFORMATION
)SemaphoreInformation
;
268 BasicInfo
->CurrentCount
= KeReadStateSemaphore(Semaphore
);
269 BasicInfo
->MaximumCount
= Semaphore
->Limit
;
271 if(ReturnLength
!= NULL
)
273 *ReturnLength
= sizeof(SEMAPHORE_BASIC_INFORMATION
);
278 Status
= _SEH_GetExceptionCode();
285 Status
= STATUS_NOT_IMPLEMENTED
;
289 ObDereferenceObject(Semaphore
);
300 NtReleaseSemaphore(IN HANDLE SemaphoreHandle
,
301 IN LONG ReleaseCount
,
302 OUT PLONG PreviousCount OPTIONAL
)
304 KPROCESSOR_MODE PreviousMode
;
305 PKSEMAPHORE Semaphore
;
306 NTSTATUS Status
= STATUS_SUCCESS
;
310 PreviousMode
= ExGetPreviousMode();
312 if(PreviousCount
!= NULL
&& PreviousMode
== UserMode
)
316 ProbeForWrite(PreviousCount
,
322 Status
= _SEH_GetExceptionCode();
326 if(!NT_SUCCESS(Status
))
332 Status
= ObReferenceObjectByHandle(SemaphoreHandle
,
333 SEMAPHORE_MODIFY_STATE
,
334 ExSemaphoreObjectType
,
338 if (NT_SUCCESS(Status
))
340 LONG PrevCount
= KeReleaseSemaphore(Semaphore
,
344 ObDereferenceObject(Semaphore
);
346 if(PreviousCount
!= NULL
)
350 *PreviousCount
= PrevCount
;
354 Status
= _SEH_GetExceptionCode();