NT4/private/windows/win4help/winhelp/dll.c
2020-09-30 17:12:29 +02:00

838 lines
22 KiB
C

/*****************************************************************************
* *
* DLL.C *
* *
* Copyright (C) Microsoft Corporation 1990. *
* All Rights reserved. *
* *
******************************************************************************
* *
* Module Intent *
* *
* Module for handling DLL library loading and "storage" and messaging *
* *
*****************************************************************************/
#include "help.h"
#pragma hdrstop
#define MAX_DLL_NAME 128
typedef INT16 (STDCALL *FARPR)(WORD, DWORD, DWORD);
typedef struct {
HLIBMOD hMod;
DWORD dwInform; // Class flags for sending messages
FARPR farprInform; // Function pointer to msz entry
char rgchName[1]; // Name of the DLL
} DLL, *QDLL;
static LL llDLL;
static int iThunkState;
enum {
THUNK_UNINITIALIZED,
THUNK_FOUND,
THUNK_MISSING,
};
DWORD dwMpMszClass[] = {
DC_NOMSG, // DW_NOTUSED 0
DC_NOMSG, // DW_WHATMSG 1
DC_MINMAX, // DW_MINMAX 2
DC_MINMAX, // DW_SIZE 3
DC_INITTERM, // DW_INIT 4
DC_INITTERM, // DW_TERM 5
DC_JUMP, // DW_STARTJUMP 6
DC_JUMP, // DW_ENDJUMP 7
DC_JUMP, // DW_CHGFILE 8
DC_ACTIVATE, // DW_ACTIVATE 9
DC_CALLBACKS, // DW_CALLBACKS 10
DC_ACTIVATE // DW_ACTIVATEAPP 11
};
/*****************************************************************************
*
* Prototypes
*
*****************************************************************************/
static HANDLE STDCALL HLookupDLLQch(LPCSTR);
QV STDCALL QVGetCallbacks(VOID);
BOOL STDCALL bInitThunk(void);
HFS EXPORT ExpHfsOpenQch (LPSTR qch, BYTE b);
RC EXPORT ExpRcCloseHfs (HFS hfs);
HF EXPORT ExpHfCreateFileHfs (HFS hfs, LPSTR sz, BYTE b);
RC EXPORT ExpRcUnlinkFileHfs (HFS hfs, LPSTR sz);
HF EXPORT ExpHfOpenHfs(HFS hfs, LPSTR sz, BYTE b);
RC EXPORT ExpRcFlushHf (HF hf);
RC EXPORT ExpRcCloseHf (HF hf);
LONG EXPORT ExpLcbReadHf (HF hf, QV qv, LONG l);
LONG EXPORT ExpLcbWriteHf (HF hf, QV qv, LONG l);
LONG EXPORT ExpLTellHf (HF hf);
LONG EXPORT ExpLSeekHf (HF hf, LONG l, WORD w);
BOOL EXPORT ExpFEofHf (HF hf);
BOOL EXPORT ExpFChSizeHf (HF hf, LONG l);
LONG EXPORT ExpLcbSizeHf (HF hf);
BOOL EXPORT ExpFAccessHfs (HFS hfs, LPSTR sz, BYTE b);
RC EXPORT ExpRcAbandonHf (HF);
RC EXPORT ExpRcRenameFileHfs (HFS hfs, LPSTR sz, LPSTR sz2);
VOID EXPORT ExpError (INT16 nError);
VOID EXPORT ExpErrorQch(LPSTR qch);
LONG EXPORT ExpGetInfo (WORD wWhich, HWND hwnd);
BOOL EXPORT ExpFAPI(LPSTR qchFile, WORD usCommand, DWORD ulData);
RC EXPORT ExpRcLLInfoFromHf(HF hf, WORD wOption, FID *qfid, QL qlBase, QL qlcb);
RC EXPORT ExpRcLLInfoFromHfsSz(HFS hfs, LPSTR szFile, WORD wOption, FID *qfid, QL qlBase, QL qlcb);
HFS EXPORT ExpHfsCreateFileSys(LPSTR szFile, FS_PARAMS *qfsp);
RC EXPORT ExpRcDestroyFileSys(LPSTR szFile);
static HLIBMOD STDCALL HmodFromName(PCSTR pszDllName, FM* pfm);
extern BOOL fTableLoaded;
typedef DWORD (STDCALL *REG_THK)(LPCSTR, LPCSTR, VOID *);
typedef DWORD (STDCALL *MAKE_CALL)(LPSTR lpBuffer, DWORD dw, LPSTR lp, WORD cb);
typedef VOID (_stdcall *MAKE_CALL_CLEANUP)(VOID);
typedef VOID (STDCALL *INFORM_DLLS)(DWORD, UINT16, DWORD, DWORD);
typedef VOID (STDCALL *FINALIZE)();
typedef HWND (STDCALL *EMBED_CREATE)(LPSTR lpModule, LPSTR lpClass,
LPSTR lpData, int dx,
int dy, HWND hwndParent,
HINSTANCE hInst, EWDATA *lpewd,
VOID* qvCallbacks);
typedef DWORD (STDCALL *GETMODFN)(HINSTANCE hInst, LPSTR lpModule, DWORD nSize);
static REG_THK lpRegisterThnk;
static MAKE_CALL lpCallThnk;
MAKE_CALL_CLEANUP lpCallThnkCleanup;
static INFORM_DLLS lpInformDlls;
static FINALIZE lpFinalize;
EMBED_CREATE lpEmbedCreate;
/*******************
-
- Name: InitDLL()
*
* Purpose: Initializes data structures used for user DLL calls.
*
* Arguments: None.
*
* Returns: Nothing.
*
******************/
VOID STDCALL InitDLL(VOID)
{
llDLL = LLCreate();
}
/*******************
-
- Name: FinalizeDLL()
*
* Purpose: Destroys data structures used for user DLL calls.
*
* Arguments: None.
*
* Returns: Nothing.
*
******************/
VOID STDCALL FinalizeDLL(VOID)
{
QDLL qDLL;
HLLN hlln = NULL;
#ifdef RAWHIDE
if (fTableLoaded)
FUnloadSearchModule();
#endif
RemoveOle();
while (hlln = WalkLL(llDLL, hlln)) {
qDLL = (QDLL) GetLLDataPtr(hlln);
if (qDLL->dwInform & DC_INITTERM) {
if (qDLL->farprInform)
(qDLL->farprInform) (DW_TERM, 0L, 0L);
}
FreeLibrary(qDLL->hMod);
}
if (lpFinalize)
(lpFinalize)();
DestroyLL(llDLL);
}
/*******************
-
- Name: HLookupDLLQch(qch)
*
* Purpose: Sees if a particular module has alreay been
* saved in our internal list.
*
* Arguments: qch - module name.
*
* Returns: handle to the module if found or NULL if the module
* is not found.
*
******************/
static HLIBMOD STDCALL HLookupDLLQch(LPCSTR qch)
{
QDLL qDLL;
HLLN hlln = NULL;
while (hlln = WalkLL(llDLL, hlln)) {
qDLL = (QDLL) GetLLDataPtr(hlln);
if (_strcmpi(qch, qDLL->rgchName) == 0) {
return qDLL->hMod;
}
}
return NULL;
}
/*******************
-
- Name: InformDLLs
*
* Purpose: This function informs DLLs of of help events.
*
* Arguments: wMsz - message to send
* p1 - data
* p2 - data
*
* Returns: Nothing
*
******************/
VOID STDCALL InformDLLs(WORD wMsz, DWORD p1, DWORD p2)
{
QDLL qDLL;
DWORD dwClass;
HLLN hlln = NULL;
// Message should never be larger larger than the class table
ASSERT((wMsz > 0) &&
(wMsz < sizeof(dwMpMszClass)/sizeof(dwMpMszClass[0])));
dwClass = dwMpMszClass[wMsz]; // Get class for the message
while (hlln = WalkLL(llDLL, hlln)) {
qDLL = (QDLL) GetLLDataPtr(hlln);
// If the DLL is interested in the class, then send the message
if (qDLL->dwInform & dwClass && qDLL->farprInform)
(qDLL->farprInform)(wMsz, p1, p2);
}
if (lpInformDlls)
(lpInformDlls)(dwClass, wMsz, p1, p2);
}
/*******************
-
- Name: HFindDLL
*
* Purpose: Finds (loading if necessary) the specified DLL
*
* Arguments: pszDllName - name of the DLL. An extension of
* .EXE or .DLL is assumed.
*
* Returns: module handle or NULL if the handle is not found.
*
******************/
#pragma warning(disable:4113) // function parameter lists differed
HLIBMOD STDCALL HFindDLL(LPCSTR pszDllName, BOOL fHelpDll)
{
BYTE rgbDLL[MAX_PATH];
HLIBMOD hmod;
QDLL qdll = (QDLL) rgbDLL;
QV qvCallbacks;
FM fm;
#ifdef RAWHIDE
char szFtui[MAX_PATH];
#endif
#ifndef RAWHIDE
if (FIsSearchModule(pszDllName))
return NULL;
#endif
if (strlen(pszDllName) > MAX_PATH)
return NULL;
ASSERT(StrChrDBCS(pszDllName, '.'));
if ((hmod = HLookupDLLQch(pszDllName)) != NULL)
return hmod;
if (Is16Dll(pszDllName))
return NULL;
#ifdef RAWHIDE
// REVIEW: we can only deal with the 32-bit version of ftui.
if (FIsSearchModule(pszDllName) && !strstr(pszDllName, "32") && !strchr(pszDllName, '.')) {
strcpy(szFtui, "ftui32.dll");
pszDllName = szFtui;
}
#endif
WaitCursor();
// Progress past this point indicates that the DLL was not previously
// loaded.
hmod = HmodFromName(pszDllName, &fm);
if (hmod) {
qdll->hMod = hmod; // save the handle
qdll->dwInform = DC_NOMSG;
qdll->farprInform = NULL;
strcpy(qdll->rgchName, pszDllName);
DisposeFm(fm);
if (fHelpDll && (qdll->farprInform =
(FARPR) GetProcAddress(hmod, "LDLLHandler")) != NULL) {
qdll->dwInform = (qdll->farprInform)(DW_WHATMSG, 0L, 0L);
// Notify dll of initialization
if (qdll->dwInform & DC_INITTERM &&
!(qdll->farprInform)(DW_INIT, 0L, 0L)) {
goto DllError;
}
// Send dll our array of callback functions
if (qdll->dwInform & DC_CALLBACKS) {
if ((qvCallbacks = QVGetCallbacks()) == NULL)
goto DllError;
(qdll->farprInform) (DW_CALLBACKS, (LONG) qvCallbacks, 0L);
}
}
if (!InsertLL(llDLL, (QV) qdll, sizeof(DLL) + strlen(qdll->rgchName))) {
if (qdll->farprInform)
(qdll->farprInform)(DW_TERM, 0L, 0L);
goto DllError;
}
// Special Processing for FTUI! If what we have just loaded is FTUI, then
// load the table of routine pointers into it.
// This is a bit of a hack, and should be replaced by a more general
// mechanism. 07-Jan-1991 LeoN
#ifdef RAWHIDE
if (FIsSearchModule(qdll->rgchName)) {
FLoadSearchModule(hmod);
FLoadFtIndexPdb(NULL);
}
#endif
}
RemoveWaitCursor();
return hmod;
DllError:
FreeLibrary(hmod);
RemoveWaitCursor();
return NULL;
}
/*******************
-
- Name: FarprocDLL32GetEntry()
*
* Purpose: Gets the address of a function in the specified DLL
*
* Arguments: pszDllName - name of the DLL. An extension of
* .EXE or .DLL is assumed.
* qchEntry - exported entry to find in DLL
*
* Returns: procedure address or NULL if the entry is not found.
*
******************/
#ifndef NO_PRAGMAS
#pragma data_seg(".text", "CODE")
#endif
const char txtThunkDll[] = "WHLP32T.DLL";
#ifndef NO_PRAGMAS
#pragma data_seg()
#endif
BOOL STDCALL bInitThunk(void)
{
HLIBMOD hmod;
FM fm;
switch(iThunkState)
{
case THUNK_UNINITIALIZED: // We haven't tried to thunk yet. Try it.
if (!(hmod = HLookupDLLQch(txtThunkDll)))
{
hmod = HmodFromName(txtThunkDll, &fm);
DisposeFm(fm);
}
if (hmod)
{
lpRegisterThnk =
(REG_THK) GetProcAddress(hmod, "RegisterThunk");
lpCallThnk = (MAKE_CALL) GetProcAddress(hmod, "CallThunk");
lpCallThnkCleanup = (MAKE_CALL_CLEANUP) GetProcAddress(hmod, "CallThunkCleanup");
lpInformDlls = (INFORM_DLLS) GetProcAddress(hmod, "InformDlls");
lpFinalize = (INFORM_DLLS) GetProcAddress(hmod, "FinalizeDLL");
lpEmbedCreate = (EMBED_CREATE) GetProcAddress(hmod, "DoEmbedCreate");
}
if (lpRegisterThnk && lpCallThnk && lpInformDlls && lpFinalize && lpEmbedCreate)
{
iThunkState = THUNK_FOUND;
return(TRUE);
}
iThunkState = THUNK_MISSING;
return(FALSE);
case THUNK_FOUND: // We have gotten our thunk before. It is safe to use.
return(TRUE);
case THUNK_MISSING: // We tried and failed before, don't bother again.
return(FALSE);
}
}
#ifndef NO_PRAGMAS
#pragma data_seg(".text", "CODE")
#endif
static const char txtUserDll[] = "USER.DLL";
static const char txtUserExe[] = "USER.EXE";
const char txtUser32Dll[] = "USER32.DLL";
static const char txtGdiDll[] = "GDI.DLL";
static const char txtGdiExe[] = "GDI.EXE";
static const char txtGdi32Dll[] = "GDI32.DLL";
#ifndef NO_PRAGMAS
#pragma data_seg()
#endif
FARPROC STDCALL FarprocDLLGetEntry(LPCSTR pszDllName, LPCSTR pszFunctionName,
DWORD* pdwTag)
{
FM fm;
HLIBMOD hMod;
FARPROC fproc;
char szCopy[MAX_PATH];
if (!StrChrDBCS(pszDllName, '.')) { // if no extension, force .DLL
lstrcpy(szCopy, pszDllName);
lstrcat(szCopy, txtDllExtension);
pszDllName = (PCSTR) szCopy;
}
if (_stricmp(pszDllName, txtUserDll) == 0 ||
_stricmp(pszDllName, txtUserExe) == 0)
pszDllName = (PCSTR) txtUser32Dll;
else if (_stricmp(pszDllName, txtGdiDll) == 0 ||
_stricmp(pszDllName, txtGdiExe) == 0)
pszDllName = (PCSTR) txtGdi32Dll;
else if (_stricmp(pszDllName, "mmsystem.dll") == 0)
pszDllName = (PCSTR) "winmm.dll";
#ifndef RAWHIDE
if (FIsSearchModule(pszDllName))
return NULL;
#endif
if ((hMod = HFindDLL(pszDllName, TRUE)) != NULL) {
fproc = GetProcAddress(hMod, pszFunctionName);
if (!fproc && (_stricmp(pszDllName, txtUser32Dll) == 0 ||
_stricmp(pszDllName, "winmm.dll") == 0)) {
// Many USER functions now have an 'A' on the end
char szFuncName[256];
strcpy(szFuncName, pszFunctionName);
strcat(szFuncName, "A");
fproc = GetProcAddress(hMod, szFuncName);
}
if (pdwTag)
*pdwTag = 0; // native 32-bit dll
}
else {
if (fIsThisChicago) {
if (!pdwTag)
return NULL; // we don't want to thunk this dll
if (!bInitThunk()) {
ReportMissingDll(pszDllName);
return NULL;
}
fm = FmNewExistSzDir(pszDllName,
DIR_CUR_HELP | DIR_INI | DIR_PATH | DIR_CURRENT | DIR_SILENT_REG);
if (!fm) {
ReportMissingDll(pszDllName);
return NULL;
}
*pdwTag = lpRegisterThnk((PCSTR) fm, pszFunctionName, QVGetCallbacks());
fproc = (*pdwTag == 0) ? NULL : (FARPROC) lpCallThnk;
if (fproc)
AddTo16DllList(fm);
DisposeFm(fm);
}
else {
ReportMissingDll(pszDllName);
return NULL;
}
}
if (!fproc && fHelpAuthor && !FIsSearchModule(pszDllName)) {
char szBuf[MAX_PATH + 100];
wsprintf(szBuf, GetStringResource(wERRS_NO_DLL_ROUTINE),
pszFunctionName, pszDllName);
ErrorQch(szBuf);
}
return fproc;
}
/*******************
-
- Name: QVGetCallbacks
*
* Purpose: Creates a block of memory containing callback functions
* within WinHelp.
*
* Arguments: None.
*
* Returns: handle to block of memory. NULL is returned in case of
* an error.
*
******************/
void* STDCALL QVGetCallbacks(VOID)
{
static FARPROC *pFarproc;
if (pFarproc != NULL)
return (QV)pFarproc;
if ((pFarproc = (FARPROC *)LocalAlloc(LMEM_FIXED,
sizeof(FARPROC) * HE_Count)) == NULL)
{
OOM(); // doesn't return
return NULL;
}
pFarproc[HE_NotUsed ] = (FARPROC)NULL;
pFarproc[HE_HfsOpen ] = (FARPROC) ExpHfsOpenQch;
pFarproc[HE_RcCloseHfs ] = (FARPROC) ExpRcCloseHfs;
pFarproc[HE_HfCreateFileHfs ] = (FARPROC) ExpHfCreateFileHfs;
pFarproc[HE_RcUnlinkFileHfs ] = (FARPROC) ExpRcUnlinkFileHfs;
pFarproc[HE_HfOpenHfs ] = (FARPROC) ExpHfOpenHfs;
pFarproc[HE_RcFlushHf ] = (FARPROC) ExpRcFlushHf;
pFarproc[HE_RcCloseHf ] = (FARPROC) ExpRcCloseHf;
pFarproc[HE_LcbReadHf ] = (FARPROC) ExpLcbReadHf;
pFarproc[HE_LcbWriteHf ] = (FARPROC) ExpLcbWriteHf;
pFarproc[HE_LTellHf ] = (FARPROC) ExpLTellHf;
pFarproc[HE_LSeekHf ] = (FARPROC) ExpLSeekHf;
pFarproc[HE_FEofHf ] = (FARPROC) ExpFEofHf;
pFarproc[HE_FChSizeHf ] = (FARPROC) ExpFChSizeHf;
pFarproc[HE_LcbSizeHf ] = (FARPROC) ExpLcbSizeHf;
pFarproc[HE_FAccessHfs ] = (FARPROC) ExpFAccessHfs;
pFarproc[HE_RcAbandonHf ] = (FARPROC) ExpRcAbandonHf;
pFarproc[HE_RcRenameFileHfs ] = (FARPROC) ExpRcRenameFileHfs;
pFarproc[HE_RcLLInfoFromHf ] = (FARPROC) ExpRcLLInfoFromHf;
pFarproc[HE_RcLLInfoFromHfsSz ] = (FARPROC) ExpRcLLInfoFromHfsSz;
pFarproc[HE_ErrorW ] = (FARPROC) ExpError;
pFarproc[HE_ErrorLpstr ] = (FARPROC) ExpErrorQch;
pFarproc[HE_GetInfo ] = (FARPROC) ExpGetInfo;
pFarproc[HE_API ] = (FARPROC) ExpFAPI;
pFarproc[HE_HfsCreateFileSys ] = (FARPROC) ExpHfsCreateFileSys;
pFarproc[HE_RcDestroyFileSys ] = (FARPROC) ExpRcDestroyFileSys;
return (QV) pFarproc;
}
UINT GetModuleFileName16(HINSTANCE hInstance, LPSTR lpFileName, UINT nSize)
{
HLIBMOD hmod;
GETMODFN lpFunction;
if (fIsThisChicago) {
if (bInitThunk() && ((hmod = GetModuleHandle(txtThunkDll)) != NULL) &&
((lpFunction = GetProcAddress(hmod, "GetModuleFileName16")) != NULL))
return (*lpFunction)(hInstance, lpFileName, nSize);
}
return 0;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
HFS EXPORT ExpHfsOpenQch ( LPSTR qch, BYTE b)
{
FM fm;
HFS hfs;
fm = FmNewSzDir((LPSTR) qch, DIR_CURRENT);
hfs = HfsOpenFm(fm, b);
DisposeFm(fm);
return hfs;
}
HFS EXPORT ExpHfsCreateFileSys( LPSTR szFile, FS_PARAMS *qfsp )
{
FM fm;
HFS hfs;
fm = FmNewSzDir((LPSTR) szFile, DIR_CURRENT);
hfs = HfsCreateFileSysFm(fm, qfsp);
DisposeFm(fm);
return hfs;
}
RC EXPORT ExpRcDestroyFileSys(LPSTR szFile)
{
FM fm;
RC rc;
fm = FmNewSzDir((LPSTR) szFile, DIR_CURRENT);
rc = RcDestroyFileSysFm(fm);
DisposeFm(fm);
return rc;
}
// REVIEW: if we have the same parameters, we should export the real function
RC EXPORT ExpRcCloseHfs ( HFS hfs )
{ return RcCloseHfs(hfs); }
HF EXPORT ExpHfCreateFileHfs ( HFS hfs, LPSTR sz, BYTE b)
{ return HfCreateFileHfs ( hfs, sz, b); }
RC EXPORT ExpRcUnlinkFileHfs ( HFS hfs, LPSTR sz)
{ return RcUnlinkFileHfs ( hfs, sz); }
HF EXPORT ExpHfOpenHfs( HFS hfs, LPSTR sz, BYTE b)
{ return HfOpenHfs ( hfs, sz, b); }
RC EXPORT ExpRcFlushHf ( HF hf )
{ return RcCloseOrFlushHf(hf, TRUE, 0); }
RC EXPORT ExpRcCloseHf ( HF hf )
{ return RcCloseOrFlushHf(hf, TRUE, 0); }
LONG EXPORT ExpLcbReadHf ( HF hf, QV qv, LONG l)
{ return LcbReadHf ( hf, qv, l ); }
LONG EXPORT ExpLcbWriteHf ( HF hf, QV qv, LONG l)
{ return LcbWriteHf ( hf, qv, l); }
LONG EXPORT ExpLTellHf ( HF hf )
{ return LTellHf ( hf ); }
LONG EXPORT ExpLSeekHf ( HF hf, LONG l, WORD w)
{ return LSeekHf ( hf, l, w); }
BOOL EXPORT ExpFEofHf ( HF hf )
{ return FEofHf (hf); }
BOOL EXPORT ExpFChSizeHf ( HF hf, LONG l )
{ return FChSizeHf (hf, l); }
LONG EXPORT ExpLcbSizeHf ( HF hf )
{ return LcbSizeHf (hf); }
BOOL EXPORT ExpFAccessHfs ( HFS hfs, LPSTR sz, BYTE b)
{ return FAccessHfs (hfs, sz); }
RC EXPORT ExpRcAbandonHf ( HF hf )
{ return RcAbandonHf (hf); }
RC EXPORT ExpRcRenameFileHfs ( HFS hfs, LPSTR sz, LPSTR sz2 )
{ return RcRenameFileHfs (hfs, sz, sz2); }
VOID EXPORT ExpError(INT16 nError )
{ Error(nError, wERRA_RETURN); }
VOID EXPORT ExpErrorQch ( LPSTR qch )
{ ErrorQch(qch); }
LONG EXPORT ExpGetInfo (WORD wWhich, HWND hwnd)
{ return LGetInfo(wWhich, hwnd); }
BOOL EXPORT ExpFAPI(LPSTR qchFile, WORD usCommand, DWORD ulData)
{ return FWinHelp(qchFile, usCommand, ulData); }
RC EXPORT ExpRcLLInfoFromHf(HF hf, WORD wOption, FID *qfid, QL qlBase, QL qlcb )
{ return RcLLInfoFromHf(hf, wOption, qfid, qlBase, qlcb); }
RC EXPORT ExpRcLLInfoFromHfsSz(HFS hfs, LPSTR szFile, WORD wOption, FID *qfid, QL qlBase, QL qlcb )
{ return RcLLInfoFromHfsSz(hfs, szFile, wOption, qfid, qlBase, qlcb); }
/***************************************************************************
FUNCTION: HmodFromName
PURPOSE: Attempts to load a dll. If necessary, the extension .DLL will
be appended, and if the original name had no extension,
then .EXE will be tried as well for backwards compatability.
Highly recommended that all dll names specify an extension.
PARAMETERS:
pszName -- original name
pfm -- receives the fm of the actual name used
RETURNS:
COMMENTS:
MODIFICATION DATES:
23-Jul-1994 [ralphw]
***************************************************************************/
extern const char txtFtuiDll[];
extern const char txtFtuiDll32[];
static HLIBMOD STDCALL HmodFromName(PCSTR pszDllName, FM* pfm)
{
FM fm;
HLIBMOD hmodReturn;
/*
* Look for the DLL starting with the directory of the current help
* file, then the current directory, directories specified in
* winhelp.ini, the windows\help directory and the PATH.
*/
fm = FmNewExistSzDir(pszDllName,
DIR_CUR_HELP | DIR_INI | DIR_PATH | DIR_CURRENT | DIR_SILENT_REG);
if (fm) {
if (!fIsThisChicago) {
UINT UErrCode;
UErrCode = SetErrorMode(0);
SetErrorMode(UErrCode | SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS );
hmodReturn = (HLIBMOD) LoadLibrary(PszFromGh(fm));
SetErrorMode( UErrCode );
if (!hmodReturn) { // not a 32 bit exe
long lExeType;
if (GetBinaryType( fm, &lExeType )) { // it must be a 16 bit binary
Error(wERRS_WRONG_NT_EXE, wERRA_DIE_SPAWN);
}
}
} else { // Chicago - just do it
hmodReturn = (HLIBMOD) LoadLibrary(PszFromGh(fm));
}
#ifdef _PRIVATE
{
char szBuf[512];
wsprintf(szBuf, "LoadLibray of \042%s\042 %s.\r\n",
fm, hmodReturn ?
GetStringResource(sidSuccess) : GetStringResource(sidFail));
SendStringToParent(szBuf);
}
#endif
}
else
hmodReturn = 0;
if (!hmodReturn) {
char szNewName[MAX_PATH];
strcpy(szNewName, pszDllName);
CharUpper(szNewName); // so we can search for .dll names
// Only substitute extensions if we weren't told it was a .DLL/.EXE file
if (!strstr(szNewName, txtExeExtension))
{
if (!strstr(szNewName, txtDllExtension) &&
!strstr(szNewName, txtExeExtension)) {
ChangeExtension(szNewName, txtDllExtension);
hmodReturn = HmodFromName(szNewName, &fm);
}
#ifdef RAWHIDE
// If we couldn't load the dll, and its ftui, then try ftui32
if (!hmodReturn && strcmp(txtFtuiDll, szNewName) == 0)
hmodReturn = HmodFromName(txtFtuiDll32, &fm);
// If we still can't load it, try with an .EXE extension
else if (!hmodReturn)
#else
if (!hmodReturn)
#endif
{
#ifdef _PRIVATE
char szBuf[512];
wsprintf(szBuf, "HmodFromName of \042%s\042 %s.\r\n",
szNewName, hmodReturn ?
GetStringResource(sidSuccess) : GetStringResource(sidFail));
SendStringToParent(szBuf);
#endif
ChangeExtension(szNewName, txtExeExtension);
hmodReturn = HmodFromName(szNewName, &fm);
#ifdef _PRIVATE
wsprintf(szBuf, "HmodFromName of \042%s\042 %s.\r\n",
szNewName, hmodReturn ?
GetStringResource(sidSuccess) : GetStringResource(sidFail));
SendStringToParent(szBuf);
#endif
}
}
#ifdef RAWHIDE
else if (strcmp(txtFtuiDll, szNewName) == 0)
hmodReturn = HmodFromName(txtFtuiDll32, &fm);
#endif
}
*pfm = fm;
return hmodReturn;
}
/***************************************************************************
*
- Name: FIsSearchModule
-
* Purpose:
* determine if the passed name refers to the full text search engine
*
* Arguments:
* szFn - pointer to string containg basename of the dll
*
* Returns:
* true if that's the full text engine, false otherwise.
*
***************************************************************************/
BOOL STDCALL FIsSearchModule(LPCSTR pszDllName)
{
char szText[MAX_PATH];
lstrcpy(szText, pszDllName);
return (BOOL) (strstr(CharUpper((LPTSTR) szText), "FTUI") != NULL);
}