Move thread related functions to new file.
Implement SHCreateThread,@224,@424, stub SHReleaseThreadRef. Fix: SHGetThreadRef() calls AddRef(), @356 param count wrong.
This commit is contained in:
parent
b8a70d8973
commit
d84875ceaf
|
@ -20,6 +20,7 @@ C_SRCS = \
|
|||
regstream.c \
|
||||
shlwapi_main.c \
|
||||
string.c \
|
||||
thread.c \
|
||||
url.c \
|
||||
wsprintf.c
|
||||
|
||||
|
|
|
@ -133,7 +133,6 @@ static DWORD (WINAPI *pWNetGetLastErrorW)(LPVOID, LPVOID, LPVOID, LPVOID, LPVO
|
|||
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*);
|
||||
|
@ -724,19 +723,6 @@ HRESULT WINAPI SHLWAPI_15 (
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* @ [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]
|
||||
*
|
||||
|
@ -1524,41 +1510,6 @@ HRESULT WINAPI SHLWAPI_219 (
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* @ [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]
|
||||
*/
|
||||
|
@ -1997,30 +1948,6 @@ WORD WINAPI SHLWAPI_352 (
|
|||
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]
|
||||
*
|
||||
|
@ -2270,42 +2197,6 @@ DWORD WINAPI SHLWAPI_413 (DWORD x)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* 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]
|
||||
*
|
||||
|
@ -2521,43 +2412,3 @@ INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ init SHLWAPI_LibMain
|
|||
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 @@ init SHLWAPI_LibMain
|
|||
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 @@ init SHLWAPI_LibMain
|
|||
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 @@ init SHLWAPI_LibMain
|
|||
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 @@ init SHLWAPI_LibMain
|
|||
@ 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
|
||||
|
|
|
@ -0,0 +1,466 @@
|
|||
/*
|
||||
* 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 [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);
|
||||
}
|
Loading…
Reference in New Issue