Improved mutex and event functions
authorArmin Novak <armin.novak@thincast.com>
Thu, 7 Feb 2019 15:43:55 +0000 (16:43 +0100)
committerArmin Novak <armin.novak@thincast.com>
Fri, 5 Apr 2019 07:14:35 +0000 (09:14 +0200)
* Added name for debugging to handle.
* Implemented *Ex functions

winpr/include/winpr/synch.h
winpr/libwinpr/synch/event.c
winpr/libwinpr/synch/mutex.c
winpr/libwinpr/synch/synch.h

index 05f7601..a94061d 100644 (file)
@@ -40,15 +40,20 @@ extern "C" {
 #ifndef _WIN32
 
 /* Mutex */
+#define CREATE_MUTEX_INITIAL_OWNER 0x00000001
 
-WINPR_API HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName);
-WINPR_API HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName);
+WINPR_API HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner,
+                              LPCSTR lpName);
+WINPR_API HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner,
+                              LPCWSTR lpName);
 
-WINPR_API HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCTSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess);
-WINPR_API HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess);
+WINPR_API HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName,
+                                DWORD dwFlags, DWORD dwDesiredAccess);
+WINPR_API HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName,
+                                DWORD dwFlags, DWORD dwDesiredAccess);
 
-WINPR_API HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle,LPCSTR lpName);
-WINPR_API HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle,LPCWSTR lpName);
+WINPR_API HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName);
+WINPR_API HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName);
 
 WINPR_API BOOL ReleaseMutex(HANDLE hMutex);
 
@@ -64,8 +69,10 @@ WINPR_API BOOL ReleaseMutex(HANDLE hMutex);
 
 /* Semaphore */
 
-WINPR_API HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName);
-WINPR_API HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName);
+WINPR_API HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount,
+                                  LONG lMaximumCount, LPCSTR lpName);
+WINPR_API HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount,
+                                  LONG lMaximumCount, LPCWSTR lpName);
 
 WINPR_API HANDLE OpenSemaphoreA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName);
 WINPR_API HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName);
@@ -81,12 +88,18 @@ WINPR_API HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCW
 WINPR_API BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount);
 
 /* Event */
+#define CREATE_EVENT_MANUAL_RESET 0x00000001
+#define CREATE_EVENT_INITIAL_SET  0x00000002
 
-WINPR_API HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName);
-WINPR_API HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName);
+WINPR_API HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
+                              BOOL bInitialState, LPCSTR lpName);
+WINPR_API HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
+                              BOOL bInitialState, LPCWSTR lpName);
 
-WINPR_API HANDLE CreateEventExA(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess);
-WINPR_API HANDLE CreateEventExW(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess);
+WINPR_API HANDLE CreateEventExA(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName,
+                                DWORD dwFlags, DWORD dwDesiredAccess);
+WINPR_API HANDLE CreateEventExW(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName,
+                                DWORD dwFlags, DWORD dwDesiredAccess);
 
 WINPR_API HANDLE OpenEventA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName);
 WINPR_API HANDLE OpenEventW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName);
@@ -150,10 +163,13 @@ typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
 typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;
 
 WINPR_API VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
-WINPR_API BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
-WINPR_API BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);
+WINPR_API BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount,
+        DWORD Flags);
+WINPR_API BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection,
+        DWORD dwSpinCount);
 
-WINPR_API DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);
+WINPR_API DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection,
+        DWORD dwSpinCount);
 
 WINPR_API VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
 WINPR_API BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
@@ -172,7 +188,8 @@ WINPR_API DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable);
 WINPR_API VOID WakeByAddressAll(PVOID Address);
 WINPR_API VOID WakeByAddressSingle(PVOID Address);
 
-WINPR_API BOOL WaitOnAddress(VOID volatile *Address, PVOID CompareAddress, SIZE_T AddressSize, DWORD dwMilliseconds);
+WINPR_API BOOL WaitOnAddress(VOID volatile* Address, PVOID CompareAddress, SIZE_T AddressSize,
+                             DWORD dwMilliseconds);
 
 /* Wait */
 
@@ -191,10 +208,13 @@ WINPR_API BOOL WaitOnAddress(VOID volatile *Address, PVOID CompareAddress, SIZE_
 
 WINPR_API DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
 WINPR_API DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable);
-WINPR_API DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);
-WINPR_API DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable);
+WINPR_API DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll,
+                                       DWORD dwMilliseconds);
+WINPR_API DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll,
+        DWORD dwMilliseconds, BOOL bAlertable);
 
-WINPR_API DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable);
+WINPR_API DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn,
+                                    DWORD dwMilliseconds, BOOL bAlertable);
 
 /* Waitable Timer */
 
@@ -219,22 +239,29 @@ typedef struct _REASON_CONTEXT
        } Reason;
 } REASON_CONTEXT, *PREASON_CONTEXT;
 
-typedef VOID (*PTIMERAPCROUTINE)(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue);
+typedef VOID (*PTIMERAPCROUTINE)(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue,
+                                 DWORD dwTimerHighValue);
 
-WINPR_API HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCSTR lpTimerName);
-WINPR_API HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCWSTR lpTimerName);
+WINPR_API HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset,
+                                      LPCSTR lpTimerName);
+WINPR_API HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset,
+                                      LPCWSTR lpTimerName);
 
-WINPR_API HANDLE CreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess);
-WINPR_API HANDLE CreateWaitableTimerExW(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess);
+WINPR_API HANDLE CreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCSTR lpTimerName,
+                                        DWORD dwFlags, DWORD dwDesiredAccess);
+WINPR_API HANDLE CreateWaitableTimerExW(LPSECURITY_ATTRIBUTES lpTimerAttributes,
+                                        LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess);
 
 WINPR_API BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod,
-               PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume);
+                                PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume);
 
 WINPR_API BOOL SetWaitableTimerEx(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod,
-               PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay);
+                                  PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext,
+                                  ULONG TolerableDelay);
 
 WINPR_API HANDLE OpenWaitableTimerA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpTimerName);
-WINPR_API HANDLE OpenWaitableTimerW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpTimerName);
+WINPR_API HANDLE OpenWaitableTimerW(DWORD dwDesiredAccess, BOOL bInheritHandle,
+                                    LPCWSTR lpTimerName);
 
 WINPR_API BOOL CancelWaitableTimer(HANDLE hTimer);
 
@@ -270,7 +297,7 @@ WINPR_API BOOL DeleteTimerQueue(HANDLE TimerQueue);
 WINPR_API BOOL DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent);
 
 WINPR_API BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue,
-               WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags);
+                                     WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags);
 WINPR_API BOOL ChangeTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, ULONG DueTime, ULONG Period);
 WINPR_API BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent);
 
@@ -296,8 +323,8 @@ typedef struct _RTL_RUN_ONCE
        PVOID Ptr;
 } RTL_RUN_ONCE, *PRTL_RUN_ONCE;
 
-typedef ULONG CALLBACK RTL_RUN_ONCE_INIT_FN (PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID* Context);
-typedef RTL_RUN_ONCE_INIT_FN *PRTL_RUN_ONCE_INIT_FN;
+typedef ULONG CALLBACK RTL_RUN_ONCE_INIT_FN(PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID* Context);
+typedef RTL_RUN_ONCE_INIT_FNPRTL_RUN_ONCE_INIT_FN;
 
 #endif
 
@@ -310,11 +337,13 @@ typedef RTL_RUN_ONCE_INIT_FN *PRTL_RUN_ONCE_INIT_FN;
 typedef RTL_RUN_ONCE INIT_ONCE;
 typedef PRTL_RUN_ONCE PINIT_ONCE;
 typedef PRTL_RUN_ONCE LPINIT_ONCE;
-typedef BOOL (CALLBACK * PINIT_ONCE_FN)(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context);
+typedef BOOL (CALLBACK* PINIT_ONCE_FN)(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context);
 
-WINPR_API BOOL winpr_InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID* lpContext);
+WINPR_API BOOL winpr_InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending,
+        LPVOID* lpContext);
 WINPR_API BOOL winpr_InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext);
-WINPR_API BOOL winpr_InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID* Context);
+WINPR_API BOOL winpr_InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter,
+        LPVOID* Context);
 WINPR_API VOID winpr_InitOnceInitialize(PINIT_ONCE InitOnce);
 
 #define InitOnceBeginInitialize winpr_InitOnceBeginInitialize
@@ -348,8 +377,10 @@ typedef PRTL_BARRIER LPSYNCHRONIZATION_BARRIER;
 #define SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY       0x02
 #define SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE                0x04
 
-WINPR_API BOOL WINAPI winpr_InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount);
-WINPR_API BOOL WINAPI winpr_EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags);
+WINPR_API BOOL WINAPI winpr_InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier,
+        LONG lTotalThreads, LONG lSpinCount);
+WINPR_API BOOL WINAPI winpr_EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier,
+        DWORD dwFlags);
 WINPR_API BOOL WINAPI winpr_DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier);
 
 #define InitializeSynchronizationBarrier winpr_InitializeSynchronizationBarrier
@@ -363,12 +394,12 @@ WINPR_API BOOL WINAPI winpr_DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRI
 WINPR_API VOID USleep(DWORD dwMicroseconds);
 
 WINPR_API HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes,
-               BOOL bManualReset, BOOL bInitialState, int FileDescriptor, ULONG mode);
+        BOOL bManualReset, BOOL bInitialState, int FileDescriptor, ULONG mode);
 WINPR_API HANDLE CreateFileDescriptorEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,
-               BOOL bManualReset, BOOL bInitialState, int FileDescriptor, ULONG mode);
+        BOOL bManualReset, BOOL bInitialState, int FileDescriptor, ULONG mode);
 
 WINPR_API HANDLE CreateWaitObjectEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
-               BOOL bManualReset, BOOL bInitialState, void* pObject);
+                                       BOOL bManualReset, BOOL bInitialState, void* pObject);
 
 #ifdef UNICODE
 #define CreateFileDescriptorEvent      CreateFileDescriptorEventW
index 9c3e37a..fc5681b 100644 (file)
@@ -127,8 +127,30 @@ static HANDLE_OPS ops =
 HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState,
                     LPCWSTR lpName)
 {
+       HANDLE handle;
+       char* name = NULL;
+
+       if (lpName)
+       {
+               int rc = ConvertFromUnicode(CP_UTF8, 0, lpName, -1, &name, 0, NULL, NULL);
+
+               if (rc < 0)
+                       return NULL;
+       }
+
+       handle = CreateEventA(lpEventAttributes, bManualReset, bInitialState, name);
+       free(name);
+       return handle;
+}
+
+HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState,
+                    LPCSTR lpName)
+{
        WINPR_EVENT* event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));
 
+       if (lpEventAttributes)
+               WLog_WARN(TAG, "%s [%s] does not support lpEventAttributes", __FUNCTION__, lpName);
+
        if (!event)
                return NULL;
 
@@ -167,31 +189,61 @@ fail:
        return NULL;
 }
 
-HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState,
-                    LPCSTR lpName)
-{
-       return CreateEventW(lpEventAttributes, bManualReset, bInitialState, NULL);
-}
-
 HANDLE CreateEventExW(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName, DWORD dwFlags,
                       DWORD dwDesiredAccess)
 {
-       return NULL;
+       BOOL initial = FALSE;
+       BOOL manual = FALSE;
+
+       if (dwFlags & CREATE_EVENT_INITIAL_SET)
+               initial = TRUE;
+
+       if (dwFlags & CREATE_EVENT_MANUAL_RESET)
+               manual = TRUE;
+
+       if (dwDesiredAccess != 0)
+               WLog_WARN(TAG, "%s [%s] does not support dwDesiredAccess 0x%08"PRIx32, __FUNCTION__, lpName,
+                         dwDesiredAccess);
+
+       return CreateEventW(lpEventAttributes, manual, initial, lpName);
 }
 
 HANDLE CreateEventExA(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags,
                       DWORD dwDesiredAccess)
 {
-       return NULL;
+       BOOL initial = FALSE;
+       BOOL manual = FALSE;
+
+       if (dwFlags & CREATE_EVENT_INITIAL_SET)
+               initial = TRUE;
+
+       if (dwFlags & CREATE_EVENT_MANUAL_RESET)
+               manual = TRUE;
+
+       if (dwDesiredAccess != 0)
+               WLog_WARN(TAG, "%s [%s] does not support dwDesiredAccess 0x%08"PRIx32, __FUNCTION__, lpName,
+                         dwDesiredAccess);
+
+       return CreateEventA(lpEventAttributes, manual, initial, lpName);
 }
 
 HANDLE OpenEventW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
 {
+       /* TODO: Implement */
+       WINPR_UNUSED(dwDesiredAccess);
+       WINPR_UNUSED(bInheritHandle);
+       WINPR_UNUSED(lpName);
+       WLog_ERR(TAG, "%s not implemented", __FUNCTION__);
        return NULL;
 }
 
 HANDLE OpenEventA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
 {
+       /* TODO: Implement */
+       WINPR_UNUSED(dwDesiredAccess);
+       WINPR_UNUSED(bInheritHandle);
+       WINPR_UNUSED(lpName);
+       WLog_ERR(TAG, "%s not implemented", __FUNCTION__);
        return NULL;
 }
 
index 7c41cb5..f25c2d0 100644 (file)
@@ -24,6 +24,7 @@
 #include <winpr/synch.h>
 #include <winpr/debug.h>
 #include <winpr/wlog.h>
+#include <winpr/string.h>
 
 #include "synch.h"
 
@@ -99,6 +100,7 @@ BOOL MutexCloseHandle(HANDLE handle)
                 */
        }
 
+       free(mutex->name);
        free(handle);
        return TRUE;
 }
@@ -129,10 +131,31 @@ static HANDLE_OPS ops =
 
 HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
 {
+       HANDLE handle;
+       char* name = NULL;
+
+       if (lpName)
+       {
+               int rc = ConvertFromUnicode(CP_UTF8, 0, lpName, -1, &name, 0, NULL, NULL);
+
+               if (rc < 0)
+                       return NULL;
+       }
+
+       handle = CreateMutexA(lpMutexAttributes, bInitialOwner, name);
+       free(name);
+       return handle;
+}
+
+HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)
+{
        HANDLE handle = NULL;
        WINPR_MUTEX* mutex;
        mutex = (WINPR_MUTEX*) calloc(1, sizeof(WINPR_MUTEX));
 
+       if (lpMutexAttributes)
+               WLog_WARN(TAG, "%s [%s] does not support lpMutexAttributes", __FUNCTION__, lpName);
+
        if (mutex)
        {
                pthread_mutexattr_t attr;
@@ -145,35 +168,62 @@ HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner,
 
                if (bInitialOwner)
                        pthread_mutex_lock(&mutex->mutex);
+
+               mutex->name = strdup(lpName); /* Non runtime relevant information, skip NULL check */
        }
 
        return handle;
 }
 
-HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)
-{
-       return CreateMutexW(lpMutexAttributes, bInitialOwner, NULL);
-}
-
-HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCTSTR lpName, DWORD dwFlags,
+HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName, DWORD dwFlags,
                       DWORD dwDesiredAccess)
 {
-       return CreateMutexW(lpMutexAttributes, FALSE, NULL);
+       BOOL initial = FALSE;
+       /* TODO: support access modes */
+
+       if (dwDesiredAccess != 0)
+               WLog_WARN(TAG, "%s [%s] does not support dwDesiredAccess 0x%08"PRIx32, __FUNCTION__, lpName,
+                         dwDesiredAccess);
+
+       if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
+               initial = TRUE;
+
+       return CreateMutexA(lpMutexAttributes, initial, lpName);
 }
 
 HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, DWORD dwFlags,
                       DWORD dwDesiredAccess)
 {
-       return CreateMutexW(lpMutexAttributes, FALSE, NULL);
+       BOOL initial = FALSE;
+
+       /* TODO: support access modes */
+       if (dwDesiredAccess != 0)
+               WLog_WARN(TAG, "%s [%s] does not support dwDesiredAccess 0x%08"PRIx32, __FUNCTION__, lpName,
+                         dwDesiredAccess);
+
+       if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
+               initial = TRUE;
+
+       return CreateMutexW(lpMutexAttributes, initial, lpName);
 }
 
 HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
 {
+       /* TODO: Implement */
+       WINPR_UNUSED(dwDesiredAccess);
+       WINPR_UNUSED(bInheritHandle);
+       WINPR_UNUSED(lpName);
+       WLog_ERR(TAG, "%s not implemented", __FUNCTION__);
        return NULL;
 }
 
 HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
 {
+       /* TODO: Implement */
+       WINPR_UNUSED(dwDesiredAccess);
+       WINPR_UNUSED(bInheritHandle);
+       WINPR_UNUSED(lpName);
+       WLog_ERR(TAG, "%s not implemented", __FUNCTION__);
        return NULL;
 }
 
index 15da96f..387c52b 100644 (file)
@@ -51,7 +51,7 @@
 struct winpr_mutex
 {
        WINPR_HANDLE_DEF();
-
+       char* name;
        pthread_mutex_t mutex;
 };
 typedef struct winpr_mutex WINPR_MUTEX;