|
|
/*
* 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 <stdlib.h>
#include <direct.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <conio.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <process.h>
#include <ctype.h>
#include <windows.h>
#include <time.h>
#include <setupapi.h>
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 (); }
}
|