You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
7.3 KiB
264 lines
7.3 KiB
#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
|
|
}
|