diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c index 84d2fddd2e4..c107aae084c 100644 --- a/dlls/shlwapi/ordinal.c +++ b/dlls/shlwapi/ordinal.c @@ -1212,6 +1212,17 @@ DWORD WINAPI SHLWAPI_174( return ret; } +/************************************************************************* + * @ [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] * diff --git a/dlls/shlwapi/reg.c b/dlls/shlwapi/reg.c index 79e5a7570f6..8f839d49cff 100644 --- a/dlls/shlwapi/reg.c +++ b/dlls/shlwapi/reg.c @@ -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); - dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); - if (!dwRet) + /* 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) { - 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); - dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); - if (!dwRet) + if(lpszSubKey) + dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); + + 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); - dwRet = pfn(hKey, lpszValue, lpReserved, &dwType, pvData, &dwDataLen); + if (pcbData) dwDataLen = *pcbData; + + 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, - LPDWORD lpReserved, LPDWORD pwType, - LPVOID pvData, LPDWORD pcbData) +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; } /************************************************************************* diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index 66ef7d61350..f933f6624c3 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -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 @