:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / ntoskrnl / nt / ntsem.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/nt/ntsem.c
6  * PURPOSE:         Synchronization primitives
7  * PROGRAMMER:      David Welch (welch@mcmail.com)
8  * UPDATE HISTORY:
9  *                  Created 22/05/98
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <limits.h>
15 #include <ddk/ntddk.h>
16 #include <ntos/synch.h>
17 #include <internal/pool.h>
18 #include <internal/ps.h>
19
20 #define NDEBUG
21 #include <internal/debug.h>
22
23 /* GLOBALS ******************************************************************/
24
25 POBJECT_TYPE ExSemaphoreType;
26
27 static GENERIC_MAPPING ExSemaphoreMapping = {
28         STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
29         STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
30         STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
31         SEMAPHORE_ALL_ACCESS};
32
33 /* FUNCTIONS *****************************************************************/
34
35 NTSTATUS STDCALL
36 NtpCreateSemaphore(PVOID ObjectBody,
37                    PVOID Parent,
38                    PWSTR RemainingPath,
39                    POBJECT_ATTRIBUTES ObjectAttributes)
40 {
41   DPRINT("NtpCreateSemaphore(ObjectBody %x, Parent %x, RemainingPath %S)\n",
42          ObjectBody, Parent, RemainingPath);
43
44   if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
45     {
46       return(STATUS_UNSUCCESSFUL);
47     }
48
49   return(STATUS_SUCCESS);
50 }
51
52 VOID NtInitializeSemaphoreImplementation(VOID)
53 {
54    ExSemaphoreType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
55    
56    RtlCreateUnicodeString(&ExSemaphoreType->TypeName, L"Semaphore");
57    
58    ExSemaphoreType->Tag = TAG('S', 'E', 'M', 'T');
59    ExSemaphoreType->MaxObjects = ULONG_MAX;
60    ExSemaphoreType->MaxHandles = ULONG_MAX;
61    ExSemaphoreType->TotalObjects = 0;
62    ExSemaphoreType->TotalHandles = 0;
63    ExSemaphoreType->PagedPoolCharge = 0;
64    ExSemaphoreType->NonpagedPoolCharge = sizeof(KSEMAPHORE);
65    ExSemaphoreType->Mapping = &ExSemaphoreMapping;
66    ExSemaphoreType->Dump = NULL;
67    ExSemaphoreType->Open = NULL;
68    ExSemaphoreType->Close = NULL;
69    ExSemaphoreType->Delete = NULL;
70    ExSemaphoreType->Parse = NULL;
71    ExSemaphoreType->Security = NULL;
72    ExSemaphoreType->QueryName = NULL;
73    ExSemaphoreType->OkayToClose = NULL;
74    ExSemaphoreType->Create = NtpCreateSemaphore;
75    ExSemaphoreType->DuplicationNotify = NULL;
76 }
77
78 NTSTATUS STDCALL
79 NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
80                   IN ACCESS_MASK DesiredAccess,
81                   IN POBJECT_ATTRIBUTES ObjectAttributes,
82                   IN LONG InitialCount,
83                   IN LONG MaximumCount)
84 {
85    PKSEMAPHORE Semaphore;
86    NTSTATUS Status;
87    
88    Status = ObCreateObject(SemaphoreHandle,
89                            DesiredAccess,
90                            ObjectAttributes,
91                            ExSemaphoreType,
92                            (PVOID*)&Semaphore);
93    if (!NT_SUCCESS(Status))
94      {
95         return(Status);
96      }
97    KeInitializeSemaphore(Semaphore,
98                          InitialCount,
99                          MaximumCount);
100    ObDereferenceObject(Semaphore);
101    return(STATUS_SUCCESS);
102 }
103
104
105 NTSTATUS STDCALL
106 NtOpenSemaphore(IN HANDLE SemaphoreHandle,
107                 IN ACCESS_MASK  DesiredAccess,
108                 IN POBJECT_ATTRIBUTES ObjectAttributes)
109 {
110    NTSTATUS Status;
111    
112    Status = ObOpenObjectByName(ObjectAttributes,
113                                ExSemaphoreType,
114                                NULL,
115                                UserMode,
116                                DesiredAccess,
117                                NULL,
118                                SemaphoreHandle);
119    
120    return Status;
121 }
122
123
124 NTSTATUS STDCALL
125 NtQuerySemaphore(IN HANDLE SemaphoreHandle,
126                  IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
127                  OUT PVOID SemaphoreInformation,
128                  IN ULONG SemaphoreInformationLength,
129                  OUT PULONG ReturnLength)
130 {
131    PSEMAPHORE_BASIC_INFORMATION Info;
132    PKSEMAPHORE Semaphore;
133    NTSTATUS Status;
134
135    Info = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
136
137    if (SemaphoreInformationClass > SemaphoreBasicInformation)
138      return STATUS_INVALID_INFO_CLASS;
139
140    if (SemaphoreInformationLength < sizeof(SEMAPHORE_BASIC_INFORMATION))
141      return STATUS_INFO_LENGTH_MISMATCH;
142
143    Status = ObReferenceObjectByHandle(SemaphoreHandle,
144                                       SEMAPHORE_QUERY_STATE,
145                                       ExSemaphoreType,
146                                       UserMode,
147                                       (PVOID*)&Semaphore,
148                                       NULL);
149    if (!NT_SUCCESS(Status))
150      return Status;
151
152    Info->CurrentCount = KeReadStateSemaphore(Semaphore);
153    Info->MaximumCount = Semaphore->Limit;
154
155    *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
156
157    ObDereferenceObject(Semaphore);
158
159    return STATUS_SUCCESS;
160 }
161
162 NTSTATUS STDCALL
163 NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
164                    IN LONG ReleaseCount,
165                    OUT PLONG PreviousCount)
166 {
167    PKSEMAPHORE Semaphore;
168    NTSTATUS Status;
169    
170    Status = ObReferenceObjectByHandle(SemaphoreHandle,
171                                       SEMAPHORE_MODIFY_STATE,
172                                       ExSemaphoreType,
173                                       UserMode,
174                                       (PVOID*)&Semaphore,
175                                       NULL);
176    if (!NT_SUCCESS(Status))
177      {
178         return(Status);
179      }
180    KeReleaseSemaphore(Semaphore,
181                       IO_NO_INCREMENT,
182                       ReleaseCount,
183                       FALSE);
184    ObDereferenceObject(Semaphore);
185    return(STATUS_SUCCESS);
186 }
187
188 /* EOF */