mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2569 lines
78 KiB
2569 lines
78 KiB
#include "precomp.h"
|
|
#pragma hdrstop
|
|
/**************************************************************************/
|
|
/***** Common Library Component - Parse Table Handling Routines 2 *********/
|
|
/**************************************************************************/
|
|
|
|
extern BOOL APIENTRY FGetCmo(INT Line, UINT *pcFields, CMO * pcmo);
|
|
|
|
extern HWND hWndShell;
|
|
extern UINT iFieldCur;
|
|
extern BOOL fFullScreen;
|
|
|
|
extern BOOL
|
|
FWaitForEventOrFailure(
|
|
IN LPSTR InfVar,
|
|
IN LPSTR Event,
|
|
IN DWORD Timeout
|
|
);
|
|
|
|
extern
|
|
BOOL
|
|
APIENTRY
|
|
FFlushInfParsedInfo(
|
|
SZ szInfName
|
|
);
|
|
|
|
VOID TermRestoreDiskLogging();
|
|
|
|
BOOL APIENTRY FParseBmpShow ( INT Line, UINT * pcFields ) ;
|
|
BOOL APIENTRY FParseBmpHide ( INT Line, UINT * pcFields ) ;
|
|
|
|
// PSEFL pseflHead = (PSEFL)NULL;
|
|
|
|
/*
|
|
** Array of String Code Pairs for initializing Flow Statement Handling
|
|
*/
|
|
SCP rgscpFlow[] = {
|
|
{ "SET", spcSet },
|
|
{ "SET-SUBSYM", spcSetSubsym },
|
|
{ "SET-SUBST", spcSetSubst },
|
|
{ "SET-ADD", spcSetAdd },
|
|
{ "SET-SUB", spcSetSub },
|
|
{ "SET-MUL", spcSetMul },
|
|
{ "SET-DIV", spcSetDiv },
|
|
{ "SET-OR", spcSetOr },
|
|
{ "SET-HEXTODEC", spcSetHexToDec },
|
|
{ "SET-DECTOHEX", spcSetDecToHex },
|
|
{ "IFSTR", spcIfStr },
|
|
{ "==", spcEQ },
|
|
{ "!=", spcNE },
|
|
{ "ELSE", spcElse },
|
|
{ "ENDIF", spcEndIf },
|
|
{ "GOTO", spcGoTo },
|
|
{ "ELSE-IFSTR", spcElseIfStr },
|
|
{ "IFINT", spcIfInt },
|
|
{ "<", spcLT },
|
|
{ "<=", spcLE },
|
|
{ "=<", spcLE },
|
|
{ ">", spcGT },
|
|
{ ">=", spcGE },
|
|
{ "=>", spcGE },
|
|
{ "ELSE-IFINT", spcElseIfInt },
|
|
{ "IFSTR(I)", spcIfStrI },
|
|
{ "ELSE-IFSTR(I)", spcElseIfStrI },
|
|
{ "IFCONTAINS", spcIfContains },
|
|
{ "IFCONTAINS(I)", spcIfContainsI },
|
|
{ "IN", spcIn },
|
|
{ "NOT-IN", spcNotIn },
|
|
{ "ELSE-IFCONTAINS", spcElseIfContains },
|
|
{ "ELSE-IFCONTAINS(I)", spcElseIfContainsI },
|
|
{ "FORLISTDO", spcForListDo },
|
|
{ "ENDFORLISTDO", spcEndForListDo },
|
|
{ "DEBUG-MSG", spcDebugMsg },
|
|
{ "STARTWAIT", spcHourglass },
|
|
{ "ENDWAIT", spcArrow },
|
|
{ "SETHELPFILE", spcSetHelpFile },
|
|
{ "CREATEREGKEY", spcCreateRegKey },
|
|
{ "OPENREGKEY", spcOpenRegKey },
|
|
{ "FLUSHREGKEY", spcFlushRegKey },
|
|
{ "CLOSEREGKEY", spcCloseRegKey },
|
|
{ "DELETEREGKEY", spcDeleteRegKey },
|
|
{ "DELETEREGTREE", spcDeleteRegTree },
|
|
{ "ENUMREGKEY", spcEnumRegKey },
|
|
{ "SETREGVALUE", spcSetRegValue },
|
|
{ "GETREGVALUE", spcGetRegValue },
|
|
{ "DELETEREGVALUE", spcDeleteRegValue },
|
|
{ "ENUMREGVALUE", spcEnumRegValue },
|
|
{ "GETDRIVEINPATH", spcGetDriveInPath },
|
|
{ "GETDIRINPATH", spcGetDirInPath },
|
|
{ "LOADLIBRARY", spcLoadLibrary },
|
|
{ "FREELIBRARY", spcFreeLibrary },
|
|
{ "LIBRARYPROCEDURE", spcLibraryProcedure },
|
|
{ "RUNPROGRAM", spcRunExternalProgram },
|
|
{ "INVOKEAPPLET", spcInvokeApplet },
|
|
{ "STARTDETACHEDPROCESS", spcStartDetachedProcess },
|
|
{ "DEBUG-OUTPUT", spcDebugOutput },
|
|
{ "SPLIT-STRING", spcSplitString },
|
|
{ "QUERYLISTSIZE", spcQueryListSize },
|
|
{ "ADDFILETODELETELIST", spcAddFileToDeleteList },
|
|
{ "INITRESTOREDISKLOG", spcInitRestoreDiskLog },
|
|
{ "WAITONEVENT", spcWaitOnEvent },
|
|
{ "SIGNALEVENT", spcSignalEvent },
|
|
{ "SLEEP", spcSleep },
|
|
{ "FLUSHINF", spcFlushInf },
|
|
{ "BMPSHOW", spcBmpShow },
|
|
{ "BMPHIDE", spcBmpHide },
|
|
{ "TERMRESTOREDISKLOG", spcTermRestoreDiskLog },
|
|
{ NULL, spcUnknown }
|
|
};
|
|
/*
|
|
** String Parsing Table for handling Flow Statements
|
|
*/
|
|
PSPT psptFlow = (PSPT)NULL;
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Evaluates an expression and determines whether it is valid, and if
|
|
** so, if it is true or false. Used by FHandleFlowStatements().
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** ecm: Comparison Mode (eg ecmIfStr, ecmIfInt)
|
|
** szArg1: Non-NULL string for left argument.
|
|
** szArg2: Non-NULL string for right argument.
|
|
** szOper: Non-NULL string for operator (eg '==', '>=', etc).
|
|
** Notes:
|
|
** Requires that psptFlow was initialized with a successful call to
|
|
** FInitFlowPspt().
|
|
** Returns:
|
|
** ercError if comparison is not valid (eg operator and ecm don't
|
|
** correspond).
|
|
** ercTrue if expression evaluates to fTrue.
|
|
** ercFalse if expression evaluates to fFalse.
|
|
**
|
|
**************************************************************************/
|
|
ERC APIENTRY ErcEvaluateCompare(HWND hwndParent,
|
|
ECM ecm,
|
|
SZ szArg1,
|
|
SZ szArg2,
|
|
SZ szOper)
|
|
{
|
|
SPC spc;
|
|
|
|
PreCondFlowInit(ecmError);
|
|
|
|
ChkArg(ecm == ecmIfStr ||
|
|
ecm == ecmIfStrI ||
|
|
ecm == ecmIfInt ||
|
|
ecm == ecmIfContains ||
|
|
ecm == ecmIfContainsI, 1, ecmError);
|
|
ChkArg(szArg1 != (SZ)NULL, 2, ecmError);
|
|
ChkArg(szArg2 != (SZ)NULL, 3, ecmError);
|
|
ChkArg(szOper != (SZ)NULL &&
|
|
*szOper != '\0', 4, ecmError);
|
|
|
|
EvalAssert((spc = SpcParseString(psptFlow, szOper)) != spcError);
|
|
|
|
switch (ecm)
|
|
{
|
|
case ecmIfStrI:
|
|
EvalAssert(SzStrUpper(szArg1) == szArg1);
|
|
EvalAssert(SzStrUpper(szArg2) == szArg2);
|
|
case ecmIfStr:
|
|
/* BLOCK */
|
|
{
|
|
CRC crc = CrcStringCompare(szArg1, szArg2);
|
|
|
|
switch (spc)
|
|
{
|
|
case spcEQ:
|
|
return ((crc == crcEqual) ? ercTrue : ercFalse);
|
|
case spcNE:
|
|
return ((crc != crcEqual) ? ercTrue : ercFalse);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ecmIfInt:
|
|
/* BLOCK */
|
|
{
|
|
LONG arg1 = atol(szArg1);
|
|
LONG arg2 = atol(szArg2);
|
|
|
|
switch (spc)
|
|
{
|
|
case spcEQ:
|
|
return ((arg1 == arg2) ? ercTrue : ercFalse);
|
|
case spcNE:
|
|
return ((arg1 != arg2) ? ercTrue : ercFalse);
|
|
case spcLT:
|
|
return ((arg1 < arg2) ? ercTrue : ercFalse);
|
|
case spcLE:
|
|
return ((arg1 <= arg2) ? ercTrue : ercFalse);
|
|
case spcGT:
|
|
return ((arg1 > arg2) ? ercTrue : ercFalse);
|
|
case spcGE:
|
|
return ((arg1 >= arg2) ? ercTrue : ercFalse);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ecmIfContainsI:
|
|
EvalAssert(SzStrUpper(szArg1) == szArg1);
|
|
EvalAssert(SzStrUpper(szArg2) == szArg2);
|
|
case ecmIfContains:
|
|
switch (spc)
|
|
{
|
|
case spcIn:
|
|
case spcNotIn:
|
|
/* BLOCK */
|
|
{
|
|
RGSZ rgsz;
|
|
PSZ psz;
|
|
|
|
while ((rgsz = RgszFromSzListValue(szArg2)) == (RGSZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
return(ercError);
|
|
|
|
if ((psz = rgsz) != (RGSZ)NULL)
|
|
{
|
|
while (*psz != (SZ)NULL)
|
|
{
|
|
if (CrcStringCompare(szArg1, *psz) == crcEqual)
|
|
{
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
return((spc == spcIn) ? ercTrue : ercFalse);
|
|
}
|
|
psz++;
|
|
}
|
|
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
return((spc == spcIn) ? ercFalse : ercTrue);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return(ercError);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Skips Script statements until an ENDIF statement is reached.
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** Notes:
|
|
** Requires that psptFlow was initialized with a successful call to
|
|
** FInitFlowPspt().
|
|
** Returns:
|
|
** fTrue if successful.
|
|
** fFalse if an ENDIF was not found before running out of Script
|
|
** statements in the current INF section.
|
|
**
|
|
**************************************************************************/
|
|
BOOL APIENTRY FSkipToEnd(INT *Line,HWND hwndParent)
|
|
{
|
|
UINT cEndsToSkip = 1;
|
|
UINT cFields;
|
|
SZ szCmd;
|
|
SPC spc;
|
|
|
|
PreCondFlowInit(fFalse);
|
|
|
|
do {
|
|
do {
|
|
if ((*Line = FindNextLineFromInf(*Line)) == -1)
|
|
return(fTrue); /* REVIEW */
|
|
} while ((cFields = CFieldsInInfLine(*Line)) == 0);
|
|
|
|
while ((szCmd = SzGetNthFieldFromInfLine(*Line,1)) == (SZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
|
|
EvalAssert((spc = SpcParseString(psptFlow, szCmd)) != spcError);
|
|
SFree(szCmd);
|
|
|
|
if (spc >= spcIfFirst &&
|
|
spc <= spcIfLast)
|
|
cEndsToSkip++;
|
|
} while (spc != spcEndIf ||
|
|
cEndsToSkip-- != 1);
|
|
|
|
return(fTrue); /* REVIEW */
|
|
return((BOOL)(cFields == 1));
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Skips to the next ELSE or ENDIF statement, and if it is an ELSE-IF,
|
|
** evaluates it and possibly skips to the next ELSE statement.
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** Notes:
|
|
** Requires that psptFlow was initialized with a successful call to
|
|
** FInitFlowPspt().
|
|
** Returns:
|
|
** fTrue if successful.
|
|
** fFalse if an ENDIF or ELSEIF was not found before running out of Script
|
|
** statements in the current INF section.
|
|
**
|
|
**************************************************************************/
|
|
BOOL APIENTRY FSkipToElse(INT *Line,HWND hwndParent)
|
|
{
|
|
UINT cEndsToSkip = 0;
|
|
UINT cFields;
|
|
SPC spc;
|
|
|
|
PreCondFlowInit(fFalse);
|
|
|
|
do {
|
|
ECM ecm;
|
|
ERC erc;
|
|
RGSZ rgsz;
|
|
SZ sz;
|
|
|
|
if ((*Line = FindNextLineFromInf(*Line)) == -1)
|
|
return(fTrue);
|
|
|
|
while((sz = SzGetNthFieldFromInfLine(*Line,1)) == NULL) {
|
|
if(!FHandleOOM(hwndParent)) {
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
EvalAssert((spc = SpcParseString(psptFlow, sz)) != spcError);
|
|
|
|
if ((spc >= spcIfFirst) && (spc <= spcIfLast)) {
|
|
cEndsToSkip++;
|
|
}
|
|
|
|
if (cEndsToSkip > 0) {
|
|
SFree(sz);
|
|
continue;
|
|
}
|
|
|
|
if (spc == spcElseIfStr) {
|
|
ecm = ecmIfStr;
|
|
} else if (spc == spcElseIfInt) {
|
|
ecm = ecmIfInt;
|
|
} else if (spc == spcElseIfStrI) {
|
|
ecm = ecmIfStrI;
|
|
} else if (spc == spcElseIfContains) {
|
|
ecm = ecmIfContains;
|
|
} else if (spc == spcElseIfContainsI) {
|
|
ecm = ecmIfContainsI;
|
|
} else {
|
|
SFree(sz);
|
|
continue;
|
|
}
|
|
|
|
cFields = CFieldsInInfLine(*Line);
|
|
|
|
if (cFields != 4) {
|
|
SFree(sz);
|
|
continue; /* REVIEW */
|
|
return(fFalse);
|
|
}
|
|
|
|
SFree(sz);
|
|
|
|
while((rgsz = RgszFromInfScriptLine(*Line,cFields)) == NULL) {
|
|
if(!FHandleOOM(hwndParent)) {
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
if (spc == spcIfStrI || spc == spcIfContainsI) {
|
|
|
|
EvalAssert(SzStrUpper(rgsz[1]) == rgsz[1]);
|
|
EvalAssert(SzStrUpper(rgsz[3]) == rgsz[3]);
|
|
}
|
|
|
|
if ((erc = ErcEvaluateCompare(hwndParent, ecm, rgsz[1], rgsz[3],
|
|
rgsz[2])) == ercError)
|
|
{
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
continue; /* REVIEW */
|
|
return(fFalse);
|
|
}
|
|
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
|
|
if (erc == ercTrue)
|
|
return(fTrue);
|
|
|
|
} while ((spc != spcEndIf || cEndsToSkip-- > 0) && (spc != spcElse || cEndsToSkip > 0));
|
|
|
|
return(fTrue); /* REVIEW */
|
|
return((BOOL)(cFields == 1));
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Allocates a new empty SEFL struct.
|
|
** Arguments:
|
|
** none
|
|
** Returns:
|
|
** non-Null PSEFL if successful; NULL otherwise.
|
|
**
|
|
**************************************************************************/
|
|
PSEFL APIENTRY PseflAlloc(VOID)
|
|
{
|
|
PSEFL psefl;
|
|
|
|
if ((psefl = (PSEFL)SAlloc((CB)sizeof(SEFL))) != (PSEFL)NULL)
|
|
{
|
|
psefl->rgszList = (RGSZ)NULL;
|
|
psefl->szDollarSav = (SZ)NULL;
|
|
psefl->szPoundSav = (SZ)NULL;
|
|
}
|
|
|
|
return(psefl);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Frees an SEFL struct and any non-Null fields.
|
|
** Arguments:
|
|
** psefl: non-Null SEFL to free.
|
|
** Returns:
|
|
** fTrue if successful; fFalse otherwise.
|
|
**
|
|
**************************************************************************/
|
|
BOOL APIENTRY FFreePsefl(psefl)
|
|
PSEFL psefl;
|
|
{
|
|
ChkArg(psefl != (PSEFL)NULL, 1, fFalse);
|
|
|
|
if(psefl->rgszList) {
|
|
FFreeRgsz(psefl->rgszList);
|
|
}
|
|
|
|
if(psefl->szDollarSav) {
|
|
SFree(psefl->szDollarSav);
|
|
}
|
|
|
|
if(psefl->szPoundSav) {
|
|
SFree(psefl->szPoundSav);
|
|
}
|
|
|
|
SFree(psefl);
|
|
|
|
return(fTrue);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Skips Script statements until an ENDFORLISTDO statement is reached.
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** Notes:
|
|
** Requires that psptFlow was initialized with a successful call to
|
|
** FInitFlowPspt().
|
|
** Returns:
|
|
** fTrue if successful.
|
|
** fFalse if an ENDFORLISTDO was not found before running out of Script
|
|
** statements in the current INF section.
|
|
**
|
|
**************************************************************************/
|
|
BOOL APIENTRY FSkipToEndOfLoop(INT *Line,HWND hwndParent)
|
|
{
|
|
UINT cEndOfLoopsToSkip = 1;
|
|
UINT cFields;
|
|
SZ szCmd;
|
|
SPC spc;
|
|
|
|
PreCondFlowInit(fFalse);
|
|
|
|
do {
|
|
do {
|
|
if ((*Line = FindNextLineFromInf(*Line)) == -1)
|
|
return(fTrue); /* REVIEW */
|
|
} while ((cFields = CFieldsInInfLine(*Line)) == 0);
|
|
|
|
while ((szCmd = SzGetNthFieldFromInfLine(*Line,1)) == (SZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
|
|
EvalAssert((spc = SpcParseString(psptFlow, szCmd)) != spcError);
|
|
SFree(szCmd);
|
|
|
|
if (spc == spcForListDo)
|
|
cEndOfLoopsToSkip++;
|
|
} while (spc != spcEndForListDo ||
|
|
cEndOfLoopsToSkip-- != 1);
|
|
|
|
return(fTrue); /* REVIEW */
|
|
return((BOOL)(cFields == 1));
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Handles a ForListDo statement by setting up the appropriate structs
|
|
** and setting $($) and $(#).
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** szList: non-Null list to handle in For Loop.
|
|
** Notes:
|
|
** Requires that psptFlow was initialized with a successful call to
|
|
** FInitFlowPspt().
|
|
** Requires that statements within the loop do not jump out of the loop
|
|
** (eg no GoTo to outside the loop or If/EndIf block that straddles a loop
|
|
** boundary).
|
|
** Returns:
|
|
** fTrue if successful; fFalse otherwise.
|
|
**
|
|
**************************************************************************/
|
|
BOOL APIENTRY FInitForLoop(INT *Line,HWND hwndParent,SZ szList)
|
|
{
|
|
PSEFL psefl;
|
|
RGSZ rgsz;
|
|
SZ sz;
|
|
|
|
ChkArg(szList != (SZ)NULL, 1, fFalse);
|
|
|
|
PreCondFlowInit(fFalse);
|
|
|
|
while ((rgsz = RgszFromSzListValue(szList)) == (RGSZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
|
|
if (*rgsz == (SZ)NULL)
|
|
{
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
return(FSkipToEndOfLoop(Line,hwndParent));
|
|
}
|
|
|
|
while ((psefl = PseflAlloc()) == (PSEFL)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
{
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
return(fFalse);
|
|
}
|
|
|
|
psefl->rgszList = rgsz;
|
|
psefl->iItemCur = 1;
|
|
|
|
psefl->iStartLine = *Line;
|
|
if ((sz = SzFindSymbolValueInSymTab("$")) != (SZ)NULL)
|
|
while ((psefl->szDollarSav = SzDupl(sz)) == (SZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
{
|
|
EvalAssert(FFreePsefl(psefl));
|
|
return(fFalse);
|
|
}
|
|
|
|
if ((sz = SzFindSymbolValueInSymTab("#")) != (SZ)NULL)
|
|
while ((psefl->szPoundSav = SzDupl(sz)) == (SZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
{
|
|
EvalAssert(FFreePsefl(psefl));
|
|
return(fFalse);
|
|
}
|
|
|
|
while (!FAddSymbolValueToSymTab("#", "1"))
|
|
if (!FHandleOOM(hwndParent))
|
|
{
|
|
EvalAssert(FFreePsefl(psefl));
|
|
return(fFalse);
|
|
}
|
|
|
|
while (!FAddSymbolValueToSymTab("$", rgsz[0]))
|
|
if (!FHandleOOM(hwndParent))
|
|
{
|
|
EvalAssert(FFreePsefl(psefl));
|
|
return(fFalse);
|
|
}
|
|
|
|
psefl->pseflNext = pLocalContext()->pseflHead;
|
|
pLocalContext()->pseflHead = psefl;
|
|
|
|
return(fTrue);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Handles an EndForListDo statement by resetting $($) and $(#) and
|
|
** jumping back to the top of the loop (if appropriate).
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** Notes:
|
|
** Requires that a ForListDo statement was previously successfully handled.
|
|
** Returns:
|
|
** fTrue if successful; fFalse otherwise.
|
|
**
|
|
**************************************************************************/
|
|
BOOL APIENTRY FContinueForLoop(INT *Line,HWND hwndParent)
|
|
{
|
|
PSEFL psefl = pLocalContext()->pseflHead;
|
|
PCHP rgchp = (PCHP)NULL;
|
|
|
|
PreCondition(psefl != (PSEFL)NULL, fFalse);
|
|
|
|
if (*(psefl->rgszList + psefl->iItemCur) == (SZ)NULL)
|
|
{
|
|
pLocalContext()->pseflHead = psefl->pseflNext;
|
|
|
|
if (psefl->szDollarSav == (SZ)NULL)
|
|
EvalAssert(FRemoveSymbolFromSymTab("$"));
|
|
else
|
|
while (!FAddSymbolValueToSymTab("$", psefl->szDollarSav))
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
|
|
if (psefl->szPoundSav == (SZ)NULL)
|
|
EvalAssert(FRemoveSymbolFromSymTab("#"));
|
|
else
|
|
while (!FAddSymbolValueToSymTab("#", psefl->szPoundSav))
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
|
|
EvalAssert(FFreePsefl(psefl));
|
|
|
|
return(fTrue);
|
|
}
|
|
|
|
while (!FAddSymbolValueToSymTab("$", *(psefl->rgszList + psefl->iItemCur)))
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
while ((rgchp = (PCHP)SAlloc((CB)(20 * sizeof(CHP)))) == (PCHP)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
EvalAssert(_itoa(++(psefl->iItemCur), rgchp, 10) == rgchp);
|
|
while (!FAddSymbolValueToSymTab("#", rgchp))
|
|
if (!FHandleOOM(hwndParent))
|
|
{
|
|
SFree(rgchp);
|
|
return(fFalse);
|
|
}
|
|
|
|
SFree(rgchp);
|
|
*Line = psefl->iStartLine;
|
|
|
|
return(fTrue);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Processes a string and replaces symbol references ('$(SYM)').
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** sz: non-Null string to process.
|
|
** Returns:
|
|
** non-Null string if successful; Null otherwise.
|
|
**
|
|
**************************************************************************/
|
|
SZ APIENTRY SzProcessSzForSyms(hwndParent, sz)
|
|
HWND hwndParent;
|
|
SZ sz;
|
|
{
|
|
SZ szNew, szCur;
|
|
|
|
ChkArg(sz != (SZ)NULL, 1, (SZ)NULL);
|
|
|
|
/* REVIEW doesn't check for running off end of buffer */
|
|
while ((szNew = (SZ)SAlloc((CB)cbSymbolMax)) == (SZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
return((SZ)NULL);
|
|
|
|
szCur = szNew;
|
|
while (*sz != '\0')
|
|
{
|
|
SZ szNext;
|
|
|
|
if (*sz == '$' && *(sz + 1) == '(')
|
|
{
|
|
szNext = sz;
|
|
|
|
while (*szNext != ')' && *szNext != '\0')
|
|
szNext++;
|
|
|
|
if (*szNext == ')')
|
|
{
|
|
SZ szValue;
|
|
|
|
*szNext = '\0';
|
|
sz += 2;
|
|
|
|
if ((szValue = SzFindSymbolValueInSymTab(sz)) != (SZ)NULL)
|
|
{
|
|
EvalAssert(strcpy(szCur, szValue) == szCur);
|
|
while (*szCur != '\0')
|
|
szCur = SzNextChar(szCur);
|
|
}
|
|
|
|
*szNext = ')';
|
|
sz = szNext + 1;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
szNext = SzNextChar(sz);
|
|
while (sz < szNext)
|
|
*szCur++ = *sz++;
|
|
}
|
|
|
|
*szCur = '\0';
|
|
Assert(strlen(szNew) < (CB)(cbSymbolMax - 1));
|
|
|
|
szCur = SRealloc(szNew,strlen(szNew)+1);
|
|
Assert(szCur);
|
|
|
|
return(szCur);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Processes a string and replaces escape sequences (\n \r \t \###
|
|
** where ### is an octal number) with their byte equivalent.
|
|
** Arguments:
|
|
** hwndParent: window handle to be used in MessageBoxes. NULL implies
|
|
** no message box - just fail.
|
|
** sz: non-Null string to process.
|
|
** Returns:
|
|
** non-Null string if successful; Null otherwise.
|
|
**
|
|
**************************************************************************/
|
|
SZ APIENTRY SzProcessSz(hwndParent, sz)
|
|
HWND hwndParent;
|
|
SZ sz;
|
|
{
|
|
SZ szNew, szCur;
|
|
|
|
ChkArg(sz != (SZ)NULL && strlen(sz) < cbSymbolMax, 2, (SZ)NULL);
|
|
|
|
while ((szNew = (SZ)SAlloc(cbSymbolMax)) == (SZ)NULL)
|
|
if (hwndParent == NULL || !FHandleOOM(hwndParent))
|
|
return((SZ)NULL);
|
|
|
|
szCur = szNew;
|
|
while (*sz != '\0')
|
|
{
|
|
if (*sz == '\\')
|
|
{
|
|
CHP chp1, chp2, chp3;
|
|
|
|
if ((chp1 = *(++sz)) == '\\')
|
|
*szCur++ = '\\';
|
|
else if (chp1 == 'n')
|
|
*szCur++ = '\n';
|
|
else if (chp1 == 'r')
|
|
*szCur++ = '\r';
|
|
else if (chp1 == 't')
|
|
*szCur++ = '\t';
|
|
else if (chp1 < '0' || chp1 > '7' ||
|
|
(chp2 = *(sz + 1)) < '0' || chp2 > '7')
|
|
{
|
|
*szCur++ = '\\';
|
|
*szCur++ = chp1;
|
|
}
|
|
else if ((chp3 = *(sz + 2)) < '0' || chp3 > '7' ||
|
|
(chp1 == '0' && chp2 == '0' && chp3 == '0'))
|
|
{
|
|
*szCur++ = '\\';
|
|
*szCur++ = chp1;
|
|
*szCur++ = chp2;
|
|
*szCur++ = chp3;
|
|
sz += 2;
|
|
}
|
|
else
|
|
{
|
|
*szCur++ = (CHP)(64*(chp1-'0') + 8*(chp2-'0') + chp3-'0');
|
|
sz += 2;
|
|
}
|
|
sz++;
|
|
}
|
|
else
|
|
{
|
|
SZ szNext;
|
|
|
|
szNext = SzNextChar(sz);
|
|
while (sz < szNext)
|
|
*szCur++ = *sz++;
|
|
}
|
|
}
|
|
|
|
*szCur = '\0';
|
|
Assert(strlen(szNew) < (CB)cbSymbolMax);
|
|
|
|
while ((szCur = SzDupl(szNew)) == (SZ)NULL)
|
|
if (hwndParent == NULL || !FHandleOOM(hwndParent))
|
|
return((SZ)NULL);
|
|
|
|
SFree(szNew);
|
|
|
|
return(szCur);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Handles Flow Script statements (IFs, ELSEs, ENDIFs, GOTOs, SETs),
|
|
** returning when an unrecognized statement is encountered.
|
|
** Arguments:
|
|
** CurrentLine: current line #, gets new line # if return value is fTrue
|
|
** hwndParent: window handle to be used in MessageBoxes.
|
|
** szSection: non-NULL, non-empty section label (goto statements).
|
|
** CallerCFields: if non-NULL, will be filled with the number of fields
|
|
** on the line with the unrecognized statement (if
|
|
** returning TRUE)
|
|
** CallerRgsz: if non-NULL, will get a pointer to the rgsz for the line
|
|
** with the unrecognized statement (if returning true).
|
|
** Notes:
|
|
** Requires that psptFlow was initialized with a successful call to
|
|
** FInitFlowPspt(), that an INF file was successfully opened, that
|
|
** the INF Read location is defined and pointing at the beginning of
|
|
** a script line to be interpreted, and that the Symbol Table was
|
|
** successfully initialized.
|
|
** Returns:
|
|
** fTrue if an unrecognized statement is reached.
|
|
** The caller must free rgsz if CallerRgsz was non-NULL.
|
|
** fFalse if the end of the section is reached before an unrecognized
|
|
** statement is reached, or if a Flow statement has an invalid
|
|
** format.
|
|
**
|
|
**************************************************************************/
|
|
BOOL APIENTRY FHandleFlowStatements(INT *CurrentLine,
|
|
HWND hwndParent,
|
|
SZ szSection,
|
|
UINT *CallerCFields,
|
|
RGSZ *CallerRgsz)
|
|
{
|
|
SPC spc;
|
|
RGSZ rgsz;
|
|
INT Line = *CurrentLine;
|
|
CHP rgchNum[20];
|
|
|
|
PreCondFlowInit(fFalse);
|
|
PreCondInfOpen(fFalse);
|
|
PreCondSymTabInit(fFalse);
|
|
|
|
ChkArg(szSection != (SZ)NULL &&
|
|
*szSection != '\0' &&
|
|
*szSection != '[', 1, fFalse);
|
|
|
|
while (fTrue)
|
|
{
|
|
UINT cFields;
|
|
ECM ecm;
|
|
ERC erc;
|
|
SZ sz, sz2 ;
|
|
|
|
if ((cFields = CFieldsInInfLine(Line)) == 0)
|
|
{
|
|
rgsz = (RGSZ)NULL;
|
|
spc = spcSet;
|
|
goto LNextFlowLine;
|
|
}
|
|
|
|
while ((rgsz = RgszFromInfScriptLine(Line,cFields)) == (RGSZ)NULL)
|
|
if (!FHandleOOM(hwndParent))
|
|
return(fFalse);
|
|
|
|
switch ((spc = SpcParseString(psptFlow, rgsz[0])))
|
|
{
|
|
case spcSet:
|
|
SdAtNewLine(Line);
|
|
|
|
if (cFields != 4 ||
|
|
*(rgsz[1]) == '\0' ||
|
|
CrcStringCompare(rgsz[2], "=") != crcEqual)
|
|
goto LFlowParseError;
|
|
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], rgsz[3]))
|
|
if (!FHandleOOM(hwndParent))
|
|
goto LFlowParseExitErr;
|
|
break;
|
|
|
|
case spcSetSubsym:
|
|
case spcSetSubst:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 4 ||
|
|
*(rgsz[1]) == '\0' ||
|
|
CrcStringCompare(rgsz[2], "=") != crcEqual)
|
|
goto LFlowParseError;
|
|
|
|
if ((spc == spcSetSubsym &&
|
|
(sz=SzProcessSzForSyms(hwndParent,rgsz[3])) == (SZ)NULL) ||
|
|
(spc == spcSetSubst &&
|
|
(sz = SzProcessSz(hwndParent, rgsz[3])) == (SZ)NULL))
|
|
goto LFlowParseExitErr;
|
|
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], sz))
|
|
if (!FHandleOOM(hwndParent))
|
|
{
|
|
SFree(sz);
|
|
goto LFlowParseExitErr;
|
|
}
|
|
|
|
SFree(sz);
|
|
break;
|
|
|
|
case spcSetAdd:
|
|
case spcSetSub:
|
|
case spcSetMul:
|
|
case spcSetDiv:
|
|
case spcSetOr:
|
|
|
|
SdAtNewLine(Line);
|
|
if ( cFields != 5 ||
|
|
*(rgsz[1]) == '\0' ||
|
|
CrcStringCompare(rgsz[2], "="
|
|
) != crcEqual) {
|
|
|
|
goto LFlowParseError;
|
|
}
|
|
|
|
switch ( spc ) {
|
|
|
|
case spcSetAdd:
|
|
|
|
_ltoa ( atol(rgsz[3]) + atol(rgsz[4]), rgchNum, 10 );
|
|
break;
|
|
|
|
case spcSetSub:
|
|
|
|
_ltoa ( atol(rgsz[3]) - atol(rgsz[4]), rgchNum, 10 );
|
|
break;
|
|
|
|
case spcSetMul:
|
|
|
|
_ltoa ( atol(rgsz[3]) * atol(rgsz[4]), rgchNum, 10 );
|
|
break;
|
|
|
|
|
|
case spcSetDiv:
|
|
|
|
_ltoa ( atol(rgsz[3]) / atol(rgsz[4]), rgchNum, 10 );
|
|
break;
|
|
|
|
case spcSetOr:
|
|
_ultoa ( (ULONG)atol(rgsz[2]) | (ULONG)atol(rgsz[4]), rgchNum, 10);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], rgchNum)) {
|
|
if (!FHandleOOM(hwndParent)) {
|
|
goto LFlowParseExitErr;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case spcSetHexToDec:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 4 ||
|
|
*(rgsz[1]) == '\0' ||
|
|
CrcStringCompare(rgsz[2], "=") != crcEqual)
|
|
goto LFlowParseError;
|
|
|
|
|
|
_ltoa ( strtoul(rgsz[3],(char **)NULL,16), rgchNum, 10 );
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], rgchNum))
|
|
if (!FHandleOOM(hwndParent))
|
|
goto LFlowParseExitErr;
|
|
break;
|
|
|
|
case spcSetDecToHex:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 4 ||
|
|
*(rgsz[1]) == '\0' ||
|
|
CrcStringCompare(rgsz[2], "=") != crcEqual)
|
|
goto LFlowParseError;
|
|
|
|
wsprintf(rgchNum,"0x%X",atol(rgsz[3]));
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], rgchNum))
|
|
if (!FHandleOOM(hwndParent))
|
|
goto LFlowParseExitErr;
|
|
break;
|
|
|
|
case spcDebugMsg:
|
|
#if DBG
|
|
SdAtNewLine(Line);
|
|
if (cFields != 2)
|
|
goto LFlowParseError;
|
|
|
|
if ((sz = SzProcessSzForSyms(hwndParent, rgsz[1])) == (SZ)NULL)
|
|
goto LFlowParseExitErr;
|
|
|
|
EvalAssert(LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax));
|
|
MessageBox(hwndParent, sz, rgchBufTmpShort, MB_OK | MB_TASKMODAL);
|
|
|
|
SFree(sz);
|
|
#endif /* DBG */
|
|
break;
|
|
|
|
case spcIfStrI:
|
|
ecm = ecmIfStrI;
|
|
goto LHandleIfs;
|
|
case spcIfInt:
|
|
ecm = ecmIfInt;
|
|
goto LHandleIfs;
|
|
case spcIfContains:
|
|
ecm = ecmIfContains;
|
|
goto LHandleIfs;
|
|
case spcIfContainsI:
|
|
ecm = ecmIfContainsI;
|
|
goto LHandleIfs;
|
|
case spcIfStr:
|
|
ecm = ecmIfStr;
|
|
LHandleIfs:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 4)
|
|
goto LFlowParseError;
|
|
|
|
if (spc == spcIfStrI ||
|
|
spc == spcIfContainsI)
|
|
{
|
|
EvalAssert(SzStrUpper(rgsz[1]) == rgsz[1]);
|
|
EvalAssert(SzStrUpper(rgsz[3]) == rgsz[3]);
|
|
}
|
|
|
|
if ((erc = ErcEvaluateCompare(hwndParent, ecm, rgsz[1], rgsz[3],
|
|
rgsz[2])) == ercError)
|
|
goto LFlowParseError;
|
|
|
|
if (erc == ercFalse &&
|
|
!FSkipToElse(&Line,hwndParent))
|
|
goto LFlowParseExitErr;
|
|
break;
|
|
|
|
case spcEndIf:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 1)
|
|
goto LFlowParseError;
|
|
break;
|
|
|
|
case spcElse:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 1)
|
|
goto LFlowParseError;
|
|
case spcElseIfStr:
|
|
case spcElseIfStrI:
|
|
case spcElseIfInt:
|
|
case spcElseIfContains:
|
|
case spcElseIfContainsI:
|
|
SdAtNewLine(Line);
|
|
if (spc != spcElse &&
|
|
cFields != 4)
|
|
goto LFlowParseError;
|
|
|
|
if (!FSkipToEnd(&Line,hwndParent))
|
|
goto LFlowParseExitErr;
|
|
break;
|
|
|
|
case spcGoTo:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 2 ||
|
|
*(rgsz[1]) == '\0' ||
|
|
(Line = FindLineFromInfSectionKey(szSection, rgsz[1])) == -1)
|
|
goto LFlowParseError;
|
|
break;
|
|
|
|
case spcForListDo:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 2)
|
|
goto LFlowParseError;
|
|
|
|
if (!FInitForLoop(&Line,hwndParent, rgsz[1]))
|
|
goto LFlowParseExitErr;
|
|
break;
|
|
|
|
case spcEndForListDo:
|
|
SdAtNewLine(Line);
|
|
if (cFields != 1)
|
|
goto LFlowParseError;
|
|
|
|
if (!FContinueForLoop(&Line,hwndParent))
|
|
goto LFlowParseExitErr;
|
|
break;
|
|
|
|
case spcHourglass:
|
|
SdAtNewLine(Line);
|
|
if(cFields != 1) {
|
|
goto LFlowParseError;
|
|
}
|
|
SetCursor(CurrentCursor = LoadCursor(NULL,IDC_WAIT));
|
|
break;
|
|
|
|
case spcArrow:
|
|
SdAtNewLine(Line);
|
|
if(cFields != 1) {
|
|
goto LFlowParseError;
|
|
}
|
|
SetCursor(CurrentCursor = LoadCursor(NULL,IDC_ARROW));
|
|
break;
|
|
|
|
case spcSetHelpFile:
|
|
SdAtNewLine(Line);
|
|
|
|
//
|
|
// Command is SetHelpFile "helpfilename" "locontext" "highcontext" "helpindex-optional"
|
|
//
|
|
|
|
if (cFields < 4) {
|
|
goto LFlowParseError;
|
|
}
|
|
|
|
if (cFields == 4) {
|
|
if ( !FInitWinHelpFile (
|
|
hWndShell,
|
|
rgsz[1],
|
|
rgsz[2],
|
|
rgsz[3],
|
|
(SZ)NULL
|
|
) ) {
|
|
goto LFlowParseExitErr;
|
|
}
|
|
}
|
|
else {
|
|
if ( !FInitWinHelpFile (
|
|
hWndShell,
|
|
rgsz[1],
|
|
rgsz[2],
|
|
rgsz[3],
|
|
rgsz[4]
|
|
) ) {
|
|
goto LFlowParseExitErr;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case spcGetDriveInPath:
|
|
|
|
SdAtNewLine(Line);
|
|
{
|
|
SZ sz;
|
|
CHP chp1, chp2, rgchDrive[3];
|
|
|
|
//
|
|
// Command: GetDriveInPath DriveVar, Path
|
|
//
|
|
|
|
if (cFields != 3) {
|
|
goto LFlowParseError;
|
|
}
|
|
|
|
sz = rgsz[2];
|
|
rgchDrive[0] = '\0';
|
|
|
|
if ( ((chp1 = *sz++) != '\0') &&
|
|
((chp2 = *sz) == ':') &&
|
|
((chp1 >= 'a' && chp1 <='z') || (chp1 >= 'A' && chp1 <= 'Z'))) {
|
|
rgchDrive[0] = chp1;
|
|
rgchDrive[1] = chp2;
|
|
rgchDrive[2] = '\0';
|
|
}
|
|
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], rgchDrive)) {
|
|
if (!FHandleOOM(hwndParent)) {
|
|
goto LFlowParseExitErr;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
case spcGetDirInPath:
|
|
|
|
SdAtNewLine(Line);
|
|
{
|
|
SZ sz, sz1;
|
|
SZ szUNDEF = "";
|
|
|
|
//
|
|
// Command: GetDirInPath DirVar, Path
|
|
//
|
|
|
|
if (cFields != 3) {
|
|
goto LFlowParseError;
|
|
}
|
|
|
|
sz = rgsz[2];
|
|
sz1 = (SZ)strchr(sz, '\\');
|
|
|
|
if (sz1 == NULL) {
|
|
|
|
sz1 = szUNDEF;
|
|
|
|
}
|
|
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], sz1)) {
|
|
if (!FHandleOOM(hwndParent)) {
|
|
goto LFlowParseExitErr;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
case spcCreateRegKey:
|
|
case spcOpenRegKey:
|
|
case spcFlushRegKey:
|
|
case spcCloseRegKey:
|
|
case spcDeleteRegKey:
|
|
case spcDeleteRegTree:
|
|
case spcEnumRegKey:
|
|
case spcSetRegValue:
|
|
case spcGetRegValue:
|
|
case spcDeleteRegValue:
|
|
case spcEnumRegValue:
|
|
SdAtNewLine(Line);
|
|
if (!FParseRegistrySection(Line, &cFields, spc)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcLoadLibrary:
|
|
SdAtNewLine(Line);
|
|
if(!FParseLoadLibrary(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcFreeLibrary:
|
|
SdAtNewLine(Line);
|
|
if(!FParseFreeLibrary(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcLibraryProcedure:
|
|
SdAtNewLine(Line);
|
|
if(!FParseLibraryProcedure(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcRunExternalProgram:
|
|
SdAtNewLine(Line);
|
|
if(!FParseRunExternalProgram(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcInvokeApplet:
|
|
SdAtNewLine(Line);
|
|
if(!FParseInvokeApplet(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcStartDetachedProcess:
|
|
SdAtNewLine(Line);
|
|
if(!FParseStartDetachedProcess(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcWaitOnEvent:
|
|
SdAtNewLine(Line);
|
|
if(!FParseWaitOnEvent(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcSignalEvent:
|
|
SdAtNewLine(Line);
|
|
if(!FParseSignalEvent(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcSleep:
|
|
SdAtNewLine(Line);
|
|
if(!FParseSleep(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcFlushInf:
|
|
SdAtNewLine(Line);
|
|
if(!FParseFlushInf(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcBmpShow:
|
|
SdAtNewLine(Line);
|
|
if(!FParseBmpShow(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break ;
|
|
case spcBmpHide:
|
|
SdAtNewLine(Line);
|
|
if(!FParseBmpHide(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break ;
|
|
|
|
case spcDebugOutput:
|
|
#if DEVL
|
|
SdAtNewLine(Line);
|
|
if (cFields != 2)
|
|
goto LFlowParseError;
|
|
|
|
if ((sz = SzProcessSzForSyms(hwndParent, rgsz[1])) == (SZ)NULL)
|
|
goto LFlowParseExitErr;
|
|
|
|
if ( (sz2 = SzFindSymbolValueInSymTab("!G:DebugOutputControl"))
|
|
&& atol(sz2) == 0 )
|
|
break;
|
|
|
|
OutputDebugString( "SETUP:" );
|
|
OutputDebugString( sz ) ;
|
|
OutputDebugString( "\n" );
|
|
|
|
SFree(sz);
|
|
#endif
|
|
break;
|
|
|
|
case spcQueryListSize:
|
|
SdAtNewLine(Line);
|
|
{
|
|
INT ListSize = 0;
|
|
CHP rgchListSize[10];
|
|
|
|
if( cFields != 3 )
|
|
{
|
|
goto LFlowParseError;
|
|
}
|
|
else
|
|
{
|
|
RGSZ rgszList = NULL;
|
|
if ((rgszList = RgszFromSzListValue( rgsz[2] )) != NULL )
|
|
{
|
|
for(ListSize=0;rgszList[ListSize]; ListSize++)
|
|
{
|
|
;
|
|
}
|
|
}
|
|
}
|
|
while (!FAddSymbolValueToSymTab(rgsz[1], _itoa(ListSize, rgchListSize, 10))) {
|
|
if (!FHandleOOM(hwndParent)) {
|
|
goto LFlowParseExitErr;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case spcAddFileToDeleteList:
|
|
SdAtNewLine(Line);
|
|
|
|
if(!FParseAddFileToDeleteList(Line, &cFields)) {
|
|
goto LFlowParseError;
|
|
}
|
|
break;
|
|
|
|
case spcInitRestoreDiskLog:
|
|
SdAtNewLine(Line);
|
|
if( cFields != 1 ) {
|
|
goto LFlowParseError;
|
|
}
|
|
InitRestoreDiskLogging(TRUE);
|
|
break;
|
|
|
|
case spcTermRestoreDiskLog:
|
|
SdAtNewLine(Line);
|
|
if( cFields != 1 ) {
|
|
goto LFlowParseError;
|
|
}
|
|
TermRestoreDiskLogging();
|
|
break;
|
|
|
|
|
|
|
|
case spcSplitString:
|
|
SdAtNewLine(Line);
|
|
if( cFields != 4 )
|
|
{
|
|
goto LFlowParseError;
|
|
}
|
|
else
|
|
{
|
|
CHP rgchSplitString[2000];
|
|
SZ szSource;
|
|
SZ szSource2;
|
|
SZ szSep;
|
|
SZ szSep2;
|
|
SZ szSplitString;
|
|
INT i;
|
|
BOOL fAddComma;
|
|
BOOL fFind;
|
|
BOOL fFirst;
|
|
|
|
szSplitString = rgchSplitString;
|
|
|
|
if ((( szSource = SzProcessSzForSyms( hwndParent, rgsz[1] )) == (SZ)NULL) ||
|
|
(( szSep = SzProcessSzForSyms( hwndParent, rgsz[2] )) == (SZ)NULL ))
|
|
{
|
|
goto LFlowParseExitErr;
|
|
}
|
|
|
|
fAddComma = FALSE;
|
|
fFirst = TRUE;
|
|
|
|
*szSplitString++='{';
|
|
szSource2 = szSource;
|
|
|
|
while( *szSource2 != '\0' )
|
|
{
|
|
if ( fAddComma )
|
|
{
|
|
*szSplitString++=',';
|
|
fAddComma = FALSE;
|
|
}
|
|
if ( fFirst )
|
|
{
|
|
*szSplitString++='"';
|
|
}
|
|
szSep2 = szSep;
|
|
fFind = FALSE;
|
|
for ( i = 0; i < (INT)strlen( szSep ); i ++ )
|
|
{
|
|
if ( FSingleByteCharSz( szSep2 ) == FSingleByteCharSz( szSource2 ))
|
|
{
|
|
if ( FSingleByteCharSz( szSep2 ))
|
|
{
|
|
if ( *szSep2 == *szSource2 )
|
|
{
|
|
fFind = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (( *szSep2 == *szSource2 ) &&
|
|
( *(szSep2+1) == *(szSource2+1)))
|
|
{
|
|
fFind = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
szSep2 = SzNextChar(szSep2);
|
|
}
|
|
if (fFind)
|
|
{
|
|
if (!fFirst)
|
|
{
|
|
*szSplitString++ = '"';
|
|
*szSplitString++ = ',';
|
|
*szSplitString++ = '"';
|
|
}
|
|
*szSplitString++ = *szSep2;
|
|
if ( !FSingleByteCharSz( szSep2 ))
|
|
{
|
|
*szSplitString++ = *(szSep2+1);
|
|
}
|
|
*szSplitString++ = '"';
|
|
fAddComma = TRUE;
|
|
fFirst = TRUE;
|
|
}
|
|
else
|
|
{
|
|
*szSplitString++ = *szSource2;
|
|
if ( !FSingleByteCharSz( szSource2 ))
|
|
{
|
|
*szSplitString++ = *(szSource2+1);
|
|
}
|
|
fFirst = FALSE;
|
|
}
|
|
szSource2 = SzNextChar( szSource2 );
|
|
}
|
|
if (!fFirst)
|
|
{
|
|
*szSplitString++='"';
|
|
}
|
|
*szSplitString++='}';
|
|
*szSplitString++='\0';
|
|
|
|
while (!FAddSymbolValueToSymTab(rgsz[3], rgchSplitString)) {
|
|
if (!FHandleOOM(hwndParent)) {
|
|
goto LFlowParseExitErr;
|
|
}
|
|
}
|
|
SFree(szSource);
|
|
SFree(szSep);
|
|
}
|
|
break;
|
|
|
|
case spcUnknown:
|
|
if(CallerCFields != NULL) {
|
|
*CallerCFields = cFields;
|
|
}
|
|
if(CallerRgsz != NULL) {
|
|
*CallerRgsz = rgsz;
|
|
} else {
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
}
|
|
*CurrentLine = Line;
|
|
return(fTrue);
|
|
|
|
default:
|
|
Assert(fFalse);
|
|
}
|
|
|
|
LNextFlowLine:
|
|
if (spc != spcGoTo &&
|
|
((Line = FindNextLineFromInf(Line)) == -1))
|
|
{
|
|
if (rgsz != (RGSZ)NULL)
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
EvalAssert(LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax));
|
|
EvalAssert(LoadString(hInst, IDS_NEED_EXIT, rgchBufTmpLong, cchpBufTmpLongMax));
|
|
MessageBox(hwndParent, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND);
|
|
return(fFalse);
|
|
}
|
|
|
|
EvalAssert(rgsz == (RGSZ)NULL ||
|
|
FFreeRgsz(rgsz));
|
|
}
|
|
|
|
Assert(fFalse); /* Should never reach here! */
|
|
|
|
LFlowParseError:
|
|
/* BLOCK */
|
|
{
|
|
#define cchpBuf (2 * cchpFullPathBuf)
|
|
CHP rgchBuf[cchpBuf];
|
|
|
|
EvalAssert(LoadString(hInst, IDS_SHL_CMD_ERROR, rgchBuf, cchpBuf));
|
|
if (rgsz != (RGSZ)NULL ||
|
|
*rgsz != (SZ)NULL)
|
|
{
|
|
USHORT iszCur = 0;
|
|
SZ szCur;
|
|
|
|
while ((szCur = rgsz[iszCur++]) != (SZ)NULL)
|
|
{
|
|
if (iszCur == 1)
|
|
EvalAssert(SzStrCat((SZ)rgchBuf, "\n'") == (SZ)rgchBuf);
|
|
else
|
|
EvalAssert(SzStrCat((SZ)rgchBuf, " ") == (SZ)rgchBuf);
|
|
|
|
if (strlen(rgchBuf) + strlen(szCur) > (cchpBuf - 7))
|
|
{
|
|
Assert(strlen(rgchBuf) <= (cchpBuf - 5));
|
|
EvalAssert(SzStrCat((SZ)rgchBuf, "...") == (SZ)rgchBuf);
|
|
break;
|
|
}
|
|
else
|
|
EvalAssert(SzStrCat((SZ)rgchBuf, szCur) == (SZ)rgchBuf);
|
|
}
|
|
|
|
EvalAssert(SzStrCat((SZ)rgchBuf, "'") == (SZ)rgchBuf);
|
|
}
|
|
|
|
EvalAssert(LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax));
|
|
MessageBox(hwndParent, rgchBuf, rgchBufTmpShort, MB_OK | MB_ICONHAND);
|
|
}
|
|
|
|
LFlowParseExitErr:
|
|
if (rgsz != (RGSZ)NULL)
|
|
EvalAssert(FFreeRgsz(rgsz));
|
|
return(fFalse);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Initializes the structures needed for parsing/handling Flow Script
|
|
** statements. Must be called before FHandleFlowStatements().
|
|
** Arguments:
|
|
** none
|
|
** Returns:
|
|
** fTrue if successful.
|
|
** fFalse if not successful.
|
|
*/
|
|
BOOL APIENTRY FInitFlowPspt(VOID)
|
|
{
|
|
if (psptFlow != (PSPT)NULL)
|
|
return(fFalse);
|
|
|
|
return((BOOL)((psptFlow = PsptInitParsingTable(rgscpFlow)) != (PSPT)NULL));
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Destroys the structures needed for parsing/handling Flow Script
|
|
** statements.
|
|
** Arguments:
|
|
** none
|
|
** Returns:
|
|
** fTrue if successful.
|
|
** fFalse if not successful.
|
|
*/
|
|
BOOL APIENTRY FDestroyFlowPspt(VOID)
|
|
{
|
|
if (psptFlow == (PSPT)NULL ||
|
|
!FDestroyParsingTable(psptFlow))
|
|
return(fFalse);
|
|
|
|
psptFlow = (PSPT)NULL;
|
|
return(fTrue);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseRegistrySection(INT Line, UINT *pcFields, SPC spc)
|
|
{
|
|
|
|
BOOL fOkay = fFalse;
|
|
SZ szHandle = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if ( ( *pcFields >= 1 ) &&
|
|
FGetArgSz( Line, pcFields, &szHandle )
|
|
) {
|
|
|
|
|
|
FAddSymbolValueToSymTab( REGLASTERROR, "0" );
|
|
|
|
switch (spc) {
|
|
|
|
default:
|
|
Assert(fFalse);
|
|
break;
|
|
|
|
case spcCreateRegKey:
|
|
fOkay = FParseCreateRegKey( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcOpenRegKey:
|
|
fOkay = FParseOpenRegKey( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcFlushRegKey:
|
|
fOkay = FParseFlushRegKey( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcCloseRegKey:
|
|
fOkay = FParseCloseRegKey( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcDeleteRegKey:
|
|
fOkay = FParseDeleteRegKey( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcDeleteRegTree:
|
|
fOkay = FParseDeleteRegTree( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcEnumRegKey:
|
|
fOkay = FParseEnumRegKey( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcSetRegValue:
|
|
fOkay = FParseSetRegValue( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcGetRegValue:
|
|
fOkay = FParseGetRegValue( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcDeleteRegValue:
|
|
fOkay = FParseDeleteRegValue( Line, pcFields, szHandle );
|
|
break;
|
|
|
|
case spcEnumRegValue:
|
|
fOkay = FParseEnumRegValue( Line, pcFields, szHandle );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( szHandle ) {
|
|
SFree(szHandle);
|
|
}
|
|
|
|
return( fOkay );
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseOpenRegKey(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szMachineName = NULL;
|
|
SZ szKeyName = NULL;
|
|
UINT AccessMask;
|
|
SZ szNewHandle = NULL;
|
|
CMO cmo;
|
|
|
|
if ( *pcFields >= 4 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szMachineName ) ) {
|
|
if ( FGetArgSz( Line, pcFields, &szKeyName ) ) {
|
|
if ( FGetArgUINT( Line, pcFields, &AccessMask ) ) {
|
|
if ( FGetArgSz( Line, pcFields, &szNewHandle ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FOpenRegKey( szHandle,
|
|
szMachineName,
|
|
szKeyName,
|
|
AccessMask,
|
|
szNewHandle,
|
|
cmo );
|
|
}
|
|
}
|
|
SFree(szNewHandle);
|
|
}
|
|
}
|
|
SFree(szKeyName);
|
|
}
|
|
SFree(szMachineName);
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseFlushRegKey(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
CMO cmo;
|
|
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FFlushRegKey( szHandle, cmo );
|
|
}
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseCloseRegKey(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
CMO cmo;
|
|
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FCloseRegKey( szHandle, cmo );
|
|
}
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseDeleteRegKey(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szKeyName = NULL;
|
|
CMO cmo;
|
|
|
|
if ( *pcFields >= 1 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szKeyName ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FDeleteRegKey( szHandle,
|
|
szKeyName,
|
|
cmo );
|
|
}
|
|
}
|
|
SFree(szKeyName);
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseDeleteRegTree(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szKeyName = NULL;
|
|
CMO cmo;
|
|
|
|
if ( *pcFields >= 1 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szKeyName ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FDeleteRegTree( szHandle,
|
|
szKeyName,
|
|
cmo );
|
|
}
|
|
}
|
|
SFree(szKeyName);
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseEnumRegKey(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szInfVar;
|
|
CMO cmo;
|
|
|
|
if ( *pcFields >= 1 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szInfVar ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FEnumRegKey( szHandle,
|
|
szInfVar,
|
|
cmo );
|
|
}
|
|
SFree( szInfVar );
|
|
}
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseSetRegValue(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szValueInfo = NULL;
|
|
SZ szValueName = NULL;
|
|
UINT TitleIndex;
|
|
UINT ValueType;
|
|
SZ szValueData = NULL;
|
|
RGSZ rgszInfo;
|
|
CMO cmo;
|
|
|
|
|
|
if ( *pcFields >= 1 ) {
|
|
|
|
if ( FGetArgSz( Line, pcFields, &szValueInfo )) {
|
|
|
|
if ( FListValue( szValueInfo )) {
|
|
|
|
if ( rgszInfo = RgszFromSzListValue( szValueInfo )) {
|
|
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
if ( (rgszInfo[0] != NULL) &&
|
|
(rgszInfo[1] != NULL) &&
|
|
(rgszInfo[2] != NULL) &&
|
|
(rgszInfo[3] != NULL) ) {
|
|
|
|
szValueName = rgszInfo[0];
|
|
TitleIndex = atol(rgszInfo[1]);
|
|
ValueType = atol(rgszInfo[2]);
|
|
szValueData = rgszInfo[3];
|
|
|
|
fOkay = FSetRegValue( szHandle,
|
|
szValueName,
|
|
TitleIndex,
|
|
ValueType,
|
|
szValueData,
|
|
cmo );
|
|
}
|
|
}
|
|
}
|
|
FFreeRgsz( rgszInfo );
|
|
}
|
|
}
|
|
SFree( szValueInfo );
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseGetRegValue(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szValueName = NULL;
|
|
SZ szInfVar = NULL;
|
|
CMO cmo;
|
|
|
|
if ( *pcFields >= 2 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szValueName ) ) {
|
|
if ( FGetArgSz( Line, pcFields, &szInfVar ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FGetRegValue( szHandle,
|
|
szValueName,
|
|
szInfVar,
|
|
cmo );
|
|
}
|
|
}
|
|
SFree( szInfVar );
|
|
|
|
}
|
|
SFree( szValueName );
|
|
}
|
|
|
|
return fOkay;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseDeleteRegValue(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szValueName = NULL;
|
|
CMO cmo;
|
|
|
|
if ( *pcFields >= 1 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szValueName ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FDeleteRegValue( szHandle,
|
|
szValueName,
|
|
cmo );
|
|
}
|
|
}
|
|
SFree( szValueName );
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseEnumRegValue(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szInfVar;
|
|
CMO cmo;
|
|
|
|
if ( *pcFields >= 1 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szInfVar ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FEnumRegValue( szHandle,
|
|
szInfVar,
|
|
cmo );
|
|
|
|
}
|
|
SFree( szInfVar );
|
|
}
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseCreateRegKey(INT Line, UINT *pcFields, SZ szHandle)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szKeyInfo;
|
|
SZ szSecurity;
|
|
UINT AccessMask;
|
|
UINT Options;
|
|
SZ szNewHandle;
|
|
SZ szKeyName;
|
|
UINT TitleIndex;
|
|
SZ szClass;
|
|
RGSZ rgszInfo;
|
|
CMO cmo;
|
|
|
|
|
|
if ( *pcFields >= 5 ) {
|
|
if ( FGetArgSz( Line, pcFields, &szKeyInfo ) ) {
|
|
|
|
//
|
|
// Validate the key Info.
|
|
//
|
|
if ( FListValue( szKeyInfo )) {
|
|
|
|
if ( rgszInfo = RgszFromSzListValue( szKeyInfo )) {
|
|
|
|
if ( (rgszInfo[0] != NULL) &&
|
|
(rgszInfo[1] != NULL) &&
|
|
(rgszInfo[2] != NULL ) ) {
|
|
|
|
szKeyName = rgszInfo[0];
|
|
TitleIndex = atol(rgszInfo[1]);
|
|
szClass = rgszInfo[2];
|
|
|
|
if ( FGetArgSz( Line, pcFields, &szSecurity ) ) {
|
|
|
|
//
|
|
// BugBug At this point we should validate the security Info.
|
|
//
|
|
|
|
if ( FGetArgUINT( Line, pcFields, &AccessMask ) ) {
|
|
if ( FGetArgUINT( Line, pcFields, &Options ) ) {
|
|
if ( FGetArgSz( Line, pcFields, &szNewHandle ) ) {
|
|
if ( FGetCmo( Line, pcFields, &cmo )) {
|
|
fOkay = FCreateRegKey( szHandle,
|
|
szKeyName,
|
|
TitleIndex,
|
|
szClass,
|
|
szSecurity,
|
|
AccessMask,
|
|
Options,
|
|
szNewHandle,
|
|
cmo );
|
|
}
|
|
SFree( szNewHandle );
|
|
}
|
|
}
|
|
}
|
|
SFree( szSecurity );
|
|
}
|
|
}
|
|
FFreeRgsz( rgszInfo );
|
|
}
|
|
}
|
|
SFree( szKeyInfo );
|
|
}
|
|
}
|
|
|
|
return fOkay;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseLoadLibrary(INT Line, UINT *pcFields)
|
|
{
|
|
BOOL fOkay = FALSE;
|
|
SZ szDiskName = NULL,
|
|
szLibName = NULL,
|
|
szHandleVar = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields == 4) {
|
|
FGetArgSz(Line,pcFields,&szDiskName); // disk name
|
|
FGetArgSz(Line,pcFields,&szLibName); // library pathname
|
|
FGetArgSz(Line,pcFields,&szHandleVar); // INF var to get lib handle
|
|
|
|
if((szLibName != NULL)
|
|
&& (szHandleVar != NULL)
|
|
&& *szLibName
|
|
&& *szHandleVar)
|
|
{
|
|
fOkay = FLoadLibrary(szDiskName,szLibName,szHandleVar);
|
|
}
|
|
if(szDiskName != NULL) {
|
|
SFree(szDiskName);
|
|
}
|
|
if(szLibName != NULL) {
|
|
SFree(szLibName);
|
|
}
|
|
if(szHandleVar != NULL) {
|
|
SFree(szHandleVar);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseFreeLibrary(INT Line, UINT *pcFields)
|
|
{
|
|
BOOL fOkay = FALSE;
|
|
SZ szHandle = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields == 2) {
|
|
FGetArgSz(Line,pcFields,&szHandle); // lib handle
|
|
|
|
if((szHandle != NULL) && *szHandle)
|
|
{
|
|
fOkay = FFreeLibrary(szHandle);
|
|
}
|
|
if(szHandle != NULL) {
|
|
SFree(szHandle);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseLibraryProcedure(INT Line,UINT *pcFields)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szINFVar = NULL,
|
|
szLibHand = NULL,
|
|
szRoutine = NULL;
|
|
RGSZ rgszArgs = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields >= 4) {
|
|
FGetArgSz(Line,pcFields,&szINFVar); // INF var for result
|
|
FGetArgSz(Line,pcFields,&szLibHand); // library handle
|
|
FGetArgSz(Line,pcFields,&szRoutine); // entry point
|
|
|
|
rgszArgs = RgszFromInfLineFields(Line,5,(*pcFields) - 4);
|
|
|
|
if((szLibHand != NULL)
|
|
&& (szRoutine != NULL)
|
|
&& (rgszArgs != NULL))
|
|
{
|
|
fOkay = FLibraryProcedure(szINFVar,szLibHand,szRoutine,rgszArgs);
|
|
}
|
|
if(szINFVar != NULL) {
|
|
SFree(szINFVar);
|
|
}
|
|
if(szLibHand != NULL) {
|
|
SFree(szLibHand);
|
|
}
|
|
if(szRoutine != NULL) {
|
|
SFree(szRoutine);
|
|
}
|
|
if(rgszArgs != NULL) {
|
|
FFreeRgsz(rgszArgs);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseRunExternalProgram(INT Line,UINT *pcFields)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szVar = NULL,
|
|
szDisk = NULL,
|
|
szLibHand = NULL,
|
|
szProgram = NULL;
|
|
RGSZ rgszArgs = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields >= 5) {
|
|
FGetArgSz(Line,pcFields,&szVar); // INF variable to stuff
|
|
FGetArgSz(Line,pcFields,&szDisk); // disk name
|
|
FGetArgSz(Line,pcFields,&szLibHand); // mod with string table
|
|
FGetArgSz(Line,pcFields,&szProgram); // name of program
|
|
|
|
// To be nice, we will supply argv[0]. To do this we'll
|
|
// take advantage of placement of the program name immediately
|
|
// before the arguments. It ain't perfect (argv[0] doesn't
|
|
// conventionally contain a full path) but it'll do.
|
|
|
|
rgszArgs = RgszFromInfLineFields(Line,5,(*pcFields) - 4);
|
|
|
|
if((szDisk != NULL) && (szProgram != NULL) && (rgszArgs != NULL)) {
|
|
|
|
AssertRet((*szProgram != '\0'),fFalse);
|
|
|
|
fOkay = FRunProgram(szVar,szDisk,szLibHand,szProgram,rgszArgs);
|
|
}
|
|
if(szVar != NULL) {
|
|
SFree(szVar);
|
|
}
|
|
if(szDisk != NULL) {
|
|
SFree(szDisk);
|
|
}
|
|
if(szLibHand != NULL) {
|
|
SFree(szLibHand);
|
|
}
|
|
if(szProgram != NULL) {
|
|
SFree(szProgram);
|
|
}
|
|
if(rgszArgs != NULL) {
|
|
FFreeRgsz(rgszArgs);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseStartDetachedProcess(INT Line,UINT *pcFields)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szVar = NULL,
|
|
szDisk = NULL,
|
|
szLibHand = NULL,
|
|
szProgram = NULL;
|
|
RGSZ rgszArgs = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields >= 5) {
|
|
FGetArgSz(Line,pcFields,&szVar); // INF variable to stuff
|
|
FGetArgSz(Line,pcFields,&szDisk); // disk name
|
|
FGetArgSz(Line,pcFields,&szLibHand); // mod with string table
|
|
FGetArgSz(Line,pcFields,&szProgram); // name of program
|
|
|
|
// To be nice, we will supply argv[0]. To do this we'll
|
|
// take advantage of placement of the program name immediately
|
|
// before the arguments. It ain't perfect (argv[0] doesn't
|
|
// conventionally contain a full path) but it'll do.
|
|
|
|
rgszArgs = RgszFromInfLineFields(Line,5,(*pcFields) - 4);
|
|
|
|
if((szDisk != NULL) && (szProgram != NULL) && (rgszArgs != NULL)) {
|
|
|
|
AssertRet((*szProgram != '\0'),fFalse);
|
|
|
|
fOkay = FStartDetachedProcess(szVar,szDisk,szLibHand,szProgram,rgszArgs);
|
|
}
|
|
if(szVar != NULL) {
|
|
SFree(szVar);
|
|
}
|
|
if(szDisk != NULL) {
|
|
SFree(szDisk);
|
|
}
|
|
if(szLibHand != NULL) {
|
|
SFree(szLibHand);
|
|
}
|
|
if(szProgram != NULL) {
|
|
SFree(szProgram);
|
|
}
|
|
if(rgszArgs != NULL) {
|
|
FFreeRgsz(rgszArgs);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
** Purpose:
|
|
** Arguments:
|
|
** Returns:
|
|
**
|
|
*************************************************************************/
|
|
BOOL APIENTRY FParseInvokeApplet(INT Line, UINT *pcFields)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szLibrary = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields >= 2) {
|
|
|
|
FGetArgSz(Line,pcFields,&szLibrary); // name of library
|
|
|
|
if(szLibrary != NULL) {
|
|
|
|
fOkay = FInvokeApplet(szLibrary);
|
|
SFree(szLibrary);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
|
|
BOOL APIENTRY FParseAddFileToDeleteList(INT Line, UINT *pcFields)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szFile = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields >= 2) {
|
|
|
|
FGetArgSz(Line,pcFields,&szFile); // filename to add
|
|
|
|
if(szFile != NULL) {
|
|
|
|
fOkay = AddFileToDeleteList(szFile);
|
|
SFree(szFile);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
#define FAIL_EVENT_MARK '*'
|
|
|
|
BOOL APIENTRY FParseWaitOnEvent(INT Line,UINT *pcFields)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szInfVar = NULL,
|
|
szEvent = NULL,
|
|
szTimeout = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields >= 4) {
|
|
FGetArgSz(Line,pcFields,&szInfVar); // INF variable to stuff
|
|
FGetArgSz(Line,pcFields,&szEvent);
|
|
FGetArgSz(Line,pcFields,&szTimeout);
|
|
|
|
//
|
|
// If the first character of the event name string is '*', this is a
|
|
// signal to call the special version of event waiting which allows the
|
|
// signaller to alternatively signal an event named SETUP_FAILED
|
|
// to indicate that the process failed and an error popup has already
|
|
// been presented to the user. In this case, the result variable will
|
|
// contain "EventFailed". If the SETUP_FAILED event cannot be created,
|
|
// the result is "EventNoFailEvent".
|
|
//
|
|
if ( (szInfVar != NULL) && (szEvent != NULL) && (szTimeout != NULL) )
|
|
{
|
|
DWORD dwTimeout = atol( szTimeout ) ;
|
|
|
|
if ( szEvent[0] == FAIL_EVENT_MARK )
|
|
{
|
|
fOkay = FWaitForEventOrFailure( szInfVar, szEvent+1, dwTimeout );
|
|
}
|
|
else
|
|
{
|
|
fOkay = FWaitForEvent( szInfVar, szEvent, dwTimeout );
|
|
}
|
|
}
|
|
|
|
if(szInfVar != NULL) {
|
|
SFree(szInfVar);
|
|
}
|
|
if(szEvent != NULL) {
|
|
SFree(szEvent);
|
|
}
|
|
if(szTimeout != NULL) {
|
|
SFree(szTimeout);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|
|
|
|
BOOL APIENTRY FParseSleep(INT Line,UINT *pcFields)
|
|
{
|
|
SZ szMilliseconds = NULL;
|
|
|
|
iFieldCur = 2 ;
|
|
|
|
if (*pcFields >= 2) {
|
|
FGetArgSz(Line,pcFields,&szMilliseconds);
|
|
FSleep( atol( szMilliseconds ) ) ;
|
|
}
|
|
|
|
return TRUE ;
|
|
}
|
|
|
|
BOOL APIENTRY FParseFlushInf(INT Line,UINT *pcFields)
|
|
{
|
|
SZ szInf;
|
|
BOOL fOkay = fFalse;
|
|
|
|
iFieldCur = 2 ;
|
|
|
|
if (*pcFields >= 2) {
|
|
FGetArgSz(Line,pcFields,&szInf);
|
|
fOkay = FFlushInfParsedInfo( szInf );
|
|
}
|
|
|
|
return(fOkay);
|
|
}
|
|
|
|
static VOID freeBmps ( VOID )
|
|
{
|
|
INT i ;
|
|
|
|
for ( i = 0 ; i < BMP_MAX && hbmAdvertList[i] ; i++ )
|
|
{
|
|
DeleteObject( hbmAdvertList[i] ) ;
|
|
hbmAdvertList[i] = NULL ;
|
|
|
|
if ( hWndShell && i == 0 )
|
|
{
|
|
InvalidateRect( hWndShell, NULL, FALSE ) ;
|
|
UpdateWindow( hWndShell ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Syntax:
|
|
//
|
|
// BMPSHOW
|
|
// <cycle time in seconds>
|
|
// <relative X position, 0..100>
|
|
// <relative Y position, 0..100>
|
|
// {list of bitmap id numbers}
|
|
//
|
|
BOOL APIENTRY FParseBmpShow ( INT Line, UINT * pcFields )
|
|
{
|
|
SZ sz=NULL;
|
|
INT iId, iCycle, cBmps, i ;
|
|
BOOL fOkay = fFalse;
|
|
RGSZ rgszIds ;
|
|
|
|
iFieldCur = 2 ;
|
|
|
|
if ( ! fFullScreen )
|
|
{
|
|
fOkay = fTrue ;
|
|
}
|
|
else
|
|
if ( *pcFields >= 4)
|
|
{
|
|
freeBmps() ;
|
|
|
|
FGetArgSz( Line, pcFields, & sz );
|
|
iCycle = atoi( sz ) ;
|
|
sz = NULL;
|
|
FGetArgSz( Line, pcFields, & sz );
|
|
cxAdvert = atoi( sz ) ;
|
|
sz = NULL;
|
|
FGetArgSz( Line, pcFields, & sz );
|
|
cyAdvert = atoi( sz ) ;
|
|
sz = NULL;
|
|
FGetArgSz( Line, pcFields, & sz );
|
|
rgszIds = RgszFromSzListValue( sz ) ;
|
|
|
|
cBmps = 0 ;
|
|
if ( rgszIds )
|
|
{
|
|
// Load all the bitmaps we can fit and find.
|
|
|
|
for ( iId = 0 ; iId < BMP_MAX && rgszIds[iId] ; iId++ )
|
|
{
|
|
hbmAdvertList[cBmps] = LoadBitmap( hInst,
|
|
MAKEINTRESOURCE( atoi( rgszIds[iId] ) ) ) ;
|
|
if ( hbmAdvertList[cBmps] )
|
|
cBmps++ ;
|
|
}
|
|
FFreeRgsz( rgszIds ) ;
|
|
}
|
|
|
|
hbmAdvertList[cBmps] = NULL ;
|
|
|
|
if ( cBmps )
|
|
{
|
|
fOkay = fTrue ;
|
|
cAdvertCycleSeconds = iCycle ;
|
|
|
|
// Activate BMP display: point at last bitmap (end of cycle)
|
|
cAdvertIndex = cBmps - 1 ;
|
|
}
|
|
}
|
|
|
|
return(fOkay);
|
|
}
|
|
|
|
//
|
|
// Syntax: BMPHIDE
|
|
//
|
|
BOOL APIENTRY FParseBmpHide ( INT Line, UINT * pcFields )
|
|
{
|
|
BOOL fOkay = fTrue ;
|
|
|
|
iFieldCur = 2 ;
|
|
|
|
if ( fFullScreen )
|
|
{
|
|
// Turn off BMP display
|
|
cAdvertIndex = -1 ;
|
|
freeBmps() ;
|
|
}
|
|
|
|
return(fOkay);
|
|
}
|
|
|
|
|
|
|
|
BOOL APIENTRY FParseSignalEvent(INT Line,UINT *pcFields)
|
|
{
|
|
BOOL fOkay = fFalse;
|
|
SZ szInfVar = NULL,
|
|
szEvent = NULL;
|
|
|
|
iFieldCur = 2;
|
|
|
|
if(*pcFields >= 3) {
|
|
FGetArgSz(Line,pcFields,&szInfVar); // INF variable to stuff
|
|
FGetArgSz(Line,pcFields,&szEvent);
|
|
|
|
if((szInfVar != NULL) && (szEvent != NULL)) {
|
|
fOkay = FSignalEvent( szInfVar, szEvent );
|
|
}
|
|
|
|
if(szInfVar != NULL) {
|
|
SFree(szInfVar);
|
|
}
|
|
if(szEvent != NULL) {
|
|
SFree(szEvent);
|
|
}
|
|
}
|
|
return(fOkay);
|
|
}
|