Commit 68b6f56b authored by Juergen Schmied's avatar Juergen Schmied Committed by Alexandre Julliard

Reimplemented SHRegGetPathA/W, SHGetValueA/W, SHRegGetPathA/W.

parent 7919d5a1
......@@ -1213,6 +1213,17 @@ DWORD WINAPI SHLWAPI_174(
}
/*************************************************************************
* @ [SHLWAPI.175]
*
* NOTE:
* Param1 can be an IShellFolder Object
*/
HRESULT WINAPI SHLWAPI_175 (LPVOID x, LPVOID y)
{
FIXME("(%p %p) stub\n", x,y);
return E_FAIL;
}
/*************************************************************************
* @ [SHLWAPI.176]
*
* Function appears to be interface to IServiceProvider::QueryService
......
......@@ -34,8 +34,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
typedef DWORD (WINAPI *RegQueryFn)(HKEY,LPCVOID,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
static const char *lpszContentTypeA = "Content Type";
static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
......@@ -727,24 +725,12 @@ LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType,
DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
LPSTR lpszPath, DWORD dwFlags)
{
HKEY hSubKey;
DWORD dwType = REG_SZ, dwSize = MAX_PATH, dwRet = ERROR_SUCCESS;
DWORD dwSize = MAX_PATH;
TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_a(lpszSubKey),
debugstr_a(lpszValue), lpszPath, dwFlags);
if (lpszSubKey && *lpszSubKey)
dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
else
hSubKey = hKey;
if (!dwRet)
dwRet = SHQueryValueExA(hSubKey, lpszValue, NULL, &dwType, lpszPath, &dwSize);
if (hSubKey != hKey)
RegCloseKey(hSubKey);
return dwRet;
return SHGetValueA(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
}
/*************************************************************************
......@@ -755,24 +741,12 @@ DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
DWORD WINAPI SHRegGetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
LPWSTR lpszPath, DWORD dwFlags)
{
HKEY hSubKey;
DWORD dwType = REG_SZ, dwSize = MAX_PATH, dwRet = ERROR_SUCCESS;
DWORD dwSize = MAX_PATH;
TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_w(lpszSubKey),
debugstr_w(lpszValue), lpszPath, dwFlags);
if (lpszSubKey && *lpszSubKey)
dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
else
hSubKey = hKey;
if (!dwRet)
dwRet = SHQueryValueExW(hSubKey, lpszValue, NULL, &dwType, lpszPath, &dwSize);
if (hSubKey != hKey)
RegCloseKey(hSubKey);
return dwRet;
return SHGetValueW(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
}
......@@ -844,22 +818,28 @@ DWORD WINAPI SHRegSetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
*
* RETURNS
* Success: ERROR_SUCCESS. Output parameters contain the details read.
* Failure: An error code from RegOpenKeyExA or RegQueryValueExA.
* 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;
HKEY hSubKey;
DWORD dwRet = 0;
HKEY hSubKey = 0;
TRACE("(hkey=0x%08x,%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)
if (! dwRet)
{
dwRet = RegQueryValueExA(hSubKey, lpszValue, 0, pwType, pvData, pcbData);
RegCloseKey(hSubKey);
/* SHQueryValueEx expands Environment strings */
dwRet = SHQueryValueExA(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
if (hSubKey) RegCloseKey(hSubKey);
}
return dwRet;
}
......@@ -872,17 +852,19 @@ DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
{
DWORD dwRet;
HKEY hSubKey;
DWORD dwRet = 0;
HKEY hSubKey = 0;
TRACE("(hkey=0x%08x,%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)
if (! dwRet)
{
dwRet = RegQueryValueExW(hSubKey, lpszValue, 0, pwType, pvData, pcbData);
RegCloseKey(hSubKey);
dwRet = SHQueryValueExW(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
if (hSubKey) RegCloseKey(hSubKey);
}
return dwRet;
}
......@@ -990,86 +972,67 @@ LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax,
NULL, pwValues, pwValueMax, NULL, NULL, NULL);
}
/*************************************************************************
* SHQueryValueExAW
*
* Internal implementation of SHQueryValueExA/SHQueryValueExW.
*/
static DWORD WINAPI SHQueryValueExAW(RegQueryFn pfn,
HKEY hKey, LPCVOID lpszValue,
LPDWORD lpReserved, LPDWORD pwType,
LPBYTE pvData, LPDWORD pcbData)
{
/*
DWORD dwRet, dwType, dwDataLen;
if (pcbData)
dwDataLen = *pcbData;
FIXME("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_a(lpszValue),
lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
if (pcbData) dwDataLen = *pcbData;
dwRet = pfn(hKey, lpszValue, lpReserved, &dwType, pvData, &dwDataLen);
dwRet = RegQueryValueExA(hKey, lpszValue, lpReserved, &dwType, pvData, &dwDataLen);
if (!dwRet)
{
if (dwType == REG_EXPAND_SZ)
{
/* Expand type REG_EXPAND_SZ into REG_SZ */
LPSTR szExpand;
LPBYTE pData = pvData;
if (!pData)
{
/* Create a buffer to hold the data, to get the size */
if (!pcbData ||
!(pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pcbData)))
if (!pcbData || !(pData = (LPBYTE) LocalAlloc(GMEM_ZEROINIT, *pcbData)))
return ERROR_OUTOFMEMORY;
/* Read the data in to the buffer */
if ((dwRet = pfn(hKey, lpszValue, lpReserved, &dwType,
pData, &dwDataLen)))
if ((dwRet = RegQueryValueExA (hKey, lpszValue, lpReserved, &dwType, pData, &dwDataLen)))
return dwRet;
}
if (!pcbData && pData != pvData)
{
/* Note: In this case the caller will crash under Win32 */
WARN("Invalid pcbData would crash under Win32!");
return ERROR_OUTOFMEMORY;
}
szExpand = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pcbData);
szExpand = (LPBYTE) LocalAlloc(GMEM_ZEROINIT, *pcbData);
if (!szExpand)
{
if (pData != pvData)
HeapFree(GetProcessHeap(), 0, pData);
if ( pData != pvData ) LocalFree((HLOCAL)pData);
return ERROR_OUTOFMEMORY;
}
if ((ExpandEnvironmentStringsA(pvData, szExpand, *pcbData) <= 0))
if ((ExpandEnvironmentStringsA(pvData, szExpand, *pcbData) > 0))
{
dwDataLen = strlen(szExpand) + 1;
strncpy(pvData, szExpand, *pcbData);
}
else
{
if (pData != pvData)
HeapFree(GetProcessHeap(), 0, pData);
HeapFree(GetProcessHeap(), 0, szExpand);
if ( pData != pvData ) LocalFree((HLOCAL)pData);
LocalFree((HLOCAL)szExpand);
return GetLastError();
}
if (pData != pvData)
HeapFree(GetProcessHeap(), 0, pData);
HeapFree(GetProcessHeap(), 0, szExpand);
if (pData != pvData) LocalFree((HLOCAL)pData);
LocalFree((HLOCAL)szExpand);
dwType = REG_SZ;
}
if (dwType == REG_SZ && pvData && pcbData && dwDataLen >= *pcbData)
{
/* String type too long: truncate it */
pvData[*pcbData] = '\0';
((LPBYTE) pvData)[*pcbData] = '\0';
}
}
/* Update the type and data size if the caller wanted them */
if (pwType)
*pwType = dwType;
if (pcbData)
*pcbData = dwDataLen;
if ( pwType ) *pwType = dwType;
if ( pcbData ) *pcbData = dwDataLen;
return dwRet;
}
*/
/*************************************************************************
* SHQueryValueExA [SHLWAPI.@]
......@@ -1078,7 +1041,7 @@ static DWORD WINAPI SHQueryValueExAW(RegQueryFn pfn,
*
* PARAMS
* hKey [I] Handle to registry key
* lpszValue [I] Name of value to delete
* 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
......@@ -1099,17 +1062,60 @@ static DWORD WINAPI SHQueryValueExAW(RegQueryFn pfn,
* value returned will be truncated if it is of type REG_SZ and bigger than
* the buffer given to store it.
*/
DWORD WINAPI SHQueryValueExA(HKEY hKey, LPCSTR lpszValue,
DWORD WINAPI SHQueryValueExA( HKEY hKey, LPCSTR lpszValue,
LPDWORD lpReserved, LPDWORD pwType,
LPVOID pvData, LPDWORD pcbData)
{
DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
TRACE("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_a(lpszValue),
lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
return SHQueryValueExAW((RegQueryFn)RegQueryValueExA, hKey, lpszValue,
lpReserved, pwType, pvData, pcbData);
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 to small we have
* to allocate our own
*/
if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
{
char cNull = '\0';
nBytesToAlloc = (!pvData || (dwRet == ERROR_MORE_DATA)) ? dwUnExpDataLen : *pcbData;
szData = (LPSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc);
RegQueryValueExA (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
dwExpDataLen = ExpandEnvironmentStringsA(szData, &cNull, 1);
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) szData);
}
else
{
nBytesToAlloc = lstrlenA(pvData) * sizeof (CHAR);
szData = (LPSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc + 1);
lstrcpyA(szData, pvData);
dwExpDataLen = ExpandEnvironmentStringsA(szData, pvData, *pcbData / sizeof(CHAR));
if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) 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.@]
*
......@@ -1119,11 +1125,53 @@ DWORD WINAPI SHQueryValueExW(HKEY hKey, LPCWSTR lpszValue,
LPDWORD lpReserved, LPDWORD pwType,
LPVOID pvData, LPDWORD pcbData)
{
DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
TRACE("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_w(lpszValue),
lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
return SHQueryValueExAW((RegQueryFn)RegQueryValueExW, hKey, lpszValue,
lpReserved, pwType, pvData, pcbData);
if (pcbData) dwUnExpDataLen = *pcbData;
dwRet = RegQueryValueExW(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen);
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 to small we have
* to allocate our own
*/
if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
{
WCHAR cNull = '\0';
nBytesToAlloc = (!pvData || (dwRet == ERROR_MORE_DATA)) ? dwUnExpDataLen : *pcbData;
szData = (LPWSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc);
RegQueryValueExW (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1);
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) szData);
}
else
{
nBytesToAlloc = lstrlenW(pvData) * sizeof(WCHAR);
szData = (LPWSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc + 1);
lstrcpyW(szData, pvData);
dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, *pcbData/sizeof(WCHAR) );
if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) 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;
}
/*************************************************************************
......
......@@ -178,7 +178,7 @@ debug_channels (shell)
172 stdcall @(ptr ptr) SHLWAPI_172
173 stub @
174 stdcall @(ptr ptr) SHLWAPI_174
175 stub @
175 stdcall @(ptr ptr) SHLWAPI_175
176 stdcall @(ptr ptr ptr ptr) SHLWAPI_176
177 stub @
178 stub @
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment