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