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
;
95 PreviousMode
= ExGetPreviousMode();
97 if(PreviousMode
== UserMode
)
101 ProbeForWrite(SemaphoreHandle
,
107 Status
= _SEH_GetExceptionCode();
111 if(!NT_SUCCESS(Status
))
117 Status
= ObCreateObject(PreviousMode
,
118 ExSemaphoreObjectType
,
126 if (NT_SUCCESS(Status
))
128 KeInitializeSemaphore(Semaphore
,
132 Status
= ObInsertObject ((PVOID
)Semaphore
,
139 ObDereferenceObject(Semaphore
);
141 if(NT_SUCCESS(Status
))
145 *SemaphoreHandle
= hSemaphore
;
149 Status
= _SEH_GetExceptionCode();
163 NtOpenSemaphore(OUT PHANDLE SemaphoreHandle
,
164 IN ACCESS_MASK DesiredAccess
,
165 IN POBJECT_ATTRIBUTES ObjectAttributes
)
168 KPROCESSOR_MODE PreviousMode
;
169 NTSTATUS Status
= STATUS_SUCCESS
;
171 PreviousMode
= ExGetPreviousMode();
173 if(PreviousMode
== UserMode
)
177 ProbeForWrite(SemaphoreHandle
,
183 Status
= _SEH_GetExceptionCode();
187 if(!NT_SUCCESS(Status
))
193 Status
= ObOpenObjectByName(ObjectAttributes
,
194 ExSemaphoreObjectType
,
200 if(NT_SUCCESS(Status
))
204 *SemaphoreHandle
= hSemaphore
;
208 Status
= _SEH_GetExceptionCode();
221 NtQuerySemaphore(IN HANDLE SemaphoreHandle
,
222 IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass
,
223 OUT PVOID SemaphoreInformation
,
224 IN ULONG SemaphoreInformationLength
,
225 OUT PULONG ReturnLength OPTIONAL
)
227 PKSEMAPHORE Semaphore
;
228 KPROCESSOR_MODE PreviousMode
;
229 NTSTATUS Status
= STATUS_SUCCESS
;
231 PreviousMode
= ExGetPreviousMode();
233 DefaultQueryInfoBufferCheck(SemaphoreInformationClass
,
234 ExSemaphoreInfoClass
,
235 SemaphoreInformation
,
236 SemaphoreInformationLength
,
240 if(!NT_SUCCESS(Status
))
242 DPRINT1("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
246 Status
= ObReferenceObjectByHandle(SemaphoreHandle
,
247 SEMAPHORE_QUERY_STATE
,
248 ExSemaphoreObjectType
,
252 if(NT_SUCCESS(Status
))
254 switch(SemaphoreInformationClass
)
256 case SemaphoreBasicInformation
:
258 PSEMAPHORE_BASIC_INFORMATION BasicInfo
= (PSEMAPHORE_BASIC_INFORMATION
)SemaphoreInformation
;
262 BasicInfo
->CurrentCount
= KeReadStateSemaphore(Semaphore
);
263 BasicInfo
->MaximumCount
= Semaphore
->Limit
;
265 if(ReturnLength
!= NULL
)
267 *ReturnLength
= sizeof(SEMAPHORE_BASIC_INFORMATION
);
272 Status
= _SEH_GetExceptionCode();
279 Status
= STATUS_NOT_IMPLEMENTED
;
283 ObDereferenceObject(Semaphore
);
294 NtReleaseSemaphore(IN HANDLE SemaphoreHandle
,
295 IN LONG ReleaseCount
,
296 OUT PLONG PreviousCount OPTIONAL
)
298 KPROCESSOR_MODE PreviousMode
;
299 PKSEMAPHORE Semaphore
;
300 NTSTATUS Status
= STATUS_SUCCESS
;
302 PreviousMode
= ExGetPreviousMode();
304 if(PreviousCount
!= NULL
&& PreviousMode
== UserMode
)
308 ProbeForWrite(PreviousCount
,
314 Status
= _SEH_GetExceptionCode();
318 if(!NT_SUCCESS(Status
))
324 Status
= ObReferenceObjectByHandle(SemaphoreHandle
,
325 SEMAPHORE_MODIFY_STATE
,
326 ExSemaphoreObjectType
,
330 if (NT_SUCCESS(Status
))
332 LONG PrevCount
= KeReleaseSemaphore(Semaphore
,
336 ObDereferenceObject(Semaphore
);
338 if(PreviousCount
!= NULL
)
342 *PreviousCount
= PrevCount
;
346 Status
= _SEH_GetExceptionCode();