If a mutex already exist, open it instead of create.
[reactos.git] / reactos / lib / kernel32 / synch / mutex.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/synch/mutex.c
6 * PURPOSE: Mutex functions
7 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
8 * UPDATE HISTORY:
9 * Created 01/20/2001
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <k32.h>
15
16 #define NDEBUG
17 #include "../include/debug.h"
18
19
20 /* FUNCTIONS *****************************************************************/
21
22 /*
23 * @implemented
24 */
25 HANDLE STDCALL
26 CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes,
27 BOOL bInitialOwner,
28 LPCSTR lpName)
29 {
30 UNICODE_STRING NameU;
31 ANSI_STRING Name;
32 HANDLE Handle;
33
34 if (lpName != NULL)
35 {
36 RtlInitAnsiString(&Name,
37 (LPSTR)lpName);
38
39 RtlAnsiStringToUnicodeString(&NameU,
40 &Name,
41 TRUE);
42 }
43
44 Handle = CreateMutexW(lpMutexAttributes,
45 bInitialOwner,
46 (lpName ? NameU.Buffer : NULL));
47
48 if (lpName != NULL)
49 {
50 RtlFreeUnicodeString(&NameU);
51 }
52
53 return Handle;
54 }
55
56
57 /*
58 * @implemented
59 */
60 HANDLE STDCALL
61 CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes,
62 BOOL bInitialOwner,
63 LPCWSTR lpName)
64 {
65 OBJECT_ATTRIBUTES ObjectAttributes;
66 NTSTATUS Status;
67 UNICODE_STRING UnicodeName;
68 HANDLE MutantHandle;
69
70 if (lpName != NULL)
71 {
72 RtlInitUnicodeString(&UnicodeName,
73 (LPWSTR)lpName);
74 }
75
76 InitializeObjectAttributes(&ObjectAttributes,
77 (lpName ? &UnicodeName : NULL),
78 0,
79 (lpName ? hBaseDir : NULL),
80 NULL);
81
82 if (lpMutexAttributes != NULL)
83 {
84 ObjectAttributes.SecurityDescriptor = lpMutexAttributes->lpSecurityDescriptor;
85 if (lpMutexAttributes->bInheritHandle)
86 {
87 ObjectAttributes.Attributes |= OBJ_INHERIT;
88 }
89 }
90
91 Status = NtCreateMutant(&MutantHandle,
92 MUTEX_ALL_ACCESS,
93 &ObjectAttributes,
94 (BOOLEAN)bInitialOwner);
95 if (Status == STATUS_OBJECT_NAME_COLLISION)
96 {
97 Status = NtOpenMutant(&MutantHandle,
98 MUTEX_ALL_ACCESS,
99 &ObjectAttributes);
100 if (NT_SUCCESS(Status))
101 {
102 if(bInitialOwner)
103 {
104 WaitForSingleObject(MutantHandle, INFINITE);
105 }
106 SetLastError(ERROR_ALREADY_EXISTS);
107 }
108 }
109 if (!NT_SUCCESS(Status))
110 {
111 SetLastErrorByStatus(Status);
112 return NULL;
113 }
114
115 return MutantHandle;
116 }
117
118
119 /*
120 * @implemented
121 */
122 HANDLE STDCALL
123 OpenMutexA(DWORD dwDesiredAccess,
124 BOOL bInheritHandle,
125 LPCSTR lpName)
126 {
127 OBJECT_ATTRIBUTES ObjectAttributes;
128 UNICODE_STRING NameU;
129 ANSI_STRING Name;
130 HANDLE Handle;
131 NTSTATUS Status;
132
133 if (lpName == NULL)
134 {
135 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
136 return NULL;
137 }
138
139 RtlInitAnsiString(&Name,
140 (LPSTR)lpName);
141 RtlAnsiStringToUnicodeString(&NameU,
142 &Name,
143 TRUE);
144
145 InitializeObjectAttributes(&ObjectAttributes,
146 &NameU,
147 (bInheritHandle ? OBJ_INHERIT : 0),
148 hBaseDir,
149 NULL);
150
151 Status = NtOpenMutant(&Handle,
152 (ACCESS_MASK)dwDesiredAccess,
153 &ObjectAttributes);
154
155 RtlFreeUnicodeString(&NameU);
156
157 if (!NT_SUCCESS(Status))
158 {
159 SetLastErrorByStatus(Status);
160 return NULL;
161 }
162
163 return Handle;
164 }
165
166
167 /*
168 * @implemented
169 */
170 HANDLE STDCALL
171 OpenMutexW(DWORD dwDesiredAccess,
172 BOOL bInheritHandle,
173 LPCWSTR lpName)
174 {
175 OBJECT_ATTRIBUTES ObjectAttributes;
176 UNICODE_STRING Name;
177 HANDLE Handle;
178 NTSTATUS Status;
179
180 if (lpName == NULL)
181 {
182 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
183 return NULL;
184 }
185
186 RtlInitUnicodeString(&Name,
187 (LPWSTR)lpName);
188
189 InitializeObjectAttributes(&ObjectAttributes,
190 &Name,
191 (bInheritHandle ? OBJ_INHERIT : 0),
192 hBaseDir,
193 NULL);
194
195 Status = NtOpenMutant(&Handle,
196 (ACCESS_MASK)dwDesiredAccess,
197 &ObjectAttributes);
198 if (!NT_SUCCESS(Status))
199 {
200 SetLastErrorByStatus(Status);
201 return NULL;
202 }
203
204 return Handle;
205 }
206
207
208 /*
209 * @implemented
210 */
211 BOOL STDCALL
212 ReleaseMutex(HANDLE hMutex)
213 {
214 NTSTATUS Status;
215
216 Status = NtReleaseMutant(hMutex,
217 NULL);
218 if (!NT_SUCCESS(Status))
219 {
220 SetLastErrorByStatus(Status);
221 return FALSE;
222 }
223
224 return TRUE;
225 }
226
227
228 /* EOF */