2044 lines
52 KiB
C
2044 lines
52 KiB
C
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dosmig95.c
|
|
|
|
Abstract:
|
|
|
|
Handles win95 side gathering of data from config.sys and autoexec.bat files.
|
|
|
|
Author:
|
|
|
|
Marc R. Whitten (marcw) 15-Feb-1997
|
|
|
|
Revision History:
|
|
|
|
Marc R. Whitten (marcw) 08-Mar-1999 - Cleanup Environment variable parsing.
|
|
Marc R. Whitten (marcw) 5-Sep-1997 - Major changes.
|
|
Marc R. Whitten (marcw) 18-Aug-1997 - Bug sweep.
|
|
Marc R. Whitten (marcw) 14-Apr-1997 - Dosmig is now ProgressBar aware.
|
|
|
|
--*/
|
|
#include "pch.h"
|
|
|
|
#define DBG_DOSMIG "DOSMIG"
|
|
|
|
|
|
|
|
|
|
typedef BOOL (RULEFUNC)(PLINESTRUCT,DWORD);
|
|
|
|
typedef struct _PARSERULE PARSERULE, *PPARSERULE;
|
|
|
|
struct _PARSERULE {
|
|
|
|
PCTSTR Name;
|
|
PCTSTR Pattern;
|
|
RULEFUNC * Handle;
|
|
DWORD Parameter;
|
|
PPARSERULE Next;
|
|
|
|
};
|
|
|
|
|
|
typedef enum {
|
|
|
|
DOSMIG_UNUSED,
|
|
DOSMIG_BAD,
|
|
DOSMIG_UNKNOWN,
|
|
DOSMIG_USE,
|
|
DOSMIG_MIGRATE,
|
|
DOSMIG_IGNORE,
|
|
DOSMIG_LAST
|
|
|
|
} DOSMIG_LINETAG, *PDOSMIG_LINETAG;
|
|
|
|
|
|
|
|
typedef struct _PARSERULES {
|
|
|
|
PCTSTR Name;
|
|
PPARSERULE RuleList;
|
|
PPARSERULE DefaultRule;
|
|
|
|
} PARSERULES, *PPARSERULES;
|
|
|
|
|
|
BOOL g_IncompatibilityDetected = FALSE;
|
|
GROWBUFFER g_IncompatibilityBuffer = GROWBUF_INIT;
|
|
|
|
|
|
//
|
|
// Global pointers to the rule lists for config.sys and batch files.
|
|
//
|
|
PARSERULES g_ConfigSysRules;
|
|
PARSERULES g_BatchFileRules;
|
|
PPARSERULES g_CurrentRules = NULL;
|
|
|
|
//
|
|
// This variable holds the offset within memdb to where the file currently being parsed is saved.
|
|
//
|
|
DWORD g_CurrentFileOffset;
|
|
|
|
//
|
|
// This growlist holds the list of all files that will be parsed. It can increase during parsing
|
|
// (e.g. by encountering a CALL statement in a batch file.)
|
|
//
|
|
GROWLIST g_FileList = GROWLIST_INIT;
|
|
|
|
|
|
GROWBUFFER g_LineGrowBuf = GROWBUF_INIT;
|
|
GROWBUFFER g_ExtraPaths = GROWBUF_INIT;
|
|
#define MAXFILESIZE 0xFFFFFFFF
|
|
|
|
|
|
//
|
|
// Various bits of state that are kept during parsing..
|
|
//
|
|
PCTSTR g_CurrentFile;
|
|
PCTSTR g_CurrentLine;
|
|
DWORD g_CurrentLineNumber;
|
|
POOLHANDLE g_DosMigPool = NULL;
|
|
|
|
|
|
#define BATCHFILELIST \
|
|
DEFAULTPARSERULE(TEXT("Default Rule"),NULL,pHandleUnknownBatLine,0) \
|
|
PARSERULE(TEXT("Rem"),TEXT("REM *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT(" "),TEXT("*DOSKEY*"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT(": (Menu or Label"),TEXT(":*"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("@"),TEXT("@*"),pHandleAtSign,0) \
|
|
PARSERULE(TEXT("CLS"),TEXT("CLS *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("CD"),TEXT("CD *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("CHDIR"),TEXT("CHDIR *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("PAUSE"),TEXT("PAUSE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("ECHO"),TEXT("ECHO *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("ATTRIB"),TEXT("ATTRIB *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("CHDIR"),TEXT("CHDIR *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("CHCP"),TEXT("CHCP *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("CHOICE"),TEXT("CHOICE *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("CALL"),TEXT("CALL *"),pHandleCall,0) \
|
|
PARSERULE(TEXT("COMMAND"),TEXT("COMMAND *"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("CHKDSK"),TEXT("CHKDSK *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("COPY"),TEXT("COPY *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("CTTY"),TEXT("CTTY *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("DATE"),TEXT("DATE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("DBLSPACE"),TEXT("DBLSPACE *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("DEFRAG"),TEXT("DEFRAG *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("DEL"),TEXT("DEL *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("DELETE"),TEXT("DELETE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("DELOLDDOS"),TEXT("DELOLDDOS *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("DELTREE"),TEXT("DELTREE *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("DIR"),TEXT("DIR *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("DISKCOMP"),TEXT("DISKCOMP *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("DISKCOPY"),TEXT("DISKCOPY *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("DOSSHELL"),TEXT("DOSSHELL *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("DRVSPACE"),TEXT("DRVSPACE *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("ECHO"),TEXT("ECHO *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("EDIT"),TEXT("EDIT *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("EMM386"),TEXT("EMM386 *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("ERASE"),TEXT("ERASE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("EXIT"),TEXT("EXIT *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("EXPAND"),TEXT("EXPAND *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("FASTHELP"),TEXT("FASTHELP *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("FASTOPEN"),TEXT("FASTOPEN *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("FC"),TEXT("FC *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("FDISK"),TEXT("FDISK *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("FIND"),TEXT("FIND *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("FOR"),TEXT("FOR *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("FORMAT"),TEXT("FORMAT *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("GOTO"),TEXT("GOTO *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("GRAPHICS"),TEXT("GRAPHICS *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("HELP"),TEXT("HELP *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("IF"),TEXT("IF *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("INTERLNK"),TEXT("INTERLNK*"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("INTERSVR"),TEXT("INTERSVR*"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("KEYB"),TEXT("KEYB *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("LABEL"),TEXT("LABEL *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("LH"),TEXT("LH *"),pHandleLoadHigh,0) \
|
|
PARSERULE(TEXT("LOADHIGH"),TEXT("LOADHIGH *"),pHandleLoadHigh,0) \
|
|
PARSERULE(TEXT("MD"),TEXT("MD *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("MKDIR"),TEXT("MKDIR *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("MEM"),TEXT("MEM *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("MEMMAKER"),TEXT("MEMMAKER *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("MODE"),TEXT("MODE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("MORE"),TEXT("MORE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("MOVE"),TEXT("MOVE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("MSAV"),TEXT("MSAV *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("MSBACKUP"),TEXT("MSBACKUP *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("MSCDEX"),TEXT("*MSCDEX*"),pHandleMSCDEX,0) \
|
|
PARSERULE(TEXT("MSD"),TEXT("MSD *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("NLSFUNC"),TEXT("NLSFUNC *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("NUMLOCK"),TEXT("NUMLOCK *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("PATH"),TEXT("PATH *"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("PATH"),TEXT("PATH*=*"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("PAUSE"),TEXT("PAUSE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("POWER"),TEXT("POWER *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("PRINT"),TEXT("PRINT *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("PROMPT"),TEXT("PROMPT*"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("QBASIC"),TEXT("QBASIC *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("RD"),TEXT("RD *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("RMDIR"),TEXT("RMDIR *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("REN"),TEXT("REN *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("RENAME"),TEXT("RENAME *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("REPLACE"),TEXT("REPLACE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("RESTORE"),TEXT("RESTORE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("SCANDISK"),TEXT("SCANDISK *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("SET"),TEXT("SET*=*"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("SET"),TEXT("SET *"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("SETVER"),TEXT("SETVER *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("SHARE"),TEXT("SHARE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("SHIFT"),TEXT("SHIFT *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("SMARTDRV"),TEXT("SMARTDRV*"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("SORT"),TEXT("SORT *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("SUBST"),TEXT("SUBST *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("SYS"),TEXT("SYS *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("TIME"),TEXT("TIME *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("TREE"),TEXT("TREE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("TRUENAME"),TEXT("TRUENAME *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("TYPE"),TEXT("TYPE *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("UNDELETE"),TEXT("UNDELETE *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("UNFORMAT"),TEXT("UNFORMAT *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("VER"),TEXT("VER *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("VERIFY"),TEXT("VERIFY *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("VOL"),TEXT("VOL *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("VSAFE"),TEXT("VSAFE *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("XCOPY"),TEXT("XCOPY *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("High"),TEXT("*High *"),pHandleHighFilter,0)
|
|
|
|
|
|
|
|
#define CONFIGSYSLIST \
|
|
DEFAULTPARSERULE(TEXT("Default Rule"),NULL,pSaveItem,DOSMIG_UNKNOWN) \
|
|
PARSERULE(TEXT("Rem"),TEXT("REM *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("[ (Menu)"),TEXT("[*"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("DEVICE"),TEXT("DEVICE *"),pHandleConfigSysDevice,0) \
|
|
PARSERULE(TEXT("INSTALL"),TEXT("INSTALL *"),pHandleConfigSysDevice,0) \
|
|
PARSERULE(TEXT("MENUITEM"),TEXT("MENUITEM *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("MENUDEFAULT"),TEXT("MENUDEFAULT*"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("MENUCOLOR"),TEXT("MENUCOLOR *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("SUBMENU"),TEXT("SUBMENU *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("STACKS"),TEXT("STACKS *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("DOS"),TEXT("DOS *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("FILES"),TEXT("FILES *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("SHELL"),TEXT("SHELL *"),pHandleShell,0) \
|
|
PARSERULE(TEXT("COUNTRY"),TEXT("COUNTRY *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("BUFFERS"),TEXT("BUFFERS *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("BREAK"),TEXT("BREAK *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("DRIVEPARM"),TEXT("DRIVEPARM *"),pSaveItem,DOSMIG_BAD) \
|
|
PARSERULE(TEXT("FCBS"),TEXT("FCBS *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("INCLUDE"),TEXT("INCLUDE *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("LASTDRIVE"),TEXT("LASTDRIVE *"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("SET"),TEXT("SET*=*"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("SET"),TEXT("SET *"),pSaveItem,DOSMIG_MIGRATE) \
|
|
PARSERULE(TEXT("SWITCHES"),TEXT("SWITCHES*"),pSaveItem,DOSMIG_IGNORE) \
|
|
PARSERULE(TEXT("VERIFY"),TEXT("VERIFY *"),pSaveItem,DOSMIG_USE) \
|
|
PARSERULE(TEXT("High"),TEXT("*High *"),pHandleHighFilter,0)
|
|
|
|
BOOL
|
|
InitParser (
|
|
VOID
|
|
);
|
|
|
|
|
|
VOID
|
|
CleanUpParser (
|
|
VOID
|
|
);
|
|
|
|
|
|
BOOL
|
|
ParseLine (
|
|
IN PTSTR Line,
|
|
IN PPARSERULES ParseRules
|
|
);
|
|
|
|
BOOL
|
|
ParseFile (
|
|
IN LPCTSTR File,
|
|
IN PPARSERULES ParseRules
|
|
);
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
ParseDosFiles (
|
|
VOID
|
|
);
|
|
|
|
BOOL
|
|
ParseEnvironmentVariables (
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BuildParseRules (
|
|
VOID
|
|
);
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pGetNextLine retrieves a complete line from the file being processed.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
A valid lline from the current file being parsed, or, NULL if there are no
|
|
more lines to parse..
|
|
|
|
--*/
|
|
|
|
PTSTR
|
|
pGetNextLine (
|
|
VOID
|
|
)
|
|
|
|
{
|
|
PTSTR rLine = NULL;
|
|
PTSTR eol = NULL;
|
|
|
|
MYASSERT(g_LineGrowBuf.Buf);
|
|
|
|
|
|
while (!rLine && g_LineGrowBuf.UserIndex < g_LineGrowBuf.End) {
|
|
|
|
//
|
|
// Set rLine to the current user index within the growbuf.
|
|
//
|
|
rLine = g_LineGrowBuf.Buf + g_LineGrowBuf.UserIndex;
|
|
|
|
//
|
|
// Walk forward in the growbuf, looking for a \r or \n or the end of the file.
|
|
//
|
|
eol = _tcschr(rLine, TEXT('\n'));
|
|
if(!eol) {
|
|
eol = _tcschr(rLine, TEXT('\r'));
|
|
}
|
|
|
|
if (!eol) {
|
|
eol = _tcschr(rLine, 26);
|
|
}
|
|
|
|
if (!eol) {
|
|
eol = GetEndOfString (rLine);
|
|
}
|
|
|
|
//
|
|
// Remember where to start from next time.
|
|
//
|
|
g_LineGrowBuf.UserIndex = (DWORD) eol - (DWORD) g_LineGrowBuf.Buf + 1;
|
|
|
|
//
|
|
// Now, walk backwards, trimming off all of the white space.
|
|
//
|
|
do {
|
|
|
|
*eol = 0;
|
|
eol = _tcsdec2(rLine,eol);
|
|
|
|
} while (eol && _istspace(*eol));
|
|
|
|
if (!eol) {
|
|
//
|
|
// This is a blank line. NULL out rLine and get the next line.
|
|
//
|
|
rLine = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
g_CurrentLineNumber++;
|
|
|
|
|
|
return rLine;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pGetFirstLine is responsible for setting up the data structure that will
|
|
hold the lines of the file to parse. After setting up the data structure,
|
|
pGetFirstLine calls pGetNextLine to return the first line of the file.
|
|
|
|
Arguments:
|
|
|
|
FileHandle - Contains a valid file handle opened via CreateFile.
|
|
|
|
Return Value:
|
|
|
|
The first complete line of the file being parse, or NULL if there are no
|
|
lines, or there was an error..
|
|
|
|
--*/
|
|
|
|
|
|
PTSTR
|
|
pGetFirstLine (
|
|
IN HANDLE FileHandle
|
|
)
|
|
{
|
|
DWORD fileSize;
|
|
DWORD numBytesRead;
|
|
PTSTR rLine = NULL;
|
|
|
|
MYASSERT(FileHandle != INVALID_HANDLE_VALUE);
|
|
|
|
g_LineGrowBuf.End = 0;
|
|
g_LineGrowBuf.UserIndex = 0;
|
|
|
|
//
|
|
// Get the file size. We'll read the whole file into a grow buf.
|
|
//
|
|
fileSize = GetFileSize(FileHandle,NULL);
|
|
|
|
if (fileSize != MAXFILESIZE && fileSize != 0) {
|
|
|
|
//
|
|
// Ensure that the growbuffer is large enough for this file and
|
|
// then read the file into it.
|
|
//
|
|
if (GrowBuffer(&g_LineGrowBuf,fileSize)) {
|
|
|
|
if (ReadFile(
|
|
FileHandle,
|
|
g_LineGrowBuf.Buf,
|
|
fileSize,
|
|
&numBytesRead,
|
|
NULL
|
|
)) {
|
|
|
|
//
|
|
// Null terminate the whole file..for good measure.
|
|
//
|
|
*(g_LineGrowBuf.Buf + g_LineGrowBuf.End) = 0;
|
|
|
|
|
|
//
|
|
// Now that we have the file in memory, return the first line to the
|
|
// caller.
|
|
//
|
|
rLine = pGetNextLine();
|
|
}
|
|
else {
|
|
|
|
LOG((LOG_ERROR,"Dosmig: Error reading from file."));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DEBUGMSG((DBG_ERROR,"Dosmig: Growbuf failure in pGetFirstLine."));
|
|
}
|
|
}
|
|
else {
|
|
|
|
DEBUGMSG((DBG_WARNING, "Dosmig: File to large to read or empty file... (filesize: %u)",fileSize));
|
|
}
|
|
|
|
return rLine;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pFindParseRule trys to find a parse rule that matches the line passed in.
|
|
The function will first search the regular rules in the PARSERULES
|
|
structure passed in. If the line does not match any of the rules found
|
|
there, it will return the default rule.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains the valid line to try to match with a parse rule.
|
|
Rules - Contains a pointer to the set of rules to look through.
|
|
|
|
Return Value:
|
|
|
|
The rule that should be used to parse the given line. Since a default rule
|
|
is required, this function is guaranteed not to return NULL.
|
|
|
|
--*/
|
|
|
|
|
|
PPARSERULE
|
|
pFindParseRule (
|
|
IN PLINESTRUCT LineStruct,
|
|
IN PPARSERULES Rules
|
|
)
|
|
{
|
|
PPARSERULE rRule = NULL;
|
|
PTSTR matchLine = NULL;
|
|
|
|
|
|
MYASSERT(LineStruct && Rules && Rules -> DefaultRule);
|
|
|
|
rRule = Rules -> RuleList;
|
|
|
|
//
|
|
// Minor kludge here: The parse code uses pattern matches with rules that look
|
|
// something like: "REM *" for example. This pattern depends on there being at least
|
|
// one bit of white space after a REM statement. Unfortunately, a line such as
|
|
// "REM" is entirely possible in the growbuf (Line). So, we actually perform the match
|
|
// against the line with an extra space added.
|
|
//
|
|
matchLine = JoinText(LineStruct -> Command,TEXT(" "));
|
|
|
|
if (matchLine) {
|
|
|
|
while (rRule && !IsPatternMatch(rRule -> Pattern, matchLine)) {
|
|
rRule = rRule -> Next;
|
|
}
|
|
|
|
|
|
if (!rRule) {
|
|
rRule = Rules -> DefaultRule;
|
|
}
|
|
|
|
FreeText(matchLine);
|
|
}
|
|
|
|
return rRule;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
InitParser is responsible for doing any one-time initialization of the
|
|
parser. It should be called only once, before any parsing is done.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the parser was successfully initialized, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
InitParser (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
BOOL rSuccess = TRUE;
|
|
|
|
if (g_ToolMode) {
|
|
g_DosMigPool = PoolMemInitNamedPool ("DosMig");
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CleanUpParser is responsible for doing any one time cleanup of the parser.
|
|
It should be called after all parsing is done.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
|
|
VOID
|
|
CleanUpParser (
|
|
VOID
|
|
)
|
|
{
|
|
if (g_ToolMode) {
|
|
|
|
PoolMemDestroyPool (g_DosMigPool);
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeGrowBuffer(&g_LineGrowBuf);
|
|
FreeGrowBuffer(&g_ExtraPaths);
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
pEnsurePathHasExecutableExtension (
|
|
OUT PTSTR NewPath,
|
|
IN PTSTR OldPath,
|
|
IN PTSTR File OPTIONAL
|
|
)
|
|
{
|
|
|
|
BOOL rSuccess = FALSE;
|
|
PCTSTR p = NULL;
|
|
WIN32_FIND_DATA findData;
|
|
HANDLE h = INVALID_HANDLE_VALUE;
|
|
|
|
StringCopy(NewPath,OldPath);
|
|
|
|
if (File) {
|
|
AppendPathWack(NewPath);
|
|
StringCat(NewPath,File);
|
|
}
|
|
|
|
StringCat(NewPath,TEXT("*"));
|
|
|
|
|
|
if ((h=FindFirstFile(NewPath,&findData)) != INVALID_HANDLE_VALUE) {
|
|
do {
|
|
p = GetFileExtensionFromPath(findData.cFileName);
|
|
if (p) {
|
|
if (StringIMatch(p,TEXT("exe")) ||
|
|
StringIMatch(p,TEXT("bat")) ||
|
|
StringIMatch(p,TEXT("com")) ||
|
|
StringIMatch(p,TEXT("sys"))) {
|
|
|
|
p = _tcsrchr(NewPath,TEXT('\\'));
|
|
|
|
MYASSERT (p);
|
|
if (p) {
|
|
|
|
StringCopy(
|
|
_tcsinc(p),
|
|
*findData.cAlternateFileName ? findData.cAlternateFileName : findData.cFileName
|
|
);
|
|
|
|
FindClose(h);
|
|
rSuccess = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} while (FindNextFile(h,&findData));
|
|
}
|
|
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
BOOL
|
|
pGetFullPath (
|
|
IN OUT PLINESTRUCT LineStruct
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
PATH_ENUM e;
|
|
HANDLE h = INVALID_HANDLE_VALUE;
|
|
BOOL pathFound = FALSE;
|
|
|
|
if (StringIMatch(LineStruct -> Path, LineStruct -> Command)) {
|
|
|
|
//
|
|
// No path information was stored in the config line. We have to find the full path ourselves.
|
|
//
|
|
if (EnumFirstPath (&e, g_ExtraPaths.Buf, NULL, NULL)) {
|
|
|
|
do {
|
|
rSuccess = pEnsurePathHasExecutableExtension(LineStruct -> FullPath, e.PtrCurrPath, LineStruct -> Command);
|
|
if (rSuccess) {
|
|
EnumPathAbort(&e);
|
|
break;
|
|
}
|
|
} while (EnumNextPath(&e));
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
//
|
|
// A full path name was specified in the line. Now all we need to do is ensure that it includes the extension.
|
|
//
|
|
rSuccess = pEnsurePathHasExecutableExtension(LineStruct -> FullPath, LineStruct -> Path, NULL);
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
InitLineStruct (
|
|
OUT PLINESTRUCT LineStruct,
|
|
IN PTSTR Line
|
|
)
|
|
{
|
|
|
|
BOOL inQuotes = FALSE;
|
|
PTSTR p = NULL;
|
|
TCHAR oldChar;
|
|
TCHAR ntPath[MEMDB_MAX];
|
|
static TCHAR extraPath[MEMDB_MAX] = "";
|
|
|
|
MYASSERT(Line);
|
|
|
|
ZeroMemory(LineStruct,sizeof(LINESTRUCT));
|
|
|
|
|
|
//
|
|
// If line is empty, we are done..
|
|
//
|
|
if (!*Line) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Save away a copy of the full line.
|
|
//
|
|
StringCopy(LineStruct -> FullLine,Line);
|
|
|
|
//
|
|
// Seperate the path and the arguments.
|
|
//
|
|
p = Line;
|
|
while(!*LineStruct -> Path) {
|
|
|
|
if (!*p) {
|
|
StringCopy(LineStruct -> Path,Line);
|
|
break;
|
|
}
|
|
|
|
if (*p == TEXT('"')) {
|
|
inQuotes = !inQuotes;
|
|
}
|
|
|
|
if ((*p == TEXT(' ') && !inQuotes) || *p == TEXT('=')) {
|
|
|
|
//
|
|
// reached the end of the command/path part of the string.
|
|
//
|
|
oldChar = *p;
|
|
*p = 0;
|
|
StringCopy(LineStruct -> Path,Line);
|
|
*p = oldChar;
|
|
StringCopy(LineStruct -> Arguments,p);
|
|
break;
|
|
}
|
|
|
|
p = _tcsinc(p);
|
|
}
|
|
|
|
//
|
|
// Grab the actual command.
|
|
//
|
|
p = _tcsrchr(LineStruct -> Path,TEXT('\\'));
|
|
if (p) {
|
|
StringCopy(LineStruct -> Command,_tcsinc(p));
|
|
}
|
|
else {
|
|
StringCopy(LineStruct -> Command,LineStruct -> Path);
|
|
}
|
|
|
|
//
|
|
// We need to find the fully qualified path, with extension, and if that path will change on NT.
|
|
//
|
|
if (!pGetFullPath(LineStruct)) {
|
|
DEBUGMSG((DBG_VERBOSE,"Could not get full path for %s.",LineStruct -> FullLine));
|
|
StringCopy(LineStruct -> FullPath,LineStruct -> Path);
|
|
LineStruct -> StatusOnNt = FILESTATUS_UNCHANGED;
|
|
}
|
|
else {
|
|
|
|
LineStruct -> StatusOnNt = GetFileInfoOnNt(LineStruct -> FullPath, ntPath, MEMDB_MAX);
|
|
}
|
|
|
|
//
|
|
// We only change the line if it is moved on NT and they specified a path before.
|
|
//
|
|
if ((LineStruct -> StatusOnNt & FILESTATUS_MOVED) && (!StringIMatch(LineStruct -> Path, LineStruct -> Command))) {
|
|
|
|
StringCopy(LineStruct -> PathOnNt,ntPath);
|
|
|
|
}
|
|
else {
|
|
StringCopy(LineStruct -> PathOnNt,LineStruct -> Path);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
ParseLine parses a single line of a text using the provided parse rules.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains a valid string that the caller wishes to be
|
|
parsed.
|
|
|
|
ParseRules - Points to the list of rules to use in parsing the provided
|
|
line.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the line was successfully parsed, FALSE
|
|
otherwise.
|
|
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
ParseLine (
|
|
IN PTSTR Line,
|
|
IN PPARSERULES ParseRules
|
|
)
|
|
{
|
|
|
|
BOOL rSuccess = FALSE;
|
|
PPARSERULE rule;
|
|
LINESTRUCT ls;
|
|
|
|
|
|
InitLineStruct(&ls,Line);
|
|
|
|
//
|
|
// Look for a match in the parse rules. call the matching rule.
|
|
// If no match is found, call the default rule.
|
|
//
|
|
|
|
rule = pFindParseRule(&ls,ParseRules);
|
|
|
|
if (rule) {
|
|
|
|
rSuccess = (rule -> Handle)(&ls,rule -> Parameter);
|
|
DEBUGMSG_IF ((!rSuccess,DBG_ERROR,"The %s rule reported an error parsing the line:\n\t%s",rule -> Name, Line));
|
|
if (!rSuccess) {
|
|
LOG ((
|
|
LOG_WARNING,
|
|
"There was an error processing the line %s in the file %s. "
|
|
"There could be problems associated with this file after migration.",
|
|
Line,
|
|
g_CurrentFile
|
|
));
|
|
}
|
|
}
|
|
|
|
return rSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
ParseFile parses an entire file using the provided parse rules.
|
|
|
|
Arguments:
|
|
|
|
File - The path of a file that the caller wishes parsed.
|
|
ParseRules - Points to the list of rules to use in parsing this file.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the file was successfully parsed, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
ParseFile (
|
|
IN LPCTSTR File,
|
|
IN PPARSERULES ParseRules
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
HANDLE fileHandle;
|
|
PTSTR line;
|
|
|
|
MYASSERT(File);
|
|
MYASSERT(ParseRules);
|
|
|
|
DEBUGMSG((DBG_DOSMIG,"Parsing file %s. Parse rules: %s",File,ParseRules -> Name));
|
|
|
|
//
|
|
// Initialize global per file parse variables.
|
|
//
|
|
g_CurrentFile = File;
|
|
g_CurrentLineNumber = 0;
|
|
g_CurrentLine = NULL;
|
|
|
|
//
|
|
// Open File for parsing
|
|
//
|
|
fileHandle = CreateFile(
|
|
File,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL, // Handle cannot be inherited.
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL // No template file.
|
|
);
|
|
|
|
|
|
|
|
if (fileHandle != INVALID_HANDLE_VALUE) {
|
|
|
|
//
|
|
// Parse each line of the file.
|
|
//
|
|
line = pGetFirstLine(fileHandle);
|
|
|
|
if (line) {
|
|
|
|
do {
|
|
|
|
//
|
|
// Save the current line away.
|
|
//
|
|
g_CurrentLine = line;
|
|
|
|
if (SizeOfString (line) <= MEMDB_MAX) {
|
|
ParseLine(line,ParseRules);
|
|
} else {
|
|
SetLastError (ERROR_SUCCESS);
|
|
LOG((LOG_ERROR, "Line too long in %s; setup will not migrate it", File));
|
|
}
|
|
//
|
|
// Get the next line.
|
|
//
|
|
line = pGetNextLine();
|
|
|
|
|
|
} while (line && rSuccess);
|
|
}
|
|
|
|
CloseHandle(fileHandle);
|
|
|
|
}
|
|
ELSE_DEBUGMSG((DBG_WARNING,"Could not open file %s for parsing. ",File));
|
|
|
|
return rSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
pAddMessage (
|
|
IN UINT Type,
|
|
IN UINT LineNumber,
|
|
IN PCTSTR File,
|
|
IN PCTSTR Line,
|
|
IN PCTSTR Path
|
|
)
|
|
|
|
{
|
|
|
|
|
|
|
|
TCHAR lineNumberString[20];
|
|
UINT messageId;
|
|
PCTSTR message;
|
|
PCTSTR totalMessage;
|
|
PCTSTR argArray[3];
|
|
|
|
|
|
|
|
|
|
//
|
|
// if this is the first message found, add a report message. In any case, add
|
|
// a message to the setupact.log.
|
|
//
|
|
if (!g_IncompatibilityDetected) {
|
|
/*
|
|
Don't Display this message -- It just confuses users without offering any real information.
|
|
|
|
baseGroup = GetStringResource(MSG_INSTALL_NOTES_ROOT);
|
|
subGroup = GetStringResource(MSG_DOS_WARNING_SUBGROUP);
|
|
message = GetStringResource(MSG_DOS_WARNING);
|
|
|
|
if (baseGroup && subGroup && message) {
|
|
|
|
group = JoinPaths(baseGroup,subGroup);
|
|
|
|
MsgMgr_ObjectMsg_Add (
|
|
Path,
|
|
group,
|
|
message
|
|
);
|
|
}
|
|
|
|
if (message) {
|
|
FreeStringResource(message);
|
|
}
|
|
if (subGroup) {
|
|
FreeStringResource(subGroup);
|
|
}
|
|
if (baseGroup) {
|
|
FreeStringResource(baseGroup);
|
|
}
|
|
if (group) {
|
|
FreePathString(group);
|
|
}
|
|
*/
|
|
|
|
g_IncompatibilityDetected = TRUE;
|
|
}
|
|
|
|
messageId = Type == DOSMIG_BAD ? MSG_DOS_INCOMPATIBLE_ITEM : MSG_DOS_UNKNOWN_ITEM;
|
|
|
|
//
|
|
// Prepare message
|
|
//
|
|
wsprintf(lineNumberString,"%u",LineNumber);
|
|
|
|
|
|
argArray[0] = lineNumberString,
|
|
argArray[1] = File;
|
|
argArray[2] = Line;
|
|
|
|
message = ParseMessageID(messageId,argArray);
|
|
|
|
if (message) {
|
|
|
|
totalMessage=GrowBuffer(&g_IncompatibilityBuffer,SizeOfString(message) + 2);
|
|
if (totalMessage) {
|
|
|
|
StringCopy( (PTSTR) (g_IncompatibilityBuffer.Buf + g_IncompatibilityBuffer.UserIndex), message);
|
|
StringCat( (PTSTR) (g_IncompatibilityBuffer.Buf + g_IncompatibilityBuffer.UserIndex), TEXT("\r\n"));
|
|
|
|
g_IncompatibilityBuffer.UserIndex += ByteCount (message) + 2;
|
|
}
|
|
|
|
FreeStringResource(message);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pSaveItem is a common routine that saves a line into memdb along with the
|
|
information that dosmignt will need to successfully migrate the line in GUI
|
|
mode. Depending on the type of the line, this function may also add an
|
|
incompatibility message to memdb.
|
|
|
|
Arguments:
|
|
|
|
Line - A valid line of text. The current line being parsed. Note that this
|
|
line may have been altered through parse rules and thus be different
|
|
than g_CurrentLine. g_CurrentLine is what is saved into memdb, this
|
|
parameter is ignored.
|
|
Type - The type of the line. This information is saved into memdb where it
|
|
will be used by dosmignt during GUI mode processing. Type is also
|
|
used to trigger incompatibility messages, if necessary.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the line was successfully saved, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
pSaveItem (
|
|
IN PLINESTRUCT LineStruct,
|
|
IN DWORD Type
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
static DWORD enumerator = 0;
|
|
TCHAR enumString[20];
|
|
TCHAR key[MEMDB_MAX];
|
|
TCHAR lineToSave[MEMDB_MAX];
|
|
|
|
MYASSERT(LineStruct);
|
|
|
|
|
|
//
|
|
// First, save away all of the information into memdb. We'll need it on the NT side.
|
|
//
|
|
wsprintf(enumString,TEXT("%07u"),enumerator++);
|
|
|
|
//
|
|
// Fix up the g_CurrentLine as necessary..
|
|
//
|
|
|
|
StringCopy(lineToSave,g_CurrentLine);
|
|
if (!StringIMatch(LineStruct -> Path, LineStruct -> Command)) {
|
|
//
|
|
// path was specified..
|
|
//
|
|
|
|
if (!StringIMatch(LineStruct -> Path,LineStruct -> PathOnNt)) {
|
|
//
|
|
// Different path on NT..
|
|
//
|
|
StringSearchAndReplace(lineToSave,LineStruct -> Path,LineStruct -> PathOnNt);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Build the key for this line (can't use the EX Memdb calls since we are setting userflags..)
|
|
//
|
|
MemDbBuildKey(key,MEMDB_CATEGORY_DM_LINES,enumString,NULL,lineToSave);
|
|
rSuccess = MemDbSetValueAndFlags(key,g_CurrentFileOffset,(WORD) Type,0);
|
|
|
|
//
|
|
// Now, if the passed in parameter was either unknown or bad, we need to add a message to the
|
|
// message manager.
|
|
//
|
|
|
|
if (Type == DOSMIG_BAD || Type == DOSMIG_UNKNOWN) {
|
|
|
|
pAddMessage(Type,g_CurrentLineNumber,g_CurrentFile,g_CurrentLine,LineStruct -> FullPath);
|
|
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pHandleMSCDEX (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
PCTSTR driveSwitch = NULL;
|
|
TCHAR driveLetter;
|
|
TCHAR driveString[20];
|
|
|
|
|
|
//
|
|
// This function is a minor kludge. MSCDEX can assign a drive letter to real mode
|
|
// cd roms.. Since it is handled in dos files instead of the registry, the code
|
|
// that is supposed to collect this information (drvlettr.c) does not have a chance.
|
|
// We will catch this case and save it into the winnt.sif file just as drvlettr.c
|
|
// would have.
|
|
//
|
|
driveSwitch = _tcsistr(LineStruct -> Arguments,TEXT("/l:"));
|
|
if (driveSwitch) {
|
|
//
|
|
// This mscdex line is one of the one's we care about.
|
|
//
|
|
driveLetter = *(driveSwitch + 3);
|
|
|
|
if (driveLetter) {
|
|
|
|
DEBUGMSG((DBG_DOSMIG,"Drive letter information is contained in the line %s. Preserving it. (%c)", LineStruct -> FullLine,driveLetter));
|
|
|
|
wsprintf(driveString,TEXT("%u"),toupper(driveLetter) - TEXT('A'));
|
|
rSuccess &= WriteInfKey(WINNT_D_WIN9XDRIVES,driveString,TEXT("5,"));
|
|
|
|
DEBUGMSG_IF((!rSuccess,DBG_ERROR,"Unable to save drive letter information for line %s.",LineStruct -> FullLine));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// Go ahead and save this into memdb.
|
|
//
|
|
rSuccess &= pSaveItem(LineStruct,DOSMIG_IGNORE);
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pHandleAtSign takes care of lines that begin with the '@' symbol. The
|
|
symbol is trimmed of f of the line and this modified line is parsed again.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains the valid line that is currently being parsed.
|
|
Parameter - This parameter is unused.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the function completed successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
pHandleAtSign (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
TCHAR buffer[MEMDB_MAX];
|
|
|
|
MYASSERT(_tcschr(LineStruct -> FullLine,TEXT('@')));
|
|
|
|
StringCopy(buffer,_tcsinc(_tcschr(LineStruct -> FullLine,TEXT('@'))));
|
|
|
|
rSuccess = ParseLine(buffer,&g_BatchFileRules);
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pHandleLoadHigh - Is responsible for handling the "loadhigh" and "lh" dos
|
|
statements. It simply skips past these statements and calls parseline on
|
|
the remainder of the line.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains the valid line that is currently being parsed.
|
|
Parameter - This parameter is unused.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the function completed successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
pHandleLoadHigh (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
TCHAR buffer[MEMDB_MAX];
|
|
PCTSTR p;
|
|
|
|
p = _tcschr(LineStruct -> Arguments, TEXT(' '));
|
|
if (!p) {
|
|
return FALSE;
|
|
}
|
|
|
|
buffer[0] = 0;
|
|
StringCopy(buffer,SkipSpace(p));
|
|
rSuccess = ParseLine(buffer,&g_BatchFileRules);
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pHandleCall takes care of call statements in batch files. It saves these
|
|
lines to memdb and adds the file mentioned in the call statement to the
|
|
list of files to be parsed.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains the valid line that is currently being parsed.
|
|
Parameter - This parameter is unused.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the function completed successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
pHandleCall (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
LINESTRUCT ls;
|
|
|
|
rSuccess = pSaveItem(LineStruct,DOSMIG_USE);
|
|
|
|
InitLineStruct (&ls, (PTSTR) SkipSpace (LineStruct -> Arguments));
|
|
|
|
if (!GrowListAppendString(&g_FileList,ls.FullPath)) {
|
|
rSuccess = FALSE;
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pHandleConfigSysDevice is responsible for device and devicehigh statements
|
|
in config.sys. The function extracts the driver from the line and tries to
|
|
determine if the compatibility of that driver. The line is eventually
|
|
written to memdb.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains the valid line that is currently being parsed.
|
|
Parameter - This parameter is unused.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the function completed successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
pHandleConfigSysDevice (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
TCHAR buffer[MEMDB_MAX];
|
|
PCTSTR p;
|
|
|
|
//
|
|
// looks like there ARE config.sys files with INSTALLHIGH "driver",
|
|
// without "equal" sign (like INSTALLHIGH driver, and not INSTALLHIGH=driver)
|
|
|
|
p = SkipSpace(LineStruct -> Arguments);
|
|
if (_tcsnextc (p) == TEXT('=')) {
|
|
p = SkipSpace (p + 1);
|
|
}
|
|
|
|
StringCopy(buffer, p);
|
|
return ParseLine(buffer, &g_BatchFileRules);
|
|
}
|
|
|
|
DWORD
|
|
pGetLineTypeFromNtStatusAndPath (
|
|
IN DWORD Status,
|
|
IN PCTSTR Path
|
|
)
|
|
{
|
|
DWORD unused;
|
|
DWORD rType = DOSMIG_UNKNOWN;
|
|
|
|
|
|
if (Status & (FILESTATUS_MOVED | FILESTATUS_REPLACED)) {
|
|
|
|
rType = DOSMIG_USE;
|
|
|
|
} else if (Status & FILESTATUS_DELETED) {
|
|
|
|
rType = DOSMIG_IGNORE;
|
|
|
|
} else {
|
|
|
|
if (IsFileMarkedAsHandled (Path)) {
|
|
|
|
rType = DOSMIG_IGNORE;
|
|
|
|
}else if (IsReportObjectHandled(Path)) {
|
|
|
|
rType = DOSMIG_USE;
|
|
|
|
} else if (MemDbGetOffsetEx(MEMDB_CATEGORY_COMPATIBLE_DOS,Path,NULL,NULL,&unused)) {
|
|
|
|
rType = DOSMIG_USE;
|
|
|
|
} else if (MemDbGetOffsetEx(MEMDB_CATEGORY_DEFERREDANNOUNCE,Path,NULL,NULL,&unused)) {
|
|
|
|
rType = DOSMIG_IGNORE;
|
|
}
|
|
}
|
|
|
|
return rType;
|
|
}
|
|
|
|
BOOL
|
|
pHandleShell (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
PTSTR p=LineStruct->Arguments;
|
|
LINESTRUCT ls;
|
|
TCHAR buffer[MEMDB_MAX];
|
|
UINT lineType;
|
|
|
|
|
|
if (p) {
|
|
p = _tcsinc (p);
|
|
|
|
}
|
|
else {
|
|
return pSaveItem (LineStruct, DOSMIG_IGNORE);
|
|
}
|
|
|
|
InitLineStruct (&ls, p);
|
|
|
|
lineType = pGetLineTypeFromNtStatusAndPath (ls.StatusOnNt, ls.FullPath);
|
|
|
|
if (lineType == DOSMIG_USE) {
|
|
|
|
//
|
|
// Fix up the line and save it back.
|
|
//
|
|
wsprintf(buffer, TEXT("SHELL=%s %s"), ls.PathOnNt, ls.Arguments ? ls.Arguments : S_EMPTY);
|
|
g_CurrentLine = PoolMemDuplicateString (g_DosMigPool, buffer);
|
|
|
|
}
|
|
|
|
return pSaveItem (LineStruct, lineType);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pHandleUnknownBatLine _tries_ to deal with any line that is not caught by
|
|
another explicit rule...The first thing it will do is see if the line
|
|
starts with a path containing *.bat. If so, it will add that bat file to
|
|
the list to be parsed. If the file does not end with *.bat, then, the
|
|
function will assume that this is a tsr and attempt to determine its
|
|
compatibility.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains the valid line that is currently being parsed.
|
|
Parameter - This parameter is unused.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the function completed successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
pHandleUnknownBatLine (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
|
|
BOOL rSuccess = TRUE;
|
|
DWORD lineType = DOSMIG_UNKNOWN;
|
|
|
|
DEBUGMSG((DBG_DOSMIG,"Processing unknown bat line...%s.",LineStruct -> FullLine));
|
|
|
|
//
|
|
// First, see if this is a *.bat file..
|
|
//
|
|
if (IsPatternMatch(TEXT("*.bat"),LineStruct -> Command)) {
|
|
//
|
|
// This is another batch file..add it to those to be parsed..
|
|
//
|
|
DEBUGMSG((DBG_DOSMIG,"...The line is a batch file. Add it to those to be parsed.."));
|
|
if (!GrowListAppendString(&g_FileList,LineStruct -> FullLine)) {
|
|
rSuccess = FALSE;
|
|
}
|
|
|
|
lineType = DOSMIG_USE;
|
|
}
|
|
|
|
//
|
|
// See if they are changing the drive.
|
|
//
|
|
if (IsPatternMatch(TEXT("?:"),LineStruct->Command)) {
|
|
|
|
lineType = DOSMIG_USE;
|
|
}
|
|
|
|
|
|
if (lineType == DOSMIG_UNKNOWN) {
|
|
|
|
//
|
|
// Still don't know what the line is. Lets check its status on NT. if it is moved ore replaced,
|
|
// we'll just change the path if necessary, and use it. Otherwise,
|
|
//
|
|
|
|
lineType = pGetLineTypeFromNtStatusAndPath (LineStruct->StatusOnNt, LineStruct->FullPath);
|
|
}
|
|
|
|
//
|
|
// In anycase, save away the line in memdb.
|
|
//
|
|
rSuccess &= pSaveItem(LineStruct,lineType);
|
|
|
|
|
|
|
|
return rSuccess;
|
|
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pHandleHighFilter - Is responsible for handling the "*high" statements
|
|
besides LoadHigh and lh.
|
|
|
|
Arguments:
|
|
|
|
Line - Contains the valid line that is currently being parsed.
|
|
Parameter - This parameter is unused.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the function completed successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
BOOL
|
|
pHandleHighFilter (
|
|
IN PLINESTRUCT LineStruct,
|
|
DWORD Parameter
|
|
)
|
|
{
|
|
PTSTR p;
|
|
BOOL rSuccess = TRUE;
|
|
|
|
|
|
if (!StringIMatch (LineStruct->Command, LineStruct->FullPath)) {
|
|
|
|
return pHandleUnknownBatLine (LineStruct, Parameter);
|
|
}
|
|
|
|
_tcslwr (LineStruct->FullLine);
|
|
p = _tcsstr (LineStruct->FullLine,TEXT("high"));
|
|
if (!p || p == LineStruct->FullLine) {
|
|
return pHandleUnknownBatLine (LineStruct, Parameter);
|
|
}
|
|
|
|
*p = 0;
|
|
p = JoinTextEx (NULL, LineStruct->FullLine, p + 4, TEXT(""), 0, NULL);
|
|
rSuccess = ParseLine (p, g_CurrentRules);
|
|
FreeText (p);
|
|
|
|
|
|
return rSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pAddRuleToList creates a PARSERULE out of the parameters passed in and adds
|
|
it to the List provided by the caller.
|
|
|
|
Arguments:
|
|
|
|
Name - The name of the parse rule.
|
|
Pattern - The pattern for this parse rule
|
|
Function - The function to call when this rule is hit.
|
|
Parameter - The extra parameter data to pass to the function when this rule
|
|
is hit.
|
|
List - This list of rules to add the new parse rule to.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the rule was successfully added, FALSE
|
|
otherwise.
|
|
|
|
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
pAddRuleToList (
|
|
PCTSTR Name,
|
|
PCTSTR Pattern,
|
|
RULEFUNC * Function,
|
|
DWORD Parameter,
|
|
PPARSERULE * List
|
|
)
|
|
|
|
{
|
|
|
|
BOOL rSuccess = TRUE;
|
|
PPARSERULE newRule = NULL;
|
|
PPARSERULE curRule = NULL;
|
|
|
|
MYASSERT(List);
|
|
MYASSERT(Function);
|
|
MYASSERT(Name);
|
|
|
|
|
|
//
|
|
// Allocate memory for the new rule.
|
|
//
|
|
newRule = PoolMemGetMemory(g_DosMigPool,sizeof(PARSERULE));
|
|
if (newRule) {
|
|
|
|
|
|
//
|
|
// Fill in the new rule.
|
|
//
|
|
newRule -> Name = Name;
|
|
newRule -> Pattern = Pattern;
|
|
newRule -> Handle = Function;
|
|
newRule -> Parameter = Parameter;
|
|
newRule -> Next = NULL;
|
|
|
|
|
|
//
|
|
// Attach the rule into the provided list.
|
|
//
|
|
if (!*List) {
|
|
*List = newRule;
|
|
}
|
|
else {
|
|
curRule = *List;
|
|
while (curRule -> Next) {
|
|
curRule = curRule -> Next;
|
|
}
|
|
curRule -> Next = newRule;
|
|
}
|
|
}
|
|
ELSE_DEBUGMSG((DBG_ERROR,"Not enough memory to create rule."));
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pBuildParseRules builds the rule lists for config.sys and autoexec.bat
|
|
files.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
VOID
|
|
pBuildParseRules (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
|
|
|
|
#define DEFAULTPARSERULE(Name,Pattern,Function,Parameter) \
|
|
pAddRuleToList(Name,Pattern,Function,Parameter,&(curRules -> DefaultRule));
|
|
|
|
#define PARSERULE(Name,Pattern,Function,Parameter) \
|
|
pAddRuleToList(Name,Pattern,Function,Parameter,&(curRules -> RuleList));
|
|
|
|
|
|
PPARSERULES curRules = NULL;
|
|
|
|
|
|
//
|
|
// Create config sys rules.
|
|
//
|
|
curRules = &g_ConfigSysRules;
|
|
curRules -> Name = TEXT("Config.sys Rules");
|
|
|
|
CONFIGSYSLIST;
|
|
|
|
//
|
|
// Create batch file rules.
|
|
//
|
|
curRules = &g_BatchFileRules;
|
|
curRules -> Name = TEXT("Batch File Rules");
|
|
|
|
BATCHFILELIST;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
ParseDosFiles is the function which handles the parsing of legacy
|
|
configuration files (config.sys and batch files...)
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
True if the files were successfully parsed, FALSE
|
|
otherwise.
|
|
|
|
|
|
--*/
|
|
|
|
|
|
BOOL
|
|
ParseDosFiles (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
BOOL rSuccess = TRUE;
|
|
PCTSTR curFile;
|
|
DWORD curIndex = 0;
|
|
TCHAR autoexecPath[] = S_AUTOEXECPATH;
|
|
TCHAR configsysPath[] = S_CONFIGSYSPATH;
|
|
PTSTR p;
|
|
|
|
//
|
|
// Initialize the parser.
|
|
//
|
|
if (InitParser()) {
|
|
|
|
//
|
|
// build the lists of parse rules.
|
|
//
|
|
pBuildParseRules();
|
|
|
|
//
|
|
// Update drive letter
|
|
//
|
|
|
|
autoexecPath[0] = g_BootDriveLetter;
|
|
configsysPath[0] = g_BootDriveLetter;
|
|
|
|
p = _tcschr(autoexecPath, TEXT('a'));
|
|
*p = 0;
|
|
GrowBufAppendString(&g_ExtraPaths,autoexecPath);
|
|
*p = TEXT('a');
|
|
|
|
//
|
|
// Add config.sys and autoexec.bat to the list of files to parse.
|
|
//
|
|
GrowListAppendString(&g_FileList,configsysPath);
|
|
GrowListAppendString(&g_FileList,autoexecPath);
|
|
|
|
//
|
|
// Now, parse the files in the list. Note that additional files may be added
|
|
// to the list as a result of parsing. (i.e. by finding a call statement.)
|
|
//
|
|
while (curFile = GrowListGetString(&g_FileList,curIndex++)) {
|
|
|
|
if (DoesFileExist (curFile)) {
|
|
|
|
//
|
|
// Save the file into memdb.
|
|
//
|
|
MemDbSetValueEx(MEMDB_CATEGORY_DM_FILES,NULL,NULL,curFile,0,&g_CurrentFileOffset);
|
|
|
|
//
|
|
// parse the file using config.sys parse rules if the file is config.sys and
|
|
// the batch file parse rules otherwise.
|
|
//
|
|
if (StringIMatch(configsysPath,curFile)) {
|
|
|
|
g_CurrentRules = &g_ConfigSysRules;
|
|
rSuccess &= ParseFile(curFile,&g_ConfigSysRules);
|
|
|
|
}
|
|
else {
|
|
|
|
g_CurrentRules = &g_BatchFileRules;
|
|
rSuccess &= ParseFile(curFile,&g_BatchFileRules);
|
|
|
|
}
|
|
}
|
|
ELSE_DEBUGMSG((DBG_DOSMIG,"The path %s does not exist. This file will not be processed.", curFile));
|
|
}
|
|
|
|
|
|
//
|
|
// There was an incompatibility detected. Write the incompatibility buffer to the log.
|
|
//
|
|
if (g_IncompatibilityDetected) {
|
|
|
|
LOG ((LOG_WARNING, (PCSTR)MSG_DOS_LOG_WARNING, g_IncompatibilityBuffer.Buf));
|
|
}
|
|
|
|
//
|
|
// Cleanup resources.
|
|
//
|
|
FreeGrowBuffer(&g_IncompatibilityBuffer);
|
|
FreeGrowList(&g_FileList);
|
|
CleanUpParser();
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
|
|
#define S_PATH_PATTERN TEXT("Path*")
|
|
|
|
BOOL
|
|
ParseEnvironmentVariables (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
BOOL rSuccess = TRUE;
|
|
PVOID envVars = NULL;
|
|
PTSTR line = NULL;
|
|
MULTISZ_ENUM e;
|
|
LINESTRUCT ls;
|
|
PTSTR p;
|
|
HASHTABLE excludeTable = NULL;
|
|
HASHITEM hashResult;
|
|
|
|
envVars = GetEnvironmentStrings();
|
|
|
|
|
|
__try {
|
|
|
|
if (!envVars) {
|
|
LOG((
|
|
LOG_WARNING,
|
|
"Unable to retrieve environment variables. "
|
|
"Some environment variables may not be migrated correctly. "
|
|
"rc from GetEnvironmentStrings: %u",
|
|
GetLastError()
|
|
));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Set fake name of file for envvars.
|
|
//
|
|
MemDbSetValueEx (MEMDB_CATEGORY_DM_FILES, NULL, NULL, S_ENVVARS, 0, &g_CurrentFileOffset);
|
|
|
|
//
|
|
// Enumerate through each of the environment variables and save them away for migration.
|
|
//
|
|
if (EnumFirstMultiSz (&e, envVars)) {
|
|
|
|
//
|
|
// Create list of environment variables to skip.
|
|
//
|
|
excludeTable = HtAlloc ();
|
|
MYASSERT (excludeTable);
|
|
|
|
HtAddString (excludeTable, TEXT("path"));
|
|
HtAddString (excludeTable, TEXT("comspec"));
|
|
HtAddString (excludeTable, TEXT("cmdline"));
|
|
|
|
ZeroMemory(&ls,sizeof(LINESTRUCT));
|
|
|
|
|
|
do {
|
|
|
|
p = _tcschr (e.CurrentString, TEXT('='));
|
|
|
|
//
|
|
// Get rid of empty environment strings or the dummy env string starting
|
|
// with '='
|
|
//
|
|
if (!p || p == e.CurrentString) {
|
|
continue;
|
|
}
|
|
|
|
*p = 0;
|
|
|
|
hashResult = HtFindString (excludeTable, e.CurrentString);
|
|
|
|
*p = TEXT('=');
|
|
|
|
if (!hashResult) {
|
|
//
|
|
// This is a good environment string. As long as the length is ok, lets migrate it.
|
|
//
|
|
line = JoinTextEx (NULL, TEXT("SET"), e.CurrentString, TEXT(" "), 0, NULL);
|
|
if (line) {
|
|
|
|
if (CharCount (line) < (MEMDB_MAX/sizeof(WCHAR))) {
|
|
|
|
g_CurrentLine = line;
|
|
StringCopy (ls.FullLine, line);
|
|
pSaveItem (&ls, DOSMIG_MIGRATE);
|
|
}
|
|
|
|
|
|
FreeText (line);
|
|
}
|
|
|
|
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_VERBOSE, "Skipping excluded environment variable %s.", e.CurrentString));
|
|
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
|
|
//
|
|
// Add %windir% as an environment variable in NT. %windir% is implicit, but is not passed down to the
|
|
// WOW layer on NT.
|
|
//
|
|
line = AllocPathString (MAX_TCHAR_PATH);
|
|
wsprintf (line, TEXT("SET WINDIR=%s"), g_WinDir);
|
|
|
|
g_CurrentLine = line;
|
|
StringCopy (ls.FullLine, line);
|
|
pSaveItem (&ls, DOSMIG_MIGRATE);
|
|
|
|
FreePathString (line);
|
|
|
|
|
|
}
|
|
}
|
|
__finally {
|
|
|
|
if (envVars) {
|
|
FreeEnvironmentStrings(envVars);
|
|
}
|
|
HtFree (excludeTable);
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
LONG
|
|
pProcessDosConfigFiles (
|
|
void
|
|
)
|
|
|
|
{
|
|
|
|
BeginMessageProcessing();
|
|
|
|
g_DosMigPool = PoolMemInitNamedPool ("DosMig");
|
|
|
|
if (g_DosMigPool) {
|
|
|
|
if (!ParseDosFiles()) {
|
|
DEBUGMSG ((DBG_ERROR, "Errors occurred during the processing of DOS configuration files. Some dos settings may not be preserved."));
|
|
|
|
}
|
|
if (!ParseEnvironmentVariables()) {
|
|
DEBUGMSG ((DBG_ERROR, "Errors occured during the processing of environment variables. Environment variables may not be preserved."));
|
|
}
|
|
|
|
PoolMemDestroyPool(g_DosMigPool);
|
|
}
|
|
|
|
EndMessageProcessing();
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
DWORD
|
|
ProcessDosConfigFiles (
|
|
IN DWORD Request
|
|
)
|
|
{
|
|
switch (Request) {
|
|
case REQUEST_QUERYTICKS:
|
|
return TICKS_DOSMIG_PREPARE_REPORT;
|
|
case REQUEST_RUN:
|
|
return pProcessDosConfigFiles ();
|
|
default:
|
|
DEBUGMSG ((DBG_ERROR, "Bad parameter in DosMig_PrepareReport"));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BOOL
|
|
DosMig_Entry (
|
|
IN HINSTANCE hinstDLL,
|
|
IN DWORD dwReason,
|
|
IN LPVOID lpv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the g_CfgFiles structure.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Returns true if g_CfgFiles was successfully initialized,
|
|
FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
BOOL rFlag = TRUE;
|
|
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
break;
|
|
}
|
|
|
|
return rFlag;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|