mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-03-09 20:21:10 +00:00
engine: add a function to determine if library has direct dependency on chosen DLL(Win32 only)
This commit is contained in:
parent
413882a8d5
commit
b5d9bf5dc8
@ -42,6 +42,7 @@ void *COM_FunctionFromName_SR( void *hInstance, const char *pName ); // Save/Res
|
|||||||
void *COM_FunctionFromName( void *hInstance, const char *pName );
|
void *COM_FunctionFromName( void *hInstance, const char *pName );
|
||||||
void COM_FreeLibrary( void *hInstance );
|
void COM_FreeLibrary( void *hInstance );
|
||||||
const char *COM_GetLibraryError( void );
|
const char *COM_GetLibraryError( void );
|
||||||
|
qboolean COM_CheckLibraryDirectDependency( const char *name, const char *depname, qboolean directpath );
|
||||||
|
|
||||||
// TODO: Move to internal?
|
// TODO: Move to internal?
|
||||||
void COM_ResetLibraryError( void );
|
void COM_ResetLibraryError( void );
|
||||||
|
@ -58,6 +58,12 @@ int dladdr( const void *addr, Dl_info *info )
|
|||||||
}
|
}
|
||||||
#endif // XASH_NO_LIBDL
|
#endif // XASH_NO_LIBDL
|
||||||
|
|
||||||
|
qboolean COM_CheckLibraryDirectDependency( const char *name, const char *depname, qboolean directpath )
|
||||||
|
{
|
||||||
|
// TODO: implement
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath )
|
void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath )
|
||||||
{
|
{
|
||||||
dll_user_t *hInst = NULL;
|
dll_user_t *hInst = NULL;
|
||||||
|
@ -591,7 +591,7 @@ void *MemoryLoadLibrary( const char *name )
|
|||||||
{
|
{
|
||||||
// try to allocate memory at arbitrary position
|
// try to allocate memory at arbitrary position
|
||||||
code = (byte *)VirtualAlloc( NULL, old_header->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_READWRITE );
|
code = (byte *)VirtualAlloc( NULL, old_header->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_READWRITE );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( code == NULL )
|
if( code == NULL )
|
||||||
{
|
{
|
||||||
@ -951,6 +951,72 @@ table_error:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qboolean COM_CheckLibraryDirectDependency( const char *name, const char *depname, qboolean directpath )
|
||||||
|
{
|
||||||
|
MEMORYMODULE *result = NULL;
|
||||||
|
PIMAGE_DOS_HEADER dos_header;
|
||||||
|
PIMAGE_NT_HEADERS old_header;
|
||||||
|
PIMAGE_DATA_DIRECTORY directory;
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR importDesc;
|
||||||
|
string errorstring;
|
||||||
|
void *data = NULL;
|
||||||
|
dll_user_t *hInst;
|
||||||
|
|
||||||
|
hInst = FS_FindLibrary( name, directpath );
|
||||||
|
if( !hInst )
|
||||||
|
{
|
||||||
|
return false; // nothing to load
|
||||||
|
}
|
||||||
|
|
||||||
|
data = FS_LoadFile( name, NULL, false );
|
||||||
|
if( !data )
|
||||||
|
{
|
||||||
|
Q_snprintf( errorstring, sizeof( errorstring ), "couldn't load %s", name );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dos_header = ( PIMAGE_DOS_HEADER )data;
|
||||||
|
if( dos_header->e_magic != IMAGE_DOS_SIGNATURE )
|
||||||
|
{
|
||||||
|
Q_snprintf( errorstring, sizeof( errorstring ), "%s it's not a valid executable file", name );
|
||||||
|
goto libraryerror;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_header = ( PIMAGE_NT_HEADERS )&( ( const byte * )( data ) )[dos_header->e_lfanew];
|
||||||
|
if( old_header->Signature != IMAGE_NT_SIGNATURE )
|
||||||
|
{
|
||||||
|
Q_snprintf( errorstring, sizeof( errorstring ), "%s missing PE header", name );
|
||||||
|
goto libraryerror;
|
||||||
|
}
|
||||||
|
|
||||||
|
directory = &old_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
|
||||||
|
|
||||||
|
if( directory->Size <= 0 )
|
||||||
|
{
|
||||||
|
Q_snprintf( errorstring, sizeof( errorstring ), "%s has no dependencies. Is this dll valid?\n" );
|
||||||
|
goto libraryerror;
|
||||||
|
}
|
||||||
|
|
||||||
|
importDesc = (PIMAGE_IMPORT_DESCRIPTOR)CALCULATE_ADDRESS( data, directory->VirtualAddress );
|
||||||
|
|
||||||
|
for( ; importDesc->Name; importDesc++ )
|
||||||
|
{
|
||||||
|
const char *importName = ( const char* )CALCULATE_ADDRESS( data, importDesc->Name );
|
||||||
|
Con_Reportf( "library %s has direct dependency %s\n", name, importName );
|
||||||
|
|
||||||
|
if( !Q_stricmp( importName, depname ) )
|
||||||
|
{
|
||||||
|
Mem_Free( data );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libraryerror:
|
||||||
|
Con_Printf( errorstring );
|
||||||
|
Mem_Free( data ); // release memory
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
COM_LoadLibrary
|
COM_LoadLibrary
|
||||||
@ -964,10 +1030,10 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d
|
|||||||
|
|
||||||
hInst = FS_FindLibrary( dllname, directpath );
|
hInst = FS_FindLibrary( dllname, directpath );
|
||||||
if( !hInst ) return NULL; // nothing to load
|
if( !hInst ) return NULL; // nothing to load
|
||||||
|
|
||||||
if( hInst->custom_loader )
|
if( hInst->custom_loader )
|
||||||
{
|
{
|
||||||
if( hInst->encrypted )
|
if( hInst->encrypted )
|
||||||
{
|
{
|
||||||
Con_Printf( S_ERROR "LoadLibrary: couldn't load encrypted library %s\n", dllname );
|
Con_Printf( S_ERROR "LoadLibrary: couldn't load encrypted library %s\n", dllname );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user