Renamed version4 to flaim and version5 to xflaim
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
375
flaim/src/ftkmod.cpp
Normal file
375
flaim/src/ftkmod.cpp
Normal file
@@ -0,0 +1,375 @@
|
||||
//-------------------------------------------------------------------------
|
||||
// Desc: Module loading
|
||||
// Tabs: 3
|
||||
//
|
||||
// Copyright (c) 2004-2006 Novell, Inc. All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of version 2 of the GNU General Public
|
||||
// License as published by the Free Software Foundation.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, contact Novell, Inc.
|
||||
//
|
||||
// To contact Novell about this file by physical or electronic mail,
|
||||
// you may find current contact information at www.novell.com
|
||||
//
|
||||
// $Id: ftkmod.cpp 12334 2006-01-23 12:45:35 -0700 (Mon, 23 Jan 2006) dsanders $
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#include "flaim.h"
|
||||
|
||||
#ifndef FLM_OSX
|
||||
|
||||
// OS X 10.2 and earlier don't have dlopen, dlsym, etc... They have a totally
|
||||
// different mechanism and since these functions are only used for our unit
|
||||
// tests, it's probably not worth the time to sort it all out. In 10.3,
|
||||
// the dl functions were implemented in terms of the native functions and
|
||||
// this should all work. Pity there's no easy way to determine which version
|
||||
// we're on...
|
||||
|
||||
|
||||
#include "flaimsys.h"
|
||||
|
||||
#ifdef FLM_UNIX
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FLM_WIN
|
||||
|
||||
FSTATIC RCODE flmSymLoadWin(
|
||||
const FLMBYTE * pszName,
|
||||
FlmModHandle hMod,
|
||||
void ** ppvSym);
|
||||
|
||||
#elif defined (FLM_NLM)
|
||||
|
||||
FSTATIC RCODE flmSymLoadNW(
|
||||
const FLMBYTE * pszName,
|
||||
void ** ppvSym);
|
||||
|
||||
#elif defined( FLM_UNIX)
|
||||
|
||||
FSTATIC RCODE flmSymLoadUnix(
|
||||
const FLMBYTE * pszName,
|
||||
FlmModHandle hMod,
|
||||
void ** ppvSym);
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc: This routine loads a shared library (cross-platform)
|
||||
****************************************************************************/
|
||||
RCODE FlmModLoad(
|
||||
const char * pszName,
|
||||
FlmModHandle * phMod)
|
||||
{
|
||||
RCODE rc = FERR_OK;
|
||||
#ifdef FLM_WIN
|
||||
HMODULE hMod;
|
||||
|
||||
if ((hMod = LoadLibrary( pszName)) == NULL)
|
||||
{
|
||||
rc = MapWinErrorToFlaim( GetLastError(), FERR_LOAD_LIBRARY);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( phMod)
|
||||
{
|
||||
*phMod = (FlmModHandle)hMod;
|
||||
}
|
||||
|
||||
#elif defined (FLM_UNIX)
|
||||
FlmModHandle hMod;
|
||||
|
||||
if (!(hMod = dlopen( (const char *)pszName, RTLD_LAZY)))
|
||||
{
|
||||
// Note, I can't seem to get any real diagnostic info back
|
||||
// from the operating system. It does not set errno on failure.
|
||||
rc = RC_SET( FERR_LOAD_LIBRARY);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( phMod)
|
||||
{
|
||||
*phMod = hMod;
|
||||
}
|
||||
|
||||
#elif defined (FLM_NLM)
|
||||
|
||||
char szLoadName[ 128];
|
||||
LONG lErr;
|
||||
|
||||
// The module handle will be passed back in the first 4 bytes of the name
|
||||
f_strcpy( &szLoadName[4], pszName);
|
||||
|
||||
if ( ( lErr = LoadModule(
|
||||
GetSystemConsoleScreen(),
|
||||
(unsigned char *)&szLoadName[4],
|
||||
LO_RETURN_HANDLE)) != 0)
|
||||
{
|
||||
rc = RC_SET( FERR_LOAD_LIBRARY);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*phMod = (FlmModHandle)&szLoadName[0];
|
||||
|
||||
#else
|
||||
#error Unsupported OS
|
||||
#endif
|
||||
|
||||
Exit:
|
||||
return( rc);
|
||||
}
|
||||
|
||||
#ifndef FLM_NLM
|
||||
/****************************************************************************
|
||||
Desc: This routine unloads a shared library (cross-platform)
|
||||
****************************************************************************/
|
||||
RCODE FlmModUnload( FlmModHandle * phMod)
|
||||
{
|
||||
RCODE rc = FERR_OK;
|
||||
|
||||
flmAssert( phMod);
|
||||
#ifdef FLM_WIN
|
||||
|
||||
if (!FreeLibrary((HMODULE)*phMod))
|
||||
{
|
||||
rc = MapWinErrorToFlaim( GetLastError(), FERR_UNLOAD_LIBRARY);
|
||||
goto Exit;
|
||||
}
|
||||
*phMod = NULL;
|
||||
|
||||
#elif defined (FLM_UNIX)
|
||||
if (dlclose(phMod) != 0)
|
||||
{
|
||||
rc = RC_SET( FERR_UNLOAD_LIBRARY);
|
||||
goto Exit;
|
||||
}
|
||||
*phMod = NULL;
|
||||
#else
|
||||
#error Unsupported OS
|
||||
#endif
|
||||
Exit:
|
||||
return( rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FLM_NLM
|
||||
|
||||
/****************************************************************************
|
||||
Desc: This routine creates a FLAIM file. For whatever reason, NetWare unloads
|
||||
a module using its path and not its handle. While routines exist that look up
|
||||
the path given the module handle, I can't use them because they are all LibC
|
||||
calls
|
||||
****************************************************************************/
|
||||
RCODE FlmModUnload( FLMBYTE * pszModPath)
|
||||
{
|
||||
int iErr;
|
||||
RCODE rc = FERR_OK;
|
||||
|
||||
if ( (iErr = UnloadModule(
|
||||
NULL,
|
||||
(const char *)pszModPath)) != 0)
|
||||
{
|
||||
rc = MapNWtoFlaimError( iErr, FERR_UNLOAD_LIBRARY);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
return( rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FLM_WIN
|
||||
|
||||
/****************************************************************************
|
||||
Desc: This routine loads a symbol from a .dll file
|
||||
****************************************************************************/
|
||||
FSTATIC RCODE flmSymLoadWin(
|
||||
const FLMBYTE * pszName,
|
||||
FlmModHandle hMod,
|
||||
void ** ppvSym)
|
||||
{
|
||||
RCODE rc = FERR_OK;
|
||||
void * pvSym;
|
||||
|
||||
if ( ( pvSym = GetProcAddress( (HMODULE)hMod, (LPCSTR)pszName)) == NULL)
|
||||
{
|
||||
rc = MapWinErrorToFlaim( GetLastError(), FERR_IMPORT_SYMBOL);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( ppvSym && RC_OK( rc))
|
||||
{
|
||||
*ppvSym = pvSym;
|
||||
}
|
||||
|
||||
return( rc);
|
||||
}
|
||||
|
||||
#elif defined (FLM_NLM)
|
||||
|
||||
/****************************************************************************
|
||||
Desc: This routine loads a symbol from a .nlm file
|
||||
****************************************************************************/
|
||||
FSTATIC RCODE flmSymLoadNW(
|
||||
const FLMBYTE * pszName,
|
||||
void ** ppvSym)
|
||||
{
|
||||
RCODE rc = FERR_OK;
|
||||
void * pvSym;
|
||||
FLMUINT uiNameLen;
|
||||
FLMBYTE * pszLengthPlusName = NULL;
|
||||
|
||||
// NetWare is a little different (of course). You use your own handle
|
||||
// to query for and retrieve symbols. All loaded modules are queried.
|
||||
|
||||
uiNameLen = f_strlen( (const char *)pszName);
|
||||
|
||||
if ( uiNameLen > 255)
|
||||
{
|
||||
|
||||
// If the name's length can't be represented in a single byte,
|
||||
// it's too large.
|
||||
|
||||
rc = RC_SET( FERR_VALUE_TOO_LARGE);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( RC_BAD( rc = f_alloc( uiNameLen + 2, &pszLengthPlusName)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// The first byte of the name should be the length of the name
|
||||
|
||||
pszLengthPlusName[0] = (FLMBYTE)uiNameLen;
|
||||
f_strcpy( (char *)&pszLengthPlusName[1], (const char *)pszName);
|
||||
|
||||
if (( pvSym = (void *)ImportPublicSymbol(
|
||||
f_getNLMHandle(),
|
||||
(BYTE*)pszLengthPlusName)) == NULL)
|
||||
{
|
||||
rc = RC_SET( FERR_IMPORT_SYMBOL);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( pszLengthPlusName)
|
||||
{
|
||||
f_free( &pszLengthPlusName);
|
||||
}
|
||||
|
||||
if ( ppvSym && RC_OK( rc))
|
||||
{
|
||||
*ppvSym = pvSym;
|
||||
}
|
||||
return( rc);
|
||||
}
|
||||
|
||||
#elif defined( FLM_UNIX)
|
||||
|
||||
/****************************************************************************
|
||||
Desc: This routine loads a symbol from a .so file.
|
||||
****************************************************************************/
|
||||
FSTATIC RCODE flmSymLoadUnix(
|
||||
const FLMBYTE * pszName,
|
||||
FlmModHandle hMod,
|
||||
void ** ppvSym)
|
||||
{
|
||||
RCODE rc = FERR_OK;
|
||||
void * pvSym;
|
||||
|
||||
if ( ( pvSym = dlsym( hMod, (const char*)pszName)) == NULL)
|
||||
{
|
||||
rc = RC_SET( FERR_IMPORT_SYMBOL);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( ppvSym && RC_OK( rc))
|
||||
{
|
||||
*ppvSym = pvSym;
|
||||
}
|
||||
|
||||
return( rc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc: This routine loads a symbol from a shared library (cross-platform)
|
||||
****************************************************************************/
|
||||
RCODE FlmSymLoad( const FLMBYTE * pszName, FlmModHandle hMod, void ** ppvSym)
|
||||
{
|
||||
#ifdef FLM_WIN
|
||||
return flmSymLoadWin( pszName, hMod, ppvSym);
|
||||
#elif defined (FLM_NLM)
|
||||
F_UNREFERENCED_PARM( hMod);
|
||||
return flmSymLoadNW( pszName, ppvSym);
|
||||
#elif defined (FLM_UNIX)
|
||||
return flmSymLoadUnix( pszName, hMod, ppvSym);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Desc: This routine unloads a shared library symbol (cross-platform, but only
|
||||
really useful on NetWare since it seems to be the only platform that keeps a
|
||||
reference count on loaded symbols)
|
||||
****************************************************************************/
|
||||
RCODE FlmSymUnload(
|
||||
const FLMBYTE * pszName)
|
||||
{
|
||||
#ifdef FLM_NLM
|
||||
RCODE rc = FERR_OK;
|
||||
FLMUINT uiSymLen;
|
||||
FLMBYTE * pszLenAndSymbol = NULL;
|
||||
|
||||
uiSymLen = f_strlen( (const char *)pszName);
|
||||
|
||||
if ( uiSymLen > 255)
|
||||
{
|
||||
rc = RC_SET( FERR_VALUE_TOO_LARGE);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( RC_BAD( rc = f_alloc( uiSymLen + 2, &pszLenAndSymbol)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pszLenAndSymbol[0] = (FLMBYTE)uiSymLen;
|
||||
f_strcpy( (char *)&pszLenAndSymbol[1], (const char *)pszName);
|
||||
|
||||
if ((UnImportPublicSymbol (
|
||||
f_getNLMHandle(), pszLenAndSymbol)) != 0)
|
||||
{
|
||||
rc = RC_SET( FERR_UNIMPORT_SYMBOL);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if( pszLenAndSymbol)
|
||||
{
|
||||
f_free( &pszLenAndSymbol);
|
||||
}
|
||||
|
||||
return( rc);
|
||||
#else
|
||||
|
||||
// This is only really necessary on NetWare
|
||||
|
||||
F_UNREFERENCED_PARM( pszName);
|
||||
return FERR_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user