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.

289 lines
8.1 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: wdfiter.cxx
  7. //
  8. // Contents: CWrappedDocFile iterator methods
  9. //
  10. // History: 22-Jan-92 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #include <dfhead.cxx>
  14. #pragma hdrstop
  15. //+---------------------------------------------------------------------------
  16. //
  17. // Member: CWrappedDocFile::FindGreaterEntry, public
  18. //
  19. // Synopsis: Returns the next greater child
  20. //
  21. // Arguments: [pdfnKey] - Previous key
  22. // [pib] - Fast iterator buffer
  23. // [pstat] - Full iterator buffer
  24. //
  25. // Returns: Appropriate status code
  26. //
  27. // Modifies: [pib] or [pstat]
  28. //
  29. // History: 16-Apr-93 DrewB Created
  30. //
  31. // Notes: Either [pib] or [pstat] must be NULL
  32. //
  33. //----------------------------------------------------------------------------
  34. #ifdef CODESEGMENTS
  35. #pragma code_seg(SEG_CWrappedDocFile_FindGreaterEntry) // Iterate_TEXT
  36. #endif
  37. SCODE CWrappedDocFile::FindGreaterEntry(CDfName const *pdfnKey,
  38. SIterBuffer *pib,
  39. STATSTGW *pstat)
  40. {
  41. SCODE sc;
  42. CDfName *pdfnGreater, *pdfn;
  43. CUpdate *pud, *pudGreater;
  44. BOOL fFilled = FALSE;
  45. WCHAR *pwcsName;
  46. olDebugOut((DEB_ITRACE, "In CWrappedDocFile::FindGreaterEntry:%p("
  47. "%p, %p, %p)\n", this, pdfnKey, pib, pstat));
  48. olAssert(pib == NULL || pstat == NULL);
  49. // Find the update entry that has the next greater name than the key
  50. pudGreater = NULL;
  51. for (pud = _ulChanged.GetHead(); pud; pud = pud->GetNext())
  52. {
  53. if (pud->IsCreate() || pud->IsRename())
  54. {
  55. pdfn = pud->GetCurrentName();
  56. if (_ulChanged.IsEntry(pdfn, NULL) == UIE_CURRENT &&
  57. CDirectory::NameCompare(pdfn, pdfnKey) > 0 &&
  58. (pudGreater == NULL ||
  59. CDirectory::NameCompare(pdfn,
  60. pudGreater->GetCurrentName()) < 0))
  61. {
  62. pudGreater = pud;
  63. pdfnGreater = pdfn;
  64. }
  65. }
  66. }
  67. // Request the next greater name from the base
  68. if (_pdfBase != NULL)
  69. {
  70. CDfName dfnKey;
  71. // Loop until we either get a valid name or we run out
  72. dfnKey.Set(pdfnKey);
  73. for (;;)
  74. {
  75. if (FAILED(sc = _pdfBase->FindGreaterEntry(&dfnKey, pib, pstat)))
  76. {
  77. if (sc != STG_E_NOMOREFILES)
  78. {
  79. olErr(EH_Err, sc);
  80. }
  81. else
  82. {
  83. break;
  84. }
  85. }
  86. if (pib)
  87. dfnKey.Set(&pib->dfnName);
  88. else
  89. {
  90. olAssert(pstat != NULL);
  91. dfnKey.CopyString(pstat->pwcsName);
  92. }
  93. // Filter this name against the update list
  94. pdfn = &dfnKey;
  95. if (_ulChanged.IsEntry(pdfn, NULL) == UIE_ORIGINAL)
  96. {
  97. if (pstat)
  98. TaskMemFree(pstat->pwcsName);
  99. continue;
  100. }
  101. // If this name is less than the update list name, use
  102. // the stat entry
  103. if (pudGreater == NULL ||
  104. CDirectory::NameCompare(pdfn,
  105. pudGreater->GetCurrentName()) < 0)
  106. {
  107. PTSetMember *ptsm;
  108. fFilled = TRUE;
  109. if (pstat && (ptsm = _ppubdf->FindXSMember(pdfn, GetName())))
  110. {
  111. pwcsName = pstat->pwcsName;
  112. // We want to keep the name already in pstat but pick
  113. // up any new times on the XSM
  114. olChkTo(EH_name, ptsm->Stat(pstat, STATFLAG_NONAME));
  115. pstat->pwcsName = pwcsName;
  116. }
  117. // No need to check for renames because Exists would
  118. // have failed if there was a rename
  119. }
  120. else if (pstat)
  121. {
  122. TaskMemFree(pstat->pwcsName);
  123. }
  124. // Found a valid name, so stop looping
  125. break;
  126. }
  127. }
  128. if (!fFilled)
  129. {
  130. if (pudGreater == NULL)
  131. {
  132. sc = STG_E_NOMOREFILES;
  133. }
  134. else
  135. {
  136. if (pstat)
  137. {
  138. if (pudGreater->IsCreate())
  139. {
  140. olChk(pudGreater->GetXSM()->Stat(pstat, 0));
  141. }
  142. else
  143. {
  144. olAssert(pudGreater->IsRename());
  145. olChk(StatEntry(pudGreater->GetCurrentName(), pib, pstat));
  146. }
  147. }
  148. else
  149. {
  150. olAssert(pib != NULL);
  151. pib->dfnName.Set(pudGreater->GetCurrentName());
  152. pib->type = pudGreater->GetFlags() & ULF_TYPEFLAGS;
  153. }
  154. sc = S_OK;
  155. }
  156. }
  157. olDebugOut((DEB_ITRACE, "Out CWrappedDocFile::FindGreaterEntry\n"));
  158. EH_Err:
  159. return sc;
  160. EH_name:
  161. if (pstat)
  162. TaskMemFree(pwcsName);
  163. return sc;
  164. }
  165. //+---------------------------------------------------------------------------
  166. //
  167. // Member: CWrappedDocFile::StatEntry, public
  168. //
  169. // Synopsis: Gets information for a child
  170. //
  171. // Arguments: [pdfn] - Child name
  172. // [pib] - Short information
  173. // [pstat] - Full information
  174. //
  175. // Returns: Appropriate status code
  176. //
  177. // Modifies: [pib] or [pstat]
  178. //
  179. // History: 16-Apr-93 DrewB Created
  180. //
  181. // Notes: Either [pib] or [pstat] must be NULL
  182. //
  183. //----------------------------------------------------------------------------
  184. #ifdef CODESEGMENTS
  185. #pragma code_seg(SEG_CWrappedDocFile_StatEntry)
  186. #endif
  187. SCODE CWrappedDocFile::StatEntry(CDfName const *pdfn,
  188. SIterBuffer *pib,
  189. STATSTGW *pstat)
  190. {
  191. CUpdate *pud;
  192. UlIsEntry uie;
  193. SCODE sc = S_FALSE;
  194. CDfName const *pdfnBase = pdfn;
  195. BOOL fResult = FALSE;
  196. olDebugOut((DEB_ITRACE, "In CWrappedDocFile::StatEntry:%p(%p, %p, %p)\n",
  197. this, pdfn, pib, pstat));
  198. olAssert((pib != NULL) != (pstat != NULL));
  199. // Attempt to find the name in the update list
  200. uie = _ulChanged.IsEntry(pdfn, &pud);
  201. if (uie == UIE_ORIGINAL)
  202. {
  203. // Name has been renamed or deleted
  204. sc = STG_E_FILENOTFOUND;
  205. fResult = TRUE;
  206. }
  207. else if (uie == UIE_CURRENT)
  208. {
  209. if (pib)
  210. {
  211. pib->dfnName.Set(pud->GetCurrentName());
  212. pib->type = pud->GetFlags() & ULF_TYPEFLAGS;
  213. fResult = TRUE;
  214. sc = S_OK;
  215. }
  216. else
  217. {
  218. olAssert(pstat != NULL);
  219. // Find whether the given name came from a create entry
  220. // or resolve the name to the base name
  221. pud = CUpdateList::FindBase(pud, &pdfnBase);
  222. if (pud != NULL)
  223. {
  224. // Stat creation update entry
  225. olChk(pud->GetXSM()->Stat(pstat, 0));
  226. fResult = TRUE;
  227. }
  228. // else the update entry is a rename of an object in the base
  229. // and FindBase changed pdfnBase to the base name
  230. }
  231. }
  232. olAssert(fResult || sc == S_FALSE);
  233. if (!fResult)
  234. {
  235. // Haven't found the entry so try the base
  236. if (_pdfBase)
  237. {
  238. olChk(_pdfBase->StatEntry(pdfnBase, pib, pstat));
  239. // Check to see if we need to return a renamed name
  240. if (!pdfn->IsEqual(pdfnBase))
  241. {
  242. if (pib)
  243. pib->dfnName.Set(pdfn);
  244. else
  245. {
  246. TaskMemFree(pstat->pwcsName);
  247. olMem(pstat->pwcsName =
  248. (WCHAR *)TaskMemAlloc(pdfn->GetLength()));
  249. memcpy(pstat->pwcsName, pdfn->GetBuffer(),
  250. pdfn->GetLength());
  251. }
  252. }
  253. }
  254. else
  255. sc = STG_E_FILENOTFOUND;
  256. }
  257. olDebugOut((DEB_ITRACE, "Out CWrappedDocFile::StatEntry\n"));
  258. EH_Err:
  259. return sc;
  260. }