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