4 * Copyright 1998 Alexandre Julliard
14 #include "server/request.h"
22 static void SEMAPHORE_Destroy( K32OBJ
*obj
);
24 const K32OBJ_OPS SEMAPHORE_Ops
=
26 SEMAPHORE_Destroy
/* destroy */
30 /***********************************************************************
31 * CreateSemaphore32A (KERNEL32.174)
33 HANDLE32 WINAPI
CreateSemaphore32A( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
34 LONG max
, LPCSTR name
)
36 struct create_semaphore_request req
;
37 struct create_semaphore_reply reply
;
38 int len
= name
? strlen(name
) + 1 : 0;
42 /* Check parameters */
44 if ((max
<= 0) || (initial
< 0) || (initial
> max
))
46 SetLastError( ERROR_INVALID_PARAMETER
);
50 req
.initial
= (unsigned int)initial
;
51 req
.max
= (unsigned int)max
;
52 req
.inherit
= (sa
&& (sa
->nLength
>=sizeof(*sa
)) && sa
->bInheritHandle
);
54 CLIENT_SendRequest( REQ_CREATE_SEMAPHORE
, -1, 2, &req
, sizeof(req
), name
, len
);
55 CLIENT_WaitReply( &len
, NULL
, 1, &reply
, sizeof(reply
) );
56 CHECK_LEN( len
, sizeof(reply
) );
57 if (reply
.handle
== -1) return 0;
60 sem
= (SEMAPHORE
*)K32OBJ_Create( K32OBJ_SEMAPHORE
, sizeof(*sem
),
61 name
, reply
.handle
, SEMAPHORE_ALL_ACCESS
,
63 if (sem
) K32OBJ_DecCount( &sem
->header
);
65 if (handle
== INVALID_HANDLE_VALUE32
) handle
= 0;
70 /***********************************************************************
71 * CreateSemaphore32W (KERNEL32.175)
73 HANDLE32 WINAPI
CreateSemaphore32W( SECURITY_ATTRIBUTES
*sa
, LONG initial
,
74 LONG max
, LPCWSTR name
)
76 LPSTR nameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
77 HANDLE32 ret
= CreateSemaphore32A( sa
, initial
, max
, nameA
);
78 if (nameA
) HeapFree( GetProcessHeap(), 0, nameA
);
83 /***********************************************************************
84 * OpenSemaphore32A (KERNEL32.545)
86 HANDLE32 WINAPI
OpenSemaphore32A( DWORD access
, BOOL32 inherit
, LPCSTR name
)
90 struct open_named_obj_request req
;
91 struct open_named_obj_reply reply
;
92 int len
= name
? strlen(name
) + 1 : 0;
94 req
.type
= OPEN_SEMAPHORE
;
96 req
.inherit
= inherit
;
97 CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ
, -1, 2, &req
, sizeof(req
), name
, len
);
98 CLIENT_WaitReply( &len
, NULL
, 1, &reply
, sizeof(reply
) );
99 CHECK_LEN( len
, sizeof(reply
) );
100 if (reply
.handle
!= -1)
103 if ((obj
= K32OBJ_FindNameType( name
, K32OBJ_SEMAPHORE
)) != NULL
)
105 handle
= HANDLE_Alloc( PROCESS_Current(), obj
, access
, inherit
, reply
.handle
);
106 K32OBJ_DecCount( obj
);
107 if (handle
== INVALID_HANDLE_VALUE32
)
108 handle
= 0; /* must return 0 on failure, not -1 */
110 else CLIENT_CloseHandle( reply
.handle
);
117 /***********************************************************************
118 * OpenSemaphore32W (KERNEL32.546)
120 HANDLE32 WINAPI
OpenSemaphore32W( DWORD access
, BOOL32 inherit
, LPCWSTR name
)
122 LPSTR nameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
123 HANDLE32 ret
= OpenSemaphore32A( access
, inherit
, nameA
);
124 if (nameA
) HeapFree( GetProcessHeap(), 0, nameA
);
129 /***********************************************************************
130 * ReleaseSemaphore (KERNEL32.583)
132 BOOL32 WINAPI
ReleaseSemaphore( HANDLE32 handle
, LONG count
, LONG
*previous
)
134 struct release_semaphore_request req
;
135 struct release_semaphore_reply reply
;
140 SetLastError( ERROR_INVALID_PARAMETER
);
143 req
.handle
= HANDLE_GetServerHandle( PROCESS_Current(), handle
,
144 K32OBJ_SEMAPHORE
, SEMAPHORE_MODIFY_STATE
);
145 if (req
.handle
== -1) return FALSE
;
146 req
.count
= (unsigned int)count
;
147 CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE
, -1, 1, &req
, sizeof(req
) );
148 if (CLIENT_WaitReply( &len
, NULL
, 1, &reply
, sizeof(reply
) )) return FALSE
;
149 CHECK_LEN( len
, sizeof(reply
) );
150 if (previous
) *previous
= reply
.prev_count
;
155 /***********************************************************************
158 static void SEMAPHORE_Destroy( K32OBJ
*obj
)
160 SEMAPHORE
*sem
= (SEMAPHORE
*)obj
;
161 assert( obj
->type
== K32OBJ_SEMAPHORE
);
162 /* There cannot be any thread on the list since the ref count is 0 */
163 obj
->type
= K32OBJ_UNKNOWN
;
164 HeapFree( SystemHeap
, 0, sem
);