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.

427 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. diskcleaner.c
  5. Abstract:
  6. Implements the code specific to the disk cleaner COM server.
  7. Author:
  8. Jim Schmidt (jimschm) 21-Jan-2001
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "pch.h"
  13. #include "undop.h"
  14. #include "com.h"
  15. /*++
  16. Routine Descriptions:
  17. This constructor is a generic class factory that supports multiple object
  18. types. Upon creation, the object interface pointer ref count is set to zero,
  19. and the global number of objects for the dll is incremented.
  20. The destructor simply decrements the DLL object count.
  21. Arguments:
  22. None.
  23. Return Value:
  24. None.
  25. --*/
  26. CUninstallDiskCleaner::CUninstallDiskCleaner (
  27. VOID
  28. )
  29. {
  30. //
  31. // -Initialize the interface pointer count
  32. // -Increment the DLL's global count of objects
  33. //
  34. _References = 0;
  35. g_DllObjects++;
  36. }
  37. CUninstallDiskCleaner::~CUninstallDiskCleaner (
  38. VOID
  39. )
  40. {
  41. g_DllObjects--;
  42. }
  43. STDMETHODIMP
  44. CUninstallDiskCleaner::QueryInterface (
  45. IN REFIID InterfaceIdRef,
  46. OUT PVOID *InterfacePtr
  47. )
  48. {
  49. HRESULT hr = S_OK;
  50. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
  51. __try {
  52. //
  53. // Initialize out arg
  54. //
  55. __try {
  56. *InterfacePtr = NULL;
  57. }
  58. __except(1) {
  59. hr = E_INVALIDARG;
  60. }
  61. if (hr != S_OK) {
  62. DEBUGMSG ((DBG_ERROR, __FUNCTION__ ": Invalid InterfacePtr arg"));
  63. __leave;
  64. }
  65. //
  66. // Test for the supported interface
  67. //
  68. if (IsEqualIID (InterfaceIdRef, IID_IUnknown)) {
  69. DEBUGMSG ((DBG_VERBOSE, "Caller requested IUnknown"));
  70. *InterfacePtr = (LPUNKNOWN) this;
  71. AddRef();
  72. __leave;
  73. }
  74. if (IsEqualIID (InterfaceIdRef, IID_IEmptyVolumeCache)) {
  75. DEBUGMSG ((DBG_VERBOSE, "Caller requested IEmptyVolumeCache"));
  76. *InterfacePtr = (IEmptyVolumeCache*) this;
  77. AddRef();
  78. __leave;
  79. }
  80. DEBUGMSG ((DBG_WARNING, "Caller requested unknown interface"));
  81. hr = E_NOINTERFACE;
  82. }
  83. __finally {
  84. }
  85. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
  86. return hr;
  87. }
  88. /*++
  89. Routine Description:
  90. AddRef is the standard IUnknown member function that increments the object
  91. reference count.
  92. Release is the standard IUnknown member function that decrements the object
  93. reference count.
  94. Arguments:
  95. None.
  96. Return Value:
  97. The number of interface references.
  98. --*/
  99. STDMETHODIMP_(ULONG)
  100. CUninstallDiskCleaner::AddRef (
  101. VOID
  102. )
  103. {
  104. return ++_References;
  105. }
  106. STDMETHODIMP_(ULONG)
  107. CUninstallDiskCleaner::Release (
  108. VOID
  109. )
  110. {
  111. if (!_References) {
  112. DEBUGMSG ((DBG_ERROR, "Can't release because there are no references"));
  113. } else {
  114. _References--;
  115. if (!_References) {
  116. delete this;
  117. return 0;
  118. }
  119. }
  120. return _References;
  121. }
  122. STDMETHODIMP
  123. CUninstallDiskCleaner::Initialize (
  124. IN HKEY hRegKey,
  125. IN PCWSTR VolumePath,
  126. OUT PWSTR *DisplayName,
  127. OUT PWSTR *Description,
  128. IN OUT DWORD *Flags
  129. )
  130. /*++
  131. Routine Description:
  132. The Initialize member function does most of the work for the disk cleaner.
  133. It evaluates the backup files, and if they all exist, and the user has the
  134. right to execute an uninstall, and if they are at least 7 days old, then
  135. show the backup items in the list box.
  136. Arguments:
  137. hRegKey - Specifies the registry key for this object, used to store
  138. properties and settings
  139. VolumePath - Specifies the volume path selected by the user when they launch
  140. disk cleanup
  141. DisplayName - Receives the name to put in the disk cleaner list box, or NULL
  142. to use the name stored in the registry
  143. Description - Receives the verbose description to put in the disk cleaner
  144. Details text control, or NULL to use the description stored in the
  145. registry
  146. Flags - Specifies flags that influence the behavior of this disk cleaner
  147. object and flags that indicate which mode the disk cleaner is running
  148. in. Receivies flags that control how the disk cleaner displays this
  149. object's info in its UI.
  150. Return Value:
  151. S_FALSE - The disk cleaner will skip this object
  152. S_OK - The disk cleaner will include this object in its UI
  153. --*/
  154. {
  155. HRESULT hr = S_FALSE;
  156. DWORD inFlags = *Flags;
  157. ULONGLONG diskSpace;
  158. UNINSTALLSTATUS status;
  159. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
  160. __try {
  161. //
  162. // Initialize
  163. //
  164. _Purged = FALSE;
  165. *DisplayName = NULL; // use the display name stored in the registry
  166. *Description = NULL; // use the description stored in the registry
  167. *Flags = 0; // unchecked by default, no property page
  168. //
  169. // Check undo files. If they are not at least 7 days old, don't
  170. // recommend them to be deleted.
  171. //
  172. status = SanityCheck (FAIL_IF_NOT_OLD, VolumePath, &diskSpace);
  173. if (status == Uninstall_NewImage) {
  174. DEBUGMSG ((DBG_WARNING, "OS Backup Image is too new to be listed in the disk cleaner"));
  175. __leave;
  176. }
  177. if (diskSpace == 0) {
  178. DEBUGMSG ((DBG_WARNING, "OS Backup Image is not present, isn't valid, can't be removed, or has missing registry entries"));
  179. __leave;
  180. }
  181. //
  182. // Files are old enough and are present on the machine. Initialize the
  183. // IEmptyVolumeCache interface
  184. //
  185. if (inFlags & EVCF_SETTINGSMODE) {
  186. DEBUGMSG ((DBG_VERBOSE, "We don't support settings mode"));
  187. __leave;
  188. }
  189. hr = S_OK;
  190. DEBUGMSG ((DBG_VERBOSE, "Successful initialization"));
  191. }
  192. __finally {
  193. }
  194. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
  195. return hr;
  196. }
  197. STDMETHODIMP
  198. CUninstallDiskCleaner::GetSpaceUsed (
  199. OUT DWORDLONG *SpaceUsed,
  200. IN IEmptyVolumeCacheCallBack *Callback
  201. )
  202. /*++
  203. Routine Description:
  204. GetSpaceUsed is called by the disk cleaner after this object has
  205. successfully initialized. Our job is to return the amount of disk space we
  206. can clean up. Since all undo files are on the same drive, we don't care
  207. about the volume restriction passed to the Initialize member function.
  208. Arguments:
  209. SpaceUsed - Receives the amount of disk space that we can recover upon
  210. deletion. We don't take into account cluster savings, but maybe we
  211. should.
  212. Callback - Specifies an object that provides a progress interface. We don't
  213. use this.
  214. Return Value:
  215. S_FALSE - Failed to get disk space values
  216. S_OK - Success
  217. --*/
  218. {
  219. ULONGLONG diskSpace;
  220. HRESULT hr = S_FALSE;
  221. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
  222. __try {
  223. if (SanityCheck (QUICK_CHECK, NULL, &diskSpace) == Uninstall_NewImage) {
  224. DEBUGMSG ((DBG_ERROR, "Sanity check failed"));
  225. __leave;
  226. }
  227. DEBUGMSG ((DBG_VERBOSE, "Disk space: %I64u", diskSpace));
  228. *SpaceUsed = (DWORDLONG) diskSpace;
  229. hr = S_OK;
  230. }
  231. __finally {
  232. }
  233. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
  234. return hr;
  235. }
  236. STDMETHODIMP
  237. CUninstallDiskCleaner::Purge (
  238. IN DWORDLONG SpaceToFree,
  239. IN IEmptyVolumeCacheCallBack *Callback
  240. )
  241. /*++
  242. Routine Description:
  243. Purge does the deletion. We don't care about the inbound arguments. If we
  244. are called, it is because Initialize succeeded, and GetSpaceUsed returned a
  245. valid number. These two things mean it is OK to remove uninstall capability.
  246. Arguments:
  247. SpaceToFree - Specifies the space to free. We expect this to equal the
  248. value provided in GetSpaceUsed.
  249. Callback - Specifies an interface for progress updates. We don't use this.
  250. Return Value:
  251. S_OK - Success
  252. S_FALSE - Failed
  253. --*/
  254. {
  255. HRESULT hr = S_FALSE;
  256. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
  257. __try {
  258. if (!DoCleanup()) {
  259. __leave;
  260. }
  261. _Purged = TRUE;
  262. hr = S_OK;
  263. }
  264. __finally {
  265. }
  266. DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
  267. return hr;
  268. }
  269. //
  270. // NO-OP property page stub
  271. //
  272. STDMETHODIMP
  273. CUninstallDiskCleaner::ShowProperties (
  274. IN HWND hwnd
  275. )
  276. {
  277. MYASSERT (FALSE);
  278. return S_FALSE;
  279. }
  280. STDMETHODIMP
  281. CUninstallDiskCleaner::Deactivate (
  282. OUT DWORD *Flags
  283. )
  284. /*++
  285. Routine Description:
  286. Deactivate indicates if the uninstall list item should be permanently
  287. removed from the disk cleaner or not, based on a successful deletion of the
  288. backup image.
  289. Arguments:
  290. Flags - Receives the indicator to remove the list item from the disk
  291. cleaner list
  292. Return Value:
  293. Always S_OK
  294. --*/
  295. {
  296. //
  297. // Done -- if we deleted uninstall, remove the list item
  298. //
  299. *Flags = _Purged ? EVCF_REMOVEFROMLIST : 0;
  300. return S_OK;
  301. }