Added two macros, ICOM_VFIELD and ICOM_VTBL, so that when implementing
[wine] / scheduler / semaphore.c
1 /*
2  * Win32 semaphores
3  *
4  * Copyright 1998 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <string.h>
9 #include "winerror.h"
10 #include "heap.h"
11 #include "server.h"
12
13
14 /***********************************************************************
15  *           CreateSemaphore32A   (KERNEL32.174)
16  */
17 HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name )
18 {
19     struct create_semaphore_request *req = get_req_buffer();
20
21     /* Check parameters */
22
23     if ((max <= 0) || (initial < 0) || (initial > max))
24     {
25         SetLastError( ERROR_INVALID_PARAMETER );
26         return 0;
27     }
28
29     req->initial = (unsigned int)initial;
30     req->max     = (unsigned int)max;
31     req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
32     lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
33     SetLastError(0);
34     server_call( REQ_CREATE_SEMAPHORE );
35     if (req->handle == -1) return 0;
36     return req->handle;
37 }
38
39
40 /***********************************************************************
41  *           CreateSemaphore32W   (KERNEL32.175)
42  */
43 HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial,
44                                     LONG max, LPCWSTR name )
45 {
46     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
47     HANDLE ret = CreateSemaphoreA( sa, initial, max, nameA );
48     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
49     return ret;
50 }
51
52
53 /***********************************************************************
54  *           OpenSemaphore32A   (KERNEL32.545)
55  */
56 HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name )
57 {
58     struct open_semaphore_request *req = get_req_buffer();
59
60     req->access  = access;
61     req->inherit = inherit;
62     lstrcpynA( req->name, name ? name : "", server_remaining(req->name) );
63     server_call( REQ_OPEN_SEMAPHORE );
64     if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
65     return req->handle;
66 }
67
68
69 /***********************************************************************
70  *           OpenSemaphore32W   (KERNEL32.546)
71  */
72 HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name )
73 {
74     LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
75     HANDLE ret = OpenSemaphoreA( access, inherit, nameA );
76     if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
77     return ret;
78 }
79
80
81 /***********************************************************************
82  *           ReleaseSemaphore   (KERNEL32.583)
83  */
84 BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous )
85 {
86     struct release_semaphore_request *req = get_req_buffer();
87
88     if (count < 0)
89     {
90         SetLastError( ERROR_INVALID_PARAMETER );
91         return FALSE;
92     }
93     req->handle = handle;
94     req->count  = (unsigned int)count;
95     if (server_call( REQ_RELEASE_SEMAPHORE )) return FALSE;
96     if (previous) *previous = req->prev_count;
97     return TRUE;
98 }