public: add dll helpers to simplify basic interaction with exported functions lists
This commit is contained in:
parent
f1d7101ad8
commit
70897af362
8 changed files with 60 additions and 47 deletions
|
@ -232,6 +232,7 @@ typedef struct dll_info_s
|
|||
{
|
||||
const char *name; // name of library
|
||||
const dllfunc_t *fcts; // list of dll exports
|
||||
const size_t num_fcts;
|
||||
qboolean crash; // crash if dll not found
|
||||
void *link; // hinstance of loading library
|
||||
} dll_info_t;
|
||||
|
|
|
@ -30,10 +30,9 @@ static dllfunc_t msvfw_funcs[] =
|
|||
{ "DrawDibOpen", (void **) &pDrawDibOpen },
|
||||
{ "DrawDibDraw", (void **) &pDrawDibDraw },
|
||||
{ "DrawDibClose", (void **) &pDrawDibClose },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
dll_info_t msvfw_dll = { "msvfw32.dll", msvfw_funcs, false };
|
||||
dll_info_t msvfw_dll = { "msvfw32.dll", msvfw_funcs, ARRAYSIZE( msvfw_funcs ), false };
|
||||
|
||||
// msacm32.dll exports
|
||||
static MMRESULT (_stdcall *pacmStreamOpen)( LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER, DWORD, DWORD, DWORD );
|
||||
|
@ -51,10 +50,9 @@ static dllfunc_t msacm_funcs[] =
|
|||
{ "acmStreamConvert", (void **) &pacmStreamConvert },
|
||||
{ "acmStreamSize", (void **) &pacmStreamSize },
|
||||
{ "acmStreamClose", (void **) &pacmStreamClose },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
dll_info_t msacm_dll = { "msacm32.dll", msacm_funcs, false };
|
||||
dll_info_t msacm_dll = { "msacm32.dll", msacm_funcs, ARRAYSIZE( msacm_funcs ), false };
|
||||
|
||||
// avifil32.dll exports
|
||||
static int (_stdcall *pAVIStreamInfo)( PAVISTREAM pavi, AVISTREAMINFO *psi, LONG lSize );
|
||||
|
@ -88,10 +86,9 @@ static dllfunc_t avifile_funcs[] =
|
|||
{ "AVIStreamRelease", (void **) &pAVIStreamRelease },
|
||||
{ "AVIStreamStart", (void **) &pAVIStreamStart },
|
||||
{ "AVIStreamTimeToSample", (void **) &pAVIStreamTimeToSample },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
dll_info_t avifile_dll = { "avifil32.dll", avifile_funcs, false };
|
||||
dll_info_t avifile_dll = { "avifil32.dll", avifile_funcs, ARRAYSIZE( avifile_funcs ), false };
|
||||
|
||||
typedef struct movie_state_s
|
||||
{
|
||||
|
|
|
@ -4062,8 +4062,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||
}
|
||||
|
||||
// clear exports
|
||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
||||
*(cdll_exports[i].func) = NULL;
|
||||
ClearExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
||||
|
||||
// trying to get single export
|
||||
if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
||||
|
@ -4081,19 +4080,8 @@ qboolean CL_LoadProgs( const char *name )
|
|||
CL_GetSecuredClientAPI( GetClientAPI );
|
||||
}
|
||||
|
||||
if( GetClientAPI != NULL )
|
||||
{
|
||||
// check critical functions again
|
||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
||||
{
|
||||
if( *(cdll_exports[i].func) == NULL )
|
||||
break; // BAH critical function was missed
|
||||
}
|
||||
|
||||
// everything was loaded
|
||||
if( i == ARRAYSIZE( cdll_exports ))
|
||||
valid_single_export = true;
|
||||
}
|
||||
if( GetClientAPI != NULL ) // check critical functions again
|
||||
valid_single_export = ValidateExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
||||
{
|
||||
|
@ -4119,11 +4107,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||
|
||||
// it may be loaded through 'GetClientAPI' so we don't need to clear them
|
||||
if( !valid_single_export )
|
||||
{
|
||||
// clear new exports
|
||||
for( i = 0; i < ARRAYSIZE( cdll_new_exports ); i++ )
|
||||
*(cdll_new_exports[i].func) = NULL;
|
||||
}
|
||||
ClearExports( cdll_new_exports, ARRAYSIZE( cdll_new_exports ));
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( cdll_new_exports ); i++ )
|
||||
{
|
||||
|
|
|
@ -255,7 +255,7 @@ void Sys_SendKeyEvents( void )
|
|||
//=======================================================================
|
||||
qboolean Sys_LoadLibrary( dll_info_t *dll )
|
||||
{
|
||||
const dllfunc_t *func;
|
||||
size_t i;
|
||||
string errorstring;
|
||||
|
||||
// check errors
|
||||
|
@ -267,12 +267,8 @@ qboolean Sys_LoadLibrary( dll_info_t *dll )
|
|||
|
||||
Con_Reportf( "%s: Loading %s", __func__, dll->name );
|
||||
|
||||
if( dll->fcts )
|
||||
{
|
||||
// lookup export table
|
||||
for( func = dll->fcts; func && func->name != NULL; func++ )
|
||||
*func->func = NULL;
|
||||
}
|
||||
if( dll->fcts ) // lookup export table
|
||||
ClearExports( dll->fcts, dll->num_fcts );
|
||||
|
||||
if( !dll->link )
|
||||
dll->link = COM_LoadLibrary( dll->name, false, true ); // environment pathes
|
||||
|
@ -285,9 +281,10 @@ qboolean Sys_LoadLibrary( dll_info_t *dll )
|
|||
}
|
||||
|
||||
// Get the function adresses
|
||||
for( func = dll->fcts; func && func->name != NULL; func++ )
|
||||
for( i = 0; i < dll->num_fcts; i++ )
|
||||
{
|
||||
if( !( *func->func = Sys_GetProcAddress( dll, func->name )))
|
||||
const dllfunc_t *func = &dll->fcts[i];
|
||||
if( !( *func->func = COM_GetProcAddress( dll->link, func->name )))
|
||||
{
|
||||
Q_snprintf( errorstring, sizeof( errorstring ), "Sys_LoadLibrary: %s missing or invalid function (%s)\n", dll->name, func->name );
|
||||
goto error;
|
||||
|
@ -300,19 +297,11 @@ error:
|
|||
Con_Reportf( " - failed\n" );
|
||||
Sys_FreeLibrary( dll ); // trying to free
|
||||
if( dll->crash ) Sys_Error( "%s", errorstring );
|
||||
else Con_Reportf( S_ERROR "%s", errorstring );
|
||||
else Con_Reportf( S_ERROR "%s", errorstring );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void* Sys_GetProcAddress( dll_info_t *dll, const char* name )
|
||||
{
|
||||
if( !dll || !dll->link ) // invalid desc
|
||||
return NULL;
|
||||
|
||||
return (void *)COM_GetProcAddress( dll->link, name );
|
||||
}
|
||||
|
||||
qboolean Sys_FreeLibrary( dll_info_t *dll )
|
||||
{
|
||||
// invalid desc or alredy freed
|
||||
|
@ -330,6 +319,8 @@ qboolean Sys_FreeLibrary( dll_info_t *dll )
|
|||
COM_FreeLibrary( dll->link );
|
||||
dll->link = NULL;
|
||||
|
||||
ClearExports( dll->fcts, dll->num_fcts );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ int Sys_CheckParm( const char *parm );
|
|||
void Sys_Warn( const char *format, ... ) FORMAT_CHECK( 1 );
|
||||
void Sys_Error( const char *error, ... ) FORMAT_CHECK( 1 );
|
||||
qboolean Sys_LoadLibrary( dll_info_t *dll );
|
||||
void* Sys_GetProcAddress( dll_info_t *dll, const char* name );
|
||||
qboolean Sys_FreeLibrary( dll_info_t *dll );
|
||||
void Sys_ParseCommandLine( int argc, char **argv );
|
||||
void Sys_SetupCrashHandler( void );
|
||||
|
|
|
@ -106,6 +106,12 @@ char *COM_ParseFileSafe( char *data, char *token, const int size, unsigned int f
|
|||
int matchpattern( const char *in, const char *pattern, qboolean caseinsensitive );
|
||||
int matchpattern_with_separator( const char *in, const char *pattern, qboolean caseinsensitive, const char *separators, qboolean wildcard_least_one );
|
||||
|
||||
//
|
||||
// dllhelpers.c
|
||||
//
|
||||
void ClearExports( const dllfunc_t *funcs, size_t num_funcs );
|
||||
qboolean ValidateExports( const dllfunc_t *funcs, size_t num_funcs );
|
||||
|
||||
static inline char Q_toupper( const char in )
|
||||
{
|
||||
char out;
|
||||
|
|
36
public/dllhelpers.c
Normal file
36
public/dllhelpers.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
dllhelpers.c - dll exports helpers
|
||||
Copyright (C) 2024 Alibek Omarov
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
#include "crtlib.h"
|
||||
|
||||
void ClearExports( const dllfunc_t *funcs, size_t num_funcs )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < num_funcs; i++ )
|
||||
*(funcs[i].func) = NULL;
|
||||
}
|
||||
|
||||
qboolean ValidateExports( const dllfunc_t *funcs, size_t num_funcs )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < num_funcs; i++ )
|
||||
{
|
||||
if( *(funcs[i].func) == NULL )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -531,8 +531,7 @@ static qboolean GL_CheckExtension( const char *name, const dllfunc_t *funcs, siz
|
|||
|
||||
#if !XASH_GL_STATIC
|
||||
// clear exports
|
||||
for( i = 0; i < num_funcs; i++ )
|
||||
*(funcs[i].func) = NULL;
|
||||
ClearExports( funcs, num_funcs );
|
||||
|
||||
for( i = 0; i < num_funcs; i++ )
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue