#include "precomp.h" #pragma hdrstop /*++ Copyright (c) 1990 Microsoft Corporation Module Name: vdm.c Abstract: Routines to handle VDM config files Detect Routines: ---------------- 1. GetDosPathVar: This finds out the value of the DOS Path variable 2. GetWindowsPath: THis finds out the directory where windows in installed on the current system 3. GetInstalledOSNames: Finds out all the OSs installed on current system. Install Routines Workers: ------------------------- 1. VdmFixupWorker: This forms the NT VDM configuration files from DOS configuration files and NT VDM template config files. 2. MigrateWinIniWorker: This migrates windows ini configuration from win.ini files. BUGBUG**REMOVED General Subroutines: -------------------- 1. FFileExist: Whether a file exists or not. 2. FileSize: The size of a file. Author: Sunil Pai (sunilp) Mar 31, 1992 --*/ #define WIN_COM "WIN.COM" #define INI ".INI" #define TMP ".TMP" #define CONFIG_SYS "C:\\CONFIG.SYS" #define BATCH_BAT "C:\\AUTOEXEC.BAT" #define CONFIG_NT "\\CONFIG.NT" #define BATCH_NT "\\AUTOEXEC.NT" #define CONFIG_TMP "\\CONFIG.TMP" #define BATCH_TMP "\\AUTOEXEC.TMP" #define IO_SYS "C:\\IO.SYS" #define MSDOS_SYS "C:\\MSDOS.SYS" #define IBMBIO_COM "C:\\IBMBIO.COM" #define IBMDOS_COM "C:\\IBMDOS.COM" #define OS2LDR "C:\\OS2LDR" #define STARTUPCMD "C:\\STARTUP.CMD" #define DOS "DOS" #define OS2 "OS2" // // Local prototypes // BOOL FilterDosConfigFile(LPSTR szSrc, LPSTR szDst, LPSTR szTemplate); BOOL DosConfigFilter(IN OUT TEXTFILE *SrcText, IN OUT FILE *f, OUT RGSZ *rgszFound); DWORD FileSize(SZ szFile); BOOL AppendSzToFile( SZ szFileName, SZ szAddOnSz ); SZ SzGetDosPathVar(DWORD MaxLength); BOOL GetPathVarFromLine( SZ, SZ, DWORD ); BOOL CheckDosConfigModified( IN LPSTR szConfig); #if 0 BOOL FilterDosBatchFile(LPSTR szSrc, LPSTR szDst, LPSTR szTemplate); BOOL DosBatchFilter( TEXTFILE*, FILE* ); BOOL FixConfigFileMacroChar(SZ szConfigFile, CHAR cReplaceChar, SZ szSystemDir); BOOL FFindAndCopyIniFiles( SZ szSrcDir, SZ szDstDir ); BOOL FMigrateStandardIniData( SZ szWindowsDir ); BOOL FMigrateWinIniAppSections( SZ szWindowsDir ); SZ SzMapStandardIni( SZ szIniFile ); VOID CleanupIniFiles( SZ szWindowsDir ); BOOL FIsStandardWinIniSection( SZ szSection ); #endif // *************************************************************************** // // DOS VDM FIXUP MAIN ROUTINE // // *************************************************************************** BOOL VdmFixupWorker( LPSTR szAddOnConfig, LPSTR szAddOnBatch ) { CHAR szConfigVDM[MAX_PATH], szBatchVDM[MAX_PATH]; CHAR szConfigTmp[MAX_PATH], szBatchTmp[MAX_PATH]; SZ szConfigDOS, szBatchDOS; CHAR szSystemDir[ MAX_PATH ]; DWORD dwDosConfigAttr = FILE_ATTRIBUTE_NORMAL; DWORD dwDosBatchAttr = FILE_ATTRIBUTE_NORMAL; DWORD dw; BOOL bStatus = TRUE; // // A. Determine names to use: no renaming any more. Config.sys and // autoexec.bat on root of C drive are the files to use for DOS, // config.nt and autoexec.nt in the system directory are the files // to use for nt. the template config.nt and autoexec.nt are // still copied into the root of the C drive for reference. // GetSystemDirectory( szSystemDir, MAX_PATH ); szConfigDOS = CONFIG_SYS; szBatchDOS = BATCH_BAT; lstrcpy( szConfigVDM, szSystemDir ); lstrcat( szConfigVDM, CONFIG_NT ); lstrcpy( szBatchVDM, szSystemDir ); lstrcat( szBatchVDM, BATCH_NT ); lstrcpy( szConfigTmp, szSystemDir ); lstrcat( szConfigTmp, CONFIG_TMP ); lstrcpy( szBatchTmp, szSystemDir ); lstrcat( szBatchTmp, BATCH_TMP ); // // Verify that the template files exist, else // if ( !(FFileExist( szConfigTmp ) && FFileExist( szBatchTmp )) ) { SetErrorText(IDS_ERROR_OPENFAIL); return( fFalse ); } else { SetFileAttributes ( szConfigTmp, FILE_ATTRIBUTE_NORMAL ); SetFileAttributes ( szBatchTmp, FILE_ATTRIBUTE_NORMAL ); } // // Fix the attributes of the DOS CONFIG FILES so that we can look at // them henceforth // if ( FFileExist(szConfigDOS) ) { if ( (dw = GetFileAttributes( szConfigDOS )) != 0xFFFFFFFF) { dwDosConfigAttr = dw; } SetFileAttributes( szConfigDOS, FILE_ATTRIBUTE_NORMAL ); } if ( FFileExist(szBatchDOS) ) { if ( (dw = GetFileAttributes( szBatchDOS )) != 0xFFFFFFFF) { dwDosBatchAttr = dw; } SetFileAttributes( szBatchDOS, FILE_ATTRIBUTE_NORMAL ); } // // Delete the existing config files for the vdm - no upgrade supported // at this moment. // if ( FFileExist( szConfigVDM ) ) { SetFileAttributes ( szConfigVDM, FILE_ATTRIBUTE_NORMAL ); DeleteFile( szConfigVDM ); } if ( FFileExist( szBatchVDM ) ) { SetFileAttributes ( szBatchVDM, FILE_ATTRIBUTE_NORMAL ); DeleteFile( szBatchVDM ); } // // Check if configuration information exists, else just rename // the default temporary configuration files to the final names. // if ((!FFileExist(szConfigDOS)) || (!CheckConfigTypeWorker(szConfigDOS)) ) { if( !( MoveFile( szConfigTmp, szConfigVDM ) && MoveFile( szBatchTmp, szBatchVDM ))) { SetErrorText(IDS_ERROR_WRITE); bStatus = fFalse; goto cleanup; } } else { if( !FilterDosConfigFile(szConfigDOS, szConfigVDM, szConfigTmp) ) { bStatus = fFalse; goto cleanup; } // // Nothing is being migrated from the DOS batch file, so we // can just rename the temporary file to the permanent one // if( !MoveFile( szBatchTmp, szBatchVDM ) ) { SetErrorText(IDS_ERROR_WRITE); bStatus = fFalse; goto cleanup; } } // // Append the NT Signature blocks onto the existing config files. If // files don't exist then create them // if(!CheckDosConfigModified(szConfigDOS) ) { if( !AppendSzToFile( szConfigDOS, szAddOnConfig ) ) { // // Silently fail if unable to append the signature. // Failure will occur if c: is not formatted. // // bStatus = fFalse; goto cleanup; } } if(!CheckDosConfigModified(szBatchDOS) ) { if( !AppendSzToFile( szBatchDOS, szAddOnBatch ) ) { // // Silently fail if unable to append the signature. // Failure will occur if c: is not formatted. // // bStatus = fFalse; goto cleanup; } } cleanup: // // If autoexec.nt and config.nt files not found, try creating them from // the tmp files if possible // if( !FFileExist( szConfigVDM ) ) { MoveFile( szConfigTmp, szConfigVDM ); } if( !FFileExist( szBatchVDM ) ) { MoveFile( szBatchTmp, szBatchVDM ); } // // Remove the temporary config files if they exist. // DeleteFile( szConfigTmp ); DeleteFile( szBatchTmp ); // // reset the attributs on the DOS config files, if they exist // if ( FFileExist( szConfigDOS ) ) { SetFileAttributes( szConfigDOS, dwDosConfigAttr ); } if ( FFileExist( szBatchDOS ) ) { SetFileAttributes( szBatchDOS, dwDosBatchAttr ); } #if 0 // // If the NT config files have been created, set the attributes of these // to system and readonly // if( FFileExist( szConfigVDM ) ) { SetFileAttributes( szConfigVDM, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY ); } if( FFileExist( szBatchVDM ) ) { SetFileAttributes( szBatchVDM, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY ); } #endif return( bStatus ); } // *************************************************************************** // // DOS CONFIG.SYS ROUTINES // // *************************************************************************** // // copy a DOS config file REMing out any line that is not a // SET or a PATH command // // szSrc: Source batch file (DOS c:\autoexec.bat ) // szDst: Destination batch file (NT VDM c:\autoexec.nt ) BOOL FilterDosConfigFile( LPSTR szSrc, LPSTR szDst, LPSTR szTemplate ) { TEXTFILE SrcText, TemplateText; FILE* f; size_t Idx; RGSZ rgszFound = NULL; BOOL bStatus = TRUE; SZ sz, szLine; CHAR Buffer[ MAX_PATH ]; // // If destination already exists get rid of it // if (FFileExist( szDst )) { bStatus = SetFileAttributes ( szDst, FILE_ATTRIBUTE_NORMAL ); if (bStatus) { bStatus = DeleteFile( szDst ); } } if (!bStatus) { SetErrorText(IDS_ERROR_WRITE); return (fFalse); } // // Open destination file for writing. // if ( !(f = fopen( szDst, "w" )) ) { SetErrorText(IDS_ERROR_WRITE); return( FALSE ); } // // Open source file and filter it // if ( FFileExist( szSrc ) && TextFileOpen( szSrc, &SrcText ) ) { bStatus = DosConfigFilter( &SrcText, f, &rgszFound ); TextFileClose( &SrcText ); } if( !bStatus ) { goto err; } // // Now add on the default config file from the template file // if ( !TextFileOpen( szTemplate, &TemplateText ) ) { bStatus = fFalse; SetErrorText(IDS_ERROR_OPENFAIL); goto err; } while ( TextFileReadLine( &TemplateText ) ) { BOOL fFound = FALSE; szLine = TextFileGetLine( &TemplateText ); sz = TextFileSkipBlanks( szLine ); // // If blank line, ignore // if ( sz && *sz != '\0' && rgszFound ) { Idx = strcspn( sz, " \t=" ); if ( Idx <= strlen(sz) ) { PSZ psz; memcpy( Buffer, sz, Idx ); Buffer[Idx] = '\0'; // // If one of the entries we have found from a dos config file // set fFound to true so that we don't copy this file // psz = rgszFound; while ( *psz ) { if ( !lstrcmpi( Buffer, *psz ) ) { fFound = fTrue; break; } psz++; } } } if( !fFound ) { fprintf( f, "%s\n", szLine ); } } TextFileClose( &TemplateText ); bStatus = fTrue; err: fclose( f ); if( rgszFound ) { RgszFree( rgszFound ); } return(bStatus); } BOOL DosConfigFilter( IN OUT TEXTFILE * SrcText, IN OUT FILE* f, OUT RGSZ* rgszFound ) { SZ szLine; SZ sz; CHAR Buffer[ MAX_PATH ]; size_t Idx; int i; RGSZ rgsz; #define NUM_RESPECTED_ENTRIES 4 CHAR *ConfEntry[NUM_RESPECTED_ENTRIES] = { "BREAK", "FCBS", "FILES", "LASTDRIVE" }; BOOL ConfEntryFound[NUM_RESPECTED_ENTRIES] = { FALSE,FALSE,FALSE,FALSE }; if( !(rgsz = RgszAlloc(1)) ) { SetErrorText(IDS_ERROR_DLLOOM); return( FALSE ); } while ( TextFileReadLine( SrcText ) ) { szLine = TextFileGetLine( SrcText ); sz = TextFileSkipBlanks( szLine ); // // If blank line, ignore // if ( !sz || *sz == '\0' ) { continue; } Idx = strcspn( sz, " \t=" ); if ( Idx <= strlen(sz) ) { memcpy( Buffer, sz, Idx ); Buffer[Idx] = '\0'; // // If one of the entries we respect, copy the line out verbatim // for (i = 0; i MAX_PATH ) { continue; } memcpy( szSection, sz, dwSize ); *(szSection + dwSize) = '\0'; // // If section name one of standard set ignore // if( FIsStandardWinIniSection( szSection ) ) { continue; } // // Read the entire section corresponding to the section // from the source file and transfer it to the destination // file using profile api // if( GetPrivateProfileSection( szSection, (LPSTR)Buffer, MAX_SECTION_BUFFER, szConfig ) ) { if (!WriteProfileSection( szSection, Buffer ) ) { // BUGBUG Do we quit here?? KdPrint(("SETUPDLL: Failed to migrate ini section.")); } } } } SFree( Buffer ); TextFileClose(&SrcText); } return ( TRUE ); } SZ SzMapStandardIni( SZ szIniFile ) { INT i; for ( i = 0; i < nIniList; i++ ) { if( !lstrcmpi(szIniFile, IniList[i].szIniFileName ) ) { return( IniList[i].szIniTmpFileName ); } } return( NULL ); } VOID CleanupIniFiles( SZ szWindowsDir ) { CHAR szFile[ MAX_PATH ]; INT i; for ( i = 0; i < nIniList; i++ ) { if ( lstrcmpi( IniList[i].szIniTmpFileName, "" ) ) { lstrcpy( szFile, szWindowsDir ); lstrcat( szFile, IniList[i].szIniTmpFileName ); if( FFileExist( szFile ) ) { SetFileAttributes ( szFile, FILE_ATTRIBUTE_NORMAL ); DeleteFile( szFile ); } } } return; } BOOL FIsStandardWinIniSection( SZ szSection ) { PSZ psz; psz = WinIniStandardSections; while ( *psz ) { if( !lstrcmpi( *psz++, szSection ) ) { return ( TRUE ); } } return( FALSE ); } #endif