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.

282 lines
8.8 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: volclean.cpp
  8. //
  9. // Authors;
  10. // Jeff Saathoff (jeffreys)
  11. //
  12. // Notes;
  13. // CSC disk cleanup implementation (IEmptyVolumeCache)
  14. //--------------------------------------------------------------------------
  15. #include "pch.h"
  16. #include "folder.h"
  17. int
  18. CoTaskLoadString(HINSTANCE hInstance, UINT idString, LPWSTR *ppwsz)
  19. {
  20. int nResult = 0;
  21. *ppwsz = NULL;
  22. ULONG cchString = SizeofStringResource(hInstance, idString);
  23. if (cchString)
  24. {
  25. cchString++; // for NULL
  26. *ppwsz = (LPWSTR)CoTaskMemAlloc(cchString * sizeof(WCHAR));
  27. if (*ppwsz)
  28. nResult = LoadStringW(hInstance, idString, *ppwsz, cchString);
  29. }
  30. return nResult;
  31. }
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // //
  34. // IClassFactory::CreateInstance support //
  35. // //
  36. ///////////////////////////////////////////////////////////////////////////////
  37. HRESULT WINAPI
  38. CCscVolumeCleaner::CreateInstance(REFIID riid, LPVOID *ppv)
  39. {
  40. return Create(FALSE, riid, ppv);
  41. }
  42. HRESULT WINAPI
  43. CCscVolumeCleaner::CreateInstance2(REFIID riid, LPVOID *ppv)
  44. {
  45. return Create(TRUE, riid, ppv);
  46. }
  47. HRESULT WINAPI
  48. CCscVolumeCleaner::Create(BOOL fPinned, REFIID riid, LPVOID *ppv)
  49. {
  50. HRESULT hr;
  51. CCscVolumeCleaner *pThis = new CCscVolumeCleaner(fPinned);
  52. if (pThis)
  53. {
  54. hr = pThis->QueryInterface(riid, ppv);
  55. pThis->Release();
  56. }
  57. else
  58. hr = E_OUTOFMEMORY;
  59. return hr;
  60. }
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // //
  63. // IUnknown implementation //
  64. // //
  65. ///////////////////////////////////////////////////////////////////////////////
  66. STDMETHODIMP CCscVolumeCleaner::QueryInterface(REFIID riid, void **ppv)
  67. {
  68. static const QITAB qit[] =
  69. {
  70. QITABENT(CCscVolumeCleaner, IEmptyVolumeCache),
  71. QITABENT(CCscVolumeCleaner, IEmptyVolumeCache2),
  72. { 0 },
  73. };
  74. return QISearch(this, qit, riid, ppv);
  75. }
  76. STDMETHODIMP_(ULONG) CCscVolumeCleaner::AddRef()
  77. {
  78. return InterlockedIncrement(&m_cRef);
  79. }
  80. STDMETHODIMP_(ULONG) CCscVolumeCleaner::Release()
  81. {
  82. ASSERT( 0 != m_cRef );
  83. ULONG cRef = InterlockedDecrement(&m_cRef);
  84. if ( 0 == cRef )
  85. {
  86. delete this;
  87. }
  88. return cRef;
  89. }
  90. ///////////////////////////////////////////////////////////////////////////////
  91. // //
  92. // IEmptyVolumeCache implementation //
  93. // //
  94. ///////////////////////////////////////////////////////////////////////////////
  95. STDMETHODIMP
  96. CCscVolumeCleaner::Initialize(HKEY /*hkRegKey*/,
  97. LPCWSTR pcwszVolume,
  98. LPWSTR *ppwszDisplayName,
  99. LPWSTR *ppwszDescription,
  100. LPDWORD pdwFlags)
  101. {
  102. BOOL bSettingsMode;
  103. CSCSPACEUSAGEINFO sui = {0};
  104. TraceEnter(TRACE_SHELLEX, "IEmptyVolumeCache::Initialize");
  105. TraceAssert(pcwszVolume != NULL);
  106. TraceAssert(ppwszDisplayName != NULL);
  107. TraceAssert(ppwszDescription != NULL);
  108. TraceAssert(pdwFlags != NULL);
  109. TraceAssert(IsCSCEnabled());
  110. bSettingsMode = (BOOL)((*pdwFlags) & EVCF_SETTINGSMODE);
  111. *ppwszDisplayName = NULL;
  112. *ppwszDescription = NULL;
  113. *pdwFlags = 0;
  114. // If this isn't the volume containing the CSC database, then we have
  115. // nothing to free. Note that we don't use the space usage data
  116. // returned here.
  117. GetCscSpaceUsageInfo(&sui);
  118. if (!bSettingsMode && !PathIsSameRoot(sui.szVolume, pcwszVolume))
  119. TraceLeaveResult(S_FALSE);
  120. m_PurgerSel.SetFlags(m_fPinned ? PURGE_FLAG_PINNED : (PURGE_FLAG_UNPINNED | PURGE_IGNORE_ACCESS));
  121. m_pPurger = new CCachePurger(m_PurgerSel,
  122. CachePurgerCallback,
  123. this);
  124. if (!m_pPurger)
  125. TraceLeaveResult(E_FAIL);
  126. // If we're freeing auto-cached files, we want to be enabled by default,
  127. // but not if we're freeing pinned files.
  128. *pdwFlags = 0;
  129. if (!m_fPinned)
  130. *pdwFlags = EVCF_ENABLEBYDEFAULT | EVCF_ENABLEBYDEFAULT_AUTO;
  131. // If policy allows, turn on the "Details" button which launches the viewer
  132. if (!CConfig::GetSingleton().NoCacheViewer())
  133. *pdwFlags |= EVCF_HASSETTINGS;
  134. // Load the display name string
  135. CoTaskLoadString(g_hInstance,
  136. m_fPinned ? IDS_APPLICATION : IDS_DISKCLEAN_DISPLAY,
  137. ppwszDisplayName);
  138. // Load the description string
  139. CoTaskLoadString(g_hInstance,
  140. m_fPinned ? IDS_DISKCLEAN_PIN_DESCRIPTION : IDS_DISKCLEAN_DESCRIPTION,
  141. ppwszDescription);
  142. TraceLeaveResult(S_OK);
  143. }
  144. STDMETHODIMP
  145. CCscVolumeCleaner::GetSpaceUsed(DWORDLONG *pdwlSpaceUsed,
  146. LPEMPTYVOLUMECACHECALLBACK picb)
  147. {
  148. m_pDiskCleaner = picb;
  149. m_pPurger->Scan();
  150. if (m_pDiskCleaner)
  151. m_pDiskCleaner->ScanProgress(m_dwlSpaceToFree,
  152. EVCCBF_LASTNOTIFICATION,
  153. NULL);
  154. *pdwlSpaceUsed = m_dwlSpaceToFree;
  155. return S_OK;
  156. }
  157. STDMETHODIMP
  158. CCscVolumeCleaner::Purge(DWORDLONG /*dwlSpaceToFree*/,
  159. LPEMPTYVOLUMECACHECALLBACK picb)
  160. {
  161. m_pDiskCleaner = picb;
  162. m_pPurger->Delete();
  163. if (m_pDiskCleaner)
  164. m_pDiskCleaner->PurgeProgress(m_dwlSpaceFreed,
  165. 0,
  166. EVCCBF_LASTNOTIFICATION,
  167. NULL);
  168. return S_OK;
  169. }
  170. STDMETHODIMP
  171. CCscVolumeCleaner::ShowProperties(HWND /*hwnd*/)
  172. {
  173. // Launch the viewer
  174. COfflineFilesFolder::Open();
  175. return S_FALSE;
  176. }
  177. STDMETHODIMP
  178. CCscVolumeCleaner::Deactivate(LPDWORD /*pdwFlags*/)
  179. {
  180. // nothing to do here
  181. return S_OK;
  182. }
  183. // IEmptyVolumeCache2 method
  184. STDMETHODIMP
  185. CCscVolumeCleaner::InitializeEx(HKEY hkRegKey,
  186. LPCWSTR pcwszVolume,
  187. LPCWSTR pcwszKeyName,
  188. LPWSTR *ppwszDisplayName,
  189. LPWSTR *ppwszDescription,
  190. LPWSTR *ppwszBtnText,
  191. LPDWORD pdwFlags)
  192. {
  193. HRESULT hr = Initialize(hkRegKey,
  194. pcwszVolume,
  195. ppwszDisplayName,
  196. ppwszDescription,
  197. pdwFlags);
  198. if (S_OK == hr)
  199. CoTaskLoadString(g_hInstance, IDS_DISKCLEAN_BTN_TEXT, ppwszBtnText);
  200. return hr;
  201. }
  202. BOOL
  203. CCscVolumeCleaner::ScanCallback(CCachePurger *pPurger)
  204. {
  205. BOOL bContinue = TRUE;
  206. // If the pinned state matches what we're looking for, add the
  207. // size to the total.
  208. if (pPurger->WillDeleteThisFile())
  209. m_dwlSpaceToFree += pPurger->FileBytes();
  210. if (m_pDiskCleaner)
  211. bContinue = SUCCEEDED(m_pDiskCleaner->ScanProgress(m_dwlSpaceToFree,
  212. 0,
  213. NULL));
  214. return bContinue;
  215. }
  216. BOOL
  217. CCscVolumeCleaner::DeleteCallback(CCachePurger *pPurger)
  218. {
  219. BOOL bContinue = TRUE;
  220. // Don't let this go below zero
  221. m_dwlSpaceToFree -= min(pPurger->FileBytes(), m_dwlSpaceToFree);
  222. m_dwlSpaceFreed += pPurger->FileBytes();
  223. if (m_pDiskCleaner)
  224. bContinue = SUCCEEDED(m_pDiskCleaner->PurgeProgress(m_dwlSpaceFreed,
  225. m_dwlSpaceToFree,
  226. 0,
  227. NULL));
  228. return bContinue;
  229. }
  230. BOOL CALLBACK
  231. CCscVolumeCleaner::CachePurgerCallback(CCachePurger *pPurger)
  232. {
  233. PCSCVOLCLEANER pThis = (PCSCVOLCLEANER)pPurger->CallbackData();
  234. switch (pPurger->Phase())
  235. {
  236. case PURGE_PHASE_SCAN:
  237. return pThis->ScanCallback(pPurger);
  238. case PURGE_PHASE_DELETE:
  239. return pThis->DeleteCallback(pPurger);
  240. }
  241. return FALSE;
  242. }