shlwapi: Forward ThreadRef functions to shcore.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
77a8ac3683
commit
678c18b22e
|
@ -55,7 +55,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||||
|
|
||||||
/* DLL handles for late bound calls */
|
/* DLL handles for late bound calls */
|
||||||
extern HINSTANCE shlwapi_hInstance;
|
extern HINSTANCE shlwapi_hInstance;
|
||||||
extern DWORD SHLWAPI_ThreadRef_index;
|
|
||||||
|
|
||||||
static HRESULT iunknown_query_service(IUnknown*,REFGUID,REFIID,LPVOID*);
|
static HRESULT iunknown_query_service(IUnknown*,REFGUID,REFIID,LPVOID*);
|
||||||
HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,DWORD);
|
HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,DWORD);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
13 stdcall -noname RegisterDefaultAcceptHeaders(ptr ptr)
|
13 stdcall -noname RegisterDefaultAcceptHeaders(ptr ptr)
|
||||||
14 stdcall -ordinal GetAcceptLanguagesA(ptr ptr)
|
14 stdcall -ordinal GetAcceptLanguagesA(ptr ptr)
|
||||||
15 stdcall -ordinal GetAcceptLanguagesW(ptr ptr)
|
15 stdcall -ordinal GetAcceptLanguagesW(ptr ptr)
|
||||||
16 stdcall -ordinal SHCreateThread(ptr ptr long ptr)
|
16 stdcall -ordinal SHCreateThread(ptr ptr long ptr) shcore.SHCreateThread
|
||||||
17 stdcall -noname SHWriteDataBlockList(ptr ptr)
|
17 stdcall -noname SHWriteDataBlockList(ptr ptr)
|
||||||
18 stdcall -noname SHReadDataBlockList(ptr ptr)
|
18 stdcall -noname SHReadDataBlockList(ptr ptr)
|
||||||
19 stdcall -noname SHFreeDataBlockList(ptr)
|
19 stdcall -noname SHFreeDataBlockList(ptr)
|
||||||
|
@ -687,7 +687,7 @@
|
||||||
@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) shcore.SHCreateStreamOnFileEx
|
@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) shcore.SHCreateStreamOnFileEx
|
||||||
@ stdcall SHCreateStreamOnFileW(wstr long ptr) shcore.SHCreateStreamOnFileW
|
@ stdcall SHCreateStreamOnFileW(wstr long ptr) shcore.SHCreateStreamOnFileW
|
||||||
@ stdcall SHCreateStreamWrapper(ptr ptr long ptr)
|
@ stdcall SHCreateStreamWrapper(ptr ptr long ptr)
|
||||||
@ stdcall SHCreateThreadRef(ptr ptr)
|
@ stdcall SHCreateThreadRef(ptr ptr) shcore.SHCreateThreadRef
|
||||||
@ stdcall SHDeleteEmptyKeyA(long ptr)
|
@ stdcall SHDeleteEmptyKeyA(long ptr)
|
||||||
@ stdcall SHDeleteEmptyKeyW(long ptr)
|
@ stdcall SHDeleteEmptyKeyW(long ptr)
|
||||||
@ stdcall SHDeleteKeyA(long str)
|
@ stdcall SHDeleteKeyA(long str)
|
||||||
|
@ -701,7 +701,7 @@
|
||||||
@ stdcall SHEnumValueA(long long str ptr ptr ptr ptr)
|
@ stdcall SHEnumValueA(long long str ptr ptr ptr ptr)
|
||||||
@ stdcall SHEnumValueW(long long wstr ptr ptr ptr ptr)
|
@ stdcall SHEnumValueW(long long wstr ptr ptr ptr ptr)
|
||||||
@ stdcall SHGetInverseCMAP ( ptr long )
|
@ stdcall SHGetInverseCMAP ( ptr long )
|
||||||
@ stdcall SHGetThreadRef (ptr)
|
@ stdcall SHGetThreadRef(ptr) shcore.SHGetThreadRef
|
||||||
@ stdcall SHGetValueA ( long str str ptr ptr ptr )
|
@ stdcall SHGetValueA ( long str str ptr ptr ptr )
|
||||||
@ stdcall SHGetValueW ( long wstr wstr ptr ptr ptr )
|
@ stdcall SHGetValueW ( long wstr wstr ptr ptr ptr )
|
||||||
@ stdcall SHIsLowMemoryMachine(long)
|
@ stdcall SHIsLowMemoryMachine(long)
|
||||||
|
@ -746,8 +746,8 @@
|
||||||
@ stdcall SHRegWriteUSValueA (long str long ptr long long)
|
@ stdcall SHRegWriteUSValueA (long str long ptr long long)
|
||||||
@ stdcall SHRegWriteUSValueW (long wstr long ptr long long)
|
@ stdcall SHRegWriteUSValueW (long wstr long ptr long long)
|
||||||
@ stdcall SHRegisterValidateTemplate(wstr long)
|
@ stdcall SHRegisterValidateTemplate(wstr long)
|
||||||
@ stdcall SHReleaseThreadRef()
|
@ stdcall SHReleaseThreadRef() shcore.SHReleaseThreadRef
|
||||||
@ stdcall SHSetThreadRef (ptr)
|
@ stdcall SHSetThreadRef(ptr) shcore.SHSetThreadRef
|
||||||
@ stdcall SHSetValueA (long str str long ptr long)
|
@ stdcall SHSetValueA (long str str long ptr long)
|
||||||
@ stdcall SHSetValueW (long wstr wstr long ptr long)
|
@ stdcall SHSetValueW (long wstr wstr long ptr long)
|
||||||
@ stdcall SHSkipJunction(ptr ptr)
|
@ stdcall SHSkipJunction(ptr ptr)
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||||
|
|
||||||
DECLSPEC_HIDDEN HINSTANCE shlwapi_hInstance = 0;
|
DECLSPEC_HIDDEN HINSTANCE shlwapi_hInstance = 0;
|
||||||
DECLSPEC_HIDDEN DWORD SHLWAPI_ThreadRef_index = TLS_OUT_OF_INDEXES;
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* SHLWAPI {SHLWAPI}
|
* SHLWAPI {SHLWAPI}
|
||||||
|
@ -61,11 +60,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(hinstDLL);
|
DisableThreadLibraryCalls(hinstDLL);
|
||||||
shlwapi_hInstance = hinstDLL;
|
shlwapi_hInstance = hinstDLL;
|
||||||
SHLWAPI_ThreadRef_index = TlsAlloc();
|
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (fImpLoad) break;
|
if (fImpLoad) break;
|
||||||
if (SHLWAPI_ThreadRef_index != TLS_OUT_OF_INDEXES) TlsFree(SHLWAPI_ThreadRef_index);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -108,316 +108,6 @@ HRESULT WINAPI _SHGetInstanceExplorer(IUnknown **lppUnknown)
|
||||||
return SHGetInstanceExplorer(lppUnknown);
|
return SHGetInstanceExplorer(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;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
IUnknown IUnknown_iface;
|
|
||||||
LONG *ref;
|
|
||||||
} threadref;
|
|
||||||
|
|
||||||
static inline threadref *impl_from_IUnknown(IUnknown *iface)
|
|
||||||
{
|
|
||||||
return CONTAINING_RECORD(iface, threadref, IUnknown_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI threadref_QueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj)
|
|
||||||
{
|
|
||||||
threadref * This = impl_from_IUnknown(iface);
|
|
||||||
|
|
||||||
TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObj);
|
|
||||||
|
|
||||||
if (ppvObj == NULL)
|
|
||||||
return E_POINTER;
|
|
||||||
|
|
||||||
if (IsEqualGUID(&IID_IUnknown, riid)) {
|
|
||||||
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppvObj);
|
|
||||||
*ppvObj = This;
|
|
||||||
IUnknown_AddRef((IUnknown*)*ppvObj);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ppvObj = NULL;
|
|
||||||
FIXME("(%p, %s, %p) interface not supported\n", This, debugstr_guid(riid), ppvObj);
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI threadref_AddRef(IUnknown *iface)
|
|
||||||
{
|
|
||||||
threadref * This = impl_from_IUnknown(iface);
|
|
||||||
|
|
||||||
TRACE("(%p)\n", This);
|
|
||||||
return InterlockedIncrement(This->ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI threadref_Release(IUnknown *iface)
|
|
||||||
{
|
|
||||||
LONG refcount;
|
|
||||||
threadref * This = impl_from_IUnknown(iface);
|
|
||||||
|
|
||||||
TRACE("(%p)\n", This);
|
|
||||||
|
|
||||||
refcount = InterlockedDecrement(This->ref);
|
|
||||||
if (!refcount)
|
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
|
||||||
|
|
||||||
return refcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* VTable */
|
|
||||||
static const IUnknownVtbl threadref_vt =
|
|
||||||
{
|
|
||||||
threadref_QueryInterface,
|
|
||||||
threadref_AddRef,
|
|
||||||
threadref_Release,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* SHCreateThreadRef [SHLWAPI.@]
|
|
||||||
*
|
|
||||||
* Create a per-thread IUnknown object
|
|
||||||
*
|
|
||||||
* PARAMS
|
|
||||||
* lprefcount [I] Pointer to a LONG to be used as refcount
|
|
||||||
* lppUnknown [O] Destination to receive the created object reference
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* Success: S_OK. lppUnknown is set to the object reference.
|
|
||||||
* Failure: E_INVALIDARG, if a parameter is NULL
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI SHCreateThreadRef(LONG *lprefcount, IUnknown **lppUnknown)
|
|
||||||
{
|
|
||||||
threadref * This;
|
|
||||||
TRACE("(%p, %p)\n", lprefcount, lppUnknown);
|
|
||||||
|
|
||||||
if (!lprefcount || !lppUnknown)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(threadref));
|
|
||||||
This->IUnknown_iface.lpVtbl = &threadref_vt;
|
|
||||||
This->ref = lprefcount;
|
|
||||||
|
|
||||||
*lprefcount = 1;
|
|
||||||
*lppUnknown = &This->IUnknown_iface;
|
|
||||||
TRACE("=> returning S_OK with %p\n", This);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* SHGetThreadRef [SHLWAPI.@]
|
|
||||||
*
|
|
||||||
* Get a per-thread object reference set by SHSetThreadRef().
|
|
||||||
*
|
|
||||||
* PARAMS
|
|
||||||
* lppUnknown [O] Destination to receive object reference
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* Success: S_OK. lppUnknown is set to the object reference.
|
|
||||||
* Failure: E_NOINTERFACE, if an error occurs or no object is set
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown)
|
|
||||||
{
|
|
||||||
TRACE("(%p)\n", lppUnknown);
|
|
||||||
|
|
||||||
if (SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES)
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
|
|
||||||
*lppUnknown = 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
|
|
||||||
* lpUnknown [I] Object reference to store
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* Success: S_OK. lpUnknown is stored and can be retrieved by SHGetThreadRef()
|
|
||||||
* Failure: E_NOINTERFACE, if an error occurs
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI SHSetThreadRef(IUnknown *lpUnknown)
|
|
||||||
{
|
|
||||||
TRACE("(%p)\n", lpUnknown);
|
|
||||||
|
|
||||||
if (SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES)
|
|
||||||
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 object reference is released.
|
|
||||||
* Failure: An HRESULT error code.
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI SHReleaseThreadRef(void)
|
|
||||||
{
|
|
||||||
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)\n", 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] CTF_ flags from "shlwapi.h"
|
|
||||||
* 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%X,%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) != 0;
|
|
||||||
ti.hEvent = CreateEventW(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, INFINITE);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* SHGlobalCounterGetValue [SHLWAPI.223]
|
* SHGlobalCounterGetValue [SHLWAPI.223]
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue