Leaked source code of windows server 2003
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

#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
}