| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***************************************************************************
- ** 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 **
- ***************************************************************************
- * *
- * Project Name : Westwood Library *
- * *
- * File Name : FINDFILE.C *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : August 21, 1991 *
- * *
- * Last Update : September 29, 1993 [SKB] *
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * Find_File_Index -- Finds the FileTable index number for a given file. *
- * Find_File -- Checks if a file is immediatly available. *
- * Get_FileData -- Gets a pointer back to the correct file. *
- * Find_File -- Checks if a file is immediatly available. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /*=========================================================================*/
- /* The following PRIVATE functions are in this file: */
- /*=========================================================================*/
- /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
- #ifndef WWSTD_H
- #include "wwstd.h"
- #endif
- #ifndef _FILE_H
- #include "_file.h"
- #endif
- #include <direct.h>
- #include <dos.h>
- #include <fcntl.h>
- #include <io.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <search.h>
- #include <sys\stat.h>
- /***************************************************************************
- * FIND_FILE -- Checks if a file is immediatly available. *
- * *
- * Use this function to determine if a file is immediatly available. *
- * This routine will NOT request for the proper disk to be inserted *
- * if the file could not be found. Use File_Exists for that feature. *
- * The Westwood file I/O system does NOT have to be initialized as *
- * a prerequisit to using this function. *
- * *
- * INPUT: file_name -- Name of the file to check. *
- * *
- * OUTPUT: Returns the disk number that the file exits on (A=1, B=2, etc) *
- * *
- * WARNINGS: This sets the current drive to the drive that contains the *
- * specified file (if it is found). *
- * *
- * HISTORY: *
- * 11/14/1991 JLB : Created. *
- * 03/14/1992 JLB : Modified for Amiga compatability. *
- * 01/11/1993 SKB : Modified for CD-ROM searches. *
- *=========================================================================*/
- WORD cdecl Find_File(BYTE const *file_name)
- {
- FileDataType *filedata = NULL;
- WORD index; // File index (if any).
- WORD disk; // Disk number of file (if in filetable).
-
- /*
- ** If the filename is invalid then it errors out as if the file wasn't
- ** found (naturally).
- */
- if (!file_name) return(FALSE);
- /*
- ** Determine if the file has a file table entry. If it does, then
- ** special checks and processing must occur.
- ** Also, if it is in memory, return with it.
- */
- index = Find_File_Index(file_name);
- filedata = &FileDataPtr[index];
- if (index != ERROR) {
- // If the file is currently cached, return TRUE that it was found.
- if (filedata->Ptr) {
- return (TRUE);
- }
- }
- /*
- ** Always check the current directory for the file. Only if it can't
- ** be found are furthur measures required.
- */
- DiskNumber = ERROR; // This indicates file exists in current directory.
-
- #if (LIB_CDROM)
- ibm_setdisk(*StartPath - 'A');
- #endif
- /*
- ** Check the current directory by attempting to open with READ access.
- */
- {
- WORD handle;
-
- CallingDOSInt++;
- handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
- CallingDOSInt--;
- if (handle != ERROR)
- {
- // WORD d;
- unsigned d ;
- CallingDOSInt++;
- close(handle);
- // d = getdisk();
- _dos_getdrive ( & d) ;
- CallingDOSInt--;
- return(d);
- }
- }
-
-
- if (index != ERROR) {
- disk = filedata->Disk;
- /*
- ** If the file is in a packed file, then search for the packed file
- ** instead of the specified one.
- */
- if (index != ERROR && (filedata->Flag & FILEF_PACKED)) {
- filedata = &FileDataPtr[disk];
- return (Find_File(filedata->Name));
- }
- }
- /*
- ** It could not be found on the current drive, so search the other
- ** drives if allowed to do so.
- */
- if (!MultiDriveSearch) {
- return(FALSE);
- }
- #if (LIB_CDROM)
- // If we were unable to find the file on the hard drive, change
- // drives to the CD rom drive and see if it is there.
- ibm_setdisk(*DataPath - 'A');
-
- {
- WORD handle;
-
- Hard_Error_Occured = 0;
- handle = Open_File_With_Recovery( file_name, MODE_OLDFILE );
- if (handle != FILEOPENERROR) {
- FILECLOSE(handle);
- return(ibm_getdisk() + 1);
- }
- }
- ibm_setdisk(*StartPath - 'A');
- return (FALSE);
- #else
- {
- WORD start_drive; // Original current drive number.
- /*
- ** Record the current drive for restoring later in case of failure.
- */
- CallingDOSInt++;
- start_drive = getdisk();
- CallingDOSInt--;
- /*
- ** Sweep backward from the last real drive to the first, looking for the
- ** file on each in turn.
- */
- for (index = MaxDevice; index != -1; index--) {
- if (Is_Device_Real(index)) {
- CallingDOSInt++;
- setdisk(index);
- CallingDOSInt--;
- {
- WORD handle;
- CallingDOSInt++;
- handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
- CallingDOSInt--;
- if (handle != ERROR) {
- CallingDOSInt++;
- close(handle);
- CallingDOSInt--;
- DiskNumber = index+1;
- return (DiskNumber);
- }
- }
- }
- }
- CallingDOSInt++;
- setdisk(start_drive);
- CallingDOSInt--;
- }
-
- return(FALSE);
- #endif
- }
- /***************************************************************************
- * FIND_FILE_INDEX -- Finds the FileTable index number for a given file. *
- * *
- * This function searches the FileTable and returns with the index of *
- * the matching file. If the file doesn't exist in the table, then *
- * ERROR is returned. It does not care about case. *
- * *
- * INPUT: filename -- Pointer to the filename to check. *
- * *
- * OUTPUT: Returns with the index into the FileTable. If the file does *
- * not exist in the file table, then ERROR is returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 11/09/1991 JLB : Created. *
- * 06/11/1993 JLB : Sorts and binary searches the file table. *
- *=========================================================================*/
- PRIVATE int Comp_Func(const void *p1, const void *p2)
- {
- return(strcmp((char *) ((FileDataType*)p1)->Name, (char *) ((FileDataType*)p2)->Name));
- }
- WORD cdecl Find_File_Index(BYTE const *filename)
- {
- FileDataType *filedata; // File entry pointer.
- FileDataType key; // Working file data type var.
- /*
- ** Perform a binary search on the presorted filetable.
- */
- if (filename) {
- filedata = NULL;
- key.Name = (BYTE *) strupr((char *)filename);
- if (strstr((char *)key.Name, (char *)".PAK")) {
-
- /*
- ** If the FileData table was not loaded from the disk then the PAK files are
- ** not sorted so Perform a linear search for the pak files.
- ** Otherwise the files are sorted so speed things up by doing a bsearch.
- */
- if (FileData == FileDataPtr) {
- filedata = (FileDataType *) lfind(&key, FileDataPtr, (size_t *) &NumPAKFiles, sizeof(FileDataType), Comp_Func);
- }
- else {
- filedata = (FileDataType *)bsearch(&key, FileDataPtr, NumPAKFiles, sizeof(FileDataType), Comp_Func);
- }
- } else {
-
- /*
- ** Perform a binary search for the regular files.
- */
- filedata = (FileDataType *)bsearch(&key, &FileDataPtr[NumPAKFiles], NumFiles, sizeof(FileDataType), Comp_Func);
- }
- // Return the element in the array if file was found in table.
- if (filedata) {
- return (filedata - FileDataPtr);
- //return ((WORD)((((LONG)filedata) - ((LONG)FileDataPtr)) / sizeof(FileDataType)));
- }
- }
- return(ERROR);
- }
|