Source code of Windows XP (NT5)
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.

277 lines
6.2 KiB

  1. #include "private.h"
  2. #define TF_THISMODULE TF_WEBCHECKCORE
  3. //////////////////////////////////////////////////////////////////////////
  4. //
  5. // CMemStream implementation
  6. //
  7. //////////////////////////////////////////////////////////////////////////
  8. CMemStream::CMemStream(BOOL fNewStream)
  9. {
  10. // We don't start dirty
  11. m_fDirty = FALSE;
  12. m_pstm = NULL;
  13. m_fNewStream = fNewStream;
  14. m_fError = FALSE;
  15. if (fNewStream)
  16. {
  17. // Create new stream
  18. if (FAILED(CreateStreamOnHGlobal(NULL, TRUE, &m_pstm)))
  19. {
  20. m_pstm = NULL;
  21. m_fError = TRUE;
  22. DBG_WARN("CMemStream CreateStream fail");
  23. }
  24. }
  25. }
  26. CMemStream::~CMemStream()
  27. {
  28. DWORD dwSize = 0;
  29. // Free up stream
  30. if (m_pstm)
  31. {
  32. m_pstm->Release();
  33. }
  34. #ifdef DEBUG
  35. if (m_fDirty)
  36. DBG_WARN("CMemStream destructor with dirty data");
  37. if (m_fError)
  38. DBG_WARN("CMemStream encountered read/write error");
  39. #endif
  40. }
  41. HRESULT CMemStream::CopyToStream(IStream *pStm)
  42. {
  43. char * pData;
  44. DWORD dwSize = 0;
  45. HLOCAL hGlobal=NULL;
  46. if (m_pstm)
  47. {
  48. // get global handle from stream
  49. GetHGlobalFromStream(m_pstm, &hGlobal);
  50. // find how much data we have
  51. STATSTG stats;
  52. m_pstm->Stat( &stats, STATFLAG_NONAME );
  53. dwSize = stats.cbSize.LowPart;
  54. // write out data
  55. ASSERT(hGlobal);
  56. pData = (char *)GlobalLock(hGlobal);
  57. if (pData)
  58. pStm->Write(pData, dwSize, NULL);
  59. GlobalUnlock(hGlobal);
  60. m_fDirty = FALSE;
  61. }
  62. return NOERROR;
  63. }
  64. HRESULT CMemStream::Read(void *pv, ULONG cb, ULONG *cbRead)
  65. {
  66. HRESULT hr;
  67. // make sure we have a stream
  68. if(NULL == m_pstm)
  69. return ResultFromScode(E_OUTOFMEMORY);
  70. hr = m_pstm->Read(pv, cb, cbRead);
  71. if (FAILED(hr) || *cbRead!=cb)
  72. m_fError=TRUE;
  73. return hr;
  74. }
  75. HRESULT CMemStream::Write(void *pv, ULONG cb, ULONG *cbWritten)
  76. {
  77. HRESULT hr;
  78. // make sure we have a stream
  79. if(NULL == m_pstm)
  80. return ResultFromScode(E_OUTOFMEMORY);
  81. m_fDirty = TRUE;
  82. hr = m_pstm->Write(pv, cb, cbWritten);
  83. if (FAILED(hr) || *cbWritten != cb)
  84. m_fError=TRUE;
  85. return hr;
  86. }
  87. HRESULT CMemStream::SaveToStream(IUnknown *punk)
  88. {
  89. IPersistStream * pips;
  90. HRESULT hr;
  91. // make sure we have a stream
  92. if(NULL == m_pstm)
  93. return ResultFromScode(E_OUTOFMEMORY);
  94. // Get IPersistStream interface and save!
  95. hr = punk->QueryInterface(IID_IPersistStream, (void **)&pips);
  96. if(SUCCEEDED(hr))
  97. hr = OleSaveToStream(pips, m_pstm);
  98. if(pips)
  99. pips->Release();
  100. if (FAILED(hr))
  101. m_fError=TRUE;
  102. return hr;
  103. }
  104. HRESULT CMemStream::LoadFromStream(IUnknown **ppunk)
  105. {
  106. HRESULT hr;
  107. // make sure we have a stream
  108. if(NULL == m_pstm)
  109. return ResultFromScode(E_OUTOFMEMORY);
  110. hr = OleLoadFromStream(m_pstm, IID_IUnknown, (void **)ppunk);
  111. if (FAILED(hr))
  112. m_fError=TRUE;
  113. return hr;
  114. }
  115. HRESULT CMemStream::Seek(long lMove, DWORD dwOrigin, DWORD *dwNewPos)
  116. {
  117. LARGE_INTEGER liDist;
  118. ULARGE_INTEGER uliNew;
  119. HRESULT hr;
  120. LISet32(liDist, lMove);
  121. hr = m_pstm->Seek(liDist, dwOrigin, &uliNew);
  122. if(dwNewPos)
  123. *dwNewPos = uliNew.LowPart;
  124. return hr;
  125. }
  126. //////////////////////////////////////////////////////////////////////////
  127. //
  128. // CRegStream implementation
  129. //
  130. //////////////////////////////////////////////////////////////////////////
  131. CRegStream::CRegStream(HKEY hBaseKey, LPCTSTR pszRegKey, LPCTSTR pszSubKey, BOOL fForceNewStream) :
  132. CMemStream(fForceNewStream)
  133. {
  134. long lRes;
  135. DWORD dwDisposition, dwType, dwSize;
  136. char * pData;
  137. HLOCAL hGlobal;
  138. m_hKey = NULL;
  139. lstrcpyn(m_pszSubKey, pszSubKey, ARRAYSIZE(m_pszSubKey));
  140. lRes = RegCreateKeyEx(
  141. hBaseKey,
  142. pszRegKey,
  143. 0,
  144. NULL,
  145. 0,
  146. KEY_QUERY_VALUE | KEY_SET_VALUE,
  147. NULL,
  148. &m_hKey,
  149. &dwDisposition
  150. );
  151. if(lRes != ERROR_SUCCESS)
  152. return;
  153. if (!fForceNewStream)
  154. {
  155. // Initialize our stream from the registry
  156. m_fError=TRUE; // assume failure
  157. // Find reg data size
  158. lRes = RegQueryValueEx(m_hKey, m_pszSubKey, NULL, &dwType, NULL, &dwSize);
  159. if(lRes != ERROR_SUCCESS) {
  160. // nothing in there at the moment - create new stream
  161. DBG("CRegStream creating new stream");
  162. m_fNewStream = TRUE;
  163. if(FAILED(CreateStreamOnHGlobal(NULL, TRUE, &m_pstm)))
  164. {
  165. m_pstm = NULL;
  166. }
  167. else
  168. m_fError=FALSE;
  169. }
  170. else
  171. {
  172. // Get global handle to data
  173. hGlobal = MemAlloc(LMEM_MOVEABLE, dwSize);
  174. if(NULL == hGlobal)
  175. {
  176. return;
  177. }
  178. pData = (char *)GlobalLock(hGlobal);
  179. lRes = RegQueryValueEx(m_hKey, m_pszSubKey, NULL, &dwType,
  180. (BYTE *)pData, &dwSize);
  181. GlobalUnlock(hGlobal);
  182. if (lRes != ERROR_SUCCESS)
  183. {
  184. MemFree(hGlobal);
  185. return;
  186. }
  187. // make stream on global handle
  188. if (FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &m_pstm)))
  189. {
  190. m_pstm = NULL;
  191. MemFree(hGlobal);
  192. }
  193. else
  194. m_fError=FALSE;
  195. }
  196. }
  197. }
  198. CRegStream::~CRegStream()
  199. {
  200. char * pData;
  201. DWORD dwSize = 0;
  202. HLOCAL hGlobal=NULL;
  203. // Save stream to registry if it's changed
  204. if (m_pstm && m_fDirty)
  205. {
  206. GetHGlobalFromStream(m_pstm, &hGlobal);
  207. STATSTG stats;
  208. m_pstm->Stat( &stats, STATFLAG_NONAME );
  209. dwSize = stats.cbSize.LowPart;
  210. pData = (char *)GlobalLock(hGlobal);
  211. if(pData)
  212. RegSetValueEx(m_hKey, m_pszSubKey, NULL, REG_BINARY,
  213. (const BYTE *)pData, dwSize);
  214. GlobalUnlock(hGlobal);
  215. m_fDirty = FALSE;
  216. }
  217. // clean up
  218. if(m_hKey)
  219. RegCloseKey(m_hKey);
  220. }