CDFILE.CPP 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /CounterStrike/CDFILE.CPP 1 3/03/97 10:24a Joe_bostic $ */
  15. /***********************************************************************************************
  16. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Westwood Library *
  20. * *
  21. * File Name : CDFILE.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : October 18, 1994 *
  26. * *
  27. * Last Update : September 22, 1995 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * CDFileClass::Clear_Search_Drives -- Removes all record of a search path. *
  32. * CDFileClass::Open -- Opens the file object -- with path search. *
  33. * CDFileClass::Open -- Opens the file wherever it can be found. *
  34. * CDFileClass::Set_Name -- Performs a multiple directory scan to set the filename. *
  35. * CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. *
  36. * Is_Disk_Inserted -- Checks to see if a disk is inserted in specified drive. *
  37. * harderr_handler -- Handles hard DOS errors. *
  38. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  39. #include "cdfile.h"
  40. #include <stdio.h>
  41. #include <string.h>
  42. #ifndef WIN32
  43. #include <wwstd.h>
  44. #include <playcd.h>
  45. #endif
  46. /*
  47. ** Pointer to the first search path record.
  48. */
  49. CDFileClass::SearchDriveType * CDFileClass::First = 0;
  50. int CDFileClass::CurrentCDDrive = 0;
  51. int CDFileClass::LastCDDrive = 0;
  52. char CDFileClass::RawPath[512] = {0};
  53. CDFileClass::CDFileClass(char const *filename) :
  54. IsDisabled(false)
  55. {
  56. CDFileClass::Set_Name(filename);
  57. // memset (RawPath, 0, sizeof(RawPath));
  58. }
  59. CDFileClass::CDFileClass(void) :
  60. IsDisabled(false)
  61. {
  62. }
  63. extern int Get_CD_Index (int cd_drive, int timeout);
  64. /***********************************************************************************************
  65. * harderr_handler -- Handles hard DOS errors. *
  66. * *
  67. * This routine will handle the low level DOS error trapper. Instead of displaying the *
  68. * typical "Abort, Retry, Ignore" message, it simply returns with the failure code. The *
  69. * cause of the error will fail. The likely case would be with disk I/O. *
  70. * *
  71. * INPUT: *
  72. * *
  73. * OUTPUT: Return the failure code. *
  74. * *
  75. * WARNINGS: Do no processing in this routine that could possibly generate another *
  76. * hard error condition. *
  77. * *
  78. * HISTORY: *
  79. * 09/22/1995 JLB : Created. *
  80. *=============================================================================================*/
  81. #ifdef WIN32
  82. int harderr_handler(unsigned int , unsigned int , unsigned int *)
  83. #else
  84. int harderr_handler(unsigned int , unsigned int , unsigned int __far *)
  85. #endif
  86. {
  87. return(0); // _HARDERR_FAIL);
  88. }
  89. /***********************************************************************************************
  90. * Is_Disk_Inserted -- Checks to see if a disk is inserted in specified drive. *
  91. * *
  92. * This routine will examine the drive specified to see if there is a disk inserted. It *
  93. * can be used for floppy drives as well as for the CD-ROM. *
  94. * *
  95. * INPUT: disk -- The drive number to examine. 0=A, 1=B, etc. *
  96. * *
  97. * OUTPUT: bool; Is a disk inserted into the specified drive? *
  98. * *
  99. * WARNINGS: none *
  100. * *
  101. * HISTORY: *
  102. * 09/20/1995 JLB : Created. *
  103. *=============================================================================================*/
  104. int cdecl Is_Disk_Inserted(int disk)
  105. {
  106. #ifndef OBSOLETE
  107. disk;
  108. return true;
  109. #if (0)
  110. struct find_t fb;
  111. char scan[] = "?:\\*.*";
  112. #ifndef WIN32
  113. _harderr(harderr_handler); // BG: Install hard error handler
  114. #endif
  115. scan[0] = (char)('A' + disk);
  116. return(_dos_findfirst(scan, _A_SUBDIR, &fb) == 0);
  117. #endif
  118. #else
  119. struct {
  120. struct {
  121. char Length;
  122. char Unit;
  123. char Function;
  124. char Status;
  125. char Reserved[8];
  126. } ReqHdr;
  127. char MediaDescriptor; // Media descriptor byte from BPB.
  128. void *Transfer; // Pointer to transfer address block.
  129. short Length; // Number of bytes to transfer.
  130. short Sector; // Starting sector number.
  131. void *Volume; // Pointer to requested volume.
  132. } IOCTLI;
  133. char status[5];
  134. memset(IOCTLI, 0, sizeof(IOCTLI));
  135. IOCTLI.ReqHdr.Length = 26;
  136. IOCTLI.ReqHdr.Unit = 0; // First CD-ROM controlled by this driver.
  137. //IOCTLI.ReqHdr.Unit = 11; // Hard coded for K:
  138. IOCTLI.ReqHdr.Function = 3; // IOCTL read
  139. IOCTLI.Transfer = &status[0];
  140. IOCTLI.Length = sizeof(status);
  141. status[0] = 6; // Fetch device status code.
  142. _AX = 0x440D;
  143. _CX = 0x0003;
  144. geninterrupt(0x21);
  145. return(!(_AX & (1<<11)));
  146. #endif
  147. }
  148. /***********************************************************************************************
  149. * CDFileClass::Open -- Opens the file object -- with path search. *
  150. * *
  151. * This will open the file object, but since the file object could have been constructed *
  152. * with a pathname, this routine will try to find the file first. For files opened for *
  153. * writing, then use the existing filename without performing a path search. *
  154. * *
  155. * INPUT: rights -- The access rights to use when opening the file *
  156. * *
  157. * OUTPUT: bool; Was the open successful? *
  158. * *
  159. * WARNINGS: none *
  160. * *
  161. * HISTORY: *
  162. * 10/18/1994 JLB : Created. *
  163. *=============================================================================================*/
  164. int CDFileClass::Open(int rights)
  165. {
  166. return(BufferIOFileClass::Open(rights));
  167. }
  168. /***********************************************************************************************
  169. * CDFC::Refresh_Search_Drives -- Updates the search path when a CD changes or is added *
  170. * *
  171. * *
  172. * *
  173. * INPUT: Nothing *
  174. * *
  175. * OUTPUT: Nothing *
  176. * *
  177. * WARNINGS: None *
  178. * *
  179. * HISTORY: *
  180. * 5/22/96 9:01AM ST : Created *
  181. *=============================================================================================*/
  182. void CDFileClass::Refresh_Search_Drives (void)
  183. {
  184. Clear_Search_Drives();
  185. Set_Search_Drives(RawPath);
  186. }
  187. #if 0
  188. /***********************************************************************************************
  189. * CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. *
  190. * *
  191. * This routine sets up a list of search paths to use when accessing files. The path list *
  192. * is scanned if the file could not be found in the current directory. This is the primary *
  193. * method of supporting CD-ROM drives, but is also useful for scanning network and other *
  194. * directories. The pathlist as passed to this routine is of the same format as the path *
  195. * list used by DOS -- paths are separated by semicolons and need not end in an antivirgule.*
  196. * *
  197. * If a path entry begins with "?:" then the question mark will be replaced with the first *
  198. * CD-ROM drive letter available. If there is no CD-ROM driver detected, then this path *
  199. * entry will be ignored. By using this feature, you can always pass the CD-ROM path *
  200. * specification to this routine and it will not break if the CD-ROM is not loaded (as in *
  201. * the case during development). *
  202. * *
  203. * Here is an example path specification: *
  204. * *
  205. * Set_Search_Drives("DATA;?:\DATA;F:\PROJECT\DATA"); *
  206. * *
  207. * In this example, the current directory will be searched first, followed by a the *
  208. * subdirectory "DATA" located off of the current directory. If not found, then the CD-ROM *
  209. * will be searched in a directory called "\DATA". If not found or the CD-ROM is not *
  210. * present, then it will look to the hard coded path of "F:\PROJECTS\DATA" (maybe a *
  211. * network?). If all of these searches fail, the file system will default to the current *
  212. * directory and let the normal file error system take over. *
  213. * *
  214. * INPUT: pathlist -- Pointer to string of path specifications (separated by semicolons) *
  215. * that will be used to search for files. *
  216. * *
  217. * OUTPUT: none *
  218. * *
  219. * WARNINGS: none *
  220. * *
  221. * HISTORY: *
  222. * 10/18/1994 JLB : Created. *
  223. *=============================================================================================*/
  224. int CDFileClass::Set_Search_Drives(char * pathlist)
  225. {
  226. int found = false;
  227. int empty = false;
  228. /*
  229. ** If there is no pathlist to add, then just return.
  230. */
  231. if (!pathlist) return(0);
  232. char const * ptr = strtok(pathlist, ";");
  233. while (ptr) {
  234. char path[PATH_MAX]; // Working path buffer.
  235. SearchDriveType *srch; // Working pointer to path object.
  236. /*
  237. ** Fixup the path to be legal. Legal is defined as all that is necessary to
  238. ** create a pathname is to append the actual filename submitted to the
  239. ** file system. This means that it must have either a trailing ':' or '\'
  240. ** character.
  241. */
  242. strcpy(path, ptr);
  243. switch (path[strlen(path)-1]) {
  244. case ':':
  245. case '\\':
  246. break;
  247. default:
  248. strcat(path, "\\");
  249. break;
  250. }
  251. /*
  252. ** If there is a drive letter specified, and this drive letter is '?', then it should
  253. ** be substituted with the CD-ROM drive letter. In the case of no CD-ROM attached, then
  254. ** merely ignore this path entry.
  255. */
  256. if (strncmp(path, "?:", 2) == 0) {
  257. #ifndef WIN32
  258. GetCDClass temp;
  259. int cd = temp.GetCDDrive();
  260. #else
  261. int cd = 10;
  262. #endif
  263. found = cd;
  264. empty = !Is_Disk_Inserted(cd);
  265. if (!found || empty) goto nextpath;
  266. path[0] = (char)('A' + cd);
  267. }
  268. /*
  269. ** Allocate a record structure.
  270. */
  271. srch = new SearchDriveType;
  272. if (srch) {
  273. found = true;
  274. /*
  275. ** Attach the path to this structure.
  276. */
  277. srch->Path = strdup(path);
  278. srch->Next = NULL;
  279. /*
  280. ** Attach this path record to the end of the path chain.
  281. */
  282. if (!First) {
  283. First = srch;
  284. } else {
  285. SearchDriveType * chain = First;
  286. while (chain->Next) {
  287. chain = (SearchDriveType *)chain->Next;
  288. }
  289. chain->Next = srch;
  290. }
  291. }
  292. /*
  293. ** Find the next path string and resubmit.
  294. */
  295. nextpath:
  296. ptr = strtok(NULL, ";");
  297. }
  298. if (!found) return(1);
  299. if (empty) return(2);
  300. return(0);
  301. }
  302. #endif
  303. /***********************************************************************************************
  304. * CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. *
  305. * *
  306. * This routine sets up a list of search paths to use when accessing files. The path list *
  307. * is scanned if the file could not be found in the current directory. This is the primary *
  308. * method of supporting CD-ROM drives, but is also useful for scanning network and other *
  309. * directories. The pathlist as passed to this routine is of the same format as the path *
  310. * list used by DOS -- paths are separated by semicolons and need not end in an antivirgule.*
  311. * *
  312. * If a path entry begins with "?:" then the question mark will be replaced with the first *
  313. * CD-ROM drive letter available. If there is no CD-ROM driver detected, then this path *
  314. * entry will be ignored. By using this feature, you can always pass the CD-ROM path *
  315. * specification to this routine and it will not break if the CD-ROM is not loaded (as in *
  316. * the case during development). *
  317. * *
  318. * Here is an example path specification: *
  319. * *
  320. * Set_Search_Drives("DATA;?:\DATA;F:\PROJECT\DATA"); *
  321. * *
  322. * In this example, the current directory will be searched first, followed by a the *
  323. * subdirectory "DATA" located off of the current directory. If not found, then the CD-ROM *
  324. * will be searched in a directory called "\DATA". If not found or the CD-ROM is not *
  325. * present, then it will look to the hard coded path of "F:\PROJECTS\DATA" (maybe a *
  326. * network?). If all of these searches fail, the file system will default to the current *
  327. * directory and let the normal file error system take over. *
  328. * *
  329. * INPUT: pathlist -- Pointer to string of path specifications (separated by semicolons) *
  330. * that will be used to search for files. *
  331. * *
  332. * OUTPUT: none *
  333. * *
  334. * WARNINGS: none *
  335. * *
  336. * HISTORY: *
  337. * 10/18/1994 JLB : Created. *
  338. * 05/21/1996 ST : Modified to recognise multiple CD drives *
  339. *=============================================================================================*/
  340. int CDFileClass::Set_Search_Drives(char * pathlist)
  341. {
  342. int found = FALSE;
  343. int empty = FALSE;
  344. /*
  345. ** If there is no pathlist to add, then just return.
  346. */
  347. if (!pathlist) return(0);
  348. /*
  349. ** Save the path as it was passed in so we can parse it again later.
  350. ** Check for the case where RawPath was passed in.
  351. */
  352. if (pathlist != RawPath) {
  353. strcat (RawPath, ";");
  354. strcat (RawPath, pathlist);
  355. }
  356. char const * ptr = strtok(pathlist, ";");
  357. while (ptr != NULL) {
  358. if (strlen(ptr) > 0) {
  359. char path[MAX_PATH]; // Working path buffer.
  360. /*
  361. ** Fixup the path to be legal. Legal is defined as all that is necessary to
  362. ** create a pathname is to append the actual filename submitted to the
  363. ** file system. This means that it must have either a trailing ':' or '\'
  364. ** character.
  365. */
  366. strcpy(path, ptr);
  367. switch (path[strlen(path)-1]) {
  368. case ':':
  369. case '\\':
  370. break;
  371. default:
  372. strcat(path, "\\");
  373. break;
  374. }
  375. /*
  376. ** If there is a drive letter specified, and this drive letter is '?', then it should
  377. ** be substituted with the CD-ROM drive letter. In the case of no CD-ROM attached, then
  378. ** merely ignore this path entry.
  379. ** Adds an extra entry for each CD drive in the system that has a C&C disc inserted.
  380. ** ST - 5/21/96 4:40PM
  381. */
  382. if (strncmp(path, "?:", 2) == 0) {
  383. if (CurrentCDDrive) {
  384. found = true;
  385. /*
  386. ** If the drive has a C&C CD in it then add it to the path
  387. */
  388. if (Get_CD_Index(CurrentCDDrive, 2*60) >= 0) {
  389. path[0] = (char)(CurrentCDDrive + 'A');
  390. Add_Search_Drive(path);
  391. }
  392. }
  393. /*
  394. ** Find the next path string and resubmit.
  395. */
  396. ptr = strtok(NULL, ";");
  397. continue;
  398. }
  399. found = true;
  400. Add_Search_Drive(path);
  401. }
  402. /*
  403. ** Find the next path string and resubmit.
  404. */
  405. ptr = strtok(NULL, ";");
  406. }
  407. if (!found) return(1);
  408. if (empty) return(2);
  409. return(0);
  410. }
  411. /***********************************************************************************************
  412. * CDFC::Add_Search_Drive -- Add a new path to the search path list *
  413. * *
  414. * *
  415. * *
  416. * INPUT: path *
  417. * *
  418. * OUTPUT: Nothing *
  419. * *
  420. * WARNINGS: None *
  421. * *
  422. * HISTORY: *
  423. * 5/22/96 10:12AM ST : Created *
  424. *=============================================================================================*/
  425. void CDFileClass::Add_Search_Drive(char *path)
  426. {
  427. SearchDriveType *srch; // Working pointer to path object.
  428. /*
  429. ** Allocate a record structure.
  430. */
  431. srch = new SearchDriveType;
  432. /*
  433. ** Attach the path to this structure.
  434. */
  435. srch->Path = strdup(path);
  436. srch->Next = NULL;
  437. /*
  438. ** Attach this path record to the end of the path chain.
  439. */
  440. if (!First) {
  441. First = srch;
  442. } else {
  443. SearchDriveType * chain = First;
  444. while (chain->Next) {
  445. chain = (SearchDriveType *)chain->Next;
  446. }
  447. chain->Next = srch;
  448. }
  449. }
  450. /***********************************************************************************************
  451. * CDFC::Set_CD_Drive -- sets the current CD drive letter *
  452. * *
  453. * *
  454. * *
  455. * INPUT: Nothing *
  456. * *
  457. * OUTPUT: Nothing *
  458. * *
  459. * WARNINGS: None *
  460. * *
  461. * HISTORY: *
  462. * 5/22/96 9:39AM ST : Created *
  463. *=============================================================================================*/
  464. void CDFileClass::Set_CD_Drive (int drive)
  465. {
  466. LastCDDrive = CurrentCDDrive;
  467. CurrentCDDrive = drive;
  468. }
  469. /***********************************************************************************************
  470. * CDFileClass::Clear_Search_Drives -- Removes all record of a search path. *
  471. * *
  472. * Use this routine to clear out any previous path(s) set with Set_Search_Drives() *
  473. * function. *
  474. * *
  475. * INPUT: none *
  476. * *
  477. * OUTPUT: none *
  478. * *
  479. * WARNINGS: none *
  480. * *
  481. * HISTORY: *
  482. * 10/18/1994 JLB : Created. *
  483. *=============================================================================================*/
  484. void CDFileClass::Clear_Search_Drives(void)
  485. {
  486. SearchDriveType * chain; // Working pointer to path chain.
  487. chain = First;
  488. while (chain) {
  489. SearchDriveType *next;
  490. next = (SearchDriveType *)chain->Next;
  491. if (chain->Path) {
  492. free((char *)chain->Path);
  493. }
  494. delete chain;
  495. chain = next;
  496. }
  497. First = 0;
  498. }
  499. /***********************************************************************************************
  500. * CDFileClass::Set_Name -- Performs a multiple directory scan to set the filename. *
  501. * *
  502. * This routine will scan all the directories specified in the path list and if the file *
  503. * was found in one of the directories, it will set the filename to a composite of the *
  504. * correct directory and the filename. It is used to allow path searching when searching *
  505. * for files. Typical use is to support CD-ROM drives. This routine examines the current *
  506. * directory first before scanning through the path list. If after scanning the entire *
  507. * path list, the file still could not be found, then the file object's name is set with *
  508. * just the raw filename as passed to this routine. *
  509. * *
  510. * INPUT: filename -- Pointer to the filename to set as the name of this file object. *
  511. * *
  512. * OUTPUT: Returns a pointer to the final and complete filename of this file object. This *
  513. * may have a path attached to the file. *
  514. * *
  515. * WARNINGS: none *
  516. * *
  517. * HISTORY: *
  518. * 10/18/1994 JLB : Created. *
  519. *=============================================================================================*/
  520. char const * CDFileClass::Set_Name(char const *filename)
  521. {
  522. /*
  523. ** Try to find the file in the current directory first. If it can be found, then
  524. ** just return with the normal file name setting process. Do the same if there is
  525. ** no multi-drive search path.
  526. */
  527. BufferIOFileClass::Set_Name(filename);
  528. if (IsDisabled || !First || BufferIOFileClass::Is_Available()) return(File_Name());
  529. /*
  530. ** Attempt to find the file first. Check the current directory. If not found there, then
  531. ** search all the path specifications available. If it still can't be found, then just
  532. ** fall into the normal raw file filename setting system.
  533. */
  534. SearchDriveType * srch = First;
  535. while (srch) {
  536. char path[_MAX_PATH];
  537. /*
  538. ** Build a pathname to search for.
  539. */
  540. strcpy(path, srch->Path);
  541. strcat(path, filename);
  542. /*
  543. ** Check to see if the file could be found. The low level Is_Available logic will
  544. ** prompt if necessary when the CD-ROM drive has been removed. In all other cases,
  545. ** it will return false and the search process will continue.
  546. */
  547. BufferIOFileClass::Set_Name(path);
  548. if (BufferIOFileClass::Is_Available()) {
  549. return(File_Name());
  550. }
  551. /*
  552. ** It wasn't found, so try the next path entry.
  553. */
  554. srch = (SearchDriveType *)srch->Next;
  555. }
  556. /*
  557. ** At this point, all path searching has failed. Just set the file name to the
  558. ** plain text passed to this routine and be done with it.
  559. */
  560. BufferIOFileClass::Set_Name(filename);
  561. return(File_Name());
  562. }
  563. /***********************************************************************************************
  564. * CDFileClass::Open -- Opens the file wherever it can be found. *
  565. * *
  566. * This routine is similar to the RawFileClass open except that if the file is being *
  567. * opened only for READ access, it will search all specified directories looking for the *
  568. * file. If after a complete search the file still couldn't be found, then it is opened *
  569. * using the normal BufferIOFileClass system -- resulting in normal error procedures. *
  570. * *
  571. * INPUT: filename -- Pointer to the override filename to supply for this file object. It *
  572. * would be the base filename (sans any directory specification). *
  573. * *
  574. * rights -- The access rights to use when opening the file. *
  575. * *
  576. * OUTPUT: bool; Was the file opened successfully? If so then the filename may be different *
  577. * than requested. The location of the file can be determined by examining the *
  578. * filename of this file object. The filename will contain the complete *
  579. * pathname used to open the file. *
  580. * *
  581. * WARNINGS: none *
  582. * *
  583. * HISTORY: *
  584. * 10/18/1994 JLB : Created. *
  585. *=============================================================================================*/
  586. int CDFileClass::Open(char const *filename, int rights)
  587. {
  588. CDFileClass::Close();
  589. /*
  590. ** Verify that there is a filename associated with this file object. If not, then this is a
  591. ** big error condition.
  592. */
  593. if (!filename) {
  594. Error(ENOENT, false);
  595. }
  596. /*
  597. ** If writing is requested, then multiple drive searching is not performed.
  598. */
  599. if (IsDisabled || rights == WRITE) {
  600. BufferIOFileClass::Set_Name( filename );
  601. return( BufferIOFileClass::Open( rights ) );
  602. }
  603. /*
  604. ** Perform normal multiple drive searching for the filename and open
  605. ** using the normal procedure.
  606. */
  607. Set_Name(filename);
  608. return(BufferIOFileClass::Open(rights));
  609. }
  610. const char *CDFileClass::Get_Search_Path(int index)
  611. {
  612. if (First == NULL) {
  613. return NULL;
  614. }
  615. SearchDriveType *sd = First;
  616. for (int i = 0; i <= index; i++) { // We want to loop once, even if index==0
  617. if (i == index) {
  618. return sd->Path;
  619. }
  620. sd = (SearchDriveType *)sd->Next;
  621. if (sd == NULL) {
  622. return NULL;
  623. }
  624. }
  625. return NULL;
  626. }
  627. #ifdef NEVER
  628. /*
  629. ** Get the drive letters if the CD's online */
  630. */
  631. WORD cdecl GetCDDrive(VOID)
  632. {
  633. _ES = FP_SEG(&cdDrive[0]);
  634. _BX = FP_OFF(&cdDrive[0]);
  635. _AX = 0x150d;
  636. geninterrupt(0x2F);
  637. return((WORD)(*cdDrive));
  638. }
  639. #endif
  640. #if 0
  641. int Get_CD_Drive(void)
  642. {
  643. #ifdef WIN32
  644. return(10);
  645. #else
  646. #ifdef NEVER
  647. for (int index = 0; index < 26; index++) {
  648. union REGS regs;
  649. regs.w.ax = 0x150B;
  650. regs.w.bx = 0;
  651. regs.w.cx = index;
  652. int386(0x2F, &regs, &regs);
  653. if (regs.w.bx == 0xADAD) {
  654. return(index);
  655. }
  656. }
  657. return(0);
  658. #else
  659. GetCDClass temp;
  660. return(temp.GetCDDrive());
  661. #endif
  662. #endif
  663. }
  664. #endif