Source code of Windows XP (NT5)
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

  1. /*
  2. Modifications:
  3. 01.10.94 Joe Holman Added DISK_TO_START_NUMBERING_AT because
  4. we now have 2 bootdisks, thus we to start
  5. making floppies on disk # 3.
  6. 01.11.94 Joe Holman Change value back to 2.
  7. 04.04.94 Joe Holman Add debugging to LayoutDisks.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <windows.h>
  13. #include <time.h>
  14. #include "general.h"
  15. FILE* logFile;
  16. char* product;
  17. int useCdPath;
  18. BOOL bAssigned[15000]; // should put this in Entry struct after Beta.
  19. struct _list {
  20. char name[15]; // name of file
  21. int size;
  22. int csize;
  23. int disk;
  24. int priority;
  25. char nocompress[15];
  26. };
  27. struct _list fileList[15000];
  28. int numFiles;
  29. int totalCompressed=0;
  30. int totalUnCompressed=0;
  31. void Msg ( const char * szFormat, ... ) {
  32. va_list vaArgs;
  33. va_start ( vaArgs, szFormat );
  34. vprintf ( szFormat, vaArgs );
  35. vfprintf ( logFile, szFormat, vaArgs );
  36. va_end ( vaArgs );
  37. }
  38. void Header(argv)
  39. char* argv[];
  40. {
  41. time_t t;
  42. PRINT1("\n=========== LAYOUT =============\n")
  43. PRINT2("Input BOM: %s\n",argv[2])
  44. PRINT2("Output Layout: %s\n",argv[3])
  45. PRINT2("Product: %s\n",argv[4])
  46. PRINT2("Floppy Size: %s\n",argv[5])
  47. time(&t); PRINT2("Time: %s",ctime(&t))
  48. PRINT1("================================\n\n");
  49. }
  50. void Usage()
  51. {
  52. printf("PURPOSE: Assigns files to disks and generates a layout file.\n");
  53. printf("\n");
  54. printf("PARAMETERS:\n");
  55. printf("\n");
  56. printf("[LogFile] - Path to append a log of actions and errors.\n");
  57. printf("[InBom] - Path of BOM for which a layout is to be made.\n");
  58. printf("[OutLayout] - Path of new layout.\n");
  59. printf("[Product] - Product to lay out.\n");
  60. printf(" NTFLOP = Windows NT on floppy\n");
  61. printf(" LMFLOP = Lan Manager on floppy\n");
  62. printf(" NTCD = Windows NT on CD\n");
  63. printf(" LMCD = Lan Manager on CD\n");
  64. printf(" SDK = Software Development Kit\n");
  65. printf("[FloppySize] - Size in bytes of the second disk.\n\n");
  66. }
  67. int __cdecl PrioritySizeNameCompare(const void*,const void*);
  68. int Same(Entry * e1, Entry * e2) {
  69. char *p1, *p2;
  70. BOOL bSame;
  71. if (useCdPath) {
  72. p1=e1->cdpath;
  73. p2=e2->cdpath;
  74. }
  75. else {
  76. p1="x";
  77. p2=p1;
  78. }
  79. bSame = (!_stricmp(e1->name,e2->name)) &&
  80. (!_stricmp(e1->path,e2->path)) &&
  81. (!_stricmp(e1->source,e2->source)) &&
  82. (!_stricmp(p1,p2));
  83. if ( !bSame ) {
  84. Msg ( "\n>>>>>>>\n" );
  85. Msg ( "e1->name = %s\n", e1->name );
  86. Msg ( "e2->name = %s\n", e2->name );
  87. Msg ( "e1->path = %s\n", e1->path );
  88. Msg ( "e2->path = %s\n", e2->path );
  89. Msg ( "e1->source = %s\n", e1->source );
  90. Msg ( "e2->source = %s\n", e2->source );
  91. Msg ( "p1 = %s\n", p1 );
  92. Msg ( "p2 = %s\n", p2 );
  93. }
  94. return ( bSame );
  95. }
  96. BOOL FindFile ( char * name ) {
  97. int i;
  98. for ( i = 0; i < numFiles; ++i ) {
  99. if ( _stricmp ( name, fileList[i].name ) == 0 ) {
  100. return TRUE; // found the file in the file list
  101. }
  102. }
  103. return FALSE; // did NOT find the file in the file list.
  104. }
  105. void AddFileToList ( char * name,
  106. int size,
  107. int csize,
  108. int disk,
  109. int priority,
  110. char * nocompress ) {
  111. sprintf ( fileList[numFiles].name, "%s", name );
  112. fileList[numFiles].size = size;
  113. fileList[numFiles].csize = csize;
  114. fileList[numFiles].disk = disk;
  115. fileList[numFiles].priority = priority;
  116. sprintf ( fileList[numFiles].nocompress, "%s", nocompress );
  117. totalUnCompressed += fileList[numFiles].size;
  118. totalCompressed += fileList[numFiles].csize;
  119. Msg ( "totalUncomp = %d, size = %d,totalComp = %d, csize = %d\n", totalUnCompressed, fileList[numFiles].size, totalCompressed, fileList[numFiles].csize );
  120. if ( fileList[numFiles].size < fileList[numFiles].csize ) {
  121. Msg ( "ER: %s compressed bigger than uncomp\n", fileList[numFiles].name );
  122. }
  123. ++numFiles;
  124. }
  125. void MakeEntries ( Entry * e, int records ) {
  126. int i;
  127. BOOL bInList;
  128. int numFiles = 0;
  129. for ( i = 0; i < records; i++ ) {
  130. bInList = FindFile ( e[i].name );
  131. if ( !bInList ) {
  132. AddFileToList ( e[i].name,
  133. e[i].size,
  134. e[i].csize,
  135. e[i].disk,
  136. e[i].priority,
  137. e[i].nocompress );
  138. }
  139. }
  140. }
  141. void ShowEntries ( void ) {
  142. int i;
  143. totalCompressed=0;
  144. totalUnCompressed=0;
  145. for ( i = 0; i < numFiles; ++i ) {
  146. Msg ( "#%d\t%s,nocomp=%d,comp=%d,priority=%d,disk=%d,%s\n",
  147. i,
  148. fileList[i].name,
  149. fileList[i].size,
  150. fileList[i].csize,
  151. fileList[i].priority,
  152. fileList[i].disk,
  153. fileList[i].nocompress );
  154. totalCompressed+=fileList[i].csize;
  155. totalUnCompressed+=fileList[i].size;
  156. }
  157. Msg ( "totalCompressed = %d, totalUnCompressed = %d\n\n\n",
  158. totalCompressed, totalUnCompressed );
  159. }
  160. //
  161. // Returns TRUE if a file hasn't been assigned a disk #, ie. 0.
  162. // Returns FALSE if all have been assigned.
  163. //
  164. BOOL FileUnAssigned ( void ) {
  165. int i;
  166. for ( i = 0; i < numFiles; ++i ) {
  167. if ( fileList[i].disk == 0 ) {
  168. return TRUE;
  169. }
  170. }
  171. return FALSE;
  172. }
  173. void StuffDiskNumIntoRecords ( void ) {
  174. }
  175. void LayoutAssignDisks(e,diskSize,records)
  176. Entry* e;
  177. int diskSize;
  178. int records;
  179. {
  180. #define DISK_TO_START_NUMBERING_AT 1 // must start on disk #1 for all files.
  181. //
  182. //
  183. // Do we REALLY need to use disk # assignment in BOM ?????
  184. // With proper Priority, we shouldn't really need this...
  185. //
  186. //
  187. //
  188. //
  189. int disk=DISK_TO_START_NUMBERING_AT;
  190. int freeSpace;
  191. int i, itemSize, totalUnassigned;
  192. int lastUnassignedPriority;
  193. int workingPriority;
  194. //
  195. // Make unique entries for each file for the product.
  196. //
  197. MakeEntries ( e, records );
  198. ShowEntries ( );
  199. // Priority values can be from 1-1000;
  200. //
  201. do {
  202. // Free space left to begin with is the disk size.
  203. //
  204. freeSpace=diskSize - 512; // add in safety fudge factor...
  205. Msg ( "\n\n\n\n\nInitial Disk #%d freeSpace = %d\n", disk, freeSpace );
  206. // First, find all the files that
  207. // are HARDCODED to go on this disk.
  208. //
  209. //
  210. Msg ( "\n\n\nAnalyze HARDCODED disk #s...\n\n" );
  211. for ( i=0; i < numFiles; i++) {
  212. if ( fileList[i].disk == disk) {
  213. if ( fileList[i].nocompress[1] == 'x' ||
  214. fileList[i].nocompress[1] == 'X' ) {
  215. freeSpace -= fileList[i].size;
  216. Msg ( "freeSpace(nocomp) = %d, %d, %s, disk #%d, prio = %d\n",
  217. freeSpace,
  218. fileList[i].size,
  219. fileList[i].name, disk, fileList[i].priority );
  220. }
  221. else {
  222. freeSpace -= fileList[i].csize;
  223. Msg ( "freeSpace(comp) = %d, %d, %s, disk #%d, prio = %d\n",
  224. freeSpace,
  225. fileList[i].csize, fileList[i].name, disk, fileList[i].priority );
  226. }
  227. }
  228. }
  229. // We have a big problem if our freespace is less than 0.
  230. // I.E, too many disks have HARDCODED disk # for this disk.
  231. //
  232. if ( freeSpace < 0 ) {
  233. Msg ( "FATAL ER: disk #%d freeSpace = %d\n", disk, freeSpace );
  234. Msg ( ">>>> Too many files with HARDCODED disk #%d\n", disk);
  235. }
  236. #define NOT_ASSIGNED_YET 0
  237. #define MAX_GROUPING_NUM 1000
  238. // Now let's deal with the PRIORITY.
  239. //
  240. Msg ( "\n\n\nAnalyze GROUPINGS...\n\n" );
  241. workingPriority = 1;
  242. do {
  243. for ( i = 0; i < numFiles; ++i ) {
  244. int fileSize;
  245. if ( fileList[i].disk == NOT_ASSIGNED_YET ) {
  246. if ( fileList[i].nocompress[1] == 'x' ||
  247. fileList[i].nocompress[1] == 'X' ) {
  248. fileSize = fileList[i].size;
  249. }
  250. else {
  251. fileSize = fileList[i].csize;
  252. }
  253. if ( fileList[i].priority <= workingPriority &&
  254. freeSpace-fileSize > 0 ) {
  255. freeSpace -= fileSize;
  256. fileList[i].disk = disk;
  257. Msg ( "freespace(%s) = %d, %s, disk #%d, priority = %d, csize=%d,size=%d\n",
  258. (_stricmp(fileList[i].nocompress,"x")) ? "comp" : "nocomp",
  259. freeSpace,
  260. fileList[i].name, disk, workingPriority,
  261. fileList[i].csize, fileList[i].size );
  262. }
  263. }
  264. }
  265. ++workingPriority;
  266. if ( workingPriority > MAX_GROUPING_NUM ) {
  267. break;
  268. }
  269. //Msg ( "workingPriority = %d, freeSpace = %d, disk = %d\n",
  270. // workingPriority, freeSpace, disk );
  271. } while ( freeSpace > 0 && FileUnAssigned() );
  272. Msg ( "Disk %d Excess Space: %d\n", disk, freeSpace );
  273. ++disk;
  274. } while ( FileUnAssigned() );
  275. ShowEntries ( );
  276. StuffDiskNumIntoRecords ();
  277. exit(0);
  278. // # of unassigned files.
  279. //
  280. totalUnassigned = records;
  281. //
  282. //
  283. // After BETA, rewrite the following algorithms to:
  284. //
  285. // o not use totalUnassigned.
  286. // o to be better written algorithm below for laying out.
  287. //
  288. //
  289. // Calculate the # of unassigned files, and initiate the disk #
  290. // for each to be layed-out from.
  291. //
  292. for (i=0;i<records;i++) {
  293. // If this file has specific disk # to be on, reduce the
  294. // # of files to be assigned by 1.
  295. //
  296. if(e[i].disk>0) {
  297. totalUnassigned--;
  298. }
  299. // Is this code ever executed ????
  300. //
  301. // this stuff is bs -- if this is the cd, we should detect that earlier
  302. // and have a simple loop for that case. All files on the cd must be
  303. // on disk 1.
  304. //
  305. // if(diskSize > CD_SIZE) {
  306. // for(i=0; i<records; i++) {
  307. // e[i].disk = 1;
  308. // }
  309. // }
  310. //
  311. if( (e[i].disk>=DISK_TO_START_NUMBERING_AT) && (diskSize>CD_SIZE))
  312. {
  313. e[i].disk=DISK_TO_START_NUMBERING_AT;
  314. bAssigned[i] = TRUE;
  315. Msg ( "ever-executed?: %s, %d, %d\n",
  316. e[i].source, e[i].disk, diskSize );
  317. }
  318. }
  319. //
  320. //
  321. do {
  322. // Free space left to begin with is the disk size.
  323. //
  324. freeSpace=diskSize - 512; // add in safety fudge factor...
  325. Msg ( "freeSpace(init) = %d, %d\n", freeSpace, diskSize );
  326. // First, find all the files that
  327. // are HARDCODED to go on this disk.
  328. //
  329. //
  330. for ( i=0; i<records; i++) {
  331. //
  332. // Rules: specific disk # assignment, next available i==0,
  333. // or !Same (due to multiple entries in the bom
  334. // for the same file, but used for different inf lines.
  335. // >>> If we remove multiple entries in bom for same files
  336. // this test can be removed.
  337. //
  338. // SAME() JUST WONT WORK IF E entries ARE NOT IN ALPHABETICALL ORDER.
  339. // AND, that is just the CASE, some of them are not in ORDER,
  340. // that's why we are getting some negative values for disk size.
  341. //
  342. if ( (e[i].disk==disk) &&
  343. ((i==0) || !Same(&e[i],&e[i-1]))) {
  344. if (!_stricmp(e[i].nocompress,"x")) {
  345. freeSpace-=e[i].size;
  346. Msg ( "freeSpace(nocomp) = %d, %d, %s, disk #%d, i = %d\n",
  347. freeSpace, e[i].size, e[i].name, disk, i );
  348. }
  349. else {
  350. freeSpace-=e[i].csize;
  351. Msg ( "freeSpace(comp) = %d, %d, %s, disk #%d, i = %d\n",
  352. freeSpace, e[i].csize, e[i].name, disk, i );
  353. }
  354. }
  355. }
  356. // We have a big problem if our freespace is less than 0.
  357. // I.E, too many disks have HARDCODED disk # for this disk.
  358. //
  359. if ( freeSpace < 0 ) {
  360. Msg ( "FATAL ER: disk #%d freeSpace = %d\n", disk, freeSpace );
  361. Msg ( ">>>> Too many files with HARDCODED disk #%d\n", disk);
  362. }
  363. // Now, fill the floppies with files working with the Highest Priority.
  364. //
  365. lastUnassignedPriority=1000;
  366. for ( i=0; i<records; i++) {
  367. //
  368. // If the file hasn't been assigned yet, ie. 0, figure the disk
  369. // for it to live on.
  370. //
  371. if (e[i].disk==0) {
  372. //
  373. // WHEN WE GET RID OF MULTIPLE ENTRIES IN THE BOM FOR
  374. // THE SAME FILE, WE CAN GET RID OF THE 'SAME' FUNCTION
  375. // BECAUSE THIS LOOKS TO SEE THAT THE LAST FILE PROCESSED
  376. // HAD THE SAME NAME (DUE TO INF MULTIPLE INSTANCES).
  377. //
  378. if ((i!=0) && Same(&e[i],&e[i-1])) {
  379. // If we aren't on the 1st e entry AND
  380. // we have the same filename, then just
  381. // give the same disk # as PREVIOUSLY assigned.
  382. //
  383. e[i].disk=e[i-1].disk;
  384. bAssigned[i] = TRUE;
  385. Msg ( "Assign(same-as-last) %s: %d\n",
  386. e[i].name, e[i].disk );
  387. }
  388. else {
  389. // Get the size of the file in compressed or non-comp
  390. // format.
  391. //
  392. itemSize =
  393. (!_stricmp(e[i].nocompress,"x")) ? e[i].size : e[i].csize;
  394. // If the file can fit on the floppy,
  395. // see if we can assign it to the disk #.
  396. //
  397. if ( freeSpace >= itemSize ) {
  398. if ((e[i].priority<=lastUnassignedPriority) ||
  399. ((e[i].priority==999) && (lastUnassignedPriority>9))) {
  400. if ( e[i].priority <= lastUnassignedPriority) {
  401. Msg ( ">>> priority %d <= lastUnassignedPriority %d\n", e[i].priority, lastUnassignedPriority );
  402. }
  403. if ( (e[i].priority==999) &&
  404. (lastUnassignedPriority>9) ) {
  405. Msg ( ">>> priority==999 && lastUnassignedPriority %d > 9\n", lastUnassignedPriority );
  406. }
  407. // Assign the disk #.
  408. //
  409. e[i].disk=disk;
  410. bAssigned[i] = TRUE;
  411. Msg ( "Assign(1) %s: %d\n", e[i].name, e[i].disk );
  412. // Free space remaining...
  413. //
  414. freeSpace-=itemSize;
  415. Msg ( "freeSpace(3) = %d, %d\n", freeSpace, itemSize );
  416. }
  417. }
  418. else if (lastUnassignedPriority==1000) {
  419. // ???????
  420. //
  421. lastUnassignedPriority=e[i].priority;
  422. Msg ( "?????ever get executed(2) - lastUnassignedPriority = %d\n", e[i].priority );
  423. }
  424. // Look for files that are TOO big to fit on media.
  425. //
  426. if ( itemSize >= diskSize) {
  427. Msg ("FATAL ERROR: %s too big, %d bytes\n",
  428. e[i].name, itemSize );
  429. // Assign the disk #, although invalid.
  430. //
  431. e[i].disk=999;
  432. bAssigned[i] = TRUE;
  433. Msg ( "Assign %s: %d\n", e[i].name, e[i].disk );
  434. }
  435. }
  436. // If the disk# is no longer 0, then file has been assigned.
  437. //
  438. if (e[i].disk) {
  439. totalUnassigned--;
  440. }
  441. if ( freeSpace < 0 ) {
  442. Msg ( "FATAL ER: freeSpace %d < 0\n", freeSpace );
  443. }
  444. }
  445. }
  446. // Tell the amount of space left on the disk.
  447. //
  448. //PRINT3("INFO Disk: %2.d Free Space: %7.d\n",disk,freeSpace)
  449. Msg ( "Disk %d Free Space: %d\n", disk, freeSpace );
  450. disk++;
  451. } while (totalUnassigned>0); // continue until all files assigned.
  452. //
  453. // the above 'totalUnassigned' method is bad, what if the # gets
  454. // off by some reason. better thing to do is have flag for
  455. // each file saying bAssigned yet or not.
  456. //
  457. // Reduce the last disk # by 1.
  458. //
  459. disk--;
  460. }
  461. __cdecl main(argc,argv)
  462. int argc;
  463. char* argv[];
  464. {
  465. FILE *outLayout;
  466. Entry *e;
  467. int records,i;
  468. char *buf;
  469. if (argc!=6) { Usage(); return(1); }
  470. if ((logFile=fopen(argv[1],"a"))==NULL)
  471. {
  472. printf("ERROR Couldn't open log file %s\n",argv[1]);
  473. return(1);
  474. }
  475. Header(argv);
  476. LoadFile(argv[2],&buf,&e,&records,argv[4]);
  477. if (MyOpenFile(&outLayout,argv[3],"wb")) return(1);
  478. if (!_stricmp(argv[4],"ntflop") || !_stricmp(argv[4],"lmflop")) {
  479. useCdPath=0;
  480. }
  481. else {
  482. useCdPath=1;
  483. }
  484. //
  485. // munge the compress flag depending on the product type.
  486. // if we are laying out floppies, then files are always
  487. // compressed unless a special flag is set in the bom.
  488. //
  489. if(!useCdPath) {
  490. for (i=0;i<records;i++) {
  491. if(_strnicmp(e[i].nocompress,"xfloppy",7)) {
  492. //
  493. // not xfloppy; not uncompressed.
  494. //
  495. e[i].nocompress = "";
  496. } else {
  497. e[i].nocompress = "x";
  498. }
  499. }
  500. }
  501. #ifdef JOE
  502. #else
  503. qsort(e,records,sizeof(Entry),PrioritySizeNameCompare);
  504. LayoutAssignDisks(e,atoi(argv[5]),records);
  505. #endif
  506. i=0;
  507. while ((fputc(buf[i++],outLayout))!='\n');
  508. for (i=0;i<records;i++) {
  509. EntryPrint(&e[i],outLayout);
  510. }
  511. fclose(outLayout);
  512. fclose(logFile);
  513. free(e);
  514. return(0);
  515. }
  516. int __cdecl PrioritySizeNameCompare(const void *v1, const void *v2)
  517. {
  518. int result;
  519. Entry *e1 = (Entry *)v1;
  520. Entry *e2 = (Entry *)v2;
  521. if (e1->priority!=e2->priority)
  522. return(e1->priority-e2->priority);
  523. if (e1->size!=e2->size)
  524. return(e2->size-e1->size);
  525. if (result=_stricmp(e1->name,e2->name))
  526. return(result);
  527. if (useCdPath)
  528. return(_stricmp(e1->cdpath,e2->cdpath));
  529. else
  530. return(0); // always the same for floppies.
  531. }