:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / kernel32 / synch / sem.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/synch/sem.c
6  * PURPOSE:         Semaphore functions
7  * PROGRAMMER:      Eric Kohl (ekohl@rz-online.de)
8  * UPDATE HISTORY:
9  *                  Created 01/20/2001
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <windows.h>
16
17 #define NDEBUG
18 #include <kernel32/kernel32.h>
19 #include <kernel32/error.h>
20
21 /* FUNCTIONS ****************************************************************/
22
23 HANDLE STDCALL
24 CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
25                  LONG lInitialCount,
26                  LONG lMaximumCount,
27                  LPCSTR lpName)
28 {
29    UNICODE_STRING NameU;
30    ANSI_STRING Name;
31    HANDLE Handle;
32
33    RtlInitAnsiString(&Name,
34                      (LPSTR)lpName);
35    RtlAnsiStringToUnicodeString(&NameU,
36                                 &Name,
37                                 TRUE);
38
39    Handle = CreateSemaphoreW(lpSemaphoreAttributes,
40                              lInitialCount,
41                              lMaximumCount,
42                              NameU.Buffer);
43
44    RtlFreeUnicodeString (&NameU);
45
46    return Handle;
47 }
48
49
50 HANDLE STDCALL
51 CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
52                  LONG lInitialCount,
53                  LONG lMaximumCount,
54                  LPCWSTR lpName)
55 {
56    OBJECT_ATTRIBUTES ObjectAttributes;
57    NTSTATUS Status;
58    UNICODE_STRING NameString;
59    HANDLE SemaphoreHandle;
60
61    if (lpName)
62      {
63         NameString.Length = lstrlenW(lpName)*sizeof(WCHAR);
64      }
65    else
66      {
67         NameString.Length = 0;
68      }
69
70    NameString.Buffer = (WCHAR *)lpName;
71    NameString.MaximumLength = NameString.Length;
72
73    ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
74    ObjectAttributes.RootDirectory = hBaseDir;
75    ObjectAttributes.ObjectName = &NameString;
76    ObjectAttributes.Attributes = 0;
77    ObjectAttributes.SecurityDescriptor = NULL;
78    ObjectAttributes.SecurityQualityOfService = NULL;
79    if (lpSemaphoreAttributes != NULL)
80      {
81         ObjectAttributes.SecurityDescriptor = lpSemaphoreAttributes->lpSecurityDescriptor;
82         if (lpSemaphoreAttributes->bInheritHandle == TRUE)
83           {
84              ObjectAttributes.Attributes |= OBJ_INHERIT;
85           }
86      }
87
88    Status = NtCreateSemaphore(&SemaphoreHandle,
89                               SEMAPHORE_ALL_ACCESS,
90                               &ObjectAttributes,
91                               lInitialCount,
92                               lMaximumCount);
93    if (!NT_SUCCESS(Status))
94      {
95         SetLastErrorByStatus(Status);
96         return NULL;
97      }
98    return SemaphoreHandle;
99 }
100
101
102 HANDLE STDCALL
103 OpenSemaphoreA(DWORD dwDesiredAccess,
104                WINBOOL bInheritHandle,
105                LPCSTR lpName)
106 {
107    OBJECT_ATTRIBUTES ObjectAttributes;
108    UNICODE_STRING NameU;
109    ANSI_STRING Name;
110    HANDLE Handle;
111    NTSTATUS Status;
112
113    if (lpName == NULL)
114      {
115         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
116         return NULL;
117      }
118
119    RtlInitAnsiString(&Name,
120                      (LPSTR)lpName);
121    RtlAnsiStringToUnicodeString(&NameU,
122                                 &Name,
123                                 TRUE);
124
125    ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
126    ObjectAttributes.RootDirectory = hBaseDir;
127    ObjectAttributes.ObjectName = &NameU;
128    ObjectAttributes.Attributes = 0;
129    ObjectAttributes.SecurityDescriptor = NULL;
130    ObjectAttributes.SecurityQualityOfService = NULL;
131    if (bInheritHandle == TRUE)
132      {
133         ObjectAttributes.Attributes |= OBJ_INHERIT;
134      }
135
136    Status = NtOpenSemaphore(&Handle,
137                             (ACCESS_MASK)dwDesiredAccess,
138                             &ObjectAttributes);
139
140    RtlFreeUnicodeString(&NameU);
141
142    if (!NT_SUCCESS(Status))
143      {
144         SetLastErrorByStatus(Status);
145         return NULL;
146      }
147
148    return Handle;
149 }
150
151
152 HANDLE STDCALL
153 OpenSemaphoreW(DWORD dwDesiredAccess,
154                WINBOOL bInheritHandle,
155                LPCWSTR lpName)
156 {
157    OBJECT_ATTRIBUTES ObjectAttributes;
158    UNICODE_STRING Name;
159    HANDLE Handle;
160    NTSTATUS Status;
161
162    if (lpName == NULL)
163      {
164         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
165         return NULL;
166      }
167
168    RtlInitUnicodeString(&Name,
169                         (LPWSTR)lpName);
170
171    ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
172    ObjectAttributes.RootDirectory = hBaseDir;
173    ObjectAttributes.ObjectName = &Name;
174    ObjectAttributes.Attributes = 0;
175    ObjectAttributes.SecurityDescriptor = NULL;
176    ObjectAttributes.SecurityQualityOfService = NULL;
177    if (bInheritHandle == TRUE)
178      {
179         ObjectAttributes.Attributes |= OBJ_INHERIT;
180      }
181
182    Status = NtOpenSemaphore(&Handle,
183                             (ACCESS_MASK)dwDesiredAccess,
184                             &ObjectAttributes);
185    if (!NT_SUCCESS(Status))
186      {
187         SetLastErrorByStatus(Status);
188         return NULL;
189      }
190
191    return Handle;
192 }
193
194
195 WINBOOL STDCALL
196 ReleaseSemaphore(HANDLE hSemaphore,
197                  LONG lReleaseCount,
198                  LPLONG lpPreviousCount)
199 {
200    NTSTATUS Status;
201
202    Status = NtReleaseSemaphore(hSemaphore,
203                                lReleaseCount,
204                                lpPreviousCount);
205    if (!NT_SUCCESS(Status))
206      {
207         SetLastErrorByStatus(Status);
208         return FALSE;
209      }
210
211    return TRUE;
212 }
213
214 /* EOF */