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.

381 lines
9.5 KiB

  1. /*** filelist.c - File List Manager
  2. *
  3. * Microsoft Confidential
  4. * Copyright (C) Microsoft Corporation 1993-1994
  5. * All Rights Reserved.
  6. *
  7. * Author:
  8. * Benjamin W. Slivka
  9. *
  10. * History:
  11. * 20-Aug-1993 bens Initial version
  12. * 21-Aug-1993 bens Add more set/query operations
  13. * 10-Feb-1994 bens Add comments to FLDestroyList
  14. * 15-Feb-1994 bens Fix bug in FLSetDestination
  15. * 01-Apr-1994 bens Added FLSetSource() message
  16. *
  17. * Exported Functions:
  18. * FLAddFile - Add file spec to a file list
  19. * FLCreateList - Create a file list
  20. * FLDestroyList - Destroy a file list
  21. * FLFirstFile - Get first file spec from a file list
  22. * FLGetDestination - Get destination file name
  23. * FLGetGroup - Get group/disk number for a file spec
  24. * FLGetSource - Get source file name
  25. * FLNextFile - Get next file spec
  26. * FLPreviousFile - Get previous file spec
  27. * FLSetSource - Change source file name
  28. * FLSetDestination - Change destination file name
  29. * FLSetGroup - Set group/disk number for a file spec
  30. */
  31. #include "types.h"
  32. #include "asrt.h"
  33. #include "error.h"
  34. #include "mem.h"
  35. #include "filelist.h"
  36. #include <filelist.msg> // LOCALIZED for EXTRACT.EXE -- specify "cl /Ipath"
  37. typedef struct FILESPEC_t {
  38. #ifdef ASSERT
  39. SIGNATURE sig; // structure signature sigFILESPEC
  40. #endif
  41. char *pszSrc; // Source file name
  42. char *pszDst; // Destination file name
  43. GROUP grp; // Group status / Disk Number
  44. struct FILESPEC_t *pfspecPrev; // Previous filespec in list
  45. struct FILESPEC_t *pfspecNext; // Next filespec in list
  46. } FILESPEC; /* fspec */
  47. typedef FILESPEC *PFILESPEC; /* pfspec */
  48. #ifdef ASSERT
  49. #define sigFILESPEC MAKESIG('F','S','P','C') // FILESPEC signature
  50. #define AssertFSpec(pv) AssertStructure(pv,sigFILESPEC);
  51. #else // !ASSERT
  52. #define AssertFSpec(pv)
  53. #endif // !ASSERT
  54. typedef struct FILELIST_t {
  55. #ifdef ASSERT
  56. SIGNATURE sig; // structure signature sigFILELIST
  57. #endif
  58. PFILESPEC pfspecHead;
  59. PFILESPEC pfspecTail;
  60. } FILELIST; /* flist */
  61. typedef FILELIST *PFILELIST; /* pflist */
  62. #ifdef ASSERT
  63. #define sigFILELIST MAKESIG('F','L','S','T') // FILELIST signature
  64. #define AssertFList(pv) AssertStructure(pv,sigFILELIST);
  65. #else // !ASSERT
  66. #define AssertFList(pv)
  67. #endif // !ASSERT
  68. #define HFSfromPFS(hfs) ((PFILESPEC)(hfs))
  69. #define PFSfromHFS(pfs) ((HFILESPEC)(pfs))
  70. #define HFLfromPFL(hfl) ((PFILELIST)(hfl))
  71. #define PFLfromHFL(pfl) ((HFILELIST)(pfl))
  72. /*** FLAddFile - Add file spec to a file list
  73. *
  74. * NOTE: See filelist.h for entry/exit conditions.
  75. */
  76. HFILESPEC FLAddFile(HFILELIST hflist,char *pszSrc,char *pszDst,PERROR perr)
  77. {
  78. PFILESPEC pfspec;
  79. PFILELIST pflist;
  80. pflist = PFLfromHFL(hflist);
  81. AssertFList(pflist);
  82. Assert(pszSrc != NULL);
  83. //** Create file specification
  84. if (!(pfspec = MemAlloc(sizeof(FILESPEC)))) {
  85. goto error;
  86. }
  87. //** Intialize structure enough so that clean-up routine can determine
  88. // if any resources need to be freed.
  89. pfspec->pszSrc = NULL;
  90. pfspec->pszDst = NULL;
  91. SetAssertSignature(pfspec,sigFILESPEC);
  92. //** Make copy of source name
  93. if (!(pfspec->pszSrc = MemStrDup(pszSrc))) {
  94. goto error;
  95. }
  96. //** pszDst is optional, may be NULL!
  97. if (pszDst == NULL) {
  98. pfspec->pszDst = NULL;
  99. }
  100. else if (!(pfspec->pszDst = MemStrDup(pszDst))) {
  101. goto error;
  102. }
  103. //** Finishing initializing file spec, and link onto list
  104. pfspec->grp = grpNONE; // Assume no group
  105. pfspec->pfspecNext = NULL; // Always last on list
  106. pfspec->pfspecPrev = pflist->pfspecTail; // Always points to last file spec
  107. if (pflist->pfspecHead == NULL) { // File list is empty
  108. pflist->pfspecHead = pfspec;
  109. pflist->pfspecTail = pfspec;
  110. }
  111. else { // File list is not empty
  112. AssertFSpec(pflist->pfspecTail);
  113. pflist->pfspecTail->pfspecNext = pfspec; // Add to end of list
  114. pflist->pfspecTail = pfspec; // New tail
  115. }
  116. // Success
  117. return HFSfromPFS(pfspec);
  118. error:
  119. if (pfspec) {
  120. if (pfspec->pszSrc) {
  121. MemFree(pfspec->pszSrc);
  122. }
  123. if (pfspec->pszDst) {
  124. MemFree(pfspec->pszDst);
  125. }
  126. MemFree(pfspec);
  127. }
  128. ErrSet(perr,pszFLISTERR_OUT_OF_MEMORY,"%s",pszADDING_FILE);
  129. return NULL; // Failure
  130. } /* FLAddFile */
  131. /*** FLCreateList - Create a file list
  132. *
  133. * NOTE: See filelist.h for entry/exit conditions.
  134. */
  135. HFILELIST FLCreateList(PERROR perr)
  136. {
  137. PFILELIST pflist;
  138. if (!(pflist = MemAlloc(sizeof(FILELIST)))) {
  139. ErrSet(perr,pszFLISTERR_OUT_OF_MEMORY,"%s",pszCREATING_FILE_LIST);
  140. return FALSE;
  141. }
  142. pflist->pfspecHead = NULL;
  143. pflist->pfspecTail = NULL;
  144. SetAssertSignature(pflist,sigFILELIST);
  145. return HFLfromPFL(pflist);
  146. } /* FLCreateList */
  147. /*** FLDestroyList - Destroy a file list
  148. *
  149. * NOTE: See filelist.h for entry/exit conditions.
  150. */
  151. BOOL FLDestroyList(HFILELIST hflist,PERROR perr)
  152. {
  153. PFILELIST pflist;
  154. PFILESPEC pfspecThis;
  155. PFILESPEC pfspecNext;
  156. pflist = PFLfromHFL(hflist);
  157. AssertFList(pflist);
  158. pfspecThis = pflist->pfspecHead;
  159. while (pfspecThis != NULL) {
  160. AssertFSpec(pfspecThis);
  161. if (pfspecThis->pszSrc != NULL) {
  162. MemFree(pfspecThis->pszSrc);
  163. }
  164. if (pfspecThis->pszDst != NULL) {
  165. MemFree(pfspecThis->pszDst);
  166. }
  167. pfspecNext = pfspecThis->pfspecNext;
  168. ClearAssertSignature(pfspecThis);
  169. MemFree(pfspecThis);
  170. pfspecThis = pfspecNext;
  171. }
  172. ClearAssertSignature(pflist);
  173. MemFree(pflist);
  174. return TRUE;
  175. }
  176. /*** FLFirstFile - Get first file spec from a file list
  177. *
  178. * NOTE: See filelist.h for entry/exit conditions.
  179. */
  180. HFILESPEC FLFirstFile(HFILELIST hflist)
  181. {
  182. PFILELIST pflist;
  183. pflist = PFLfromHFL(hflist);
  184. AssertFList(pflist);
  185. return HFSfromPFS(pflist->pfspecHead);
  186. }
  187. /*** FLNextFile - Get next file spec
  188. *
  189. * NOTE: See filelist.h for entry/exit conditions.
  190. */
  191. HFILESPEC FLNextFile(HFILESPEC hfspec)
  192. {
  193. PFILESPEC pfspec;
  194. pfspec = PFSfromHFS(hfspec);
  195. AssertFSpec(pfspec);
  196. return HFSfromPFS(pfspec->pfspecNext);
  197. }
  198. /*** FLPreviousFile - Get previous file spec
  199. *
  200. * NOTE: See filelist.h for entry/exit conditions.
  201. */
  202. HFILESPEC FLPreviousFile(HFILESPEC hfspec)
  203. {
  204. PFILESPEC pfspec;
  205. pfspec = PFSfromHFS(hfspec);
  206. AssertFSpec(pfspec);
  207. return HFSfromPFS(pfspec->pfspecPrev);
  208. }
  209. /*** FLGetGroup - Get group/disk number for a file spec
  210. *
  211. * NOTE: See filelist.h for entry/exit conditions.
  212. */
  213. GROUP FLGetGroup(HFILESPEC hfspec)
  214. {
  215. PFILESPEC pfspec;
  216. pfspec = PFSfromHFS(hfspec);
  217. AssertFSpec(pfspec);
  218. return pfspec->grp;
  219. }
  220. /*** FLGetDestination - Get destination file name
  221. *
  222. * NOTE: See filelist.h for entry/exit conditions.
  223. */
  224. char *FLGetDestination(HFILESPEC hfspec)
  225. {
  226. PFILESPEC pfspec;
  227. pfspec = PFSfromHFS(hfspec);
  228. AssertFSpec(pfspec);
  229. return pfspec->pszDst;
  230. } /* FLGetDestination */
  231. /*** FLGetSource - Get source file name
  232. *
  233. * NOTE: See filelist.h for entry/exit conditions.
  234. */
  235. char *FLGetSource(HFILESPEC hfspec)
  236. {
  237. PFILESPEC pfspec;
  238. pfspec = PFSfromHFS(hfspec);
  239. AssertFSpec(pfspec);
  240. return pfspec->pszSrc;
  241. } /* FLGetSource */
  242. /*** FLSetGroup - Set group/disk number for a file spec
  243. *
  244. * NOTE: See filelist.h for entry/exit conditions.
  245. */
  246. void FLSetGroup(HFILESPEC hfspec,GROUP grp)
  247. {
  248. PFILESPEC pfspec;
  249. pfspec = PFSfromHFS(hfspec);
  250. AssertFSpec(pfspec);
  251. pfspec->grp = grp;
  252. }
  253. /*** FLSetSource - Change source file name
  254. *
  255. * NOTE: See filelist.h for entry/exit conditions.
  256. */
  257. BOOL FLSetSource(HFILESPEC hfspec, char *pszSrc, PERROR perr)
  258. {
  259. PFILESPEC pfspec;
  260. char *pszOriginal;
  261. pfspec = PFSfromHFS(hfspec);
  262. AssertFSpec(pfspec);
  263. //** Save original destination, so we can free it later
  264. pszOriginal = pfspec->pszSrc;
  265. //** Set new destination
  266. if (!(pfspec->pszSrc = MemStrDup(pszSrc))) {
  267. ErrSet(perr,pszFLISTERR_OUT_OF_MEMORY,"%s",pszCHANGING_SOURCE);
  268. return FALSE; // Failure
  269. }
  270. //** Free old destination
  271. if (pszOriginal) {
  272. MemFree(pszOriginal);
  273. }
  274. //** Success
  275. return TRUE;
  276. }
  277. /*** FLSetDestination - Change destination file name
  278. *
  279. * NOTE: See filelist.h for entry/exit conditions.
  280. */
  281. BOOL FLSetDestination(HFILESPEC hfspec, char *pszDst, PERROR perr)
  282. {
  283. PFILESPEC pfspec;
  284. char *pszDstOriginal;
  285. pfspec = PFSfromHFS(hfspec);
  286. AssertFSpec(pfspec);
  287. //** Save original destination, so we can free it later
  288. pszDstOriginal = pfspec->pszDst;
  289. //** Set new destination
  290. if (!(pfspec->pszDst = MemStrDup(pszDst))) {
  291. ErrSet(perr,pszFLISTERR_OUT_OF_MEMORY,"%s",pszCHANGING_DESTINATION);
  292. return FALSE; // Failure
  293. }
  294. //** Free old destination
  295. if (pszDstOriginal) {
  296. MemFree(pszDstOriginal);
  297. }
  298. //** Success
  299. return TRUE;
  300. }