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.
 
 
 
 
 
 

476 lines
12 KiB

#include <windows.h>
#include <fusenetincludes.h>
#define REGISTRY_BASE_LOCATION L"Software\\Microsoft\\Fusion\\Installer\\"
//////////////////////////////////////////////////////////////////////////////
//
// Emitter
//
//////////////////////////////////////////////////////////////////////////////
// ---------------------------------------------------------------------------
// CRegEmit ctor
// ---------------------------------------------------------------------------
CRegEmit::CRegEmit()
: _hr(S_OK), _hBaseKey((HKEY) INVALID_HANDLE_VALUE)
{}
// ---------------------------------------------------------------------------
// CRegEmit dtor
// ---------------------------------------------------------------------------
CRegEmit::~CRegEmit()
{
if (_hBaseKey != INVALID_HANDLE_VALUE)
IF_FAILED_EXIT(RegCloseKey(_hBaseKey));
exit:
return;
}
// ---------------------------------------------------------------------------
// CRegEmit::Create
// ---------------------------------------------------------------------------
HRESULT CRegEmit::Create(CRegEmit **ppEmit, LPCWSTR pwzRelKeyPath,
CRegEmit* pParentEmit)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
LONG lReturn = 0;
DWORD dwDisposition = 0;
CString sBasePath;
CRegEmit *pEmit = NULL;
if (!pParentEmit)
{
IF_FAILED_EXIT(sBasePath.Assign(REGISTRY_BASE_LOCATION));
if (pwzRelKeyPath)
IF_FAILED_EXIT(sBasePath.Append(pwzRelKeyPath));
hKey = HKEY_CURRENT_USER;
}
else
{
IF_NULL_EXIT(pwzRelKeyPath, E_INVALIDARG);
sBasePath.Assign(pwzRelKeyPath);
hKey = pParentEmit->_hBaseKey;
}
IF_ALLOC_FAILED_EXIT(pEmit = new CRegEmit);
lReturn = RegCreateKeyEx(
hKey,
sBasePath._pwz,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&pEmit->_hBaseKey,
&dwDisposition);
IF_WIN32_FAILED_EXIT(lReturn);
*ppEmit = pEmit;
exit:
if (FAILED(hr))
SAFEDELETE(pEmit);
return hr;
}
// ---------------------------------------------------------------------------
// WriteDword
// ---------------------------------------------------------------------------
HRESULT CRegEmit::WriteDword(LPCWSTR pwzValue, DWORD dwData)
{
LONG lReturn = 0;
lReturn = RegSetValueEx(_hBaseKey, pwzValue, 0, REG_DWORD, (LPBYTE) &dwData, sizeof(DWORD));
IF_WIN32_FAILED_EXIT(lReturn);
exit:
return _hr;
}
// ---------------------------------------------------------------------------
// WriteString
// ---------------------------------------------------------------------------
HRESULT CRegEmit::WriteString(LPCWSTR pwzValue, LPCWSTR pwzData, DWORD ccData)
{
LONG lReturn = 0;
DWORD cbData = 0;
IF_FALSE_EXIT(pwzData, E_INVALIDARG);
if (ccData)
cbData = ccData * sizeof(WCHAR);
else
cbData = (lstrlen(pwzData) + 1) * sizeof(WCHAR);
lReturn = RegSetValueEx(_hBaseKey, pwzValue, 0, REG_SZ, (LPBYTE) pwzData, cbData);
IF_WIN32_FAILED_EXIT(lReturn);
exit:
return _hr;
}
// ---------------------------------------------------------------------------
// WriteString
// ---------------------------------------------------------------------------
HRESULT CRegEmit::WriteString(LPCWSTR pwzValue, CString &sData)
{
return WriteString(pwzValue, sData._pwz, sData._cc);
}
// ---------------------------------------------------------------------------
// DeleteKey
// The one and only place we use the lousy Shlwapi apis.
// ---------------------------------------------------------------------------
HRESULT CRegEmit::DeleteKey(LPCWSTR pwzSubKey)
{
IF_FAILED_EXIT(SHDeleteKey(_hBaseKey, pwzSubKey));
exit:
return _hr;
}
//////////////////////////////////////////////////////////////////////////////
//
// Importer
//
//////////////////////////////////////////////////////////////////////////////
// ---------------------------------------------------------------------------
// CRegImport ctor
// ---------------------------------------------------------------------------
CRegImport::CRegImport()
: _hr(S_OK), _hBaseKey((HKEY) INVALID_HANDLE_VALUE)
{}
// ---------------------------------------------------------------------------
// CRegImport dtor
// ---------------------------------------------------------------------------
CRegImport::~CRegImport()
{
if (_hBaseKey != INVALID_HANDLE_VALUE)
IF_FAILED_EXIT(RegCloseKey(_hBaseKey));
exit:
return;
}
// ---------------------------------------------------------------------------
// CRegImport::Create
// ---------------------------------------------------------------------------
HRESULT CRegImport::Create(CRegImport **ppImport, LPCWSTR pwzRelKeyPath,
CRegImport *pParentImport)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
LONG lReturn = 0;
DWORD dwDisposition = 0;
CString sBasePath;
CRegImport *pImport = NULL;
if (!pParentImport)
{
IF_FAILED_EXIT(sBasePath.Assign(REGISTRY_BASE_LOCATION));
if (pwzRelKeyPath)
IF_FAILED_EXIT(sBasePath.Append(pwzRelKeyPath));
hKey = HKEY_CURRENT_USER;
}
else
{
IF_NULL_EXIT(pwzRelKeyPath, E_INVALIDARG);
sBasePath.Assign(pwzRelKeyPath);
hKey = pParentImport->_hBaseKey;
}
IF_ALLOC_FAILED_EXIT(pImport = new CRegImport);
lReturn = RegOpenKeyEx(
hKey,
sBasePath._pwz,
0,
KEY_READ,
&pImport->_hBaseKey);
if (lReturn == ERROR_FILE_NOT_FOUND)
{
hr = S_FALSE;
*ppImport = NULL;
goto exit;
}
IF_WIN32_FAILED_EXIT(lReturn);
*ppImport = pImport;
exit:
if (FAILED(hr))
SAFEDELETE(pImport);
return hr;
}
// ---------------------------------------------------------------------------
// CRegImport::Create
// ---------------------------------------------------------------------------
HRESULT CRegImport::Create(CRegImport **ppImport, LPCWSTR pwzRelKeyPath,
HKEY hkeyRoot)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
LONG lReturn = 0;
DWORD dwDisposition = 0;
CString sBasePath;
CRegImport *pImport = NULL;
IF_NULL_EXIT(pwzRelKeyPath, E_INVALIDARG);
IF_FAILED_EXIT(sBasePath.Assign(pwzRelKeyPath));
IF_ALLOC_FAILED_EXIT(pImport = new CRegImport);
lReturn = RegOpenKeyEx(
hkeyRoot,
sBasePath._pwz,
0,
KEY_READ,
&pImport->_hBaseKey);
if (lReturn == ERROR_FILE_NOT_FOUND)
{
hr = S_FALSE;
*ppImport = NULL;
goto exit;
}
IF_WIN32_FAILED_EXIT(lReturn);
*ppImport = pImport;
exit:
if (FAILED(hr))
SAFEDELETE(pImport);
return hr;
}
// ---------------------------------------------------------------------------
// Check
// ---------------------------------------------------------------------------
HRESULT CRegImport::Check(LPCWSTR pwzValue, BOOL &bExist)
{
LONG lReturn = 0;
bExist = FALSE;
lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, NULL, NULL, NULL);
IF_TRUE_EXIT(lReturn == ERROR_FILE_NOT_FOUND, S_FALSE);
IF_WIN32_FAILED_EXIT(lReturn);
bExist = TRUE;
exit:
return _hr;
}
// ---------------------------------------------------------------------------
// ReadDword
// ---------------------------------------------------------------------------
HRESULT CRegImport::ReadDword(LPCWSTR pwzValue, LPDWORD pdwData)
{
LONG lReturn = 0;
DWORD dwType = REG_DWORD;
DWORD cbData = sizeof(DWORD);
lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, &dwType, (LPBYTE) pdwData, &cbData);
IF_WIN32_FAILED_EXIT(lReturn);
// Validate reg value type
IF_FALSE_EXIT(dwType == REG_DWORD || dwType == REG_DWORD_LITTLE_ENDIAN, E_UNEXPECTED);
exit:
return _hr;
}
// ---------------------------------------------------------------------------
// ReadString
// ---------------------------------------------------------------------------
HRESULT CRegImport::ReadString(LPCWSTR pwzValue, CString& sData)
{
LONG lReturn = 0;
DWORD dwType = REG_SZ;
DWORD cbData = 0;
DWORD dwCC = 0;
DWORD dwBufLen = 0;
CStringAccessor<CString> acc;
LPWSTR pwzData = NULL;
// IF_FALSE_EXIT(pwzValue, E_INVALIDARG); // if pwzValue == NULL or "", the "default" value is returned
lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, &dwType, NULL, &cbData);
IF_WIN32_FAILED_EXIT(lReturn);
IF_FALSE_EXIT(cbData, E_FAIL);
// Validate reg value type
IF_FALSE_EXIT(dwType == REG_SZ || dwType == REG_EXPAND_SZ, E_UNEXPECTED);
// Allocate for call to RQEX, with one extra char in case
// returned buffer is not null terminated.
dwCC = cbData / sizeof(WCHAR);
dwBufLen = dwCC+1;
// check overflow
IF_FALSE_EXIT(dwBufLen > dwCC, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
IF_ALLOC_FAILED_EXIT(pwzData = new WCHAR[dwBufLen]);
lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, &dwType, (LPBYTE) pwzData, &cbData);
IF_WIN32_FAILED_EXIT(lReturn);
// Null terminate returned buffer.
*(pwzData + dwCC) = L'\0';
if (*(pwzData + dwCC - 1) != L'\0')
dwCC++;
sData.FreeBuffer();
// Attach accessor, set buffer, detach with corrected length.
IF_FAILED_EXIT(acc.Attach(sData));
*(&acc) = pwzData;
// Buffer size could be dwCC+1
IF_FAILED_EXIT(acc.Detach(dwCC));
// If Detach succeeds, reset pointer so that it is freed once.
pwzData = NULL;
exit:
SAFEDELETEARRAY(pwzData);
return _hr;
}
// ---------------------------------------------------------------------------
// EnumKeys
// ---------------------------------------------------------------------------
HRESULT CRegImport::EnumKeys(DWORD n, CString &sSubKey)
{
LONG lReturn = 0;
DWORD cSubKeys = 0, ccMaxSubKeyLen = 0, cValues = 0,
cMaxValueNameLen = 0, cMaxValueLen = 0;
DWORD ccSubKey = 0;
LPWSTR pwzSubKey = NULL;
// ISSUE-2002/03/04-adriaanc
// A race condition exists where a key could be added
// between RegQueryInfoKey and RegEnumKey. If a key
// greater than ccMaxSubKeyLen is added this will cause
// the enum call to fail. Need synchronization.
lReturn = RegQueryInfoKey(
_hBaseKey,
NULL,
NULL,
NULL,
&cSubKeys,
&ccMaxSubKeyLen,
NULL,
&cValues,
&cMaxValueNameLen,
&cMaxValueLen,
NULL,
NULL);
IF_WIN32_FAILED_EXIT(lReturn);
ccSubKey = ccMaxSubKeyLen + 1;
IF_ALLOC_FAILED_EXIT(pwzSubKey = new WCHAR[ccSubKey]);
lReturn = RegEnumKeyEx(
_hBaseKey,
n,
pwzSubKey,
&ccSubKey,
0,
NULL,
NULL,
NULL);
if (lReturn == ERROR_NO_MORE_ITEMS)
{
_hr = S_FALSE;
goto exit;
}
IF_WIN32_FAILED_EXIT(lReturn);
sSubKey.Assign(pwzSubKey);
exit:
SAFEDELETEARRAY(pwzSubKey);
return _hr;
}
// ---------------------------------------------------------------------------
// EnumKeys
// ---------------------------------------------------------------------------
HRESULT CRegImport::EnumKeys(DWORD n, CRegImport **ppImport)
{
CString sSubKey;
CRegImport *pImport = NULL;
IF_FAILED_EXIT(EnumKeys(n, sSubKey));
if (_hr == S_FALSE)
{
*ppImport = NULL;
goto exit;
}
IF_FAILED_EXIT(CRegImport::Create(&pImport, sSubKey._pwz, this));
*ppImport = pImport;
exit:
return _hr;
}