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.

397 lines
11 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: ulist.cxx
  7. //
  8. // Contents: CUpdateList implementation and support routines
  9. //
  10. // History: 15-Jan-92 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #include <dfhead.cxx>
  14. #pragma hdrstop
  15. //+--------------------------------------------------------------
  16. //
  17. // Member: CUpdate::CUpdate, public
  18. //
  19. // Synopsis: Constructor
  20. //
  21. // Arguments: [pdfnCurrentName] - Current name pointer
  22. // [pdfnOriginalName] - Original name pointer
  23. // [dlLUID] - LUID
  24. // [dwFlags] - Flags
  25. // [ptsm] - Entry object
  26. //
  27. // History: 15-Jan-92 DrewB Created
  28. //
  29. //---------------------------------------------------------------
  30. #ifdef CODESEGMENTS
  31. #pragma code_seg(SEG_CUpdate_CUpdate)
  32. #endif
  33. CUpdate::CUpdate(CDfName const *pdfnCurrent,
  34. CDfName const *pdfnOriginal,
  35. DFLUID dlLUID,
  36. DWORD dwFlags,
  37. PTSetMember *ptsm)
  38. {
  39. SetCurrentName(pdfnCurrent);
  40. SetOriginalName(pdfnOriginal);
  41. _dl = dlLUID;
  42. _dwFlags = dwFlags;
  43. _ptsm = P_TO_BP(CBasedTSetMemberPtr, ptsm);
  44. _pudNext = _pudPrev = NULL;
  45. if (_ptsm)
  46. _ptsm->AddRef();
  47. }
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Member: CUpdate::~CUpdate, public
  51. //
  52. // Synopsis: Destructor
  53. //
  54. // History: 05-Nov-92 DrewB Created
  55. //
  56. //----------------------------------------------------------------------------
  57. #ifdef CODESEGMENTS
  58. #pragma code_seg(SEG_CUpdate_1CUpdate) // inline?
  59. #endif
  60. CUpdate::~CUpdate(void)
  61. {
  62. if (_ptsm)
  63. _ptsm->Release();
  64. }
  65. //+--------------------------------------------------------------
  66. //
  67. // Member: CUpdateList::Add, public
  68. //
  69. // Synopsis: Adds an element to an update list
  70. //
  71. // Arguments: [pdfnCurrent] - Current name
  72. // [pdfnOriginal] - Original name
  73. // [dlLUID] - LUID
  74. // [dwFlags] - Flags
  75. // [ptsm] - Entry object
  76. //
  77. // Returns: The new element or NULL
  78. //
  79. // History: 15-Jan-92 DrewB Created
  80. //
  81. // Notes: Caller must handle NULL
  82. // Entries must be added in the list in the order of
  83. // Add calls
  84. //
  85. //---------------------------------------------------------------
  86. #ifdef CODESEGMENTS
  87. #pragma code_seg(SEG_CUpdateList_Add)
  88. #endif
  89. CUpdate *CUpdateList::Add(IMalloc * const pMalloc,
  90. CDfName const *pdfnCurrent,
  91. CDfName const *pdfnOriginal,
  92. DFLUID dlLUID,
  93. DWORD dwFlags,
  94. PTSetMember *ptsm)
  95. {
  96. CUpdate *pudNew;
  97. olDebugOut((DEB_ITRACE, "In CUpdateList::Add:%p("
  98. "%ws, %ws, %ld, %lX, %p)\n", this, pdfnCurrent->GetBuffer(),
  99. pdfnOriginal->GetBuffer(), dlLUID, dwFlags, ptsm));
  100. olAssert((dlLUID != DF_NOLUID || pdfnOriginal != NULL) &&
  101. aMsg("Create update luid can't be DF_NOLUID"));
  102. pudNew = new (pMalloc) CUpdate(pdfnCurrent, pdfnOriginal, dlLUID,
  103. dwFlags, ptsm);
  104. if (pudNew)
  105. {
  106. Append(pudNew);
  107. }
  108. olDebugOut((DEB_ITRACE, "Out CUpdateList::Add => %p\n", pudNew));
  109. return pudNew;
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CUpdateList::Append, public
  114. //
  115. // Synopsis: Appends an update to the list
  116. //
  117. // Arguments: [pud] - Update
  118. //
  119. // History: 25-Nov-92 DrewB Created
  120. //
  121. //----------------------------------------------------------------------------
  122. #ifdef CODESEGMENTS
  123. #pragma code_seg(SEG_CUpdateList_Append)
  124. #endif
  125. void CUpdateList::Append(CUpdate *pud)
  126. {
  127. olDebugOut((DEB_ITRACE, "In CUpdateList::Append:%p(%p)\n", this, pud));
  128. if (_pudTail)
  129. _pudTail->SetNext(pud);
  130. else
  131. _pudHead = P_TO_BP(CBasedUpdatePtr, pud);
  132. pud->SetPrev(BP_TO_P(CUpdate *, _pudTail));
  133. pud->SetNext(NULL);
  134. _pudTail = P_TO_BP(CBasedUpdatePtr, pud);
  135. olDebugOut((DEB_ITRACE, "Out CUpdateList::Append\n"));
  136. }
  137. //+---------------------------------------------------------------------------
  138. //
  139. // Member: CUpdateList::Remove, public
  140. //
  141. // Synopsis: Removes an element from the list
  142. //
  143. // Arguments: [pud] - Element to remove
  144. //
  145. // History: 25-Nov-92 DrewB Created
  146. //
  147. //----------------------------------------------------------------------------
  148. #ifdef CODESEGMENTS
  149. #pragma code_seg(SEG_CUpdateList_Remove)
  150. #endif
  151. void CUpdateList::Remove(CUpdate *pud)
  152. {
  153. olDebugOut((DEB_ITRACE, "In CUpdateList::Remove:%p(%p)\n", this, pud));
  154. olAssert(pud != NULL);
  155. CUpdate *pudNext = pud->GetNext();
  156. CUpdate *pudPrev = pud->GetPrev();
  157. if (pud->GetNext())
  158. pudNext->SetPrev(pudPrev);
  159. if (pud->GetPrev())
  160. pudPrev->SetNext(pudNext);
  161. if (pud == _pudHead)
  162. _pudHead = P_TO_BP(CBasedUpdatePtr, pudNext);
  163. if (pud == _pudTail)
  164. _pudTail = P_TO_BP(CBasedUpdatePtr, pudPrev);
  165. pud->SetNext(NULL);
  166. pud->SetPrev(NULL);
  167. olDebugOut((DEB_ITRACE, "Out CUpdateList::Remove\n"));
  168. }
  169. //+--------------------------------------------------------------
  170. //
  171. // Member: CUpdateList::Empty, public
  172. //
  173. // Synopsis: Frees all elements in an update list
  174. //
  175. // History: 06-Jan-92 DrewB Created
  176. //
  177. //---------------------------------------------------------------
  178. #ifdef CODESEGMENTS
  179. #pragma code_seg(SEG_CUpdateList_Empty)
  180. #endif
  181. void CUpdateList::Empty(void)
  182. {
  183. CUpdate *pudTmp;
  184. olDebugOut((DEB_ITRACE, "In CUpdateList::Empty()\n"));
  185. while (_pudHead)
  186. {
  187. pudTmp = _pudHead->GetNext();
  188. delete BP_TO_P(CUpdate *, _pudHead);
  189. _pudHead = P_TO_BP(CBasedUpdatePtr, pudTmp);
  190. }
  191. _pudTail = NULL;
  192. olDebugOut((DEB_ITRACE, "Out CUpdateList::Empty\n"));
  193. }
  194. //+---------------------------------------------------------------------------
  195. //
  196. // Member: CUpdateList::IsEntry, public
  197. //
  198. // Synopsis: Checks the update list to see if the given name represents
  199. // and existing entry in the list
  200. //
  201. // Arguments: [pdfn] - Name
  202. // [ppud] - Update entry return or NULL
  203. //
  204. // Returns: UIE_CURRENT - Found as a current name
  205. // UIE_ORIGINAL - Found as an original name
  206. // UIE_NOTFOUND
  207. //
  208. // Modifies: [ppud]
  209. //
  210. // History: 02-Nov-92 DrewB Created
  211. //
  212. //----------------------------------------------------------------------------
  213. #ifdef CODESEGMENTS
  214. #pragma code_seg(SEG_CUpdateList_IsEntry)
  215. #endif
  216. UlIsEntry CUpdateList::IsEntry(CDfName const *pdfn, CUpdate **ppud)
  217. {
  218. CUpdate *pud;
  219. UlIsEntry ret = UIE_NOTFOUND;
  220. olDebugOut((DEB_ITRACE, "In CUpdateList::IsEntry:%p(%ws, %p)\n", this,
  221. pdfn->GetBuffer(), ppud));
  222. olAssert(pdfn != NULL && pdfn->GetLength() > 0);
  223. for (pud = BP_TO_P(CUpdate *, _pudTail); pud; pud = pud->GetPrev())
  224. {
  225. if (pdfn->IsEqual(pud->GetCurrentName()))
  226. {
  227. ret = UIE_CURRENT;
  228. break;
  229. }
  230. else if (pdfn->IsEqual(pud->GetOriginalName()))
  231. {
  232. ret = UIE_ORIGINAL;
  233. break;
  234. }
  235. }
  236. olDebugOut((DEB_ITRACE, "Out CUpdateList::IsEntry\n"));
  237. if (ppud)
  238. *ppud = pud;
  239. return ret;
  240. }
  241. //+---------------------------------------------------------------------------
  242. //
  243. // Member: CUpdateList::Concat, public
  244. //
  245. // Synopsis: Concatenates an update list onto the end of this one
  246. //
  247. // Arguments: [ul] - List to concatenate
  248. //
  249. // History: 02-Nov-92 DrewB Created
  250. //
  251. // Notes: [ul]'s head may be modified
  252. //
  253. //+---------------------------------------------------------------------------
  254. #ifdef FUTURECODE
  255. void CUpdateList::Concat(CUpdateList &ul)
  256. {
  257. olDebugOut((DEB_ITRACE, "In CUpdateList::Concat:%p(ul)\n", this));
  258. if (_pudTail)
  259. {
  260. _pudTail->SetNext(ul.GetHead());
  261. if (ul.GetHead())
  262. {
  263. ul.GetHead()->SetPrev(_pudTail);
  264. olAssert(ul.GetTail() != NULL);
  265. _pudTail = ul.GetTail();
  266. }
  267. }
  268. else
  269. {
  270. olAssert(_pudHead == NULL);
  271. _pudHead = ul.GetHead();
  272. _pudTail = ul.GetTail();
  273. }
  274. olDebugOut((DEB_ITRACE, "Out CUpdateList::Concat\n"));
  275. }
  276. #endif
  277. //+---------------------------------------------------------------------------
  278. //
  279. // Member: CUpdateList::Exists, public static
  280. //
  281. // Synopsis: Traverses an update list from a particular point
  282. // and determines whether a given name exists or
  283. // is renamed
  284. //
  285. // Arguments: [pud] - Update to look from
  286. // [ppdfn] - Name in/out
  287. // [fRename] - Perform renames or quit
  288. //
  289. // Returns: TRUE if exists
  290. // FALSE if deleted
  291. //
  292. // History: 03-Nov-92 DrewB Created
  293. //
  294. //----------------------------------------------------------------------------
  295. #ifdef FUTURECODE
  296. BOOL CUpdateList::Exists(CUpdate *pud,
  297. CDfName **ppdfn,
  298. BOOL fRename)
  299. {
  300. for (; pud; pud = pud->GetNext())
  301. {
  302. if (pud->IsRename() &&
  303. (*ppdfn)->IsEqual(pud->GetOriginalName()))
  304. {
  305. if (fRename)
  306. *ppdfn = pud->GetCurrentName();
  307. else
  308. return FALSE;
  309. }
  310. else if (pud->IsDelete() &&
  311. (*ppdfn)->IsEqual(pud->GetOriginalName()))
  312. {
  313. return FALSE;
  314. }
  315. }
  316. return TRUE;
  317. }
  318. #endif
  319. //+---------------------------------------------------------------------------
  320. //
  321. // Member: CUpdateList::FindBase, public static
  322. //
  323. // Synopsis: Searches backwards in an update list for the creation of
  324. // a particular object, applying renames if necessary
  325. //
  326. // Arguments: [pud] - Update to start from
  327. // [ppdfn] - Name in/out
  328. //
  329. // Returns: Pointer to update entry for creation or NULL if
  330. // no creation entry. [ppdfn] is changed to point to
  331. // the base name.
  332. //
  333. // Modifies: [ppdfn]
  334. //
  335. // History: 16-Apr-93 DrewB Created
  336. //
  337. // Notes: Does not kill the search on deletions; primarily
  338. // intended to be used with names that represent existing
  339. // entries, although it will work on any name
  340. //
  341. //----------------------------------------------------------------------------
  342. #ifdef CODESEGMENTS
  343. #pragma code_seg(SEG_CUpdateList_FindBase)
  344. #endif
  345. CUpdate *CUpdateList::FindBase(CUpdate *pud, CDfName const **ppdfn)
  346. {
  347. for (; pud; pud = pud->GetPrev())
  348. {
  349. if (pud->IsRename() &&
  350. (*ppdfn)->IsEqual(pud->GetCurrentName()))
  351. {
  352. *ppdfn = pud->GetOriginalName();
  353. }
  354. else if (pud->IsCreate() &&
  355. (*ppdfn)->IsEqual(pud->GetCurrentName()))
  356. {
  357. return pud;
  358. }
  359. }
  360. return NULL;
  361. }