mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
UTIL is never used, and JA2 is always used. assumption being we'll never make 1.13 for Wizardry 8. video2.h doesn't exist, which prevented me from deleting it.
1101 lines
35 KiB
C++
1101 lines
35 KiB
C++
#include "Types.h"
|
|
#include "windows.h"
|
|
#include "FileMan.h"
|
|
#include "LibraryDataBase.h"
|
|
#include "MemMan.h"
|
|
#include "stdio.h"
|
|
#include "WCheck.h"
|
|
#include "Debug.h"
|
|
|
|
#include "video.h"
|
|
|
|
//NUMBER_OF_LIBRARIES
|
|
#include "Ja2 Libs.h"
|
|
#include "GameSettings.h"
|
|
|
|
|
|
|
|
|
|
//used when doing the binary search of the libraries
|
|
INT16 gsCurrentLibrary = -1;
|
|
|
|
|
|
//The location of the cdrom drive
|
|
CHAR8 gzCdDirectory[ SGPFILENAME_LEN ];
|
|
|
|
|
|
INT CompareFileNames( CHAR8 **arg1, FileHeaderStruct **arg2 );
|
|
BOOLEAN GetFileHeaderFromLibrary( INT16 sLibraryID, STR pstrFileName, FileHeaderStruct **pFileHeader );
|
|
void AddSlashToPath( STR pName );
|
|
HWFILE CreateLibraryFileHandle( INT16 sLibraryID, UINT32 uiFileNum );
|
|
BOOLEAN CheckIfFileIsAlreadyOpen( STR pFileName, INT16 sLibraryID );
|
|
|
|
INT32 CompareDirEntryFileNames( CHAR8 *arg1[], DIRENTRY **arg2 );
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// InitializeFileDatabase(): Call this function to initialize the file
|
|
// database. It will use the gGameLibaries[] array for the list of libraries
|
|
// and the define NUMBER_OF_LIBRARIES for the number of libraries. The gGameLibaries
|
|
// array is an array of structure, one of the fields determines if the library
|
|
// will be initialized and game start.
|
|
//
|
|
//************************************************************************
|
|
BOOLEAN InitializeFileDatabase( )
|
|
{
|
|
INT16 i;
|
|
UINT32 uiSize;
|
|
BOOLEAN fLibraryInited = FALSE;
|
|
|
|
GetCDLocation( );
|
|
|
|
//if all the libraries exist, set them up
|
|
gFileDataBase.usNumberOfLibraries = NUMBER_OF_LIBRARIES;
|
|
|
|
//allocate memory for the each of the library headers
|
|
uiSize = NUMBER_OF_LIBRARIES * sizeof( LibraryHeaderStruct );
|
|
if( uiSize )
|
|
{
|
|
gFileDataBase.pLibraries = (LibraryHeaderStruct *) MemAlloc( uiSize );
|
|
CHECKF( gFileDataBase.pLibraries );
|
|
|
|
//set all the memrory to 0
|
|
memset( gFileDataBase.pLibraries, 0, uiSize );
|
|
|
|
|
|
//Load up each library
|
|
for( i=0; i< NUMBER_OF_LIBRARIES; i++ )
|
|
{
|
|
//if you want to init the library at the begining of the game
|
|
if( gGameLibaries[i].fInitOnStart )
|
|
{
|
|
//if the library exists
|
|
if( OpenLibrary( i ) )
|
|
fLibraryInited = TRUE;
|
|
|
|
//else the library doesnt exist
|
|
else
|
|
{
|
|
FastDebugMsg( String("Warning in InitializeFileDatabase( ): Library Id #%d (%s) is to be loaded but cannot be found.\n", i, gGameLibaries[i].sLibraryName ));
|
|
gFileDataBase.pLibraries[ i ].fLibraryOpen = FALSE;
|
|
}
|
|
}
|
|
}
|
|
//signify that the database has been initialized ( only if there was a library loaded )
|
|
gFileDataBase.fInitialized = fLibraryInited;
|
|
}
|
|
|
|
//allocate memory for the handles of the 'real files' that will be open
|
|
//This is needed because the the code wouldnt be able to tell the difference between a 'real' handle and a made up one
|
|
uiSize = INITIAL_NUM_HANDLES * sizeof( RealFileOpenStruct );
|
|
gFileDataBase.RealFiles.pRealFilesOpen = (RealFileOpenStruct *) MemAlloc( uiSize );
|
|
CHECKF( gFileDataBase.RealFiles.pRealFilesOpen );
|
|
|
|
//clear the memory
|
|
memset( gFileDataBase.RealFiles.pRealFilesOpen, 0, uiSize);
|
|
|
|
//set the initial number how many files can be opened at the one time
|
|
gFileDataBase.RealFiles.iSizeOfOpenFileArray = INITIAL_NUM_HANDLES;
|
|
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
//*****************************************************************************************
|
|
// ReopenCDLibraries
|
|
//
|
|
// Closes all CD libraries, then reopens them. This function needs to be called when CDs
|
|
// are changed.
|
|
//
|
|
// Returns BOOLEAN - TRUE, always
|
|
//
|
|
// Created: 3/21/00 Derek Beland
|
|
//*****************************************************************************************
|
|
BOOLEAN ReopenCDLibraries(void)
|
|
{
|
|
INT16 i;
|
|
|
|
//Load up each library
|
|
for(i=0; i < NUMBER_OF_LIBRARIES; i++ )
|
|
{
|
|
if(gFileDataBase.pLibraries[ i ].fLibraryOpen && gGameLibaries[i].fOnCDrom)
|
|
CloseLibrary(i);
|
|
|
|
if(gGameLibaries[i].fOnCDrom)
|
|
OpenLibrary( i );
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//************************************************************************
|
|
//
|
|
// ShutDownFileDatabase(): Call this function to close down the file
|
|
// database.
|
|
//
|
|
//************************************************************************
|
|
|
|
BOOLEAN ShutDownFileDatabase( )
|
|
{
|
|
UINT16 sLoop1;
|
|
|
|
// Free up the memory used for each library
|
|
for(sLoop1=0; sLoop1 < gFileDataBase.usNumberOfLibraries; sLoop1++)
|
|
CloseLibrary( sLoop1 );
|
|
|
|
//Free up the memory used for all the library headers
|
|
if( gFileDataBase.pLibraries )
|
|
{
|
|
MemFree( gFileDataBase.pLibraries );
|
|
gFileDataBase.pLibraries = NULL;
|
|
}
|
|
|
|
|
|
//loop through all the 'opened files' ( there should be no files open )
|
|
for( sLoop1=0; sLoop1< gFileDataBase.RealFiles.iNumFilesOpen; sLoop1++)
|
|
{
|
|
FastDebugMsg( String("ShutDownFileDatabase( ): ERROR: real file id still exists, wasnt closed") );
|
|
CloseHandle( gFileDataBase.RealFiles.pRealFilesOpen[ sLoop1 ].hRealFileHandle );
|
|
}
|
|
|
|
//Free up the memory used for the real files array for the opened files
|
|
if( gFileDataBase.RealFiles.pRealFilesOpen )
|
|
{
|
|
MemFree( gFileDataBase.RealFiles.pRealFilesOpen );
|
|
gFileDataBase.RealFiles.pRealFilesOpen = NULL;
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN CheckForLibraryExistence( STR pLibraryName )
|
|
{
|
|
BOOLEAN fRetVal = FALSE;
|
|
HANDLE hFile;
|
|
|
|
//try to opent the file, if we canm the library exists
|
|
hFile = CreateFile( pLibraryName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL );
|
|
|
|
//if the file was not opened
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
|
|
//the file wasnt opened
|
|
fRetVal = FALSE;
|
|
}
|
|
else
|
|
{
|
|
CloseHandle( hFile );
|
|
fRetVal = TRUE;
|
|
}
|
|
|
|
return( fRetVal );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN InitializeLibrary( STR pLibraryName, LibraryHeaderStruct *pLibHeader, BOOLEAN fCanBeOnCDrom )
|
|
{
|
|
HANDLE hFile;
|
|
UINT16 usNumEntries=0;
|
|
UINT32 uiNumBytesRead;
|
|
UINT32 uiLoop;
|
|
DIRENTRY DirEntry;
|
|
LIBHEADER LibFileHeader;
|
|
UINT32 uiCount=0;
|
|
CHAR8 zTempPath[ SGPFILENAME_LEN ];
|
|
|
|
//open the library for reading ( if it exists )
|
|
hFile = CreateFile( pLibraryName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL );
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
//if it failed finding the file on the hard drive, and the file can be on the cdrom
|
|
if( fCanBeOnCDrom )
|
|
{
|
|
// Add the path of the cdrom to the path of the library file
|
|
sprintf( zTempPath, "%s%s", gzCdDirectory, pLibraryName );
|
|
|
|
//look on the cdrom
|
|
hFile = CreateFile( zTempPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL );
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
UINT32 uiLastError = GetLastError();
|
|
char zString[1024];
|
|
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, uiLastError, 0, zString, 1024, NULL);
|
|
|
|
return( FALSE );
|
|
}
|
|
else
|
|
FastDebugMsg( String("CD Library %s opened.", zTempPath));
|
|
}
|
|
else
|
|
{
|
|
//error opening the library
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
// Read in the library header ( at the begining of the library )
|
|
if( !ReadFile( hFile, &LibFileHeader, sizeof( LIBHEADER ), (LPDWORD) &uiNumBytesRead, NULL ) )
|
|
return( FALSE );
|
|
|
|
if( uiNumBytesRead != sizeof( LIBHEADER ) )
|
|
{
|
|
//Error Reading the file database header.
|
|
return( FALSE );
|
|
}
|
|
|
|
//place the file pointer at the begining of the file headers ( they are at the end of the file )
|
|
SetFilePointer( hFile, -( LibFileHeader.iEntries * (INT32)sizeof(DIRENTRY) ), NULL, FILE_END );
|
|
|
|
//loop through the library and determine the number of files that are FILE_OK
|
|
//ie. so we dont load the old or deleted files
|
|
usNumEntries = 0;
|
|
for( uiLoop=0; uiLoop<(UINT32)LibFileHeader.iEntries; uiLoop++ )
|
|
{
|
|
//read in the file header
|
|
if( !ReadFile( hFile, &DirEntry, sizeof( DIRENTRY ), (LPDWORD) &uiNumBytesRead, NULL ) )
|
|
return( FALSE );
|
|
|
|
if( DirEntry.ubState == FILE_OK )
|
|
usNumEntries++;
|
|
}
|
|
|
|
|
|
//Allocate enough memory for the library header
|
|
pLibHeader->pFileHeader = (FileHeaderStruct *) MemAlloc( sizeof( FileHeaderStruct ) * usNumEntries );
|
|
|
|
#ifdef JA2TESTVERSION
|
|
pLibHeader->uiTotalMemoryAllocatedForLibrary = sizeof( FileHeaderStruct ) * usNumEntries;
|
|
#endif
|
|
|
|
|
|
//place the file pointer at the begining of the file headers ( they are at the end of the file )
|
|
SetFilePointer( hFile, -( LibFileHeader.iEntries * (INT32)sizeof(DIRENTRY) ), NULL, FILE_END );
|
|
|
|
//loop through all the entries
|
|
uiCount=0;
|
|
for( uiLoop=0; uiLoop<(UINT32)LibFileHeader.iEntries; uiLoop++ )
|
|
{
|
|
//read in the file header
|
|
if( !ReadFile( hFile, &DirEntry, sizeof( DIRENTRY ), (LPDWORD) &uiNumBytesRead, NULL ) )
|
|
return( FALSE );
|
|
|
|
|
|
if( DirEntry.ubState == FILE_OK )
|
|
{
|
|
//Check to see if the file is not longer then it should be
|
|
if( ( strlen( DirEntry.sFileName ) + 1 ) >= FILENAME_SIZE )
|
|
FastDebugMsg(String("\n*******InitializeLibrary(): Warning!: '%s' from the library '%s' has name whose size (%d) is bigger then it should be (%s)", DirEntry.sFileName, pLibHeader->sLibraryPath, ( strlen( DirEntry.sFileName ) + 1 ), FILENAME_SIZE ) );
|
|
|
|
|
|
//allocate memory for the files name
|
|
pLibHeader->pFileHeader[ uiCount ].pFileName = (STR) MemAlloc( strlen( DirEntry.sFileName ) + 1 );
|
|
|
|
//if we couldnt allocate memory
|
|
if( !pLibHeader->pFileHeader[ uiCount ].pFileName )
|
|
{
|
|
//report an error
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
#ifdef JA2TESTVERSION
|
|
pLibHeader->uiTotalMemoryAllocatedForLibrary += strlen( DirEntry.sFileName ) + 1;
|
|
#endif
|
|
|
|
|
|
//copy the file name, offset and length into the header
|
|
strcpy( pLibHeader->pFileHeader[ uiCount ].pFileName, DirEntry.sFileName);
|
|
pLibHeader->pFileHeader[ uiCount ].uiFileOffset = DirEntry.uiOffset;
|
|
pLibHeader->pFileHeader[ uiCount ].uiFileLength = DirEntry.uiLength;
|
|
|
|
uiCount++;
|
|
}
|
|
}
|
|
|
|
|
|
pLibHeader->usNumberOfEntries = usNumEntries;
|
|
|
|
//allocate memory for the library path
|
|
// if( strlen( LibFileHeader.sPathToLibrary ) == 0 )
|
|
{
|
|
// FastDebugMsg( String("The %s library file does not contain a path. Use 'n' argument to name the library when you create it\n", LibFileHeader.sLibName ) );
|
|
// Assert( 0 );
|
|
}
|
|
|
|
//if the library has a path
|
|
if( strlen( LibFileHeader.sPathToLibrary ) != 0 )
|
|
{
|
|
pLibHeader->sLibraryPath = (STR) MemAlloc( strlen( LibFileHeader.sPathToLibrary ) + 1 );
|
|
strcpy( pLibHeader->sLibraryPath, LibFileHeader.sPathToLibrary );
|
|
}
|
|
else
|
|
{
|
|
//else the library name does not contain a path ( most likely either an error or it is the default path )
|
|
pLibHeader->sLibraryPath = (STR) MemAlloc( 1 );
|
|
pLibHeader->sLibraryPath[0] = '\0';
|
|
}
|
|
|
|
|
|
#ifdef JA2TESTVERSION
|
|
pLibHeader->uiTotalMemoryAllocatedForLibrary += strlen( LibFileHeader.sPathToLibrary ) + 1;
|
|
#endif
|
|
|
|
|
|
//allocate space for the open files array
|
|
pLibHeader->pOpenFiles = (FileOpenStruct *) MemAlloc( INITIAL_NUM_HANDLES * sizeof( FileOpenStruct ) );
|
|
if( !pLibHeader->pOpenFiles )
|
|
{
|
|
//report an error
|
|
return(FALSE);
|
|
}
|
|
|
|
memset( pLibHeader->pOpenFiles, 0, INITIAL_NUM_HANDLES * sizeof( FileOpenStruct ) );
|
|
|
|
#ifdef JA2TESTVERSION
|
|
pLibHeader->uiTotalMemoryAllocatedForLibrary += INITIAL_NUM_HANDLES * sizeof( FileOpenStruct );
|
|
#endif
|
|
|
|
|
|
|
|
pLibHeader->hLibraryHandle = hFile;
|
|
pLibHeader->usNumberOfEntries = usNumEntries;
|
|
pLibHeader->fLibraryOpen = TRUE;
|
|
pLibHeader->iNumFilesOpen = 0;
|
|
pLibHeader->iSizeOfOpenFileArray = INITIAL_NUM_HANDLES;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN LoadDataFromLibrary( INT16 sLibraryID, UINT32 uiFileNum, PTR pData, UINT32 uiBytesToRead, UINT32 *pBytesRead )
|
|
{
|
|
UINT32 uiOffsetInLibrary, uiLength;
|
|
HANDLE hLibraryFile;
|
|
UINT32 uiNumBytesRead;
|
|
UINT32 uiCurPos;
|
|
|
|
|
|
//get the offset into the library, the length and current position of the file pointer.
|
|
uiOffsetInLibrary = gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].pFileHeader->uiFileOffset;
|
|
uiLength = gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].pFileHeader->uiFileLength;
|
|
hLibraryFile = gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle;
|
|
uiCurPos = gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].uiFilePosInFile;
|
|
|
|
|
|
//set the file pointer to the right location
|
|
SetFilePointer( hLibraryFile, ( uiOffsetInLibrary + uiCurPos ), NULL, FILE_BEGIN );
|
|
|
|
//if we are trying to read more data then the size of the file, return an error
|
|
if( uiBytesToRead + uiCurPos > uiLength )
|
|
{
|
|
*pBytesRead = 0;
|
|
return( FALSE );
|
|
}
|
|
|
|
//get the data
|
|
if( !ReadFile( hLibraryFile, pData, uiBytesToRead, (LPDWORD) &uiNumBytesRead, NULL ) )
|
|
return( FALSE );
|
|
|
|
if( uiBytesToRead != uiNumBytesRead )
|
|
{
|
|
// Gets the reason why the function failed
|
|
// UINT32 uiLastError = GetLastError();
|
|
// char zString[1024];
|
|
// FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, uiLastError, 0, zString, 1024, NULL);
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].uiFilePosInFile += uiNumBytesRead;
|
|
|
|
// CloseHandle( hLibraryFile );
|
|
|
|
*pBytesRead = uiNumBytesRead;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
//************************************************************************
|
|
//
|
|
// CheckIfFileExistInLibrary() determines if a file exists in a library.
|
|
//
|
|
//************************************************************************
|
|
|
|
BOOLEAN CheckIfFileExistInLibrary( STR pFileName )
|
|
{
|
|
INT16 sLibraryID;
|
|
FileHeaderStruct *pFileHeader;
|
|
|
|
//get thelibrary that file is in
|
|
sLibraryID = GetLibraryIDFromFileName( pFileName );
|
|
if( sLibraryID == -1 )
|
|
{
|
|
//not in any library
|
|
return( FALSE );
|
|
}
|
|
|
|
if( GetFileHeaderFromLibrary( sLibraryID, pFileName, &pFileHeader ) )
|
|
return( TRUE );
|
|
else
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// This function finds out if the file CAN be in a library. It determines
|
|
// if the library that the file MAY be in is open.
|
|
// ( eg. File is Laptop\Test.sti, if the Laptop\ library is open, it returns true
|
|
//
|
|
//************************************************************************
|
|
INT16 GetLibraryIDFromFileName( STR pFileName )
|
|
{
|
|
INT16 sLoop1, sBestMatch=-1;
|
|
|
|
//loop through all the libraries to check which library the file is in
|
|
for( sLoop1=0; sLoop1<gFileDataBase.usNumberOfLibraries; sLoop1++)
|
|
{
|
|
//if the library is not loaded, dont try to access the array
|
|
if( IsLibraryOpened( sLoop1 ) )
|
|
{
|
|
//if the library path name is of size zero, ( the library is for the default path )
|
|
if( strlen( gFileDataBase.pLibraries[ sLoop1 ].sLibraryPath ) == 0 )
|
|
{
|
|
//determine if there is a directory in the file name
|
|
if( strchr( pFileName, '\\' ) == NULL && strchr( pFileName, '//' ) == NULL )
|
|
{
|
|
//There is no directory in the file name
|
|
return( sLoop1 );
|
|
}
|
|
}
|
|
|
|
//compare the library name to the file name that is passed in
|
|
else
|
|
{
|
|
// if the directory paths are the same, to the length of the lib's path
|
|
if( _strnicmp( gFileDataBase.pLibraries[ sLoop1 ].sLibraryPath, pFileName, strlen( gFileDataBase.pLibraries[ sLoop1 ].sLibraryPath ) ) == 0 )
|
|
{
|
|
// if we've never matched, or this match's path is longer than the previous match (meaning it's more exact)
|
|
if((sBestMatch==(-1)) || (strlen(gFileDataBase.pLibraries[ sLoop1 ].sLibraryPath) > strlen(gFileDataBase.pLibraries[ sBestMatch ].sLibraryPath)))
|
|
sBestMatch = sLoop1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//no library was found, return an error
|
|
return(sBestMatch);
|
|
}
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// GetFileHeaderFromLibrary() performsperforms a binary search of the
|
|
// library. It adds the libraries path to the file in the
|
|
// library and then string compared that to the name that we are
|
|
// searching for.
|
|
//
|
|
//************************************************************************
|
|
|
|
BOOLEAN GetFileHeaderFromLibrary( INT16 sLibraryID, STR pstrFileName, FileHeaderStruct **pFileHeader )
|
|
{
|
|
FileHeaderStruct **ppFileHeader;
|
|
CHAR8 sFileNameWithPath[ FILENAME_SIZE ];
|
|
|
|
//combine the library path to the file name (need it for the search of the library )
|
|
strcpy( sFileNameWithPath, pstrFileName);
|
|
|
|
gsCurrentLibrary = sLibraryID;
|
|
|
|
/* try to find the filename using a binary search algorithm: */
|
|
ppFileHeader = (FileHeaderStruct **) bsearch( &sFileNameWithPath, (FileHeaderStruct *) gFileDataBase.pLibraries[ sLibraryID ].pFileHeader, gFileDataBase.pLibraries[ sLibraryID ].usNumberOfEntries,
|
|
sizeof( FileHeaderStruct ), (int (*)(const void*, const void*))CompareFileNames );
|
|
|
|
if( ppFileHeader )
|
|
{
|
|
*pFileHeader = ( FileHeaderStruct * ) ppFileHeader;
|
|
return( TRUE );
|
|
}
|
|
else
|
|
{
|
|
pFileHeader = NULL;
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// CompareFileNames() gets called by the binary search function.
|
|
//
|
|
//************************************************************************
|
|
|
|
INT CompareFileNames( CHAR8 *arg1[], FileHeaderStruct **arg2 )
|
|
{
|
|
CHAR8 sSearchKey[ FILENAME_SIZE ];
|
|
CHAR8 sFileNameWithPath[ FILENAME_SIZE ];
|
|
FileHeaderStruct *TempFileHeader;
|
|
|
|
TempFileHeader = ( FileHeaderStruct * ) arg2;
|
|
|
|
sprintf( sSearchKey, "%s", arg1); // FIXME: arg1 must be a string pointer
|
|
|
|
sprintf( sFileNameWithPath, "%s%s", gFileDataBase.pLibraries[ gsCurrentLibrary ].sLibraryPath, TempFileHeader->pFileName );
|
|
|
|
/* Compare all of both strings: */
|
|
return _stricmp( sSearchKey, sFileNameWithPath );
|
|
}
|
|
|
|
|
|
|
|
|
|
void AddSlashToPath( STR pName )
|
|
{
|
|
UINT32 uiLoop, uiCounter;
|
|
BOOLEAN fDone = FALSE;
|
|
CHAR8 sNewName[ FILENAME_SIZE ];
|
|
|
|
//find out if there is a '\' in the file name
|
|
|
|
uiCounter=0;
|
|
for( uiLoop=0; uiLoop < strlen( pName ) && !fDone; uiLoop++)
|
|
{
|
|
if( pName[ uiLoop ] == '\\' )
|
|
{
|
|
sNewName[ uiCounter ] = pName[ uiLoop ];
|
|
uiCounter++;
|
|
sNewName[ uiCounter ] = '\\';
|
|
}
|
|
else
|
|
sNewName[ uiCounter ] = pName[ uiLoop ];
|
|
|
|
uiCounter++;
|
|
}
|
|
sNewName[ uiCounter ] = '\0';
|
|
|
|
strcpy( pName, sNewName );
|
|
}
|
|
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// This function will see if a file is in a library. If it is, the file will be opened and a file
|
|
// handle will be created for it.
|
|
//
|
|
//************************************************************************
|
|
|
|
HWFILE OpenFileFromLibrary( STR pName )
|
|
{
|
|
FileHeaderStruct *pFileHeader;
|
|
HWFILE hLibFile;
|
|
INT16 sLibraryID;
|
|
UINT16 uiLoop1;
|
|
UINT32 uiFileNum=0;
|
|
|
|
UINT32 uiNewFilePosition=0;
|
|
|
|
|
|
//Check if the file can be contained from an open library ( the path to the file a library path )
|
|
sLibraryID = GetLibraryIDFromFileName( pName );
|
|
|
|
if( sLibraryID != -1 )
|
|
{
|
|
//Check if another file is already open in the library ( report a warning if so )
|
|
|
|
// if( gFileDataBase.pLibraries[ sLibraryID ].fAnotherFileAlreadyOpenedLibrary )
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].uiIdOfOtherFileAlreadyOpenedLibrary != 0 )
|
|
{
|
|
// Temp removed
|
|
// FastDebugMsg(String("\n*******\nOpenFileFromLibrary(): Warning!: Trying to load file '%s' from the library '%s' which already has a file open\n", pName, gGameLibaries[ sLibraryID ].sLibraryName ) );
|
|
// FastDebugMsg(String("\n*******\nOpenFileFromLibrary(): Warning!: Trying to load file '%s' from the library '%s' which already has a file open ( file open is '%s')\n", pName, gGameLibaries[ sLibraryID ].sLibraryName, gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ gFileDataBase.pLibraries[ sLibraryID ].uiIdOfOtherFileAlreadyOpenedLibrary ].pFileHeader->pFileName ) );
|
|
}
|
|
|
|
//check if the file is already open
|
|
if( CheckIfFileIsAlreadyOpen( pName, sLibraryID ) )
|
|
return( 0 );
|
|
|
|
//if the file is in a library, get the file
|
|
if( GetFileHeaderFromLibrary( sLibraryID, pName, &pFileHeader ) )
|
|
{
|
|
//increment the number of open files
|
|
gFileDataBase.pLibraries[ sLibraryID ].iNumFilesOpen ++;
|
|
|
|
//if there isnt enough space to put the file, realloc more space
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].iNumFilesOpen >= gFileDataBase.pLibraries[ sLibraryID ].iSizeOfOpenFileArray )
|
|
{
|
|
FileOpenStruct *pOpenFiles;
|
|
|
|
//reallocate more space for the array
|
|
pOpenFiles = (FileOpenStruct *) MemRealloc( gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles,
|
|
gFileDataBase.pLibraries[ sLibraryID ].iSizeOfOpenFileArray + NUM_FILES_TO_ADD_AT_A_TIME );
|
|
|
|
if( !pOpenFiles )
|
|
return( 0 );
|
|
|
|
//increment the number of open files that we can have open
|
|
gFileDataBase.pLibraries[ sLibraryID ].iSizeOfOpenFileArray += NUM_FILES_TO_ADD_AT_A_TIME;
|
|
|
|
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles = pOpenFiles;
|
|
}
|
|
|
|
//loop through to find a new spot in the array
|
|
uiFileNum = 0;
|
|
for( uiLoop1=1; uiLoop1 < gFileDataBase.pLibraries[ sLibraryID ].iSizeOfOpenFileArray; uiLoop1++)
|
|
{
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiLoop1 ].uiFileID == 0 )
|
|
{
|
|
uiFileNum = uiLoop1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//if for some reason we couldnt find a spot, return an error
|
|
if( uiFileNum == 0 )
|
|
return( 0 );
|
|
|
|
//Create a library handle for the new file
|
|
hLibFile = CreateLibraryFileHandle( sLibraryID, uiFileNum );
|
|
|
|
//Set the current file data into the array of open files
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].uiFileID = hLibFile;
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].uiFilePosInFile = 0;
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].pFileHeader = pFileHeader;
|
|
|
|
//Save the current file position in the library
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].uiActualPositionInLibrary = SetFilePointer( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, 0, NULL, FILE_CURRENT );
|
|
|
|
//Set the file position in the library to the begining of the 'file' in the library
|
|
uiNewFilePosition = SetFilePointer( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].pFileHeader->uiFileOffset, NULL, FILE_BEGIN );
|
|
|
|
uiNewFilePosition = GetFileSize( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, NULL );
|
|
|
|
}
|
|
else
|
|
{
|
|
// Failed to find the file in a library
|
|
return( 0 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Library is not open, or doesnt exist
|
|
return( 0 );
|
|
}
|
|
|
|
//Set the fact the a file is currently open in the library
|
|
// gFileDataBase.pLibraries[ sLibraryID ].fAnotherFileAlreadyOpenedLibrary = TRUE;
|
|
gFileDataBase.pLibraries[ sLibraryID ].uiIdOfOtherFileAlreadyOpenedLibrary = uiFileNum;
|
|
|
|
return( hLibFile );
|
|
}
|
|
|
|
|
|
|
|
|
|
HWFILE CreateLibraryFileHandle( INT16 sLibraryID, UINT32 uiFileNum )
|
|
{
|
|
HWFILE hLibFile;
|
|
|
|
|
|
hLibFile = uiFileNum;
|
|
hLibFile |= DB_ADD_LIBRARY_ID( sLibraryID );
|
|
|
|
return( hLibFile );
|
|
}
|
|
|
|
|
|
HWFILE CreateRealFileHandle( HANDLE hFile )
|
|
{
|
|
HWFILE hLibFile;
|
|
INT32 iLoop1;
|
|
UINT32 uiFileNum=0;
|
|
UINT32 uiSize;
|
|
|
|
//if there isnt enough space to put the file, realloc more space
|
|
if( gFileDataBase.RealFiles.iNumFilesOpen >= ( gFileDataBase.RealFiles.iSizeOfOpenFileArray -1 ) )
|
|
{
|
|
uiSize = ( gFileDataBase.RealFiles.iSizeOfOpenFileArray + NUM_FILES_TO_ADD_AT_A_TIME ) * sizeof( RealFileOpenStruct );
|
|
|
|
gFileDataBase.RealFiles.pRealFilesOpen = (RealFileOpenStruct *) MemRealloc( gFileDataBase.RealFiles.pRealFilesOpen, uiSize );
|
|
CHECKF( gFileDataBase.RealFiles.pRealFilesOpen );
|
|
|
|
//Clear out the new part of the array
|
|
memset( &gFileDataBase.RealFiles.pRealFilesOpen[ gFileDataBase.RealFiles.iSizeOfOpenFileArray ], 0, ( NUM_FILES_TO_ADD_AT_A_TIME * sizeof( RealFileOpenStruct ) ) );
|
|
|
|
gFileDataBase.RealFiles.iSizeOfOpenFileArray += NUM_FILES_TO_ADD_AT_A_TIME;
|
|
}
|
|
|
|
|
|
//loop through to find a new spot in the array
|
|
uiFileNum = 0;
|
|
for( iLoop1=1; iLoop1 < gFileDataBase.RealFiles.iSizeOfOpenFileArray; iLoop1++)
|
|
{
|
|
if( gFileDataBase.RealFiles.pRealFilesOpen[ iLoop1 ].uiFileID == 0 )
|
|
{
|
|
uiFileNum = iLoop1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//if for some reason we couldnt find a spot, return an error
|
|
if( uiFileNum == 0 )
|
|
return( 0 );
|
|
|
|
hLibFile = uiFileNum;
|
|
hLibFile |= DB_ADD_LIBRARY_ID( REAL_FILE_LIBRARY_ID );
|
|
|
|
gFileDataBase.RealFiles.pRealFilesOpen[ iLoop1 ].uiFileID = hLibFile;
|
|
gFileDataBase.RealFiles.pRealFilesOpen[ iLoop1 ].hRealFileHandle = hFile;
|
|
|
|
gFileDataBase.RealFiles.iNumFilesOpen++;
|
|
|
|
return( hLibFile );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN GetLibraryAndFileIDFromLibraryFileHandle( HWFILE hlibFile, INT16 *pLibraryID, UINT32 *pFileNum )
|
|
{
|
|
*pFileNum = DB_EXTRACT_FILE_ID( hlibFile );
|
|
*pLibraryID = (UINT16)DB_EXTRACT_LIBRARY( hlibFile );
|
|
|
|
//TEST: qq
|
|
/* if( *pLibraryID == LIBRARY_SOUNDS )
|
|
{
|
|
int q=5;
|
|
}
|
|
*/
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// Close an individual file that is contained in the library
|
|
//
|
|
//************************************************************************
|
|
|
|
|
|
|
|
BOOLEAN CloseLibraryFile( INT16 sLibraryID, UINT32 uiFileID )
|
|
{
|
|
if( IsLibraryOpened( sLibraryID ) )
|
|
{
|
|
//if the uiFileID is invalid
|
|
if( (uiFileID >= (UINT32)gFileDataBase.pLibraries[ sLibraryID ].iSizeOfOpenFileArray ) )
|
|
return( FALSE );
|
|
|
|
//if the file is not opened, dont close it
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileID ].uiFileID != 0 )
|
|
{
|
|
//reset the variables
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileID ].uiFileID = 0;
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileID ].uiFilePosInFile = 0;
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileID ].pFileHeader = NULL;
|
|
|
|
//reset the libraries file pointer to the positon it was in prior to opening the current file
|
|
SetFilePointer( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileID ].uiActualPositionInLibrary, NULL, FILE_CURRENT);
|
|
|
|
//decrement the number of files that are open
|
|
gFileDataBase.pLibraries[ sLibraryID ].iNumFilesOpen--;
|
|
|
|
// Reset the fact that a file is accessing the library
|
|
// gFileDataBase.pLibraries[ sLibraryID ].fAnotherFileAlreadyOpenedLibrary = FALSE;
|
|
gFileDataBase.pLibraries[ sLibraryID ].uiIdOfOtherFileAlreadyOpenedLibrary = 0;
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN LibraryFileSeek( INT16 sLibraryID, UINT32 uiFileNum, UINT32 uiDistance, UINT8 uiHowToSeek )
|
|
{
|
|
UINT32 uiCurPos, uiSize;
|
|
|
|
//if the library is not open, return an error
|
|
if( !IsLibraryOpened( sLibraryID ) )
|
|
return( FALSE );
|
|
|
|
uiCurPos = gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].uiFilePosInFile;
|
|
uiSize = gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].pFileHeader->uiFileLength;
|
|
|
|
|
|
if ( uiHowToSeek == FILE_SEEK_FROM_START )
|
|
uiCurPos = uiDistance;
|
|
else if ( uiHowToSeek == FILE_SEEK_FROM_END )
|
|
uiCurPos = uiSize - uiDistance;
|
|
else if ( uiHowToSeek == FILE_SEEK_FROM_CURRENT )
|
|
uiCurPos += uiDistance;
|
|
else
|
|
return(FALSE);
|
|
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].uiFilePosInFile = uiCurPos;
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// OpenLibrary() Opens a library from the 'array' of library names
|
|
// that was passd in at game initialization. Pass in an enum for the
|
|
// library.
|
|
//
|
|
//************************************************************************
|
|
|
|
BOOLEAN OpenLibrary( INT16 sLibraryID )
|
|
{
|
|
//if the library is already opened, report an error
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].fLibraryOpen )
|
|
return( FALSE );
|
|
|
|
//if we are trying to do something with an invalid library id
|
|
if( sLibraryID >= gFileDataBase.usNumberOfLibraries )
|
|
return( FALSE );
|
|
|
|
|
|
//if we cant open the library
|
|
if( !InitializeLibrary( gGameLibaries[ sLibraryID ].sLibraryName, &gFileDataBase.pLibraries[ sLibraryID ], gGameLibaries[ sLibraryID ].fOnCDrom ) )
|
|
return( FALSE );
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN CloseLibrary( INT16 sLibraryID )
|
|
{
|
|
UINT32 uiLoop1;
|
|
|
|
//if the library isnt loaded, dont close it
|
|
if( !IsLibraryOpened( sLibraryID ) )
|
|
return( FALSE );
|
|
|
|
#ifdef JA2TESTVERSION
|
|
FastDebugMsg( String("ShutDownFileDatabase( ): %d bytes of ram used for the Library #%3d, path '%s', in the File Database System\n", gFileDataBase.pLibraries[ sLibraryID ].uiTotalMemoryAllocatedForLibrary, sLibraryID, gFileDataBase.pLibraries[ sLibraryID ].sLibraryPath ));
|
|
gFileDataBase.pLibraries[ sLibraryID ].uiTotalMemoryAllocatedForLibrary = 0;
|
|
#endif
|
|
|
|
//if there are any open files, loop through the library and close down whatever file is still open
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].iNumFilesOpen )
|
|
{
|
|
//loop though the array of open files to see if any are still open
|
|
for( uiLoop1=0; uiLoop1<( UINT32 )gFileDataBase.pLibraries[ sLibraryID ].usNumberOfEntries; uiLoop1++)
|
|
{
|
|
if( CheckIfFileIsAlreadyOpen( gFileDataBase.pLibraries[ sLibraryID ].pFileHeader[ uiLoop1 ].pFileName, sLibraryID ) )
|
|
{
|
|
FastDebugMsg( String("CloseLibrary(): ERROR: %s library file id still exists, wasnt closed, closing now.", gFileDataBase.pLibraries[ sLibraryID ].pFileHeader[ uiLoop1 ].pFileName ) );
|
|
CloseLibraryFile( sLibraryID, uiLoop1 );
|
|
|
|
// Removed because the memory gets freed in the next for loop. Would only enter here if files were still open
|
|
// gFileDataBase.pLibraries[ sLibraryID ].pFileHeader[ uiLoop1 ].pFileName = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Free up the memory used for each file name
|
|
for( uiLoop1=0; uiLoop1<gFileDataBase.pLibraries[ sLibraryID ].usNumberOfEntries; uiLoop1++)
|
|
{
|
|
MemFree( gFileDataBase.pLibraries[ sLibraryID ].pFileHeader[ uiLoop1 ].pFileName );
|
|
gFileDataBase.pLibraries[ sLibraryID ].pFileHeader[ uiLoop1 ].pFileName = NULL;
|
|
}
|
|
|
|
//Free up the memory needed for the Library File Headers
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].pFileHeader )
|
|
{
|
|
MemFree( gFileDataBase.pLibraries[ sLibraryID ].pFileHeader );
|
|
gFileDataBase.pLibraries[ sLibraryID ].pFileHeader = NULL;
|
|
}
|
|
|
|
//Free up the memory used for the library name
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].sLibraryPath )
|
|
{
|
|
MemFree( gFileDataBase.pLibraries[ sLibraryID ].sLibraryPath );
|
|
gFileDataBase.pLibraries[ sLibraryID ].sLibraryPath = NULL;
|
|
}
|
|
|
|
//Free up the space requiered for the open files array
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles )
|
|
{
|
|
MemFree( gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles );
|
|
gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles = NULL;
|
|
}
|
|
|
|
//set that the library isnt open
|
|
gFileDataBase.pLibraries[ sLibraryID ].fLibraryOpen = FALSE;
|
|
|
|
//close the file ( note libraries are to be closed by the Windows close function )
|
|
CloseHandle( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle );
|
|
|
|
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN IsLibraryOpened( INT16 sLibraryID )
|
|
{
|
|
//if the database is not initialized
|
|
if( !gFileDataBase.fInitialized )
|
|
return( FALSE );
|
|
|
|
//if we are trying to do something with an invalid library id
|
|
if( sLibraryID >= gFileDataBase.usNumberOfLibraries )
|
|
return( FALSE );
|
|
|
|
//if the library is opened
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].fLibraryOpen )
|
|
return( TRUE );
|
|
else
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN CheckIfFileIsAlreadyOpen( STR pFileName, INT16 sLibraryID )
|
|
{
|
|
UINT16 usLoop1=0;
|
|
|
|
CHAR8 sName[ 60 ];
|
|
CHAR8 sPath[ 90 ];
|
|
CHAR8 sDrive[ 60 ];
|
|
CHAR8 sExt[ 6 ];
|
|
|
|
CHAR8 sTempName[ 70 ];
|
|
|
|
_splitpath( pFileName, sDrive, sPath, sName, sExt);
|
|
|
|
strcpy( sTempName, sName );
|
|
strcat( sTempName, sExt );
|
|
|
|
//loop through all the open files to see if 'new' file to open is already open
|
|
for( usLoop1=1; usLoop1 < gFileDataBase.pLibraries[ sLibraryID ].iSizeOfOpenFileArray ; usLoop1++ )
|
|
{
|
|
//check if the file is open
|
|
if( gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ usLoop1].uiFileID != 0 )
|
|
{
|
|
//Check if the file already exists
|
|
if( _stricmp( sTempName, gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ usLoop1].pFileHeader->pFileName ) == 0 )
|
|
return( TRUE );
|
|
}
|
|
}
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
BOOLEAN GetLibraryFileTime( INT16 sLibraryID, UINT32 uiFileNum, SGP_FILETIME *pLastWriteTime )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
DIRENTRY *pDirEntry;
|
|
LIBHEADER LibFileHeader;
|
|
// UINT32 cnt;
|
|
INT32 iFilePos=0;
|
|
|
|
DIRENTRY **ppDirEntry;
|
|
|
|
DIRENTRY *pAllEntries;
|
|
|
|
|
|
memset( pLastWriteTime, 0, sizeof( SGP_FILETIME ) );
|
|
|
|
SetFilePointer( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, 0, NULL, FILE_BEGIN );
|
|
|
|
// Read in the library header ( at the begining of the library )
|
|
if( !ReadFile( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, &LibFileHeader, sizeof( LIBHEADER ), (LPDWORD) &uiNumBytesRead, NULL ) )
|
|
return( FALSE );
|
|
if( uiNumBytesRead != sizeof( LIBHEADER ) )
|
|
{
|
|
//Error Reading the file database header.
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
//If the file number is greater then the number in the lirary, return false
|
|
if( uiFileNum >= (UINT32)LibFileHeader.iEntries )
|
|
return( FALSE );
|
|
|
|
pAllEntries = (DIRENTRY *) MemAlloc( sizeof( DIRENTRY ) * LibFileHeader.iEntries );
|
|
if( pAllEntries == NULL )
|
|
return( FALSE );
|
|
memset( pAllEntries, 0, sizeof( DIRENTRY ) );
|
|
|
|
|
|
|
|
iFilePos = -( LibFileHeader.iEntries * (INT32)sizeof(DIRENTRY) );
|
|
|
|
//set the file pointer to the right location
|
|
SetFilePointer( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, iFilePos, NULL, FILE_END );
|
|
|
|
// Read in the library header ( at the begining of the library )
|
|
if( !ReadFile( gFileDataBase.pLibraries[ sLibraryID ].hLibraryHandle, pAllEntries, ( sizeof( DIRENTRY ) * LibFileHeader.iEntries ), (LPDWORD) &uiNumBytesRead, NULL ) )
|
|
return( FALSE );
|
|
if( uiNumBytesRead != ( sizeof( DIRENTRY ) * LibFileHeader.iEntries ) )
|
|
{
|
|
//Error Reading the file database header.
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
|
|
/* try to find the filename using a binary search algorithm: */
|
|
ppDirEntry = (DIRENTRY **) bsearch( gFileDataBase.pLibraries[ sLibraryID ].pOpenFiles[ uiFileNum ].pFileHeader->pFileName,
|
|
(DIRENTRY *) pAllEntries,
|
|
LibFileHeader.iEntries,
|
|
sizeof( DIRENTRY ), (int (*)(const void*, const void*))CompareDirEntryFileNames );
|
|
|
|
if( ppDirEntry )
|
|
pDirEntry = ( DIRENTRY * ) ppDirEntry;
|
|
else
|
|
return( FALSE );
|
|
|
|
//Copy the dir entry time over to the passed in time
|
|
memcpy( pLastWriteTime, &pDirEntry->sFileTime, sizeof( SGP_FILETIME ) );
|
|
|
|
|
|
MemFree( pAllEntries );
|
|
pAllEntries = NULL;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
//************************************************************************
|
|
//
|
|
// CompareFileNames() gets called by the binary search function.
|
|
//
|
|
//************************************************************************
|
|
|
|
INT32 CompareDirEntryFileNames( CHAR8 *arg1[], DIRENTRY **arg2 )
|
|
{
|
|
CHAR8 sSearchKey[ FILENAME_SIZE ];
|
|
CHAR8 sFileNameWithPath[ FILENAME_SIZE ];
|
|
DIRENTRY *TempDirEntry;
|
|
|
|
TempDirEntry = ( DIRENTRY * ) arg2;
|
|
|
|
sprintf( sSearchKey, "%s", arg1); // FIXME: arg1 must be a string pointer
|
|
|
|
sprintf( sFileNameWithPath, "%s", TempDirEntry->sFileName );
|
|
|
|
/* Compare all of both strings: */
|
|
return _stricmp( sSearchKey, sFileNameWithPath );
|
|
}
|
|
|