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.

332 lines
9.2 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. // All rights reserved.
  5. //
  6. // File Name:
  7. // namelist.c
  8. //
  9. // Description:
  10. //
  11. // This file contains the implementation for a NAMELIST. It is
  12. // useful for keeping a copy of what the user puts into a list-box.
  13. // Storage is obtained from the heap and there is not a fixed limit
  14. // on the size of the table.
  15. //
  16. // IMPORTANT: When a NAMELIST is declared, init it to 0. e.g.
  17. // NAMELIST Names = {0}. Use ResetNameList() to reset
  18. // it because we use the heap to store this list.
  19. //
  20. //----------------------------------------------------------------------------
  21. #include "pch.h"
  22. //
  23. // The NAMELIST type is used on dialogs such as ComputerName and Printers
  24. // where the user can ADD or REMOVE a list of entries which are displayed
  25. // in a list box. Callers should declare a NAMELIST and use these routines
  26. // to get/set values. These routines take care of the reallocation
  27. // needed to support an arbitrary length list.
  28. //
  29. // Entries in the namelist can be added to the end or any specific index.
  30. // Entries can be removed by name or by index. This allows the programmer to
  31. // not worry about maintaining the order in this list and keeping it
  32. // synchronized with however the listbox displays (e.g. the listbox might
  33. // display in alphabetical order).
  34. //
  35. // Obviously, a search for the entry must be done at removal time, and this
  36. // is an insignificant (and unnoticeable) time hit in this context.
  37. //
  38. #define SIZE_TO_GROW 16
  39. //----------------------------------------------------------------------------
  40. //
  41. // Function: ResetNameList
  42. //
  43. // Purpose: Empties the names in the namelist. A namelist looks like:
  44. // int AllocedSize
  45. // int NumEntries
  46. // char **Vector
  47. // We free each of the names in the vector and set NumEntries
  48. // to 0. The NAMELIST block is not freed or shrunk.
  49. //
  50. // Arguments: NAMELIST * - pointer to namelist to reset
  51. //
  52. // Returns: void
  53. //
  54. //----------------------------------------------------------------------------
  55. VOID ResetNameList(NAMELIST *pNameList)
  56. {
  57. UINT i;
  58. for ( i=0; i<pNameList->nEntries; i++ )
  59. free(pNameList->Names[i]);
  60. pNameList->nEntries = 0;
  61. }
  62. //----------------------------------------------------------------------------
  63. //
  64. // Function: GetNameListSize
  65. //
  66. // Purpose: retrieves number entries in namelist
  67. //
  68. // Arguments: NAMELIST * - pointer to namelist
  69. //
  70. // Returns: UINT - number of entries
  71. //
  72. //----------------------------------------------------------------------------
  73. UINT GetNameListSize(NAMELIST *pNameList)
  74. {
  75. return pNameList->nEntries;
  76. }
  77. //----------------------------------------------------------------------------
  78. //
  79. // Function: GetNameListName
  80. //
  81. // Purpose: Gets a name out of the namelist by index.
  82. //
  83. // Arguments:
  84. // NAMELIST* - pointer to namelist
  85. // UINT idx - index of name to retrieve
  86. //
  87. //----------------------------------------------------------------------------
  88. TCHAR *GetNameListName(NAMELIST *pNameList,
  89. UINT idx)
  90. {
  91. if( idx >= pNameList->nEntries )
  92. return( _T("") );
  93. return pNameList->Names[idx];
  94. }
  95. //----------------------------------------------------------------------------
  96. //
  97. // Function: RemoveNameFromNameListIdx
  98. //
  99. // Purpose: Removes a name at a specific position in the namelist.
  100. //
  101. // Arguments:
  102. // NAMELIST* - namelist to remove from
  103. // UINT - 0-based index on where to do the deletion
  104. //
  105. // Returns: VOID
  106. //
  107. //----------------------------------------------------------------------------
  108. VOID
  109. RemoveNameFromNameListIdx(
  110. IN NAMELIST *pNameList,
  111. IN UINT idx)
  112. {
  113. UINT i;
  114. Assert(idx < pNameList->nEntries);
  115. free(pNameList->Names[idx]);
  116. for ( i=idx+1; i<pNameList->nEntries; i++ )
  117. pNameList->Names[i-1] = pNameList->Names[i];
  118. pNameList->nEntries--;
  119. }
  120. //----------------------------------------------------------------------------
  121. //
  122. // Function: RemoveNameFromNameList
  123. //
  124. // Purpose: Removes a name from the name list (by name).
  125. //
  126. // Arguments:
  127. // NAMELIST* - pointer to namelist
  128. // TCHAR* - name to remove
  129. //
  130. // Returns: TRUE if found and removed, FALSE if not found
  131. //
  132. //----------------------------------------------------------------------------
  133. BOOL RemoveNameFromNameList(NAMELIST *pNameList,
  134. TCHAR *NameToRemove)
  135. {
  136. UINT idx;
  137. if ( (idx=FindNameInNameList(pNameList, NameToRemove)) == -1 )
  138. return FALSE;
  139. Assert(idx < pNameList->nEntries);
  140. RemoveNameFromNameListIdx(pNameList, idx);
  141. return TRUE;
  142. }
  143. //----------------------------------------------------------------------------
  144. //
  145. // Function: AddNameToNameListIdx
  146. //
  147. // Purpose: Inserts a name at a specific position in the namelist. Handles
  148. // the details of allocating more room if the table gets full.
  149. //
  150. // Arguments:
  151. // NAMELIST* - namelist to add to
  152. // TCHAR* - string to add (input)
  153. // UINT - 0-based index on where to do the insertion
  154. //
  155. // Returns: FALSE if out of memory.
  156. //
  157. //----------------------------------------------------------------------------
  158. BOOL AddNameToNameListIdx(NAMELIST *pNameList,
  159. TCHAR *String,
  160. UINT idx) {
  161. UINT i;
  162. TCHAR *pStr; // temp var
  163. //
  164. // If we're out of room, realloc the namelist. It is a vector
  165. // of TCHAR*
  166. //
  167. if ( pNameList->nEntries >= pNameList->AllocedSize ) {
  168. LPTSTR *lpTmpNames;
  169. pNameList->AllocedSize += SIZE_TO_GROW;
  170. // Use a temporary buffer in case the realloc fails
  171. //
  172. lpTmpNames = realloc(pNameList->Names,
  173. pNameList->AllocedSize * sizeof(TCHAR*));
  174. // Make sure the realloc succeeded before stomping the original pointer
  175. //
  176. if ( lpTmpNames == NULL ) {
  177. free(pNameList->Names);
  178. pNameList->Names = NULL;
  179. pNameList->AllocedSize = 0;
  180. pNameList->nEntries = 0;
  181. return FALSE;
  182. }
  183. else {
  184. pNameList->Names = lpTmpNames;
  185. }
  186. }
  187. if ( (pStr = lstrdup(String)) == NULL )
  188. return FALSE;
  189. //
  190. // If they specifed an index beyond the end of the list,
  191. // just add it to the end of the list
  192. //
  193. if ( idx > pNameList->nEntries ) {
  194. idx = pNameList->nEntries;
  195. }
  196. //
  197. // Shift the array to make room at the insertion point
  198. //
  199. for( i = pNameList->nEntries; i > idx ; i-- ) {
  200. pNameList->Names[i] = pNameList->Names[i-1];
  201. }
  202. pNameList->Names[i] = pStr;
  203. pNameList->nEntries++;
  204. return TRUE;
  205. }
  206. //----------------------------------------------------------------------------
  207. //
  208. // Function: AddNameToNameList
  209. //
  210. // Purpose: Adds a name to the end of the namelist. Handles the details
  211. // of allocating more room if the table gets full.
  212. //
  213. // Arguments:
  214. // NAMELIST* - namelist to add to
  215. // TCHAR* - string to add (input)
  216. //
  217. // Returns: FALSE if out of memory.
  218. //
  219. //----------------------------------------------------------------------------
  220. BOOL AddNameToNameList(NAMELIST *pNameList,
  221. TCHAR *String)
  222. {
  223. return( AddNameToNameListIdx( pNameList, String, pNameList->nEntries ) );
  224. }
  225. //----------------------------------------------------------------------------
  226. //
  227. // Function: AddNameToNameListNoDuplicates
  228. //
  229. // Purpose: Adds a name to the end of the namelist only if the string is not
  230. // already in the list. Handles the details of allocating more room
  231. // if the table gets full.
  232. //
  233. // Arguments:
  234. // NAMELIST* - namelist to add to
  235. // TCHAR* - string to add (input)
  236. //
  237. // Returns: FALSE if out of memory.
  238. //
  239. //----------------------------------------------------------------------------
  240. BOOL AddNameToNameListNoDuplicates( NAMELIST *pNameList,
  241. TCHAR *String )
  242. {
  243. if( FindNameInNameList( pNameList, String ) == -1 ) {
  244. return( AddNameToNameListIdx( pNameList, String, pNameList->nEntries ) );
  245. }
  246. //
  247. // the string is already in the list so just return
  248. //
  249. return( TRUE );
  250. }
  251. //----------------------------------------------------------------------------
  252. //
  253. // Function: FindNameInNameList
  254. //
  255. // Purpose: Checks to see if a name already exists in the table.
  256. //
  257. // Arguments:
  258. // NAMELIST* - namelist to add to
  259. // TCHAR* - string to search for
  260. //
  261. // Returns: INT idx of entry, -1 if not found
  262. //
  263. //----------------------------------------------------------------------------
  264. INT FindNameInNameList(NAMELIST *pNameList,
  265. TCHAR *String)
  266. {
  267. UINT i;
  268. for ( i=0; i<pNameList->nEntries; i++ )
  269. if ( (pNameList->Names) && (lstrcmpi(pNameList->Names[i], String) == 0) )
  270. return i;
  271. return -1;
  272. }