|
|
#include "precomp.h"
LONG SHCleanUpValue(HKEY hk, PCTSTR pszKey, PCTSTR pszValue /*= NULL*/) { TCHAR szKey[MAX_PATH]; LPTSTR pszCurrent; HKEY hkAux; HRESULT hr; LONG lResult;
if (hk == NULL) return E_INVALIDARG;
if (StrLen(pszKey) >= countof(szKey)) return E_OUTOFMEMORY; StrCpy(szKey, pszKey);
if (pszValue != NULL) { lResult = SHOpenKey(hk, pszKey, KEY_SET_VALUE, &hkAux); if (lResult == ERROR_SUCCESS) { lResult = RegDeleteValue(hkAux, pszValue); SHCloseKey(hkAux);
if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND) return E_FAIL; } }
for (pszCurrent = szKey + StrLen(szKey); TRUE; *pszCurrent = TEXT('\0')) { hr = SHIsKeyEmpty(hk, szKey); if (FAILED(hr)) if (hr == STG_E_PATHNOTFOUND) continue; else return E_FAIL;
if (hr == S_FALSE) break;
RegDeleteKey(hk, szKey);
pszCurrent = StrRChr(szKey, pszCurrent, TEXT('\\')); if (pszCurrent == NULL) break; }
return S_OK; }
void SHCopyKey(HKEY hkFrom, HKEY hkTo) { TCHAR szData[1024], szValue[MAX_PATH]; DWORD dwSize, dwVal, dwSizeData, dwType; HKEY hkSubkeyFrom, hkSubkeyTo;
dwVal = 0; dwSize = countof(szValue); dwSizeData = sizeof(szData); while (ERROR_SUCCESS == RegEnumValue(hkFrom, dwVal++, szValue, &dwSize, NULL, &dwType, (LPBYTE)szData, &dwSizeData)) { RegSetValueEx(hkTo, szValue, 0, dwType, (LPBYTE)szData, dwSizeData); dwSize = countof(szValue); dwSizeData = sizeof(szData); }
dwVal = 0; while (ERROR_SUCCESS == RegEnumKey(hkFrom, dwVal++, szValue, countof(szValue))) if (ERROR_SUCCESS == SHOpenKey(hkFrom, szValue, KEY_DEFAULT_ACCESS, &hkSubkeyFrom)) if (SHCreateKey(hkTo, szValue, KEY_DEFAULT_ACCESS, &hkSubkeyTo) == ERROR_SUCCESS) SHCopyKey(hkSubkeyFrom, hkSubkeyTo); }
HRESULT SHCopyValue(HKEY hkFrom, HKEY hkTo, PCTSTR pszValue) { PBYTE pData; DWORD dwType, cbData; LONG lResult;
if (NULL == hkFrom || NULL == hkTo) return E_INVALIDARG;
if (S_OK != SHValueExists(hkFrom, pszValue)) return STG_E_FILENOTFOUND;
cbData = 0; lResult = RegQueryValueEx(hkFrom, pszValue, NULL, &dwType, NULL, &cbData); if (ERROR_SUCCESS != lResult) return E_FAIL;
pData = (PBYTE)CoTaskMemAlloc(cbData); if (NULL == pData) return E_OUTOFMEMORY; // ZeroMemory(pData, cbData); // don't really have to do this
lResult = RegQueryValueEx(hkFrom, pszValue, NULL, NULL, pData, &cbData); ASSERT(ERROR_SUCCESS == lResult);
lResult = RegSetValueEx(hkTo, pszValue, 0, dwType, pData, cbData); CoTaskMemFree(pData);
return (ERROR_SUCCESS == lResult) ? S_OK : HRESULT_FROM_WIN32(lResult); }
HRESULT SHCopyValue(HKEY hkFrom, PCTSTR pszSubkeyFrom, HKEY hkTo, PCTSTR pszSubkeyTo, PCTSTR pszValue) { HKEY hkSubkeyFrom, hkSubkeyTo; HRESULT hr; LONG lResult;
hkSubkeyFrom = NULL; hkSubkeyTo = NULL; hr = E_FAIL;
if (NULL == hkFrom || NULL == pszSubkeyFrom || NULL == hkTo || NULL == pszSubkeyTo) { hr = E_INVALIDARG; goto Exit; }
lResult = SHOpenKey(hkFrom, pszSubkeyFrom, KEY_QUERY_VALUE, &hkSubkeyFrom); if (ERROR_SUCCESS != lResult) { hr = (ERROR_FILE_NOT_FOUND == lResult) ? STG_E_PATHNOTFOUND : E_FAIL; goto Exit; }
lResult = SHCreateKey(hkTo, pszSubkeyTo, KEY_SET_VALUE, &hkSubkeyTo); if (ERROR_SUCCESS != lResult) goto Exit;
hr = SHCopyValue(hkSubkeyFrom, hkSubkeyTo, pszValue);
Exit: SHCloseKey(hkSubkeyFrom); SHCloseKey(hkSubkeyTo);
return hr; }
HRESULT SHIsKeyEmpty(HKEY hk) { DWORD dwKeys, dwValues; LONG lResult;
if (hk == NULL) return E_INVALIDARG;
lResult = RegQueryInfoKey(hk, NULL, NULL, NULL, &dwKeys, NULL, NULL, &dwValues, NULL, NULL, NULL, NULL); if (lResult != ERROR_SUCCESS) return E_FAIL;
return (dwKeys == 0 && dwValues == 0) ? S_OK : S_FALSE; }
HRESULT SHIsKeyEmpty(HKEY hk, PCTSTR pszSubKey) { HKEY hkAux; HRESULT hr; LONG lResult;
lResult = SHOpenKey(hk, pszSubKey, KEY_QUERY_VALUE, &hkAux); if (lResult != ERROR_SUCCESS) return (lResult == ERROR_FILE_NOT_FOUND) ? STG_E_PATHNOTFOUND : E_FAIL;
hr = SHIsKeyEmpty(hkAux); SHCloseKey(hkAux);
return hr; }
HRESULT SHKeyExists(HKEY hk, PCTSTR pszSubKey) { HKEY hkAux; HRESULT hr; DWORD lResult;
if (hk == NULL) return E_INVALIDARG;
hkAux = NULL; lResult = SHOpenKey(hk, pszSubKey, KEY_QUERY_VALUE, &hkAux); SHCloseKey(hkAux);
hr = S_OK; if (lResult != ERROR_SUCCESS) hr = (lResult == ERROR_FILE_NOT_FOUND) ? S_FALSE : E_FAIL;
return hr; }
HRESULT SHValueExists(HKEY hk, PCTSTR pszValue) { HRESULT hr; DWORD lResult;
if (hk == NULL) return E_INVALIDARG;
if (pszValue != NULL && *pszValue != TEXT('\0')) lResult = RegQueryValueEx(hk, pszValue, NULL, NULL, NULL, NULL);
else { DWORD dwValueDataLen; TCHAR szDummyBuf[1];
// On Win95, for the default value name, its existence is checked as follows:
// - pass in a dummy buffer for the value data but pass in the size of the buffer as 0
// - the query would succeed if and only if there is no value data set
// - for all other cases, including the case where the value data is just the empty string,
// the query would fail and dwValueDataLen would contain the no. of bytes needed to
// fit in the value data
// On NT4.0, if no value data is set, the query returns ERROR_FILE_NOT_FOUND
dwValueDataLen = 0; lResult = RegQueryValueEx(hk, pszValue, NULL, NULL, (LPBYTE)szDummyBuf, &dwValueDataLen); if (lResult == ERROR_SUCCESS) lResult = ERROR_FILE_NOT_FOUND; }
hr = S_OK; if (lResult != ERROR_SUCCESS) hr = (lResult == ERROR_FILE_NOT_FOUND) ? S_FALSE : E_FAIL;
return hr; }
HRESULT SHValueExists(HKEY hk, PCTSTR pszSubKey, PCTSTR pszValue) { HKEY hkAux; HRESULT hr; LONG lResult;
lResult = SHOpenKey(hk, pszSubKey, KEY_QUERY_VALUE, &hkAux); if (lResult != ERROR_SUCCESS) return (lResult == ERROR_FILE_NOT_FOUND) ? STG_E_PATHNOTFOUND : E_FAIL;
hr = SHValueExists(hkAux, pszValue); SHCloseKey(hkAux);
return hr; }
DWORD RegSaveRestoreDWORD(HKEY hk, PCTSTR pcszValue, DWORD dwVal) { DWORD dwRet, dwSize;
// Note: we assume that a value of 0 is equivalent to the value not being there at all
dwSize = sizeof(dwRet);
if (SHQueryValueEx(hk, pcszValue, NULL, NULL, (LPVOID)&dwRet, &dwSize) != ERROR_SUCCESS) dwRet = 0; if (dwVal == 0) RegDeleteValue(hk, pcszValue); else RegSetValueEx(hk, pcszValue, 0, REG_DWORD, (CONST BYTE *)&dwVal, sizeof(dwVal));
return dwRet; // return the value we overwrite in the registry
}
|