mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6102 3b4a5df2-a311-0410-b5c6-a8a6f20db521
1122 lines
35 KiB
C++
1122 lines
35 KiB
C++
#ifdef JA2_PRECOMPILED_HEADERS
|
|
#include "JA2 SGP ALL.H"
|
|
#elif defined( WIZ8_PRECOMPILED_HEADERS )
|
|
#include "WIZ8 SGP ALL.H"
|
|
#else
|
|
#include "Types.h"
|
|
#include "windows.h"
|
|
#include "FileMan.h"
|
|
#include "LibraryDataBase.h"
|
|
#include "MemMan.h"
|
|
#include "stdio.h"
|
|
#include "WCheck.h"
|
|
#include "Debug.h"
|
|
|
|
#if defined(JA2) || defined( UTIL )
|
|
#include "video.h"
|
|
#else
|
|
#include "video2.h"
|
|
#endif
|
|
#endif
|
|
|
|
//NUMBER_OF_LIBRARIES
|
|
#ifdef JA2
|
|
#include "Ja2 Libs.h"
|
|
#include "GameSettings.h"
|
|
#elif defined(UTIL)
|
|
LibraryInitHeader gGameLibaries[ ] = { 0 };
|
|
#else
|
|
// We link it as an .obj file
|
|
// #include "WizLibs.c"
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//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;
|
|
|
|
#ifdef JA2
|
|
GetCDLocation( );
|
|
#else
|
|
gzCdDirectory[ 0 ] = '.';
|
|
#endif
|
|
|
|
//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 );
|
|
}
|
|
|