FINDFILE.CPP 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***************************************************************************
  19. ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  20. ***************************************************************************
  21. * *
  22. * Project Name : Westwood Library *
  23. * *
  24. * File Name : FINDFILE.C *
  25. * *
  26. * Programmer : Joe L. Bostic *
  27. * *
  28. * Start Date : August 21, 1991 *
  29. * *
  30. * Last Update : September 29, 1993 [SKB] *
  31. * *
  32. *-------------------------------------------------------------------------*
  33. * Functions: *
  34. * Find_File_Index -- Finds the FileTable index number for a given file. *
  35. * Find_File -- Checks if a file is immediatly available. *
  36. * Get_FileData -- Gets a pointer back to the correct file. *
  37. * Find_File -- Checks if a file is immediatly available. *
  38. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  39. /*=========================================================================*/
  40. /* The following PRIVATE functions are in this file: */
  41. /*=========================================================================*/
  42. /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
  43. #ifndef WWSTD_H
  44. #include "wwstd.h"
  45. #endif
  46. #ifndef _FILE_H
  47. #include "_file.h"
  48. #endif
  49. #include <direct.h>
  50. #include <dos.h>
  51. #include <fcntl.h>
  52. #include <io.h>
  53. #include <stdlib.h>
  54. #include <stdio.h>
  55. #include <string.h>
  56. #include <search.h>
  57. #include <sys\stat.h>
  58. /***************************************************************************
  59. * FIND_FILE -- Checks if a file is immediatly available. *
  60. * *
  61. * Use this function to determine if a file is immediatly available. *
  62. * This routine will NOT request for the proper disk to be inserted *
  63. * if the file could not be found. Use File_Exists for that feature. *
  64. * The Westwood file I/O system does NOT have to be initialized as *
  65. * a prerequisit to using this function. *
  66. * *
  67. * INPUT: file_name -- Name of the file to check. *
  68. * *
  69. * OUTPUT: Returns the disk number that the file exits on (A=1, B=2, etc) *
  70. * *
  71. * WARNINGS: This sets the current drive to the drive that contains the *
  72. * specified file (if it is found). *
  73. * *
  74. * HISTORY: *
  75. * 11/14/1991 JLB : Created. *
  76. * 03/14/1992 JLB : Modified for Amiga compatability. *
  77. * 01/11/1993 SKB : Modified for CD-ROM searches. *
  78. *=========================================================================*/
  79. WORD cdecl Find_File(BYTE const *file_name)
  80. {
  81. FileDataType *filedata = NULL;
  82. WORD index; // File index (if any).
  83. WORD disk; // Disk number of file (if in filetable).
  84. /*
  85. ** If the filename is invalid then it errors out as if the file wasn't
  86. ** found (naturally).
  87. */
  88. if (!file_name) return(FALSE);
  89. /*
  90. ** Determine if the file has a file table entry. If it does, then
  91. ** special checks and processing must occur.
  92. ** Also, if it is in memory, return with it.
  93. */
  94. index = Find_File_Index(file_name);
  95. filedata = &FileDataPtr[index];
  96. if (index != ERROR) {
  97. // If the file is currently cached, return TRUE that it was found.
  98. if (filedata->Ptr) {
  99. return (TRUE);
  100. }
  101. }
  102. /*
  103. ** Always check the current directory for the file. Only if it can't
  104. ** be found are furthur measures required.
  105. */
  106. DiskNumber = ERROR; // This indicates file exists in current directory.
  107. #if (LIB_CDROM)
  108. ibm_setdisk(*StartPath - 'A');
  109. #endif
  110. /*
  111. ** Check the current directory by attempting to open with READ access.
  112. */
  113. {
  114. WORD handle;
  115. CallingDOSInt++;
  116. handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
  117. CallingDOSInt--;
  118. if (handle != ERROR)
  119. {
  120. // WORD d;
  121. unsigned d ;
  122. CallingDOSInt++;
  123. close(handle);
  124. // d = getdisk();
  125. _dos_getdrive ( & d) ;
  126. CallingDOSInt--;
  127. return(d);
  128. }
  129. }
  130. if (index != ERROR) {
  131. disk = filedata->Disk;
  132. /*
  133. ** If the file is in a packed file, then search for the packed file
  134. ** instead of the specified one.
  135. */
  136. if (index != ERROR && (filedata->Flag & FILEF_PACKED)) {
  137. filedata = &FileDataPtr[disk];
  138. return (Find_File(filedata->Name));
  139. }
  140. }
  141. /*
  142. ** It could not be found on the current drive, so search the other
  143. ** drives if allowed to do so.
  144. */
  145. if (!MultiDriveSearch) {
  146. return(FALSE);
  147. }
  148. #if (LIB_CDROM)
  149. // If we were unable to find the file on the hard drive, change
  150. // drives to the CD rom drive and see if it is there.
  151. ibm_setdisk(*DataPath - 'A');
  152. {
  153. WORD handle;
  154. Hard_Error_Occured = 0;
  155. handle = Open_File_With_Recovery( file_name, MODE_OLDFILE );
  156. if (handle != FILEOPENERROR) {
  157. FILECLOSE(handle);
  158. return(ibm_getdisk() + 1);
  159. }
  160. }
  161. ibm_setdisk(*StartPath - 'A');
  162. return (FALSE);
  163. #else
  164. {
  165. WORD start_drive; // Original current drive number.
  166. /*
  167. ** Record the current drive for restoring later in case of failure.
  168. */
  169. CallingDOSInt++;
  170. start_drive = getdisk();
  171. CallingDOSInt--;
  172. /*
  173. ** Sweep backward from the last real drive to the first, looking for the
  174. ** file on each in turn.
  175. */
  176. for (index = MaxDevice; index != -1; index--) {
  177. if (Is_Device_Real(index)) {
  178. CallingDOSInt++;
  179. setdisk(index);
  180. CallingDOSInt--;
  181. {
  182. WORD handle;
  183. CallingDOSInt++;
  184. handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
  185. CallingDOSInt--;
  186. if (handle != ERROR) {
  187. CallingDOSInt++;
  188. close(handle);
  189. CallingDOSInt--;
  190. DiskNumber = index+1;
  191. return (DiskNumber);
  192. }
  193. }
  194. }
  195. }
  196. CallingDOSInt++;
  197. setdisk(start_drive);
  198. CallingDOSInt--;
  199. }
  200. return(FALSE);
  201. #endif
  202. }
  203. /***************************************************************************
  204. * FIND_FILE_INDEX -- Finds the FileTable index number for a given file. *
  205. * *
  206. * This function searches the FileTable and returns with the index of *
  207. * the matching file. If the file doesn't exist in the table, then *
  208. * ERROR is returned. It does not care about case. *
  209. * *
  210. * INPUT: filename -- Pointer to the filename to check. *
  211. * *
  212. * OUTPUT: Returns with the index into the FileTable. If the file does *
  213. * not exist in the file table, then ERROR is returned. *
  214. * *
  215. * WARNINGS: none *
  216. * *
  217. * HISTORY: *
  218. * 11/09/1991 JLB : Created. *
  219. * 06/11/1993 JLB : Sorts and binary searches the file table. *
  220. *=========================================================================*/
  221. PRIVATE int Comp_Func(const void *p1, const void *p2)
  222. {
  223. return(strcmp((char *) ((FileDataType*)p1)->Name, (char *) ((FileDataType*)p2)->Name));
  224. }
  225. WORD cdecl Find_File_Index(BYTE const *filename)
  226. {
  227. FileDataType *filedata; // File entry pointer.
  228. FileDataType key; // Working file data type var.
  229. /*
  230. ** Perform a binary search on the presorted filetable.
  231. */
  232. if (filename) {
  233. filedata = NULL;
  234. key.Name = (BYTE *) strupr((char *)filename);
  235. if (strstr((char *)key.Name, (char *)".PAK")) {
  236. /*
  237. ** If the FileData table was not loaded from the disk then the PAK files are
  238. ** not sorted so Perform a linear search for the pak files.
  239. ** Otherwise the files are sorted so speed things up by doing a bsearch.
  240. */
  241. if (FileData == FileDataPtr) {
  242. filedata = (FileDataType *) lfind(&key, FileDataPtr, (size_t *) &NumPAKFiles, sizeof(FileDataType), Comp_Func);
  243. }
  244. else {
  245. filedata = (FileDataType *)bsearch(&key, FileDataPtr, NumPAKFiles, sizeof(FileDataType), Comp_Func);
  246. }
  247. } else {
  248. /*
  249. ** Perform a binary search for the regular files.
  250. */
  251. filedata = (FileDataType *)bsearch(&key, &FileDataPtr[NumPAKFiles], NumFiles, sizeof(FileDataType), Comp_Func);
  252. }
  253. // Return the element in the array if file was found in table.
  254. if (filedata) {
  255. return (filedata - FileDataPtr);
  256. //return ((WORD)((((LONG)filedata) - ((LONG)FileDataPtr)) / sizeof(FileDataType)));
  257. }
  258. }
  259. return(ERROR);
  260. }
  261.