windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/w95upgnt/migmain/dosmignt.c
2020-09-26 16:20:57 +08:00

1451 lines
33 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
dosmignt.c
Abstract:
handles windows nt side migration of config.sys and autoexec.bat information
gathered during win9x upgrading. migrates environement settings, prompts, and
some doskey information. Also modifies the autoexec.nt and config.nt files.
Author:
Marc R. Whitten (marcw) 15-Feb-1997
Revision History:
--*/
#include "pch.h"
#include "w95upgnt.h"
#define DBG_DOSMIG "Dosmig"
//
// Flag that is set if Doskey /INSERT needs to be set.
//
BOOL g_MigrateDoskeySetting = FALSE;
//
// PoolMem Handle to pool used for dynamic allocations.
//
POOLHANDLE g_Pool = NULL;
//
// Flag that is set if all necessary data has been collected for migration.
//
BOOL g_MigrationPrepared = FALSE;
//
// String that points to the current file being processed.
//
PCTSTR g_CurrentFile = NULL;
PCTSTR g_LastFile = NULL;
//
// Boolean flag indicating wether any changes were made to the flag.
//
BOOL g_FileChanged = FALSE;
//
// The suppression table holds environment variables we want to ignore.
//
HASHTABLE g_SuppressionTable = NULL;
//
// List of path segments.
//
GROWLIST g_PathList = GROWLIST_INIT;
#define STRINGBUFFER(x) ((PTSTR) (x)->Buf)
#define BUFFEREMPTY(x) ((x)->End == 0)
typedef enum {
DOSMIG_UNUSED,
DOSMIG_BAD,
DOSMIG_UNKNOWN,
DOSMIG_USE,
DOSMIG_MIGRATE,
DOSMIG_IGNORE,
DOSMIG_LAST
} DOSMIG_LINETAG, *PDOSMIG_LINETAG;
PCTSTR
pGetFileNameStartFromPath (
IN PCTSTR Line
)
/*++
Routine Description:
This function returns the start of a File name in a(n assumed
wellformed) path.
Arguments:
Line - The String containing the path and filename.
Return Value:
A pointer to the filename portion of the path. Note, this function
assumes that there may be (potentially valuable) arguments after the
file name. The pointer does not, therefore point only
--*/
{
PCTSTR lineStart = Line;
PCTSTR lineEnd = Line;
if (Line == NULL) {
return NULL;
}
while (_istalnum(*lineEnd) ||
*lineEnd == TEXT('_') ||
*lineEnd == TEXT('.') ||
*lineEnd == TEXT('\\') ||
*lineEnd == TEXT(':')) {
if((*lineEnd == TEXT('\\')) || (*lineEnd == TEXT(':'))) {
lineStart = _tcsinc(lineEnd);
}
lineEnd = _tcsinc(lineEnd);
}
return lineStart;
}
LONG
pSaveBufferToAnsiFile (
IN PCTSTR Path,
IN PCTSTR Buffer
)
{
HANDLE fileHandle;
LONG rc = ERROR_SUCCESS;
DWORD amountWritten;
PTSTR savePath = NULL;
BOOL sysFile = TRUE;
PCSTR ansiString = NULL;
DWORD ansiStringLength;
PCTSTR ArgList[1];
PCTSTR Message = NULL;
PCTSTR p;
PCTSTR fileName;
MYASSERT (Path && Buffer);
//
// IF this is a system file (i.e. config.sys or autoexec.bat) redirect the
// file to config.nt or autoexec.nt.
//
p = _tcschr (Path, TEXT('\\'));
if (p) {
p = _tcsinc (p);
} else {
p = Path;
}
fileName = p;
if (StringIMatch (p, TEXT("config.sys"))) {
savePath = JoinPaths(g_System32Dir,TEXT("config.nt"));
} else if (StringIMatch (p, TEXT("autoexec.bat"))) {
savePath = JoinPaths(g_System32Dir,TEXT("autoexec.nt"));
} else {
sysFile = FALSE;
savePath = (PTSTR) Path;
}
//
// If the file was not changed during the migration, do nothing.
//
if (sysFile || g_FileChanged) {
//
// Open a handle to the file to be created.
//
fileHandle = CreateFile(
savePath,
GENERIC_WRITE,
0,
NULL,
sysFile ? OPEN_ALWAYS : CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (fileHandle == INVALID_HANDLE_VALUE) {
rc = GetLastError();
} else {
//
// Append from the end of the file.
//
SetFilePointer(
fileHandle,
0,
NULL,
FILE_END
);
ArgList[0] = g_Win95Name;
Message = ParseMessageID (MSG_DMNT_APPENDSTRING, ArgList);
ansiString = CreateDbcs (Message);
ansiStringLength = ByteCountA (ansiString);
WriteFile(
fileHandle,
ansiString,
ansiStringLength,
&amountWritten,
NULL
);
FreeStringResource (Message);
DestroyDbcs (ansiString);
ansiString = CreateDbcs (Buffer);
ansiStringLength = ByteCountA (ansiString);
if (!WriteFile(
fileHandle,
ansiString,
ansiStringLength,
&amountWritten,
NULL
)) {
LOG((LOG_ERROR, "Error writing buffer to file."));
}
DestroyDbcs (ansiString);
//
// Log the file change.
//
LOG ((
LOG_INFORMATION,
"%s was updated with settings from %s",
savePath,
fileName
));
CloseHandle(fileHandle);
}
if (sysFile) {
FreePathString(savePath);
}
}
return rc;
}
LONG
pTurnInsertModeOn (
HKEY UserKey
)
{
LONG rc;
HKEY key;
DWORD value = 1;
rc = TrackedRegOpenKeyEx (UserKey,S_CONSOLEKEY,0,KEY_ALL_ACCESS,&key);
if (rc == ERROR_SUCCESS) {
rc = RegSetValueEx(
key,
S_INSERTMODEVALUE,
0,
REG_DWORD,
(PBYTE) &value,
sizeof(DWORD)
);
CloseRegKey(key);
}
return rc;
}
LONG
pTurnAutoParseOff (
HKEY UserKey
)
{
LONG rc;
HKEY key;
PCTSTR valueStr = TEXT("0");
DWORD valueStrBytes = 2*sizeof(TCHAR);
rc = TrackedRegOpenKeyEx(UserKey,S_WINLOGONKEY,0,KEY_ALL_ACCESS,&key);
if (rc == ERROR_SUCCESS) {
rc = RegSetValueEx(
key,
S_AUTOPARSEVALUE,
0,
REG_SZ,
(PBYTE) valueStr,
valueStrBytes
);
if (rc != ERROR_SUCCESS) {
DEBUGMSG((DBG_WARNING,"DosMig: Unable to Save new ParseAutoexec value. rc: %u (%x)",rc,rc));
}
else {
DEBUGMSG((DBG_DOSMIG,"ParseAutoexec turned off."));
}
CloseRegKey(key);
}
else {
DEBUGMSG((DBG_WARNING,"DosMig: Unable to open %s rc: %u (%x)",S_WINLOGONKEY,rc,rc));
}
return rc;
}
LONG
pMigrateEnvSetting (
IN PCTSTR Setting,
IN PCTSTR EnvValue,
IN BOOL PrependSetPrefix,
IN OUT PGROWBUFFER Buffer, OPTIONAL
OUT PBOOL AppendedToBuffer OPTIONAL
)
{
LONG rc = ERROR_SUCCESS;
GROWBUFFER newSetting = GROWBUF_INIT;
TCHAR currentPath[MAX_CMDLINE];
TCHAR matchBuffer[MEMDB_MAX];
PCTSTR start;
PCTSTR end;
HKEY key;
DWORD sizeNeeded;
DWORD valueType;
PTSTR storage;
BOOL append = FALSE;
PTSTR p;
PTSTR q;
BOOL bRegMigrationSuppressed;
PTSTR expandKey = TEXT("");
if (AppendedToBuffer) {
*AppendedToBuffer = FALSE;
}
//
// Make sure this setting is not suppressed.
//
bRegMigrationSuppressed = HtFindString (g_SuppressionTable, Setting) != NULL;
if (bRegMigrationSuppressed) {
DEBUGMSG ((DBG_DOSMIG, "pMigrateEnvSetting: NOT Migrating %s = %s in registry. Environment variable is suppressed.", Setting, EnvValue));
}
DEBUGMSG((DBG_DOSMIG,"pMigrateEnvSetting: Migrating %s = %s.",Setting,EnvValue));
if (!bRegMigrationSuppressed) {
//
// Attempt to open the registry key.
//
rc = TrackedRegOpenKeyEx(
HKEY_LOCAL_MACHINE,
S_ENVIRONMENTKEY,
0,
KEY_ALL_ACCESS,
&key
);
if (rc != ERROR_SUCCESS) {
LOG((LOG_ERROR,"Dosmig: Could not open key %s",S_ENVIRONMENTKEY));
return rc;
}
}
start = EnvValue;
do {
//
// Find end of this portion of the environment string.
// this is (1) the first ';' encountered, or (2) the trailing NULL
//
end = _tcschr(start,TEXT(';'));
if (!end) {
end = GetEndOfString(start);
}
//
// save a copy of the currently found path.
//
StringCopyAB(currentPath,start,end);
//
// Look for self-replacement case.
// This is the case where there are multiple statements setting the
// same environment variable like:
// set foo=bar
// set foo=%foo%;bar2
//
wsprintf(matchBuffer,TEXT("%%%s%%"),Setting);
if (!bRegMigrationSuppressed &&
(StringIMatch(currentPath,matchBuffer) ||
(StringIMatch(currentPath,TEXT("%PATH%")) &&
StringIMatch(Setting,TEXT("MIGRATED_PATH"))
))) {
//
// Get contents of key if it exists.
//
rc = RegQueryValueEx(
key,
Setting,
0,
&valueType,
NULL,
&sizeNeeded);
if (rc == ERROR_SUCCESS) {
//
// Now, create a temporary duplicate of the key and
//
storage = PoolMemCreateString(g_Pool,sizeNeeded+1);
if (storage != NULL) {
rc = RegQueryValueEx(
key,
Setting,
0,
&valueType,
(PBYTE) storage,
&sizeNeeded
);
if (rc != ERROR_SUCCESS) {
LOG((LOG_ERROR,"Dosmig: ReqQueryValueEx failure."));
}
//
// Add this to the environment string to be set.
//
if (append) {
GrowBufAppendString (&newSetting,TEXT(";"));
}
GrowBufAppendString (&newSetting,storage);
PoolMemReleaseMemory(g_Pool,storage);
append = TRUE;
}
else {
rc = GetLastError();
DEBUGMSG((DBG_ERROR,"Dosmig: Error! Unable to allocate storage."));
}
}
else {
rc = ERROR_SUCCESS;
}
}
else {
//
// append the massaged path, keep it for later use.
//
if (append) {
GrowBufAppendString (&newSetting,TEXT(";"));
}
//
// Make sure we take care of any DIR moves.
//
ConvertWin9xCmdLine (currentPath, NULL, NULL);
GrowBufAppendString (&newSetting, currentPath);
//
// store the updated path in the given growbuffer
//
if (Buffer) {
if (PrependSetPrefix && !append) {
StringCopy (matchBuffer, TEXT("SET "));
q = GetEndOfString (matchBuffer);
} else {
q = matchBuffer;
}
if (!append) {
wsprintf (q, TEXT("%s=%s"), Setting, currentPath);
} else {
*q++ = TEXT(';');
StringCopy (q, currentPath);
}
GrowBufAppendString (Buffer, matchBuffer);
if (AppendedToBuffer) {
*AppendedToBuffer = TRUE;
}
}
append = TRUE;
}
//
// set start pointer for next iteration of path.
//
start = end;
if (*start == TEXT(';')) {
start = _tcsinc(start);
}
} while (*start);
if (!bRegMigrationSuppressed) {
//
// Save the value we built up into the registry.
//
if (rc == ERROR_SUCCESS && newSetting.Buf && *newSetting.Buf) {
rc = RegSetValueEx(
key,
Setting,
0,
REG_EXPAND_SZ,
(LPBYTE) newSetting.Buf,
SizeOfString((PCTSTR) newSetting.Buf)
);
if (rc != ERROR_SUCCESS) {
LOG ((LOG_ERROR,"Dosmig: Unexpectedly could not write key into registry."));
}
DEBUGMSG_IF((rc == ERROR_SUCCESS,DBG_DOSMIG,"Saved env setting into registry. (%s)",newSetting.Buf));
}
else if (rc != ERROR_SUCCESS) {
LOG((LOG_ERROR,"Dosmig: Some previous failure prevents writing the migrated env variable to the registry."));
}
//
// Clean up resource usage.
//
CloseRegKey(key);
}
FreeGrowBuffer(&newSetting);
return rc;
}
LONG
pSetPrompt (
IN PCTSTR PromptCommand
)
{
LONG rc = ERROR_SUCCESS;
PCTSTR promptSetting;
promptSetting = SkipSpace(CharCountToPointer((PTSTR)PromptCommand,6));
if (promptSetting && *promptSetting == TEXT('=')) {
promptSetting = SkipSpace(_tcsinc(promptSetting));
}
if (promptSetting) {
DEBUGMSG((DBG_DOSMIG,"Passing prompt statement off to env migration function."));
rc = pMigrateEnvSetting(S_PROMPT,promptSetting, FALSE, NULL, NULL);
}
ELSE_DEBUGMSG((DBG_DOSMIG,"PromptSetting is empty...ignored."));
return rc;
}
BOOL
pIsValidPath (
PCTSTR Path
)
{
PCTSTR currPtr;
if (!Path) {
return FALSE;
}
Path = SkipSpace(Path);
currPtr = Path;
do {
if ((*currPtr == TEXT(',')) ||
(*currPtr == TEXT(';')) ||
(*currPtr == TEXT('<')) ||
(*currPtr == TEXT('>')) ||
(*currPtr == TEXT('|')) ||
(*currPtr == TEXT('?')) ||
(*currPtr == TEXT('*'))
) {
return FALSE;
}
currPtr = _tcsinc (currPtr);
} while (*currPtr);
if ((*Path==0) || (*(Path+1)==0)) {
return FALSE;
}
currPtr = Path;
while (*currPtr == TEXT('"')) {
currPtr = _tcsinc (currPtr);
}
currPtr = SkipSpace(currPtr);
if (!_istalpha (*currPtr) &&
*currPtr != TEXT('\\') &&
*currPtr != TEXT('%')) {
return FALSE;
}
return TRUE;
}
LONG
pMigratePathSettings (
IN PCTSTR PathSettings
)
{
LONG rc = ERROR_SUCCESS;
PTSTR oldPath;
UINT i;
UINT size;
PTSTR end;
PTSTR p;
MYASSERT (StringIMatchCharCount (PathSettings, TEXT("PATH"), 4));
//
//skip past the 'PATH' portion of this statement.
//
oldPath = PoolMemDuplicateString (g_Pool, PathSettings);
oldPath = CharCountToPointer(oldPath,4);
//
//Look for an '=' sign.
//
p = _tcschr(oldPath,TEXT('='));
if (p) {
//
// Pass the equals sign.
//
oldPath = _tcsinc(p);
}
//
// Skip any white space before the actual beginning of the path.
//
while (*oldPath && iswspace(*oldPath)) {
oldPath = _tcsinc(oldPath);
}
if (*oldPath) {
//
// If there is actually anything to add to the path, add it.
//
p = oldPath;
while (p && *p) {
//
// Look for ';'
//
end = _tcschr (p, TEXT(';'));
if (end) {
*end = 0;
}
//
// Add this path to our path list.
//
size = GrowListGetSize (&g_PathList);
for (i = 0;i < size; i++) {
if (StringIMatch (p, GrowListGetString (&g_PathList, i))) {
DEBUGMSG ((DBG_DOSMIG, "Skipping path %s. It already exists in path.", p));
break;
}
}
if (i == size) {
//
// Path was not found in the list of path segments. Add it now.
//
if (pIsValidPath (p)) {
GrowListAppendString (&g_PathList, p);
}
ELSE_DEBUGMSG ((DBG_DOSMIG, "Skipping path %s. It is invalid.", p));
}
//
// Go to the next path segment.
//
if (end) {
p = _tcsinc(end);
}
else {
p = NULL;
}
}
}
return rc;
}
LONG
pMigrateSetSetting (
IN PCTSTR SetLine,
IN OUT PGROWBUFFER Buffer,
OUT PBOOL AppendedToBuffer
)
{
TCHAR setIdentifier[MEMDB_MAX];
PTSTR idEnd;
PCTSTR start;
PCTSTR end;
MYASSERT (StringIMatchCharCount (SetLine, TEXT("SET"), 3));
if (AppendedToBuffer) {
*AppendedToBuffer = FALSE;
}
//
// First, skip past the set and any whitespace.
//
start = SkipSpace(CharCountToPointer((PWSTR)SetLine,3));
if (!start) {
//
// line is of the form SET
//
return ERROR_SUCCESS;
}
end = _tcschr(start,TEXT('='));
if (!end) {
//
// line is of the form SET dafasdfasdfasdfasd
//
return ERROR_SUCCESS;
}
if (start==end) {
//
// line is of the form SET=
//
return ERROR_SUCCESS;
}
//
// Create an identifier now.
//
StringCopyAB(setIdentifier,start,end);
idEnd = GetEndOfString (setIdentifier);
//
// Shake off any space.
//
idEnd = (PTSTR) SkipSpaceR(setIdentifier,idEnd);
if (!idEnd) {
//
// Line is of the form SET =
//
return ERROR_SUCCESS;
}
idEnd = _tcsinc(idEnd);
*idEnd = TEXT('\0');
if (StringIMatch(setIdentifier,TEXT("PATH"))) {
DEBUGMSG((DBG_DOSMIG,"Env setting is really a path statement. passing off to path migration function."));
//
// This is really a path setting. let the proper function take care of it.
//
start = SkipSpace(CharCountToPointer((PWSTR)SetLine,3));
if(AppendedToBuffer){
*AppendedToBuffer = TRUE;
}
return pMigratePathSettings(start);
}
//
// Now that setIdentifier is well formed, root out the value to be set.
//
//
// Move start to the beginning of the value to be set.
//
start = SkipSpace(_tcsinc(end));
if (!start) {
//
// Line is of the form SET <id>=
// Nothing to do.
//
return ERROR_SUCCESS;
}
//
// Good to go. Let MigrateEnvSetting handle it.
//
DEBUGMSG((DBG_DOSMIG,"handing massaged set statement to env migration function."));
return pMigrateEnvSetting(setIdentifier,start, TRUE, Buffer, AppendedToBuffer);
}
BOOL
pProcessLine (
DWORD Type,
PGROWBUFFER Buffer,
PTSTR Line
)
{
BOOL rSuccess = TRUE;
LONG migrateRc = ERROR_SUCCESS;
PTSTR migrateString;
BOOL bAppendOrigLine;
TCHAR fixedCmdLine[MAX_CMDLINE];
//
// Do type specific massaging of the line
//
switch (Type) {
case DOSMIG_UNKNOWN: case DOSMIG_BAD: case DOSMIG_IGNORE:
g_FileChanged = TRUE;
GrowBufAppendString (Buffer,TEXT("REM "));
//
// intentionally skipped break.
//
case DOSMIG_USE:
//
// Perform path conversion on Line, then write it to the file
//
StackStringCopy (fixedCmdLine, Line);
ConvertWin9xCmdLine (fixedCmdLine, NULL, NULL);
GrowBufAppendString (Buffer, fixedCmdLine);
GrowBufAppendString (Buffer, TEXT("\r\n"));
break;
case DOSMIG_MIGRATE:
DEBUGMSG((DBG_DOSMIG,"Processing a potentially migrateable line. (%s)",Line));
if (IsPatternMatch(TEXT("doskey*"),Line) || IsPatternMatch(TEXT("*\\doskey*"),Line)) {
GrowBufAppendString (Buffer,TEXT("REM "));
}
//
// Skip space and ECHO OFF char (@) if any.
// Also, skip any path portion of the string.
// i.e, convert path/doskey to doskey.
migrateString = (PTSTR) SkipSpace(Line);
if (*migrateString == TEXT('@')) {
migrateString = (PTSTR) _tcsinc(migrateString);
}
migrateString = (PTSTR) pGetFileNameStartFromPath(migrateString);
bAppendOrigLine = TRUE;
//
// Now, attempt to determine what migration case this is.
//
if (IsPatternMatch(TEXT("prompt*"),migrateString)) {
DEBUGMSG((DBG_DOSMIG,"Migrating prompt. (%s)",migrateString));
migrateRc = pSetPrompt(migrateString);
if (migrateRc != ERROR_SUCCESS) {
rSuccess = FALSE;
LOG((LOG_ERROR,"Dosmig: Error trying to Set Prompt."));
}
ELSE_DEBUGMSG((DBG_DOSMIG,"Prompt successfully migrated."));
}
else if (IsPatternMatch(TEXT("doskey *"),migrateString)) {
//
// Doskey migration.
//
if (IsPatternMatch(TEXT("*/I*"),migrateString)) {
g_MigrateDoskeySetting = TRUE;
DEBUGMSG((DBG_DOSMIG,"Insert mode will be enabled for each user. (%s)",migrateString));
}
ELSE_DEBUGMSG((DBG_DOSMIG,"Doskey command found. However, no migrateable doskey settings found. Command ignored."));
}
else if (IsPatternMatch(TEXT("path=*"),migrateString)
|| IsPatternMatch(TEXT("path *"),migrateString)) {
//
// PATH migration.
//
DEBUGMSG((DBG_DOSMIG,"Migrating path setting (%s)",migrateString));
migrateRc = pMigratePathSettings(migrateString);
if (migrateRc != ERROR_SUCCESS) {
rSuccess = FALSE;
LOG((LOG_ERROR,"Dosmig: Error trying to migrate path settings."));
}
ELSE_DEBUGMSG((DBG_DOSMIG,"Path successfully migrated."));
}
else if (IsPatternMatch(TEXT("set *"),migrateString)) {
BOOL b;
//
// SET migration.
//
DEBUGMSG((DBG_DOSMIG,"Migrating env variable. (%s)",migrateString));
migrateRc = pMigrateSetSetting(migrateString, Buffer, &b);
bAppendOrigLine = !b;
if (migrateRc != ERROR_SUCCESS) {
rSuccess = FALSE;
LOG((LOG_ERROR,"Dosmig: Error trying to migrate environment setting."));
}
ELSE_DEBUGMSG((DBG_DOSMIG,"Env variable successfully migrated."));
}
ELSE_DEBUGMSG((DBG_DOSMIG,"Dosmig: Line marked for migration doesn't fit any migration rule.\n%s",Line));
if (bAppendOrigLine) {
GrowBufAppendString (Buffer,Line);
}
//
// Last, append a CRLF into the buffer to be written.
//
GrowBufAppendString (Buffer,TEXT("\r\n"));
break;
default:
LOG((LOG_ERROR,"Dosmig: Invalid Type in switch statement."));
break;
}
return rSuccess;
}
BOOL
pNewFile (
DWORD Offset
) {
TCHAR file[MAX_TCHAR_PATH];
static DWORD curOffset = INVALID_OFFSET;
BOOL rNewFile = FALSE;
if (Offset != curOffset && MemDbBuildKeyFromOffset(Offset,file,1,NULL)) {
//
// if there isn't a current file, or this is a new file, set the current file
// to this file.
//
if (!g_CurrentFile || !StringMatch(file,g_CurrentFile)) {
//
// If this is a genuine new file (i.e. not just the first file, we'll return true.)
//
rNewFile = g_CurrentFile != NULL;
g_LastFile = g_CurrentFile;
g_CurrentFile = PoolMemDuplicateString(g_Pool,file);
}
}
return rNewFile;
}
VOID
pCompletePathProcessing (
VOID
)
{
UINT i;
UINT size;
UINT winDirLen;
GROWBUFFER buf = GROWBUF_INIT;
PTSTR p;
TCHAR pathStatement[2*MAX_TCHAR_PATH];
TCHAR newPath[MAX_TCHAR_PATH];
HKEY key;
DWORD rc;
//
// Make sure %systemroot% and %systemroot%\system32 are in the path.
//
wsprintf (pathStatement, TEXT("PATH=%s"), g_WinDir);
pMigratePathSettings (pathStatement);
wsprintf (pathStatement, TEXT("PATH=%s\\system32"), g_WinDir);
pMigratePathSettings (pathStatement);
wsprintf (pathStatement, TEXT("PATH=%s\\system32\\WBEM"), g_WinDir);
pMigratePathSettings (pathStatement);
winDirLen = CharCount (g_WinDir);
size = GrowListGetSize (&g_PathList);
for (i = 0; i < size; i++) {
p = (PTSTR) GrowListGetString (&g_PathList, i);
if (StringIMatch (TEXT("%PATH%"), p)) {
//
// Skip self-replacement.
//
continue;
}
if (GetFileStatusOnNt (p) & FILESTATUS_DELETED) {
//
// Skip this path portion. The directory was deleted.
//
DEBUGMSG ((DBG_DOSMIG, "Not migrating %s to new %%path%%. Directory was deleted.", p));
continue;
}
//
// See if the path is moved.
//
if (GetFileInfoOnNt (p, newPath, MAX_TCHAR_PATH) & FILESTATUS_MOVED) {
p = newPath;
}
//
// Replace c:\windows with %systemroot%.
//
if (StringIMatchCharCount (g_WinDir, p, winDirLen)) {
GrowBufAppendString (&buf, TEXT("%SYSTEMROOT%"));
GrowBufAppendString (&buf, p + winDirLen);
}
else {
GrowBufAppendString (&buf, p);
}
GrowBufAppendString (&buf, TEXT(";"));
}
if (size) {
//
// Take off trailing ';'.
//
p = GetEndOfString ((PTSTR) buf.Buf);
if (p) {
p--;
*p = 0;
}
//
// Save into registry.
//
key = OpenRegKey (HKEY_LOCAL_MACHINE,S_ENVIRONMENTKEY);
if (key && key != INVALID_HANDLE_VALUE) {
rc = RegSetValueEx (
key,
TEXT("Path"),
0,
REG_EXPAND_SZ,
(PBYTE) buf.Buf,
SizeOfString((PCTSTR) buf.Buf)
);
if (rc != ERROR_SUCCESS) {
DEBUGMSG ((DBG_WARNING, "Unable to create migrated Path variable."));
}
CloseRegKey (key);
}
ELSE_DEBUGMSG ((DBG_WARNING, "pCompletePathProcessing: Unable to open environment key."));
}
//
// Clean up resources.
//
FreeGrowBuffer (&buf);
}
VOID
pPathListToBuffer(
GROWBUFFER * growBuf
)
{
INT i;
i = GrowListGetSize (&g_PathList);
if(i <= 0){
return;
}
GrowBufAppendString (growBuf, TEXT("\r\nPATH="));
for (--i; i >= 0; i--) {
GrowBufAppendString (growBuf, GrowListGetString (&g_PathList, i));
if(i){
GrowBufAppendString (growBuf, TEXT(";"));
}
}
GrowBufAppendString (growBuf, TEXT("\r\n"));
}
BOOL
pGeneralMigration (
VOID
)
{
BOOL rSuccess = TRUE; // return value.
MEMDB_ENUM eItems; // Enumerator for each dosmig line.
TCHAR lineBuffer[MEMDB_MAX]; // Buffer for the contents of the current line.
GROWBUFFER buffer = GROWBUF_INIT;
TCHAR key[MEMDB_MAX];
DWORD offset;
DWORD value;
INFSTRUCT is = INITINFSTRUCT_POOLHANDLE;
PTSTR p = NULL;
TCHAR pathStatement[MAX_PATH];
//
// Assume that there are no doskey settings to migrate.
//
g_MigrateDoskeySetting = FALSE;
//
// Set the change flag to false.
//
g_FileChanged = FALSE;
//
// Read in the suppression table from win95upg.inf and add it the suppression table.
//
g_SuppressionTable = HtAlloc ();
if (InfFindFirstLine (g_WkstaMigInf, S_SUPPRESSED_ENV_VARS, NULL, &is)) {
do {
p = InfGetStringField (&is, 0);
if (p) {
HtAddString (g_SuppressionTable, p);
}
} while (InfFindNextLine (&is));
}
InfCleanUpInfStruct (&is);
//
// Ok, enumerate through each dosmigration line in memdb. These lines are stored
// as following:
//
// DOSMIG LINES\<item>\<field>\<data>
//
// Where
// o item is a 5 digit enumerator string.
// o field is one of either TYPE,TEXT,DESC,or FILE
// o data is the data associated with the field. For TYPE, data contains a string
// representation of the LINETYPE, for TEXT, it contains the actual text of the line
// for DESC, it contains a description supplied by DOSMIG95's parse rules and for FILE
// it contains the originating file (config.sys, autoexec.bat)
//
//
// Add %system32% by default
//
wsprintf (pathStatement, TEXT("PATH=%s\\system32"), g_WinDir);
pMigratePathSettings (pathStatement);
if (MemDbEnumItems(&eItems,MEMDB_CATEGORY_DM_LINES)) {
do {
//
// Get the actual line contents.
//
if (MemDbGetEndpointValueEx(
MEMDB_CATEGORY_DM_LINES,
eItems.szName,
NULL,
lineBuffer
)) {
//
// Get the value and flags from this endpoint.
//
MemDbBuildKey(key,MEMDB_CATEGORY_DM_LINES,eItems.szName,NULL,lineBuffer);
MemDbGetValueAndFlags(key, &offset, &value);
if (pNewFile(offset)) {
//
// the S_ENVVARS entry is a special case and is not an actual file. All of its entries are simply migrated
// into the registry.
//
if (!StringIMatch(g_LastFile,S_ENVVARS)) {
if (_tcsistr(g_LastFile, TEXT("autoexec.bat"))){
//
// Flush PathList to actual buffer
//
pPathListToBuffer(&buffer);
}
pSaveBufferToAnsiFile(g_LastFile,STRINGBUFFER(&buffer));
}
buffer.End = 0;
g_FileChanged = FALSE;
}
rSuccess = pProcessLine(value,&buffer,lineBuffer);
DEBUGMSG_IF((rSuccess, DBG_DOSMIG,"Line successfully processed. (%s)",lineBuffer));
if (!rSuccess) {
LOG ((LOG_ERROR,"Dosmig: Error processing line. (%s)",lineBuffer));
}
}
else {
LOG((LOG_ERROR,"Dosmig: MemDbGetEndpointValueEx failed trying to retrieve line %s",eItems.szName));
}
} while (MemDbEnumNextValue(&eItems) && rSuccess);
//
// Get the file name and save the file off.
//
if (!StringIMatch(g_CurrentFile,S_ENVVARS)) {
if (_tcsistr(g_CurrentFile, TEXT("autoexec.bat"))){
//
// Flush PathList to actual buffer
//
pPathListToBuffer(&buffer);
}
pSaveBufferToAnsiFile(g_CurrentFile,STRINGBUFFER(&buffer));
}
pCompletePathProcessing ();
FreeGrowList (&g_PathList);
}
ELSE_DEBUGMSG((DBG_DOSMIG,"No lines to migrate..."));
//
// Free our growbuffer.
//
FreeGrowBuffer(&buffer);
//
// Clean up the suppression table.
//
HtFree (g_SuppressionTable);
return rSuccess;
}
BOOL
WINAPI
DosMigNt_Entry (
IN HINSTANCE hinstDLL,
IN DWORD dwReason,
IN PVOID lpv
)
{
BOOL rSuccess = TRUE;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
g_Pool = PoolMemInitNamedPool ("DOS mig - NT side");
rSuccess = g_Pool != NULL;
// Set flag to indicate that migration information has not
// yet been processed.
g_MigrationPrepared = FALSE;
break;
case DLL_PROCESS_DETACH:
rSuccess = TRUE;
PoolMemDestroyPool(g_Pool);
break;
}
return rSuccess;
}
LONG
DosMigNt_User (
IN HKEY User
)
{
LONG rc = ERROR_SUCCESS;
if (!g_MigrationPrepared) {
if (pGeneralMigration()) {
g_MigrationPrepared = TRUE;
}
else {
LOG((LOG_ERROR,"Dosmig: General migration failed"));
}
}
if (g_MigrationPrepared) {
//
// Turn off autoexec.bat parsing.
//
rc = pTurnAutoParseOff(User);
if (g_MigrateDoskeySetting) {
rc = pTurnInsertModeOn(User);
if (rc != ERROR_SUCCESS) {
LOG ((LOG_ERROR,"Dosmig: Error attempting to turn insert mode on."));
}
}
}
return rc;
}
LONG
DosMigNt_System(
VOID
)
{
if (!g_MigrationPrepared) {
if (pGeneralMigration()) {
g_MigrationPrepared = TRUE;
}
else {
LOG((LOG_ERROR,"Dosmig: General migration failed"));
}
}
return ERROR_SUCCESS;
}