CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

CDFILE.CPP (34803B)


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