Browse Source

engine: add a function to determine if library has direct dependency on chosen DLL(Win32 only)

pull/2/head
Alibek Omarov 6 years ago
parent
commit
b5d9bf5dc8
  1. 1
      engine/common/library.h
  2. 6
      engine/platform/posix/lib_posix.c
  3. 72
      engine/platform/win32/lib_win.c

1
engine/common/library.h

@ -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 );

6
engine/platform/posix/lib_posix.c

@ -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;

72
engine/platform/win32/lib_win.c

@ -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…
Cancel
Save