public: add dll helpers to simplify basic interaction with exported functions lists

This commit is contained in:
Alibek Omarov 2024-12-23 04:43:15 +03:00
parent f1d7101ad8
commit 70897af362
8 changed files with 60 additions and 47 deletions

View file

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

View file

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

View file

@ -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++ )
{

View file

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

View file

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

View file

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

View file

@ -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++ )
{