ReactOS 0.4.16-dev-306-g647d351
sem.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/ex/sem.c
5 * PURPOSE: Semaphore Implementation
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Thomas Weidenmueller
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16#if defined (ALLOC_PRAGMA)
17#pragma alloc_text(INIT, ExpInitializeSemaphoreImplementation)
18#endif
19
20/* GLOBALS ******************************************************************/
21
23
25{
30};
31
33{
34 /* SemaphoreBasicInformation */
36};
37
38/* FUNCTIONS *****************************************************************/
39
40CODE_SEG("INIT")
44{
45 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
48 DPRINT("Creating Semaphore Object Type\n");
49
50 /* Create the Event Pair Object Type */
51 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
52 RtlInitUnicodeString(&Name, L"Semaphore");
53 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
54 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KSEMAPHORE);
55 ObjectTypeInitializer.GenericMapping = ExSemaphoreMapping;
56 ObjectTypeInitializer.PoolType = NonPagedPool;
57 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
58 ObjectTypeInitializer.ValidAccessMask = SEMAPHORE_ALL_ACCESS;
59 Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExSemaphoreObjectType);
60 if (!NT_SUCCESS(Status)) return FALSE;
61 return TRUE;
62}
63
64/*
65 * @implemented
66 */
72 IN LONG InitialCount,
74{
75 PKSEMAPHORE Semaphore;
76 HANDLE hSemaphore;
79 PAGED_CODE();
80
81 /* Check if we were called from user-mode */
83 {
84 /* Enter SEH Block */
86 {
87 /* Check handle pointer */
88 ProbeForWriteHandle(SemaphoreHandle);
89 }
91 {
92 /* Return the exception code */
94 }
96 }
97
98 /* Make sure the counts make sense */
99 if ((MaximumCount <= 0) ||
100 (InitialCount < 0) ||
101 (InitialCount > MaximumCount))
102 {
103 DPRINT("Invalid Count Data!\n");
105 }
106
107 /* Create the Semaphore Object */
112 NULL,
113 sizeof(KSEMAPHORE),
114 0,
115 0,
116 (PVOID*)&Semaphore);
117
118 /* Check for Success */
119 if (NT_SUCCESS(Status))
120 {
121 /* Initialize it */
122 KeInitializeSemaphore(Semaphore,
123 InitialCount,
125
126 /* Insert it into the Object Tree */
127 Status = ObInsertObject((PVOID)Semaphore,
128 NULL,
130 0,
131 NULL,
132 &hSemaphore);
133
134 /* Check for success */
135 if (NT_SUCCESS(Status))
136 {
137 /* Enter SEH Block for return */
139 {
140 /* Return the handle */
141 *SemaphoreHandle = hSemaphore;
142 }
144 {
145 /* Get the exception code */
147 }
148 _SEH2_END;
149 }
150 }
151
152 /* Return Status */
153 return Status;
154}
155
156/*
157 * @implemented
158 */
160NTAPI
164{
165 HANDLE hSemaphore;
168 PAGED_CODE();
169
170 /* Check if we were called from user-mode */
172 {
173 /* Enter SEH Block */
175 {
176 /* Check handle pointer */
177 ProbeForWriteHandle(SemaphoreHandle);
178 }
180 {
181 /* Return the exception code */
183 }
184 _SEH2_END;
185 }
186
187 /* Open the Object */
191 NULL,
193 NULL,
194 &hSemaphore);
195
196 /* Check for success */
197 if (NT_SUCCESS(Status))
198 {
199 /* Enter SEH Block for return */
201 {
202 /* Return the handle */
203 *SemaphoreHandle = hSemaphore;
204 }
206 {
207 /* Get the exception code */
209 }
210 _SEH2_END;
211 }
212
213 /* Return Status */
214 return Status;
215}
216
217/*
218 * @implemented
219 */
221NTAPI
222NtQuerySemaphore(IN HANDLE SemaphoreHandle,
223 IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
224 OUT PVOID SemaphoreInformation,
225 IN ULONG SemaphoreInformationLength,
227{
228 PKSEMAPHORE Semaphore;
231 PAGED_CODE();
232
233 /* Check buffers and class validity */
234 Status = DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
236 sizeof(ExSemaphoreInfoClass) /
237 sizeof(ExSemaphoreInfoClass[0]),
239 SemaphoreInformation,
240 SemaphoreInformationLength,
242 NULL,
244 if (!NT_SUCCESS(Status))
245 {
246 /* Invalid buffers */
247 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
248 return Status;
249 }
250
251 /* Get the Object */
252 Status = ObReferenceObjectByHandle(SemaphoreHandle,
256 (PVOID*)&Semaphore,
257 NULL);
258
259 /* Check for success */
260 if (NT_SUCCESS(Status))
261 {
262 /* Entry SEH Block */
264 {
266 (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
267
268 /* Return the basic information */
269 BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
270 BasicInfo->MaximumCount = Semaphore->Limit;
271
272 /* Return the length */
273 if (ReturnLength) *ReturnLength = sizeof(*BasicInfo);
274 }
276 {
277 /* Get the exception code */
279 }
280 _SEH2_END;
281
282 /* Dereference the Object */
283 ObDereferenceObject(Semaphore);
284 }
285
286 /* Return status */
287 return Status;
288}
289
290/*
291 * @implemented
292 */
294NTAPI
296 IN LONG ReleaseCount,
297 OUT PLONG PreviousCount OPTIONAL)
298{
300 PKSEMAPHORE Semaphore;
302 PAGED_CODE();
303
304 /* Check if we were called from user-mode */
305 if ((PreviousCount) && (PreviousMode != KernelMode))
306 {
307 /* Entry SEH Block */
309 {
310 /* Make sure the state pointer is valid */
311 ProbeForWriteLong(PreviousCount);
312 }
314 {
315 /* Return the exception code */
317 }
318 _SEH2_END;
319 }
320
321 /* Make sure count makes sense */
322 if (ReleaseCount <= 0)
323 {
324 DPRINT("Invalid Release Count\n");
326 }
327
328 /* Get the Object */
329 Status = ObReferenceObjectByHandle(SemaphoreHandle,
333 (PVOID*)&Semaphore,
334 NULL);
335
336 /* Check for success */
337 if (NT_SUCCESS(Status))
338 {
339 /* Enter SEH Block */
341 {
342 /* Release the semaphore */
343 LONG PrevCount = KeReleaseSemaphore(Semaphore,
345 ReleaseCount,
346 FALSE);
347
348 /* Return the old count if requested */
349 if (PreviousCount) *PreviousCount = PrevCount;
350 }
352 {
353 /* Get the exception code */
355 }
356 _SEH2_END;
357
358 /* Dereference the Semaphore */
359 ObDereferenceObject(Semaphore);
360 }
361
362 /* Return Status */
363 return Status;
364}
365
366/* EOF */
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExGetPreviousMode
Definition: ex.h:140
Status
Definition: gdiplustypes.h:25
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define ICIF_QUERY
Definition: icif.h:18
#define IQS_SAME(Type, Alignment, Flags)
Definition: icif.h:37
#define ICIF_PROBE_READ_WRITE
Definition: icif.h:24
#define OBJ_OPENLINK
Definition: winternl.h:230
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define SEMAPHORE_QUERY_STATE
Definition: security.c:57
#define KernelMode
Definition: asm.h:34
struct _SEMAPHORE_BASIC_INFORMATION * PSEMAPHORE_BASIC_INFORMATION
enum _SEMAPHORE_INFORMATION_CLASS SEMAPHORE_INFORMATION_CLASS
#define SYNCHRONIZE
Definition: nt_native.h:61
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67
static __inline NTSTATUS DefaultQueryInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ ULONG Flags, _In_opt_ PVOID Buffer, _In_ ULONG BufferLength, _In_opt_ PULONG ReturnLength, _In_opt_ PULONG_PTR ReturnLengthPtr, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtQuery*** system call is invoked from...
Definition: probe.h:219
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
long LONG
Definition: pedump.c:60
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define ProbeForWriteLong(Ptr)
Definition: probe.h:37
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
NTSTATUS NTAPI NtOpenSemaphore(OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: sem.c:161
BOOLEAN NTAPI ExpInitializeSemaphoreImplementation(VOID)
Definition: sem.c:43
NTSTATUS NTAPI NtQuerySemaphore(IN HANDLE SemaphoreHandle, IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass, OUT PVOID SemaphoreInformation, IN ULONG SemaphoreInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: sem.c:222
static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[]
Definition: sem.c:32
NTSTATUS NTAPI NtCreateSemaphore(OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN LONG InitialCount, IN LONG MaximumCount)
Definition: sem.c:69
NTSTATUS NTAPI NtReleaseSemaphore(IN HANDLE SemaphoreHandle, IN LONG ReleaseCount, OUT PLONG PreviousCount OPTIONAL)
Definition: sem.c:295
GENERIC_MAPPING ExSemaphoreMapping
Definition: sem.c:24
POBJECT_TYPE ExSemaphoreObjectType
Definition: sem.c:22
LONG NTAPI KeReadStateSemaphore(IN PKSEMAPHORE Semaphore)
Definition: semphobj.c:41
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
LONG Limit
Definition: ketypes.h:817
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
#define SEMAPHORE_MODIFY_STATE
Definition: winbase.h:162
#define SEMAPHORE_ALL_ACCESS
Definition: winbase.h:161
#define IO_NO_INCREMENT
Definition: iotypes.h:598
*Count PHARDWARE_COUNTER _In_ ULONG MaximumCount
Definition: kefuncs.h:1369
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
struct _KSEMAPHORE KSEMAPHORE
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103