Leaked source code of windows server 2003
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.

409 lines
9.4 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. OfflineCache_Master.cpp
  5. Abstract:
  6. Handles caching of database lookups, service-side.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 07/17/2000
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. ////////////////////////////////////////////////////////////////////////////////
  13. ////////////////////////////////////////////////////////////////////////////////
  14. HRESULT OfflineCache::Query::Store( /*[in]*/ const MPC::wstring& strDir ,
  15. /*[in]*/ const CPCHQueryResultCollection* pColl )
  16. {
  17. __HCP_FUNC_ENTRY( "OfflineCache::Query::Store" );
  18. HRESULT hr;
  19. if(m_fNull == false)
  20. {
  21. MPC::wstring strFile;
  22. CComPtr<MPC::FileStream> stream;
  23. __MPC_EXIT_IF_METHOD_FAILS(hr, InitFile ( strDir, strFile ));
  24. __MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Init( strFile, stream ));
  25. //
  26. // Create an IStream from the collection.
  27. //
  28. {
  29. MPC::Serializer_IStream streamGen ( stream );
  30. MPC::Serializer_Buffering streamGen2( streamGen );
  31. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->Save( streamGen2 ));
  32. __MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2.Flush());
  33. }
  34. __MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Finalize( strFile, stream ));
  35. }
  36. hr = S_OK;
  37. __HCP_FUNC_CLEANUP;
  38. __HCP_FUNC_EXIT(hr);
  39. }
  40. HRESULT OfflineCache::Query::Remove( /*[in]*/ const MPC::wstring& strDir )
  41. {
  42. __HCP_FUNC_ENTRY( "OfflineCache::Query::Remove" );
  43. HRESULT hr;
  44. if(m_fNull == false)
  45. {
  46. MPC::wstring strFile;
  47. __MPC_EXIT_IF_METHOD_FAILS(hr, InitFile( strDir, strFile ));
  48. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::DeleteFile( strFile, /*fForce*/true, /*fDelayed*/false ));
  49. }
  50. hr = S_OK;
  51. __HCP_FUNC_CLEANUP;
  52. __HCP_FUNC_EXIT(hr);
  53. }
  54. ////////////////////////////////////////////////////////////////////////////////
  55. ////////////////////////////////////////////////////////////////////////////////
  56. bool OfflineCache::SetOfHelpTopics::AreYouInterested( /*[in]*/ LPCWSTR szID ,
  57. /*[in]*/ int iType )
  58. {
  59. int iDepth = 1;
  60. switch(iType)
  61. {
  62. case ET_NODE :
  63. case ET_SUBNODES :
  64. case ET_SUBNODES_VISIBLE :
  65. case ET_NODESANDTOPICS :
  66. case ET_NODESANDTOPICS_VISIBLE:
  67. case ET_TOPICS :
  68. case ET_TOPICS_VISIBLE : break;
  69. default : return false; // Not interested for now...
  70. }
  71. //
  72. // Count the depth of the taxonomy node, we are only interested in the first two levels.
  73. //
  74. if(szID)
  75. {
  76. WCHAR c;
  77. while((c = *szID++))
  78. {
  79. if(c == '/') iDepth++;
  80. }
  81. }
  82. if(m_inst.m_fDesktop && iDepth < 4) return true;
  83. if( iDepth < 3) return true;
  84. return false;
  85. }
  86. HRESULT OfflineCache::SetOfHelpTopics::Store( /*[in]*/ LPCWSTR szID ,
  87. /*[in]*/ int iType ,
  88. /*[in]*/ const CPCHQueryResultCollection* pColl )
  89. {
  90. __HCP_FUNC_ENTRY( "OfflineCache::SetOfHelpTopics::Store" );
  91. HRESULT hr;
  92. QueryIter it;
  93. __MPC_PARAMCHECK_BEGIN(hr)
  94. __MPC_PARAMCHECK_NOTNULL(pColl);
  95. __MPC_PARAMCHECK_END();
  96. __MPC_EXIT_IF_METHOD_FAILS(hr, Find( szID, iType, it ));
  97. if(it == m_lstQueries.end())
  98. {
  99. it = m_lstQueries.insert( m_lstQueries.end() );
  100. it->m_strID = szID;
  101. it->m_iType = iType;
  102. it->m_iSequence = m_iLastSeq++;
  103. it->m_fNull = (pColl->Size() == 0);
  104. if(m_parent) __MPC_EXIT_IF_METHOD_FAILS(hr, m_parent->SetDirty());
  105. }
  106. //
  107. // Persist to disk.
  108. //
  109. if(it->m_fNull == false)
  110. {
  111. MPC::wstring strDir;
  112. __MPC_EXIT_IF_METHOD_FAILS(hr, InitDir( strDir ));
  113. __MPC_EXIT_IF_METHOD_FAILS(hr, it->Store( strDir, pColl ));
  114. }
  115. hr = S_OK;
  116. __HCP_FUNC_CLEANUP;
  117. __HCP_FUNC_EXIT(hr);
  118. }
  119. HRESULT OfflineCache::SetOfHelpTopics::RemoveQueries()
  120. {
  121. __HCP_FUNC_ENTRY( "OfflineCache::SetOfHelpTopics::RemoveQueries" );
  122. HRESULT hr;
  123. MPC::wstring strDir;
  124. QueryIter it;
  125. __MPC_EXIT_IF_METHOD_FAILS(hr, InitDir( strDir ));
  126. for(it = m_lstQueries.begin(); it != m_lstQueries.end(); it++)
  127. {
  128. __MPC_EXIT_IF_METHOD_FAILS(hr, it->Remove( strDir ));
  129. }
  130. m_lstQueries.clear();
  131. m_iLastSeq = 0;
  132. {
  133. MPC::FileSystemObject fso( strDir.c_str() );
  134. __MPC_EXIT_IF_METHOD_FAILS(hr, fso.DeleteChildren( /*fForce*/true, /*fComplain*/false ));
  135. }
  136. if(m_parent) __MPC_EXIT_IF_METHOD_FAILS(hr, m_parent->SetDirty());
  137. hr = S_OK;
  138. __HCP_FUNC_CLEANUP;
  139. __HCP_FUNC_EXIT(hr);
  140. }
  141. ////////////////////////////////////////////////////////////////////////////////
  142. ////////////////////////////////////////////////////////////////////////////////
  143. HRESULT OfflineCache::Root::SetDirty()
  144. {
  145. m_fDirty = true;
  146. return S_OK;
  147. }
  148. HRESULT OfflineCache::Root::DisableSave()
  149. {
  150. MPC::SmartLock<_ThreadModel> lock( this );
  151. m_dwDisableSave++;
  152. return S_OK;
  153. }
  154. HRESULT OfflineCache::Root::EnableSave()
  155. {
  156. __HCP_FUNC_ENTRY( "OfflineCache::Root::EnableSave" );
  157. HRESULT hr;
  158. MPC::SmartLock<_ThreadModel> lock( this );
  159. if(m_dwDisableSave)
  160. {
  161. if(--m_dwDisableSave == 0)
  162. {
  163. __MPC_EXIT_IF_METHOD_FAILS(hr, Save());
  164. }
  165. }
  166. hr = S_OK;
  167. __HCP_FUNC_CLEANUP;
  168. __HCP_FUNC_EXIT(hr);
  169. }
  170. HRESULT OfflineCache::Root::Save()
  171. {
  172. __HCP_FUNC_ENTRY( "OfflineCache::Root::Save" );
  173. HRESULT hr;
  174. if(m_fDirty && m_fMaster && m_dwDisableSave == 0) // Only master can write to the registry.
  175. {
  176. MPC::wstring strIndex;
  177. CComPtr<MPC::FileStream> stream;
  178. __MPC_EXIT_IF_METHOD_FAILS(hr, GetIndexFile ( strIndex ));
  179. __MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Init( strIndex, stream ));
  180. //
  181. // Create IStream from the collection.
  182. //
  183. {
  184. MPC::Serializer_IStream streamGen ( stream );
  185. MPC::Serializer_Buffering streamGen2( streamGen );
  186. DWORD dwVer = s_dwVersion;
  187. __MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << dwVer );
  188. __MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << *this );
  189. __MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2.Flush());
  190. }
  191. __MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Finalize( strIndex, stream ));
  192. m_fDirty = false;
  193. }
  194. hr = S_OK;
  195. __HCP_FUNC_CLEANUP;
  196. __HCP_FUNC_EXIT(hr);
  197. }
  198. ////////////////////////////////////////
  199. HRESULT OfflineCache::Root::Import( /*[in]*/ const Taxonomy::Instance& inst )
  200. {
  201. __HCP_FUNC_ENTRY( "OfflineCache::Root::Import" );
  202. HRESULT hr;
  203. MPC::SmartLock<_ThreadModel> lock( this );
  204. SKUIter it;
  205. if(m_fMaster == false)
  206. {
  207. __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  208. }
  209. __MPC_EXIT_IF_METHOD_FAILS(hr, Find( inst.m_ths, it ));
  210. if(it == m_lstSKUs.end())
  211. {
  212. it = m_lstSKUs.insert( m_lstSKUs.end() );
  213. it->ConnectToParent( this );
  214. it->m_inst = inst;
  215. m_fDirty = true;
  216. }
  217. hr = S_OK;
  218. __HCP_FUNC_CLEANUP;
  219. __HCP_FUNC_EXIT(hr);
  220. }
  221. ////////////////////
  222. HRESULT OfflineCache::Root::Remove( /*[in]*/ const Taxonomy::HelpSet& ths )
  223. {
  224. __HCP_FUNC_ENTRY( "OfflineCache::Root::Remove" );
  225. HRESULT hr;
  226. MPC::SmartLock<_ThreadModel> lock( this );
  227. SKUIter it;
  228. if(m_fMaster == false)
  229. {
  230. __MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
  231. }
  232. __MPC_EXIT_IF_METHOD_FAILS(hr, Find( ths, it ));
  233. if(it != m_lstSKUs.end())
  234. {
  235. (void)it->RemoveQueries();
  236. m_lstSKUs.erase( it );
  237. m_fDirty = true;
  238. }
  239. hr = S_OK;
  240. __HCP_FUNC_CLEANUP;
  241. __HCP_FUNC_EXIT(hr);
  242. }
  243. HRESULT OfflineCache::Root::Flush( /*[in]*/ bool fForce )
  244. {
  245. __HCP_FUNC_ENTRY( "OfflineCache::Root::Flush" );
  246. HRESULT hr;
  247. MPC::SmartLock<_ThreadModel> lock( this );
  248. if(m_fMaster)
  249. {
  250. if(fForce) m_fDirty = true;
  251. }
  252. else
  253. {
  254. //
  255. // On the slave side, Flush is like Reload.
  256. //
  257. __MPC_EXIT_IF_METHOD_FAILS(hr, Clean());
  258. }
  259. __MPC_EXIT_IF_METHOD_FAILS(hr, Save());
  260. hr = S_OK;
  261. __HCP_FUNC_CLEANUP;
  262. __HCP_FUNC_EXIT(hr);
  263. }
  264. ////////////////////////////////////////
  265. HRESULT OfflineCache::Root::SetReady( /*[in]*/ bool fReady )
  266. {
  267. __HCP_FUNC_ENTRY( "OfflineCache::Root::SetReady" );
  268. HRESULT hr;
  269. MPC::SmartLock<_ThreadModel> lock( this );
  270. m_fReady = fReady;
  271. m_fDirty = true;
  272. hr = S_OK;
  273. __HCP_FUNC_EXIT(hr);
  274. }