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.

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