From 2dd8a784c7e128f736228825a6b29ce5681fa7ba Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 18 May 2026 17:11:05 +0300 Subject: [PATCH] [SHLWAPI] Forward some functions to shcore.dll Some have a forwarder in the spec file, some will export the import-stub. This is how Wine has it. --- dll/win32/shlwapi/CMakeLists.txt | 2 +- dll/win32/shlwapi/istream.c | 540 -------------------- dll/win32/shlwapi/ordinal.c | 300 +---------- dll/win32/shlwapi/reg.c | 833 +------------------------------ dll/win32/shlwapi/regstream.c | 280 ----------- dll/win32/shlwapi/shlwapi.spec | 68 +-- dll/win32/shlwapi/string.c | 39 -- dll/win32/shlwapi/thread.c | 310 ------------ 8 files changed, 39 insertions(+), 2333 deletions(-) diff --git a/dll/win32/shlwapi/CMakeLists.txt b/dll/win32/shlwapi/CMakeLists.txt index c47698108fd..3fe8a6e600f 100644 --- a/dll/win32/shlwapi/CMakeLists.txt +++ b/dll/win32/shlwapi/CMakeLists.txt @@ -69,6 +69,6 @@ add_dependencies(shlwapi_autocomp psdk) set_module_type(shlwapi win32dll UNICODE) target_link_libraries(shlwapi uuid wine crtheap cppstl) add_delay_importlibs(shlwapi userenv oleaut32 ole32 comctl32 comdlg32 mpr mlang urlmon shell32 winmm version) -add_importlibs(shlwapi user32 gdi32 advapi32 wininet msvcrt kernel32 ntdll) +add_importlibs(shlwapi shcore user32 gdi32 advapi32 wininet msvcrt kernel32 ntdll) #add_pch(shlwapi precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET shlwapi DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/shlwapi/istream.c b/dll/win32/shlwapi/istream.c index 1da064014d7..f2b7e7bd34b 100644 --- a/dll/win32/shlwapi/istream.c +++ b/dll/win32/shlwapi/istream.c @@ -35,497 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); -#define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f) -#define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0) -#define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000) - -/* Layout of ISHFileStream object */ -typedef struct -{ - IStream IStream_iface; - LONG ref; - HANDLE hFile; - DWORD dwMode; - LPOLESTR lpszPath; - DWORD type; - DWORD grfStateBits; -} ISHFileStream; - -static inline ISHFileStream *impl_from_IStream(IStream *iface) -{ - return CONTAINING_RECORD(iface, ISHFileStream, IStream_iface); -} - -static HRESULT WINAPI IStream_fnCommit(IStream*,DWORD); - - -/************************************************************************** -* IStream_fnQueryInterface -*/ -static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IStream)) - { - IStream_AddRef(iface); - *ppvObj = iface; - return S_OK; - } - return E_NOINTERFACE; -} - -/************************************************************************** -* IStream_fnAddRef -*/ -static ULONG WINAPI IStream_fnAddRef(IStream *iface) -{ - ISHFileStream *This = impl_from_IStream(iface); - ULONG refCount = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); - - return refCount; -} - -/************************************************************************** -* IStream_fnRelease -*/ -static ULONG WINAPI IStream_fnRelease(IStream *iface) -{ - ISHFileStream *This = impl_from_IStream(iface); - ULONG refCount = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); - - if (!refCount) - { - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - LocalFree(This->lpszPath); - CloseHandle(This->hFile); - HeapFree(GetProcessHeap(), 0, This); - } - - return refCount; -} - -/************************************************************************** - * IStream_fnRead - */ -static HRESULT WINAPI IStream_fnRead(IStream *iface, void* pv, ULONG cb, ULONG* pcbRead) -{ - ISHFileStream *This = impl_from_IStream(iface); - DWORD dwRead = 0; - - TRACE("(%p,%p,0x%08x,%p)\n", This, pv, cb, pcbRead); - - if (!ReadFile(This->hFile, pv, cb, &dwRead, NULL)) - { - WARN("error %d reading file\n", GetLastError()); - return S_FALSE; - } - if (pcbRead) - *pcbRead = dwRead; - return dwRead == cb ? S_OK : S_FALSE; -} - -/************************************************************************** - * IStream_fnWrite - */ -static HRESULT WINAPI IStream_fnWrite(IStream *iface, const void* pv, ULONG cb, ULONG* pcbWritten) -{ - ISHFileStream *This = impl_from_IStream(iface); - DWORD dwWritten = 0; - - TRACE("(%p,%p,0x%08x,%p)\n", This, pv, cb, pcbWritten); - - switch (STGM_ACCESS_MODE(This->dwMode)) - { - case STGM_WRITE: - case STGM_READWRITE: - break; - default: - return STG_E_ACCESSDENIED; - } - - if (!WriteFile(This->hFile, pv, cb, &dwWritten, NULL)) - return HRESULT_FROM_WIN32(GetLastError()); - - if (pcbWritten) - *pcbWritten = dwWritten; - return S_OK; -} - -/************************************************************************** - * IStream_fnSeek - */ -static HRESULT WINAPI IStream_fnSeek(IStream *iface, LARGE_INTEGER dlibMove, - DWORD dwOrigin, ULARGE_INTEGER* pNewPos) -{ - ISHFileStream *This = impl_from_IStream(iface); - DWORD dwPos; - - TRACE("(%p,%d,%d,%p)\n", This, dlibMove.u.LowPart, dwOrigin, pNewPos); - - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - dwPos = SetFilePointer(This->hFile, dlibMove.u.LowPart, NULL, dwOrigin); - if( dwPos == INVALID_SET_FILE_POINTER ) - return HRESULT_FROM_WIN32(GetLastError()); - - if (pNewPos) - { - pNewPos->u.HighPart = 0; - pNewPos->u.LowPart = dwPos; - } - return S_OK; -} - -/************************************************************************** - * IStream_fnSetSize - */ -static HRESULT WINAPI IStream_fnSetSize(IStream *iface, ULARGE_INTEGER libNewSize) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p,%d)\n", This, libNewSize.u.LowPart); - - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - if( ! SetFilePointer( This->hFile, libNewSize.QuadPart, NULL, FILE_BEGIN ) ) - return E_FAIL; - - if( ! SetEndOfFile( This->hFile ) ) - return E_FAIL; - - return S_OK; -} - -/************************************************************************** - * IStream_fnCopyTo - */ -static HRESULT WINAPI IStream_fnCopyTo(IStream *iface, IStream* pstm, ULARGE_INTEGER cb, - ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) -{ - ISHFileStream *This = impl_from_IStream(iface); - char copyBuff[1024]; - ULONGLONG ulSize; - HRESULT hRet = S_OK; - - TRACE("(%p,%p,%d,%p,%p)\n", This, pstm, cb.u.LowPart, pcbRead, pcbWritten); - - if (pcbRead) - pcbRead->QuadPart = 0; - if (pcbWritten) - pcbWritten->QuadPart = 0; - - if (!pstm) - return S_OK; - - IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */ - - /* Copy data */ - ulSize = cb.QuadPart; - while (ulSize) - { - ULONG ulLeft, ulRead, ulWritten; - - ulLeft = ulSize > sizeof(copyBuff) ? sizeof(copyBuff) : ulSize; - - /* Read */ - hRet = IStream_fnRead(iface, copyBuff, ulLeft, &ulRead); - if (FAILED(hRet) || ulRead == 0) - break; - if (pcbRead) - pcbRead->QuadPart += ulRead; - - /* Write */ - hRet = IStream_fnWrite(pstm, copyBuff, ulRead, &ulWritten); - if (pcbWritten) - pcbWritten->QuadPart += ulWritten; - if (FAILED(hRet) || ulWritten != ulLeft) - break; - - ulSize -= ulLeft; - } - return hRet; -} - -/************************************************************************** - * IStream_fnCommit - */ -static HRESULT WINAPI IStream_fnCommit(IStream *iface, DWORD grfCommitFlags) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p,%d)\n", This, grfCommitFlags); - /* Currently unbuffered: This function is not needed */ - return S_OK; -} - -/************************************************************************** - * IStream_fnRevert - */ -static HRESULT WINAPI IStream_fnRevert(IStream *iface) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p)\n", This); - return E_NOTIMPL; -} - -/************************************************************************** - * IStream_fnLockUnlockRegion - */ -static HRESULT WINAPI IStream_fnLockUnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, DWORD dwLockType) -{ - ISHFileStream *This = impl_from_IStream(iface); - TRACE("(%p,%d,%d,%d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType); - return E_NOTIMPL; -} - /************************************************************************* - * IStream_fnStat - */ -static HRESULT WINAPI IStream_fnStat(IStream *iface, STATSTG* lpStat, - DWORD grfStatFlag) -{ - ISHFileStream *This = impl_from_IStream(iface); - BY_HANDLE_FILE_INFORMATION fi; - - TRACE("(%p,%p,%d)\n", This, lpStat, grfStatFlag); - - if (!lpStat) - return STG_E_INVALIDPOINTER; - - memset(&fi, 0, sizeof(fi)); - GetFileInformationByHandle(This->hFile, &fi); - - if (grfStatFlag & STATFLAG_NONAME) - lpStat->pwcsName = NULL; - else - lpStat->pwcsName = StrDupW(This->lpszPath); - lpStat->type = This->type; - lpStat->cbSize.u.LowPart = fi.nFileSizeLow; - lpStat->cbSize.u.HighPart = fi.nFileSizeHigh; - lpStat->mtime = fi.ftLastWriteTime; - lpStat->ctime = fi.ftCreationTime; - lpStat->atime = fi.ftLastAccessTime; - lpStat->grfMode = This->dwMode; - lpStat->grfLocksSupported = 0; - memcpy(&lpStat->clsid, &IID_IStream, sizeof(CLSID)); - lpStat->grfStateBits = This->grfStateBits; - lpStat->reserved = 0; - - return S_OK; -} - -/************************************************************************* - * IStream_fnClone - */ -static HRESULT WINAPI IStream_fnClone(IStream *iface, IStream** ppstm) -{ - ISHFileStream *This = impl_from_IStream(iface); - - TRACE("(%p)\n",This); - if (ppstm) - *ppstm = NULL; - return E_NOTIMPL; -} - -static const IStreamVtbl SHLWAPI_fsVTable = -{ - IStream_fnQueryInterface, - IStream_fnAddRef, - IStream_fnRelease, - IStream_fnRead, - IStream_fnWrite, - IStream_fnSeek, - IStream_fnSetSize, - IStream_fnCopyTo, - IStream_fnCommit, - IStream_fnRevert, - IStream_fnLockUnlockRegion, - IStream_fnLockUnlockRegion, - IStream_fnStat, - IStream_fnClone -}; - -/************************************************************************** - * IStream_Create - * - * Internal helper: Create and initialise a new file stream object. - */ -static IStream *IStream_Create(LPCWSTR lpszPath, HANDLE hFile, DWORD dwMode) -{ - ISHFileStream *fileStream; - - fileStream = HeapAlloc(GetProcessHeap(), 0, sizeof(ISHFileStream)); - if (!fileStream) return NULL; - - fileStream->IStream_iface.lpVtbl = &SHLWAPI_fsVTable; - fileStream->ref = 1; - fileStream->hFile = hFile; - fileStream->dwMode = dwMode; - fileStream->lpszPath = StrDupW(lpszPath); - fileStream->type = 0; /* FIXME */ - fileStream->grfStateBits = 0; /* FIXME */ - - TRACE ("Returning %p\n", fileStream); - return &fileStream->IStream_iface; -} - -/************************************************************************* - * SHCreateStreamOnFileEx [SHLWAPI.@] - * - * Create a stream on a file. - * - * PARAMS - * lpszPath [I] Path of file to create stream on - * dwMode [I] Mode to create stream in - * dwAttributes [I] Attributes of the file - * bCreate [I] Whether to create the file if it doesn't exist - * lpTemplate [I] Reserved, must be NULL - * lppStream [O] Destination for created stream - * - * RETURNS - * Success: S_OK. lppStream contains the new stream object - * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code - * - * NOTES - * This function is available in Unicode only. - */ -HRESULT WINAPI SHCreateStreamOnFileEx(LPCWSTR lpszPath, DWORD dwMode, - DWORD dwAttributes, BOOL bCreate, - IStream *lpTemplate, IStream **lppStream) -{ - DWORD dwAccess, dwShare, dwCreate; - HANDLE hFile; - - TRACE("(%s,%d,0x%08X,%d,%p,%p)\n", debugstr_w(lpszPath), dwMode, - dwAttributes, bCreate, lpTemplate, lppStream); - - if (!lpszPath || !lppStream || lpTemplate) - return E_INVALIDARG; - - *lppStream = NULL; - - /* Access */ - switch (STGM_ACCESS_MODE(dwMode)) - { - case STGM_WRITE: - case STGM_READWRITE: - dwAccess = GENERIC_READ|GENERIC_WRITE; - break; - case STGM_READ: - dwAccess = GENERIC_READ; - break; - default: - return E_INVALIDARG; - } - - /* Sharing */ - switch (STGM_SHARE_MODE(dwMode)) - { - case 0: - case STGM_SHARE_DENY_NONE: - dwShare = FILE_SHARE_READ|FILE_SHARE_WRITE; - break; - case STGM_SHARE_DENY_READ: - dwShare = FILE_SHARE_WRITE; - break; - case STGM_SHARE_DENY_WRITE: - dwShare = FILE_SHARE_READ; - break; - case STGM_SHARE_EXCLUSIVE: - dwShare = 0; - break; - default: - return E_INVALIDARG; - } - - switch(STGM_CREATE_MODE(dwMode)) - { - case STGM_FAILIFTHERE: - dwCreate = bCreate ? CREATE_NEW : OPEN_EXISTING; - break; - case STGM_CREATE: - dwCreate = CREATE_ALWAYS; - break; - default: - return E_INVALIDARG; - } - - /* Open HANDLE to file */ - hFile = CreateFileW(lpszPath, dwAccess, dwShare, NULL, dwCreate, - dwAttributes, 0); - - if(hFile == INVALID_HANDLE_VALUE) - return HRESULT_FROM_WIN32(GetLastError()); - - *lppStream = IStream_Create(lpszPath, hFile, dwMode); - - if(!*lppStream) - { - CloseHandle(hFile); - return E_OUTOFMEMORY; - } - return S_OK; -} - -/************************************************************************* - * SHCreateStreamOnFileW [SHLWAPI.@] - * - * See SHCreateStreamOnFileA. - */ -HRESULT WINAPI SHCreateStreamOnFileW(LPCWSTR lpszPath, DWORD dwMode, - IStream **lppStream) -{ - TRACE("(%s,%d,%p)\n", debugstr_w(lpszPath), dwMode, lppStream); - - if (!lpszPath || !lppStream) - return E_INVALIDARG; - - if ((dwMode & (STGM_CONVERT|STGM_DELETEONRELEASE|STGM_TRANSACTED)) != 0) - return E_INVALIDARG; - - return SHCreateStreamOnFileEx(lpszPath, dwMode, 0, FALSE, NULL, lppStream); -} - -/************************************************************************* - * SHCreateStreamOnFileA [SHLWAPI.@] - * - * Create a stream on a file. - * - * PARAMS - * lpszPath [I] Path of file to create stream on - * dwMode [I] Mode to create stream in - * lppStream [O] Destination for created IStream object - * - * RETURNS - * Success: S_OK. lppStream contains the new IStream object - * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code - */ -HRESULT WINAPI SHCreateStreamOnFileA(LPCSTR lpszPath, DWORD dwMode, - IStream **lppStream) -{ - WCHAR szPath[MAX_PATH]; - - TRACE("(%s,%d,%p)\n", debugstr_a(lpszPath), dwMode, lppStream); - - if (!lpszPath) - return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); - - MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, szPath, MAX_PATH); - return SHCreateStreamOnFileW(szPath, dwMode, lppStream); -} - -/************************************************************************* - * @ [SHLWAPI.184] * * Call IStream_Read() on a stream. * @@ -597,7 +107,6 @@ BOOL WINAPI SHIsEmptyStream(IStream *lpStream) } /************************************************************************* - * @ [SHLWAPI.212] * * Call IStream_Write() on a stream. * @@ -626,55 +135,6 @@ HRESULT WINAPI SHIStream_Write(IStream *lpStream, LPCVOID lpvSrc, ULONG ulSize) return hRet; } -/************************************************************************* - * @ [SHLWAPI.213] - * - * Seek to the start of a stream. - * - * PARAMS - * lpStream [I] IStream object - * - * RETURNS - * Success: S_OK. The current position within the stream is updated - * Failure: An HRESULT error code. - */ -HRESULT WINAPI IStream_Reset(IStream *lpStream) -{ - LARGE_INTEGER zero; - TRACE("(%p)\n", lpStream); - zero.QuadPart = 0; - return IStream_Seek(lpStream, zero, 0, NULL); -} - -/************************************************************************* - * @ [SHLWAPI.214] - * - * Get the size of a stream. - * - * PARAMS - * lpStream [I] IStream object - * lpulSize [O] Destination for size - * - * RETURNS - * Success: S_OK. lpulSize contains the size of the stream. - * Failure: An HRESULT error code. - */ -HRESULT WINAPI IStream_Size(IStream *lpStream, ULARGE_INTEGER* lpulSize) -{ - STATSTG statstg; - HRESULT hRet; - - TRACE("(%p,%p)\n", lpStream, lpulSize); - - memset(&statstg, 0, sizeof(statstg)); - - hRet = IStream_Stat(lpStream, &statstg, 1); - - if (SUCCEEDED(hRet) && lpulSize) - *lpulSize = statstg.cbSize; - return hRet; -} - #ifdef __REACTOS__ /************************************************************************* * IStream_ReadPidl [SHLWAPI.512] diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c index 165b639be87..080631d6bb7 100644 --- a/dll/win32/shlwapi/ordinal.c +++ b/dll/win32/shlwapi/ordinal.c @@ -58,12 +58,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); extern HINSTANCE shlwapi_hInstance; extern DWORD SHLWAPI_ThreadRef_index; +static HRESULT iunknown_query_service(IUnknown*,REFGUID,REFIID,LPVOID*); #ifdef __REACTOS__ -HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*); -#define iunknown_query_service IUnknown_QueryService HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, LPCSTR lpVerb); #else -static HRESULT iunknown_query_service(IUnknown*,REFGUID,REFIID,LPVOID*); HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,DWORD); #endif BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD); @@ -1231,29 +1229,6 @@ HRESULT WINAPI ConnectToConnectionPoint(IUnknown* lpUnkSink, REFIID riid, BOOL f return hRet; } -/************************************************************************* - * @ [SHLWAPI.169] - * - * Release an interface and zero a supplied pointer. - * - * PARAMS - * lpUnknown [I] Object to release - * - * RETURNS - * Nothing. - */ -void WINAPI IUnknown_AtomicRelease(IUnknown ** lpUnknown) -{ - TRACE("(%p)\n", lpUnknown); - - if(!lpUnknown || !*lpUnknown) return; - - TRACE("doing Release\n"); - - IUnknown_Release(*lpUnknown); - *lpUnknown = NULL; -} - /************************************************************************* * @ [SHLWAPI.170] * @@ -1401,44 +1376,6 @@ HRESULT WINAPI IUnknown_SetOwner(IUnknown *iface, IUnknown *pUnk) return hr; } -/************************************************************************* - * @ [SHLWAPI.174] - * - * Call either IObjectWithSite_SetSite() or IInternetSecurityManager_SetSecuritySite() on - * an object. - * - */ -HRESULT WINAPI IUnknown_SetSite( - IUnknown *obj, /* [in] OLE object */ - IUnknown *site) /* [in] Site interface */ -{ - HRESULT hr; - IObjectWithSite *iobjwithsite; - IInternetSecurityManager *isecmgr; - - if (!obj) return E_FAIL; - - hr = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (LPVOID *)&iobjwithsite); - TRACE("IID_IObjectWithSite QI ret=%08x, %p\n", hr, iobjwithsite); - if (SUCCEEDED(hr)) - { - hr = IObjectWithSite_SetSite(iobjwithsite, site); - TRACE("done IObjectWithSite_SetSite ret=%08x\n", hr); - IObjectWithSite_Release(iobjwithsite); - } - else - { - hr = IUnknown_QueryInterface(obj, &IID_IInternetSecurityManager, (LPVOID *)&isecmgr); - TRACE("IID_IInternetSecurityManager QI ret=%08x, %p\n", hr, isecmgr); - if (FAILED(hr)) return hr; - - hr = IInternetSecurityManager_SetSecuritySite(isecmgr, (IInternetSecurityMgrSite *)site); - TRACE("done IInternetSecurityManager_SetSecuritySite ret=%08x\n", hr); - IInternetSecurityManager_Release(isecmgr); - } - return hr; -} - /************************************************************************* * @ [SHLWAPI.175] * @@ -1480,26 +1417,7 @@ HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID *clsid) return hr; } -/************************************************************************* - * @ [SHLWAPI.176] - * - * Retrieve a Service Interface from an object. - * - * PARAMS - * lpUnknown [I] Object to get an IServiceProvider interface from - * sid [I] Service ID for IServiceProvider_QueryService() call - * riid [I] Function requested for QueryService call - * lppOut [O] Destination for the service interface pointer - * - * RETURNS - * Success: S_OK. lppOut contains an object providing the requested service - * Failure: An HRESULT error code - * - * NOTES - * lpUnknown is expected to support the IServiceProvider interface. - */ -HRESULT WINAPI IUnknown_QueryService(IUnknown* lpUnknown, REFGUID sid, REFIID riid, - LPVOID *lppOut) +static HRESULT iunknown_query_service(IUnknown* lpUnknown, REFGUID sid, REFIID riid, LPVOID *lppOut) { IServiceProvider* pService = NULL; HRESULT hRet; @@ -2174,32 +2092,6 @@ int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int return -1; /* Not found */ } - -/************************************************************************* - * @ [SHLWAPI.199] - * - * Copy an interface pointer - * - * PARAMS - * lppDest [O] Destination for copy - * lpUnknown [I] Source for copy - * - * RETURNS - * Nothing. - */ -VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown) -{ - TRACE("(%p,%p)\n", lppDest, lpUnknown); - - IUnknown_AtomicRelease(lppDest); - - if (lpUnknown) - { - IUnknown_AddRef(lpUnknown); - *lppDest = lpUnknown; - } -} - /************************************************************************* * @ [SHLWAPI.200] * @@ -2754,29 +2646,6 @@ LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM return DefWindowProcA(hWnd, uMessage, wParam, lParam); } -/************************************************************************* - * @ [SHLWAPI.256] - */ -HRESULT WINAPI IUnknown_GetSite(LPUNKNOWN lpUnknown, REFIID iid, PVOID *lppSite) -{ - HRESULT hRet = E_INVALIDARG; - LPOBJECTWITHSITE lpSite = NULL; - - TRACE("(%p,%s,%p)\n", lpUnknown, debugstr_guid(iid), lppSite); - - if (lpUnknown && iid && lppSite) - { - hRet = IUnknown_QueryInterface(lpUnknown, &IID_IObjectWithSite, - (void**)&lpSite); - if (SUCCEEDED(hRet) && lpSite) - { - hRet = IObjectWithSite_GetSite(lpSite, iid, lppSite); - IObjectWithSite_Release(lpSite); - } - } - return hRet; -} - /************************************************************************* * @ [SHLWAPI.257] * @@ -4211,171 +4080,6 @@ HRESULT WINAPI CLSIDFromStringWrap(LPCWSTR idstr, CLSID *id) return CLSIDFromString((LPCOLESTR)idstr, id); } -/************************************************************************* - * @ [SHLWAPI.437] - * - * Determine if the OS supports a given feature. - * - * PARAMS - * dwFeature [I] Feature requested (undocumented) - * - * RETURNS - * TRUE If the feature is available. - * FALSE If the feature is not available. - */ -BOOL WINAPI IsOS(DWORD feature) -{ -#ifdef __REACTOS__ - OSVERSIONINFOEXA osvi; - DWORD platform, majorv, minorv; - - osvi.dwOSVersionInfoSize = sizeof(osvi); - if (!GetVersionExA((OSVERSIONINFOA*)&osvi)) - { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); - if (!GetVersionExA((OSVERSIONINFOA*)&osvi)) - { - ERR("GetVersionEx failed\n"); - return FALSE; - } - osvi.wProductType = VER_NT_WORKSTATION; - osvi.wSuiteMask = 0; - } -#else - OSVERSIONINFOA osvi; - DWORD platform, majorv, minorv; - - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); - if(!GetVersionExA(&osvi)) { - ERR("GetVersionEx failed\n"); - return FALSE; - } -#endif - majorv = osvi.dwMajorVersion; - minorv = osvi.dwMinorVersion; - platform = osvi.dwPlatformId; - -#define ISOS_RETURN(x) \ - TRACE("(0x%x) ret=%d\n",feature,(x)); \ - return (x); - - switch(feature) { - case OS_WIN32SORGREATER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32s - || platform == VER_PLATFORM_WIN32_WINDOWS) - case OS_NT: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) - case OS_WIN95ORGREATER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS) - case OS_NT4ORGREATER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 4) - case OS_WIN2000ORGREATER_ALT: - case OS_WIN2000ORGREATER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5) - case OS_WIN98ORGREATER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 10) - case OS_WIN98_GOLD: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 10) - case OS_WIN2000PRO: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5) - case OS_WIN2000SERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) - case OS_WIN2000ADVSERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) - case OS_WIN2000DATACENTER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) - case OS_WIN2000TERMINAL: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && (minorv == 0 || minorv == 1)) - case OS_EMBEDDED: - FIXME("(OS_EMBEDDED) What should we return here?\n"); - return FALSE; - case OS_TERMINALCLIENT: - FIXME("(OS_TERMINALCLIENT) What should we return here?\n"); - return FALSE; - case OS_TERMINALREMOTEADMIN: - FIXME("(OS_TERMINALREMOTEADMIN) What should we return here?\n"); - return FALSE; - case OS_WIN95_GOLD: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv == 0) - case OS_MEORGREATER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_WINDOWS && minorv >= 90) - case OS_XPORGREATER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1) - case OS_HOME: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5 && minorv >= 1) - case OS_PROFESSIONAL: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) - case OS_DATACENTER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) - case OS_ADVSERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 5) - case OS_SERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) - case OS_TERMINALSERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) - case OS_PERSONALTERMINALSERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && minorv >= 1 && majorv >= 5) - case OS_FASTUSERSWITCHING: - FIXME("(OS_FASTUSERSWITCHING) What should we return here?\n"); - return TRUE; - case OS_WELCOMELOGONUI: - FIXME("(OS_WELCOMELOGONUI) What should we return here?\n"); - return FALSE; - case OS_DOMAINMEMBER: - FIXME("(OS_DOMAINMEMBER) What should we return here?\n"); - return TRUE; - case OS_ANYSERVER: -#ifdef __REACTOS__ - ISOS_RETURN(osvi.wProductType > VER_NT_WORKSTATION) -#else - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) -#endif - case OS_WOW6432: - { - BOOL is_wow64; - IsWow64Process(GetCurrentProcess(), &is_wow64); - return is_wow64; - } - case OS_WEBSERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) - case OS_SMALLBUSINESSSERVER: - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) - case OS_TABLETPC: - FIXME("(OS_TABLETPC) What should we return here?\n"); - return FALSE; - case OS_SERVERADMINUI: -#ifdef __REACTOS__ - { - DWORD value = FALSE, size = sizeof(value); - HKEY hKey = SHGetShellKey(SHKEY_Root_HKCU | SHKEY_Key_Explorer, L"Advanced", FALSE); - if (hKey) - { - SHQueryValueExW(hKey, L"ServerAdminUI", NULL, NULL, &value, &size); - RegCloseKey(hKey); - } - ISOS_RETURN(value); - } -#else - FIXME("(OS_SERVERADMINUI) What should we return here?\n"); - return FALSE; -#endif - case OS_MEDIACENTER: - FIXME("(OS_MEDIACENTER) What should we return here?\n"); - return FALSE; - case OS_APPLIANCE: - FIXME("(OS_APPLIANCE) What should we return here?\n"); - return FALSE; - case 0x25: /*OS_VISTAORGREATER*/ - ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT && majorv >= 6) - } - -#undef ISOS_RETURN - - WARN("(0x%x) unknown parameter\n",feature); - - return FALSE; -} - #ifdef __REACTOS__ /************************************************************************* * @ [SHLWAPI.438] diff --git a/dll/win32/shlwapi/reg.c b/dll/win32/shlwapi/reg.c index 228d066d98e..8d59a3b5330 100644 --- a/dll/win32/shlwapi/reg.c +++ b/dll/win32/shlwapi/reg.c @@ -1090,50 +1090,7 @@ LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType, return ret; } -/************************************************************************* - * SHRegGetPathA [SHLWAPI.@] - * - * Get a path from the registry. - * - * PARAMS - * hKey [I] Handle to registry key - * lpszSubKey [I] Name of sub key containing path to get - * lpszValue [I] Name of value containing path to get - * lpszPath [O] Buffer for returned path - * dwFlags [I] Reserved - * - * RETURNS - * Success: ERROR_SUCCESS. lpszPath contains the path. - * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA(). - */ -DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, - LPSTR lpszPath, DWORD dwFlags) -{ - DWORD dwSize = MAX_PATH; - - TRACE("(hkey=%p,%s,%s,%p,%d)\n", hKey, debugstr_a(lpszSubKey), - debugstr_a(lpszValue), lpszPath, dwFlags); - - return SHGetValueA(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize); -} - -/************************************************************************* - * SHRegGetPathW [SHLWAPI.@] - * - * See SHRegGetPathA. - */ -DWORD WINAPI SHRegGetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, - LPWSTR lpszPath, DWORD dwFlags) -{ - DWORD dwSize = MAX_PATH; - - TRACE("(hkey=%p,%s,%s,%p,%d)\n", hKey, debugstr_w(lpszSubKey), - debugstr_w(lpszValue), lpszPath, dwFlags); - - return SHGetValueW(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize); -} - - +#ifdef __REACTOS__ /* Should go to shcore, but we need kernelbase for that */ /************************************************************************* * SHRegSetPathA [SHLWAPI.@] * @@ -1228,477 +1185,7 @@ DWORD WINAPI SHRegSetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, lstrlenW(szBuff)); #endif } - -/************************************************************************* - * SHGetValueA [SHLWAPI.@] - * - * Get a value from the registry. - * - * PARAMS - * hKey [I] Handle to registry key - * lpszSubKey [I] Name of sub key containing value to get - * lpszValue [I] Name of value to get - * pwType [O] Pointer to the values type - * pvData [O] Pointer to the values data - * pcbData [O] Pointer to the values size - * - * RETURNS - * Success: ERROR_SUCCESS. Output parameters contain the details read. - * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA(). - */ -DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, - LPDWORD pwType, LPVOID pvData, LPDWORD pcbData) -{ - DWORD dwRet = 0; - HKEY hSubKey = 0; - - TRACE("(hkey=%p,%s,%s,%p,%p,%p)\n", hKey, debugstr_a(lpszSubKey), - debugstr_a(lpszValue), pwType, pvData, pcbData); - - /* lpszSubKey can be 0. In this case the value is taken from the - * current key. - */ - if(lpszSubKey) - dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); - - if (! dwRet) - { - /* SHQueryValueEx expands Environment strings */ - dwRet = SHQueryValueExA(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData); - if (hSubKey) RegCloseKey(hSubKey); - } - return dwRet; -} - -/************************************************************************* - * SHGetValueW [SHLWAPI.@] - * - * See SHGetValueA. - */ -DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, - LPDWORD pwType, LPVOID pvData, LPDWORD pcbData) -{ - DWORD dwRet = 0; - HKEY hSubKey = 0; - - TRACE("(hkey=%p,%s,%s,%p,%p,%p)\n", hKey, debugstr_w(lpszSubKey), - debugstr_w(lpszValue), pwType, pvData, pcbData); - - if(lpszSubKey) - dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); - - if (! dwRet) - { - dwRet = SHQueryValueExW(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData); - if (hSubKey) RegCloseKey(hSubKey); - } - return dwRet; -} - -/************************************************************************* - * SHSetValueA [SHLWAPI.@] - * - * Set a value in the registry. - * - * PARAMS - * hKey [I] Handle to registry key - * lpszSubKey [I] Name of sub key under hKey - * lpszValue [I] Name of value to set - * dwType [I] Type of the value - * pvData [I] Data of the value - * cbData [I] Size of the value - * - * RETURNS - * Success: ERROR_SUCCESS. The value is set with the data given. - * Failure: An error code from RegCreateKeyExA() or RegSetValueExA() - * - * NOTES - * If lpszSubKey does not exist, it is created before the value is set. If - * lpszSubKey is NULL or an empty string, then the value is added directly - * to hKey instead. - */ -DWORD WINAPI SHSetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, - DWORD dwType, LPCVOID pvData, DWORD cbData) -{ - DWORD dwRet = ERROR_SUCCESS, dwDummy; - HKEY hSubKey; - - TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_a(lpszSubKey), - debugstr_a(lpszValue), dwType, pvData, cbData); - - if (lpszSubKey && *lpszSubKey) - dwRet = RegCreateKeyExA(hKey, lpszSubKey, 0, NULL, - 0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy); - else - hSubKey = hKey; - if (!dwRet) - { - dwRet = RegSetValueExA(hSubKey, lpszValue, 0, dwType, pvData, cbData); - if (hSubKey != hKey) - RegCloseKey(hSubKey); - } - return dwRet; -} - -/************************************************************************* - * SHSetValueW [SHLWAPI.@] - * - * See SHSetValueA. - */ -DWORD WINAPI SHSetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, - DWORD dwType, LPCVOID pvData, DWORD cbData) -{ - DWORD dwRet = ERROR_SUCCESS, dwDummy; - HKEY hSubKey; - - TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_w(lpszSubKey), - debugstr_w(lpszValue), dwType, pvData, cbData); - - if (lpszSubKey && *lpszSubKey) - dwRet = RegCreateKeyExW(hKey, lpszSubKey, 0, NULL, - 0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy); - else - hSubKey = hKey; - if (!dwRet) - { - dwRet = RegSetValueExW(hSubKey, lpszValue, 0, dwType, pvData, cbData); - if (hSubKey != hKey) - RegCloseKey(hSubKey); - } - return dwRet; -} - -/************************************************************************* - * SHQueryInfoKeyA [SHLWAPI.@] - * - * Get information about a registry key. See RegQueryInfoKeyA(). - * - * RETURNS - * The result of calling RegQueryInfoKeyA(). - */ -LONG WINAPI SHQueryInfoKeyA(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax, - LPDWORD pwValues, LPDWORD pwValueMax) -{ - TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax, - pwValues, pwValueMax); - return RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax, - NULL, pwValues, pwValueMax, NULL, NULL, NULL); -} - -/************************************************************************* - * SHQueryInfoKeyW [SHLWAPI.@] - * - * See SHQueryInfoKeyA. - */ -LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax, - LPDWORD pwValues, LPDWORD pwValueMax) -{ - TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax, - pwValues, pwValueMax); - return RegQueryInfoKeyW(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax, - NULL, pwValues, pwValueMax, NULL, NULL, NULL); -} - -/************************************************************************* - * SHQueryValueExA [SHLWAPI.@] - * - * Get a value from the registry, expanding environment variable strings. - * - * PARAMS - * hKey [I] Handle to registry key - * lpszValue [I] Name of value to query - * lpReserved [O] Reserved for future use; must be NULL - * pwType [O] Optional pointer updated with the values type - * pvData [O] Optional pointer updated with the values data - * pcbData [O] Optional pointer updated with the values size - * - * RETURNS - * Success: ERROR_SUCCESS. Any non NULL output parameters are updated with - * information about the value. - * Failure: ERROR_OUTOFMEMORY if memory allocation fails, or the type of the - * data is REG_EXPAND_SZ and pcbData is NULL. Otherwise an error - * code from RegQueryValueExA() or ExpandEnvironmentStringsA(). - * - * NOTES - * Either pwType, pvData or pcbData may be NULL if the caller doesn't want - * the type, data or size information for the value. - * - * If the type of the data is REG_EXPAND_SZ, it is expanded to REG_SZ. The - * value returned will be truncated if it is of type REG_SZ and bigger than - * the buffer given to store it. - * - * REG_EXPAND_SZ: - * case-1: the unexpanded string is smaller than the expanded one - * subcase-1: the buffer is too small to hold the unexpanded string: - * function fails and returns the size of the unexpanded string. - * - * subcase-2: buffer is too small to hold the expanded string: - * the function return success (!!) and the result is truncated - * *** This is clearly an error in the native implementation. *** - * - * case-2: the unexpanded string is bigger than the expanded one - * The buffer must have enough space to hold the unexpanded - * string even if the result is smaller. - * - */ -DWORD WINAPI SHQueryValueExA( HKEY hKey, LPCSTR lpszValue, - LPDWORD lpReserved, LPDWORD pwType, - LPVOID pvData, LPDWORD pcbData) -{ - DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen; - - TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_a(lpszValue), - lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0); - - if (pcbData) dwUnExpDataLen = *pcbData; - - dwRet = RegQueryValueExA(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen); - - if (pcbData && (dwType == REG_EXPAND_SZ)) - { - DWORD nBytesToAlloc; - - /* Expand type REG_EXPAND_SZ into REG_SZ */ - LPSTR szData; - - /* If the caller didn't supply a buffer or the buffer is too small we have - * to allocate our own - */ - if ((!pvData) || (dwRet == ERROR_MORE_DATA) ) - { - char cNull = '\0'; - nBytesToAlloc = dwUnExpDataLen; - - szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); - RegQueryValueExA (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc); - dwExpDataLen = ExpandEnvironmentStringsA(szData, &cNull, 1); - dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); - LocalFree(szData); - } - else - { - nBytesToAlloc = (lstrlenA(pvData)+1) * sizeof (CHAR); - szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); - lstrcpyA(szData, pvData); - dwExpDataLen = ExpandEnvironmentStringsA(szData, pvData, *pcbData / sizeof(CHAR)); - if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA; - dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); - LocalFree(szData); - } - } - - /* Update the type and data size if the caller wanted them */ - if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ; - if ( pwType ) *pwType = dwType; - if ( pcbData ) *pcbData = dwUnExpDataLen; - return dwRet; -} - - -/************************************************************************* - * SHQueryValueExW [SHLWAPI.@] - * - * See SHQueryValueExA. - */ -DWORD WINAPI SHQueryValueExW(HKEY hKey, LPCWSTR lpszValue, - LPDWORD lpReserved, LPDWORD pwType, - LPVOID pvData, LPDWORD pcbData) -{ - DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen; - - TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_w(lpszValue), - lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0); - - if (pcbData) dwUnExpDataLen = *pcbData; - - dwRet = RegQueryValueExW(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen); - if (dwRet!=ERROR_SUCCESS && dwRet!=ERROR_MORE_DATA) - return dwRet; - - if (pcbData && (dwType == REG_EXPAND_SZ)) - { - DWORD nBytesToAlloc; - - /* Expand type REG_EXPAND_SZ into REG_SZ */ - LPWSTR szData; - - /* If the caller didn't supply a buffer or the buffer is too small we have - * to allocate our own - */ - if ((!pvData) || (dwRet == ERROR_MORE_DATA) ) - { - WCHAR cNull = '\0'; - nBytesToAlloc = dwUnExpDataLen; - - szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); - RegQueryValueExW (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc); - dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1); - dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); - LocalFree(szData); - } - else - { - nBytesToAlloc = (lstrlenW(pvData) + 1) * sizeof(WCHAR); - szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); - lstrcpyW(szData, pvData); - dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, *pcbData/sizeof(WCHAR) ); - if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA; - dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); - LocalFree(szData); - } - } - - /* Update the type and data size if the caller wanted them */ - if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ; - if ( pwType ) *pwType = dwType; - if ( pcbData ) *pcbData = dwUnExpDataLen; - return dwRet; -} - -/************************************************************************* - * SHDeleteKeyA [SHLWAPI.@] - * - * Delete a registry key and any sub keys/values present - * - * This function forwards to the unicode version directly, to avoid - * handling subkeys that are not representable in ASCII. - * - * PARAMS - * hKey [I] Handle to registry key - * lpszSubKey [I] Name of sub key to delete - * - * RETURNS - * Success: ERROR_SUCCESS. The key is deleted. - * Failure: An error code from RegOpenKeyExA(), RegQueryInfoKeyA(), - * RegEnumKeyExA() or RegDeleteKeyA(). - */ -DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey) -{ - WCHAR subkeyW[MAX_PATH]; - - MultiByteToWideChar (CP_ACP, 0, lpszSubKey, -1, subkeyW, sizeof(subkeyW)/sizeof(WCHAR)); - return SHDeleteKeyW(hKey, subkeyW); -} - -/************************************************************************* - * SHDeleteKeyW [SHLWAPI.@] - * - * See SHDeleteKeyA. - */ -DWORD WINAPI SHDeleteKeyW(HKEY hKey, LPCWSTR lpszSubKey) -{ - DWORD dwRet, dwMaxSubkeyLen = 0, dwSize; - WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; - HKEY hSubKey = 0; - - TRACE("(hkey=%p,%s)\n", hKey, debugstr_w(lpszSubKey)); - - dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); - if(!dwRet) - { - /* Find the maximum subkey length so that we can allocate a buffer */ - dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, - &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL); - if(!dwRet) - { - dwMaxSubkeyLen++; - if (dwMaxSubkeyLen > sizeof(szNameBuf)/sizeof(WCHAR)) - /* Name too big: alloc a buffer for it */ - lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(WCHAR)); - - if(!lpszName) - dwRet = ERROR_NOT_ENOUGH_MEMORY; - else - { - while (dwRet == ERROR_SUCCESS) - { - dwSize = dwMaxSubkeyLen; - dwRet = RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, NULL, NULL, NULL); - if (dwRet == ERROR_SUCCESS || dwRet == ERROR_MORE_DATA) - dwRet = SHDeleteKeyW(hSubKey, lpszName); - } - if (dwRet == ERROR_NO_MORE_ITEMS) - dwRet = ERROR_SUCCESS; - - if (lpszName != szNameBuf) - HeapFree(GetProcessHeap(), 0, lpszName); /* Free buffer if allocated */ - } - } - - RegCloseKey(hSubKey); - if(!dwRet) - dwRet = RegDeleteKeyW(hKey, lpszSubKey); - } - return dwRet; -} - -/************************************************************************* - * SHDeleteEmptyKeyA [SHLWAPI.@] - * - * Delete a registry key with no sub keys. - * - * PARAMS - * hKey [I] Handle to registry key - * lpszSubKey [I] Name of sub key to delete - * - * RETURNS - * Success: ERROR_SUCCESS. The key is deleted. - * Failure: If the key is not empty, returns ERROR_KEY_HAS_CHILDREN. Otherwise - * returns an error code from RegOpenKeyExA(), RegQueryInfoKeyA() or - * RegDeleteKeyA(). - */ -DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey) -{ - DWORD dwRet, dwKeyCount = 0; - HKEY hSubKey = 0; - - TRACE("(hkey=%p,%s)\n", hKey, debugstr_a(lpszSubKey)); - - dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); - if(!dwRet) - { - dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, - NULL, NULL, NULL, NULL, NULL, NULL, NULL); - RegCloseKey(hSubKey); - if(!dwRet) - { - if (!dwKeyCount) - dwRet = RegDeleteKeyA(hKey, lpszSubKey); - else - dwRet = ERROR_KEY_HAS_CHILDREN; - } - } - return dwRet; -} - -/************************************************************************* - * SHDeleteEmptyKeyW [SHLWAPI.@] - * - * See SHDeleteEmptyKeyA. - */ -DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey) -{ - DWORD dwRet, dwKeyCount = 0; - HKEY hSubKey = 0; - - TRACE("(hkey=%p, %s)\n", hKey, debugstr_w(lpszSubKey)); - - dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); - if(!dwRet) - { - dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwKeyCount, - NULL, NULL, NULL, NULL, NULL, NULL, NULL); - RegCloseKey(hSubKey); - if(!dwRet) - { - if (!dwKeyCount) - dwRet = RegDeleteKeyW(hKey, lpszSubKey); - else - dwRet = ERROR_KEY_HAS_CHILDREN; - } - } - return dwRet; -} +#endif /* __REACTOS__ */ /************************************************************************* * SHDeleteOrphanKeyA [SHLWAPI.@] @@ -1766,138 +1253,6 @@ DWORD WINAPI SHDeleteOrphanKeyW(HKEY hKey, LPCWSTR lpszSubKey) return dwRet; } -/************************************************************************* - * SHDeleteValueA [SHLWAPI.@] - * - * Delete a value from the registry. - * - * PARAMS - * hKey [I] Handle to registry key - * lpszSubKey [I] Name of sub key containing value to delete - * lpszValue [I] Name of value to delete - * - * RETURNS - * Success: ERROR_SUCCESS. The value is deleted. - * Failure: An error code from RegOpenKeyExA() or RegDeleteValueA(). - */ -DWORD WINAPI SHDeleteValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue) -{ - DWORD dwRet; - HKEY hSubKey; - - TRACE("(hkey=%p,%s,%s)\n", hKey, debugstr_a(lpszSubKey), debugstr_a(lpszValue)); - - dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_SET_VALUE, &hSubKey); - if (!dwRet) - { - dwRet = RegDeleteValueA(hSubKey, lpszValue); - RegCloseKey(hSubKey); - } - return dwRet; -} - -/************************************************************************* - * SHDeleteValueW [SHLWAPI.@] - * - * See SHDeleteValueA. - */ -DWORD WINAPI SHDeleteValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue) -{ - DWORD dwRet; - HKEY hSubKey; - - TRACE("(hkey=%p,%s,%s)\n", hKey, debugstr_w(lpszSubKey), debugstr_w(lpszValue)); - - dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_SET_VALUE, &hSubKey); - if (!dwRet) - { - dwRet = RegDeleteValueW(hSubKey, lpszValue); - RegCloseKey(hSubKey); - } - return dwRet; -} - -/************************************************************************* - * SHEnumKeyExA [SHLWAPI.@] - * - * Enumerate sub keys in a registry key. - * - * PARAMS - * hKey [I] Handle to registry key - * dwIndex [I] Index of key to enumerate - * lpszSubKey [O] Pointer updated with the subkey name - * pwLen [O] Pointer updated with the subkey length - * - * RETURNS - * Success: ERROR_SUCCESS. lpszSubKey and pwLen are updated. - * Failure: An error code from RegEnumKeyExA(). - */ -LONG WINAPI SHEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpszSubKey, - LPDWORD pwLen) -{ - TRACE("(hkey=%p,%d,%s,%p)\n", hKey, dwIndex, debugstr_a(lpszSubKey), pwLen); - - return RegEnumKeyExA(hKey, dwIndex, lpszSubKey, pwLen, NULL, NULL, NULL, NULL); -} - -/************************************************************************* - * SHEnumKeyExW [SHLWAPI.@] - * - * See SHEnumKeyExA. - */ -LONG WINAPI SHEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpszSubKey, - LPDWORD pwLen) -{ - TRACE("(hkey=%p,%d,%s,%p)\n", hKey, dwIndex, debugstr_w(lpszSubKey), pwLen); - - return RegEnumKeyExW(hKey, dwIndex, lpszSubKey, pwLen, NULL, NULL, NULL, NULL); -} - -/************************************************************************* - * SHEnumValueA [SHLWAPI.@] - * - * Enumerate values in a registry key. - * - * PARAMS - * hKey [I] Handle to registry key - * dwIndex [I] Index of key to enumerate - * lpszValue [O] Pointer updated with the values name - * pwLen [O] Pointer updated with the values length - * pwType [O] Pointer updated with the values type - * pvData [O] Pointer updated with the values data - * pcbData [O] Pointer updated with the values size - * - * RETURNS - * Success: ERROR_SUCCESS. Output parameters are updated. - * Failure: An error code from RegEnumValueA(). - */ -LONG WINAPI SHEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpszValue, - LPDWORD pwLen, LPDWORD pwType, - LPVOID pvData, LPDWORD pcbData) -{ - TRACE("(hkey=%p,%d,%s,%p,%p,%p,%p)\n", hKey, dwIndex, - debugstr_a(lpszValue), pwLen, pwType, pvData, pcbData); - - return RegEnumValueA(hKey, dwIndex, lpszValue, pwLen, NULL, - pwType, pvData, pcbData); -} - -/************************************************************************* - * SHEnumValueW [SHLWAPI.@] - * - * See SHEnumValueA. - */ -LONG WINAPI SHEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpszValue, - LPDWORD pwLen, LPDWORD pwType, - LPVOID pvData, LPDWORD pcbData) -{ - TRACE("(hkey=%p,%d,%s,%p,%p,%p,%p)\n", hKey, dwIndex, - debugstr_w(lpszValue), pwLen, pwType, pvData, pcbData); - - return RegEnumValueW(hKey, dwIndex, lpszValue, pwLen, NULL, - pwType, pvData, pcbData); -} - /************************************************************************* * @ [SHLWAPI.205] * @@ -2242,194 +1597,10 @@ BOOL WINAPI UnregisterExtensionForMIMETypeW(LPCWSTR lpszType) return TRUE; } -/************************************************************************* - * SHRegDuplicateHKey [SHLWAPI.@] - * - * Create a duplicate of a registry handle. - * - * PARAMS - * hKey [I] key to duplicate. - * - * RETURNS - * A new handle pointing to the same key as hKey. - */ -HKEY WINAPI SHRegDuplicateHKey(HKEY hKey) -{ - HKEY newKey = 0; - - RegOpenKeyExA(hKey, 0, 0, MAXIMUM_ALLOWED, &newKey); - TRACE("new key is %p\n", newKey); - return newKey; -} - - -/************************************************************************* - * SHCopyKeyA [SHLWAPI.@] - * - * Copy a key and its values/sub keys to another location. - * - * PARAMS - * hKeySrc [I] Source key to copy from - * lpszSrcSubKey [I] Sub key under hKeySrc, or NULL to use hKeySrc directly - * hKeyDst [I] Destination key - * dwReserved [I] Reserved, must be 0 - * - * RETURNS - * Success: ERROR_SUCCESS. The key is copied to the destination key. - * Failure: A standard windows error code. - * - * NOTES - * If hKeyDst is a key under hKeySrc, this function will misbehave - * (It will loop until out of stack, or the registry is full). This - * bug is present in Win32 also. - */ -DWORD WINAPI SHCopyKeyA(HKEY hKeySrc, LPCSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved) -{ - WCHAR szSubKeyW[MAX_PATH]; - - TRACE("(hkey=%p,%s,%p08x,%d)\n", hKeySrc, debugstr_a(lpszSrcSubKey), hKeyDst, dwReserved); - - if (lpszSrcSubKey) - MultiByteToWideChar(CP_ACP, 0, lpszSrcSubKey, -1, szSubKeyW, MAX_PATH); - - return SHCopyKeyW(hKeySrc, lpszSrcSubKey ? szSubKeyW : NULL, hKeyDst, dwReserved); -} - -/************************************************************************* - * SHCopyKeyW [SHLWAPI.@] - * - * See SHCopyKeyA. - */ -DWORD WINAPI SHCopyKeyW(HKEY hKeySrc, LPCWSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved) -{ - DWORD dwKeyCount = 0, dwValueCount = 0, dwMaxKeyLen = 0; - DWORD dwMaxValueLen = 0, dwMaxDataLen = 0, i; - BYTE buff[1024]; - LPVOID lpBuff = buff; - WCHAR szName[MAX_PATH], *lpszName = szName; - DWORD dwRet = S_OK; - - TRACE("hkey=%p,%s,%p08x,%d)\n", hKeySrc, debugstr_w(lpszSrcSubKey), hKeyDst, dwReserved); - - if(!hKeyDst || !hKeySrc) - dwRet = ERROR_INVALID_PARAMETER; - else - { - /* Open source key */ - if(lpszSrcSubKey) - dwRet = RegOpenKeyExW(hKeySrc, lpszSrcSubKey, 0, KEY_ALL_ACCESS, &hKeySrc); - - if(dwRet) - hKeyDst = NULL; /* Don't close this key since we didn't open it */ - else - { - /* Get details about sub keys and values */ - dwRet = RegQueryInfoKeyW(hKeySrc, NULL, NULL, NULL, &dwKeyCount, &dwMaxKeyLen, - NULL, &dwValueCount, &dwMaxValueLen, &dwMaxDataLen, - NULL, NULL); - if(!dwRet) - { - if (dwMaxValueLen > dwMaxKeyLen) - dwMaxKeyLen = dwMaxValueLen; /* Get max size for key/value names */ - - if (dwMaxKeyLen++ > MAX_PATH - 1) - lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxKeyLen * sizeof(WCHAR)); - - if (dwMaxDataLen > sizeof(buff)) - lpBuff = HeapAlloc(GetProcessHeap(), 0, dwMaxDataLen); - - if (!lpszName || !lpBuff) - dwRet = ERROR_NOT_ENOUGH_MEMORY; - } - } - } - - /* Copy all the sub keys */ - for(i = 0; i < dwKeyCount && !dwRet; i++) - { - HKEY hSubKeySrc, hSubKeyDst; - DWORD dwSize = dwMaxKeyLen; - - dwRet = RegEnumKeyExW(hKeySrc, i, lpszName, &dwSize, NULL, NULL, NULL, NULL); - - if(!dwRet) - { - /* Open source sub key */ - dwRet = RegOpenKeyExW(hKeySrc, lpszName, 0, KEY_READ, &hSubKeySrc); - - if(!dwRet) - { - /* Create destination sub key */ - dwRet = RegCreateKeyW(hKeyDst, lpszName, &hSubKeyDst); - - if(!dwRet) - { - /* Recursively copy keys and values from the sub key */ - dwRet = SHCopyKeyW(hSubKeySrc, NULL, hSubKeyDst, 0); - RegCloseKey(hSubKeyDst); - } - } - RegCloseKey(hSubKeySrc); - } - } - - /* Copy all the values in this key */ - for (i = 0; i < dwValueCount && !dwRet; i++) - { - DWORD dwNameSize = dwMaxKeyLen, dwType, dwLen = dwMaxDataLen; - - dwRet = RegEnumValueW(hKeySrc, i, lpszName, &dwNameSize, NULL, &dwType, lpBuff, &dwLen); - - if (!dwRet) - dwRet = SHSetValueW(hKeyDst, NULL, lpszName, dwType, lpBuff, dwLen); - } - - /* Free buffers if allocated */ - if (lpszName != szName) - HeapFree(GetProcessHeap(), 0, lpszName); - if (lpBuff != buff) - HeapFree(GetProcessHeap(), 0, lpBuff); - - if (lpszSrcSubKey && hKeyDst) - RegCloseKey(hKeyDst); - return dwRet; -} - /* * The following functions are ORDINAL ONLY: */ -/************************************************************************* - * @ [SHLWAPI.280] - * - * Read an integer value from the registry, falling back to a default. - * - * PARAMS - * hKey [I] Registry key to read from - * lpszValue [I] Value name to read - * iDefault [I] Default value to return - * - * RETURNS - * The value contained in the given registry value if present, otherwise - * iDefault. - */ -int WINAPI SHRegGetIntW(HKEY hKey, LPCWSTR lpszValue, int iDefault) -{ - TRACE("(%p,%s,%d)\n", hKey, debugstr_w(lpszValue), iDefault); - - if (hKey) - { - WCHAR szBuff[32]; - DWORD dwSize = sizeof(szBuff); - szBuff[0] = '\0'; - SHQueryValueExW(hKey, lpszValue, 0, 0, szBuff, &dwSize); - - if(*szBuff >= '0' && *szBuff <= '9') - return StrToIntW(szBuff); - } - return iDefault; -} - /************************************************************************* * @ [SHLWAPI.343] * diff --git a/dll/win32/shlwapi/regstream.c b/dll/win32/shlwapi/regstream.c index 01f13765703..3755395c0ef 100644 --- a/dll/win32/shlwapi/regstream.c +++ b/dll/win32/shlwapi/regstream.c @@ -369,70 +369,6 @@ static const IStreamVtbl rstvt = IStream_fnClone }; -/* Methods overridden by the dummy stream */ - -/************************************************************************** - * IStream_fnAddRefDummy - */ -static ULONG WINAPI IStream_fnAddRefDummy(IStream *iface) -{ - ISHRegStream *This = impl_from_IStream(iface); - TRACE("(%p)\n", This); - return 2; -} - -/************************************************************************** - * IStream_fnReleaseDummy - */ -static ULONG WINAPI IStream_fnReleaseDummy(IStream *iface) -{ - ISHRegStream *This = impl_from_IStream(iface); - TRACE("(%p)\n", This); - return 1; -} - -/************************************************************************** - * IStream_fnReadDummy - */ -static HRESULT WINAPI IStream_fnReadDummy(IStream *iface, LPVOID pv, ULONG cb, ULONG* pcbRead) -{ - if (pcbRead) - *pcbRead = 0; - return E_NOTIMPL; -} - -static const IStreamVtbl DummyRegStreamVTable = -{ - IStream_fnQueryInterface, - IStream_fnAddRefDummy, /* Overridden */ - IStream_fnReleaseDummy, /* Overridden */ - IStream_fnReadDummy, /* Overridden */ - IStream_fnWrite, - IStream_fnSeek, - IStream_fnSetSize, - IStream_fnCopyTo, - IStream_fnCommit, - IStream_fnRevert, - IStream_fnLockUnlockRegion, - IStream_fnLockUnlockRegion, - IStream_fnStat, - IStream_fnClone -}; - -/* Dummy registry stream object */ -static ISHRegStream rsDummyRegStream = -{ - { &DummyRegStreamVTable }, - 1, - NULL, - NULL, - 0, - 0, - STGM_READWRITE, - {NULL}, - FALSE -}; - /************************************************************************** * IStream_Create * @@ -460,222 +396,6 @@ static ISHRegStream *IStream_Create(HKEY hKey, LPBYTE pbBuffer, DWORD dwLength) return regStream; } -/************************************************************************* - * SHOpenRegStream2A [SHLWAPI.@] - * - * Create a stream to read binary registry data. - * - * PARAMS - * hKey [I] Registry handle - * pszSubkey [I] The sub key name - * pszValue [I] The value name under the sub key - * dwMode [I] Unused - * - * RETURNS - * Success: An IStream interface referring to the registry data - * Failure: NULL, if the registry key could not be opened or is not binary. - */ -IStream * WINAPI SHOpenRegStream2A(HKEY hKey, LPCSTR pszSubkey, - LPCSTR pszValue,DWORD dwMode) -{ - ISHRegStream *tmp; - HKEY hStrKey = NULL; - LPBYTE lpBuff = NULL; - DWORD dwLength = 0; - LONG ret; - - TRACE("(%p,%s,%s,0x%08x)\n", hKey, pszSubkey, pszValue, dwMode); - - if (dwMode == STGM_READ) - ret = RegOpenKeyExA(hKey, pszSubkey, 0, KEY_READ, &hStrKey); - else /* in write mode we make sure the subkey exits */ - ret = RegCreateKeyExA(hKey, pszSubkey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hStrKey, NULL); - - if (ret == ERROR_SUCCESS) - { - if (dwMode == STGM_READ || dwMode == STGM_READWRITE) - { - /* read initial data */ - ret = RegQueryValueExA(hStrKey, pszValue, 0, 0, 0, &dwLength); - if (ret == ERROR_SUCCESS && dwLength) - { - lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); - RegQueryValueExA(hStrKey, pszValue, 0, 0, lpBuff, &dwLength); - } - } - - if (!dwLength) - lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); - - tmp = IStream_Create(hStrKey, lpBuff, dwLength); - if(tmp) - { - if(pszValue) - { - int len = lstrlenA(pszValue) + 1; - tmp->u.keyNameA = HeapAlloc(GetProcessHeap(), 0, len); - memcpy(tmp->u.keyNameA, pszValue, len); - } - - tmp->dwMode = dwMode; - tmp->bUnicode = FALSE; - return &tmp->IStream_iface; - } - } - - HeapFree(GetProcessHeap(), 0, lpBuff); - if (hStrKey) - RegCloseKey(hStrKey); - return NULL; -} - -/************************************************************************* - * SHOpenRegStream2W [SHLWAPI.@] - * - * See SHOpenRegStream2A. - */ -IStream * WINAPI SHOpenRegStream2W(HKEY hKey, LPCWSTR pszSubkey, - LPCWSTR pszValue, DWORD dwMode) -{ - ISHRegStream *tmp; - HKEY hStrKey = NULL; - LPBYTE lpBuff = NULL; - DWORD dwLength = 0; - LONG ret; - - TRACE("(%p,%s,%s,0x%08x)\n", hKey, debugstr_w(pszSubkey), - debugstr_w(pszValue), dwMode); - - if (dwMode == STGM_READ) - ret = RegOpenKeyExW(hKey, pszSubkey, 0, KEY_READ, &hStrKey); - else /* in write mode we make sure the subkey exits */ - ret = RegCreateKeyExW(hKey, pszSubkey, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &hStrKey, NULL); - - if (ret == ERROR_SUCCESS) - { - if (dwMode == STGM_READ || dwMode == STGM_READWRITE) - { - /* read initial data */ - ret = RegQueryValueExW(hStrKey, pszValue, 0, 0, 0, &dwLength); - if (ret == ERROR_SUCCESS && dwLength) - { - lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); - RegQueryValueExW(hStrKey, pszValue, 0, 0, lpBuff, &dwLength); - } - } - - if (!dwLength) - lpBuff = HeapAlloc(GetProcessHeap(), 0, dwLength); - - tmp = IStream_Create(hStrKey, lpBuff, dwLength); - if(tmp) - { - if(pszValue) - { - int len = lstrlenW(pszValue) + 1; - tmp->u.keyNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - memcpy(tmp->u.keyNameW, pszValue, len * sizeof(WCHAR)); - } - - tmp->dwMode = dwMode; - tmp->bUnicode = TRUE; - return &tmp->IStream_iface; - } - } - - HeapFree(GetProcessHeap(), 0, lpBuff); - if (hStrKey) - RegCloseKey(hStrKey); - return NULL; -} - -/************************************************************************* - * SHOpenRegStreamA [SHLWAPI.@] - * - * Create a stream to read binary registry data. - * - * PARAMS - * hKey [I] Registry handle - * pszSubkey [I] The sub key name - * pszValue [I] The value name under the sub key - * dwMode [I] STGM mode for opening the file - * - * RETURNS - * Success: An IStream interface referring to the registry data - * Failure: If the registry key could not be opened or is not binary, - * A dummy (empty) IStream object is returned. - */ -IStream * WINAPI SHOpenRegStreamA(HKEY hkey, LPCSTR pszSubkey, - LPCSTR pszValue, DWORD dwMode) -{ - IStream *iStream; - - TRACE("(%p,%s,%s,0x%08x)\n", hkey, pszSubkey, pszValue, dwMode); - - iStream = SHOpenRegStream2A(hkey, pszSubkey, pszValue, dwMode); - return iStream ? iStream : &rsDummyRegStream.IStream_iface; -} - -/************************************************************************* - * SHOpenRegStreamW [SHLWAPI.@] - * - * See SHOpenRegStreamA. - */ -IStream * WINAPI SHOpenRegStreamW(HKEY hkey, LPCWSTR pszSubkey, - LPCWSTR pszValue, DWORD dwMode) -{ - IStream *iStream; - - TRACE("(%p,%s,%s,0x%08x)\n", hkey, debugstr_w(pszSubkey), - debugstr_w(pszValue), dwMode); - iStream = SHOpenRegStream2W(hkey, pszSubkey, pszValue, dwMode); - return iStream ? iStream : &rsDummyRegStream.IStream_iface; -} - -/************************************************************************* - * @ [SHLWAPI.12] - * - * Create an IStream object on a block of memory. - * - * PARAMS - * lpbData [I] Memory block to create the IStream object on - * dwDataLen [I] Length of data block - * - * RETURNS - * Success: A pointer to the IStream object. - * Failure: NULL, if any parameters are invalid or an error occurs. - * - * NOTES - * A copy of the memory pointed to by lpbData is made, and is freed - * when the stream is released. - */ -IStream * WINAPI SHCreateMemStream(const BYTE *lpbData, UINT dwDataLen) -{ - ISHRegStream *strm = NULL; - LPBYTE lpbDup; - - TRACE("(%p,%d)\n", lpbData, dwDataLen); - - if (!lpbData) - dwDataLen = 0; - - lpbDup = HeapAlloc(GetProcessHeap(), 0, dwDataLen); - - if (lpbDup) - { - memcpy(lpbDup, lpbData, dwDataLen); - strm = IStream_Create(NULL, lpbDup, dwDataLen); - - if (!strm) - HeapFree(GetProcessHeap(), 0, lpbDup); - } -#ifdef __REACTOS__ - if (!strm) - return NULL; -#endif - return &strm->IStream_iface; -} - /************************************************************************* * SHCreateStreamWrapper [SHLWAPI.@] * diff --git a/dll/win32/shlwapi/shlwapi.spec b/dll/win32/shlwapi/shlwapi.spec index 1c2ec9ffd01..f9802b621cf 100644 --- a/dll/win32/shlwapi/shlwapi.spec +++ b/dll/win32/shlwapi/shlwapi.spec @@ -9,11 +9,11 @@ 9 stdcall -ordinal SHUnlockShared(ptr) 10 stdcall -ordinal SHFreeShared(ptr long) 11 stdcall -noname SHMapHandle(ptr long long long long) -12 stdcall -noname SHCreateMemStream(ptr long) +12 stdcall -ordinal SHCreateMemStream(ptr long) shcore.SHCreateMemStream 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) @@ -166,14 +166,14 @@ 166 stdcall -noname SHIsEmptyStream(ptr) 167 stdcall -noname SHSetParentHwnd(long ptr) 168 stdcall -noname ConnectToConnectionPoint(ptr ptr long ptr ptr ptr) -169 stdcall -noname IUnknown_AtomicRelease(long) +169 stdcall -ordinal IUnknown_AtomicRelease(ptr) shcore.IUnknown_AtomicRelease 170 stdcall -noname PathSkipLeadingSlashesA(str) 171 stdcall -noname SHIsSameObject(ptr ptr) 172 stdcall -noname IUnknown_GetWindow(ptr ptr) 173 stdcall -noname IUnknown_SetOwner(ptr ptr) -174 stdcall -noname IUnknown_SetSite(ptr ptr) +174 stdcall -ordinal IUnknown_SetSite(ptr ptr) shcore.IUnknown_SetSite 175 stdcall -noname IUnknown_GetClassID(ptr ptr) -176 stdcall -noname IUnknown_QueryService(ptr ptr ptr ptr) +176 stdcall -ordinal IUnknown_QueryService(ptr ptr ptr ptr) shcore.IUnknown_QueryService 177 stdcall -noname SHLoadMenuPopup(ptr wstr) 178 stdcall -noname SHPropagateMessage(ptr long long long long) 179 stdcall -noname SHMenuIndexFromID(long long) @@ -181,7 +181,7 @@ 181 stdcall -noname SHEnableMenuItem(long long long) 182 stdcall -noname SHCheckMenuItem(long long long) 183 stdcall -noname SHRegisterClassA(ptr) -184 stdcall -noname IStream_Read(ptr ptr long) SHIStream_Read +184 stdcall -ordinal IStream_Read(ptr ptr long) shcore.IStream_Read 185 stdcall -noname SHMessageBoxCheckA(ptr str str long long str) 186 stdcall -noname SHSimulateDrop(ptr ptr long ptr ptr) 187 stdcall -noname SHLoadFromPropertyBag(ptr ptr) @@ -196,7 +196,7 @@ 196 stdcall -noname SHVerbExistsNA(str ptr ptr long) 197 stdcall -noname SHFillRectClr(long ptr long) 198 stdcall -noname SHSearchMapInt(ptr ptr long long) -199 stdcall -noname IUnknown_Set(ptr ptr) +199 stdcall -ordinal IUnknown_Set(ptr ptr) shcore.IUnknown_Set 200 stdcall -noname MayQSForward(ptr ptr ptr long ptr ptr) 201 stdcall -noname MayExecForward(ptr long ptr long long ptr ptr) 202 stdcall -noname IsQSForward(ptr long ptr) @@ -209,9 +209,9 @@ 209 stdcall -noname FDSA_Destroy(ptr) 210 stdcall -noname FDSA_InsertItem(ptr long ptr) 211 stdcall -noname FDSA_DeleteItem(ptr long) -212 stdcall -noname IStream_Write(ptr ptr long) SHIStream_Write -213 stdcall -noname IStream_Reset(ptr) -214 stdcall -noname IStream_Size(ptr ptr) +212 stdcall -ordinal IStream_Write(ptr ptr long) shcore.IStream_Write +213 stdcall -ordinal IStream_Reset(ptr) shcore.IStream_Reset +214 stdcall -ordinal IStream_Size(ptr ptr) shcore.IStream_Size 215 stdcall -noname SHAnsiToUnicode(str ptr long) 216 stdcall -noname SHAnsiToUnicodeCP(long str ptr long) 217 stdcall -noname SHUnicodeToAnsi(wstr ptr ptr) @@ -253,7 +253,7 @@ 253 stub -noname StopWatchExA 254 stub -noname StopWatchExW 255 stub -noname EventTraceHandler -256 stdcall -noname IUnknown_GetSite(ptr ptr ptr) +256 stdcall -ordinal IUnknown_GetSite(ptr ptr ptr) shcore.IUnknown_GetSite 257 stdcall -noname SHCreateWorkerWindowA(ptr ptr long long ptr long) 258 stub -noname SHRegisterWaitForSingleObject 259 stub -noname SHUnregisterWait @@ -342,8 +342,8 @@ 342 stdcall -noname SHInterlockedCompareExchange(ptr ptr ptr) 343 stdcall -noname SHRegGetCLSIDKeyA(ptr str long long ptr) 344 stdcall -noname SHRegGetCLSIDKeyW(ptr wstr long long ptr) -345 stdcall -noname SHAnsiToAnsi(str ptr long) -346 stdcall -noname SHUnicodeToUnicode(wstr ptr long) +345 stdcall -ordinal SHAnsiToAnsi(str ptr long) shcore.SHAnsiToAnsi +346 stdcall -ordinal SHUnicodeToUnicode(wstr ptr long) shcore.SHUnicodeToUnicode 347 stdcall -noname RegDeleteValueWrapW(long wstr) advapi32.RegDeleteValueW 348 stdcall -noname SHGetFileDescriptionW(wstr wstr wstr ptr ptr) 349 stdcall -noname SHGetFileDescriptionA(str str str ptr ptr) @@ -690,35 +690,35 @@ 688 stdcall PathUnquoteSpacesA(str) 689 stdcall PathUnquoteSpacesW(wstr) 690 stdcall SHAutoComplete(ptr long) -691 stdcall SHCopyKeyA(long str long long) -692 stdcall SHCopyKeyW(long wstr long long) +@ stdcall SHCopyKeyA(long str long long) shcore.SHCopyKeyA +@ stdcall SHCopyKeyW(long wstr long long) shcore.SHCopyKeyW 693 stdcall SHCreateShellPalette(long) -694 stdcall SHCreateStreamOnFileA(str long ptr) -695 stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) -696 stdcall SHCreateStreamOnFileW(wstr long ptr) +@ stdcall SHCreateStreamOnFileA(str long ptr) shcore.SHCreateStreamOnFileA +@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) shcore.SHCreateStreamOnFileEx +@ stdcall SHCreateStreamOnFileW(wstr long ptr) shcore.SHCreateStreamOnFileW 697 stdcall SHCreateStreamWrapper(ptr ptr long ptr) -698 stdcall SHCreateThreadRef(ptr ptr) -699 stdcall SHDeleteEmptyKeyA(long ptr) -700 stdcall SHDeleteEmptyKeyW(long ptr) -701 stdcall SHDeleteKeyA(long str) -702 stdcall SHDeleteKeyW(long wstr) +@ stdcall SHCreateThreadRef(ptr ptr) shcore.SHCreateThreadRef +@ stdcall SHDeleteEmptyKeyA(long str) shcore.SHDeleteEmptyKeyA +@ stdcall SHDeleteEmptyKeyW(long wstr) shcore.SHDeleteEmptyKeyW +@ stdcall SHDeleteKeyA(long str) shcore.SHDeleteKeyA +@ stdcall SHDeleteKeyW(long wstr) shcore.SHDeleteKeyW 703 stdcall SHDeleteOrphanKeyA(long str) 704 stdcall SHDeleteOrphanKeyW(long wstr) 705 stdcall SHDeleteValueA(long str str) 706 stdcall SHDeleteValueW(long wstr wstr) -707 stdcall SHEnumKeyExA(long long str ptr) -708 stdcall SHEnumKeyExW(long long wstr ptr) -709 stdcall SHEnumValueA(long long str ptr ptr ptr ptr) -710 stdcall SHEnumValueW(long long wstr ptr ptr ptr ptr) +@ stdcall SHEnumKeyExA(long long str ptr) shcore.SHEnumKeyExA +@ stdcall SHEnumKeyExW(long long wstr ptr) shcore.SHEnumKeyExW +@ stdcall SHEnumValueA(long long str ptr ptr ptr ptr) shcore.SHEnumValueA +@ stdcall SHEnumValueW(long long wstr ptr ptr ptr ptr) shcore.SHEnumValueW 711 stdcall SHGetInverseCMAP(ptr long) -712 stdcall SHGetThreadRef(ptr) +@ stdcall SHGetThreadRef(ptr) shcore.SHGetThreadRef 713 stdcall SHGetValueA(long str str ptr ptr ptr) 714 stdcall SHGetValueW(long wstr wstr ptr ptr ptr) 715 stdcall SHIsLowMemoryMachine(long) -716 stdcall SHOpenRegStream2A(long str str long) -717 stdcall SHOpenRegStream2W(long wstr wstr long) -718 stdcall SHOpenRegStreamA(long str str long) -719 stdcall SHOpenRegStreamW(long wstr wstr long) +@ stdcall SHOpenRegStream2A(long str str long) shcore.SHOpenRegStream2A +@ stdcall SHOpenRegStream2W(long wstr wstr long) shcore.SHOpenRegStream2W +@ stdcall SHOpenRegStreamA(long str str long) shcore.SHOpenRegStreamA +@ stdcall SHOpenRegStreamW(long wstr wstr long) shcore.SHOpenRegStreamW 720 stdcall SHQueryInfoKeyA(long ptr ptr ptr ptr) 721 stdcall SHQueryInfoKeyW(long ptr ptr ptr ptr) 722 stdcall SHQueryValueExA(long str ptr ptr ptr ptr) @@ -756,8 +756,8 @@ 754 stdcall SHRegWriteUSValueA(long str long ptr long long) 755 stdcall SHRegWriteUSValueW(long wstr long ptr long long) 756 stdcall SHRegisterValidateTemplate(wstr long) -757 stdcall SHReleaseThreadRef() -758 stdcall SHSetThreadRef(ptr) +@ stdcall SHReleaseThreadRef() shcore.SHReleaseThreadRef +@ stdcall SHSetThreadRef(ptr) shcore.SHSetThreadRef 759 stdcall SHSetValueA(long str str long ptr long) 760 stdcall SHSetValueW(long wstr wstr long ptr long) 761 stdcall SHSkipJunction(ptr ptr) diff --git a/dll/win32/shlwapi/string.c b/dll/win32/shlwapi/string.c index 86769386399..d7e21d56a27 100644 --- a/dll/win32/shlwapi/string.c +++ b/dll/win32/shlwapi/string.c @@ -2958,45 +2958,6 @@ INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen) return SHUnicodeToAnsiCP(CP_ACP, lpSrcStr, lpDstStr, iLen); } -/************************************************************************* - * @ [SHLWAPI.345] - * - * Copy one string to another. - * - * PARAMS - * lpszSrc [I] Source string to copy - * lpszDst [O] Destination for copy - * iLen [I] Length of lpszDst in characters - * - * RETURNS - * The length of the copied string, including the terminating NUL. lpszDst - * contains iLen characters of lpszSrc. - */ -DWORD WINAPI SHAnsiToAnsi(LPCSTR lpszSrc, LPSTR lpszDst, int iLen) -{ - LPSTR lpszRet; - - TRACE("(%s,%p,0x%08x)\n", debugstr_a(lpszSrc), lpszDst, iLen); - - lpszRet = StrCpyNXA(lpszDst, lpszSrc, iLen); - return lpszRet - lpszDst + 1; -} - -/************************************************************************* - * @ [SHLWAPI.346] - * - * Unicode version of SSHAnsiToAnsi. - */ -DWORD WINAPI SHUnicodeToUnicode(LPCWSTR lpszSrc, LPWSTR lpszDst, int iLen) -{ - LPWSTR lpszRet; - - TRACE("(%s,%p,0x%08x)\n", debugstr_w(lpszSrc), lpszDst, iLen); - - lpszRet = StrCpyNXW(lpszDst, lpszSrc, iLen); - return lpszRet - lpszDst + 1; -} - /************************************************************************* * @ [SHLWAPI.364] * diff --git a/dll/win32/shlwapi/thread.c b/dll/win32/shlwapi/thread.c index 0fe8ff2cae1..ee79f73c040 100644 --- a/dll/win32/shlwapi/thread.c +++ b/dll/win32/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] *