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.

356 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ocdskspc.c
  5. Abstract:
  6. Routines to ask subcomponents for the approximate amount
  7. of disk space they take up.
  8. Author:
  9. Ted Miller (tedm) 17-Sep-1996
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. VOID
  15. pOcGetChildrenApproximateDiskSpace(
  16. IN POC_MANAGER OcManager,
  17. IN LONG TopLevelOcId,
  18. IN LONG CurrentOcId,
  19. IN LPCTSTR DriveSpec
  20. )
  21. /*++
  22. Routine Description:
  23. Worker routine for pOcGetApproximateDiskSpace(). This routine recursively
  24. iterates through a hierarchy of subcomponents, asking leaf components
  25. for their space (via the OC_CALC_DISK_SPACE interface routine) and amalgamating
  26. child results at non-leaf nodes.
  27. We use the OC_CALC_DISK_SPACE interface routine with an the "ignore-on-disk"
  28. disk space list, to trick the components into telling us how much space their
  29. files take up.
  30. Arguments:
  31. OcManager - supplies OC Manager context.
  32. TopLevelOcId - supplies string id in the component string table for the
  33. top-level subcomponent at the root of the hierarchy whose disk space
  34. is being summed.
  35. CurrentOcId - supplies string id for subcomponent whose disk space is
  36. being summed.
  37. DriveSpec - supplies drive spec of drive we care about for space calculations,
  38. ie, the drive where the system is installed.
  39. AccumulatedSpace - receives the summed space for all the children of the
  40. current subcomponent, or the component itself if it's a leaf node.
  41. Return Value:
  42. None.
  43. --*/
  44. {
  45. HDSKSPC DiskSpaceList;
  46. LONGLONG Space = 0;
  47. LONG Id;
  48. OPTIONAL_COMPONENT CurrentOc;
  49. OPTIONAL_COMPONENT Oc;
  50. pSetupStringTableGetExtraData(
  51. OcManager->ComponentStringTable,
  52. CurrentOcId,
  53. &CurrentOc,
  54. sizeof(OPTIONAL_COMPONENT)
  55. );
  56. if(CurrentOc.FirstChildStringId == -1) {
  57. if ( TopLevelOcId == pOcGetTopLevelComponent(OcManager,CurrentOcId) ){
  58. //
  59. // only get the approximate disk space if we haven't already retreived it from their inf
  60. //
  61. if ((CurrentOc.InternalFlags & OCFLAG_APPROXSPACE) ==0) {
  62. //
  63. // This oc is a child/leaf component.
  64. // Create an ignore-disk disk space list and ask
  65. // the component dll to add its files to it.
  66. //
  67. if(DiskSpaceList = SetupCreateDiskSpaceList(0,0,SPDSL_IGNORE_DISK | SPDSL_DISALLOW_NEGATIVE_ADJUST)) {
  68. OcInterfaceCalcDiskSpace(
  69. OcManager,
  70. pOcGetTopLevelComponent(OcManager,CurrentOcId),
  71. pSetupStringTableStringFromId(OcManager->ComponentStringTable,CurrentOcId),
  72. DiskSpaceList,
  73. TRUE
  74. );
  75. if(!SetupQuerySpaceRequiredOnDrive(DiskSpaceList,DriveSpec,&Space,0,0)) {
  76. Space = 0;
  77. }
  78. SetupDestroyDiskSpaceList(DiskSpaceList);
  79. }
  80. DBGOUT((
  81. TEXT("OCM: pOcGetChildrenApproximateDiskSpace COMP(%s) SUB(%s)\n"),
  82. pSetupStringTableStringFromId( OcManager->ComponentStringTable, TopLevelOcId),
  83. pSetupStringTableStringFromId( OcManager->ComponentStringTable, CurrentOcId)
  84. ));
  85. DBGOUT((TEXT("OCM: Space=%#lx%08lx\n"),(LONG)(Space>>32),(LONG)Space));
  86. //
  87. // Now store the required space we just calculated
  88. //
  89. CurrentOc.SizeApproximation = Space;
  90. pSetupStringTableSetExtraData(
  91. OcManager->ComponentStringTable,
  92. CurrentOcId,
  93. &CurrentOc,
  94. sizeof(OPTIONAL_COMPONENT)
  95. );
  96. }
  97. }
  98. } else {
  99. //
  100. // Parent component. Do all the children, accumulating the result.
  101. //
  102. Id = CurrentOc.FirstChildStringId;
  103. do {
  104. pOcGetChildrenApproximateDiskSpace(OcManager,TopLevelOcId,Id,DriveSpec);
  105. pSetupStringTableGetExtraData(
  106. OcManager->ComponentStringTable,
  107. Id,
  108. &Oc,
  109. sizeof(OPTIONAL_COMPONENT)
  110. );
  111. Id = Oc.NextSiblingStringId;
  112. } while(Id != -1);
  113. //
  114. // Now store the required space we just calculated
  115. //
  116. CurrentOc.SizeApproximation = Space;
  117. pSetupStringTableSetExtraData(
  118. OcManager->ComponentStringTable,
  119. CurrentOcId,
  120. &CurrentOc,
  121. sizeof(OPTIONAL_COMPONENT)
  122. );
  123. }
  124. }
  125. VOID
  126. pOcSumApproximateDiskSpace(
  127. IN POC_MANAGER OcManager,
  128. IN LONG CurrentOcId,
  129. IN OUT LONGLONG *AccumulatedSpace
  130. )
  131. /*++
  132. Routine Description:
  133. Worker routine for pOcGetApproximateDiskSpace(). This routine recursively
  134. iterates through a hierarchy of subcomponents, adding up leaf components
  135. for their space via the stored Estimated Amount
  136. Arguments:
  137. OcManager - supplies OC Manager context.
  138. CurrentOcId - supplies string id for subcomponent whose disk space is
  139. being summed.
  140. AccumulatedSpace - receives the summed space for all the children of the
  141. current subcomponent, or the component itself if it's a leaf node.
  142. Return Value:
  143. None.
  144. --*/
  145. {
  146. LONGLONG Space;
  147. LONG Id;
  148. OPTIONAL_COMPONENT CurrentOc;
  149. OPTIONAL_COMPONENT Oc;
  150. pSetupStringTableGetExtraData(
  151. OcManager->ComponentStringTable,
  152. CurrentOcId,
  153. &CurrentOc,
  154. sizeof(OPTIONAL_COMPONENT)
  155. );
  156. if(CurrentOc.FirstChildStringId == -1) {
  157. DBGOUT((TEXT("Child ")));
  158. Space = CurrentOc.SizeApproximation;
  159. } else {
  160. //
  161. // Parent component. Do all the children, accumulating the result.
  162. //
  163. Space = 0;
  164. DBGOUT((TEXT("Parent ")));
  165. DBGOUT((
  166. TEXT("SUB(%s)"),
  167. pSetupStringTableStringFromId( OcManager->ComponentStringTable, CurrentOcId)
  168. ));
  169. DBGOUT((TEXT("Space=%#lx%08lx\n"),(LONG)(Space>>32),(LONG)Space));
  170. Id = CurrentOc.FirstChildStringId;
  171. do {
  172. pOcSumApproximateDiskSpace(OcManager,Id,&Space);
  173. pSetupStringTableGetExtraData(
  174. OcManager->ComponentStringTable,
  175. Id,
  176. &Oc,
  177. sizeof(OPTIONAL_COMPONENT)
  178. );
  179. Id = Oc.NextSiblingStringId;
  180. } while(Id != -1);
  181. }
  182. *AccumulatedSpace += Space;
  183. CurrentOc.SizeApproximation = Space;
  184. pSetupStringTableSetExtraData(
  185. OcManager->ComponentStringTable,
  186. CurrentOcId,
  187. &CurrentOc,
  188. sizeof(OPTIONAL_COMPONENT)
  189. );
  190. DBGOUT((TEXT(" SUB(%s)"),
  191. pSetupStringTableStringFromId( OcManager->ComponentStringTable, CurrentOcId)));
  192. DBGOUT((TEXT(" Space=%#lx%08lx "),(LONG)(Space>>32),(LONG)Space));
  193. DBGOUT((TEXT(" AccumulatedSpace=%#lx%08lx\n"),(LONG)(*AccumulatedSpace>>32),(LONG)*AccumulatedSpace));
  194. }
  195. VOID
  196. pOcGetApproximateDiskSpace(
  197. IN POC_MANAGER OcManager
  198. )
  199. /*++
  200. Routine Description:
  201. This routine is used to get an approximate disk space usage number
  202. for display in the oc page. This number bears no relation to what is
  203. currently on the disk; rather it merely reflects the approximate of space
  204. the component takes up in an absolute, independent sense, when installed.
  205. Arguments:
  206. OcManager - supplies OC Manager context.
  207. Return Value:
  208. None.
  209. --*/
  210. {
  211. UINT iChild,n;
  212. TCHAR Drive[MAX_PATH];
  213. LONGLONG Space;
  214. OPTIONAL_COMPONENT Oc;
  215. // We check the return code of GetWindowsDirectory to make Prefix happy.
  216. if (0 == GetWindowsDirectory(Drive,MAX_PATH))
  217. return;
  218. Drive[2] = 0;
  219. //
  220. // Iterate through top-level components. We only care about
  221. // ones that have per-component infs, since those are the
  222. // only ones that will show up in the OC Page.
  223. //
  224. for(n=0; n<OcManager->TopLevelOcCount; n++) {
  225. pSetupStringTableGetExtraData(
  226. OcManager->ComponentStringTable,
  227. OcManager->TopLevelOcStringIds[n],
  228. &Oc,
  229. sizeof(OPTIONAL_COMPONENT)
  230. );
  231. if(Oc.InfStringId != -1) {
  232. for(iChild=0;
  233. iChild<OcManager->TopLevelParentOcCount;
  234. iChild++)
  235. {
  236. //
  237. // Now call the component dll for each child subcomponent.
  238. //
  239. pOcGetChildrenApproximateDiskSpace(
  240. OcManager,
  241. OcManager->TopLevelOcStringIds[n],
  242. OcManager->TopLevelParentOcStringIds[iChild],
  243. Drive
  244. );
  245. }
  246. }
  247. }
  248. // Now final pass Sum the all the information in to parent nodes
  249. for(n=0; n<OcManager->TopLevelParentOcCount; n++) {
  250. pSetupStringTableGetExtraData(
  251. OcManager->ComponentStringTable,
  252. OcManager->TopLevelParentOcStringIds[n],
  253. &Oc,
  254. sizeof(OPTIONAL_COMPONENT)
  255. );
  256. Space = 0;
  257. pOcSumApproximateDiskSpace(
  258. OcManager,
  259. OcManager->TopLevelParentOcStringIds[n],
  260. &Space
  261. );
  262. }
  263. }