Hi, More SHLWAPI updates. This patch brings the shlwapi thread functions together, and completes the implementation of the dll's semaphore functions. It sneaks in the .spec updates for my patch "SHLWAPI_regstream" also. It requires both the shlwapi.h patch sent previously, and Juergens recent "patch shlwapi" update to be applied first. You will then need to re-run configure after applying. License: X11 ChangeLog: Jon Griffiths <jon_p_griffiths@yahoo.com> +dlls/shlwapi/Makefile.in,dlls/shlwapi/ordinal.c,dlls/shlwapi/thread.c, dlls/shlwapi/shlwapi.spec Move thread related functions to new file Implement SHCreateThread,@224,@424, stub SHReleaseThreadRef Fix: SHGetThreadRef() calls AddRef(), @356 param count wrong Update spec entries for @12, SHOpenRegStream2A/W ===== "Don't wait for the seas to part, or messiahs to come; Don't you sit around and waste this chance..." - Live jon_p_griffiths@yahoo.com __________________________________________________ Do You Yahoo!? Yahoo! Health - Feel better, live better http://health.yahoo.com
diff -uP wine-post-patch/dlls/shlwapi/Makefile.in wine-develop/dlls/shlwapi/Makefile.in --- wine-post-patch/dlls/shlwapi/Makefile.in Wed Jul 17 07:10:08 2002 +++ wine-develop/dlls/shlwapi/Makefile.in Sun Jul 21 12:49:22 2002 @@ -20,6 +20,7 @@ regstream.c \ shlwapi_main.c \ string.c \ + thread.c \ url.c \ wsprintf.c diff -uP wine-post-patch/dlls/shlwapi/ordinal.c wine-develop/dlls/shlwapi/ordinal.c --- wine-post-patch/dlls/shlwapi/ordinal.c Sun Jul 21 14:19:32 2002 +++ wine-develop/dlls/shlwapi/ordinal.c Sun Jul 21 14:07:06 2002 @@ -133,7 +133,6 @@ static BOOL (WINAPI *pPageSetupDlgW)(LPPAGESETUPDLGW); static BOOL (WINAPI *pPrintDlgW)(LPPRINTDLGW); static BOOL (WINAPI *pGetOpenFileNameW)(LPOPENFILENAMEW); -static HRESULT (WINAPI *pSHGetInstanceExplorer)(LPUNKNOWN *); static DWORD (WINAPI *pGetFileVersionInfoSizeW)(LPCWSTR,LPDWORD); static BOOL (WINAPI *pGetFileVersionInfoW)(LPCWSTR,DWORD,DWORD,LPVOID); static WORD (WINAPI *pVerQueryValueW)(LPVOID,LPCWSTR,LPVOID*,UINT*); @@ -725,19 +724,6 @@ } /************************************************************************* - * @ [SHLWAPI.16] - */ -HRESULT WINAPI SHLWAPI_16 ( - LPVOID w, - LPVOID x, - LPVOID y, - LPWSTR z) -{ - FIXME("(%p %p %p %p)stub\n",w,x,y,z); - return 0xabba1252; -} - -/************************************************************************* * @ [SHLWAPI.23] * * NOTES @@ -1525,41 +1511,6 @@ } /************************************************************************* - * @ [SHLWAPI.222] - * - * NOTES - * securityattributes missing - */ -HANDLE WINAPI SHLWAPI_222 (LPCLSID guid) -{ - char lpstrName[80]; - - sprintf( lpstrName, "shell.{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); - FIXME("(%s) stub\n", lpstrName); - return CreateSemaphoreA(NULL,0, 0x7fffffff, lpstrName); -} - -/************************************************************************* - * @ [SHLWAPI.223] - * - * NOTES - * get the count of the semaphore - */ -DWORD WINAPI SHLWAPI_223 (HANDLE handle) -{ - DWORD oldCount; - - FIXME("(0x%08x) stub\n",handle); - - ReleaseSemaphore( handle, 1, &oldCount); /* +1 */ - WaitForSingleObject( handle, 0 ); /* -1 */ - return oldCount; -} - -/************************************************************************* * @ [SHLWAPI.236] */ HMODULE WINAPI SHLWAPI_236 (REFIID lpUnknown) @@ -1997,30 +1948,6 @@ return pVerQueryValueW((char*)w+0x208, x, y, z); } -/************************************************************************** - * @ [SHLWAPI.356] - * - * mbc - this function is undocumented, The parameters are correct and - * the calls to InitializeSecurityDescriptor and - * SetSecurityDescriptorDacl are correct, but apparently some - * apps call this function with all zero parameters. - */ - -DWORD WINAPI SHLWAPI_356(PACL pDacl, PSECURITY_DESCRIPTOR pSD, LPCSTR *str) -{ - if(str != 0){ - *str = 0; - } - - if(!pDacl){ - return 0; - } - - if (!InitializeSecurityDescriptor(pSD, 1)) return 0; - return SetSecurityDescriptorDacl(pSD, 1, pDacl, 0); -} - - /************************************************************************* * @ [SHLWAPI.357] * @@ -2271,42 +2198,6 @@ } /************************************************************************* - * SHGlobalCounterCreateNamedA [SHLWAPI.422] - */ -HANDLE WINAPI SHLWAPI_422 (LPCSTR pwName, int nInitialCount) -{ - CHAR pwCounterName[MAX_PATH]; - HANDLE hSem; - - lstrcpyA(pwCounterName, "shell."); - lstrcatA(pwCounterName, pwName); - hSem = CreateSemaphoreA(NULL /* FIXME */, nInitialCount, MAXLONG, pwCounterName); - if (!hSem) { - OpenSemaphoreA( SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, 0, pwCounterName); - } - return hSem; -} - -/************************************************************************* - * SHGlobalCounterCreateNamedW [SHLWAPI.423] - */ -HANDLE WINAPI SHLWAPI_423 (LPCWSTR pwName, int nInitialCount) -{ - WCHAR pwCounterName[MAX_PATH]; - WCHAR pwShell[7] = {'s','h','e','l','l','.','\0'}; - HANDLE hSem; - - lstrcpyW(pwCounterName, pwShell); - lstrcatW(pwCounterName, pwName); - hSem = CreateSemaphoreW(NULL /* FIXME */, nInitialCount, MAXLONG, pwCounterName); - if (!hSem) { - OpenSemaphoreW( SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, 0, pwCounterName); - } - return hSem; -} - - -/************************************************************************* * @ [SHLWAPI.418] * * Function seems to do FreeLibrary plus other things. @@ -2521,53 +2412,4 @@ } return -1; } - -/************************************************************************* - * _SHGetInstanceExplorer@4 [SHLWAPI.@] - * - * Late bound call to shell32.SHGetInstanceExplorer. - */ -HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown) -{ - GET_FUNC(pSHGetInstanceExplorer, shell32, "SHGetInstanceExplorer", E_FAIL); - return pSHGetInstanceExplorer(lpUnknown); -} - -/************************************************************************* - * SHGetThreadRef [SHLWAPI.@] - * - * Retrieves the per-thread object reference set by SHSetThreadRef - * "punk" - Address of a pointer to the IUnknown interface. Returns S_OK if - * successful or E_NOINTERFACE otherwise. - */ -HRESULT WINAPI SHGetThreadRef (IUnknown ** ppunk) -{ - if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE; - *ppunk = (IUnknown *)TlsGetValue(SHLWAPI_ThreadRef_index); - return S_OK; -} - -/************************************************************************* - * SHSetThreadRef [SHLWAPI.@] - * - * Stores a per-thread reference to a COM object - * "punk" - Pointer to the IUnknown interface of the object to - * which you want to store a reference. Returns S_OK if successful - * or an OLE error value. - */ -HRESULT WINAPI SHSetThreadRef (IUnknown * punk) -{ - if (SHLWAPI_ThreadRef_index < 0) return E_NOINTERFACE; - TlsSetValue(SHLWAPI_ThreadRef_index, (LPVOID) punk); - return S_OK; -} - - - - - - - - - diff -uP wine-post-patch/dlls/shlwapi/shlwapi.spec wine-develop/dlls/shlwapi/shlwapi.spec --- wine-post-patch/dlls/shlwapi/shlwapi.spec Sun Jul 21 14:19:32 2002 +++ wine-develop/dlls/shlwapi/shlwapi.spec Sun Jul 21 14:10:57 2002 @@ -15,7 +15,7 @@ 13 stdcall @(ptr ptr) SHLWAPI_13 14 stdcall @(ptr ptr) SHLWAPI_14 15 stdcall @(ptr ptr) SHLWAPI_15 -16 stdcall @(long long long long) SHLWAPI_16 +16 stdcall @(ptr ptr long ptr) SHCreateThread 17 stdcall @ (ptr ptr) SHLWAPI_17 18 stdcall @ (ptr ptr) SHLWAPI_18 19 stdcall @ (ptr) SHLWAPI_19 @@ -223,7 +223,7 @@ 221 stub @ 222 stdcall @(long) SHLWAPI_222 223 stdcall @(long) SHLWAPI_223 -224 stub @ +224 stdcall @(long) SHLWAPI_224 225 stub @ 226 stub @ 227 stub @ @@ -355,7 +355,7 @@ 353 stub @ 354 stub @ 355 stub @ -356 stdcall @(long long long) SHLWAPI_356 +356 stdcall @(ptr ptr) SHLWAPI_356 357 stdcall @(wstr wstr wstr long long) SHLWAPI_357 358 stdcall @(ptr ptr ptr ptr ptr ptr) SHLWAPI_358 359 forward @ kernel32.OpenEventW @@ -423,7 +423,7 @@ 421 stub @ 422 stdcall @(str long) SHLWAPI_422 423 stdcall @(wstr long) SHLWAPI_423 -424 stub @ +424 stdcall @(long) SHLWAPI_424 425 stub @ 426 stub @ 427 stub @ @@ -712,13 +712,13 @@ @ stdcall SHCreateStreamOnFileW(wstr long ptr) SHCreateStreamOnFileW @ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) SHCreateStreamOnFileEx @ stub SHCreateStreamWrapper -@ stub SHCreateThread @ stdcall SHGetThreadRef (ptr) SHGetThreadRef @ stdcall SHRegDuplicateHKey (long) SHRegDuplicateHKey @ stdcall SHRegSetPathA(long str str str long) SHRegSetPathA @ stdcall SHRegSetPathW(long wstr wstr wstr long) SHRegSetPathW @ stub SHRegisterValidateTemplate @ stdcall SHSetThreadRef (ptr) SHSetThreadRef +@ stdcall SHReleaseThreadRef() SHReleaseThreadRef @ stub SHSkipJunction @ stdcall SHStrDupA (str ptr) SHStrDupA @ stdcall SHStrDupW (wstr ptr) SHStrDupW diff -uP wine-post-patch/dlls/shlwapi/thread.c wine-develop/dlls/shlwapi/thread.c --- wine-post-patch/dlls/shlwapi/thread.c Thu Jan 1 12:00:00 1970 +++ wine-develop/dlls/shlwapi/thread.c Sun Jul 21 14:16:53 2002 @@ -0,0 +1,467 @@ +/* + * SHLWAPI thread and MT synchronisation functions + * + * Copyright 2002 Juergen Schmied + * Copyright 2002 Jon Griffiths + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <string.h> + +#include "windef.h" +#include "winnls.h" +#include "wine/obj_base.h" +#include "wine/debug.h" +#define NO_SHLWAPI_REG +#define NO_SHLWAPI_PATH +#define NO_SHLWAPI_GDI +#define NO_SHLWAPI_STREAM +#define NO_SHLWAPI_USER +#include "shlwapi.h" +#include "ordinal.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shell); + +extern DWORD SHLWAPI_ThreadRef_index; /* Initialised in shlwapi_main.c */ + +static HRESULT (WINAPI *pSHGetInstanceExplorer)(IUnknown**); + +DWORD WINAPI SHLWAPI_23(REFGUID,LPSTR,INT); + +/************************************************************************** + * @ [SHLWAPI.356] + * + * Initialise security attributes from a security descriptor. + * + * PARAMS + * lpAttr [O] Security attributes + * lpSec [I] Security descriptor + * + * RETURNS + * Success: lpAttr, initialised using lpSec. + * Failure: NULL, if any parameters are invalid. + * + * NOTES + * This function always returns returns NULL if the underlying OS version + * Wine is impersonating does not use security descriptors (i.e. anything + * before Windows NT). + */ +LPSECURITY_ATTRIBUTES +WINAPI SHLWAPI_356(LPSECURITY_ATTRIBUTES lpAttr, PSECURITY_DESCRIPTOR lpSec) +{ + /* This function is used within SHLWAPI only to create security attributes + * for shell semaphores. */ + + TRACE("(%p,%p)\n", lpAttr, lpSec); + + if (0) /* FIXME: SHWAPI_OsIsUnicode, as per shell32 */ + { + if (!lpSec || !lpAttr) + return NULL; + + if (InitializeSecurityDescriptor(lpSec, 1)) + { + if (SetSecurityDescriptorDacl(lpSec, TRUE, NULL, FALSE)) + { + lpAttr->nLength = sizeof(SECURITY_ATTRIBUTES); + lpAttr->lpSecurityDescriptor = lpSec; + lpAttr->bInheritHandle = FALSE; + return lpAttr; + } + } + } + return NULL; +} + +/************************************************************************* + * _SHGetInstanceExplorer@4 [SHLWAPI.@] + * + * Get an interface to the shell explorer. + * + * PARAMS + * lpUnknown [O] pointer to recieve interface. + * + * RETURNS + * Success: S_OK. lppUnknown contains the explorer interface. + * Failure: An HRESULT error code. + */ +HRESULT WINAPI _SHGetInstanceExplorer(IUnknown **lppUnknown) +{ + /* This function is used within SHLWAPI only to hold the IE reference + * for threads created with the CTF_PROCESS_REF flag set. */ + + GET_FUNC(pSHGetInstanceExplorer, shell32, "SHGetInstanceExplorer", E_FAIL); + return pSHGetInstanceExplorer(lppUnknown); +} + +/* Internal thread information structure */ +typedef struct tagSHLWAPI_THREAD_INFO +{ + LPTHREAD_START_ROUTINE pfnThreadProc; /* Thread start */ + LPTHREAD_START_ROUTINE pfnCallback; /* Thread initialisation */ + PVOID pData; /* Application specific data */ + BOOL bInitCom; /* Initialise COM for the thread? */ + HANDLE hEvent; /* Signal for creator to continue */ + IUnknown *refThread; /* Reference to thread creator */ + IUnknown *refIE; /* Reference to the IE process */ +} SHLWAPI_THREAD_INFO, *LPSHLWAPI_THREAD_INFO; + + +/************************************************************************* + * SHGetThreadRef [SHLWAPI.@] + * + * Get a per-thread object reference set by SHSetThreadRef. + * + * PARAMS + * lppUnknown [O] Destination to receive object reference + * + * RETURNS + * Success: S_OK. lppUnk is set to the object reference. + * Failure: E_NOINTERFACE, if an error occurs or lppUnk is invalid. + */ +HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown) +{ + TRACE("(%p)\n", lppUnknown); + + if (!lppUnknown || SHLWAPI_ThreadRef_index == -1u) + return E_NOINTERFACE; + + *lppUnknown = (IUnknown*)TlsGetValue(SHLWAPI_ThreadRef_index); + if (!*lppUnknown) + return E_NOINTERFACE; + + /* Add a reference. Caller will Release() us when finished */ + IUnknown_AddRef(*lppUnknown); + return S_OK; +} + +/************************************************************************* + * SHSetThreadRef [SHLWAPI.@] + * + * Store a per-thread object reference. + * + * PARAMS + * lpUnk [I] Object reference to store + * + * RETURNS + * Success: S_OK. lpUnk is stored and can be retrieved by SHGetThreadRef() + * Failure: E_NOINTERFACE, if an error occurs or lpUnk is invalid. + */ +HRESULT WINAPI SHSetThreadRef(IUnknown *lpUnknown) +{ + TRACE("(%p)\n", lpUnknown); + + if (!lpUnknown || SHLWAPI_ThreadRef_index == 0xffffffff) + return E_NOINTERFACE; + + TlsSetValue(SHLWAPI_ThreadRef_index, lpUnknown); + return S_OK; +} + +/************************************************************************* + * SHReleaseThreadRef [SHLWAPI.@] + * + * Release a per-thread object reference. + * + * PARAMS + * None. + * + * RETURNS + * Success: S_OK. The threads obbject reference is released. + * Failure: An HRESULT error code. + */ +HRESULT WINAPI SHReleaseThreadRef() +{ + FIXME("() - stub!\n"); + return S_OK; +} + +/************************************************************************* + * SHLWAPI_ThreadWrapper + * + * Internal wrapper for executing user thread functions from SHCreateThread. + */ +static DWORD WINAPI SHLWAPI_ThreadWrapper(PVOID pTi) +{ + SHLWAPI_THREAD_INFO ti; + HRESULT hCom = E_FAIL; + DWORD dwRet; + + TRACE("(%p)", pTi); + + /* We are now executing in the context of the newly created thread. + * So we copy the data passed to us (it is on the stack of the function + * that called us, which is waiting for us to signal an event before + * returning). */ + memcpy(&ti, pTi, sizeof(SHLWAPI_THREAD_INFO)); + + /* Initialise COM for the thread, if desired */ + if (ti.bInitCom) + { + hCom = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE); + + if (FAILED(hCom)) + hCom = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE); + } + + /* Execute the callback function before returning */ + if (ti.pfnCallback) + ti.pfnCallback(ti.pData); + + /* Signal the thread that created us; it can return now */ + SetEvent(ti.hEvent); + + /* Execute the callers start code */ + dwRet = ti.pfnThreadProc(ti.pData); + + /* Release references to the caller and IE process, if held */ + if (ti.refThread) + IUnknown_Release(ti.refThread); + + if (ti.refIE) + IUnknown_Release(ti.refIE); + + if (SUCCEEDED(hCom)) + CoUninitialize(); + + /* Return the users thread return value */ + return dwRet; +} + +/************************************************************************* + * SHCreateThread [SHLWAPI.16] + * + * Create a new thread. + * + * PARAMS + * pfnThreadProc [I] Function to execute in new thread + * pData [I] Application specific data passed to pfnThreadProc + * dwFlags [I] Initialisation to perform in the new thread + * pfnCallback [I] Function to execute before pfnThreadProc + * + * RETURNS + * Success: TRUE. pfnThreadProc was executed. + * Failure: FALSE. pfnThreadProc was not executed. + * + * NOTES + * If the thread cannot be created, pfnCallback is NULL, and dwFlags + * has bit CTF_INSIST set, pfnThreadProc will be executed synchronously. + */ +BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, + DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback) +{ + SHLWAPI_THREAD_INFO ti; + BOOL bCalled = FALSE; + + TRACE("(%p,%p,0x%lX,%p)\n", pfnThreadProc, pData, dwFlags, pfnCallback); + + /* Set up data to pass to the new thread (On our stack) */ + ti.pfnThreadProc = pfnThreadProc; + ti.pfnCallback = pfnCallback; + ti.pData = pData; + ti.bInitCom = dwFlags & CTF_COINIT ? TRUE : FALSE; + ti.hEvent = CreateEventA(NULL,FALSE,FALSE,NULL); + + /* Hold references to the current thread and IE process, if desired */ + if(dwFlags & CTF_THREAD_REF) + SHGetThreadRef(&ti.refThread); + else + ti.refThread = NULL; + + if(dwFlags & CTF_PROCESS_REF) + _SHGetInstanceExplorer(&ti.refIE); + else + ti.refIE = NULL; + + /* Create the thread */ + if(ti.hEvent) + { + DWORD dwRetVal; + HANDLE hThread; + + hThread = CreateThread(NULL, 0, SHLWAPI_ThreadWrapper, &ti, 0, &dwRetVal); + + if(hThread) + { + /* Wait for the thread to signal us to continue */ + WaitForSingleObject(ti.hEvent, -1); + CloseHandle(hThread); + bCalled = TRUE; + } + CloseHandle(ti.hEvent); + } + + if (!bCalled) + { + if (!ti.pfnCallback && dwFlags & CTF_INSIST) + { + /* Couldn't call, call synchronously */ + pfnThreadProc(pData); + bCalled = TRUE; + } + else + { + /* Free references, since thread hasn't run to do so */ + if(ti.refThread) + IUnknown_Release(ti.refThread); + + if(ti.refIE) + IUnknown_Release(ti.refIE); + } + } + return bCalled; +} + +/************************************************************************* + * @ [SHLWAPI.223] + * + * Get the current count of a semaphore. + * + * PARAMS + * hSem [I] Semaphore handle + * + * RETURNS + * The current count of the semaphore. + */ +DWORD WINAPI SHLWAPI_223(HANDLE hSem) +{ + DWORD dwOldCount = 0; + + TRACE("(0x%08x)\n", hSem); + ReleaseSemaphore(hSem, 1, &dwOldCount); /* +1 */ + WaitForSingleObject(hSem, 0); /* -1 */ + return dwOldCount; +} + +/************************************************************************* + * @ [SHLWAPI.224] + * + * Claim a semaphore. + * + * PARAMS + * hSem [I] Semaphore handle + * + * RETURNS + * The new count of the semaphore. + */ +DWORD WINAPI SHLWAPI_224(HANDLE hSem) +{ + DWORD dwOldCount = 0; + + TRACE("(0x%08x)\n", hSem); + ReleaseSemaphore(hSem, 1, &dwOldCount); + return dwOldCount + 1; +} + +/************************************************************************* + * @ [SHLWAPI.424] + * + * Release a semaphore. + * + * PARAMS + * hSem [I] Semaphore handle + * + * RETURNS + * The new count of the semaphore. + */ +DWORD WINAPI SHLWAPI_424(HANDLE hSem) +{ + DWORD dwOldCount = 0; + + TRACE("(0x%08x)\n", hSem); + + dwOldCount = SHLWAPI_223(hSem); + WaitForSingleObject(hSem, 0); + return dwOldCount - 1; +} + +/************************************************************************* + * @ [SHLWAPI.423] + * + * Unicode version of SHLWAPI_422. + */ +HANDLE WINAPI SHLWAPI_423(LPCWSTR lpszName, DWORD iInitial) +{ + static const WCHAR szPrefix[] = { 's', 'h', 'e', 'l', 'l', '.', '\0' }; + const int iPrefixLen = 6; + WCHAR szBuff[MAX_PATH]; + const int iBuffLen = sizeof(szBuff)/sizeof(WCHAR); + SECURITY_DESCRIPTOR sd; + SECURITY_ATTRIBUTES sAttr, *pSecAttr; + HANDLE hRet; + + TRACE("(%s,%ld)\n", debugstr_w(lpszName), iInitial); + + /* Create Semaphore name */ + memcpy(szBuff, szPrefix, (iPrefixLen + 1) * sizeof(WCHAR)); + if (lpszName) + StrCpyNW(szBuff + iPrefixLen, lpszName, iBuffLen - iPrefixLen); + + /* Initialise security attributes */ + pSecAttr = SHLWAPI_356(&sAttr, &sd); + + if (!(hRet = CreateSemaphoreW(pSecAttr , iInitial, MAXLONG, szBuff))) + hRet = OpenSemaphoreW(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, 0, szBuff); + return hRet; +} + +/************************************************************************* + * @ [SHLWAPI.422] + * + * Create a semaphore. + * + * PARAMS + * lpszName [I] Name of semaphore + * iInitial [I] Initial count for semaphore + * + * RETURNS + * A new semaphore handle. + */ +HANDLE WINAPI SHLWAPI_422(LPCSTR lpszName, DWORD iInitial) +{ + WCHAR szBuff[MAX_PATH]; + + TRACE("(%s,%ld)\n", debugstr_a(lpszName), iInitial); + + if (lpszName) + MultiByteToWideChar(0, 0, lpszName, -1, szBuff, MAX_PATH); + return SHLWAPI_423(lpszName ? szBuff : NULL, iInitial); +} + +/************************************************************************* + * @ [SHLWAPI.222] + * + * Create a semaphore using the name of a GUID. + * + * PARAMS + * guid [I] GUID to use as semaphore name + * + * RETURNS + * A handle to the semaphore. + * + * NOTES + * The initial count of the semaphore is set to 0. + */ +HANDLE WINAPI SHLWAPI_222(REFGUID guid) +{ + char szName[40]; + + TRACE("(%s)\n", debugstr_guid(guid)); + + /* Create a named semaphore using the GUID string */ + SHLWAPI_23(guid, szName, sizeof(szName) - 1); + return SHLWAPI_422(szName, 0); +} +