SimpleDataCacheWrapper.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLanguagePch.h"
  6. #if ENABLE_PROFILE_INFO
  7. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  8. #include "activscp_private.h"
  9. #endif
  10. namespace Js
  11. {
  12. SimpleDataCacheWrapper::SimpleDataCacheWrapper(IActiveScriptDataCache* dataCache) :
  13. dataCache(dataCache),
  14. outStream(nullptr),
  15. inStream(nullptr),
  16. bytesWrittenInBlock(0)
  17. {
  18. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  19. this->dataCache->AddRef();
  20. #endif
  21. }
  22. HRESULT SimpleDataCacheWrapper::Close()
  23. {
  24. HRESULT hr = E_FAIL;
  25. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  26. hr = this->SaveWriteStream();
  27. if (IsReadStreamOpen())
  28. {
  29. this->inStream->Release();
  30. this->inStream = nullptr;
  31. }
  32. if (this->dataCache != nullptr)
  33. {
  34. this->dataCache->Release();
  35. this->dataCache = nullptr;
  36. }
  37. #endif
  38. return hr;
  39. }
  40. HRESULT SimpleDataCacheWrapper::SaveWriteStream()
  41. {
  42. HRESULT hr = E_FAIL;
  43. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  44. if (IsWriteStreamOpen())
  45. {
  46. Assert(this->dataCache != nullptr);
  47. hr = this->dataCache->SaveWriteDataStream(this->outStream);
  48. this->outStream->Release();
  49. this->outStream = nullptr;
  50. }
  51. #endif
  52. return hr;
  53. }
  54. HRESULT SimpleDataCacheWrapper::OpenWriteStream()
  55. {
  56. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  57. HRESULT hr = E_FAIL;
  58. Assert(!IsWriteStreamOpen());
  59. Assert(this->dataCache != nullptr);
  60. Assert(this->outStream == nullptr);
  61. hr = this->dataCache->GetWriteDataStream(&this->outStream);
  62. if (FAILED(hr))
  63. {
  64. if (this->outStream != nullptr)
  65. {
  66. this->outStream->Release();
  67. this->outStream = nullptr;
  68. }
  69. return hr;
  70. }
  71. #endif
  72. return WriteHeader();
  73. }
  74. HRESULT SimpleDataCacheWrapper::WriteHeader()
  75. {
  76. DWORD jscriptMajorVersion;
  77. DWORD jscriptMinorVersion;
  78. HRESULT hr = E_FAIL;
  79. IFFAILRET(AutoSystemInfo::GetJscriptFileVersion(&jscriptMajorVersion, &jscriptMinorVersion));
  80. IFFAILRET(Write(jscriptMajorVersion));
  81. IFFAILRET(Write(jscriptMinorVersion));
  82. return hr;
  83. }
  84. HRESULT SimpleDataCacheWrapper::ReadHeader()
  85. {
  86. DWORD jscriptMajorVersion;
  87. DWORD jscriptMinorVersion;
  88. HRESULT hr = E_FAIL;
  89. IFFAILRET(AutoSystemInfo::GetJscriptFileVersion(&jscriptMajorVersion, &jscriptMinorVersion));
  90. DWORD majorVersion;
  91. IFFAILRET(Read(&majorVersion));
  92. if (majorVersion != jscriptMajorVersion)
  93. {
  94. return E_FAIL;
  95. }
  96. DWORD minorVersion;
  97. IFFAILRET(Read(&minorVersion));
  98. if (minorVersion != jscriptMinorVersion)
  99. {
  100. return E_FAIL;
  101. }
  102. return hr;
  103. }
  104. HRESULT SimpleDataCacheWrapper::EnsureWriteStream()
  105. {
  106. if (IsWriteStreamOpen())
  107. {
  108. return S_OK;
  109. }
  110. return OpenWriteStream();
  111. }
  112. HRESULT SimpleDataCacheWrapper::EnsureReadStream()
  113. {
  114. if (IsReadStreamOpen())
  115. {
  116. return S_OK;
  117. }
  118. return OpenReadStream();
  119. }
  120. HRESULT SimpleDataCacheWrapper::StartBlock(_In_ BlockType blockType, _In_ ULONG byteCount)
  121. {
  122. HRESULT hr = E_FAIL;
  123. IFFAILRET(Write(blockType));
  124. IFFAILRET(Write(byteCount));
  125. // Reset the bytes written for the current block
  126. this->bytesWrittenInBlock = 0;
  127. return hr;
  128. }
  129. HRESULT SimpleDataCacheWrapper::OpenReadStream()
  130. {
  131. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  132. HRESULT hr = E_FAIL;
  133. Assert(this->dataCache != nullptr);
  134. Assert(this->inStream == nullptr);
  135. IFFAILRET(this->dataCache->GetReadDataStream(&this->inStream));
  136. #endif
  137. return ReadHeader();
  138. }
  139. HRESULT SimpleDataCacheWrapper::ResetReadStream()
  140. {
  141. HRESULT hr;
  142. IFFAILRET(EnsureReadStream());
  143. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  144. // Reset the read stream to beginning of the stream - after the header
  145. LARGE_INTEGER dlibMove;
  146. dlibMove.QuadPart = sizeof(DWORD) * 2;
  147. IFFAILRET(this->inStream->Seek(dlibMove, STREAM_SEEK_SET, nullptr));
  148. #endif
  149. return hr;
  150. }
  151. HRESULT SimpleDataCacheWrapper::SeekReadStreamToBlockHelper(_In_ BlockType blockType, _Out_opt_ ULONG* bytesInBlock)
  152. {
  153. HRESULT hr;
  154. BlockType currentBlockType = BlockType_Invalid;
  155. ULONG byteCount = 0;
  156. IFFAILRET(Read(&currentBlockType));
  157. IFFAILRET(Read(&byteCount));
  158. if (currentBlockType == blockType)
  159. {
  160. if (bytesInBlock != nullptr)
  161. {
  162. *bytesInBlock = byteCount;
  163. }
  164. return S_OK;
  165. }
  166. #ifdef ENABLE_WININET_PROFILE_DATA_CACHE
  167. // The block we're pointing at is not the requested one, seek forward to the next block
  168. LARGE_INTEGER dlibMove;
  169. dlibMove.QuadPart = byteCount;
  170. IFFAILRET(this->inStream->Seek(dlibMove, STREAM_SEEK_CUR, nullptr));
  171. #endif
  172. return SeekReadStreamToBlockHelper(blockType, bytesInBlock);
  173. }
  174. HRESULT SimpleDataCacheWrapper::SeekReadStreamToBlock(_In_ BlockType blockType, _Out_opt_ ULONG* bytesInBlock)
  175. {
  176. HRESULT hr;
  177. if (bytesInBlock != nullptr)
  178. {
  179. *bytesInBlock = 0;
  180. }
  181. IFFAILRET(ResetReadStream());
  182. // Reset above has moved the seek pointer to just after the header, we're at the first block.
  183. return SeekReadStreamToBlockHelper(blockType, bytesInBlock);
  184. }
  185. }
  186. #endif