mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
filesystem: avoid scanning game directory as executable in FS_FindLibrary on Android, generic refactoring
This commit is contained in:
@@ -12,13 +12,10 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include ALLOCA_H
|
#include ALLOCA_H
|
||||||
#include "crtlib.h"
|
#include "crtlib.h"
|
||||||
#include "filesystem.h"
|
|
||||||
#include "filesystem_internal.h"
|
#include "filesystem_internal.h"
|
||||||
#include "VFileSystem009.h"
|
#include "VFileSystem009.h"
|
||||||
#include "common/com_strings.h"
|
#include "common/com_strings.h"
|
||||||
|
|||||||
@@ -1254,6 +1254,32 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo, qbo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
FS_PathExecFlag
|
||||||
|
|
||||||
|
guess if path is executable
|
||||||
|
only implemented for Android for now
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
static uint32_t FS_PathExecFlag( const char *dir )
|
||||||
|
{
|
||||||
|
#if XASH_ANDROID
|
||||||
|
// on Android, where directories usually lie outside of internal app directory
|
||||||
|
// we can't reliably load libraries from
|
||||||
|
//
|
||||||
|
// currently, launcher passes /data/... path as rodir where downloaded game libraries
|
||||||
|
// are stored in. Catch that and mark such path as executable
|
||||||
|
if( !Q_strncmp( dir, "/data/", 6 ))
|
||||||
|
return FS_EXEC_PATH;
|
||||||
|
return 0;
|
||||||
|
#else // !XASH_ANDROID
|
||||||
|
// FIXME: read noexec flag on *nix systems?
|
||||||
|
(void)dir;
|
||||||
|
return FS_EXEC_PATH;
|
||||||
|
#endif // !XASH_ANDROID
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
FS_AddGameHierarchy
|
FS_AddGameHierarchy
|
||||||
@@ -1261,9 +1287,8 @@ FS_AddGameHierarchy
|
|||||||
*/
|
*/
|
||||||
void FS_AddGameHierarchy( const char *dir, uint flags )
|
void FS_AddGameHierarchy( const char *dir, uint flags )
|
||||||
{
|
{
|
||||||
int i;
|
const qboolean is_game_dir = FBitSet( flags, FS_GAMEDIR_PATH );
|
||||||
qboolean isGameDir = flags & FS_GAMEDIR_PATH;
|
const uint32_t mount_flags = FBitSet( flags, FS_MOUNT_FLAGS );
|
||||||
char buf[MAX_VA_STRING];
|
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( dir ))
|
if( COM_StringEmptyOrNULL( dir ))
|
||||||
return;
|
return;
|
||||||
@@ -1274,7 +1299,7 @@ void FS_AddGameHierarchy( const char *dir, uint flags )
|
|||||||
|
|
||||||
// recursive gamedirs
|
// recursive gamedirs
|
||||||
// for example, czeror->czero->cstrike->valve
|
// for example, czeror->czero->cstrike->valve
|
||||||
for( i = 0; i < FI.numgames; i++ )
|
for( int i = 0; i < FI.numgames; i++ )
|
||||||
{
|
{
|
||||||
if( !Q_stricmp( FI.games[i]->gamefolder, dir ))
|
if( !Q_stricmp( FI.games[i]->gamefolder, dir ))
|
||||||
{
|
{
|
||||||
@@ -1299,55 +1324,67 @@ void FS_AddGameHierarchy( const char *dir, uint flags )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clear flags not applicable to searchpaths
|
||||||
|
ClearBits( flags, FS_MOUNT_FLAGS );
|
||||||
|
|
||||||
|
char buf[MAX_VA_STRING];
|
||||||
if( !COM_StringEmpty( fs_rodir ))
|
if( !COM_StringEmpty( fs_rodir ))
|
||||||
{
|
{
|
||||||
// append new flags to rodir, except FS_GAMEDIR_PATH and FS_CUSTOM_PATH
|
uint32_t new_flags = flags
|
||||||
uint new_flags = FS_NOWRITE_PATH | (flags & (~FS_GAMEDIR_PATH|FS_CUSTOM_PATH));
|
| FS_NOWRITE_PATH
|
||||||
if( isGameDir )
|
| ( is_game_dir ? FS_GAMERODIR_PATH : 0 )
|
||||||
SetBits( new_flags, FS_GAMERODIR_PATH );
|
| FS_PathExecFlag( fs_rodir );
|
||||||
|
|
||||||
|
// clear flags not applicable to read-only directory
|
||||||
|
ClearBits( new_flags, FS_GAMEDIR_PATH | FS_CUSTOM_PATH );
|
||||||
|
|
||||||
|
Q_snprintf( buf, sizeof( buf ), "%s/%s/", fs_rodir, dir );
|
||||||
|
|
||||||
FS_AllowDirectPaths( true );
|
FS_AllowDirectPaths( true );
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s/%s/", fs_rodir, dir );
|
|
||||||
FS_AddGameDirectory( buf, new_flags );
|
FS_AddGameDirectory( buf, new_flags );
|
||||||
FS_AllowDirectPaths( false );
|
FS_AllowDirectPaths( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isGameDir )
|
if( is_game_dir )
|
||||||
{
|
{
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s" DEFAULT_DOWNLOADED_DIRECTORY_SUFFIX "/", dir );
|
Q_snprintf( buf, sizeof( buf ), "%s" DEFAULT_DOWNLOADED_DIRECTORY_SUFFIX "/", dir );
|
||||||
FS_AddGameDirectory( buf, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_AddGameDirectory( buf, flags | FS_NOWRITE_PATH | FS_CUSTOM_PATH );
|
||||||
}
|
}
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s/", dir );
|
|
||||||
FS_AddGameDirectory( buf, flags );
|
|
||||||
|
|
||||||
if( FBitSet( flags, FS_MOUNT_HD ))
|
Q_snprintf( buf, sizeof( buf ), "%s/", dir );
|
||||||
|
FS_AddGameDirectory( buf, flags | FS_PathExecFlag( buf ) | FS_PathExecFlag( fs_rootdir ));
|
||||||
|
|
||||||
|
// paths after can only be addon paths
|
||||||
|
SetBits( flags, FS_NOWRITE_PATH | FS_CUSTOM_PATH );
|
||||||
|
|
||||||
|
if( FBitSet( mount_flags, FS_MOUNT_HD ))
|
||||||
{
|
{
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s_hd/", dir );
|
Q_snprintf( buf, sizeof( buf ), "%s_hd/", dir );
|
||||||
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_AddGameDirectory( buf, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FBitSet( flags, FS_MOUNT_ADDON ))
|
if( FBitSet( mount_flags, FS_MOUNT_ADDON ))
|
||||||
{
|
{
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s_addon/", dir );
|
Q_snprintf( buf, sizeof( buf ), "%s_addon/", dir );
|
||||||
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_AddGameDirectory( buf, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FBitSet( flags, FS_MOUNT_LV ))
|
if( FBitSet( mount_flags, FS_MOUNT_LV ))
|
||||||
{
|
{
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s_lv/", dir );
|
Q_snprintf( buf, sizeof( buf ), "%s_lv/", dir );
|
||||||
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_AddGameDirectory( buf, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FBitSet( flags, FS_MOUNT_L10N ) && !COM_StringEmpty( fs_language ) && Q_isalpha( fs_language ))
|
if( FBitSet( mount_flags, FS_MOUNT_L10N ))
|
||||||
{
|
{
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s_%s/", dir, fs_language );
|
Q_snprintf( buf, sizeof( buf ), "%s_%s/", dir, fs_language );
|
||||||
FS_AddGameDirectory( buf, flags|FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_AddGameDirectory( buf, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isGameDir )
|
if( is_game_dir )
|
||||||
{
|
{
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s/" DEFAULT_CUSTOM_DIRECTORY, dir );
|
Q_snprintf( buf, sizeof( buf ), "%s/" DEFAULT_CUSTOM_DIRECTORY, dir );
|
||||||
FS_AddGameDirectory( buf, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_AddGameDirectory( buf, flags );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1358,28 +1395,34 @@ FS_Rescan
|
|||||||
*/
|
*/
|
||||||
void FS_Rescan( uint32_t flags, const char *language )
|
void FS_Rescan( uint32_t flags, const char *language )
|
||||||
{
|
{
|
||||||
const char *str;
|
Con_Reportf( "%s( %s, 0x%x, %s )\n", __func__, GI->title, flags, language );
|
||||||
Con_Reportf( "%s( %s )\n", __func__, GI->title );
|
|
||||||
|
|
||||||
FS_ClearSearchPath();
|
FS_ClearSearchPath();
|
||||||
|
|
||||||
flags &= FS_MOUNT_HD|FS_MOUNT_LV|FS_MOUNT_ADDON|FS_MOUNT_L10N;
|
// don't let rescan set searchpath flags
|
||||||
|
flags = FBitSet( flags, FS_MOUNT_FLAGS );
|
||||||
|
|
||||||
if( FBitSet( flags, FS_MOUNT_L10N ))
|
if( FBitSet( flags, FS_MOUNT_L10N ) && !COM_StringEmpty( language ) && Q_isalpha( language ))
|
||||||
|
{
|
||||||
Q_strncpy( fs_language, language, sizeof( fs_language ));
|
Q_strncpy( fs_language, language, sizeof( fs_language ));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
fs_language[0] = 0;
|
fs_language[0] = 0;
|
||||||
|
ClearBits( flags, FS_MOUNT_L10N );
|
||||||
|
}
|
||||||
|
|
||||||
str = getenv( "XASH3D_EXTRAS_PAK1" );
|
const char *str = getenv( "XASH3D_EXTRAS_PAK1" );
|
||||||
if( !COM_StringEmptyOrNULL( str ))
|
if( !COM_StringEmptyOrNULL( str ))
|
||||||
FS_MountArchive_Fullpath( str, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_MountArchive_Fullpath( str, FS_NOWRITE_PATH | FS_CUSTOM_PATH );
|
||||||
|
|
||||||
str = getenv( "XASH3D_EXTRAS_PAK2" );
|
str = getenv( "XASH3D_EXTRAS_PAK2" );
|
||||||
if( !COM_StringEmptyOrNULL( str ))
|
if( !COM_StringEmptyOrNULL( str ))
|
||||||
FS_MountArchive_Fullpath( str, FS_NOWRITE_PATH|FS_CUSTOM_PATH );
|
FS_MountArchive_Fullpath( str, FS_NOWRITE_PATH | FS_CUSTOM_PATH );
|
||||||
|
|
||||||
if( Q_stricmp( GI->basedir, GI->gamefolder ))
|
if( Q_stricmp( GI->basedir, GI->gamefolder ))
|
||||||
FS_AddGameHierarchy( GI->basedir, flags );
|
FS_AddGameHierarchy( GI->basedir, flags );
|
||||||
|
|
||||||
if( Q_stricmp( GI->basedir, GI->falldir ) && Q_stricmp( GI->gamefolder, GI->falldir ))
|
if( Q_stricmp( GI->basedir, GI->falldir ) && Q_stricmp( GI->gamefolder, GI->falldir ))
|
||||||
FS_AddGameHierarchy( GI->falldir, flags );
|
FS_AddGameHierarchy( GI->falldir, flags );
|
||||||
|
|
||||||
@@ -1453,8 +1496,8 @@ return true if library is crypted
|
|||||||
*/
|
*/
|
||||||
static qboolean FS_CheckForCrypt( const char *dllname )
|
static qboolean FS_CheckForCrypt( const char *dllname )
|
||||||
{
|
{
|
||||||
file_t *f;
|
file_t *f;
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
// this encryption is specific to DLLs
|
// this encryption is specific to DLLs
|
||||||
if( Q_stricmp( COM_FileExtension( dllname ), "dll" ))
|
if( Q_stricmp( COM_FileExtension( dllname ), "dll" ))
|
||||||
@@ -1490,103 +1533,6 @@ static int FS_StripIdiotRelativePath( const char *dllname, const char *gamefolde
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
FS_FindLibrary
|
|
||||||
|
|
||||||
search for library, assume index is valid
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
static qboolean FS_FindLibrary( const char *dllname, qboolean directpath, fs_dllinfo_t *dllInfo )
|
|
||||||
{
|
|
||||||
string fixedname;
|
|
||||||
searchpath_t *search;
|
|
||||||
int index, start = 0, len;
|
|
||||||
|
|
||||||
// check for bad exports
|
|
||||||
if( COM_StringEmptyOrNULL( dllname ))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
FS_AllowDirectPaths( directpath );
|
|
||||||
|
|
||||||
// HACKHACK remove relative path to game folder
|
|
||||||
if( !Q_strnicmp( dllname, "..", 2 ))
|
|
||||||
{
|
|
||||||
// some modders put relative path to themselves???
|
|
||||||
len = FS_StripIdiotRelativePath( dllname, GI->gamefolder );
|
|
||||||
|
|
||||||
if( len == 0 ) // or put relative path to Half-Life game libs
|
|
||||||
len = FS_StripIdiotRelativePath( dllname, "valve" );
|
|
||||||
start += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_strnlwr( &dllname[start], dllInfo->shortPath, sizeof( dllInfo->shortPath )); // always in lower case (why?)
|
|
||||||
COM_FixSlashes( dllInfo->shortPath ); // replace all backward slashes
|
|
||||||
COM_DefaultExtension( dllInfo->shortPath, "."OS_LIB_EXT, sizeof( dllInfo->shortPath )); // apply ext if forget
|
|
||||||
|
|
||||||
search = FS_FindFile( dllInfo->shortPath, &index, fixedname, sizeof( fixedname ), false );
|
|
||||||
|
|
||||||
if( search )
|
|
||||||
{
|
|
||||||
Q_strncpy( dllInfo->shortPath, fixedname, sizeof( dllInfo->shortPath ));
|
|
||||||
}
|
|
||||||
else if( !directpath )
|
|
||||||
{
|
|
||||||
FS_AllowDirectPaths( false );
|
|
||||||
|
|
||||||
// trying check also 'bin' folder for indirect paths
|
|
||||||
search = FS_FindFile( dllname, &index, fixedname, sizeof( fixedname ), false );
|
|
||||||
if( !search )
|
|
||||||
return false; // unable to find
|
|
||||||
|
|
||||||
Q_strncpy( dllInfo->shortPath, fixedname, sizeof( dllInfo->shortPath ));
|
|
||||||
}
|
|
||||||
|
|
||||||
dllInfo->encrypted = dllInfo->custom_loader = false; // predict state
|
|
||||||
|
|
||||||
if( search && index >= 0 ) // when library is available through VFS
|
|
||||||
{
|
|
||||||
dllInfo->encrypted = FS_CheckForCrypt( dllInfo->shortPath );
|
|
||||||
|
|
||||||
if( search->type == SEARCHPATH_PLAIN ) // is it on the disk? (intentionally omit pk3dir here)
|
|
||||||
{
|
|
||||||
// NOTE: gamedll might resolve it's own path using dladdr() and expects absolute path
|
|
||||||
// NOTE: the only allowed case when searchpath is set by absolute path is the RoDir
|
|
||||||
// rather than figuring out whether path is absolute, just check if it matches
|
|
||||||
if( !COM_StringEmpty( fs_rodir ) && !Q_strnicmp( search->filename, fs_rodir, Q_strlen( fs_rodir )))
|
|
||||||
{
|
|
||||||
Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ), "%s%s", search->filename, dllInfo->shortPath );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ), "%s/%s%s", fs_rootdir, search->filename, dllInfo->shortPath );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ), "%s", dllInfo->shortPath );
|
|
||||||
Con_Printf( "%s%s: loading libraries from archives is %s\n",
|
|
||||||
#if XASH_WIN32 && XASH_X86 // a1ba: custom loader is non-portable (I just don't want to touch it)
|
|
||||||
S_WARN, __func__, "non portable and might fail on other platforms"
|
|
||||||
#else
|
|
||||||
S_ERROR, __func__, "unsupported on this platform"
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
dllInfo->custom_loader = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// NOTE: if search is NULL let OS to find the library
|
|
||||||
Q_strncpy( dllInfo->fullPath, dllInfo->shortPath, sizeof( dllInfo->fullPath ));
|
|
||||||
}
|
|
||||||
|
|
||||||
FS_AllowDirectPaths( false ); // always reset direct paths
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static poolhandle_t Mem_AllocPoolStub( const char *name, const char *filename, int fileline )
|
static poolhandle_t Mem_AllocPoolStub( const char *name, const char *filename, int fileline )
|
||||||
{
|
{
|
||||||
return (poolhandle_t)0xDEADC0DE;
|
return (poolhandle_t)0xDEADC0DE;
|
||||||
@@ -1726,9 +1672,10 @@ qboolean FS_InitStdio( qboolean unused_set_to_true, const char *rootdir, const c
|
|||||||
if( !COM_StringEmpty( fs_rodir ))
|
if( !COM_StringEmpty( fs_rodir ))
|
||||||
{
|
{
|
||||||
Q_snprintf( buf, sizeof( buf ), "%s/", fs_rodir );
|
Q_snprintf( buf, sizeof( buf ), "%s/", fs_rodir );
|
||||||
FS_AddGameDirectory( buf, FS_STATIC_PATH|FS_NOWRITE_PATH );
|
FS_AddGameDirectory( buf, FS_STATIC_PATH | FS_NOWRITE_PATH | FS_PathExecFlag( fs_rodir ));
|
||||||
}
|
}
|
||||||
FS_AddGameDirectory( "./", FS_STATIC_PATH );
|
|
||||||
|
FS_AddGameDirectory( "./", FS_STATIC_PATH | FS_PathExecFlag( fs_rootdir ));
|
||||||
|
|
||||||
// but scan rodir for games first
|
// but scan rodir for games first
|
||||||
if( !COM_StringEmpty( fs_rodir ))
|
if( !COM_StringEmpty( fs_rodir ))
|
||||||
@@ -2177,7 +2124,7 @@ Return the searchpath where the file was found (or NULL)
|
|||||||
and the file index in the package if relevant
|
and the file index in the package if relevant
|
||||||
====================
|
====================
|
||||||
*/
|
*/
|
||||||
searchpath_t *FS_FindFile( const char *name, int *index, char *fixedname, size_t len, qboolean gamedironly )
|
static searchpath_t *FS_FindFile( const char *name, int *index, char *fixedname, size_t len, uint32_t flags )
|
||||||
{
|
{
|
||||||
searchpath_t *search;
|
searchpath_t *search;
|
||||||
|
|
||||||
@@ -2186,7 +2133,7 @@ searchpath_t *FS_FindFile( const char *name, int *index, char *fixedname, size_t
|
|||||||
{
|
{
|
||||||
int pack_ind;
|
int pack_ind;
|
||||||
|
|
||||||
if( gamedironly & !FBitSet( search->flags, FS_GAMEDIRONLY_SEARCH_FLAGS ))
|
if( flags && !FBitSet( search->flags, flags ))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pack_ind = search->pfnFindFile( search, name, fixedname, len );
|
pack_ind = search->pfnFindFile( search, name, fixedname, len );
|
||||||
@@ -2245,6 +2192,103 @@ searchpath_t *FS_FindFile( const char *name, int *index, char *fixedname, size_t
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
FS_FindLibrary
|
||||||
|
|
||||||
|
search for library, assume index is valid
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
static qboolean FS_FindLibrary( const char *dllname, qboolean directpath, fs_dllinfo_t *dllInfo )
|
||||||
|
{
|
||||||
|
string fixedname;
|
||||||
|
searchpath_t *search;
|
||||||
|
int index, start = 0, len;
|
||||||
|
|
||||||
|
// check for bad exports
|
||||||
|
if( COM_StringEmptyOrNULL( dllname ))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FS_AllowDirectPaths( directpath );
|
||||||
|
|
||||||
|
// HACKHACK remove relative path to game folder
|
||||||
|
if( !Q_strnicmp( dllname, "..", 2 ))
|
||||||
|
{
|
||||||
|
// some modders put relative path to themselves???
|
||||||
|
len = FS_StripIdiotRelativePath( dllname, GI->gamefolder );
|
||||||
|
|
||||||
|
if( len == 0 ) // or put relative path to Half-Life game libs
|
||||||
|
len = FS_StripIdiotRelativePath( dllname, "valve" );
|
||||||
|
start += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_strnlwr( &dllname[start], dllInfo->shortPath, sizeof( dllInfo->shortPath )); // always in lower case (why?)
|
||||||
|
COM_FixSlashes( dllInfo->shortPath ); // replace all backward slashes
|
||||||
|
COM_DefaultExtension( dllInfo->shortPath, "."OS_LIB_EXT, sizeof( dllInfo->shortPath )); // apply ext if forget
|
||||||
|
|
||||||
|
search = FS_FindFile( dllInfo->shortPath, &index, fixedname, sizeof( fixedname ), FS_EXEC_PATH );
|
||||||
|
|
||||||
|
if( search )
|
||||||
|
{
|
||||||
|
Q_strncpy( dllInfo->shortPath, fixedname, sizeof( dllInfo->shortPath ));
|
||||||
|
}
|
||||||
|
else if( !directpath )
|
||||||
|
{
|
||||||
|
FS_AllowDirectPaths( false );
|
||||||
|
|
||||||
|
// trying check also 'bin' folder for indirect paths
|
||||||
|
search = FS_FindFile( dllname, &index, fixedname, sizeof( fixedname ), FS_EXEC_PATH );
|
||||||
|
if( !search )
|
||||||
|
return false; // unable to find
|
||||||
|
|
||||||
|
Q_strncpy( dllInfo->shortPath, fixedname, sizeof( dllInfo->shortPath ));
|
||||||
|
}
|
||||||
|
|
||||||
|
dllInfo->encrypted = dllInfo->custom_loader = false; // predict state
|
||||||
|
|
||||||
|
if( search && index >= 0 ) // when library is available through VFS
|
||||||
|
{
|
||||||
|
dllInfo->encrypted = FS_CheckForCrypt( dllInfo->shortPath );
|
||||||
|
|
||||||
|
if( search->type == SEARCHPATH_PLAIN ) // is it on the disk? (intentionally omit pk3dir here)
|
||||||
|
{
|
||||||
|
// NOTE: gamedll might resolve it's own path using dladdr() and expects absolute path
|
||||||
|
// NOTE: the only allowed case when searchpath is set by absolute path is the RoDir
|
||||||
|
// rather than figuring out whether path is absolute, just check if it matches
|
||||||
|
if( !COM_StringEmpty( fs_rodir ) && !Q_strnicmp( search->filename, fs_rodir, Q_strlen( fs_rodir )))
|
||||||
|
{
|
||||||
|
Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ), "%s%s", search->filename, dllInfo->shortPath );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ), "%s/%s%s", fs_rootdir, search->filename, dllInfo->shortPath );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ), "%s", dllInfo->shortPath );
|
||||||
|
Con_Printf( "%s%s: loading libraries from archives is %s\n",
|
||||||
|
#if XASH_WIN32 && XASH_X86 // a1ba: custom loader is non-portable (I just don't want to touch it)
|
||||||
|
S_WARN, __func__, "non portable and might fail on other platforms"
|
||||||
|
#else
|
||||||
|
S_ERROR, __func__, "unsupported on this platform"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
dllInfo->custom_loader = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// NOTE: if search is NULL let OS to find the library
|
||||||
|
Q_strncpy( dllInfo->fullPath, dllInfo->shortPath, sizeof( dllInfo->fullPath ));
|
||||||
|
}
|
||||||
|
|
||||||
|
FS_AllowDirectPaths( false ); // always reset direct paths
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========================
|
===========================
|
||||||
FS_FullPathToRelativePath
|
FS_FullPathToRelativePath
|
||||||
@@ -2286,7 +2330,7 @@ file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedi
|
|||||||
char netpath[MAX_SYSPATH];
|
char netpath[MAX_SYSPATH];
|
||||||
int pack_ind;
|
int pack_ind;
|
||||||
|
|
||||||
search = FS_FindFile( filename, &pack_ind, netpath, sizeof( netpath ), gamedironly );
|
search = FS_FindFile( filename, &pack_ind, netpath, sizeof( netpath ), gamedironly ? FS_GAMEDIRONLY_SEARCH_FLAGS : 0 );
|
||||||
|
|
||||||
// not found?
|
// not found?
|
||||||
if( search == NULL )
|
if( search == NULL )
|
||||||
@@ -2938,7 +2982,7 @@ static byte *FS_LoadFile_( const char *path, fs_offset_t *filesizeptr, const qbo
|
|||||||
if( !fs_searchpaths || FS_CheckNastyPath( path ))
|
if( !fs_searchpaths || FS_CheckNastyPath( path ))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
search = FS_FindFile( path, &pack_ind, netpath, sizeof( netpath ), gamedironly );
|
search = FS_FindFile( path, &pack_ind, netpath, sizeof( netpath ), gamedironly ? FS_GAMEDIRONLY_SEARCH_FLAGS : 0 );
|
||||||
|
|
||||||
if( !search )
|
if( !search )
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -3086,7 +3130,7 @@ Look for a file in the packages and in the filesystem
|
|||||||
*/
|
*/
|
||||||
int GAME_EXPORT FS_FileExists( const char *filename, int gamedironly )
|
int GAME_EXPORT FS_FileExists( const char *filename, int gamedironly )
|
||||||
{
|
{
|
||||||
return FS_FindFile( filename, NULL, NULL, 0, gamedironly ) != NULL;
|
return FS_FindFile( filename, NULL, NULL, 0, gamedironly ? FS_GAMEDIRONLY_SEARCH_FLAGS : 0 ) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3120,7 +3164,7 @@ qboolean FS_GetFullDiskPath( char *buffer, size_t size, const char *name, qboole
|
|||||||
searchpath_t *search;
|
searchpath_t *search;
|
||||||
char temp[MAX_SYSPATH];
|
char temp[MAX_SYSPATH];
|
||||||
|
|
||||||
search = FS_FindFile( name, NULL, temp, sizeof( temp ), gamedironly );
|
search = FS_FindFile( name, NULL, temp, sizeof( temp ), gamedironly ? FS_GAMEDIRONLY_SEARCH_FLAGS : 0 );
|
||||||
|
|
||||||
if( search && search->type == SEARCHPATH_PLAIN )
|
if( search && search->type == SEARCHPATH_PLAIN )
|
||||||
{
|
{
|
||||||
@@ -3182,8 +3226,9 @@ int FS_FileTime( const char *filename, qboolean gamedironly )
|
|||||||
char netpath[MAX_SYSPATH];
|
char netpath[MAX_SYSPATH];
|
||||||
int pack_ind;
|
int pack_ind;
|
||||||
|
|
||||||
search = FS_FindFile( filename, &pack_ind, netpath, sizeof( netpath ), gamedironly );
|
search = FS_FindFile( filename, &pack_ind, netpath, sizeof( netpath ), gamedironly ? FS_GAMEDIRONLY_SEARCH_FLAGS : 0 );
|
||||||
if( !search ) return -1; // doesn't exist
|
if( !search )
|
||||||
|
return -1; // doesn't exist
|
||||||
|
|
||||||
return search->pfnFileTime( search, netpath );
|
return search->pfnFileTime( search, netpath );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#define FS_API_VERSION 4 // not stable yet!
|
#define FS_API_VERSION 5 // not stable yet!
|
||||||
#define FS_API_CREATEINTERFACE_TAG "XashFileSystem004" // follow FS_API_VERSION!!!
|
#define FS_API_CREATEINTERFACE_TAG "XashFileSystem005" // follow FS_API_VERSION!!!
|
||||||
#define FILESYSTEM_INTERFACE_VERSION "VFileSystem009" // never change this!
|
#define FILESYSTEM_INTERFACE_VERSION "VFileSystem009" // never change this!
|
||||||
|
|
||||||
// search path flags
|
// search path flags
|
||||||
@@ -43,14 +43,17 @@ enum
|
|||||||
FS_GAMEDIR_PATH = BIT( 2 ), // just a marker for gamedir path
|
FS_GAMEDIR_PATH = BIT( 2 ), // just a marker for gamedir path
|
||||||
FS_CUSTOM_PATH = BIT( 3 ), // gamedir but with custom/mod data
|
FS_CUSTOM_PATH = BIT( 3 ), // gamedir but with custom/mod data
|
||||||
FS_GAMERODIR_PATH = BIT( 4 ), // gamedir but read-only
|
FS_GAMERODIR_PATH = BIT( 4 ), // gamedir but read-only
|
||||||
|
FS_EXEC_PATH = BIT( 5 ), // this directory is allowed to have executable code
|
||||||
|
|
||||||
FS_SKIP_ARCHIVED_WADS = BIT( 5 ), // don't mount wads inside archives automatically
|
FS_SKIP_ARCHIVED_WADS = BIT( 16 ), // don't mount wads inside archives automatically
|
||||||
FS_LOAD_PACKED_WAD = BIT( 6 ), // this wad is packed inside other archive
|
FS_LOAD_PACKED_WAD = BIT( 17 ), // this wad is packed inside other archive
|
||||||
|
|
||||||
FS_MOUNT_HD = BIT( 7 ), // mount high definition content folder
|
FS_MOUNT_HD = BIT( 24 ), // mount high definition content folder
|
||||||
FS_MOUNT_LV = BIT( 8 ), // mount low violence content folder
|
FS_MOUNT_LV = BIT( 25 ), // mount low violence content folder
|
||||||
FS_MOUNT_ADDON = BIT( 9 ), // mount addon folder
|
FS_MOUNT_ADDON = BIT( 26 ), // mount addon folder
|
||||||
FS_MOUNT_L10N = BIT( 10 ), // mount localization folder
|
FS_MOUNT_L10N = BIT( 27 ), // mount localization folder
|
||||||
|
|
||||||
|
FS_MOUNT_FLAGS = FS_MOUNT_HD | FS_MOUNT_LV | FS_MOUNT_ADDON | FS_MOUNT_L10N,
|
||||||
|
|
||||||
FS_GAMEDIRONLY_SEARCH_FLAGS = FS_GAMEDIR_PATH | FS_CUSTOM_PATH | FS_GAMERODIR_PATH
|
FS_GAMEDIRONLY_SEARCH_FLAGS = FS_GAMEDIR_PATH | FS_CUSTOM_PATH | FS_GAMERODIR_PATH
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -214,15 +214,14 @@ qboolean FS_Delete( const char *path );
|
|||||||
qboolean FS_SysFileExists( const char *path );
|
qboolean FS_SysFileExists( const char *path );
|
||||||
const char *FS_GetDiskPath( const char *name, qboolean gamedironly );
|
const char *FS_GetDiskPath( const char *name, qboolean gamedironly );
|
||||||
qboolean FS_GetFullDiskPath( char *buffer, size_t size, const char *name, qboolean gamedironly );
|
qboolean FS_GetFullDiskPath( char *buffer, size_t size, const char *name, qboolean gamedironly );
|
||||||
void FS_CreatePath( char *path );
|
void FS_CreatePath( char *path );
|
||||||
qboolean FS_SysFolderExists( const char *path );
|
qboolean FS_SysFolderExists( const char *path );
|
||||||
qboolean FS_SysFileOrFolderExists( const char *path );
|
qboolean FS_SysFileOrFolderExists( const char *path );
|
||||||
file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedironly );
|
file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedironly );
|
||||||
|
|
||||||
int FS_SysFileTime( const char *filename );
|
int FS_SysFileTime( const char *filename );
|
||||||
file_t *FS_OpenHandle( searchpath_t *search, int handle, fs_offset_t offset, fs_offset_t len );
|
file_t *FS_OpenHandle( searchpath_t *search, int handle, fs_offset_t offset, fs_offset_t len );
|
||||||
file_t *FS_SysOpen( const char *filepath, const char *mode );
|
file_t *FS_SysOpen( const char *filepath, const char *mode );
|
||||||
searchpath_t *FS_FindFile( const char *name, int *index, char *fixedname, size_t len, qboolean gamedironly );
|
|
||||||
qboolean FS_FullPathToRelativePath( char *dst, const char *src, size_t size );
|
qboolean FS_FullPathToRelativePath( char *dst, const char *src, size_t size );
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user