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.

226 lines
4.2 KiB

  1. #include "shellprv.h"
  2. #include "ynlist.h"
  3. #define YNLIST_ALLOC (2 * MAX_PATH * sizeof(TCHAR))
  4. //
  5. // Constructor - creates a YesNoList
  6. //
  7. void CreateYesNoList(PYNLIST pynl)
  8. {
  9. ZeroMemory(pynl, sizeof(*pynl));
  10. }
  11. //
  12. // Destructor - frees and destroys a YesNoList
  13. //
  14. void DestroyYesNoList(PYNLIST pynl)
  15. {
  16. if (pynl->dlYes.pszzList)
  17. GlobalFree(pynl->dlYes.pszzList);
  18. if (pynl->dlNo.pszzList)
  19. GlobalFree(pynl->dlNo.pszzList);
  20. ZeroMemory(pynl, sizeof(*pynl));
  21. }
  22. //
  23. // IsPathOfItem - determine if pszPath is on the path to pszItem
  24. //
  25. BOOL IsPathOfItem(LPCTSTR pszPath, LPCTSTR pszItem)
  26. {
  27. //
  28. // Validate pszPath is the first
  29. // substring of pszItem.
  30. //
  31. while (*pszPath)
  32. {
  33. if (*pszPath != *pszItem)
  34. {
  35. return FALSE;
  36. }
  37. pszPath++;
  38. pszItem++;
  39. }
  40. //
  41. // pszPath is the path if pszItem is empty (exact match),
  42. // or pszItem is a directory separator.
  43. //
  44. return (*pszItem == TEXT('\\')) || (*pszItem == TEXT('\0'));
  45. }
  46. //
  47. // IsInDirList - determines if DIRLIST contains
  48. // the path to pszItem.
  49. //
  50. BOOL IsInDirList(PDIRLIST pdl, LPCTSTR pszItem)
  51. {
  52. LPTSTR pszzList;
  53. //
  54. // Quick check for everything flag.
  55. //
  56. if (pdl->fEverythingInList)
  57. return TRUE;
  58. //
  59. // Quick check for empty list.
  60. //
  61. if (pdl->pszzList == NULL)
  62. {
  63. return FALSE;
  64. }
  65. //
  66. // Compare against each string in the szz list.
  67. //
  68. pszzList = pdl->pszzList;
  69. while (*pszzList)
  70. {
  71. //
  72. // If pszList is the beginning of the path to pszItem,
  73. // the item is in the list.
  74. //
  75. if (IsPathOfItem(pszzList, pszItem))
  76. {
  77. return TRUE;
  78. }
  79. pszzList += lstrlen(pszzList) + 1;
  80. }
  81. //
  82. // Couldn't find it.
  83. //
  84. return FALSE;
  85. }
  86. //
  87. // IsInYesList - determine if an item is in the
  88. // yes list of a YesNoList.
  89. //
  90. BOOL IsInYesList(PYNLIST pynl, LPCTSTR pszItem)
  91. {
  92. //
  93. // Call helper function.
  94. //
  95. return IsInDirList(&pynl->dlYes, pszItem);
  96. }
  97. //
  98. // IsInNoList - determine if an item is in the
  99. // no list of a YesNoList.
  100. //
  101. BOOL IsInNoList(PYNLIST pynl, LPCTSTR pszItem)
  102. {
  103. //
  104. // Call helper function.
  105. //
  106. return IsInDirList(&pynl->dlNo, pszItem);
  107. }
  108. //
  109. // AddToDirList - adds an item to a dir list if necessary.
  110. //
  111. void AddToDirList(PDIRLIST pdl, LPCTSTR pszItem)
  112. {
  113. UINT cchItem;
  114. //
  115. // Is the item already in the list?
  116. //
  117. if (IsInDirList(pdl, pszItem))
  118. {
  119. return;
  120. }
  121. //
  122. // Is the list empty?
  123. //
  124. if (pdl->pszzList == NULL)
  125. {
  126. pdl->pszzList = (LPTSTR)GlobalAlloc(GPTR, YNLIST_ALLOC);
  127. if (pdl->pszzList == NULL)
  128. {
  129. return;
  130. }
  131. pdl->cbAlloc = YNLIST_ALLOC;
  132. pdl->cchUsed = 1;
  133. ASSERT(pdl->pszzList[0] == TEXT('\0'));
  134. }
  135. //
  136. // Get the string length,
  137. // verify it can be added with
  138. // at most one additional alloc.
  139. //
  140. cchItem = lstrlen(pszItem) + 1;
  141. if (CbFromCch(cchItem) >= YNLIST_ALLOC)
  142. {
  143. return;
  144. }
  145. //
  146. // Do we need to allocate more space?
  147. //
  148. if (CbFromCch(cchItem) > pdl->cbAlloc - CbFromCch(pdl->cchUsed))
  149. {
  150. LPTSTR pszzNew;
  151. pszzNew = (LPTSTR)GlobalReAlloc(pdl->pszzList, pdl->cbAlloc + YNLIST_ALLOC, GMEM_MOVEABLE|GMEM_ZEROINIT);
  152. if (pszzNew == NULL)
  153. {
  154. return;
  155. }
  156. pdl->pszzList = pszzNew;
  157. pdl->cbAlloc += YNLIST_ALLOC;
  158. }
  159. //
  160. // Add the item.
  161. //
  162. lstrcpy(&(pdl->pszzList[pdl->cchUsed - 1]), pszItem);
  163. pdl->cchUsed += cchItem;
  164. //
  165. // Add the second NULL terminator
  166. // (GlobalReAlloc can't guarantee zeromeminit)
  167. //
  168. pdl->pszzList[pdl->cchUsed - 1] = TEXT('\0');
  169. }
  170. //
  171. // Adds an item to the Yes list.
  172. //
  173. void AddToYesList(PYNLIST pynl, LPCTSTR pszItem)
  174. {
  175. //
  176. // Call helper function.
  177. //
  178. AddToDirList(&pynl->dlYes, pszItem);
  179. }
  180. //
  181. // Adds an item to the No list.
  182. //
  183. void AddToNoList(PYNLIST pynl, LPCTSTR pszItem)
  184. {
  185. //
  186. // Call helper function.
  187. //
  188. AddToDirList(&pynl->dlNo, pszItem);
  189. }
  190. //
  191. // SetYesToAll - puts everything in the yes list.
  192. //
  193. void SetYesToAll(PYNLIST pynl)
  194. {
  195. pynl->dlYes.fEverythingInList = TRUE;
  196. }