📄 resmgr.c
字号:
/* haven't failed so far... */
return( TRUE );
}
/* =======================================================
FUNCTION: ResDismountCD
PURPOSE: Dismount the currently mounted CD.
PARAMETERS: None.
RETURNS: TRUE (pass) / FALSE (fail)
======================================================= */
RES_EXPORT int ResDismountCD( void )
{
ARCHIVE * archive;
LIST * list;
int hit;
int dir; /* GFG change from char to int */
if( GLOBAL_CD_DEVICE == -1 )
return( FALSE );
if( ARCHIVE_LIST ) {
do {
hit = 0;
for( list = ARCHIVE_LIST; list; list = list -> next ) {
archive = (ARCHIVE *)list -> node;
if( archive -> volume == (char)GLOBAL_CD_DEVICE ) {
REQUEST_LOCK( archive -> lock );
dir = archive -> directory;
ResDetach( archive -> os_handle );
ResPurge( NULL, NULL, &dir, NULL );
hit = 1;
RELEASE_LOCK( archive -> lock );
break;
}
}
} while( hit );
}
ResPurge( NULL, (char *)&GLOBAL_CD_DEVICE, NULL, NULL );
return( TRUE );
}
/* =======================================================
FUNCTION: ResCheckMedia
PURPOSE: Determine if the end-user has swapped
the media for the specified device.
PARAMETERS: 0=A, 1=B, 2=C (drive ordinal).
RETURNS: 0 - yes they changed the media
1 - no they didn't change media
-1 - error reading device (probably in
process of changing media.
======================================================= */
RES_EXPORT int ResCheckMedia( int device )
{
int drive;
int retval = 1;
char root[] = "C:\\";
char name[26],
dummy[6]; /* possible bug in GetVolumeInformation */
unsigned long serial,
long1, /* possible bug in GetVolumeInformation */
long2; /* possible bug in GetVolumeInformation */
DEVICE_ENTRY * dev;
#if( RES_DEBUG_PARAMS )
if( device < 0 || device > MAX_DEVICES ) {
SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResCheckMedia (use ordinals)" );
return( -1 );
}
#endif /* RES_DEBUG_PARAMS */
drive = _getdrive();
if( _chdrive( device + 1 ))
return( -1 );
_chdrive(drive);
dev = &RES_DEVICES[ device ];
root[0] = (char)(device + 'A');
if( GetVolumeInformation( root, name, 22, &serial, &long1, &long2, dummy, 5 )) {
if( strcmp( name, dev -> name ) || ( serial != dev -> serial )) {
strcpy( dev -> name, name );
dev -> serial = serial;
IF_DEBUG( LOG( "Media has changed on volume %s\n", root ));
SHOULD_I_CALL_WITH( CALLBACK_SWAP_CD, GLOBAL_CURRENT_CD, retval );
return(0);
}
return(1);
}
IF_DEBUG( LOG( "Could not read media on volume %s\n", root ));
return( -1 );
}
/* =======================================================
FUNCTION: ResAttach
PURPOSE: Open an archive file (zip).
PARAMETERS: Directory to graft archive into, name of
an archive file, replace flag. If
attact_point is NULL, the archive is
grafted on to the current working
directory. If replace_flag is TRUE, any
files contained within the archive that
collide with files on the attach_point
are replaced (the matching files in the
archive file replace those at the
destination attach point) otherwise
the reverse is true (the files within
the archive take precedence).
RETURNS: Handle if sucessful, otherwise -1.
======================================================= */
RES_EXPORT int ResAttach( const char * attach_point_arg, const char * filename, int replace_flag )
{
ARCHIVE * archive;
HASH_TABLE * table = NULL;
char path[_MAX_PATH];
char attach_point_backup[_MAX_PATH];
char * attach_point;
int len, i;
struct _finddata_t info;
#if( !RES_USE_FLAT_MODEL )
HASH_ENTRY * entry;
#endif
// _getcwd(old_cwd,MAX_PATH);
if(attach_point_arg)
{
strcpy( attach_point_backup, attach_point_arg );
attach_point = attach_point_backup;
}
else
{
attach_point = NULL;
}
IF_LOG( LOG( "attach: %s %s\n", attach_point, filename ));
#if( RES_DEBUG_PARAMS )
if( !filename || (strlen(filename) > _MAX_FNAME)) {
SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResAttach" );
return( -1 );
}
#endif
if( !GLOBAL_HASH_TABLE ) {
SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResAttach" );
return( -1 );
}
if( !attach_point )
attach_point = GLOBAL_CURRENT_PATH;
#if( RES_COERCE_FILENAMES )
len = strlen( attach_point );
if( attach_point[len-1] != ASCII_BACKSLASH ) {
attach_point[len++] = ASCII_BACKSLASH;
attach_point[len] = 0x00;
}
res_fullpath( path, attach_point, _MAX_PATH );
attach_point = path;
#endif /* RES_COERCE_FILENAMES */
info.size = 0;
#if( !RES_USE_FLAT_MODEL )
entry = hash_find( attach_point, GLOBAL_HASH_TABLE );
/* I used to force you to use a directory already in
the resource manager for the attach point. Roger
Fujii asked for anything to be used (allowing you
to create artificial directories). If you want
the original functionality, define RES_ALLOW_ALIAS
to false. */
#if( !RES_ALLOW_ALIAS )
if( !entry ) {
SAY_ERROR( RES_ERR_PATH_NOT_FOUND, attach_point );
return( -1 );
}
#else
/* The attach point does not have to be either a directory -or-
an 'added' directory (a directory that has been incorporated
into the Resource Manager via ResAddPath or ResCreatePath */
if( !entry ) {
#if( RES_DEBUG_VERSION )
if( GLOBAL_SEARCH_INDEX >= (MAX_DIRECTORIES-1)) {
assert(!"Exceeded MAX_DIRECTORIES as defined in omni.h");
// SAY_ERROR( RES_ERR_TOO_MANY_DIRECTORIES, "ResAddPath" );
return( FALSE );
}
#endif
table = hash_create( ARCHIVE_TABLE_SIZE, attach_point );
strcpy( info.name, attach_point ); /* insert a dummy entry into the global hash table */
info.attrib = _A_SUBDIR | (unsigned int)FORCE_BIT;
info.time_create = 0;
info.time_access = 0;
info.size = 0;
entry = hash_add( &info, GLOBAL_HASH_TABLE );
if( !entry ) {
SAY_ERROR( RES_ERR_UNKNOWN, "ResAttach" );
return( -1 );
}
entry -> archive = -1; /* the actual directory existence should not be considered
as part of the archive. All of the contents found within
the directory are. This allows a hard disk based file to
override a zip archive */
entry -> volume = (char)(toupper(attach_point[0]) - 'A');
entry -> directory = GLOBAL_SEARCH_INDEX;
GLOBAL_SEARCH_PATH[ GLOBAL_SEARCH_INDEX++ ] = MemStrDup( attach_point );
GLOBAL_PATH_LIST = LIST_APPEND( GLOBAL_PATH_LIST, table );
strcpy( GLOBAL_CURRENT_PATH, attach_point );
entry -> dir = table;
}
#endif /* RES_ALLOW_ALIAS */
archive = archive_create( attach_point, filename, (HASH_TABLE *)entry -> dir, replace_flag );
#else /* RES_FLAT_MODEL */
archive = archive_create( attach_point, filename, GLOBAL_HASH_TABLE, replace_flag );
#endif /* RES_FLAT_MODEL */
if( !archive ) {
SAY_ERROR( RES_ERR_CANT_OPEN_ARCHIVE, filename );
return( -1 );
}
for( i=0; i<(GLOBAL_SEARCH_INDEX-1); i++ ) {
if( !stricmp( GLOBAL_SEARCH_PATH[i], attach_point )) {
// archive -> directory = (char)i; /* GFG */
archive -> directory = (char)(i); /* GFG */
break;
}
}
if( i == GLOBAL_SEARCH_INDEX )
DebugBreak();
ARCHIVE_LIST = LIST_APPEND( ARCHIVE_LIST, archive );
return( archive -> os_handle );
}
/* =======================================================
FUNCTION: ResDevice
PURPOSE: Returns information about a given drive.
PARAMETERS: Id of device to query.
RETURNS: TRUE (pass) / FALSE (fail).
======================================================= */
RES_EXPORT int ResDevice( int device_id, DEVICE_ENTRY * dev )
{
#if( RES_DEBUG_PARAMS )
if( device_id < 0 || device_id > MAX_DEVICES || !dev ) {
SAY_ERROR( RES_ERR_INCORRECT_PARAMETER, "ResDevice" );
return( FALSE );
}
#endif /* RES_DEBUG_PARAMS */
memcpy( dev, (void *)&RES_DEVICES[device_id], sizeof( DEVICE_ENTRY ));
return( TRUE );
}
/* =======================================================
FUNCTION: ResDetach
PURPOSE: Closes an open archive file (zip).
PARAMETERS: Handle of an opened archive file.
RETURNS: None.
======================================================= */
RES_EXPORT void ResDetach( int handle )
{
ARCHIVE * archive=NULL;
LIST * list=NULL;
#if( RES_DEBUG_PARAMS )
if( !ARCHIVE_LIST ) {
SAY_ERROR( RES_ERR_UNKNOWN_ARCHIVE, "ResDetach" );
return;
}
#endif /* RES_DEBUG_PARAMS */
/* using the handle, search the list for the structure */
for( list = ARCHIVE_LIST; list; list = list -> next ) {
archive = (ARCHIVE *)list -> node;
if( archive -> os_handle == handle )
break;
}
if( !list ) { /* couldn't find it, may already have been closed - or handle is incorrect */
SAY_ERROR( RES_ERR_UNKNOWN_ARCHIVE, "ResDetach" );
return;
}
IF_LOG( LOG( "detach: %s\n", archive -> name ));
REQUEST_LOCK( archive -> lock );
ResPurge((char *)&archive -> os_handle, NULL, NULL, NULL );
/* remove the archive from out list */
ARCHIVE_LIST = LIST_REMOVE( ARCHIVE_LIST, archive );
/* The inflation code builds a table of constant values for decompressing
files compressed with pkzip's FIXED compression mode. The tables are
dynamically created (if they don't already exist) when you decompress
data via that method. Therefore, we don't want to free it up until
all the zips are detached - then we might as well to reclaim memory */
if( !ARCHIVE_LIST )
inflate_free();
/* close the actual archive file */
_close( archive -> os_handle );
RELEASE_LOCK( archive -> lock );
DESTROY_LOCK( archive -> lock );
#ifdef USE_SH_POOLS
MemFreePtr( archive );
#else
MemFree( archive );
#endif
}
/* =======================================================
FUNCTION: ResOpenFile
PURPOSE: Open a file via the Resource Manager.
PARAMETERS: Filename, mode to open with.
Wildcards are not supported.
RETURNS: File int if sucessful, otherwise -1.
======================================================= */
RES_EXPORT int ResOpenFile( const char * name, int mode )
{
HASH_TABLE * table=NULL;
HASH_ENTRY * entry=NULL;
FILE_ENTRY * file=NULL;
LIST * list=NULL;
ARCHIVE * archive=NULL;
char dirpath[_MAX_PATH];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -