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