/* * Com_LoadLibraryExt */ void *Com_LoadLibraryExt( const char *name, dllfunc_t *funcs, bool sys ) { void *lib; dllfunc_t *func; const char *fullname; if( !name || !name[0] || !funcs ) return NULL; Com_DPrintf( "LoadLibrary (%s)\n", name ); if( sys ) fullname = name; else fullname = Sys_Library_GetFullName( name ); if( !fullname ) { Com_DPrintf( "LoadLibrary (%s):(Not found)\n", name ); return NULL; } lib = Sys_Library_Open( fullname ); if( !lib ) { if( !sys ) Com_Printf( "LoadLibrary (%s):(%s)\n", fullname, Sys_Library_ErrorString() ); return NULL; } for( func = funcs; func->name; func++ ) { *( func->funcPointer ) = Sys_Library_ProcAddress( lib, func->name ); if( !( *( func->funcPointer ) ) ) { Com_UnloadLibrary( &lib ); if( sys ) return NULL; Com_Error( ERR_FATAL, "%s: Sys_GetProcAddress failed for %s", fullname, func->name ); } } return lib; }
/* * Com_LoadGameLibrary */ void *Com_LoadGameLibrary( const char *basename, const char *apifuncname, void **handle, void *parms, bool pure, char *manifest ) { static int randomizer = 0; // random part of tempmodules dir, always the same for one launch of Warsow static int64_t randomizer_time; const char *temppath; char *tempname, *libname; int libname_size; void *( *APIfunc )(void *); gamelib_t *gamelib; *handle = 0; if( !randomizer ) { randomizer_time = time( NULL ); srand( randomizer_time ); randomizer = brandom( 1, 9999 ); } gamelib = ( gamelib_t* )Mem_ZoneMalloc( sizeof( gamelib_t ) ); gamelib->lib = NULL; gamelib->fullname = NULL; libname_size = strlen( LIB_PREFIX ) + strlen( basename ) + 1 + strlen( ARCH ) + strlen( LIB_SUFFIX ) + 1; libname = ( char* )Mem_TempMalloc( libname_size ); Q_snprintfz( libname, libname_size, LIB_PREFIX "%s_" ARCH LIB_SUFFIX, basename ); // it exists? if( FS_FOpenFile( libname, NULL, FS_READ ) == -1 ) { Com_Printf( "LoadLibrary (%s):(File not found)\n", libname ); Mem_TempFree( libname ); Mem_ZoneFree( gamelib ); return NULL; } // pure check if( pure && !FS_IsPureFile( libname ) ) { Com_Printf( "LoadLibrary (%s):(Unpure file)\n", libname ); Mem_TempFree( libname ); Mem_ZoneFree( gamelib ); return NULL; } temppath = Sys_Library_GetGameLibPath( libname, randomizer_time, randomizer ); tempname = ( char * )Mem_ZoneMalloc( strlen( temppath ) + 1 ); strcpy( tempname, temppath ); if( FS_FOpenFile( tempname, NULL, FS_READ ) == -1 ) { if( !FS_ExtractFile( libname, tempname ) ) { Com_Printf( "LoadLibrary (%s):(FS_ExtractFile failed)\n", libname ); Mem_TempFree( libname ); Mem_ZoneFree( tempname ); Mem_ZoneFree( gamelib ); return NULL; } } gamelib->fullname = COM_SanitizeFilePath( tempname ); gamelib->lib = Sys_Library_Open( gamelib->fullname ); gamelib->next = gamelibs; gamelibs = gamelib; if( !( gamelib->lib ) ) { Com_Printf( "LoadLibrary (%s):(%s)\n", tempname, Sys_Library_ErrorString() ); Mem_TempFree( libname ); Com_UnloadGameLibrary( (void **)&gamelib ); return NULL; } APIfunc = ( void* ( * )( void* ) )Sys_Library_ProcAddress( gamelib->lib, apifuncname ); if( !APIfunc ) { Com_Printf( "LoadLibrary (%s):(%s)\n", tempname, Sys_Library_ErrorString() ); Mem_TempFree( libname ); Com_UnloadGameLibrary( (void **)&gamelib ); return NULL; } *handle = gamelib; if( manifest ) Com_LoadGameLibraryManifest( libname, manifest ); Mem_TempFree( libname ); return APIfunc( parms ); }