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