mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
706 lines
19 KiB
706 lines
19 KiB
/*
|
|
|
|
Modifications:
|
|
|
|
01.10.94 Joe Holman Added DISK_TO_START_NUMBERING_AT because
|
|
we now have 2 bootdisks, thus we to start
|
|
making floppies on disk # 3.
|
|
01.11.94 Joe Holman Change value back to 2.
|
|
04.04.94 Joe Holman Add debugging to LayoutDisks.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <windows.h>
|
|
#include <time.h>
|
|
#include "general.h"
|
|
|
|
FILE* logFile;
|
|
char* product;
|
|
int useCdPath;
|
|
|
|
BOOL bAssigned[15000]; // should put this in Entry struct after Beta.
|
|
|
|
struct _list {
|
|
|
|
char name[15]; // name of file
|
|
int size;
|
|
int csize;
|
|
int disk;
|
|
int priority;
|
|
char nocompress[15];
|
|
|
|
};
|
|
struct _list fileList[15000];
|
|
int numFiles;
|
|
int totalCompressed=0;
|
|
int totalUnCompressed=0;
|
|
|
|
void Msg ( const char * szFormat, ... ) {
|
|
|
|
va_list vaArgs;
|
|
|
|
va_start ( vaArgs, szFormat );
|
|
vprintf ( szFormat, vaArgs );
|
|
vfprintf ( logFile, szFormat, vaArgs );
|
|
va_end ( vaArgs );
|
|
}
|
|
|
|
|
|
void Header(argv)
|
|
char* argv[];
|
|
{
|
|
time_t t;
|
|
|
|
PRINT1("\n=========== LAYOUT =============\n")
|
|
PRINT2("Input BOM: %s\n",argv[2])
|
|
PRINT2("Output Layout: %s\n",argv[3])
|
|
PRINT2("Product: %s\n",argv[4])
|
|
PRINT2("Floppy Size: %s\n",argv[5])
|
|
time(&t); PRINT2("Time: %s",ctime(&t))
|
|
PRINT1("================================\n\n");
|
|
}
|
|
|
|
void Usage()
|
|
{
|
|
printf("PURPOSE: Assigns files to disks and generates a layout file.\n");
|
|
printf("\n");
|
|
printf("PARAMETERS:\n");
|
|
printf("\n");
|
|
printf("[LogFile] - Path to append a log of actions and errors.\n");
|
|
printf("[InBom] - Path of BOM for which a layout is to be made.\n");
|
|
printf("[OutLayout] - Path of new layout.\n");
|
|
printf("[Product] - Product to lay out.\n");
|
|
printf(" NTFLOP = Windows NT on floppy\n");
|
|
printf(" LMFLOP = Lan Manager on floppy\n");
|
|
printf(" NTCD = Windows NT on CD\n");
|
|
printf(" LMCD = Lan Manager on CD\n");
|
|
printf(" SDK = Software Development Kit\n");
|
|
printf("[FloppySize] - Size in bytes of the second disk.\n\n");
|
|
}
|
|
|
|
int __cdecl PrioritySizeNameCompare(const void*,const void*);
|
|
|
|
int Same(Entry * e1, Entry * e2) {
|
|
|
|
char *p1, *p2;
|
|
BOOL bSame;
|
|
|
|
if (useCdPath) {
|
|
|
|
p1=e1->cdpath;
|
|
p2=e2->cdpath;
|
|
}
|
|
else {
|
|
|
|
p1="x";
|
|
p2=p1;
|
|
}
|
|
|
|
bSame = (!_stricmp(e1->name,e2->name)) &&
|
|
(!_stricmp(e1->path,e2->path)) &&
|
|
(!_stricmp(e1->source,e2->source)) &&
|
|
(!_stricmp(p1,p2));
|
|
|
|
if ( !bSame ) {
|
|
|
|
Msg ( "\n>>>>>>>\n" );
|
|
Msg ( "e1->name = %s\n", e1->name );
|
|
Msg ( "e2->name = %s\n", e2->name );
|
|
Msg ( "e1->path = %s\n", e1->path );
|
|
Msg ( "e2->path = %s\n", e2->path );
|
|
Msg ( "e1->source = %s\n", e1->source );
|
|
Msg ( "e2->source = %s\n", e2->source );
|
|
Msg ( "p1 = %s\n", p1 );
|
|
Msg ( "p2 = %s\n", p2 );
|
|
}
|
|
|
|
return ( bSame );
|
|
}
|
|
|
|
BOOL FindFile ( char * name ) {
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < numFiles; ++i ) {
|
|
|
|
if ( _stricmp ( name, fileList[i].name ) == 0 ) {
|
|
|
|
return TRUE; // found the file in the file list
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE; // did NOT find the file in the file list.
|
|
|
|
}
|
|
|
|
void AddFileToList ( char * name,
|
|
int size,
|
|
int csize,
|
|
int disk,
|
|
int priority,
|
|
char * nocompress ) {
|
|
|
|
sprintf ( fileList[numFiles].name, "%s", name );
|
|
fileList[numFiles].size = size;
|
|
fileList[numFiles].csize = csize;
|
|
fileList[numFiles].disk = disk;
|
|
fileList[numFiles].priority = priority;
|
|
sprintf ( fileList[numFiles].nocompress, "%s", nocompress );
|
|
|
|
totalUnCompressed += fileList[numFiles].size;
|
|
totalCompressed += fileList[numFiles].csize;
|
|
|
|
Msg ( "totalUncomp = %d, size = %d,totalComp = %d, csize = %d\n", totalUnCompressed, fileList[numFiles].size, totalCompressed, fileList[numFiles].csize );
|
|
|
|
if ( fileList[numFiles].size < fileList[numFiles].csize ) {
|
|
|
|
Msg ( "ER: %s compressed bigger than uncomp\n", fileList[numFiles].name );
|
|
}
|
|
|
|
++numFiles;
|
|
|
|
|
|
}
|
|
|
|
void MakeEntries ( Entry * e, int records ) {
|
|
|
|
|
|
int i;
|
|
BOOL bInList;
|
|
|
|
int numFiles = 0;
|
|
|
|
for ( i = 0; i < records; i++ ) {
|
|
|
|
bInList = FindFile ( e[i].name );
|
|
|
|
if ( !bInList ) {
|
|
|
|
AddFileToList ( e[i].name,
|
|
e[i].size,
|
|
e[i].csize,
|
|
e[i].disk,
|
|
e[i].priority,
|
|
e[i].nocompress );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void ShowEntries ( void ) {
|
|
|
|
int i;
|
|
|
|
totalCompressed=0;
|
|
totalUnCompressed=0;
|
|
|
|
for ( i = 0; i < numFiles; ++i ) {
|
|
|
|
Msg ( "#%d\t%s,nocomp=%d,comp=%d,priority=%d,disk=%d,%s\n",
|
|
i,
|
|
fileList[i].name,
|
|
fileList[i].size,
|
|
fileList[i].csize,
|
|
fileList[i].priority,
|
|
fileList[i].disk,
|
|
fileList[i].nocompress );
|
|
|
|
totalCompressed+=fileList[i].csize;
|
|
totalUnCompressed+=fileList[i].size;
|
|
}
|
|
|
|
Msg ( "totalCompressed = %d, totalUnCompressed = %d\n\n\n",
|
|
totalCompressed, totalUnCompressed );
|
|
|
|
}
|
|
|
|
//
|
|
// Returns TRUE if a file hasn't been assigned a disk #, ie. 0.
|
|
// Returns FALSE if all have been assigned.
|
|
//
|
|
BOOL FileUnAssigned ( void ) {
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < numFiles; ++i ) {
|
|
|
|
if ( fileList[i].disk == 0 ) {
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
void StuffDiskNumIntoRecords ( void ) {
|
|
|
|
|
|
}
|
|
|
|
void LayoutAssignDisks(e,diskSize,records)
|
|
Entry* e;
|
|
int diskSize;
|
|
int records;
|
|
{
|
|
|
|
#define DISK_TO_START_NUMBERING_AT 1 // must start on disk #1 for all files.
|
|
|
|
|
|
//
|
|
//
|
|
// Do we REALLY need to use disk # assignment in BOM ?????
|
|
// With proper Priority, we shouldn't really need this...
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
int disk=DISK_TO_START_NUMBERING_AT;
|
|
int freeSpace;
|
|
int i, itemSize, totalUnassigned;
|
|
int lastUnassignedPriority;
|
|
int workingPriority;
|
|
|
|
|
|
//
|
|
// Make unique entries for each file for the product.
|
|
//
|
|
MakeEntries ( e, records );
|
|
ShowEntries ( );
|
|
|
|
|
|
// Priority values can be from 1-1000;
|
|
//
|
|
|
|
do {
|
|
|
|
// Free space left to begin with is the disk size.
|
|
//
|
|
freeSpace=diskSize - 512; // add in safety fudge factor...
|
|
|
|
Msg ( "\n\n\n\n\nInitial Disk #%d freeSpace = %d\n", disk, freeSpace );
|
|
|
|
// First, find all the files that
|
|
// are HARDCODED to go on this disk.
|
|
//
|
|
//
|
|
Msg ( "\n\n\nAnalyze HARDCODED disk #s...\n\n" );
|
|
for ( i=0; i < numFiles; i++) {
|
|
|
|
if ( fileList[i].disk == disk) {
|
|
|
|
if ( fileList[i].nocompress[1] == 'x' ||
|
|
fileList[i].nocompress[1] == 'X' ) {
|
|
|
|
freeSpace -= fileList[i].size;
|
|
|
|
Msg ( "freeSpace(nocomp) = %d, %d, %s, disk #%d, prio = %d\n",
|
|
freeSpace,
|
|
fileList[i].size,
|
|
fileList[i].name, disk, fileList[i].priority );
|
|
|
|
}
|
|
else {
|
|
|
|
freeSpace -= fileList[i].csize;
|
|
|
|
Msg ( "freeSpace(comp) = %d, %d, %s, disk #%d, prio = %d\n",
|
|
freeSpace,
|
|
fileList[i].csize, fileList[i].name, disk, fileList[i].priority );
|
|
}
|
|
}
|
|
}
|
|
|
|
// We have a big problem if our freespace is less than 0.
|
|
// I.E, too many disks have HARDCODED disk # for this disk.
|
|
//
|
|
if ( freeSpace < 0 ) {
|
|
|
|
Msg ( "FATAL ER: disk #%d freeSpace = %d\n", disk, freeSpace );
|
|
Msg ( ">>>> Too many files with HARDCODED disk #%d\n", disk);
|
|
}
|
|
|
|
#define NOT_ASSIGNED_YET 0
|
|
#define MAX_GROUPING_NUM 1000
|
|
|
|
// Now let's deal with the PRIORITY.
|
|
//
|
|
Msg ( "\n\n\nAnalyze GROUPINGS...\n\n" );
|
|
workingPriority = 1;
|
|
do {
|
|
|
|
for ( i = 0; i < numFiles; ++i ) {
|
|
|
|
int fileSize;
|
|
|
|
if ( fileList[i].disk == NOT_ASSIGNED_YET ) {
|
|
|
|
|
|
if ( fileList[i].nocompress[1] == 'x' ||
|
|
fileList[i].nocompress[1] == 'X' ) {
|
|
|
|
fileSize = fileList[i].size;
|
|
}
|
|
else {
|
|
fileSize = fileList[i].csize;
|
|
}
|
|
|
|
if ( fileList[i].priority <= workingPriority &&
|
|
|
|
freeSpace-fileSize > 0 ) {
|
|
|
|
freeSpace -= fileSize;
|
|
fileList[i].disk = disk;
|
|
|
|
Msg ( "freespace(%s) = %d, %s, disk #%d, priority = %d, csize=%d,size=%d\n",
|
|
(_stricmp(fileList[i].nocompress,"x")) ? "comp" : "nocomp",
|
|
freeSpace,
|
|
fileList[i].name, disk, workingPriority,
|
|
fileList[i].csize, fileList[i].size );
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++workingPriority;
|
|
|
|
if ( workingPriority > MAX_GROUPING_NUM ) {
|
|
|
|
break;
|
|
}
|
|
|
|
//Msg ( "workingPriority = %d, freeSpace = %d, disk = %d\n",
|
|
// workingPriority, freeSpace, disk );
|
|
|
|
} while ( freeSpace > 0 && FileUnAssigned() );
|
|
|
|
Msg ( "Disk %d Excess Space: %d\n", disk, freeSpace );
|
|
|
|
++disk;
|
|
|
|
} while ( FileUnAssigned() );
|
|
|
|
ShowEntries ( );
|
|
StuffDiskNumIntoRecords ();
|
|
|
|
exit(0);
|
|
|
|
// # of unassigned files.
|
|
//
|
|
totalUnassigned = records;
|
|
|
|
//
|
|
//
|
|
// After BETA, rewrite the following algorithms to:
|
|
//
|
|
// o not use totalUnassigned.
|
|
// o to be better written algorithm below for laying out.
|
|
//
|
|
//
|
|
// Calculate the # of unassigned files, and initiate the disk #
|
|
// for each to be layed-out from.
|
|
//
|
|
for (i=0;i<records;i++) {
|
|
|
|
// If this file has specific disk # to be on, reduce the
|
|
// # of files to be assigned by 1.
|
|
//
|
|
if(e[i].disk>0) {
|
|
totalUnassigned--;
|
|
}
|
|
|
|
// Is this code ever executed ????
|
|
//
|
|
// this stuff is bs -- if this is the cd, we should detect that earlier
|
|
// and have a simple loop for that case. All files on the cd must be
|
|
// on disk 1.
|
|
//
|
|
// if(diskSize > CD_SIZE) {
|
|
// for(i=0; i<records; i++) {
|
|
// e[i].disk = 1;
|
|
// }
|
|
// }
|
|
//
|
|
if( (e[i].disk>=DISK_TO_START_NUMBERING_AT) && (diskSize>CD_SIZE))
|
|
{
|
|
|
|
e[i].disk=DISK_TO_START_NUMBERING_AT;
|
|
bAssigned[i] = TRUE;
|
|
|
|
Msg ( "ever-executed?: %s, %d, %d\n",
|
|
e[i].source, e[i].disk, diskSize );
|
|
}
|
|
}
|
|
|
|
//
|
|
//
|
|
do {
|
|
|
|
// Free space left to begin with is the disk size.
|
|
//
|
|
freeSpace=diskSize - 512; // add in safety fudge factor...
|
|
|
|
Msg ( "freeSpace(init) = %d, %d\n", freeSpace, diskSize );
|
|
|
|
// First, find all the files that
|
|
// are HARDCODED to go on this disk.
|
|
//
|
|
//
|
|
for ( i=0; i<records; i++) {
|
|
|
|
//
|
|
// Rules: specific disk # assignment, next available i==0,
|
|
// or !Same (due to multiple entries in the bom
|
|
// for the same file, but used for different inf lines.
|
|
// >>> If we remove multiple entries in bom for same files
|
|
// this test can be removed.
|
|
//
|
|
|
|
// SAME() JUST WONT WORK IF E entries ARE NOT IN ALPHABETICALL ORDER.
|
|
// AND, that is just the CASE, some of them are not in ORDER,
|
|
// that's why we are getting some negative values for disk size.
|
|
//
|
|
|
|
if ( (e[i].disk==disk) &&
|
|
((i==0) || !Same(&e[i],&e[i-1]))) {
|
|
|
|
if (!_stricmp(e[i].nocompress,"x")) {
|
|
freeSpace-=e[i].size;
|
|
Msg ( "freeSpace(nocomp) = %d, %d, %s, disk #%d, i = %d\n",
|
|
freeSpace, e[i].size, e[i].name, disk, i );
|
|
}
|
|
else {
|
|
freeSpace-=e[i].csize;
|
|
Msg ( "freeSpace(comp) = %d, %d, %s, disk #%d, i = %d\n",
|
|
freeSpace, e[i].csize, e[i].name, disk, i );
|
|
}
|
|
}
|
|
}
|
|
|
|
// We have a big problem if our freespace is less than 0.
|
|
// I.E, too many disks have HARDCODED disk # for this disk.
|
|
//
|
|
if ( freeSpace < 0 ) {
|
|
|
|
Msg ( "FATAL ER: disk #%d freeSpace = %d\n", disk, freeSpace );
|
|
Msg ( ">>>> Too many files with HARDCODED disk #%d\n", disk);
|
|
}
|
|
|
|
// Now, fill the floppies with files working with the Highest Priority.
|
|
//
|
|
lastUnassignedPriority=1000;
|
|
|
|
for ( i=0; i<records; i++) {
|
|
|
|
//
|
|
// If the file hasn't been assigned yet, ie. 0, figure the disk
|
|
// for it to live on.
|
|
//
|
|
if (e[i].disk==0) {
|
|
|
|
//
|
|
// WHEN WE GET RID OF MULTIPLE ENTRIES IN THE BOM FOR
|
|
// THE SAME FILE, WE CAN GET RID OF THE 'SAME' FUNCTION
|
|
// BECAUSE THIS LOOKS TO SEE THAT THE LAST FILE PROCESSED
|
|
// HAD THE SAME NAME (DUE TO INF MULTIPLE INSTANCES).
|
|
//
|
|
if ((i!=0) && Same(&e[i],&e[i-1])) {
|
|
|
|
// If we aren't on the 1st e entry AND
|
|
// we have the same filename, then just
|
|
// give the same disk # as PREVIOUSLY assigned.
|
|
//
|
|
e[i].disk=e[i-1].disk;
|
|
bAssigned[i] = TRUE;
|
|
Msg ( "Assign(same-as-last) %s: %d\n",
|
|
e[i].name, e[i].disk );
|
|
}
|
|
else {
|
|
|
|
// Get the size of the file in compressed or non-comp
|
|
// format.
|
|
//
|
|
itemSize =
|
|
(!_stricmp(e[i].nocompress,"x")) ? e[i].size : e[i].csize;
|
|
|
|
|
|
// If the file can fit on the floppy,
|
|
// see if we can assign it to the disk #.
|
|
//
|
|
if ( freeSpace >= itemSize ) {
|
|
|
|
if ((e[i].priority<=lastUnassignedPriority) ||
|
|
((e[i].priority==999) && (lastUnassignedPriority>9))) {
|
|
|
|
|
|
if ( e[i].priority <= lastUnassignedPriority) {
|
|
Msg ( ">>> priority %d <= lastUnassignedPriority %d\n", e[i].priority, lastUnassignedPriority );
|
|
}
|
|
|
|
|
|
if ( (e[i].priority==999) &&
|
|
(lastUnassignedPriority>9) ) {
|
|
Msg ( ">>> priority==999 && lastUnassignedPriority %d > 9\n", lastUnassignedPriority );
|
|
}
|
|
|
|
// Assign the disk #.
|
|
//
|
|
e[i].disk=disk;
|
|
bAssigned[i] = TRUE;
|
|
Msg ( "Assign(1) %s: %d\n", e[i].name, e[i].disk );
|
|
|
|
// Free space remaining...
|
|
//
|
|
freeSpace-=itemSize;
|
|
Msg ( "freeSpace(3) = %d, %d\n", freeSpace, itemSize );
|
|
}
|
|
}
|
|
else if (lastUnassignedPriority==1000) {
|
|
|
|
// ???????
|
|
//
|
|
lastUnassignedPriority=e[i].priority;
|
|
|
|
Msg ( "?????ever get executed(2) - lastUnassignedPriority = %d\n", e[i].priority );
|
|
}
|
|
|
|
// Look for files that are TOO big to fit on media.
|
|
//
|
|
if ( itemSize >= diskSize) {
|
|
|
|
Msg ("FATAL ERROR: %s too big, %d bytes\n",
|
|
e[i].name, itemSize );
|
|
|
|
// Assign the disk #, although invalid.
|
|
//
|
|
e[i].disk=999;
|
|
bAssigned[i] = TRUE;
|
|
Msg ( "Assign %s: %d\n", e[i].name, e[i].disk );
|
|
}
|
|
}
|
|
|
|
// If the disk# is no longer 0, then file has been assigned.
|
|
//
|
|
if (e[i].disk) {
|
|
totalUnassigned--;
|
|
}
|
|
|
|
if ( freeSpace < 0 ) {
|
|
|
|
Msg ( "FATAL ER: freeSpace %d < 0\n", freeSpace );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tell the amount of space left on the disk.
|
|
//
|
|
//PRINT3("INFO Disk: %2.d Free Space: %7.d\n",disk,freeSpace)
|
|
Msg ( "Disk %d Free Space: %d\n", disk, freeSpace );
|
|
disk++;
|
|
|
|
} while (totalUnassigned>0); // continue until all files assigned.
|
|
|
|
//
|
|
// the above 'totalUnassigned' method is bad, what if the # gets
|
|
// off by some reason. better thing to do is have flag for
|
|
// each file saying bAssigned yet or not.
|
|
//
|
|
|
|
// Reduce the last disk # by 1.
|
|
//
|
|
disk--;
|
|
|
|
}
|
|
|
|
__cdecl main(argc,argv)
|
|
int argc;
|
|
char* argv[];
|
|
{
|
|
FILE *outLayout;
|
|
Entry *e;
|
|
int records,i;
|
|
char *buf;
|
|
|
|
if (argc!=6) { Usage(); return(1); }
|
|
if ((logFile=fopen(argv[1],"a"))==NULL)
|
|
{
|
|
printf("ERROR Couldn't open log file %s\n",argv[1]);
|
|
return(1);
|
|
}
|
|
Header(argv);
|
|
LoadFile(argv[2],&buf,&e,&records,argv[4]);
|
|
|
|
if (MyOpenFile(&outLayout,argv[3],"wb")) return(1);
|
|
|
|
if (!_stricmp(argv[4],"ntflop") || !_stricmp(argv[4],"lmflop")) {
|
|
useCdPath=0;
|
|
}
|
|
else {
|
|
useCdPath=1;
|
|
}
|
|
|
|
//
|
|
// munge the compress flag depending on the product type.
|
|
// if we are laying out floppies, then files are always
|
|
// compressed unless a special flag is set in the bom.
|
|
//
|
|
if(!useCdPath) {
|
|
for (i=0;i<records;i++) {
|
|
if(_strnicmp(e[i].nocompress,"xfloppy",7)) {
|
|
//
|
|
// not xfloppy; not uncompressed.
|
|
//
|
|
e[i].nocompress = "";
|
|
} else {
|
|
e[i].nocompress = "x";
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef JOE
|
|
#else
|
|
qsort(e,records,sizeof(Entry),PrioritySizeNameCompare);
|
|
|
|
LayoutAssignDisks(e,atoi(argv[5]),records);
|
|
#endif
|
|
|
|
i=0;
|
|
while ((fputc(buf[i++],outLayout))!='\n');
|
|
for (i=0;i<records;i++) {
|
|
EntryPrint(&e[i],outLayout);
|
|
}
|
|
|
|
fclose(outLayout);
|
|
fclose(logFile);
|
|
free(e);
|
|
return(0);
|
|
}
|
|
|
|
int __cdecl PrioritySizeNameCompare(const void *v1, const void *v2)
|
|
{
|
|
int result;
|
|
Entry *e1 = (Entry *)v1;
|
|
Entry *e2 = (Entry *)v2;
|
|
|
|
if (e1->priority!=e2->priority)
|
|
return(e1->priority-e2->priority);
|
|
if (e1->size!=e2->size)
|
|
return(e2->size-e1->size);
|
|
if (result=_stricmp(e1->name,e2->name))
|
|
return(result);
|
|
if (useCdPath)
|
|
return(_stricmp(e1->cdpath,e2->cdpath));
|
|
else
|
|
return(0); // always the same for floppies.
|
|
}
|