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( ...@@ -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] * @ [SHLWAPI.176]
* *
* Function appears to be interface to IServiceProvider::QueryService * Function appears to be interface to IServiceProvider::QueryService
......
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell); WINE_DEFAULT_DEBUG_CHANNEL(shell);
typedef DWORD (WINAPI *RegQueryFn)(HKEY,LPCVOID,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
static const char *lpszContentTypeA = "Content Type"; static const char *lpszContentTypeA = "Content Type";
static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'}; 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, ...@@ -727,24 +725,12 @@ LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType,
DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
LPSTR lpszPath, DWORD dwFlags) LPSTR lpszPath, DWORD dwFlags)
{ {
HKEY hSubKey; DWORD dwSize = MAX_PATH;
DWORD dwType = REG_SZ, dwSize = MAX_PATH, dwRet = ERROR_SUCCESS;
TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_a(lpszSubKey), TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_a(lpszSubKey),
debugstr_a(lpszValue), lpszPath, dwFlags); debugstr_a(lpszValue), lpszPath, dwFlags);
if (lpszSubKey && *lpszSubKey) return SHGetValueA(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
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;
} }
/************************************************************************* /*************************************************************************
...@@ -755,24 +741,12 @@ DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, ...@@ -755,24 +741,12 @@ DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
DWORD WINAPI SHRegGetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, DWORD WINAPI SHRegGetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
LPWSTR lpszPath, DWORD dwFlags) LPWSTR lpszPath, DWORD dwFlags)
{ {
HKEY hSubKey; DWORD dwSize = MAX_PATH;
DWORD dwType = REG_SZ, dwSize = MAX_PATH, dwRet = ERROR_SUCCESS;
TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_w(lpszSubKey), TRACE("(hkey=0x%08x,%s,%s,%p,%ld)\n", hKey, debugstr_w(lpszSubKey),
debugstr_w(lpszValue), lpszPath, dwFlags); debugstr_w(lpszValue), lpszPath, dwFlags);
if (lpszSubKey && *lpszSubKey) return SHGetValueW(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
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;
} }
...@@ -844,22 +818,28 @@ DWORD WINAPI SHRegSetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, ...@@ -844,22 +818,28 @@ DWORD WINAPI SHRegSetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
* *
* RETURNS * RETURNS
* Success: ERROR_SUCCESS. Output parameters contain the details read. * 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, DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
LPDWORD pwType, LPVOID pvData, LPDWORD pcbData) LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
{ {
DWORD dwRet; DWORD dwRet = 0;
HKEY hSubKey; HKEY hSubKey = 0;
TRACE("(hkey=0x%08x,%s,%s,%p,%p,%p)\n", hKey, debugstr_a(lpszSubKey), TRACE("(hkey=0x%08x,%s,%s,%p,%p,%p)\n", hKey, debugstr_a(lpszSubKey),
debugstr_a(lpszValue), pwType, pvData, pcbData); 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); dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
if (!dwRet)
if (! dwRet)
{ {
dwRet = RegQueryValueExA(hSubKey, lpszValue, 0, pwType, pvData, pcbData); /* SHQueryValueEx expands Environment strings */
RegCloseKey(hSubKey); dwRet = SHQueryValueExA(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
if (hSubKey) RegCloseKey(hSubKey);
} }
return dwRet; return dwRet;
} }
...@@ -872,17 +852,19 @@ DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, ...@@ -872,17 +852,19 @@ DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
LPDWORD pwType, LPVOID pvData, LPDWORD pcbData) LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
{ {
DWORD dwRet; DWORD dwRet = 0;
HKEY hSubKey; HKEY hSubKey = 0;
TRACE("(hkey=0x%08x,%s,%s,%p,%p,%p)\n", hKey, debugstr_w(lpszSubKey), TRACE("(hkey=0x%08x,%s,%s,%p,%p,%p)\n", hKey, debugstr_w(lpszSubKey),
debugstr_w(lpszValue), pwType, pvData, pcbData); debugstr_w(lpszValue), pwType, pvData, pcbData);
if(lpszSubKey)
dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
if (!dwRet)
if (! dwRet)
{ {
dwRet = RegQueryValueExW(hSubKey, lpszValue, 0, pwType, pvData, pcbData); dwRet = SHQueryValueExW(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
RegCloseKey(hSubKey); if (hSubKey) RegCloseKey(hSubKey);
} }
return dwRet; return dwRet;
} }
...@@ -990,86 +972,67 @@ LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax, ...@@ -990,86 +972,67 @@ LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax,
NULL, pwValues, pwValueMax, NULL, NULL, NULL); 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; DWORD dwRet, dwType, dwDataLen;
if (pcbData) FIXME("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_a(lpszValue),
dwDataLen = *pcbData; 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 (!dwRet)
{ {
if (dwType == REG_EXPAND_SZ) if (dwType == REG_EXPAND_SZ)
{ {
/* Expand type REG_EXPAND_SZ into REG_SZ */
LPSTR szExpand; LPSTR szExpand;
LPBYTE pData = pvData; LPBYTE pData = pvData;
if (!pData) if (!pData)
{ {
/* Create a buffer to hold the data, to get the size */ if (!pcbData || !(pData = (LPBYTE) LocalAlloc(GMEM_ZEROINIT, *pcbData)))
if (!pcbData ||
!(pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pcbData)))
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
/* Read the data in to the buffer */
if ((dwRet = pfn(hKey, lpszValue, lpReserved, &dwType, if ((dwRet = RegQueryValueExA (hKey, lpszValue, lpReserved, &dwType, pData, &dwDataLen)))
pData, &dwDataLen)))
return dwRet; return dwRet;
} }
if (!pcbData && pData != pvData) if (!pcbData && pData != pvData)
{ {
/* Note: In this case the caller will crash under Win32 */
WARN("Invalid pcbData would crash under Win32!"); WARN("Invalid pcbData would crash under Win32!");
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
szExpand = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pcbData); szExpand = (LPBYTE) LocalAlloc(GMEM_ZEROINIT, *pcbData);
if (!szExpand) if (!szExpand)
{ {
if (pData != pvData) if ( pData != pvData ) LocalFree((HLOCAL)pData);
HeapFree(GetProcessHeap(), 0, pData);
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
if ((ExpandEnvironmentStringsA(pvData, szExpand, *pcbData) <= 0)) if ((ExpandEnvironmentStringsA(pvData, szExpand, *pcbData) > 0))
{ {
dwDataLen = strlen(szExpand) + 1; dwDataLen = strlen(szExpand) + 1;
strncpy(pvData, szExpand, *pcbData); strncpy(pvData, szExpand, *pcbData);
} }
else else
{ {
if (pData != pvData) if ( pData != pvData ) LocalFree((HLOCAL)pData);
HeapFree(GetProcessHeap(), 0, pData); LocalFree((HLOCAL)szExpand);
HeapFree(GetProcessHeap(), 0, szExpand);
return GetLastError(); return GetLastError();
} }
if (pData != pvData) if (pData != pvData) LocalFree((HLOCAL)pData);
HeapFree(GetProcessHeap(), 0, pData); LocalFree((HLOCAL)szExpand);
HeapFree(GetProcessHeap(), 0, szExpand);
dwType = REG_SZ; dwType = REG_SZ;
} }
if (dwType == REG_SZ && pvData && pcbData && dwDataLen >= *pcbData) if (dwType == REG_SZ && pvData && pcbData && dwDataLen >= *pcbData)
{ {
/* String type too long: truncate it */ ((LPBYTE) pvData)[*pcbData] = '\0';
pvData[*pcbData] = '\0';
} }
} }
/* Update the type and data size if the caller wanted them */ if ( pwType ) *pwType = dwType;
if (pwType) if ( pcbData ) *pcbData = dwDataLen;
*pwType = dwType;
if (pcbData)
*pcbData = dwDataLen;
return dwRet; return dwRet;
} */
/************************************************************************* /*************************************************************************
* SHQueryValueExA [SHLWAPI.@] * SHQueryValueExA [SHLWAPI.@]
...@@ -1078,7 +1041,7 @@ static DWORD WINAPI SHQueryValueExAW(RegQueryFn pfn, ...@@ -1078,7 +1041,7 @@ static DWORD WINAPI SHQueryValueExAW(RegQueryFn pfn,
* *
* PARAMS * PARAMS
* hKey [I] Handle to registry key * 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 * lpReserved [O] Reserved for future use; must be NULL
* pwType [O] Optional pointer updated with the values type * pwType [O] Optional pointer updated with the values type
* pvData [O] Optional pointer updated with the values data * pvData [O] Optional pointer updated with the values data
...@@ -1099,17 +1062,60 @@ static DWORD WINAPI SHQueryValueExAW(RegQueryFn pfn, ...@@ -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 * value returned will be truncated if it is of type REG_SZ and bigger than
* the buffer given to store it. * the buffer given to store it.
*/ */
DWORD WINAPI SHQueryValueExA(HKEY hKey, LPCSTR lpszValue, DWORD WINAPI SHQueryValueExA( HKEY hKey, LPCSTR lpszValue,
LPDWORD lpReserved, LPDWORD pwType, LPDWORD lpReserved, LPDWORD pwType,
LPVOID pvData, LPDWORD pcbData) 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), TRACE("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_a(lpszValue),
lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0); lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
return SHQueryValueExAW((RegQueryFn)RegQueryValueExA, hKey, lpszValue, if (pcbData) dwUnExpDataLen = *pcbData;
lpReserved, pwType, pvData, 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.@] * SHQueryValueExW [SHLWAPI.@]
* *
...@@ -1119,11 +1125,53 @@ DWORD WINAPI SHQueryValueExW(HKEY hKey, LPCWSTR lpszValue, ...@@ -1119,11 +1125,53 @@ DWORD WINAPI SHQueryValueExW(HKEY hKey, LPCWSTR lpszValue,
LPDWORD lpReserved, LPDWORD pwType, LPDWORD lpReserved, LPDWORD pwType,
LPVOID pvData, LPDWORD pcbData) 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), TRACE("(hkey=0x%08x,%s,%p,%p,%p,%p=%ld)\n", hKey, debugstr_w(lpszValue),
lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0); lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
return SHQueryValueExAW((RegQueryFn)RegQueryValueExW, hKey, lpszValue, if (pcbData) dwUnExpDataLen = *pcbData;
lpReserved, pwType, pvData, 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) ...@@ -178,7 +178,7 @@ debug_channels (shell)
172 stdcall @(ptr ptr) SHLWAPI_172 172 stdcall @(ptr ptr) SHLWAPI_172
173 stub @ 173 stub @
174 stdcall @(ptr ptr) SHLWAPI_174 174 stdcall @(ptr ptr) SHLWAPI_174
175 stub @ 175 stdcall @(ptr ptr) SHLWAPI_175
176 stdcall @(ptr ptr ptr ptr) SHLWAPI_176 176 stdcall @(ptr ptr ptr ptr) SHLWAPI_176
177 stub @ 177 stub @
178 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