📄 resmgr.c
字号:
GLOBAL_CURRENT_PATH[ _MAX_PATH ];
int
RESMGR_INIT = FALSE;
LIST
* GLOBAL_PATH_LIST = NULL;
DEVICE_ENTRY
* RES_DEVICES = NULL;
int
GLOBAL_INIT_DRIVE;
int
GLOBAL_CURRENT_DRIVE;
int
GLOBAL_CURRENT_CD;
int
GLOBAL_VOLUME_MASK = 0; /* which drive volumes are available */
int
GLOBAL_SEARCH_INDEX = 0;
int
GLOBAL_CD_DEVICE;
int
RES_DEBUG_ERRNO; /* the equivalent of an 'errno' */
static char resmgr_version[] = "[Version] ResMgr version 2.0";
static HWND RES_GLOBAL_HWND;
/* ----------------------------------------------------------------------
L O C A L P R O T O T Y P E S
---------------------------------------------------------------------- */
/* ---- ASYNCH I/O ---- */
void
asynch_write( void * thread_data ), /* thread function to handle asynch writes */
asynch_read( void * thread_data ); /* thread function to handle asynch reads */
/* ---- HASH FUNCTIONS ---- */
int
hash( const char * string, int size ); /* hash function */
int
hash_resize( HASH_TABLE * hsh ), /* dynamically resize a hash table */
hash_delete( HASH_ENTRY * entry, HASH_TABLE * hsh ); /* delete an entry from a hash table */
void
hash_destroy( HASH_TABLE * hsh ), /* destroy a hash table */
// hash_purge( HASH_TABLE * hsh, char * archive, char * volume, char * directory, char * name ); /* purge hash entries */
hash_purge( HASH_TABLE * hsh, const char * archive, const char * volume, const int * directory, const char * name ); /* purge hash entries */
HASH_TABLE
* hash_create( int size, char * name ); /* create a new hash table */
HASH_ENTRY
* hash_find( const char * name, HASH_TABLE * hsh ), /* find an entry within a hash table */
* hash_add( struct _finddata_t * data, HASH_TABLE * hsh ), /* add an entry to a hash table */
* hash_find_table( const char * name, HASH_TABLE ** table ); /* find an entry within many tables */
char
* hash_strcpy( HASH_TABLE * hsh, char * string ); /* strcpy that uses the hash table string pool */
/* ---- MISCELLANEOUS ---- */
int
get_handle( void ); /* return an available file handle */
void
split_path( const char * path, char * filename, char * dirpath ), /* cut a path string in two */
shut_down( void ); /* release allocations & reset Resource Mgr. */
char
* res_fullpath( char * abs_buffer, const char * rel_buffer, int maxlen );
void
res_detach_ex( ARCHIVE * arc ); /* allows func ptr to be passed to LIST_DESTROY */
void
sort_path( void ); /* forces cd-based paths to the bottom of the
search path */
int
get_dir_index( char * path );
/* From unzip.cpp */
extern
ARCHIVE
* archive_create( const char * attach_point, const char * filename, HASH_TABLE * table, int replace_flag );
extern
void
archive_delete( ARCHIVE * arc );
extern
int
process_local_file_hdr( local_file_hdr * lrec, char * buffer );
/* From inflate.cpp */
extern
int
inflate( COMPRESSED_FILE * cmp );
extern
int
inflate_free( void );
/* From MSVC CRT */
extern __cdecl _freebuf( FILE * );
extern __cdecl _fseek_lk( FILE *, long, int );
extern __cdecl _lseek_lk( int, long, int );
extern __cdecl _read_lk( int, char *, int );
/* ----------------------------------------------------------------------
----------------------------------------------------------------------
R E S O U R C E M A N A G E R * P U B L I C F U N C T I O N S
----------------------------------------------------------------------
---------------------------------------------------------------------- */
/* =======================================================
FUNCTION: ResInit
PURPOSE: Initialize the resource manager.
PARAMETERS: Parent window pointer
RETURNS: TRUE (pass) / FALSE (fail)
======================================================= */
RES_EXPORT int ResInit( HWND hwnd )
{
DEVICE_ENTRY * dev;
unsigned long length,
file;
int drive,
index;
char root[] = "C:\\"; /* root dir mask used to query devices */
char string[_MAX_PATH]; /* dummy string to fill out parameter list */
#if USE_SH_POOLS
if ( gResmgrMemPool == NULL )
{
gResmgrMemPool = MemPoolInit( 0 );
}
#endif
/* if the user is calling ResInit to re-initialize the resource manager
(since this is allowable), we need to free up any previous allocations. */
if( !RESMGR_INIT ) {
memset( GLOBAL_SEARCH_PATH, 0, sizeof(GLOBAL_SEARCH_PATH));
memset( RES_PATH, 0, sizeof(char*) * RES_DIR_LAST ); /* reset system paths */
GLOBAL_SEARCH_INDEX = 0;
}
shut_down();
RES_GLOBAL_HWND = hwnd;
#ifdef USE_SH_POOLS
FILE_HANDLES = (FILE_ENTRY *)MemAllocPtr( gResmgrMemPool, sizeof(FILE_ENTRY) * MAX_FILE_HANDLES, 0 );
#else
FILE_HANDLES = (FILE_ENTRY *)MemMalloc( sizeof(FILE_ENTRY) * MAX_FILE_HANDLES, "File handles" );
#endif
if( !FILE_HANDLES ) {
SAY_ERROR( RES_ERR_NO_MEMORY, "ResInit" );
return( FALSE );
}
memset( FILE_HANDLES, 0, sizeof( FILE_ENTRY ) * MAX_FILE_HANDLES );
for( index = 0; index < MAX_FILE_HANDLES; index++ )
FILE_HANDLES[ index ].os_handle = -1;
/* Save current drive. */
GLOBAL_INIT_DRIVE = _getdrive();
_getdcwd( GLOBAL_INIT_DRIVE, GLOBAL_INIT_PATH, _MAX_PATH );
RES_PATH[ RES_DIR_CURR ] = MemStrDup( GLOBAL_INIT_PATH );
/* -------------------------------------------------------------
Minimal Hardware Query
-------------------------------------------------------------
We determine all devices in the host machine and store the
volume name and volume serial number of the media that is
current mounted on that device. It there is ever a read
failure, or ResCheckMedia is explicitly called, we use
this information to determine if the end-user has swapped
the media without our knowledge.
Since it's not unimagineable that a user that is attached
to a LAN has all his drive letters mapped to network drives,
or, that under Win95 his CD letter is towards the high end
of the alphabet because of network drives, it is recommended
that you use 26 as the value for MAX_DEVICES. It's not
very much memory to give up, and you may be glad you did.
------------------------------------------------------------- */
GLOBAL_VOLUME_MASK = 0;
#if 0
for( drive = 1; drive <= MAX_DEVICES; drive++ ) {
/* If we can switch to the drive, it exists. - not if there is a seriously
damaged floppy in the drive, it is possible to crash VxD HFLOP just by
switching to the device. Of course, for this case, anytime the user
double clicks on the floppy icon from the desktop will also cause this
crash. Caveat Emptor. */
if( !_chdrive( drive ))
{
GLOBAL_VOLUME_MASK |= (1<<drive);
}
}
#endif
GLOBAL_VOLUME_MASK = GetLogicalDrives();
GLOBAL_VOLUME_MASK <<= 1; /* 1 is drive A in ResMgr, GetLogicalDrives returns A equals 0 */
#ifdef USE_SH_POOLS
RES_DEVICES = (DEVICE_ENTRY *)MemAllocPtr( gResmgrMemPool, MAX_DEVICES * sizeof( DEVICE_ENTRY ), 0 );
#else
RES_DEVICES = (DEVICE_ENTRY *)MemMalloc( MAX_DEVICES * sizeof( DEVICE_ENTRY ), "Devices" );
#endif
if( !RES_DEVICES ) {
SAY_ERROR( RES_ERR_NO_MEMORY, "ResInit" );
return( FALSE );
}
GLOBAL_CD_DEVICE = -1;
for( drive = 1; drive <= MAX_DEVICES; drive++ ) {
dev = &RES_DEVICES[drive-1];
if( GLOBAL_VOLUME_MASK & ((char)(1<<drive))) {
root[0] = (char)('A' + (drive-1));
/* According to Microsoft, most of the parameters to GetVolumeInformation are optional, however
this is not the case. It is possible to completely destroy the file system on a floppy
diskette by calling this seemingly innocuous function without all of the parameters! */
dev -> type = (char)(GetDriveType( root ));
dev -> letter = root[0];
if((dev -> type == DRIVE_FIXED) ||
(dev -> type == DRIVE_CDROM) ||
(dev -> type == DRIVE_RAMDISK)) {
GetVolumeInformation( root, dev -> name, 24, &dev -> serial, &length, &file, string, _MAX_PATH );
}
else {
strcpy( dev -> name, "unknown" );
dev -> serial = 0L;
}
/* Initialize default entries into the system path tables */
if(( dev -> type == DRIVE_CDROM ) && !RES_PATH[ RES_DIR_CD ])
{
GLOBAL_CD_DEVICE = drive - 1; /* NEED A BETTER WAY!! */
RES_PATH[ RES_DIR_CD ] = MemStrDup( root );
}
if((drive == 3) && (dev -> type == DRIVE_FIXED))
RES_PATH[ RES_DIR_HD ] = MemStrDup( root );
}
else {
dev -> type = -1;
dev -> letter = ASCII_DOT;
}
}
GetTempPath( _MAX_PATH, string );
RES_PATH[ RES_DIR_TEMP ] = MemStrDup( string );
#if (RES_MULTITHREAD)
if(!GLOCK) GLOCK = CREATE_LOCK("multithread");
#endif
IF_LOG( LOG( "Resource Manager Initialized.\n" ));
RESMGR_INIT = TRUE; /* reinitialize the statics */
return( TRUE );
}
/* =======================================================
FUNCTION: ResExit
PURPOSE: Shut down the resource manager.
PARAMETERS: None.
RETURNS: None.
======================================================= */
RES_EXPORT void ResExit( void )
{
IF_LOG( LOG( "Resource Manager Exiting.\n" ));
#if (RES_MULTITHREAD)
if(GLOCK) DESTROY_LOCK(GLOCK);
GLOCK = 0;
#endif
shut_down();
/* Restore original drive.*/
_chdrive( GLOBAL_INIT_DRIVE );
_chdir( GLOBAL_INIT_PATH );
#if( RES_DEBUG_VERSION )
if( RES_DEBUG_LOGGING )
ResDbgLogClose();
# if( USE_MEMMGR )
MemSanity();
# endif /* USE_MEMMGR */
#endif /*RES_DEBUG_VERSION */
#if USE_SH_POOLS
if ( gResmgrMemPool != NULL )
{
MemPoolFree( gResmgrMemPool );
gResmgrMemPool = NULL;
}
#endif
}
/* =======================================================
FUNCTION: ResMountCD
PURPOSE: Mount a cd. If there is already a mounted
disc, call the user callback and allow
the user to resynch to the current cd.
PARAMETERS: Parent window pointer
RETURNS: TRUE (pass) / FALSE (fail)
======================================================= */
RES_EXPORT int ResMountCD( int cd_number, int device )
{
int resynch = FALSE;
int retval = 1;
IF_LOG( LOG( "mounted cd %d\n", cd_number ));
#if( RES_DEBUG_PARAMS ) /* parameter checking only with debug version */
if( cd_number < 1 || cd_number > MAX_CD )
SHOULD_I_CALL_WITH( CALLBACK_UNKNOWN_CD, RES_ERR_ILLEGAL_CD, retval );
if( !retval )
return( FALSE );
#endif
GLOBAL_CD_DEVICE = device;
if( GLOBAL_CURRENT_CD != cd_number ) /* we need this flag later */
resynch = TRUE;
/* has the user installed a handler for swap cd? */
SHOULD_I_CALL_WITH( CALLBACK_SWAP_CD, cd_number, retval );
if( !retval )
return( FALSE );
GLOBAL_CURRENT_CD = cd_number;
/* has the user installed a handler for resynch to the new cd? */
SHOULD_I_CALL_WITH( CALLBACK_RESYNCH_CD, cd_number, retval );
if( !retval )
return( FALSE );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -