/* * 10.23.97 Joe Holman Make our 3 boot disks for a product. * This program needs to do the following: * * 1. calculate if the boot files value * is adequate * 2. create a list of files that can be used * to make the boot floppies. * * 11.02.98 Joe Holman Modified per new key names. * 11.19.98 Elliott Munger Made changes to suport 4 bootdisks */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include int __cdecl main( int, char ** ); FILE * logFile; HANDLE hDosnetInf; CHAR returnBuffer[MAX_PATH]; CHAR returnBuffer2[MAX_PATH]; CHAR szWrite[MAX_PATH]; CHAR szFloppyDump[MAX_PATH]; CHAR szLog[MAX_PATH]; CHAR szReleaseShare[MAX_PATH]; DWORD dwRequiredSize; CHAR szDosnetPath[MAX_PATH]; CHAR szLayoutPath[MAX_PATH]; CHAR szRenamedFile[MAX_PATH]; CHAR szBootSector[MAX_PATH]; BOOL bHasRenamedFile = FALSE; BOOL bMakeNECBoot = FALSE; // // Macro for rounding up any number (x) to multiple of (n) which // must be a power of 2. For example, ROUNDUP( 2047, 512 ) would // yield result of 2048. // #define ROUNDUP2( x, n ) (((x) + ((n) - 1 )) & ~((n) - 1 )) #define _hK 512 #define _1K 1*1024 #define _2K 2*1024 #define _4K 4*1024 #define _8K 8*1024 #define _16K 16*1024 #define _32K 32*1024 #define _64K 64*1024 #define _128K 128*1024 #define _256K 256*1024 // System parition values per cluster size for // files that go in the ~BT directory. // DWORD dw_hK = 0; DWORD dw_1K = 0; DWORD dw_2K = 0; DWORD dw_4K = 0; DWORD dw_8K = 0; DWORD dw_16K = 0; DWORD dw_32K = 0; DWORD dw_64K = 0; DWORD dw_128K = 0; DWORD dw_256K = 0; void Msg ( const char * szFormat, ... ) { va_list vaArgs; va_start ( vaArgs, szFormat ); vprintf ( szFormat, vaArgs ); vfprintf ( logFile, szFormat, vaArgs ); va_end ( vaArgs ); } void Usage( void ) { printf ( "Usage: boot logFile dosnet.inf-path output-file-for-dmf flat-uncompressed-share path-for-floppy-files x86orNECbootdisk" ); exit (1); } void Header(argv) char* argv[]; { time_t t; Msg ("\n=========== BOOT.EXE =============\n"); Msg ("LogFile : %s\n",argv[1]); Msg ("DosNet.INF path : %s\n",argv[2]); Msg ("Output file path : %s\n",argv[3]); Msg ("Flat uncompressed share: %s\n", argv[4] ); Msg ("Path to put floppy files:%s\n", argv[5] ); Msg ("X86 or NEC Boot sector : %s\n", argv[6] ); time(&t); Msg ("Time : %s",ctime(&t)); Msg ("================================\n\n"); } void WriteToFile ( char * fileName, char flopNum ) { FILE * fHandle; CHAR Line[MAX_PATH]; CHAR szPath[MAX_PATH]; sprintf ( szPath, "%s\\b%c.txt", szFloppyDump, flopNum ); fHandle = fopen ( szPath, "a" ); if ( fHandle == NULL ) { Msg ( "ERROR Couldn't open file with fopen: %s\n", szPath ); } else { // This denotes that it is the first floppy, // which needs to have the boot sector put on it. // if ( strstr ( fileName, "disk1" ) && flopNum == '0' ) { if ( bMakeNECBoot ) { strcpy ( Line, "-bnt35nec98setup\n" ); } else { strcpy ( Line, "-bnt35setup\n" ); } fwrite ( Line, 1, strlen(Line), fHandle ); Msg ( "\nWritingToFile: %s\n%s\n\n", szPath, Line ); } if ( bHasRenamedFile ) { sprintf ( Line, "%s=%s\n", fileName, returnBuffer2 ); } else { sprintf ( Line, "%s\n" , fileName ); } fwrite ( Line, 1, strlen(Line), fHandle ); Msg ( "\nWritingToFile: %s\n%s\n\n", szPath, Line ); fclose ( fHandle ); } } VOID MakeCompName ( const char * inFile, char * outFile ) { unsigned i; unsigned period; strcpy( outFile, inFile ); for ( period=(unsigned)(-1), i = 0 ; i < strlen(inFile); i++ ) { if ( inFile[i] == '.' ) { period = i; } } if ( period == (strlen(inFile)-4) ) { outFile[strlen(outFile)-1] = '_'; } else if ( period == (unsigned)(-1)) { strcat ( outFile, "._"); } else { strcat ( outFile, "_"); } } void ChangeFileNameToCompressNameIfNeeded ( char * fileName ) { HANDLE hLayoutInf; // See if the file is going to come over as compressed or not. // If so, change it's name so we can process it. // // Special case for files not stored in the INF. // if ( strstr ( fileName, "disk1" ) || strstr ( fileName, "setupldr.bin" ) || strstr ( fileName, "usetup.exe" ) ) { goto no_processing; } // Open layout.inf to find out if the file is to be compressed or not. // hLayoutInf = SetupOpenInfFile ( szLayoutPath, NULL, INF_STYLE_WIN4, NULL ); if ( hLayoutInf == INVALID_HANDLE_VALUE ) { Msg ( "ERROR: ChangeFileNameToCompressNameIfNeeded could not open INF: %s\n", szLayoutPath ); } else { BOOL b; DWORD requiredSize; INFCONTEXT ic; CHAR returnBuffer[MAX_PATH]; b = SetupFindFirstLine ( hLayoutInf, (LPSTR) "SourceDisksFiles", (LPSTR) fileName, &ic ); if ( !b ) { // If we get an error, perhaps the file is in the .x86 section. // b = SetupFindFirstLine (hLayoutInf, (LPSTR) "SourceDisksFiles.x86", (LPSTR) fileName, &ic ); if ( !b ) { Msg ( "ERROR: CopyTheFile SetupFindFirstLine couldn't find file in section: gle = %x, >>>%s<<<\n", GetLastError(), fileName ); } else { goto continue_here; } } else { continue_here:; // Look at the 7th field. // b = SetupGetStringField ( &ic, 7, (LPSTR) returnBuffer, sizeof ( returnBuffer ), &dwRequiredSize ); if ( !b ) { Msg ( "ERROR: CopyTheFile SetupGetStringField gle = %ld\n", GetLastError()); } else { char * p; Msg ( "++++ returnBuffer = %s\n", returnBuffer ); // Get to the character that determines if we compress or not. // p = returnBuffer; if ( *p != '_' ) { CHAR commandBuffer[MAX_PATH]; CHAR szTmp[MAX_PATH]; // Since we are going to be using a compressed filename, // turn the uncompressed filename into a compressed filename. // MakeCompName ( fileName, szTmp ); strcpy ( fileName, szTmp ); Msg ( "using compressed filename, so now it is: %s\n", fileName ); } else { Msg ( "leaving filename alone, still: %s\n", fileName ); } } } SetupCloseInfFile ( hLayoutInf ); } no_processing:; } void AddInSize ( char * fileName ) { CHAR szPath[MAX_PATH]; HANDLE h; WIN32_FIND_DATA wfd; sprintf ( szPath, "%s\\%s", szReleaseShare, fileName ); Msg ( "\n+++ AddInSize for: %s +++\n", szPath ); h = FindFirstFile ( szPath, &wfd ); if ( h == INVALID_HANDLE_VALUE ) { Msg ( "ERROR: FindFirstFile on %s, gle = %ld\n", szPath, GetLastError() ); } else { dw_hK += ROUNDUP2 ( wfd.nFileSizeLow, 512 ); dw_1K += ROUNDUP2 ( wfd.nFileSizeLow, _1K ); dw_2K += ROUNDUP2 ( wfd.nFileSizeLow, _2K ); dw_4K += ROUNDUP2 ( wfd.nFileSizeLow, _4K ); dw_8K += ROUNDUP2 ( wfd.nFileSizeLow, _8K ); dw_16K += ROUNDUP2 ( wfd.nFileSizeLow, _16K ); dw_32K += ROUNDUP2 ( wfd.nFileSizeLow, _32K ); dw_64K += ROUNDUP2 ( wfd.nFileSizeLow, _64K ); dw_128K += ROUNDUP2 ( wfd.nFileSizeLow, _128K ); dw_256K += ROUNDUP2 ( wfd.nFileSizeLow, _256K ); /* Msg ( "dw_hK = %ld\n", dw_hK ); Msg ( "dw_1K = %ld\n", dw_1K ); Msg ( "dw_2K = %ld\n", dw_2K ); Msg ( "dw_4K = %ld\n", dw_4K ); Msg ( "dw_8K = %ld\n", dw_8K ); Msg ( "dw_16K = %ld\n", dw_16K ); Msg ( "dw_32K = %ld\n", dw_32K ); Msg ( "dw_64K = %ld\n", dw_64K ); Msg ( "dw_128K = %ld\n", dw_128K ); Msg ( "dw_256K = %ld\n", dw_256K ); */ FindClose ( h ); } } void CopyTheFile ( CHAR * fileName, CHAR flopNum ) { CHAR szPath1[MAX_PATH]; CHAR szPath2[MAX_PATH]; BOOL b; Msg ( "CopyTheFile: %s\n", fileName ); // Copy the file. // sprintf ( szPath1, "%s\\%s", szReleaseShare, fileName ); sprintf ( szPath2, "%s\\%s", szFloppyDump, fileName ); b = CopyFile ( szPath1, szPath2, FALSE ); if ( !b ) { Msg ( "ERROR: CopyFile failed, gle = %ld, >>>%s<<< >>>%s<<<\n", GetLastError(), szPath1, szPath2 ); } else { Msg ( "CopyFile: %s %s [ok]\n", szPath1, szPath2 ); SetFileAttributes ( szPath2, FILE_ATTRIBUTE_NORMAL ); } // Write the name of the file to B?.txt file in the specified directory. // WriteToFile ( fileName, flopNum ); } void GetFloppy ( char Floppy ) { BOOL b; INFCONTEXT ic; char szSection[MAX_PATH]; sprintf ( szSection, "%s%c", "FloppyFiles.", Floppy ); Msg ( "\nGetting for section: %s\n\n", szSection ); // Get the first line in the section, ie FloppyFiles.N. // Note: Be sure to look for files that maybe renamed: // // d1,disk1,disk101 // disk1=disk101 for the output file. // b = SetupFindFirstLine ( hDosnetInf, szSection, NULL, &ic ); if ( !b ) { Msg ( "ERROR: SetupFindFirstLine not found in %s\n", szSection ); } else { // Get the 2nd field's filename, such as in d1,disk1,disk101 // would be disk1. // b = SetupGetStringField ( &ic, 2, (LPSTR) &returnBuffer, sizeof ( returnBuffer ), &dwRequiredSize ); if ( !b ) { Msg ( "ERROR: SetupGetStringField gle = %ld\n", GetLastError()); } // See if we need to compress this file and // add in the size for the ~bt directory. // ChangeFileNameToCompressNameIfNeeded ( returnBuffer ); AddInSize ( returnBuffer ); // Get the 3rd field's filename, such as in d1,disk1,disk101 // would be disk101. // This is the case where we need to stick disk1=disk101 for // the output file for disk imaging. // // Note: we don't check for errors here because 3rd field // because this renamed file is optional. // b = SetupGetStringField ( &ic, 3, (LPSTR) &returnBuffer2, sizeof ( returnBuffer2 ), &dwRequiredSize ); // Note - not checking for errors here. // if ( b ) { bHasRenamedFile = TRUE; } else { bHasRenamedFile = FALSE; } // Copy the file to the specified directory. // CopyTheFile ( returnBuffer, Floppy ); while ( 1 ) { // Get the next line in the section. // b = SetupFindNextLine ( &ic, &ic ); if ( !b ) { // Denotes that there is NOT another line. // Msg ( "\n" ); break; } else { // Get the 2nd field's filename, // such as in d1,disk1,disk101 // would be disk1. // b = SetupGetStringField ( &ic, 2, (LPSTR) &returnBuffer, sizeof ( returnBuffer ), &dwRequiredSize ); if ( !b ) { Msg ( "ERROR: SetupGetStringField gle = %ld\n", GetLastError()); break; } //Msg ( "returnBuffer = %s\n", returnBuffer ); ChangeFileNameToCompressNameIfNeeded ( returnBuffer ); AddInSize ( returnBuffer ); // Get the 3rd field's filename, such as in // d1,disk1,disk101 // would be disk101. // This is the case where we need to stick // disk1=disk101 for // the output file for disk imaging. // // Note: we don't check for errors here because 3rd field // because this renamed file is optional. // b = SetupGetStringField ( &ic, 3, (LPSTR) &returnBuffer2, sizeof ( returnBuffer2 ), &dwRequiredSize ); // Note - not checking for errors here. // if ( b ) { bHasRenamedFile = TRUE; } else { bHasRenamedFile = FALSE; } // Copy the file to the specified directory. // CopyTheFile ( returnBuffer, Floppy ); } } } } DWORD Get2ndSize ( char * key ) { CHAR returnedString[MAX_PATH]; #define OHPROBLEM "OH OH" DWORD dwSize = 666; char * p; GetPrivateProfileString ( "DiskSpaceRequirements", key, OHPROBLEM, returnedString, MAX_PATH, szDosnetPath ); if ( strncmp ( returnedString, OHPROBLEM, sizeof ( OHPROBLEM ) ) == 0 ) { Msg ( "ERROR: section >>>%s<<< not found.\n", key ); } //Msg ( ">>> %s\n", returnedString ); // Find the ',' which denotes the ~BT data. // p = strstr ( returnedString, "," ); if ( !p ) { Msg ( "ERROR: returnedString has no ',' in it: %s\n", returnedString ); dwSize = 0; } else { ++p; // point to the number, not the ',' dwSize = atoi ( p ); //Msg ( ">+BT dwSize = %ld, p = %s\n", dwSize, p ); } return (dwSize); } DWORD GetBT ( DWORD ClusterSize ) { switch ( ClusterSize ) { case _hK : return Get2ndSize ( "TempDirSpace512" ); break; case _1K : return Get2ndSize ( "TempDirSpace1K" ); break; case _2K : return Get2ndSize ( "TempDirSpace2K" ); break; case _4K : return Get2ndSize ( "TempDirSpace4K" ); break; case _8K : return Get2ndSize ( "TempDirSpace8K" ); break; case _16K : return Get2ndSize ( "TempDirSpace16K" ); break; case _32K : return Get2ndSize ( "TempDirSpace32K" ); break; case _64K : return Get2ndSize ( "TempDirSpace64K" ); break; case _128K : return Get2ndSize ( "TempDirSpace128K" ); break; case _256K : return Get2ndSize ( "TempDirSpace256K" ); break; default : Msg ( "ERROR: ClusterSize not known: %ld\n", ClusterSize ); break; } return 0; } void VerifyTotalSizeIsAdaquate ( void ) { // Make sure that the total size we need is specified in dosnet.inf. // Msg ( "\n\nVerifyTotalSizeIsAdaquate...\n" ); // Dosnet.inf's [SpaceRequirements] cluster fields should look like: // // 512 = xxxxxx, yyyyyy where x is for the ~LS files and // where y is for the ~BT files. // #define FUDGE 1*1024*1024 // to make sure we have enough for dir entries in FAT. if ( dw_hK > GetBT ( _hK ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 512 ~BT too small, %ld, use: %ld\n", GetBT ( _hK ), dw_hK+FUDGE ); } if ( dw_1K > GetBT ( _1K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 1K ~BT too small, %ld, use: %ld\n", GetBT ( _1K ), dw_1K+FUDGE ); } if ( dw_2K > GetBT ( _2K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 2K ~BT too small, %ld, use: %ld\n", GetBT ( _2K ), dw_2K+FUDGE ); } if ( dw_4K > GetBT ( _4K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 4K ~BT too small, %ld, use: %ld\n", GetBT ( _4K ), dw_4K+FUDGE ); } if ( dw_8K > GetBT ( _8K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 8K ~BT too small, %ld, use: %ld\n", GetBT ( _8K ), dw_8K+FUDGE ); } if ( dw_16K > GetBT ( _16K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 16K ~BT too small, %ld, use: %ld\n", GetBT ( _16K ), dw_16K+FUDGE ); } if ( dw_32K > GetBT ( _32K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 32K ~BT too small, %ld, use: %ld\n", GetBT ( _32K ), dw_32K+FUDGE ); } if ( dw_64K > GetBT ( _64K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 64K ~BT too small, %ld, use: %ld\n", GetBT ( _64K ), dw_64K+FUDGE ); } if ( dw_128K > GetBT ( _128K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 128K ~BT too small, %ld, use: %ld\n", GetBT ( _128K ), dw_128K+FUDGE ); } if ( dw_256K > GetBT ( _256K ) ) { Msg ( "matth ERROR: Dosnet.inf's [DiskSpaceRequirements]'s 256K ~BT too small, %ld, use: %ld\n", GetBT ( _256K ), dw_256K+FUDGE ); } } void MyDeleteFile ( char Num ) { BOOL b; CHAR szPath[MAX_PATH]; sprintf ( szPath, "%s\\b%c.txt", szFloppyDump, Num ); Msg ( "Deleting: %s\n", szPath ); b = DeleteFile ( szPath ); if ( !b ) { if ( GetLastError() != ERROR_FILE_NOT_FOUND ) { Msg ( "ERROR: DeleteFile, gle = %ld, %s\n", GetLastError(), szPath ); } } } __cdecl main ( int argc, char * argv[] ) { if ( argc != 7) { Usage(); exit(1); } if ((logFile=fopen(argv[1],"a"))==NULL) { printf("ERROR Couldn't open logFile: %s\n",argv[1]); return(1); } Header(argv); Msg ( "%s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6] ); // Copy paths into appropriate string variables. // strcpy ( szLog, argv[1] ); Msg ( "szLog = %s\n", szLog ); strcpy ( szDosnetPath, argv[2] ); Msg ( "szDosnetPath = %s\n", szDosnetPath ); strcpy ( szReleaseShare, argv[4] ); Msg ( "szReleaseShare = %s\n", szReleaseShare ); sprintf ( szLayoutPath, "%s\\%s", argv[4], "layout.inf" ); Msg ( "szLayoutPath = %s\n", szLayoutPath ); strcpy ( szFloppyDump, argv[5] ); Msg ( "szFloppyDump = %s\n", szFloppyDump ); strcpy ( szBootSector, argv[6] ); Msg ( "szBootSector = %s\n", szBootSector ); if ( strstr ( szBootSector, "NEC" ) ) { bMakeNECBoot = TRUE; Msg ( "Making this boot floppy #1 NEC98 bootable...\n" ); } // // hDosnetInf = SetupOpenInfFile ( szDosnetPath, NULL, INF_STYLE_WIN4, NULL ); if ( hDosnetInf == INVALID_HANDLE_VALUE ) { Msg ( "ERROR: boot.exe - could not open INF: %s\n", szDosnetPath ); } else { CHAR szPath[MAX_PATH]; BOOL b; // Delete the files that hold the file list. // MyDeleteFile ( '0' ); MyDeleteFile ( '1' ); MyDeleteFile ( '2' ); MyDeleteFile ( '3' ); GetFloppy ( '0' ); GetFloppy ( '1' ); GetFloppy ( '2' ); GetFloppy ( '3' ); SetupCloseInfFile ( hDosnetInf ); VerifyTotalSizeIsAdaquate (); } }