Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Win32 semaphores |
| 3 | * |
| 4 | * Copyright 1998 Alexandre Julliard |
| 5 | */ |
| 6 | |
| 7 | #include <assert.h> |
David Luyer | ee517e8 | 1999-02-28 12:27:56 +0000 | [diff] [blame] | 8 | #include <string.h> |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 9 | #include "winerror.h" |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 10 | #include "heap.h" |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 11 | #include "server/request.h" |
| 12 | #include "server.h" |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 13 | |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 14 | |
| 15 | /*********************************************************************** |
| 16 | * CreateSemaphore32A (KERNEL32.174) |
| 17 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 18 | HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 19 | LONG max, LPCSTR name ) |
| 20 | { |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 21 | struct create_semaphore_request req; |
| 22 | struct create_semaphore_reply reply; |
| 23 | int len = name ? strlen(name) + 1 : 0; |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 24 | |
| 25 | /* Check parameters */ |
| 26 | |
| 27 | if ((max <= 0) || (initial < 0) || (initial > max)) |
| 28 | { |
| 29 | SetLastError( ERROR_INVALID_PARAMETER ); |
Alexandre Julliard | 5544387 | 1998-12-31 15:52:06 +0000 | [diff] [blame] | 30 | return 0; |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 31 | } |
| 32 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 33 | req.initial = (unsigned int)initial; |
| 34 | req.max = (unsigned int)max; |
| 35 | req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); |
| 36 | |
| 37 | CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, len ); |
Alexandre Julliard | 3f09ec5 | 1999-02-28 19:25:51 +0000 | [diff] [blame] | 38 | SetLastError(0); |
Alexandre Julliard | 6ebbe3c | 1999-01-01 17:04:00 +0000 | [diff] [blame] | 39 | CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); |
Alexandre Julliard | 5544387 | 1998-12-31 15:52:06 +0000 | [diff] [blame] | 40 | if (reply.handle == -1) return 0; |
Alexandre Julliard | 96c08d8 | 1999-02-28 13:27:56 +0000 | [diff] [blame] | 41 | return reply.handle; |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | |
| 45 | /*********************************************************************** |
| 46 | * CreateSemaphore32W (KERNEL32.175) |
| 47 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 48 | HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial, |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 49 | LONG max, LPCWSTR name ) |
| 50 | { |
| 51 | LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 52 | HANDLE ret = CreateSemaphoreA( sa, initial, max, nameA ); |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 53 | if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); |
| 54 | return ret; |
| 55 | } |
| 56 | |
| 57 | |
| 58 | /*********************************************************************** |
| 59 | * OpenSemaphore32A (KERNEL32.545) |
| 60 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 61 | HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name ) |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 62 | { |
Alexandre Julliard | 5544387 | 1998-12-31 15:52:06 +0000 | [diff] [blame] | 63 | struct open_named_obj_request req; |
| 64 | struct open_named_obj_reply reply; |
| 65 | int len = name ? strlen(name) + 1 : 0; |
| 66 | |
| 67 | req.type = OPEN_SEMAPHORE; |
| 68 | req.access = access; |
| 69 | req.inherit = inherit; |
| 70 | CLIENT_SendRequest( REQ_OPEN_NAMED_OBJ, -1, 2, &req, sizeof(req), name, len ); |
Alexandre Julliard | 6ebbe3c | 1999-01-01 17:04:00 +0000 | [diff] [blame] | 71 | CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); |
Alexandre Julliard | 96c08d8 | 1999-02-28 13:27:56 +0000 | [diff] [blame] | 72 | if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ |
| 73 | return reply.handle; |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | |
| 77 | /*********************************************************************** |
| 78 | * OpenSemaphore32W (KERNEL32.546) |
| 79 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 80 | HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name ) |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 81 | { |
| 82 | LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 83 | HANDLE ret = OpenSemaphoreA( access, inherit, nameA ); |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 84 | if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); |
| 85 | return ret; |
| 86 | } |
| 87 | |
| 88 | |
| 89 | /*********************************************************************** |
| 90 | * ReleaseSemaphore (KERNEL32.583) |
| 91 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 92 | BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous ) |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 93 | { |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 94 | struct release_semaphore_request req; |
Alexandre Julliard | 5544387 | 1998-12-31 15:52:06 +0000 | [diff] [blame] | 95 | struct release_semaphore_reply reply; |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 96 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 97 | if (count < 0) |
| 98 | { |
| 99 | SetLastError( ERROR_INVALID_PARAMETER ); |
| 100 | return FALSE; |
| 101 | } |
Alexandre Julliard | 96c08d8 | 1999-02-28 13:27:56 +0000 | [diff] [blame] | 102 | req.handle = handle; |
| 103 | req.count = (unsigned int)count; |
Alexandre Julliard | 5544387 | 1998-12-31 15:52:06 +0000 | [diff] [blame] | 104 | CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) ); |
Alexandre Julliard | 6ebbe3c | 1999-01-01 17:04:00 +0000 | [diff] [blame] | 105 | if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; |
Alexandre Julliard | 5544387 | 1998-12-31 15:52:06 +0000 | [diff] [blame] | 106 | if (previous) *previous = reply.prev_count; |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 107 | return TRUE; |
| 108 | } |