278 lines
6.2 KiB
C++
278 lines
6.2 KiB
C++
#include "private.h"
|
|
|
|
#define TF_THISMODULE TF_WEBCHECKCORE
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CMemStream implementation
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CMemStream::CMemStream(BOOL fNewStream)
|
|
{
|
|
// We don't start dirty
|
|
m_fDirty = FALSE;
|
|
m_pstm = NULL;
|
|
m_fNewStream = fNewStream;
|
|
m_fError = FALSE;
|
|
|
|
if (fNewStream)
|
|
{
|
|
// Create new stream
|
|
if (FAILED(CreateStreamOnHGlobal(NULL, TRUE, &m_pstm)))
|
|
{
|
|
m_pstm = NULL;
|
|
m_fError = TRUE;
|
|
DBG_WARN("CMemStream CreateStream fail");
|
|
}
|
|
}
|
|
}
|
|
|
|
CMemStream::~CMemStream()
|
|
{
|
|
DWORD dwSize = 0;
|
|
|
|
// Free up stream
|
|
if (m_pstm)
|
|
{
|
|
m_pstm->Release();
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (m_fDirty)
|
|
DBG_WARN("CMemStream destructor with dirty data");
|
|
if (m_fError)
|
|
DBG_WARN("CMemStream encountered read/write error");
|
|
#endif
|
|
}
|
|
|
|
HRESULT CMemStream::CopyToStream(IStream *pStm)
|
|
{
|
|
char * pData;
|
|
DWORD dwSize = 0;
|
|
HLOCAL hGlobal=NULL;
|
|
|
|
if (m_pstm)
|
|
{
|
|
// get global handle from stream
|
|
GetHGlobalFromStream(m_pstm, &hGlobal);
|
|
|
|
// find how much data we have
|
|
STATSTG stats;
|
|
m_pstm->Stat( &stats, STATFLAG_NONAME );
|
|
dwSize = stats.cbSize.LowPart;
|
|
|
|
// write out data
|
|
ASSERT(hGlobal);
|
|
|
|
pData = (char *)GlobalLock(hGlobal);
|
|
if (pData)
|
|
pStm->Write(pData, dwSize, NULL);
|
|
|
|
GlobalUnlock(hGlobal);
|
|
|
|
m_fDirty = FALSE;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
HRESULT CMemStream::Read(void *pv, ULONG cb, ULONG *cbRead)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// make sure we have a stream
|
|
if(NULL == m_pstm)
|
|
return ResultFromScode(E_OUTOFMEMORY);
|
|
|
|
hr = m_pstm->Read(pv, cb, cbRead);
|
|
if (FAILED(hr) || *cbRead!=cb)
|
|
m_fError=TRUE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMemStream::Write(void *pv, ULONG cb, ULONG *cbWritten)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// make sure we have a stream
|
|
if(NULL == m_pstm)
|
|
return ResultFromScode(E_OUTOFMEMORY);
|
|
|
|
m_fDirty = TRUE;
|
|
|
|
hr = m_pstm->Write(pv, cb, cbWritten);
|
|
if (FAILED(hr) || *cbWritten != cb)
|
|
m_fError=TRUE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMemStream::SaveToStream(IUnknown *punk)
|
|
{
|
|
IPersistStream * pips;
|
|
HRESULT hr;
|
|
|
|
// make sure we have a stream
|
|
if(NULL == m_pstm)
|
|
return ResultFromScode(E_OUTOFMEMORY);
|
|
|
|
// Get IPersistStream interface and save!
|
|
hr = punk->QueryInterface(IID_IPersistStream, (void **)&pips);
|
|
if(SUCCEEDED(hr))
|
|
hr = OleSaveToStream(pips, m_pstm);
|
|
|
|
if(pips)
|
|
pips->Release();
|
|
|
|
if (FAILED(hr))
|
|
m_fError=TRUE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMemStream::LoadFromStream(IUnknown **ppunk)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// make sure we have a stream
|
|
if(NULL == m_pstm)
|
|
return ResultFromScode(E_OUTOFMEMORY);
|
|
|
|
hr = OleLoadFromStream(m_pstm, IID_IUnknown, (void **)ppunk);
|
|
|
|
if (FAILED(hr))
|
|
m_fError=TRUE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMemStream::Seek(long lMove, DWORD dwOrigin, DWORD *dwNewPos)
|
|
{
|
|
LARGE_INTEGER liDist;
|
|
ULARGE_INTEGER uliNew;
|
|
HRESULT hr;
|
|
|
|
LISet32(liDist, lMove);
|
|
hr = m_pstm->Seek(liDist, dwOrigin, &uliNew);
|
|
if(dwNewPos)
|
|
*dwNewPos = uliNew.LowPart;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CRegStream implementation
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CRegStream::CRegStream(HKEY hBaseKey, LPCTSTR pszRegKey, LPCTSTR pszSubKey, BOOL fForceNewStream) :
|
|
CMemStream(fForceNewStream)
|
|
{
|
|
long lRes;
|
|
DWORD dwDisposition, dwType, dwSize;
|
|
char * pData;
|
|
HLOCAL hGlobal;
|
|
|
|
m_hKey = NULL;
|
|
|
|
lstrcpyn(m_pszSubKey, pszSubKey, ARRAYSIZE(m_pszSubKey));
|
|
|
|
lRes = RegCreateKeyEx(
|
|
hBaseKey,
|
|
pszRegKey,
|
|
0,
|
|
NULL,
|
|
0,
|
|
KEY_QUERY_VALUE | KEY_SET_VALUE,
|
|
NULL,
|
|
&m_hKey,
|
|
&dwDisposition
|
|
);
|
|
|
|
if(lRes != ERROR_SUCCESS)
|
|
return;
|
|
|
|
if (!fForceNewStream)
|
|
{
|
|
// Initialize our stream from the registry
|
|
m_fError=TRUE; // assume failure
|
|
|
|
// Find reg data size
|
|
lRes = RegQueryValueEx(m_hKey, m_pszSubKey, NULL, &dwType, NULL, &dwSize);
|
|
|
|
if(lRes != ERROR_SUCCESS) {
|
|
// nothing in there at the moment - create new stream
|
|
DBG("CRegStream creating new stream");
|
|
m_fNewStream = TRUE;
|
|
if(FAILED(CreateStreamOnHGlobal(NULL, TRUE, &m_pstm)))
|
|
{
|
|
m_pstm = NULL;
|
|
}
|
|
else
|
|
m_fError=FALSE;
|
|
}
|
|
else
|
|
{
|
|
// Get global handle to data
|
|
hGlobal = MemAlloc(LMEM_MOVEABLE, dwSize);
|
|
if(NULL == hGlobal)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pData = (char *)GlobalLock(hGlobal);
|
|
|
|
lRes = RegQueryValueEx(m_hKey, m_pszSubKey, NULL, &dwType,
|
|
(BYTE *)pData, &dwSize);
|
|
GlobalUnlock(hGlobal);
|
|
|
|
if (lRes != ERROR_SUCCESS)
|
|
{
|
|
MemFree(hGlobal);
|
|
return;
|
|
}
|
|
|
|
// make stream on global handle
|
|
if (FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &m_pstm)))
|
|
{
|
|
m_pstm = NULL;
|
|
MemFree(hGlobal);
|
|
}
|
|
else
|
|
m_fError=FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
CRegStream::~CRegStream()
|
|
{
|
|
char * pData;
|
|
DWORD dwSize = 0;
|
|
HLOCAL hGlobal=NULL;
|
|
|
|
// Save stream to registry if it's changed
|
|
if (m_pstm && m_fDirty)
|
|
{
|
|
GetHGlobalFromStream(m_pstm, &hGlobal);
|
|
|
|
STATSTG stats;
|
|
m_pstm->Stat( &stats, STATFLAG_NONAME );
|
|
dwSize = stats.cbSize.LowPart;
|
|
|
|
pData = (char *)GlobalLock(hGlobal);
|
|
if(pData)
|
|
RegSetValueEx(m_hKey, m_pszSubKey, NULL, REG_BINARY,
|
|
(const BYTE *)pData, dwSize);
|
|
GlobalUnlock(hGlobal);
|
|
m_fDirty = FALSE;
|
|
}
|
|
|
|
// clean up
|
|
if(m_hKey)
|
|
RegCloseKey(m_hKey);
|
|
}
|