diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c index 60e57619440..810b5746b4a 100644 --- a/dlls/shlwapi/ordinal.c +++ b/dlls/shlwapi/ordinal.c @@ -55,7 +55,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); /* DLL handles for late bound calls */ extern HINSTANCE shlwapi_hInstance; -extern DWORD SHLWAPI_ThreadRef_index; static HRESULT iunknown_query_service(IUnknown*,REFGUID,REFIID,LPVOID*); HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,DWORD); diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index 6e64a9c12e0..30c34cb9888 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -13,7 +13,7 @@ 13 stdcall -noname RegisterDefaultAcceptHeaders(ptr ptr) 14 stdcall -ordinal GetAcceptLanguagesA(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) 18 stdcall -noname SHReadDataBlockList(ptr ptr) 19 stdcall -noname SHFreeDataBlockList(ptr) @@ -687,7 +687,7 @@ @ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) shcore.SHCreateStreamOnFileEx @ stdcall SHCreateStreamOnFileW(wstr long ptr) shcore.SHCreateStreamOnFileW @ stdcall SHCreateStreamWrapper(ptr ptr long ptr) -@ stdcall SHCreateThreadRef(ptr ptr) +@ stdcall SHCreateThreadRef(ptr ptr) shcore.SHCreateThreadRef @ stdcall SHDeleteEmptyKeyA(long ptr) @ stdcall SHDeleteEmptyKeyW(long ptr) @ stdcall SHDeleteKeyA(long str) @@ -701,7 +701,7 @@ @ stdcall SHEnumValueA(long long str ptr ptr ptr ptr) @ stdcall SHEnumValueW(long long wstr ptr ptr ptr ptr) @ stdcall SHGetInverseCMAP ( ptr long ) -@ stdcall SHGetThreadRef (ptr) +@ stdcall SHGetThreadRef(ptr) shcore.SHGetThreadRef @ stdcall SHGetValueA ( long str str ptr ptr ptr ) @ stdcall SHGetValueW ( long wstr wstr ptr ptr ptr ) @ stdcall SHIsLowMemoryMachine(long) @@ -746,8 +746,8 @@ @ stdcall SHRegWriteUSValueA (long str long ptr long long) @ stdcall SHRegWriteUSValueW (long wstr long ptr long long) @ stdcall SHRegisterValidateTemplate(wstr long) -@ stdcall SHReleaseThreadRef() -@ stdcall SHSetThreadRef (ptr) +@ stdcall SHReleaseThreadRef() shcore.SHReleaseThreadRef +@ stdcall SHSetThreadRef(ptr) shcore.SHSetThreadRef @ stdcall SHSetValueA (long str str long ptr long) @ stdcall SHSetValueW (long wstr wstr long ptr long) @ stdcall SHSkipJunction(ptr ptr) diff --git a/dlls/shlwapi/shlwapi_main.c b/dlls/shlwapi/shlwapi_main.c index f466bb485aa..795bf5570e2 100644 --- a/dlls/shlwapi/shlwapi_main.c +++ b/dlls/shlwapi/shlwapi_main.c @@ -31,7 +31,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); DECLSPEC_HIDDEN HINSTANCE shlwapi_hInstance = 0; -DECLSPEC_HIDDEN DWORD SHLWAPI_ThreadRef_index = TLS_OUT_OF_INDEXES; /************************************************************************* * SHLWAPI {SHLWAPI} @@ -61,11 +60,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); shlwapi_hInstance = hinstDLL; - SHLWAPI_ThreadRef_index = TlsAlloc(); break; case DLL_PROCESS_DETACH: if (fImpLoad) break; - if (SHLWAPI_ThreadRef_index != TLS_OUT_OF_INDEXES) TlsFree(SHLWAPI_ThreadRef_index); break; } return TRUE; diff --git a/dlls/shlwapi/thread.c b/dlls/shlwapi/thread.c index 5726b855dc3..f58488aac04 100644 --- a/dlls/shlwapi/thread.c +++ b/dlls/shlwapi/thread.c @@ -108,316 +108,6 @@ HRESULT WINAPI _SHGetInstanceExplorer(IUnknown **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] *