[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.
This commit is contained in:
Timo Kreuzer
2026-05-18 17:11:05 +03:00
parent d829baa006
commit 2dd8a784c7
8 changed files with 39 additions and 2333 deletions

View File

@@ -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)

View File

@@ -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]

View File

@@ -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]

View File

@@ -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]
*

View File

@@ -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.@]
*

View File

@@ -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)

View File

@@ -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]
*

View File

@@ -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]
*