mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:54:13 +00:00
Reimplemented SHRegGetPathA/W, SHGetValueA/W, SHRegGetPathA/W.
This commit is contained in:
parent
7919d5a178
commit
68b6f56b32
3 changed files with 150 additions and 91 deletions
|
@ -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]
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -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 @
|
||||
|
|
Loading…
Reference in a new issue