#pragma once
#include <malloc.h> template <class T>
HRESULT LoadRegString(HKEY hkey, LPCTSTR pszValueName, T& strOut)
{
strOut = TEXT("");
DWORD dwType;
DWORD cbData = 0;
long lr = RegQueryValueEx(hkey, pszValueName, NULL, &dwType, NULL, &cbData);
if (ERROR_SUCCESS != lr)
return HRESULT_FROM_WIN32(lr);
if (REG_SZ != dwType)
return HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE);
if (!cbData)
return S_OK;
LPTSTR pszValue = (LPTSTR)_alloca(cbData + sizeof(TCHAR));
lr = RegQueryValueEx(hkey, pszValueName, NULL, NULL, (BYTE*)pszValue, &cbData);
if (ERROR_SUCCESS != lr)
return HRESULT_FROM_WIN32(lr);
pszValue[cbData / sizeof(TCHAR)] = TEXT('\0');
strOut = pszValue;
return S_OK;
}
inline HRESULT LoadRegStream(HKEY hkey, LPCTSTR pszValueName, IStream** ppStm)
{
*ppStm = NULL;
DWORD dwType;
DWORD cbData = 0;
long lr = RegQueryValueEx(hkey, pszValueName, NULL, &dwType, NULL, &cbData);
if (ERROR_SUCCESS != lr)
return HRESULT_FROM_WIN32(lr);
if (REG_BINARY != dwType)
return HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE);
if (!cbData)
return S_OK;
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cbData);
void* pvValue = GlobalLock(hGlobal);
lr = RegQueryValueEx(hkey, pszValueName, NULL, NULL, (BYTE*)pvValue, &cbData);
GlobalUnlock(hGlobal);
HRESULT hr = (ERROR_SUCCESS != lr) ? HRESULT_FROM_WIN32(lr) : S_OK;
if (SUCCEEDED(hr))
hr = CreateStreamOnHGlobal(hGlobal, true, ppStm);
if (SUCCEEDED(hr))
{
ULARGE_INTEGER uli;
uli.HighPart = 0;
uli.LowPart = cbData;
(*ppStm)->SetSize(uli);
LARGE_INTEGER li;
li.HighPart = 0;
li.LowPart = 0;
(*ppStm)->Seek(li, STREAM_SEEK_SET, NULL);
}
else
{
GlobalFree(hGlobal);
}
return hr;
}
inline HRESULT SaveRegStream(HKEY hkey, LPCTSTR pszValueName, IStream* pStm)
{
LARGE_INTEGER li = {0};
ULARGE_INTEGER uli;
HRESULT hr = pStm->Seek(li, STREAM_SEEK_END, &uli);
if (FAILED(hr))
return hr;
if (0 != uli.HighPart)
return E_OUTOFMEMORY;
DWORD cbData = uli.LowPart;
HGLOBAL hGlobal, hGlobalTemp = NULL;
if (FAILED(GetHGlobalFromStream(pStm, &hGlobal)))
{
hGlobal = hGlobalTemp = GlobalAlloc(GMEM_MOVEABLE, cbData);
if (!hGlobalTemp)
return E_OUTOFMEMORY;
void* pvTemp = GlobalLock(hGlobalTemp);
if (!pvTemp)
{
hr = HRESULT_FROM_WIN32(GetLastError());
GlobalFree(hGlobalTemp);
return hr;
}
hr = pStm->Read(pvTemp, cbData, NULL);
GlobalUnlock(hGlobalTemp);
if (FAILED(hr))
return hr;
}
void* pvData = GlobalLock(hGlobal);
if (pvData)
{
LONG lr = ::RegSetValueEx(hkey, pszValueName, 0, REG_BINARY,
(BYTE*)pvData, cbData);
if (ERROR_SUCCESS != lr)
hr = HRESULT_FROM_WIN32(lr);
GlobalUnlock(hGlobal);
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
if (hGlobalTemp)
GlobalFree(hGlobalTemp);
return hr;
}