/*++ 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 = // 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\\\ // // 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; }