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 char *name; // name of library
|
||||||
const dllfunc_t *fcts; // list of dll exports
|
const dllfunc_t *fcts; // list of dll exports
|
||||||
|
const size_t num_fcts;
|
||||||
qboolean crash; // crash if dll not found
|
qboolean crash; // crash if dll not found
|
||||||
void *link; // hinstance of loading library
|
void *link; // hinstance of loading library
|
||||||
} dll_info_t;
|
} dll_info_t;
|
||||||
|
|
|
@ -30,10 +30,9 @@ static dllfunc_t msvfw_funcs[] =
|
||||||
{ "DrawDibOpen", (void **) &pDrawDibOpen },
|
{ "DrawDibOpen", (void **) &pDrawDibOpen },
|
||||||
{ "DrawDibDraw", (void **) &pDrawDibDraw },
|
{ "DrawDibDraw", (void **) &pDrawDibDraw },
|
||||||
{ "DrawDibClose", (void **) &pDrawDibClose },
|
{ "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
|
// msacm32.dll exports
|
||||||
static MMRESULT (_stdcall *pacmStreamOpen)( LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER, DWORD, DWORD, DWORD );
|
static MMRESULT (_stdcall *pacmStreamOpen)( LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER, DWORD, DWORD, DWORD );
|
||||||
|
@ -51,10 +50,9 @@ static dllfunc_t msacm_funcs[] =
|
||||||
{ "acmStreamConvert", (void **) &pacmStreamConvert },
|
{ "acmStreamConvert", (void **) &pacmStreamConvert },
|
||||||
{ "acmStreamSize", (void **) &pacmStreamSize },
|
{ "acmStreamSize", (void **) &pacmStreamSize },
|
||||||
{ "acmStreamClose", (void **) &pacmStreamClose },
|
{ "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
|
// avifil32.dll exports
|
||||||
static int (_stdcall *pAVIStreamInfo)( PAVISTREAM pavi, AVISTREAMINFO *psi, LONG lSize );
|
static int (_stdcall *pAVIStreamInfo)( PAVISTREAM pavi, AVISTREAMINFO *psi, LONG lSize );
|
||||||
|
@ -88,10 +86,9 @@ static dllfunc_t avifile_funcs[] =
|
||||||
{ "AVIStreamRelease", (void **) &pAVIStreamRelease },
|
{ "AVIStreamRelease", (void **) &pAVIStreamRelease },
|
||||||
{ "AVIStreamStart", (void **) &pAVIStreamStart },
|
{ "AVIStreamStart", (void **) &pAVIStreamStart },
|
||||||
{ "AVIStreamTimeToSample", (void **) &pAVIStreamTimeToSample },
|
{ "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
|
typedef struct movie_state_s
|
||||||
{
|
{
|
||||||
|
|
|
@ -4062,8 +4062,7 @@ qboolean CL_LoadProgs( const char *name )
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear exports
|
// clear exports
|
||||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
ClearExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
||||||
*(cdll_exports[i].func) = NULL;
|
|
||||||
|
|
||||||
// trying to get single export
|
// trying to get single export
|
||||||
if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
||||||
|
@ -4081,19 +4080,8 @@ qboolean CL_LoadProgs( const char *name )
|
||||||
CL_GetSecuredClientAPI( GetClientAPI );
|
CL_GetSecuredClientAPI( GetClientAPI );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( GetClientAPI != NULL )
|
if( GetClientAPI != NULL ) // check critical functions again
|
||||||
{
|
valid_single_export = ValidateExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
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
|
// it may be loaded through 'GetClientAPI' so we don't need to clear them
|
||||||
if( !valid_single_export )
|
if( !valid_single_export )
|
||||||
{
|
ClearExports( cdll_new_exports, ARRAYSIZE( cdll_new_exports ));
|
||||||
// clear new exports
|
|
||||||
for( i = 0; i < ARRAYSIZE( cdll_new_exports ); i++ )
|
|
||||||
*(cdll_new_exports[i].func) = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i = 0; i < ARRAYSIZE( cdll_new_exports ); i++ )
|
for( i = 0; i < ARRAYSIZE( cdll_new_exports ); i++ )
|
||||||
{
|
{
|
||||||
|
|
|
@ -255,7 +255,7 @@ void Sys_SendKeyEvents( void )
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
qboolean Sys_LoadLibrary( dll_info_t *dll )
|
qboolean Sys_LoadLibrary( dll_info_t *dll )
|
||||||
{
|
{
|
||||||
const dllfunc_t *func;
|
size_t i;
|
||||||
string errorstring;
|
string errorstring;
|
||||||
|
|
||||||
// check errors
|
// check errors
|
||||||
|
@ -267,12 +267,8 @@ qboolean Sys_LoadLibrary( dll_info_t *dll )
|
||||||
|
|
||||||
Con_Reportf( "%s: Loading %s", __func__, dll->name );
|
Con_Reportf( "%s: Loading %s", __func__, dll->name );
|
||||||
|
|
||||||
if( dll->fcts )
|
if( dll->fcts ) // lookup export table
|
||||||
{
|
ClearExports( dll->fcts, dll->num_fcts );
|
||||||
// lookup export table
|
|
||||||
for( func = dll->fcts; func && func->name != NULL; func++ )
|
|
||||||
*func->func = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !dll->link )
|
if( !dll->link )
|
||||||
dll->link = COM_LoadLibrary( dll->name, false, true ); // environment pathes
|
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
|
// 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 );
|
Q_snprintf( errorstring, sizeof( errorstring ), "Sys_LoadLibrary: %s missing or invalid function (%s)\n", dll->name, func->name );
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -305,14 +302,6 @@ error:
|
||||||
return false;
|
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 )
|
qboolean Sys_FreeLibrary( dll_info_t *dll )
|
||||||
{
|
{
|
||||||
// invalid desc or alredy freed
|
// invalid desc or alredy freed
|
||||||
|
@ -330,6 +319,8 @@ qboolean Sys_FreeLibrary( dll_info_t *dll )
|
||||||
COM_FreeLibrary( dll->link );
|
COM_FreeLibrary( dll->link );
|
||||||
dll->link = NULL;
|
dll->link = NULL;
|
||||||
|
|
||||||
|
ClearExports( dll->fcts, dll->num_fcts );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ int Sys_CheckParm( const char *parm );
|
||||||
void Sys_Warn( const char *format, ... ) FORMAT_CHECK( 1 );
|
void Sys_Warn( const char *format, ... ) FORMAT_CHECK( 1 );
|
||||||
void Sys_Error( const char *error, ... ) FORMAT_CHECK( 1 );
|
void Sys_Error( const char *error, ... ) FORMAT_CHECK( 1 );
|
||||||
qboolean Sys_LoadLibrary( dll_info_t *dll );
|
qboolean Sys_LoadLibrary( dll_info_t *dll );
|
||||||
void* Sys_GetProcAddress( dll_info_t *dll, const char* name );
|
|
||||||
qboolean Sys_FreeLibrary( dll_info_t *dll );
|
qboolean Sys_FreeLibrary( dll_info_t *dll );
|
||||||
void Sys_ParseCommandLine( int argc, char **argv );
|
void Sys_ParseCommandLine( int argc, char **argv );
|
||||||
void Sys_SetupCrashHandler( void );
|
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( 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 );
|
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 )
|
static inline char Q_toupper( const char in )
|
||||||
{
|
{
|
||||||
char out;
|
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
|
#if !XASH_GL_STATIC
|
||||||
// clear exports
|
// clear exports
|
||||||
for( i = 0; i < num_funcs; i++ )
|
ClearExports( funcs, num_funcs );
|
||||||
*(funcs[i].func) = NULL;
|
|
||||||
|
|
||||||
for( i = 0; i < num_funcs; i++ )
|
for( i = 0; i < num_funcs; i++ )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue