windows-nt/Source/XPSP1/NT/base/ntsetup/legacy/dll/dinterp.c
2020-09-26 16:20:57 +08:00

338 lines
9.8 KiB
C

#include "precomp.h"
#pragma hdrstop
/* File: dinterp.c */
/**************************************************************************/
/***** DETECT COMPONENT - Detect Interpreter
/**************************************************************************/
/* Detect component return code symbol table variable name */
CHP szStfRCSym[] = "STF_DETECT_OUTCOME";
HANDLE hInstCaller = NULL;
/* Component error variable detect error values
** (ordered by priority)
*/
SZ rgszDrc[] =
{
"DLLNOTFOUND",
"OUTOFMEM",
"CMDNOTFOUND",
"CMDFAILED",
"OKAY"
};
#define drcDllNotFound 0
#define drcOutOfMem 1
#define drcCmdNotFound 2
#define drcCmdFailed 3
#define drcOkay 4
#define drcMin 0
#define drcMax 5
#if DBG
/*** REVIEW: Out of memory TEST functions (from _comstf.h) ***/
extern CB APIENTRY CbSetAllocOpsCur(CB);
extern CB APIENTRY CbGetAllocOpsCur(VOID);
extern CB APIENTRY CbSetAllocOpsForceFailure(CB);
extern CB APIENTRY CbGetAllocOpsForceFailure(VOID);
#endif /* DBG */
/*
** Purpose:
** Shell interpreter detect command handler.
** Called by Shell interpreter.
** Arguments:
** hinst, hwnd : Windows stuff
** rgsz : array of arguments (NULL terminated)
** cItems : count of arguments (must be 1)
** Returns:
** fFalse if a vital detect operation fails or if a referrenced
** detect command DLL cannot be loaded,
** fTrue otherwise.
**************************************************************************/
BOOL APIENTRY FDetectEntryPoint(HANDLE hInst,HWND hWnd,RGSZ rgsz,USHORT cItems)
{
if (hInst == (HANDLE)NULL
|| hWnd == (HWND)NULL
|| rgsz == (RGSZ)NULL
|| *rgsz == (SZ)NULL
|| cItems != 1
|| *(rgsz + 1) != (SZ)NULL)
{
Assert(fFalse);
return(fFalse);
}
hInstCaller = hInst;
return(FDetectInfSection(hWnd, rgsz[0]));
}
/*
** Purpose:
** Traverses the given section evaluating any detect commands
** found and setting the associated symbol in the symbol table.
** Also sets the detect outcome variable (STF_DETECT_OUTCOME)
** in the symbol table to one of the following (in order of
** priority):
**
** "DLLNOTFOUND" Requested detect command DLL not found
** "OUTOFMEM" Out of memory error occured
** "CMDNOTFOUND" Requested detect command not found
** "CMDFAILED" Requested detect command failed
** "OKAY" All detect commands completed okay
**
** Arguments:
** szSection: non-NULL, non-empty section name.
** Notes:
** Requires that the current INF structure was initialized with a
** successful call to GrcOpenInf().
** Requires that the Symbol Table was initialized with a successful
** call to FInitSymTab().
** Returns:
** fFalse if a vital detect operation fails or if a referrenced
** detect command DLL cannot be loaded,
** fTrue otherwise.
**************************************************************************/
BOOL APIENTRY FDetectInfSection(HWND hwnd,SZ szSection)
{
RGSZ rgsz = rgszNull;
SZ szKey = szNull;
SZ szValue = szNull;
CHP szLibCur[cchpFullPathBuf];
HANDLE hLibCur = hNull;
PFNCMD pfncmd;
INT Line;
BOOL fOkay = fTrue;
UINT cFields;
DRC drcSet = drcOkay;
DRC drc;
AssertDataSeg();
// PreCondSymTabInit(fFalse); *** REVIEW: can't use with dll ***
// PreCondInfOpen(fFalse);
ChkArg(szSection != (SZ)NULL &&
*szSection != '\0' &&
!FWhiteSpaceChp(*szSection), 1, fFalse);
*szLibCur = '\0';
Line = FindFirstLineFromInfSection(szSection);
while(Line != -1)
{
SdAtNewLine(Line);
if(FKeyInInfLine(Line)
&& (cFields = CFieldsInInfLine(Line)) >= cFieldDetMin)
{
drc = drcOkay;
if((rgsz = RgszFromInfScriptLine(Line,cFields)) == rgszNull)
{
drc = drcOutOfMem;
goto NextCmd;
}
if(CrcStringCompare(rgsz[iszDetSym], szDetSym) != crcEqual)
goto NextCmd;
if(!FLoadDetectLib(rgsz[iszLib], szLibCur, &hLibCur))
{
drc = drcDllNotFound;
fOkay = fFalse;
goto NextCmd;
}
if((pfncmd = (PFNCMD)GetProcAddress(hLibCur, rgsz[iszCmd]))
== pfncmdNull)
{
#if DBG
MessBoxSzSz("Unknown Detect Command", rgsz[iszCmd]);
#endif
drc = drcCmdNotFound;
goto NextCmd;
}
if((drc = DrcGetDetectValue(&szValue, pfncmd,
rgsz+iszArg, cFields-iszArg)) != drcOkay)
{
#if DBG
if(drc == drcCmdFailed)
MessBoxSzSz("Detect Command Failed", rgsz[iszCmd]);
#endif
goto NextCmd;
}
if((szKey = SzGetNthFieldFromInfLine(Line,0)) == szNull)
{
drc = drcOutOfMem;
goto NextCmd;
}
if(!FAddSymbolValueToSymTab(szKey, szValue))
drc = drcOutOfMem;
NextCmd:
if(drc < drcSet)
drcSet = drc;
if(szValue != szNull)
SFree(szValue);
if(szKey != szNull)
SFree(szKey);
if(rgsz != (RGSZ)szNull)
FFreeRgsz(rgsz);
szValue = szKey = szNull;
rgsz = rgszNull;
if(!fOkay)
break;
}
Line = FindNextLineFromInf(Line);
}
if(hLibCur >= hLibMin)
if(*szLibCur != '|')
FreeLibrary(hLibCur);
while(!FAddSymbolValueToSymTab(szStfRCSym, rgszDrc[drcSet]))
{
if(!FHandleOOM(hwnd))
fOkay = fFalse;
}
return(fOkay);
}
HANDLE APIENTRY StfLoadLibrary(SZ szLib)
{
INT cchp;
SZ szCWD, szCur;
SZ szLastBackSlash = (SZ)NULL;
HANDLE hDll;
if ((szCur = szCWD = (SZ)SAlloc((CB)4096)) == (SZ)NULL)
return(0);
if ((cchp = GetModuleFileName(hInstCaller, (LPSTR)szCur, 4095)) >= 4095)
{
SFree(szCur);
return((HANDLE)2);
}
*(szCur + cchp) = '\0';
while (*szCur != '\0')
if (*szCur++ == '\\')
szLastBackSlash = szCur;
if (szLastBackSlash == (SZ)NULL)
{
SFree(szCWD);
return((HANDLE)2);
}
*szLastBackSlash = '\0';
EvalAssert(SzStrCat(szCWD, szLib) == szCWD);
hDll = LoadLibrary((PfhOpenFile(szCWD, ofmExistRead) != NULL) ? szCWD
: szLib);
SFree(szCWD);
return(hDll);
}
/*
** Purpose:
** Loads the given detect DLL if not already loaded, and
** frees the previously loaded DLL, if any.
** Arguments:
** szLib : name of library to load (must be non-szNull)
** szLibCurBuf : pointer into string buffer conatining name of
** library currently loaded, if any (empty string if none
** loaded).
** phLibCir : handle to currently loaded library.
** Notes:
** Assumes szLibCurBuf buffer is large enough for any DLL name.
** Returns:
** fTrue if given detect DLL loaded okay, fFalse if not.
** Modifies szLibCurBuf and phLibCur if new library is loaded.
**************************************************************************/
BOOL APIENTRY FLoadDetectLib(szLib, szLibCurBuf, phLibCur)
SZ szLib;
SZ szLibCurBuf;
HANDLE *phLibCur;
{
ChkArg(szLib != szNull &&
*szLib != '\0' &&
!FWhiteSpaceChp(*szLib), 1, fFalse);
ChkArg(szLibCurBuf != szNull, 2, fFalse);
ChkArg(phLibCur != (HANDLE *)NULL, 3, fFalse);
if(*szLib == '|') { // lib name is really a handle
*phLibCur = LongToHandle(atol(szLib+1));
*szLibCurBuf = '|';
return(fTrue);
}
if(*szLibCurBuf == '\0'
|| CrcStringCompareI(szLibCurBuf, szLib) != crcEqual)
{
if(*phLibCur >= hLibMin)
FreeLibrary(*phLibCur);
*szLibCurBuf = '\0';
if((*phLibCur = StfLoadLibrary(szLib)) < hLibMin)
return(fFalse);
Assert(strlen(szLib) < cchpFullPathBuf);
EvalAssert(strcpy(szLibCurBuf, szLib) != szNull);
}
Assert(*phLibCur >= hLibMin);
return(fTrue);
}
/*
** Purpose:
** Gets the value of a detect command and returns it in
** an allocated, zero terminated string.
** Arguments:
** psz : pointer to be set to result value string
** pfncmd : address of detect command function
** rgsz : array of command arguments (may be empty)
** cArgs : number of args in rgsz
** Returns:
** drcCmdFailed if detect command failed (returned 0)
** drcOutOfMem if out of memory error
** drcOkay if no error
**************************************************************************/
DRC APIENTRY DrcGetDetectValue(psz, pfncmd, rgsz, cArgs)
SZ *psz;
PFNCMD pfncmd;
RGSZ rgsz;
CB cArgs; // 1632
{
SZ szValue, szT;
CB cbBuf = cbValBufDef;
CB cbVal;
if((szValue = (SZ)SAlloc(cbBuf)) == szNull)
return(drcOutOfMem);
Assert(cbBuf > 0);
while((cbVal = (*pfncmd)(rgsz, (USHORT)cArgs, szValue, cbBuf)) > cbBuf) // 1632
{
if(cbVal > cbAllocMax)
{
SFree(szValue);
return(drcCmdFailed);
}
if((szT = SRealloc((PB)szValue, cbVal)) == NULL)
{
SFree(szValue);
return(drcOutOfMem);
}
szValue = szT;
cbBuf = cbVal;
}
if(cbVal == 0)
{
SFree(szValue);
return(drcCmdFailed);
}
Assert(szValue != szNull
&& (strlen(szValue)+1) == cbVal
&& cbVal <= cbBuf);
if(cbVal < cbBuf)
szValue = SRealloc(szValue,cbBuf);
*psz = szValue;
return(drcOkay);
}