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.

3190 lines
94 KiB

  1. //
  2. // 06.05.95 Joe Holman Created to copy the system files for
  3. // the new shell and cairo releases.
  4. // Currently, it only copies uncompressed system files.
  5. // 06.16.95 Joe Holman Allow debugging tools to be copied. Uses _media.inx
  6. // 06.19.95 Joe Holman Copy compressed version of file if specified in _layout.inx.
  7. // 06.22.95 Joe Holman Added bCairoSuckNameHack to pick up files from
  8. // the inf\cairo\_layout.cai file.
  9. // 06.22.95 Joe Holman Added the SRV_INF fix so that we will pick up the compressed
  10. // Server Infs in a different location than the Workstation compressed
  11. // 06.22.95 Joe Holman For now, we won't use compressed Cairo files. Will change in July.
  12. // INFs (due to the collision of names and difference with cdrom.w|s).
  13. // 06.28.95 Joe Holman Won't make CHECKED Server.
  14. // 07.07.95 Joe Holman For Cairo, we need to also look at the _layout.cai and
  15. // _media.cai files
  16. // for additional files (superset) that goes into Cairo.
  17. // 08.03.95 Joe Holman Allow Cairo to have compressed files -> note, build team needs to
  18. // private 2 locations, one for Shell release and one for Cairo release,
  19. // ie, \\x86fre\cdcomp$.
  20. // 08.14.95 Joe Holman Figure out if we copy the .dbg file for a particular file.
  21. // 08.14.95 Joe Holman Allow DBG files for Cairo.
  22. // 08.23.95 Joe Holman Add code to make tallying work with compressed/noncomp files and
  23. // winn32 local source space needed.
  24. // 10.13.95 Joe Holman Get MAPISVC.INF and MDM*.INF from Workstation location.
  25. // 10.25.95 Joe Holman Put code in to use SetupDecompressOrCopyFile.
  26. // 10.30.95 Joe Holman Don't give errors for vmmreg32.dbg - this is a file given
  27. // by Win95 guys.
  28. // 11.02.95 Joe Holman Allow multi-threaded support when SetupDecompressOrCopyFile
  29. // is fixed.
  30. // Pickup all for PPC on Cairo.
  31. // 11.17.95 Joe Holman Check for upgrade size.
  32. // 11.30.95 Joe Holman compare current dosnet.inf and txtsetup.sif values and error
  33. // if we go over. Search for //code here.
  34. // 12.04.95 Joe Holman Use Layout.inx instead of _layout.inx.
  35. // 03.11.96 Joe Holman Don't give errors on MFC*.dbg if missing, since no .dbgs
  36. // provided.
  37. // 04.05.96 Joe Holman Add values for INETSRV and DRVLIB.NIC directories. Both of
  38. // these get copied as local source. Inetsrv is NEVER installed
  39. // automatically (unless via an unattend file) and one card is
  40. // small. Thus, we will only add INETSRV and DRVLIB.NIC sizes
  41. // to local source code below.
  42. // and one or two of drvlib.nic MAY get installed.
  43. // 04.19.96 Joe Holman Add code to NOT count *.ppd files in order to reduce
  44. // minimum disk space required.
  45. // 09.10.96 Joe Holman Add code that supports setup's new disk space calculation.
  46. // Basically, we just need to provide values for each cluster
  47. // size stored in dosnet.inf.
  48. // 10.17.96 Joe Holman Comment out MIPS code, but leave in for P7.
  49. // 12.06.96 Joe Holman Backported MSKK's DBCS changes.
  50. // 01.20.97 Joe Holman Take out PPC.
  51. // 05.15.97 Joe Holman Grovels layout.inf on release shares rather than file chked-in.
  52. // xx.xx.xx Joe Holman Allow files not to worry about .dbgs for to be in a file.
  53. // 08.01.97 Joe Holman Add code to check for 0 file size in layout.inf files.
  54. // 08.26.97 Joe Holman Add code to pick-up files for NEC PC-98 machine for JA.
  55. // 10.16.97 Joe Holman Added space calculation for .PNF files made
  56. // during gui-mode setup.
  57. // 11.07.97 Joe Holman Add code to verify that a filename is 8.3.
  58. // 01.26.98 Joe Holman Since we are going to ship Enterprise Edition
  59. // in addition to Workstation and Server,
  60. // generalize the code to call files.exe 3 times
  61. // in the script for each type of product.
  62. // 07.06.98 Joe Holman Change default cluster size to 32, instead of 16.
  63. // 11.02.98 Joe Holman Use new keys for local source and fresh install
  64. // space requirements.
  65. // 11.05.98 Joe Holman Added check to look for 0 byte length files
  66. // after copy.
  67. // 12.04.98 Joe Holman Added code for 4th floppy.
  68. // 02.26.99 Joe Holman Add code that turns dbg file copying off/on.
  69. // 03.15.99 Joe Holman Check that files in the drvindex.inf are not also in
  70. // dosnet.inf, except for files on the bootfloppies.
  71. // 05.13.99 Joe Holman Change dbg/pdb copying to use INF provided on release
  72. // shares.
  73. // 08.20.99 Joe Holman Remove Alpha.
  74. // xx.xx.xx Joe Holman Provide switch that flush bits to disk after copy, then does a DIFF.
  75. //
  76. // Need to get space for:
  77. // - inside cab and zip files ++ 20M
  78. // - lang directory [ or maybe not, if we aren't going to install another lang] ++ 90M
  79. // - uniproc directory ++ 2M
  80. // - win9xmig ++2M
  81. // - win9xupg ++3M
  82. // - winntupg ++2M
  83. //
  84. //
  85. #include <windows.h>
  86. #include <setupapi.h>
  87. #include <stdio.h>
  88. #include <time.h>
  89. #include <stdlib.h>
  90. #include <ctype.h>
  91. #define MFL 256
  92. CRITICAL_SECTION CriticalSection;
  93. #define MAX_NUMBER_OF_FILES_IN_PRODUCT 14500 // # greater than # of files in product.
  94. #define EIGHT_DOT_THREE 8+1+3+1
  95. struct _tag {
  96. WORD wNumFiles;
  97. BOOL bCopyComp [MAX_NUMBER_OF_FILES_IN_PRODUCT];
  98. char wcFilesArray[MAX_NUMBER_OF_FILES_IN_PRODUCT][EIGHT_DOT_THREE];
  99. char wcSubPath [MAX_NUMBER_OF_FILES_IN_PRODUCT][EIGHT_DOT_THREE]; // used for debugging files
  100. BOOL bCountBytes [MAX_NUMBER_OF_FILES_IN_PRODUCT];
  101. BOOL bTextMode [MAX_NUMBER_OF_FILES_IN_PRODUCT];
  102. BOOL bCopyItToCD [MAX_NUMBER_OF_FILES_IN_PRODUCT];
  103. };
  104. BOOL bNec98 = FALSE;
  105. BOOL bNec98LikeX86 = FALSE;
  106. BOOL bChecked = FALSE;
  107. BOOL bVerifyBits = FALSE;
  108. BOOL bGetSizeLater = TRUE;
  109. struct _tag ix386;
  110. struct _tag Nec98;
  111. DWORD x86From351 = 0;
  112. DWORD x86From400 = 0;
  113. DWORD x86From500 = 0;
  114. BOOL hack;
  115. BOOL fX86, fNec98;
  116. BOOL bCopyCompX86 = FALSE; // flag to tell if file shall be copied in its compressed format.
  117. BOOL bCopyCompNec98 = FALSE;
  118. //
  119. // Following are masks that correspond to the particular data in a DOS date
  120. //
  121. #define DOS_DATE_MASK_DAY (WORD) 0x001f // low 5 bits (1-31)
  122. #define DOS_DATE_MASK_MONTH (WORD) 0x01e0 // mid 4 bits (1-12)
  123. #define DOS_DATE_MASK_YEAR (WORD) 0xfe00 // high 7 bits (0-119)
  124. //
  125. // Following are masks that correspond to the particular data in a DOS time
  126. //
  127. #define DOS_TIME_MASK_SECONDS (WORD) 0x001f // low 5 bits (0-29)
  128. #define DOS_TIME_MASK_MINUTES (WORD) 0x07e0 // mid 6 bits (0-59)
  129. #define DOS_TIME_MASK_HOURS (WORD) 0xf800 // high 5 bits (0-23)
  130. //
  131. // Shift constants used for building/getting DOS dates and times
  132. //
  133. #define DOS_DATE_SHIFT_DAY 0
  134. #define DOS_DATE_SHIFT_MONTH 5
  135. #define DOS_DATE_SHIFT_YEAR 9
  136. #define DOS_TIME_SHIFT_SECONDS 0
  137. #define DOS_TIME_SHIFT_MINUTES 5
  138. #define DOS_TIME_SHIFT_HOURS 11
  139. //
  140. // Macros to extract the data out of DOS dates and times.
  141. //
  142. // Note: Dos years are offsets from 1980. Dos seconds have 2 second
  143. // granularity
  144. //
  145. #define GET_DOS_DATE_YEAR(wDate) ( ( (wDate & DOS_DATE_MASK_YEAR) >> \
  146. DOS_DATE_SHIFT_YEAR ) + \
  147. (WORD) 1980 )
  148. #define GET_DOS_DATE_MONTH(wDate) ( (wDate & DOS_DATE_MASK_MONTH) >> \
  149. DOS_DATE_SHIFT_MONTH )
  150. #define GET_DOS_DATE_DAY(wDate) ( wDate & DOS_DATE_MASK_DAY )
  151. #define GET_DOS_TIME_HOURS(wTime) ( (wTime & DOS_TIME_MASK_HOURS) >> \
  152. DOS_TIME_SHIFT_HOURS )
  153. #define GET_DOS_TIME_MINUTES(wTime) ( (wTime & DOS_TIME_MASK_MINUTES) >> \
  154. DOS_TIME_SHIFT_MINUTES )
  155. #define GET_DOS_TIME_SECONDS(wTime) ( (wTime & DOS_TIME_MASK_SECONDS) << 1 )
  156. // Paths loaded in from the command line.
  157. //
  158. char szLogFile[MFL];
  159. char szProductName[MFL];
  160. char szX86Src[MFL];
  161. char szEnlistDrv[MFL];
  162. char szX86DstDrv[MFL];
  163. char szUnCompX86[MFL];
  164. char szUnCompNec98[MFL];
  165. char szNec98Src[MFL];
  166. #define I386_DIR "\\i386\\SYSTEM32"
  167. #define NEC98_DIR "\\NEC98\\SYSTEM32"
  168. #define NETMON "\\netmon"
  169. #define I386_DIR_RAW "\\i386"
  170. #define NEC98_DIR_RAW "\\NEC98"
  171. #define idBase 0
  172. #define idX86 1
  173. HANDLE hInfDosnet = NULL;
  174. HANDLE hInfLayout = NULL;
  175. HANDLE hInfDrvIndex = NULL;
  176. #define NUM_EXTS 14
  177. char * cExtra[] = { "acm", "ax", "cfm", "com", "cpl", "dll", "drv", "ds", "exe", "io", "ocx", "scr", "sys", "tsp" };
  178. // Tally up the # of bytes required for the system from the files included.
  179. //
  180. struct _ClusterSizes {
  181. DWORD Kh1;
  182. DWORD K1;
  183. DWORD K2;
  184. DWORD K4;
  185. DWORD K8;
  186. DWORD K16;
  187. DWORD K32;
  188. DWORD K64;
  189. DWORD K128;
  190. DWORD K256;
  191. };
  192. // Cluster sizes for local source, ie. the ~ls directory.
  193. //
  194. struct _ClusterSizes lX86;
  195. struct _ClusterSizes lNec98;
  196. // Cluster sizes for fresh install space.
  197. //
  198. struct _ClusterSizes freshX86;
  199. struct _ClusterSizes freshNec98;
  200. // Cluster sizes for textmode savings.
  201. //
  202. struct _ClusterSizes tX86;
  203. struct _ClusterSizes tNec98;
  204. //DWORD bytesX86;
  205. //DWORD bytesNec98;
  206. //
  207. // Macro for rounding up any number (x) to multiple of (n) which
  208. // must be a power of 2. For example, ROUNDUP( 2047, 512 ) would
  209. // yield result of 2048.
  210. //
  211. #define ROUNDUP2( x, n ) (((x) + ((n) - 1 )) & ~((n) - 1 ))
  212. FILE* logFile;
  213. void GiveThreadId ( const CHAR * szFormat, ... ) {
  214. va_list vaArgs;
  215. va_start ( vaArgs, szFormat );
  216. vprintf ( szFormat, vaArgs );
  217. vfprintf ( logFile, szFormat, vaArgs );
  218. va_end ( vaArgs );
  219. }
  220. void Msg ( const CHAR * szFormat, ... ) {
  221. va_list vaArgs;
  222. EnterCriticalSection ( &CriticalSection );
  223. GiveThreadId ( "%s %ld: ", szProductName, GetCurrentThreadId () );
  224. va_start ( vaArgs, szFormat );
  225. vprintf ( szFormat, vaArgs );
  226. vfprintf ( logFile, szFormat, vaArgs );
  227. va_end ( vaArgs );
  228. LeaveCriticalSection ( &CriticalSection );
  229. }
  230. void Header(argv,argc)
  231. char * argv[];
  232. int argc;
  233. {
  234. time_t t;
  235. char tmpTime[100];
  236. CHAR wtmpTime[200];
  237. Msg ( "\n=========== FILES ====================\n" );
  238. Msg ( "Log file : %s\n", szLogFile );
  239. Msg ( "Product Name : %s\n", szProductName );
  240. Msg ( "enlisted drive : %s\n", szEnlistDrv );
  241. Msg ( "x86 files : %s\n", szX86Src);
  242. Msg ( "drive to put x86 : %s\n", szX86DstDrv );
  243. Msg ( "uncompressed x86 files : %s\n", szUnCompX86 );
  244. if ( bNec98 ) {
  245. Msg ( "nec98 files : %s\n", szNec98Src);
  246. Msg ( "uncompressed nec98 files : %s\n", szUnCompNec98 );
  247. }
  248. time(&t);
  249. Msg ( "Time: %s", ctime(&t) );
  250. Msg ( "========================================\n\n");
  251. }
  252. void Usage( void ) {
  253. printf( "PURPOSE: Copies the system files that compose the product.\n");
  254. printf( "\n");
  255. printf( "PARAMETERS:\n");
  256. printf( "\n");
  257. printf( "[LogFile] - Path to append a log of actions and errors.\n");
  258. printf( "[ProductName] - product name\n" );
  259. printf( "[enlisted drive]- drive that is enlisted\n" );
  260. printf( "[files share] - location of x86 files.\n" );
  261. printf( "[dest path x86] - drive to put files\n" );
  262. printf( "[uncompressed x86] - drive to put files\n" );
  263. if ( bNec98 ) {
  264. printf( "[files share]- location of nec98 files\n" );
  265. printf( "[uncomp nec98]- location to get sizes from\n" );
  266. }
  267. printf( "\n" );
  268. }
  269. char dbgStr1[30];
  270. char dbgStr2[30];
  271. BOOL IsFileInSpecialWinnt32Directory ( char * szFileName ) {
  272. char szUpCasedName[MFL];
  273. int i;
  274. char * foo[] = {
  275. "WINNT32.EXE",
  276. "WINNT32A.DLL",
  277. "WINNT32U.DLL",
  278. "WINNT32.HLP",
  279. (char *) 0
  280. };
  281. strcpy ( szUpCasedName, szFileName );
  282. _strupr ( szUpCasedName );
  283. for ( i=0; foo[i] != 0; i++ ) {
  284. //Msg ( "Comparing: %s vs. %s\n", szUpCasedName, foo[i] );
  285. if ( strstr ( szUpCasedName, foo[i] ) ) {
  286. return TRUE; // file should be in this directory
  287. }
  288. }
  289. return FALSE; // no, file doesn't go in the winnt32 directory
  290. }
  291. void ShowMeDosDateTime ( CHAR * srcPath, WORD wDateSrc, WORD wTimeSrc,
  292. CHAR * dstPath, WORD wDateDst, WORD wTimeDst ) {
  293. Msg ( "%s %02d.%02d.%02d %02d:%02d.%02d\n",
  294. srcPath,
  295. GET_DOS_DATE_MONTH(wDateSrc),
  296. GET_DOS_DATE_DAY(wDateSrc),
  297. GET_DOS_DATE_YEAR(wDateSrc),
  298. GET_DOS_TIME_HOURS(wTimeSrc),
  299. GET_DOS_TIME_MINUTES(wTimeSrc),
  300. GET_DOS_TIME_SECONDS(wTimeSrc) );
  301. Msg ( "%s %02d.%02d.%02d %02d:%02d.%02d\n",
  302. dstPath,
  303. GET_DOS_DATE_MONTH(wDateDst),
  304. GET_DOS_DATE_DAY(wDateDst),
  305. GET_DOS_DATE_YEAR(wDateDst),
  306. GET_DOS_TIME_HOURS(wTimeDst),
  307. GET_DOS_TIME_MINUTES(wTimeDst),
  308. GET_DOS_TIME_SECONDS(wTimeSrc) );
  309. }
  310. void Replay ( char * srcBuf, char * dstBuf, DWORD srcBytesRead, DWORD startIndex ) {
  311. DWORD i;
  312. for ( i = startIndex; (i < startIndex+5) && (i <= srcBytesRead); ++i ) {
  313. Msg ( "srcBuf[%ld] = %x, dstBuf[%ld] = %x\n", i, srcBuf[i], i, dstBuf[i] );
  314. }
  315. }
  316. BOOL IsDstCompressed ( char * szPath ) {
  317. // Msg ( ">>> char %s: %c\n", szPath, szPath[strlen(szPath)-1] );
  318. if ( szPath[strlen(szPath)-1] == '_' ) {
  319. return(TRUE);
  320. }
  321. return (FALSE);
  322. }
  323. #define V_I386 "C:\\testi386"
  324. #define V_NEC98 "C:\\testnec98"
  325. BOOL MyCopyFile ( char * fileSrcPath, char * fileDstPath ) {
  326. HANDLE hSrc, hDst;
  327. WIN32_FIND_DATA wfdSrc, wfdDst;
  328. BOOL bDoCopy = FALSE;
  329. #define NUM_BYTES_TO_READ 2048
  330. unsigned char srcBuf[NUM_BYTES_TO_READ];
  331. unsigned char dstBuf[NUM_BYTES_TO_READ];
  332. WORD srcDate, srcTime, dstDate, dstTime;
  333. DWORD dwAttributes;
  334. char szTmpFile[MFL] = { '\0' };
  335. UINT uiRetSize = 299;
  336. char szJustFileName[MFL];
  337. char szJustDirectoryName[MFL];
  338. BOOL b;
  339. // Find the source file.
  340. //
  341. hSrc = FindFirstFile ( fileSrcPath, &wfdSrc );
  342. if ( hSrc == INVALID_HANDLE_VALUE ) {
  343. // HACK: Since the release shares put WINNT32.EXE in the WINNT32 directory
  344. // instead of leaving it in the flat root, verify that if the fileSrcPath
  345. // contains WINNT32.EXE we look in the WINNT32 dir also before error'ing out.
  346. //
  347. if ( IsFileInSpecialWinnt32Directory ( fileSrcPath ) ) {
  348. char tmpSrcPath[MFL];
  349. strcpy ( tmpSrcPath, fileSrcPath );
  350. if ( strstr ( fileSrcPath, ".HLP" ) ||
  351. strstr ( fileSrcPath, ".hlp" ) ) {
  352. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 4 ], "\\WINNT32.HLP" );
  353. }
  354. else if ( strstr ( fileSrcPath, ".MSI" ) ||
  355. strstr ( fileSrcPath, ".msi" ) ) {
  356. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 4 ], "\\WINNT32.MSI" );
  357. }
  358. else if ( strstr ( fileSrcPath, "a.dll" ) ||
  359. strstr ( fileSrcPath, "A.DLL" ) ) {
  360. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 5 ], "\\WINNT32a.dll" );
  361. }
  362. else if ( strstr ( fileSrcPath, "u.dll" ) ||
  363. strstr ( fileSrcPath, "U.DLL" ) ) {
  364. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 5 ], "\\WINNT32u.dll" );
  365. }
  366. else {
  367. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 4 ], "\\WINNT32.EXE" );
  368. }
  369. hSrc = FindFirstFile ( tmpSrcPath, &wfdSrc );
  370. if ( hSrc == INVALID_HANDLE_VALUE ) {
  371. Msg ( "ERROR on fileSrcPath(tmpSrcPath) = %s, gle = %ld\n", tmpSrcPath, GetLastError() );
  372. return (FALSE);
  373. }
  374. else {
  375. strcpy ( fileSrcPath, tmpSrcPath );
  376. }
  377. }
  378. else {
  379. Msg ( "ERROR on fileSrcPath = %s, gle = %ld\n", fileSrcPath, GetLastError() );
  380. return (FALSE);
  381. }
  382. }
  383. // Find the destination file.
  384. //
  385. hDst = FindFirstFile ( fileDstPath, &wfdDst );
  386. if ( hDst == INVALID_HANDLE_VALUE ) {
  387. DWORD gle;
  388. gle = GetLastError();
  389. if ( gle == ERROR_FILE_NOT_FOUND ) {
  390. // The file doesn't exist on the destination. Do the copy.
  391. //
  392. bDoCopy = TRUE;
  393. }
  394. else {
  395. // Got another kind of error, report this problem.
  396. //
  397. Msg ( "ERROR FindFirstFile fileDstPath = %s, gle = %ld\n", fileDstPath, gle );
  398. FindClose ( hSrc );
  399. return ( FALSE );
  400. }
  401. }
  402. else {
  403. // Both the src and dst exist.
  404. // Let's see if the src is NEWER than the dst, if so, copy.
  405. //
  406. //
  407. b = FileTimeToDosDateTime ( &wfdSrc.ftLastWriteTime, &srcDate, &srcTime );
  408. b = FileTimeToDosDateTime ( &wfdDst.ftLastWriteTime, &dstDate, &dstTime );
  409. if ( (srcDate != dstDate) || (srcTime != dstTime) ) {
  410. ShowMeDosDateTime ( fileSrcPath, srcDate, srcTime, fileDstPath, dstDate, dstTime );
  411. bDoCopy = TRUE;
  412. }
  413. }
  414. // Additional check, verify the file sizes are the same.
  415. //
  416. if ( wfdSrc.nFileSizeLow != wfdSrc.nFileSizeLow ) {
  417. bDoCopy = TRUE;
  418. }
  419. if ( wfdSrc.nFileSizeHigh != wfdDst.nFileSizeHigh ) {
  420. bDoCopy = TRUE;
  421. }
  422. if ( bDoCopy ) {
  423. BOOL b;
  424. DWORD gle;
  425. // Make sure our destination is never READ-ONLY.
  426. //
  427. b = SetFileAttributes ( fileDstPath, FILE_ATTRIBUTE_NORMAL );
  428. if ( !b ) {
  429. // Don't error if the file doesn't exist yet.
  430. //
  431. if ( GetLastError() != ERROR_FILE_NOT_FOUND ) {
  432. Msg ( "ERROR: SetFileAttributes: gle = %ld, %s\n", GetLastError(), fileDstPath);
  433. }
  434. }
  435. b = CopyFile ( fileSrcPath, fileDstPath, FALSE );
  436. if ( b ) {
  437. Msg ( "Copy: %s >>> %s [OK]\n", fileSrcPath, fileDstPath );
  438. }
  439. else {
  440. Msg ( "ERROR Copy: %s >>> %s, gle = %ld\n", fileSrcPath, fileDstPath, GetLastError() );
  441. }
  442. }
  443. else {
  444. Msg ( "%s %d %d %ld %ld +++ %s %d %d %ld %ld [SAME]\n", fileSrcPath, srcDate, srcTime, wfdSrc.nFileSizeLow, wfdSrc.nFileSizeHigh, fileDstPath , dstDate, dstTime, wfdDst.nFileSizeLow, wfdDst.nFileSizeHigh );
  445. }
  446. FindClose ( hSrc );
  447. FindClose ( hDst );
  448. // Make sure our destination is never READ-ONLY.
  449. //
  450. b = SetFileAttributes ( fileDstPath, FILE_ATTRIBUTE_NORMAL );
  451. if ( !b ) {
  452. Msg ( "ERROR: SetFileAttributes: gle = %ld, %s\n", GetLastError(), fileDstPath);
  453. }
  454. // Let's make sure that the file is not 0 bytes in length, due to some
  455. // network problem.
  456. //
  457. hDst = FindFirstFile ( fileDstPath, &wfdDst );
  458. if ( hDst == INVALID_HANDLE_VALUE ) {
  459. Msg ( "ERROR: Can't get size of %s, gle=%ld\n", fileDstPath, GetLastError() );
  460. }
  461. else {
  462. if ( wfdDst.nFileSizeLow == 0 && wfdDst.nFileSizeHigh == 0 ) {
  463. Msg ( "ERROR: Warning: %s is 0 bytes in length !\n", fileDstPath );
  464. }
  465. FindClose ( hDst );
  466. }
  467. // Do bit verification here on all files coming into MyCopyFile.
  468. //
  469. if ( bVerifyBits ) {
  470. BOOL bNoError = TRUE;
  471. HANDLE SrcFileHandle, DstFileHandle;
  472. BOOL b;
  473. BY_HANDLE_FILE_INFORMATION srcFileInformation;
  474. BY_HANDLE_FILE_INFORMATION dstFileInformation;
  475. DWORD srcBytesRead;
  476. DWORD dstBytesRead;
  477. DWORD i;
  478. DWORD totalBytesRead = 0;
  479. #define OFFSET_FILENAME 0x3C // address of file name in diamond header.
  480. // >>> use struct later instead of this hack.
  481. #define OFFSET_PAST_FILENAME 8 + 1 + 3 + 2 // we only use 8.3 filenames.
  482. char unCompressedFileName[OFFSET_PAST_FILENAME];
  483. BOOL bIsDstCompressed = FALSE;
  484. DWORD dw;
  485. char szExpandToDir[MFL];
  486. char target[MFL];
  487. int iRc;
  488. unsigned short unicodeFileLocation[MFL];
  489. unsigned short unicodeTargetLocation[MFL];
  490. bIsDstCompressed = IsDstCompressed ( fileDstPath );
  491. if ( bIsDstCompressed ) {
  492. FILE * fHandle;
  493. char szEndingFileName[MFL];
  494. // Figure out where source should be from.
  495. // Ie., we need to figure out the uncompressed path from the compressed path.
  496. //
  497. if ( fileDstPath[0] == szX86DstDrv[0] ) {
  498. // We are working with Workstation binaries.
  499. //
  500. if ( strstr ( fileSrcPath, szX86Src ) ) {
  501. strcpy ( fileSrcPath, szX86Src );
  502. strcpy ( szExpandToDir, V_I386 );
  503. }
  504. else {
  505. Msg ( "ERROR: couldn't determined location for: %s\n", fileSrcPath );
  506. bNoError = FALSE;
  507. goto cleanup0;
  508. }
  509. }
  510. else {
  511. Msg ( "ERROR: couldn't determined drive for: %s\n", fileDstPath );
  512. bNoError = FALSE;
  513. goto cleanup0;
  514. }
  515. // NOTE: At this point, fileSrcPath ONLY has a path, it now has NO filename !
  516. //
  517. // Find the expanded file name from the compressed file.
  518. //
  519. fHandle = fopen ( fileDstPath, "rb" );
  520. if ( fHandle == NULL) {
  521. Msg ( "ERROR Couldn't open file with fopen to find expanded name: %s\n", fileDstPath );
  522. bNoError = FALSE;
  523. goto cleanup0;
  524. }
  525. else {
  526. size_t bytesRead;
  527. int location;
  528. location = fseek ( fHandle, OFFSET_FILENAME, SEEK_SET );
  529. if ( location != 0 ) {
  530. Msg ( "fseek ERROR\n" );
  531. bNoError = FALSE;
  532. fclose ( fHandle );
  533. goto cleanup0;
  534. }
  535. bytesRead = fread ( unCompressedFileName, 1, OFFSET_PAST_FILENAME, fHandle );
  536. /***
  537. for ( i = 0; i < bytesRead; ++i ) {
  538. printf ( "%X(%c) ", buffer[i], buffer[i] );
  539. }
  540. printf ( "\n" );
  541. ***/
  542. if ( bytesRead != OFFSET_PAST_FILENAME ) {
  543. Msg ( "ERROR: bytesRead = %x not %x\n", bytesRead, OFFSET_PAST_FILENAME );
  544. bNoError = FALSE;
  545. fclose ( fHandle );
  546. goto cleanup0;
  547. }
  548. fclose ( fHandle );
  549. }
  550. // Expand the file.
  551. //
  552. sprintf ( target, "%s\\%s", szExpandToDir, unCompressedFileName );
  553. iRc = MultiByteToWideChar ( CP_ACP,
  554. MB_PRECOMPOSED,
  555. fileDstPath,
  556. strlen ( fileDstPath )+1,
  557. unicodeFileLocation,
  558. MFL/2 );
  559. if ( !iRc ) {
  560. Msg ( "MultiByteToWideChar: ERROR, gle = %ld, %s\n", GetLastError(), fileDstPath );
  561. }
  562. iRc = MultiByteToWideChar ( CP_ACP,
  563. MB_PRECOMPOSED,
  564. target,
  565. strlen ( target )+1,
  566. unicodeTargetLocation,
  567. MFL/2 );
  568. if ( !iRc ) {
  569. Msg ( "MultiByteToWideChar: ERROR, gle = %ld, %s\n", GetLastError(), target );
  570. }
  571. dw = SetupDecompressOrCopyFileW (
  572. unicodeFileLocation,
  573. unicodeTargetLocation,
  574. NULL );
  575. if ( dw ) {
  576. Msg ( "ERROR SetupDecompressOrCopyFile, dw = %d, fileDstPath=%s, target=%s\n",
  577. dw, fileDstPath, target );
  578. bNoError = FALSE;
  579. goto cleanup0;
  580. }
  581. else {
  582. Msg ( "SetupDecompressOrCopyFile: %s >> %s [OK]\n", fileDstPath, target );
  583. }
  584. // Put the Source and Destination paths and filenames back together
  585. // now so we can do the file compare.
  586. //
  587. strcat ( fileSrcPath, "\\" );
  588. strcat ( fileSrcPath, unCompressedFileName );
  589. sprintf ( fileDstPath, "%s\\%s", szExpandToDir, unCompressedFileName );
  590. }
  591. SrcFileHandle = CreateFile ( fileSrcPath,
  592. GENERIC_READ /*| FILE_EXECUTE*/,
  593. FILE_SHARE_READ /*| FILE_SHARE_DELETE*/,
  594. NULL,
  595. OPEN_EXISTING,
  596. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,
  597. NULL);
  598. if ( SrcFileHandle == INVALID_HANDLE_VALUE) {
  599. Msg ( "ERROR verify: Couldn't open source: %s, gle = %ld\n", fileSrcPath, GetLastError() );
  600. bNoError = FALSE;
  601. goto cleanup0;
  602. }
  603. DstFileHandle = CreateFile ( fileDstPath,
  604. GENERIC_READ /*| FILE_EXECUTE*/,
  605. FILE_SHARE_READ /*| FILE_SHARE_DELETE*/,
  606. NULL,
  607. OPEN_EXISTING,
  608. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,
  609. NULL);
  610. if ( DstFileHandle == INVALID_HANDLE_VALUE) {
  611. Msg ( "ERROR verify: Couldn't open destination: %s, gle = %ld\n", fileDstPath, GetLastError() );
  612. bNoError = FALSE;
  613. CloseHandle ( SrcFileHandle );
  614. goto cleanup0;
  615. }
  616. //GetDiskFreeSpace(); // get sector size. // need to use this sector size in reads due to above NO_BUFFERING flag.
  617. b = GetFileInformationByHandle ( SrcFileHandle, &srcFileInformation );
  618. if ( !b ) {
  619. Msg ( "ERROR: GetFileInformationByHandle on src, gle = %ld\n", GetLastError() );
  620. bNoError = FALSE;
  621. srcFileInformation.nFileSizeLow = 0;
  622. goto cleanup1;
  623. }
  624. b = GetFileInformationByHandle ( DstFileHandle, &dstFileInformation );
  625. if ( !b ) {
  626. Msg ( "ERROR: GetFileInformationByHandle on dst, gle = %ld\n", GetLastError() );
  627. bNoError = FALSE;
  628. dstFileInformation.nFileSizeLow = 0;
  629. goto cleanup1;
  630. }
  631. // Make sure the files are the same size.
  632. //
  633. if ( srcFileInformation.nFileSizeLow != dstFileInformation.nFileSizeLow ) {
  634. Msg ( "ERROR: file size different: %s %ld %s %ld\n", fileSrcPath, srcFileInformation.nFileSizeLow, fileDstPath, dstFileInformation.nFileSizeLow );
  635. bNoError = FALSE;
  636. goto cleanup1;
  637. }
  638. // Compare the bits.
  639. //
  640. totalBytesRead = 0;
  641. while ( 1 ) {
  642. b = ReadFile ( SrcFileHandle, &srcBuf, NUM_BYTES_TO_READ, &srcBytesRead, NULL );
  643. if ( !b ) {
  644. Msg ( "ERROR: ReadFile src, gle = %ld\n", GetLastError() );
  645. bNoError = FALSE;
  646. goto cleanup1;
  647. break;
  648. }
  649. b = ReadFile ( DstFileHandle, &dstBuf, NUM_BYTES_TO_READ, &dstBytesRead, NULL );
  650. if ( !b ) {
  651. Msg ( "ERROR: ReadFile dst, gle = %ld\n", GetLastError() );
  652. bNoError = FALSE;
  653. goto cleanup1;
  654. break;
  655. }
  656. // Read # of bytes need to be the same.
  657. //
  658. if ( srcBytesRead != dstBytesRead ) {
  659. Msg ( "ERROR: file read sizes different: %ld vs. %ld\n", srcBytesRead, dstBytesRead );
  660. bNoError = FALSE;
  661. goto cleanup1;
  662. break;
  663. }
  664. // Successfully read to end of file, we can break out now.
  665. //
  666. if ( srcBytesRead == 0 || dstBytesRead == 0 ) {
  667. if ( totalBytesRead != srcFileInformation.nFileSizeLow ) {
  668. Msg ( "ERROR: totalBytesRead = %ld notequal srcFileInformation.nFileSizeLow = %ld\n",
  669. totalBytesRead, srcFileInformation.nFileSizeLow );
  670. bNoError = FALSE;
  671. goto cleanup1;
  672. }
  673. break;
  674. }
  675. totalBytesRead += srcBytesRead;
  676. for ( i = 0; i < srcBytesRead; ++i ) {
  677. if ( srcBuf[i] != dstBuf[i] ) {
  678. Msg ( "ERROR: srcBuf %d != dstBuf %d, i = %ld srcBytesRead = %ld totalBytesRead = %ld %s %s \n", srcBuf[i], dstBuf[i], i, srcBytesRead, totalBytesRead, fileSrcPath, fileDstPath );
  679. bNoError = FALSE;
  680. Replay ( srcBuf, dstBuf, srcBytesRead, i );
  681. goto cleanup1;
  682. }
  683. }
  684. //Msg ( "%s %ld of %ld examined...\n", fileSrcPath, totalBytesRead, srcFileInformation.nFileSizeLow );
  685. }
  686. // Close the file handles.
  687. //
  688. cleanup1:;
  689. CloseHandle ( SrcFileHandle );
  690. CloseHandle ( DstFileHandle );
  691. Msg ( "Verify: %s >>> %s [OK]\n", fileSrcPath, fileDstPath );
  692. cleanup0:;
  693. // If the file is compressed, ie. expanded, and the there wasn't an error
  694. // comparing, get rid of the expanded file so it doesn't take up any space.
  695. // But, if there was an error, leave it around for examination purposes.
  696. //
  697. if ( bIsDstCompressed && bNoError ) {
  698. char szDeleteFile[MFL];
  699. BOOL b;
  700. sprintf ( szDeleteFile, "%s\\%s", szExpandToDir, unCompressedFileName );
  701. b = DeleteFile ( szDeleteFile );
  702. if ( !b ) {
  703. Msg ( "ERROR: DeleteFile FAILED %s, gle = %ld\n", szDeleteFile, GetLastError() );
  704. }
  705. }
  706. }
  707. return (TRUE);
  708. }
  709. #define FILE_SECTION_BASE "[SourceDisksFiles]"
  710. #define FILE_SECTION_X86 "[SourceDisksFiles.x86]"
  711. BOOL CreateDir ( char * wcPath ) {
  712. BOOL b;
  713. char cPath[MFL];
  714. char cPath2[MFL];
  715. int iIndex = 0;
  716. char * ptr=wcPath;
  717. // Msg ( "CreateDir: wcPath = %s\n", wcPath );
  718. do {
  719. cPath[iIndex] = *wcPath;
  720. cPath[iIndex+1] = '\0';
  721. //Msg ( "cPath = %s\n", cPath );
  722. if ( cPath[iIndex] == '\\' || cPath[iIndex] == '\0' ) {
  723. if ( iIndex <= 2 ) {
  724. //Msg ( "skpdrv: iIndex = %d\n", iIndex );
  725. goto skipdrv;
  726. }
  727. strcpy ( cPath2, cPath );
  728. cPath2[iIndex] = '\0';
  729. //Msg ( "Create with: >>>%s<<<\n", cPath2 );
  730. b = CreateDirectory ( cPath, NULL );
  731. if ( !b ) {
  732. DWORD dwGle;
  733. dwGle = GetLastError();
  734. if ( dwGle != ERROR_ALREADY_EXISTS ) {
  735. Msg ( "ERROR CreateDirectory gle = %ld, wcPath = %s\n", dwGle, ptr );
  736. return(FALSE);
  737. }
  738. }
  739. else {
  740. Msg ( "Made dir: %s\n", cPath );
  741. }
  742. if ( cPath[iIndex] == '\0' ) {
  743. break;
  744. }
  745. }
  746. skipdrv:;
  747. ++iIndex;
  748. ++wcPath;
  749. } while ( 1 );
  750. return(TRUE);
  751. }
  752. BOOL CreateDestinationDirs ( void ) {
  753. CHAR dstDirectory[MFL];
  754. // Create the directories to compare the bits, used later in MyCopyFile().
  755. //
  756. CreateDir ( V_I386 );
  757. if ( bNec98 ) {
  758. CreateDir ( V_NEC98 );
  759. }
  760. // Create the %platform%\system32 directories.
  761. //
  762. sprintf ( dstDirectory, "%s%s", szX86DstDrv, I386_DIR ); CreateDir ( dstDirectory );
  763. if ( bNec98 ) {
  764. sprintf ( dstDirectory, "%s%s", szX86DstDrv, NEC98_DIR ); CreateDir ( dstDirectory );
  765. }
  766. return(TRUE);
  767. }
  768. VOID MakeCompName ( const char * inFile, char * outFile ) {
  769. unsigned i;
  770. unsigned period;
  771. strcpy( outFile, inFile );
  772. for ( period=(unsigned)(-1), i = 0 ; i < strlen(inFile); i++ ) {
  773. if ( inFile[i] == '.' ) {
  774. period = i;
  775. }
  776. }
  777. if ( period == (strlen(inFile)-4) ) {
  778. outFile[strlen(outFile)-1] = '_';
  779. }
  780. else if ( period == (unsigned)(-1)) {
  781. strcat ( outFile, "._");
  782. }
  783. else {
  784. strcat ( outFile, "_");
  785. }
  786. }
  787. DWORD CopyX86 ( void ) {
  788. char fileSrcPath[256];
  789. char fileDstPath[256];
  790. DWORD i;
  791. fX86 = FALSE;
  792. Msg ( "CopyX86...\n" );
  793. for ( i = 0; i < ix386.wNumFiles; ++i ) {
  794. //Msg ( "0.working on %ld of %ld files: %s\n", i, ix386.wNumFiles, ix386.wcFilesArray[i] );
  795. // Copy the system file.
  796. //
  797. if ( !ix386.bCopyItToCD[i] ) {
  798. Msg ( "Not going to copy inner cab file to CD: %s\n", ix386.wcFilesArray[i] );
  799. goto JustX86;
  800. }
  801. if ( ix386.bCopyComp[i] ) {
  802. char szCompressedName[256];
  803. MakeCompName ( ix386.wcFilesArray[i], szCompressedName );
  804. sprintf ( fileSrcPath, "%s\\%s", szX86Src, szCompressedName );
  805. sprintf ( fileDstPath, "%s\\i386\\%s", szX86DstDrv, szCompressedName );
  806. Msg ( "compressed source Path = %s\n", fileSrcPath );
  807. }
  808. else {
  809. sprintf ( fileSrcPath, "%s\\%s", szX86Src, ix386.wcFilesArray[i] );
  810. sprintf ( fileDstPath, "%s\\i386\\%s", szX86DstDrv, ix386.wcFilesArray[i] );
  811. }
  812. MyCopyFile ( fileSrcPath, fileDstPath );
  813. JustX86:;
  814. }
  815. fX86 = TRUE;
  816. return (TRUE);
  817. }
  818. DWORD CopyNec98 ( void ) {
  819. char fileSrcPath[256];
  820. char fileDstPath[256];
  821. DWORD i;
  822. fNec98 = FALSE;
  823. Msg ( "CopyNec98...\n" );
  824. for ( i = 0; i < Nec98.wNumFiles; ++i ) {
  825. // Copy the system file.
  826. //
  827. if ( !Nec98.bCopyItToCD[i] ) {
  828. Msg ( "Not going to copy inner cab file to CD: %s\n", Nec98.wcFilesArray[i] );
  829. goto JustNec98;
  830. }
  831. if ( Nec98.bCopyComp[i] ) {
  832. char szCompressedName[256];
  833. MakeCompName ( Nec98.wcFilesArray[i], szCompressedName );
  834. sprintf ( fileSrcPath, "%s\\%s", szNec98Src, szCompressedName );
  835. sprintf ( fileDstPath, "%s\\Nec98\\%s", szX86DstDrv, szCompressedName );
  836. Msg ( "compressed source Path = %s\n", fileSrcPath );
  837. }
  838. else {
  839. sprintf ( fileSrcPath, "%s\\%s", szNec98Src, Nec98.wcFilesArray[i] );
  840. sprintf ( fileDstPath, "%s\\Nec98\\%s", szX86DstDrv, Nec98.wcFilesArray[i] );
  841. }
  842. MyCopyFile ( fileSrcPath, fileDstPath );
  843. JustNec98:;
  844. }
  845. fNec98 = TRUE;
  846. return (TRUE);
  847. }
  848. BOOL CopyTheFiles ( void ) {
  849. DWORD tId;
  850. HANDLE hThread;
  851. hThread = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE) CopyX86, NULL, 0, &tId );
  852. if ( hThread == NULL ) {
  853. Msg ( "x86 CreateThread ERROR gle = %ld\n", GetLastError() );
  854. }
  855. // Assume TRUE here so if we don't copy Nec98 files, our while loop won't
  856. // be dependant on this variable.
  857. //
  858. fNec98 = TRUE;
  859. if ( bNec98 ) {
  860. hThread = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE) CopyNec98, NULL, 0, &tId );
  861. if ( hThread == NULL ) {
  862. Msg ( "Nec98 CreateThread ERROR gle = %ld\n", GetLastError() );
  863. }
  864. }
  865. while ( fX86 == FALSE ||
  866. fNec98 == FALSE ) {
  867. Sleep ( 1000 );
  868. }
  869. return(TRUE);
  870. }
  871. #define FILE_SECTION_NOT_USED 0xFFFF
  872. DWORD dwInsideSection = FILE_SECTION_NOT_USED;
  873. DWORD FigureSection ( char * Line ) {
  874. Msg ( "FigureSection on: %s\n", Line );
  875. if ( strstr ( Line, FILE_SECTION_BASE ) ) {
  876. dwInsideSection = idBase;
  877. }
  878. else
  879. if ( strstr ( Line, FILE_SECTION_X86 ) ) {
  880. dwInsideSection = idX86;
  881. }
  882. else {
  883. dwInsideSection = FILE_SECTION_NOT_USED;
  884. }
  885. Msg ( "dwInsideSection = %x\n", dwInsideSection );
  886. return(dwInsideSection);
  887. }
  888. char * SuckName ( const char * Line ) {
  889. static char szSuckedName[MFL];
  890. DWORD dwIndex = 0;
  891. // Copy the file name until a space is encountered.
  892. //
  893. while ( *Line != ' ' ) {
  894. szSuckedName[dwIndex] = *Line;
  895. szSuckedName[dwIndex+1] = '\0';
  896. ++Line;
  897. ++dwIndex;
  898. }
  899. return szSuckedName;
  900. }
  901. char * SuckSubName ( const char * Line ) {
  902. static char szSub[150];
  903. DWORD i = 0;
  904. char * sPtr;
  905. char * ePtr;
  906. Msg ( "SuckSubName Line = %s\n", Line );
  907. // Find the = sign in the line.
  908. //
  909. sPtr = strchr ( Line, '=' );
  910. if ( sPtr == NULL ) {
  911. Msg ( "SuckSubName ERROR, couldn't find '=' character in string: %s\n", Line );
  912. strcpy ( szSub, "" );
  913. return (szSub);
  914. }
  915. // Go past the '=' and 'space' character.
  916. //
  917. ++sPtr;
  918. ++sPtr;
  919. //Msg ( "sPtr = >>>%s<<<\n", sPtr );
  920. // Find the , character, this is the end of the string.
  921. //
  922. ePtr = strchr ( Line, ',' );
  923. if ( ePtr == NULL ) {
  924. Msg ( "SuckSubName ERROR, couldn't find ',' character in string: %s\n", Line );
  925. strcpy ( szSub, "" );
  926. return (szSub);
  927. }
  928. // Copy the string.
  929. do {
  930. szSub[i] = *sPtr;
  931. ++i;
  932. ++sPtr;
  933. } while ( sPtr < ePtr );
  934. szSub[i] = '\0';
  935. //Msg ( "szSub = >>>%s<<<\n\n", szSub );
  936. return szSub;
  937. }
  938. void ShowX86 ( void ) {
  939. int i;
  940. for ( i = 0; i < ix386.wNumFiles; ++i ) {
  941. Msg ( "%d %s Comp=%d CopyItToCD=%d\n",
  942. i,
  943. ix386.wcFilesArray[i],
  944. ix386.bCopyComp[i],
  945. ix386.bCopyItToCD[i] );
  946. }
  947. }
  948. void ShowNec98 ( void ) {
  949. int i;
  950. for ( i = 0; i < Nec98.wNumFiles; ++i ) {
  951. Msg ( "%d %s Comp=%d\n",
  952. i,
  953. Nec98.wcFilesArray[i],
  954. Nec98.bCopyComp[i] );
  955. }
  956. }
  957. void AddFileToX86 ( const char * fileName, BOOL bCopyComp, BOOL bTextMode, BOOL bCopyItToCD ) {
  958. ix386.bCopyComp[ix386.wNumFiles] = bCopyComp;
  959. ix386.bCountBytes[ix386.wNumFiles] = bGetSizeLater;
  960. ix386.bTextMode[ix386.wNumFiles] = bTextMode;
  961. ix386.bCopyItToCD[ix386.wNumFiles] = bCopyItToCD;
  962. strcpy ( ix386.wcFilesArray[ix386.wNumFiles], fileName );
  963. ++ix386.wNumFiles;
  964. if ( ix386.wNumFiles > MAX_NUMBER_OF_FILES_IN_PRODUCT ) {
  965. Msg ( "FATAL ERROR: Increase MAX_NUM in Files.C\n" );
  966. exit ( 1 );
  967. }
  968. }
  969. void AddFileToNec98 ( const char * fileName, BOOL bCopyComp, BOOL bTextMode, BOOL bCopyItToCD ) {
  970. Nec98.bCopyComp[Nec98.wNumFiles] = bCopyComp;
  971. Nec98.bCountBytes[Nec98.wNumFiles] = bGetSizeLater;
  972. Nec98.bTextMode[Nec98.wNumFiles] = bTextMode;
  973. Nec98.bCopyItToCD[Nec98.wNumFiles] = bCopyItToCD;
  974. strcpy ( Nec98.wcFilesArray[Nec98.wNumFiles], fileName );
  975. ++Nec98.wNumFiles;
  976. if ( Nec98.wNumFiles > MAX_NUMBER_OF_FILES_IN_PRODUCT ) {
  977. Msg ( "FATAL ERROR: Increase MAX_NUM in Files.C\n" );
  978. exit ( 1 );
  979. }
  980. }
  981. void CopyCompressedFile ( const char * Line ) {
  982. const char * Ptr = Line;
  983. DWORD i = 0;
  984. #define COMP_FIELD 6
  985. // Let's assume that we will compress the files and have to prove that we don't.
  986. //
  987. bCopyCompX86 = TRUE;
  988. bCopyCompNec98 = TRUE;
  989. while ( *Line != '\0' ) {
  990. // If we are at the correct field,
  991. // then stop counting fields.
  992. //
  993. if ( i == COMP_FIELD ) {
  994. break;
  995. }
  996. // Found another field, increment our counter.
  997. //
  998. if ( *Line == ',' ) {
  999. ++i;
  1000. }
  1001. // Look at next char.
  1002. //
  1003. ++Line;
  1004. }
  1005. if ( i != COMP_FIELD ) {
  1006. Msg ( "CopyCompressedFile ERROR: we are out of while loop, but didn't find the field >>> %s\n", Ptr );
  1007. }
  1008. // Determine if we should keep the file compressed or not.
  1009. //
  1010. switch ( *Line ) {
  1011. case '_' :
  1012. // Indicator that we do NOT want this file compressed.
  1013. //
  1014. bCopyCompX86 = FALSE;
  1015. bCopyCompNec98 = FALSE;
  1016. break;
  1017. case 'x' :
  1018. case 'X' :
  1019. case '1' :
  1020. case '2' :
  1021. case '3' :
  1022. case '4' :
  1023. // do nothing...
  1024. break;
  1025. case ',' :
  1026. // do nothing, there is nothing in the field, meaning get compressed files.
  1027. //
  1028. break;
  1029. default :
  1030. Msg ( "CopyCompressedFile ERROR: *Line default char >>%c<<\n", *Line );
  1031. }
  1032. }
  1033. #define X86_F 0
  1034. #define NEC98_F 4
  1035. #define DBGS_AND_NON_INSTALLED 6
  1036. // Verify that the files line in layout.inf has a file space
  1037. // associated with it, so if it ever used in optional components it
  1038. // will be added up.
  1039. //
  1040. void CheckSpace ( char * Line, char * Location, char * fileName ) {
  1041. char tLine[MFL];
  1042. int i, val;
  1043. char * sPtr = Line;
  1044. int numCommas = 0;
  1045. //Msg ( "CheckSpace: Line = %s", Line );
  1046. while ( 1 ) {
  1047. if ( *sPtr == ',' ) {
  1048. ++numCommas;
  1049. }
  1050. if ( numCommas == 2 ) {
  1051. break;
  1052. }
  1053. ++sPtr;
  1054. }
  1055. // At this point, we are pointing to the 2nd comma.
  1056. // So, let's go one char further.
  1057. //
  1058. ++sPtr;
  1059. // Copy the string until we get to the next comma.
  1060. //
  1061. strcpy ( tLine, sPtr );
  1062. sPtr = tLine;
  1063. while ( 1 ) {
  1064. if ( *sPtr == ',' ) {
  1065. *sPtr = '\0';
  1066. break;
  1067. }
  1068. else {
  1069. ++sPtr;
  1070. }
  1071. }
  1072. val = atoi ( tLine );
  1073. if ( val > 0 ) {
  1074. //Msg ( "val = %d >>> Line = %s", val, Line );
  1075. }
  1076. else {
  1077. if ( !strstr ( Line, "desktop.ini" ) ) {
  1078. Msg ( "CheckSpace ERROR - Tell build lab to run INFSIZE.EXE: location=%s, val = %d, Line = >>>%s<<<, fileName = %s\n", Location, val, Line, fileName );
  1079. }
  1080. }
  1081. }
  1082. void CheckLength ( char * Line ) {
  1083. if ( strlen ( Line ) > 12 ) {
  1084. Msg ( "ERROR CheckLength - file name is NOT an 8.3 DOS filename - tell the owner of this file to shorten it's filename length: %s\n", Line );
  1085. }
  1086. // Check for the optional . part.
  1087. //
  1088. // tbd
  1089. // Check for the optional 3 part.
  1090. //
  1091. // tbd
  1092. }
  1093. BOOL TextMode ( const char * fileName ) {
  1094. // Determine if this file has a 0 in the xth column which denotes
  1095. // it will be moved during textmode on a single partition scenario.
  1096. // If it has a 0, return TRUE to denote it gets moved on a fresh
  1097. // installed where ~ls is on the same partition that the %windir%
  1098. // will be on.
  1099. //
  1100. //const char * Ptr = Line;
  1101. DWORD i = 0;
  1102. BOOL b;
  1103. INFCONTEXT ic;
  1104. CHAR returnBuffer[MFL];
  1105. DWORD dwRequiredSize;
  1106. #define SDF "SourceDisksFiles"
  1107. #define SDF_X86 "SourceDisksFiles.x86"
  1108. #define TEXTMODE_FIELD 9
  1109. b = SetupFindFirstLine ( hInfLayout,
  1110. SDF,
  1111. fileName,
  1112. &ic );
  1113. if ( !b ) {
  1114. b = SetupFindFirstLine ( hInfLayout,
  1115. SDF_X86,
  1116. fileName,
  1117. &ic );
  1118. if ( !b ) {
  1119. if ( !strstr ( fileName, "usetup.exe" ) ) {
  1120. Msg ( "ERROR: TextMode: SetupFindFirstLine >>%s<< not found in SourceDiskFiles[.x86]\n", fileName, SDF );
  1121. return (FALSE);
  1122. }
  1123. }
  1124. }
  1125. else {
  1126. // Get the 9th field
  1127. //
  1128. b = SetupGetStringField ( &ic,
  1129. TEXTMODE_FIELD,
  1130. (LPSTR) &returnBuffer,
  1131. sizeof ( returnBuffer ),
  1132. &dwRequiredSize );
  1133. if ( !b ) {
  1134. Msg ( "ERROR: SetupGetStringField gle = %ld\n", GetLastError());
  1135. }
  1136. else {
  1137. if ( returnBuffer[0] == '0' ) {
  1138. Msg ( "file is copied during textmode: %s\n", fileName );
  1139. return (TRUE);
  1140. }
  1141. else {
  1142. Msg ( "file is NOT copied during textmode: %s\n", fileName );
  1143. return (FALSE);
  1144. }
  1145. }
  1146. }
  1147. return (FALSE);
  1148. // herehere
  1149. /****
  1150. Msg ( "4.1.hInfLayout = %ld\n", hInfLayout );
  1151. Msg ( "the Line:%s\n", Line );
  1152. while ( *Line != '\0' ) {
  1153. // If we are at the correct field,
  1154. // then stop counting fields.
  1155. //
  1156. if ( i == TEXTMODE_FIELD ) {
  1157. //++Line;
  1158. Msg ( "we are at the correct field, stop counting...\n" );
  1159. break;
  1160. }
  1161. // Found another field, increment our counter.
  1162. //
  1163. if ( *Line == ',' ) {
  1164. Msg ( "found another field, increment our counter...\n" );
  1165. ++i;
  1166. }
  1167. // Look at next char.
  1168. //
  1169. ++Line;
  1170. Msg ( "now pointing at:%s\n", Line );
  1171. }
  1172. Msg ( "we're at:%s\n", Line );
  1173. Msg ( "4.2hInfLayout = %ld\n", hInfLayout );
  1174. if ( i == TEXTMODE_FIELD ) {
  1175. if ( *Line == '0' ) {
  1176. Msg ( "TextMode: This file is copied during textmode: %s\n", Ptr );
  1177. return (TRUE);
  1178. }
  1179. else {
  1180. Msg ( "TextMode (*Line = %c): This file is NOT copied during textmode: %s\n", *Line, Ptr );
  1181. }
  1182. }
  1183. else {
  1184. Msg ( "TextMode Warning: we are out of while loop, but didn't find the field >>> %s\n", Ptr );
  1185. }
  1186. Msg ( "4.3hInfLayout = %ld\n", hInfLayout );
  1187. return (FALSE);
  1188. ***/
  1189. }
  1190. void CheckSpaceAndLength ( char * Line, char * Location, char * fileName ) {
  1191. CheckSpace ( Line, Location, fileName );
  1192. //CheckLength ( Line );
  1193. }
  1194. void AddFiles ( char * fileName, DWORD dwPlatform, BOOL bCopyItToCD ) {
  1195. CHAR Line[MFL];
  1196. BOOL bTextMode = FALSE;
  1197. BOOL b;
  1198. DWORD dwRequiredSize;
  1199. INFCONTEXT ic;
  1200. bCopyCompX86 = FALSE;
  1201. bCopyCompNec98 = FALSE;
  1202. switch ( dwPlatform ) {
  1203. case X86_F :
  1204. Msg ( "AddToX86Files: %s\n", fileName );
  1205. // Get the entire string.
  1206. //
  1207. b = SetupGetLineText ( NULL,
  1208. hInfLayout,
  1209. SDF,
  1210. fileName,
  1211. (LPSTR) &Line,
  1212. sizeof ( Line ),
  1213. &dwRequiredSize );
  1214. if ( !b ) {
  1215. b = SetupGetLineText ( NULL,
  1216. hInfLayout,
  1217. SDF_X86,
  1218. fileName,
  1219. (LPSTR) &Line,
  1220. sizeof ( Line ),
  1221. &dwRequiredSize );
  1222. if ( !b ) {
  1223. if ( strstr ( fileName, "driver.cab" ) ||
  1224. strstr ( fileName, "drvindex.inf" ) ) {
  1225. goto AddX86;
  1226. }
  1227. Msg ( "ERROR: 1.SetupGetLineText not found in %s for %s, gle=%ld, dwRequiredSize = %ld\n", "SourceDisksFiles[.x86]", fileName, GetLastError(), dwRequiredSize );
  1228. break;
  1229. }
  1230. }
  1231. Msg ( "Line:>>%s<<\n", Line );
  1232. CheckSpaceAndLength ( Line, "x86", fileName );
  1233. CopyCompressedFile ( Line );
  1234. bTextMode = TextMode ( fileName );
  1235. AddX86:
  1236. CheckLength ( fileName );
  1237. AddFileToX86 ( fileName, bCopyCompX86, bTextMode, bCopyItToCD );
  1238. break;
  1239. case NEC98_F :
  1240. Msg ( "AddToNecFiles: %s\n", fileName );
  1241. // Get the entire string.
  1242. //
  1243. b = SetupGetLineText ( NULL,
  1244. hInfLayout,
  1245. SDF,
  1246. fileName,
  1247. (LPSTR) &Line,
  1248. sizeof ( Line ),
  1249. &dwRequiredSize );
  1250. if ( !b ) {
  1251. b = SetupGetLineText ( NULL,
  1252. hInfLayout,
  1253. SDF_X86,
  1254. fileName,
  1255. (LPSTR) &Line,
  1256. sizeof ( Line ),
  1257. &dwRequiredSize );
  1258. if ( !b ) {
  1259. if ( strstr ( fileName, "driver.cab" ) ||
  1260. strstr ( fileName, "drvindex.inf" ) ) {
  1261. goto AddNec98;
  1262. }
  1263. Msg ( "ERROR: 3.SetupGetLineText not found in %s for %s, gle=%ld, dwRequiredSize = %ld\n", "SourceDisksFiles[.x86]", fileName, GetLastError(), dwRequiredSize );
  1264. break;
  1265. }
  1266. }
  1267. Msg ( "Line:>>%s<<\n", Line );
  1268. CheckSpaceAndLength ( Line, "nec", fileName );
  1269. CopyCompressedFile ( Line );
  1270. bTextMode = TextMode ( fileName );
  1271. AddNec98:;
  1272. CheckLength ( fileName );
  1273. AddFileToNec98 ( fileName, bCopyCompNec98, bTextMode, bCopyItToCD );
  1274. break;
  1275. default :
  1276. Msg ( "ERROR: AddFiles - uknown platform %ld\n", dwPlatform );
  1277. }
  1278. }
  1279. BOOL PlatformFilesToCopy ( char * szInfPath, DWORD dwPlatform ) {
  1280. CHAR infFilePath[MFL];
  1281. BOOL b;
  1282. DWORD dwRequiredSize;
  1283. INFCONTEXT ic;
  1284. CHAR returnBuffer[MAX_PATH];
  1285. #define FILES_SECTION "Files"
  1286. #define FILES_SECTION_DRIVER "driver"
  1287. Msg ( "\n\n\n" );
  1288. Msg ( "PlatformFilesToCopy: szInfPath = %s, dwPlatform = %ld\n", szInfPath, dwPlatform );
  1289. // Open up a handle to dosnet.inf
  1290. //
  1291. sprintf ( infFilePath, "%s\\%s", szInfPath, "dosnet.inf" );
  1292. Msg ( "infFilePath = %s\n", infFilePath );
  1293. hInfDosnet = SetupOpenInfFile ( infFilePath, NULL, INF_STYLE_WIN4, NULL );
  1294. if ( hInfDosnet == INVALID_HANDLE_VALUE ) {
  1295. Msg ( "FATAL ERROR: could not open INF: %s, gle = %ld\n", infFilePath, GetLastError() );
  1296. exit ( GetLastError() );
  1297. }
  1298. Msg ( "hInfDosnet = %ld\n", hInfDosnet );
  1299. // Open up a handle to layout.inf
  1300. //
  1301. sprintf ( infFilePath, "%s\\%s", szInfPath, "layout.inf" );
  1302. Msg ( "infFilePath = %s\n", infFilePath );
  1303. hInfLayout = SetupOpenInfFile ( infFilePath, NULL, INF_STYLE_WIN4, NULL );
  1304. if ( hInfLayout == INVALID_HANDLE_VALUE ) {
  1305. Msg ( "FATAL ERROR: could not open INF: %s, gle = %ld\n", infFilePath, GetLastError() );
  1306. exit ( GetLastError() );
  1307. }
  1308. Msg ( "hInfLayout = %ld\n", hInfLayout );
  1309. // Open up a handle to drvindex.inf
  1310. //
  1311. sprintf ( infFilePath, "%s\\%s", szInfPath, "drvindex.inf" );
  1312. Msg ( "infFilePath = %s\n", infFilePath );
  1313. hInfDrvIndex = SetupOpenInfFile ( infFilePath, NULL, INF_STYLE_WIN4, NULL );
  1314. if ( hInfDrvIndex == INVALID_HANDLE_VALUE ) {
  1315. Msg ( "FATAL ERROR: could not open INF: %s, gle = %ld\n", infFilePath, GetLastError() );
  1316. exit ( GetLastError () );
  1317. }
  1318. Msg ( "hInfDrvIndex = %ld\n", hInfDrvIndex );
  1319. // Get the files listed in dosnet.inf to copy to the CD.
  1320. // Denote them to be copied to the CD by specifying TRUE to AddFiles().
  1321. //
  1322. b = SetupFindFirstLine ( hInfDosnet,
  1323. FILES_SECTION,
  1324. NULL,
  1325. &ic );
  1326. if ( !b ) {
  1327. Msg ( "ERROR: SetupFindFirstLine not found in %s\n", FILES_SECTION );
  1328. }
  1329. else {
  1330. // Get the 2nd field, ie. the filename, such as in d1,ntkrnlmp.exe
  1331. //
  1332. b = SetupGetStringField ( &ic,
  1333. 2,
  1334. (LPSTR) &returnBuffer,
  1335. sizeof ( returnBuffer ),
  1336. &dwRequiredSize );
  1337. if ( !b ) {
  1338. Msg ( "ERROR: SetupGetStringField gle = %ld\n", GetLastError());
  1339. }
  1340. else {
  1341. AddFiles ( returnBuffer, dwPlatform, TRUE );
  1342. }
  1343. while ( 1 ) {
  1344. // Get the next line in the section.
  1345. //
  1346. b = SetupFindNextLine ( &ic,
  1347. &ic );
  1348. if ( !b ) {
  1349. // Denotes that there is NOT another line.
  1350. //
  1351. Msg ( "no more files in section...\n" );
  1352. break;
  1353. }
  1354. else {
  1355. // Get the 2nd field's filename,
  1356. // such as in d1,ntoskrnl.exe.
  1357. //
  1358. b = SetupGetStringField ( &ic,
  1359. 2,
  1360. (LPSTR) &returnBuffer,
  1361. sizeof ( returnBuffer ),
  1362. &dwRequiredSize );
  1363. if ( !b ) {
  1364. Msg ( "ERROR: SetupGetStringField gle = %ld\n", GetLastError());
  1365. }
  1366. else {
  1367. AddFiles ( returnBuffer, dwPlatform, TRUE );
  1368. }
  1369. }
  1370. }
  1371. }
  1372. // Get the files listed in drvindex.inf to later calculate disk space.
  1373. // Denote them NOT to be copied to the CD by specifying FALSE to AddFiles().
  1374. //
  1375. b = SetupFindFirstLine ( hInfDrvIndex,
  1376. FILES_SECTION_DRIVER,
  1377. NULL,
  1378. &ic );
  1379. if ( !b ) {
  1380. Msg ( "ERROR: SetupFindFirstLine not found in %s\n", FILES_SECTION_DRIVER );
  1381. }
  1382. else {
  1383. // Get the 1st field, ie. the filename, such as changer.sys.
  1384. //
  1385. b = SetupGetStringField ( &ic,
  1386. 1,
  1387. (LPSTR) &returnBuffer,
  1388. sizeof ( returnBuffer ),
  1389. &dwRequiredSize );
  1390. if ( !b ) {
  1391. Msg ( "ERROR: SetupGetStringField gle = %ld\n", GetLastError());
  1392. }
  1393. else {
  1394. Msg ( "found -> %s\n", returnBuffer );
  1395. AddFiles ( returnBuffer, dwPlatform, FALSE );
  1396. }
  1397. while ( 1 ) {
  1398. // Get the next line in the section.
  1399. //
  1400. b = SetupFindNextLine ( &ic,
  1401. &ic );
  1402. if ( !b ) {
  1403. // Denotes that there is NOT another line.
  1404. //
  1405. Msg ( "no more files in section...\n" );
  1406. break;
  1407. }
  1408. else {
  1409. // Get the 1st field's filename,
  1410. // such as in changer.sys.
  1411. //
  1412. b = SetupGetStringField ( &ic,
  1413. 1,
  1414. (LPSTR) &returnBuffer,
  1415. sizeof ( returnBuffer ),
  1416. &dwRequiredSize );
  1417. if ( !b ) {
  1418. Msg ( "ERROR: SetupGetStringField gle = %ld\n", GetLastError());
  1419. }
  1420. else {
  1421. Msg ( "found -> %s\n", returnBuffer );
  1422. AddFiles ( returnBuffer, dwPlatform, FALSE );
  1423. }
  1424. }
  1425. }
  1426. }
  1427. // Close all the inf handles.
  1428. //
  1429. SetupCloseInfFile ( hInfDosnet );
  1430. SetupCloseInfFile ( hInfLayout );
  1431. SetupCloseInfFile ( hInfDrvIndex );
  1432. return (TRUE);
  1433. }
  1434. BOOL GetTheFiles ( char * DosnetInfPath, char * dosnetFile, int AddToList ) {
  1435. CHAR infFilePath[MFL];
  1436. DWORD dwErrorLine;
  1437. BOOL b;
  1438. char dstDirectory[MFL];
  1439. FILE * fHandle;
  1440. char Line[MFL];
  1441. HANDLE hDosnetInf;
  1442. // Open the inx file for processing.
  1443. //
  1444. sprintf ( infFilePath, "%s\\%s", DosnetInfPath, dosnetFile );
  1445. Msg ( "infFilePath = %s\n", infFilePath );
  1446. fHandle = fopen ( infFilePath, "rt" );
  1447. if ( fHandle ) {
  1448. Msg ( "dwInsideSection = %x\n", dwInsideSection );
  1449. while ( fgets ( Line, sizeof(Line), fHandle ) ) {
  1450. int i;
  1451. char * p = Line;
  1452. int iCommas;
  1453. BOOL bTextMode = FALSE;
  1454. Msg ( "Line: %s\n", Line );
  1455. if ( Line[0] == '[' ) {
  1456. // We may have a new section.
  1457. //
  1458. dwInsideSection = FigureSection ( Line );
  1459. continue;
  1460. }
  1461. // Reasons to ignore this line from further processing.
  1462. //
  1463. //
  1464. // File section not one we process.
  1465. //
  1466. if ( dwInsideSection == FILE_SECTION_NOT_USED ) {
  1467. continue;
  1468. }
  1469. // Line just contains a non-usefull short string.
  1470. //
  1471. i = strlen ( Line );
  1472. if ( i < 4 ) {
  1473. continue;
  1474. }
  1475. // Line contains just a comment.
  1476. //
  1477. if ( Line[0] == ';' ) {
  1478. continue;
  1479. }
  1480. // There are not enough commas in the line.
  1481. //
  1482. iCommas = 0;
  1483. while ( 1 ) {
  1484. if ( *p == '\0' ) {
  1485. break;
  1486. }
  1487. if ( *p == ',' ) {
  1488. ++iCommas;
  1489. }
  1490. ++p;
  1491. }
  1492. if ( iCommas < 5 ) {
  1493. Msg ( "ERROR - there are not enough commas in the line: %s\n", Line );
  1494. continue;
  1495. }
  1496. switch ( AddToList ) {
  1497. case DBGS_AND_NON_INSTALLED :
  1498. CheckLength ( SuckName(Line) );
  1499. bCopyCompX86 = FALSE;
  1500. bCopyCompNec98 = FALSE;
  1501. bTextMode = FALSE;
  1502. if ( dwInsideSection == idBase ) {
  1503. CopyCompressedFile ( Line );
  1504. AddFileToX86 ( SuckName(Line), bCopyCompX86, bTextMode, TRUE );
  1505. if ( bNec98 ) {
  1506. AddFileToNec98 ( SuckName(Line), bCopyCompNec98, bTextMode, TRUE );
  1507. }
  1508. break;
  1509. }
  1510. if ( dwInsideSection == idX86 ) {
  1511. CopyCompressedFile ( Line );
  1512. AddFileToX86 ( SuckName(Line), bCopyCompX86, bTextMode, TRUE );
  1513. if ( bNec98 ) {
  1514. AddFileToNec98 ( SuckName(Line), bCopyCompNec98, bTextMode, TRUE );
  1515. }
  1516. break;
  1517. }
  1518. break;
  1519. default :
  1520. Msg ( "ERROR: AddToList = %d\n", AddToList );
  1521. }
  1522. }
  1523. if ( ferror(fHandle) ) {
  1524. Msg ( "ERROR fgets reading from file...\n" );
  1525. }
  1526. }
  1527. else {
  1528. Msg ( "fopen ERROR %s\n", infFilePath );
  1529. return (FALSE);
  1530. }
  1531. fclose ( fHandle );
  1532. return (TRUE);
  1533. }
  1534. void ShowFreshLocalSpace ( char * fileName, DWORD dwFresh, DWORD dwLocal ) {
  1535. Msg ( "processing: %s freshBytes->K32 = %ld, localSrcBytes->K32 = %ld\n",
  1536. fileName, dwFresh, dwLocal );
  1537. }
  1538. //
  1539. // textModeBytes is used to subtract out the bytes not really
  1540. // needed to be counted by setup for a 1 partition move of the files.
  1541. //
  1542. void TallyInstalled ( char * szUncompPath, char * szCompPath,
  1543. struct _tag * tagStruct,
  1544. // DWORD * numBytes,
  1545. struct _ClusterSizes * freshBytes,
  1546. struct _ClusterSizes * localSrcBytes,
  1547. struct _ClusterSizes * textModeBytes ) {
  1548. int i;
  1549. char szCompressedName[MFL];
  1550. char szPath[MFL];
  1551. //*numBytes = 0;
  1552. #define _h1K 512
  1553. #define _1K 1*1024
  1554. #define _2K 2*1024
  1555. #define _4K 4*1024
  1556. #define _8K 8*1024
  1557. #define _16K 16*1024
  1558. #define _32K 32*1024
  1559. #define _64K 64*1024
  1560. #define _128K 128*1024
  1561. #define _256K 256*1024
  1562. freshBytes->Kh1 = 0;
  1563. freshBytes->K1 = 0;
  1564. freshBytes->K2 = 0;
  1565. freshBytes->K4 = 0;
  1566. freshBytes->K8 = 0;
  1567. freshBytes->K16 = 0;
  1568. freshBytes->K32 = 0;
  1569. freshBytes->K64 = 0;
  1570. freshBytes->K128 = 0;
  1571. freshBytes->K256 = 0;
  1572. localSrcBytes->Kh1 = 0;
  1573. localSrcBytes->K1 = 0;
  1574. localSrcBytes->K2 = 0;
  1575. localSrcBytes->K4 = 0;
  1576. localSrcBytes->K8 = 0;
  1577. localSrcBytes->K16 = 0;
  1578. localSrcBytes->K32 = 0;
  1579. localSrcBytes->K64 = 0;
  1580. localSrcBytes->K128 = 0;
  1581. localSrcBytes->K256 = 0;
  1582. textModeBytes->Kh1 = 0;
  1583. textModeBytes->K1 = 0;
  1584. textModeBytes->K2 = 0;
  1585. textModeBytes->K4 = 0;
  1586. textModeBytes->K8 = 0;
  1587. textModeBytes->K16 = 0;
  1588. textModeBytes->K32 = 0;
  1589. textModeBytes->K64 = 0;
  1590. textModeBytes->K128 = 0;
  1591. textModeBytes->K256 = 0;
  1592. for ( i = 0; i < tagStruct->wNumFiles; ++i ) {
  1593. WIN32_FIND_DATA wfd;
  1594. HANDLE hFind;
  1595. // Don't add in space requirements for files in media.inx, since
  1596. // these files are NEVER installed.
  1597. //
  1598. if ( !tagStruct->bCountBytes[i] ) {
  1599. Msg ( "Warning: not going to count bytes for: %s\n", tagStruct->wcFilesArray[i] );
  1600. continue;
  1601. }
  1602. sprintf ( szPath, "%s\\%s", szUncompPath, tagStruct->wcFilesArray[i] );
  1603. // Need to find out space for .cab files contents.
  1604. //
  1605. if ( strstr ( szPath, ".cab" ) ||
  1606. strstr ( szPath, ".CAB" ) ) {
  1607. Msg ( "JOEHOL >>> get .cab contents filesizes for: %s\n", szPath );
  1608. }
  1609. // Calculate the installed system space required.
  1610. // This is the stuff installed into the %SYSTEMDIR% and all the other stuff
  1611. // uncompressed on the harddrive.
  1612. // This value will include the driver.cab, plus all the other files, since we
  1613. // assume worst case scenario.
  1614. //
  1615. hFind = FindFirstFile ( szPath, &wfd );
  1616. if ( hFind == INVALID_HANDLE_VALUE ) {
  1617. if ( strstr ( szPath, "desktop.ini" ) ||
  1618. strstr ( szPath, "DESKTOP.INI" ) ) {
  1619. // Build lab sometimes doesn't put the uncompressed
  1620. // file on the release shares, say the file is 512 bytes.
  1621. //
  1622. #define MAX_SETUP_CLUSTER_SIZE 32*1024
  1623. //*numBytes += ROUNDUP2 ( 512, MAX_SETUP_CLUSTER_SIZE );
  1624. freshBytes->Kh1 += ROUNDUP2 ( 512, _h1K );
  1625. freshBytes->K1 += ROUNDUP2 ( 512, _1K );
  1626. freshBytes->K2 += ROUNDUP2 ( 512, _2K );
  1627. freshBytes->K4 += ROUNDUP2 ( 512, _4K );
  1628. freshBytes->K8 += ROUNDUP2 ( 512, _8K );
  1629. freshBytes->K16 += ROUNDUP2 ( 512, _16K );
  1630. freshBytes->K32 += ROUNDUP2 ( 512, _32K );
  1631. freshBytes->K64 += ROUNDUP2 ( 512, _64K );
  1632. freshBytes->K128+= ROUNDUP2 ( 512, _128K );
  1633. freshBytes->K256+= ROUNDUP2 ( 512, _256K );
  1634. }
  1635. else
  1636. if ( strstr ( szPath, "WINNT32.EXE" ) ||
  1637. strstr ( szPath, "winnt32.exe" ) ||
  1638. strstr ( szPath, "winnt32a.dll" ) ||
  1639. strstr ( szPath, "winnt32u.dll" ) ||
  1640. strstr ( szPath, "WINNT32A.DLL" ) ||
  1641. strstr ( szPath, "WINNT32U.DLL" ) ||
  1642. strstr ( szPath, "WINNT32.HLP" ) ||
  1643. strstr ( szPath, "winnt32.hlp" ) ) {
  1644. char tmpSrcPath[MFL];
  1645. strcpy ( tmpSrcPath, szPath );
  1646. if ( strstr ( tmpSrcPath, ".HLP" ) ||
  1647. strstr ( tmpSrcPath, ".hlp" ) ) {
  1648. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 4 ], "\\WINNT32.HLP" );
  1649. }
  1650. else if ( strstr ( tmpSrcPath, "a.dll" ) ||
  1651. strstr ( tmpSrcPath, "A.DLL" ) ) {
  1652. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 5 ], "\\WINNT32a.dll" );
  1653. }
  1654. else if ( strstr ( tmpSrcPath, "u.dll" ) ||
  1655. strstr ( tmpSrcPath, "U.DLL" ) ) {
  1656. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 5 ], "\\WINNT32u.dll" );
  1657. }
  1658. else {
  1659. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 4 ], "\\WINNT32.EXE" );
  1660. }
  1661. hFind = FindFirstFile ( tmpSrcPath, &wfd );
  1662. if ( hFind == INVALID_HANDLE_VALUE ) {
  1663. Msg ( "ERROR Tally: FindFirstFile %s(%s), gle = %ld\n", szPath, tmpSrcPath, GetLastError() );
  1664. }
  1665. }
  1666. else {
  1667. Msg ( "ERROR Tally: FindFirstFile %s, gle = %ld\n", szPath, GetLastError() );
  1668. }
  1669. }
  1670. else {
  1671. // NOTE: .PNF files are made by the PNP system
  1672. // during Gui-mode setup, and are NOT listed anywhere.
  1673. // These files are compiled inf files.
  1674. // They are generally 2-3 times
  1675. // bigger than their associated .INF file.
  1676. // So, if we see and .INF file, increase it's size by
  1677. // 3 times. We need to do this, because in a low disk
  1678. // space situation, a .PNF file could be made and take
  1679. // up all the space.
  1680. //
  1681. if ( strstr ( szPath, ".INF" ) ||
  1682. strstr ( szPath, ".inf" ) ) {
  1683. wfd.nFileSizeLow *= 3;
  1684. Msg ( "Warning .PNF - %d\n %s\n", wfd.nFileSizeLow, szPath );
  1685. }
  1686. //*numBytes += ROUNDUP2 ( wfd.nFileSizeLow, MAX_SETUP_CLUSTER_SIZE );
  1687. freshBytes->Kh1 += ROUNDUP2 ( wfd.nFileSizeLow, _h1K );
  1688. freshBytes->K1 += ROUNDUP2 ( wfd.nFileSizeLow, _1K );
  1689. freshBytes->K2 += ROUNDUP2 ( wfd.nFileSizeLow, _2K );
  1690. freshBytes->K4 += ROUNDUP2 ( wfd.nFileSizeLow, _4K );
  1691. freshBytes->K8 += ROUNDUP2 ( wfd.nFileSizeLow, _8K );
  1692. freshBytes->K16 += ROUNDUP2 ( wfd.nFileSizeLow, _16K );
  1693. freshBytes->K32 += ROUNDUP2 ( wfd.nFileSizeLow, _32K );
  1694. freshBytes->K64 += ROUNDUP2 ( wfd.nFileSizeLow, _64K );
  1695. freshBytes->K128+= ROUNDUP2 ( wfd.nFileSizeLow, _128K );
  1696. freshBytes->K256+= ROUNDUP2 ( wfd.nFileSizeLow, _256K );
  1697. FindClose ( hFind );
  1698. //Msg ( "%s = %ld\n", szPath, *numBytes );
  1699. }
  1700. // Calculate the local space required.
  1701. //
  1702. //
  1703. // NOTE: If we don't copy this file to the CD, ie. it is in the driver.cab
  1704. // file, then we don't need to add it's space into the values here,
  1705. // since once counted for the driver.cab file itself is OK.
  1706. //
  1707. if ( !tagStruct->bCopyItToCD[i] ) {
  1708. Msg ( "Already in CAB file, won't add in space for local source: %s\n",
  1709. tagStruct->wcFilesArray[i] );
  1710. continue;
  1711. }
  1712. if ( tagStruct->bCopyComp[i] ) {
  1713. char szCompressedName[MFL];
  1714. MakeCompName ( tagStruct->wcFilesArray[i], szCompressedName );
  1715. sprintf ( szPath, "%s\\%s", szCompPath, szCompressedName );
  1716. }
  1717. else {
  1718. sprintf ( szPath, "%s\\%s", szUncompPath, tagStruct->wcFilesArray[i] );
  1719. }
  1720. hFind = FindFirstFile ( szPath, &wfd );
  1721. if ( hFind == INVALID_HANDLE_VALUE ) {
  1722. if ( strstr ( szPath, "WINNT32.EXE" ) ||
  1723. strstr ( szPath, "winnt32.exe" ) ||
  1724. strstr ( szPath, "winnt32a.dll" ) ||
  1725. strstr ( szPath, "winnt32u.dll" ) ||
  1726. strstr ( szPath, "WINNT32A.DLL" ) ||
  1727. strstr ( szPath, "WINNT32U.DLL" ) ||
  1728. strstr ( szPath, "WINNT32.HLP" ) ||
  1729. strstr ( szPath, "winnt32.hlp" ) ) {
  1730. char tmpSrcPath[MFL];
  1731. strcpy ( tmpSrcPath, szPath );
  1732. if ( strstr ( tmpSrcPath, ".HLP" ) ||
  1733. strstr ( tmpSrcPath, ".hlp" ) ) {
  1734. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 4 ], "\\WINNT32.HLP" );
  1735. }
  1736. else if ( strstr ( tmpSrcPath, "a.dll" ) ||
  1737. strstr ( tmpSrcPath, "A.DLL" ) ) {
  1738. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 5 ], "\\WINNT32a.dll" );
  1739. }
  1740. else if ( strstr ( tmpSrcPath, "u.dll" ) ||
  1741. strstr ( tmpSrcPath, "U.DLL" ) ) {
  1742. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 5 ], "\\WINNT32u.dll" );
  1743. }
  1744. else {
  1745. strcpy ( &tmpSrcPath[ strlen(tmpSrcPath) - 4 ], "\\WINNT32.EXE" );
  1746. }
  1747. hFind = FindFirstFile ( tmpSrcPath, &wfd );
  1748. if ( hFind == INVALID_HANDLE_VALUE ) {
  1749. Msg ( "ERROR Tally: FindFirstFile %s(%s), gle = %ld\n", szPath, tmpSrcPath, GetLastError() );
  1750. }
  1751. }
  1752. else {
  1753. Msg ( "ERROR Tally: FindFirstFile %s, gle = %ld\n", szPath, GetLastError() );
  1754. }
  1755. }
  1756. else {
  1757. // For each cluster size, add in the files bytes
  1758. // used in the ~ls directory.
  1759. //
  1760. localSrcBytes->Kh1 += ROUNDUP2 ( wfd.nFileSizeLow, _h1K );
  1761. localSrcBytes->K1 += ROUNDUP2 ( wfd.nFileSizeLow, _1K );
  1762. localSrcBytes->K2 += ROUNDUP2 ( wfd.nFileSizeLow, _2K );
  1763. localSrcBytes->K4 += ROUNDUP2 ( wfd.nFileSizeLow, _4K );
  1764. localSrcBytes->K8 += ROUNDUP2 ( wfd.nFileSizeLow, _8K );
  1765. localSrcBytes->K16 += ROUNDUP2 ( wfd.nFileSizeLow, _16K );
  1766. localSrcBytes->K32 += ROUNDUP2 ( wfd.nFileSizeLow, _32K );
  1767. localSrcBytes->K64 += ROUNDUP2 ( wfd.nFileSizeLow, _64K );
  1768. localSrcBytes->K128+= ROUNDUP2 ( wfd.nFileSizeLow, _128K );
  1769. localSrcBytes->K256+= ROUNDUP2 ( wfd.nFileSizeLow, _256K );
  1770. //Msg ( "localSrc32: %s, size=%ld, roundupsize=%ld, total32K=%ld\n", szPath, wfd.nFileSizeLow, ROUNDUP2(wfd.nFileSizeLow,_32K),localSrcBytes->K32 );
  1771. /***
  1772. if (hack){
  1773. char buf[MFL];
  1774. sprintf ( buf, "copy %s d:\\myLS", szPath );
  1775. Msg ( "thecopy: %s\n", buf );
  1776. system ( buf );
  1777. }
  1778. ***/
  1779. FindClose ( hFind );
  1780. // For the special marketing calculation number, if a
  1781. // file for a single partition installation using the ~ls
  1782. // directory, add in the file's bytes that will actually
  1783. // turn into free disk space.
  1784. //
  1785. if ( tagStruct->bTextMode[i] ) {
  1786. textModeBytes->Kh1 += ROUNDUP2 ( wfd.nFileSizeLow, _h1K );
  1787. textModeBytes->K1 += ROUNDUP2 ( wfd.nFileSizeLow, _1K );
  1788. textModeBytes->K2 += ROUNDUP2 ( wfd.nFileSizeLow, _2K );
  1789. textModeBytes->K4 += ROUNDUP2 ( wfd.nFileSizeLow, _4K );
  1790. textModeBytes->K8 += ROUNDUP2 ( wfd.nFileSizeLow, _8K );
  1791. textModeBytes->K16 += ROUNDUP2 ( wfd.nFileSizeLow, _16K );
  1792. textModeBytes->K32 += ROUNDUP2 ( wfd.nFileSizeLow, _32K );
  1793. textModeBytes->K64 += ROUNDUP2 ( wfd.nFileSizeLow, _64K );
  1794. textModeBytes->K128+= ROUNDUP2 ( wfd.nFileSizeLow, _128K );
  1795. textModeBytes->K256+= ROUNDUP2 ( wfd.nFileSizeLow, _256K );
  1796. //Msg ( "tagStruct->bTextMode TRUE for: %s, %ld\n", tagStruct->wcFilesArray[i], textModeBytes->K32 );
  1797. }
  1798. else {
  1799. //Msg ( "tagStruct->bTextMode FALSE for: %s\n", tagStruct->wcFilesArray[i]);
  1800. }
  1801. }
  1802. // ShowFreshLocalSpace ( tagStruct->wcFilesArray[i], freshBytes->K32, localSrcBytes->K32 );
  1803. }
  1804. }
  1805. DWORD GetTheSize ( const char * szPath, const char * szKey ) {
  1806. FILE * fHandle;
  1807. char Line[MFL];
  1808. Msg ( "GetTheSize: szPath = %s\n", szPath );
  1809. fHandle = fopen ( szPath, "rt" );
  1810. if ( fHandle ) {
  1811. while ( fgets ( Line, sizeof(Line), fHandle ) ) {
  1812. if ( strncmp ( Line, szKey, strlen(szKey)-1 ) == 0 ) {
  1813. char * LinePtr = Line;
  1814. Msg ( "key Line: %s\n", Line );
  1815. // First, find the equal sign.
  1816. //
  1817. LinePtr = strstr ( Line, "=" );
  1818. // Now, find the first character that is a number.
  1819. //
  1820. while ( isdigit(*LinePtr) == 0 ) {
  1821. ++LinePtr;
  1822. }
  1823. Msg ( "# = %s\n", LinePtr );
  1824. fclose ( fHandle );
  1825. return ( atoi ( LinePtr ) );
  1826. }
  1827. }
  1828. Msg ( "GetTheSize: Couldn't find key: %s\n", szKey );
  1829. fclose ( fHandle );
  1830. }
  1831. else {
  1832. Msg ( "GetTheSize: Couldn't fopen (%s)\n", szPath );
  1833. }
  1834. return 0;
  1835. }
  1836. void ShowCheckFreshSpace ( struct _ClusterSizes * Section, char * String, char * netServer ) {
  1837. DWORD dwSize = 0;
  1838. #define OHPROBLEM "problem"
  1839. char returnedString[MFL];
  1840. #define SD "DiskSpaceRequirements"
  1841. char sifFile[MFL];
  1842. char rS512[MFL];
  1843. char rS1[MFL];
  1844. char rS2[MFL];
  1845. char rS4[MFL];
  1846. char rS8[MFL];
  1847. char rS16[MFL];
  1848. char rS32[MFL];
  1849. char rS64[MFL];
  1850. char rS128[MFL];
  1851. char rS256[MFL];
  1852. ULONG dwSize512;
  1853. ULONG dwSize1;
  1854. ULONG dwSize2;
  1855. ULONG dwSize4;
  1856. ULONG dwSize8;
  1857. ULONG dwSize16;
  1858. ULONG dwSize32;
  1859. ULONG dwSize64;
  1860. ULONG dwSize128;
  1861. ULONG dwSize256;
  1862. sprintf ( sifFile, "%s\\txtsetup.sif", netServer );
  1863. Msg ( "TxtSetup.Sif location: %s\n", sifFile );
  1864. Msg ( "Clyde: SPACE REQUIRED TO DO A FRESH INSTALL.\n" );
  1865. Msg ( "Clyde:\n" );
  1866. Msg ( "Clyde: %s 512 Cluster = %ld\n", String, Section->Kh1 );
  1867. Msg ( "Clyde: %s 1K Cluster = %ld\n", String, Section->K1 );
  1868. Msg ( "Clyde: %s 2K Cluster = %ld\n", String, Section->K2 );
  1869. Msg ( "Clyde: %s 4K Cluster = %ld\n", String, Section->K4 );
  1870. Msg ( "Clyde: %s 8K Cluster = %ld\n", String, Section->K8 );
  1871. Msg ( "Clyde: %s 16K Cluster = %ld\n", String, Section->K16 );
  1872. Msg ( "Clyde: %s 32K Cluster = %ld\n", String, Section->K32 );
  1873. Msg ( "Clyde: %s 64K Cluster = %ld\n", String, Section->K64 );
  1874. Msg ( "Clyde: %s 128K Cluster = %ld\n", String, Section->K128 );
  1875. Msg ( "Clyde: %s 256K Cluster = %ld\n", String, Section->K256 );
  1876. Msg ( "Clyde:\n" );
  1877. #define FUDGE_PLUS 4*1024*1024 // ie, grow by 4 M for future growth.
  1878. GetPrivateProfileString ( SD, "WinDirSpace512", "0", rS512, MFL, sifFile );
  1879. GetPrivateProfileString ( SD, "WinDirSpace1K", "0", rS1, MFL, sifFile );
  1880. GetPrivateProfileString ( SD, "WinDirSpace2K", "0", rS2, MFL, sifFile );
  1881. GetPrivateProfileString ( SD, "WinDirSpace4K", "0", rS4, MFL, sifFile );
  1882. GetPrivateProfileString ( SD, "WinDirSpace8K", "0", rS8, MFL, sifFile );
  1883. GetPrivateProfileString ( SD, "WinDirSpace16K", "0", rS16, MFL, sifFile );
  1884. GetPrivateProfileString ( SD, "WinDirSpace32K", "0", rS32, MFL, sifFile );
  1885. GetPrivateProfileString ( SD, "WinDirSpace64K", "0", rS64, MFL, sifFile );
  1886. GetPrivateProfileString ( SD, "WinDirSpace128K","0", rS128, MFL, sifFile );
  1887. GetPrivateProfileString ( SD, "WinDirSpace256K","0", rS256, MFL, sifFile );
  1888. dwSize512 = atoi ( rS512 ) * 1024;
  1889. dwSize1 = atoi ( rS1 ) * 1024;
  1890. dwSize2 = atoi ( rS2 ) * 1024;
  1891. dwSize4 = atoi ( rS4 ) * 1024;
  1892. dwSize8 = atoi ( rS8 ) * 1024;
  1893. dwSize16 = atoi ( rS16 ) * 1024;
  1894. dwSize32 = atoi ( rS32 ) * 1024;
  1895. dwSize64 = atoi ( rS64 ) * 1024;
  1896. dwSize128 = atoi ( rS128) * 1024;
  1897. dwSize256 = atoi ( rS256) * 1024;
  1898. if ( Section->Kh1 > dwSize512 ) {
  1899. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace512 value is %ld Use: %ld\n", String, dwSize512, (Section->Kh1 + FUDGE_PLUS) / 1024 );
  1900. }
  1901. if ( Section->K1 > dwSize1 ) {
  1902. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace1K value is %ld Use: %ld\n", String, dwSize1, (Section->K1 + FUDGE_PLUS) / 1024 );
  1903. }
  1904. if ( Section->K2 > dwSize2 ) {
  1905. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace2K value is %ld Use: %ld\n", String, dwSize2, (Section->K2 + FUDGE_PLUS) / 1024 );
  1906. }
  1907. if ( Section->K4 > dwSize4 ) {
  1908. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace4K value is %ld Use: %ld\n", String, dwSize4, (Section->K4 + FUDGE_PLUS) / 1024 );
  1909. }
  1910. if ( Section->K8 > dwSize8 ) {
  1911. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace8K value is %ld Use: %ld\n", String, dwSize8, (Section->K8 + FUDGE_PLUS) / 1024 );
  1912. }
  1913. if ( Section->K16 > dwSize16 ) {
  1914. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace16K value is %ld Use: %ld\n", String, dwSize16, (Section->K16 + FUDGE_PLUS) / 1024 );
  1915. }
  1916. if ( Section->K32 > dwSize32 ) {
  1917. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace32K value is %ld Use: %ld\n", String, dwSize32, (Section->K32 + FUDGE_PLUS) / 1024 );
  1918. }
  1919. if ( Section->K64 > dwSize64 ) {
  1920. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace64K value is %ld Use: %ld\n", String, dwSize64, (Section->K64 + FUDGE_PLUS) / 1024 );
  1921. }
  1922. if ( Section->K128 > dwSize128 ) {
  1923. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace128K value is %ld Use: %ld\n", String, dwSize128, (Section->K128 + FUDGE_PLUS) / 1024 );
  1924. }
  1925. if ( Section->K256 > dwSize256 ) {
  1926. Msg ( "matth ERROR: %s txtsetup.sif's WinDirSpace256K value is %ld Use: %ld\n", String, dwSize256, (Section->K256 + FUDGE_PLUS) / 1024 );
  1927. }
  1928. }
  1929. void EnoughTempDirSpace ( char * Key, DWORD dwSpaceNeeded, char * String, char * dosnetFile ) {
  1930. DWORD dwSize = 0;
  1931. #define OHPROBLEM "problem"
  1932. #define SP "DiskSpaceRequirements"
  1933. char returnedString[MFL];
  1934. GetPrivateProfileString ( SP, Key, OHPROBLEM, returnedString, MFL, dosnetFile );
  1935. if ( strncmp ( returnedString, OHPROBLEM, sizeof ( OHPROBLEM ) ) == 0 ) {
  1936. Msg ( "ERROR: %d section not found\n", Key );
  1937. }
  1938. dwSize = atoi ( returnedString );
  1939. if ( dwSpaceNeeded > dwSize ) {
  1940. Msg ( "matth ERROR: %s dosnet.inf's %s value is %ld Use: %ld\n", String, Key, dwSize, dwSpaceNeeded + FUDGE_PLUS );
  1941. }
  1942. if ( dwSpaceNeeded+FUDGE_PLUS < dwSize ) {
  1943. Msg ( "matth ERROR - let's optimize(reduce)!: %s dosnet.inf's %s value is %ld Use: %ld\n", String, Key, dwSize, dwSpaceNeeded + FUDGE_PLUS );
  1944. }
  1945. }
  1946. void ShowCheckLocalSpace ( struct _ClusterSizes * Section, char * String, char * netServer ) {
  1947. char dosnetFile[MFL];
  1948. sprintf ( dosnetFile, "%s\\dosnet.inf", netServer );
  1949. Msg ( "Dosnet.Inf location: %s\n", dosnetFile );
  1950. Msg ( "Clyde: SPACE REQUIRED TO COPY FILES TO LOCAL DRIVE FROM CD.\n" );
  1951. Msg ( "Clyde:\n" );
  1952. Msg ( "Clyde: %s 512 Cluster = %ld\n", String, (8*1024*1024) );
  1953. Msg ( "Clyde: %s 1K Cluster = %ld\n", String, (8*1024*1024) );
  1954. Msg ( "Clyde: %s 2K Cluster = %ld\n", String, (8*1024*1024) );
  1955. Msg ( "Clyde: %s 4K Cluster = %ld\n", String, (8*1024*1024) );
  1956. Msg ( "Clyde: %s 8K Cluster = %ld\n", String, (8*1024*1024) );
  1957. Msg ( "Clyde: %s 16K Cluster = %ld\n", String, (8*1024*1024) );
  1958. Msg ( "Clyde: %s 32K Cluster = %ld\n", String, (8*1024*1024) );
  1959. Msg ( "Clyde: %s 64K Cluster = %ld\n", String, (8*1024*1024) ) ;
  1960. Msg ( "Clyde: %s 128K Cluster = %ld\n", String, (8*1024*1024) );
  1961. Msg ( "Clyde: %s 256K Cluster = %ld\n", String, (8*1024*1024) );
  1962. Msg ( "Clyde:\n" );
  1963. Msg ( "Clyde: SPACE REQUIRED TO COPY FILES TO LOCAL DRIVE FROM NETWORK.\n" );
  1964. Msg ( "Clyde:\n" );
  1965. // Note: this 8*1024*1024 is the ~bt space - 8M is average today.
  1966. // But, to be more accurate we could get the value from the inf.
  1967. //
  1968. Msg ( "Clyde: %s 512 Cluster = %ld\n", String, Section->Kh1+(8*1024*1024) );
  1969. Msg ( "Clyde: %s 1K Cluster = %ld\n", String, Section->K1+(8*1024*1024) );
  1970. Msg ( "Clyde: %s 2K Cluster = %ld\n", String, Section->K2+(8*1024*1024) );
  1971. Msg ( "Clyde: %s 4K Cluster = %ld\n", String, Section->K4+(8*1024*1024) );
  1972. Msg ( "Clyde: %s 8K Cluster = %ld\n", String, Section->K8+(8*1024*1024) );
  1973. Msg ( "Clyde: %s 16K Cluster = %ld\n", String, Section->K16+(8*1024*1024) );
  1974. Msg ( "Clyde: %s 32K Cluster = %ld\n", String, Section->K32+(8*1024*1024) );
  1975. Msg ( "Clyde: %s 64K Cluster = %ld\n", String, Section->K64+(8*1024*1024) ) ;
  1976. Msg ( "Clyde: %s 128K Cluster = %ld\n", String, Section->K128+(8*1024*1024) );
  1977. Msg ( "Clyde: %s 256K Cluster = %ld\n", String, Section->K256+(8*1024*1024) );
  1978. Msg ( "Clyde:\n" );
  1979. EnoughTempDirSpace ( "TempDirSpace512", Section->Kh1, String, dosnetFile );
  1980. EnoughTempDirSpace ( "TempDirSpace1K", Section->K1, String, dosnetFile );
  1981. EnoughTempDirSpace ( "TempDirSpace2K", Section->K2, String, dosnetFile );
  1982. EnoughTempDirSpace ( "TempDirSpace4K", Section->K4, String, dosnetFile );
  1983. EnoughTempDirSpace ( "TempDirSpace8K", Section->K8, String, dosnetFile );
  1984. EnoughTempDirSpace ( "TempDirSpace16K", Section->K16, String, dosnetFile );
  1985. EnoughTempDirSpace ( "TempDirSpace32K", Section->K32, String, dosnetFile );
  1986. EnoughTempDirSpace ( "TempDirSpace64K", Section->K64, String, dosnetFile );
  1987. EnoughTempDirSpace ( "TempDirSpace128K",Section->K128,String, dosnetFile );
  1988. EnoughTempDirSpace ( "TempDirSpace256K",Section->K256,String, dosnetFile );
  1989. }
  1990. void ClydeR ( char * String, char * desString, DWORD dwFresh, DWORD dwLocal, DWORD dwTextMode ) {
  1991. DWORD dwPageFile = 0;
  1992. DWORD dwLocalSource = 0;
  1993. DWORD dwFreshInstall = 0;
  1994. DWORD dwTextModeSavings = 0;
  1995. DWORD dwTotal = 0;
  1996. DWORD dwLocalBoot = 0;
  1997. #define LOCAL_BOOT 8*1024*1024
  1998. DWORD dwMigrationDlls = 0;
  1999. DWORD MigrationDllsK32 = 24*1024*1024; // as of 12.11.98
  2000. DWORD dwOsSizeDiff = 0;
  2001. DWORD dwCacheDelete = 0;
  2002. Msg ( "Clyde: %s Scenario 1 - Fresh install using CD (CD-boot or with floppies) on a blank machine on a 1 partition %s cluster drive.\n", String, desString );
  2003. dwPageFile = (64+11) * 1024 * 1024;
  2004. dwFreshInstall = dwFresh;
  2005. dwTotal = dwPageFile + dwFreshInstall;
  2006. Msg ( "Clyde: Pagefile for 64M RAM = %ld\n", dwPageFile );
  2007. Msg ( "Clyde: Fresh install = %ld\n", dwFreshInstall );
  2008. Msg ( "Clyde: \n" );
  2009. Msg ( "Clyde: TOTAL Space Required = %ld\n", dwTotal );
  2010. Msg ( "Clyde: \n" );
  2011. Msg ( "Clyde: \n" );
  2012. Msg ( "Clyde: %s Scenario 2 - Fresh Install Using Winnt32 (on Win9x or NT) and a CD on a 1 partition %s cluster drive.\n", String, desString );
  2013. dwPageFile = (64+11) * 1024 * 1024;
  2014. dwFreshInstall = dwFresh;
  2015. dwLocalBoot = LOCAL_BOOT;
  2016. dwTotal = dwPageFile + dwFreshInstall + dwLocalBoot;
  2017. Msg ( "Clyde: Pagefile for 64M RAM = %ld\n", dwPageFile );
  2018. Msg ( "Clyde: Local boot = %ld\n", dwLocalBoot );
  2019. Msg ( "Clyde: Fresh install = %ld\n", dwFreshInstall );
  2020. Msg ( "Clyde: \n" );
  2021. Msg ( "Clyde: TOTAL Space Required = %ld\n", dwTotal );
  2022. Msg ( "Clyde: \n" );
  2023. Msg ( "Clyde: \n" );
  2024. Msg ( "Clyde: %s Scenario 3 - Fresh Install Using Winnt32 (on Win9x or NT) over the network on a 1 partition %s cluster drive.\n", String, desString );
  2025. dwPageFile = (64+11) * 1024 * 1024;
  2026. dwLocalSource = dwLocal;
  2027. dwFreshInstall = dwFresh;
  2028. dwTextModeSavings = dwTextMode;
  2029. dwLocalBoot = LOCAL_BOOT;
  2030. dwTotal = dwPageFile + dwLocalSource + dwFreshInstall + dwLocalBoot - dwTextModeSavings;
  2031. Msg ( "Clyde: Pagefile for 64M RAM = %ld\n", dwPageFile );
  2032. Msg ( "Clyde: Local source = %ld\n", dwLocalSource );
  2033. Msg ( "Clyde: Fresh install = %ld\n", dwFreshInstall );
  2034. Msg ( "Clyde: TextMode savings = %ld\n", dwTextModeSavings );
  2035. Msg ( "Clyde: Local boot = %ld\n", dwLocalBoot );
  2036. Msg ( "Clyde: \n" );
  2037. Msg ( "Clyde: TOTAL Space Required = %ld\n", dwTotal );
  2038. Msg ( "Clyde: \n" );
  2039. Msg ( "Clyde: \n" );
  2040. Msg ( "Clyde: %s Scenario 4 - Upgrade using Winnt32 (on NT 4.0 Workstation) and a CD on a 1 partition %s cluster drive.\n", String, desString );
  2041. dwFreshInstall = dwFresh;
  2042. dwOsSizeDiff = x86From400;
  2043. dwLocalBoot = LOCAL_BOOT;
  2044. dwCacheDelete = 0;
  2045. dwTotal = dwFreshInstall - dwOsSizeDiff + dwLocalBoot - dwCacheDelete;
  2046. Msg ( "Clyde: Fresh install = %ld\n", dwFreshInstall );
  2047. Msg ( "Clyde: OsSizeDiff = %ld\n", dwOsSizeDiff );
  2048. Msg ( "Clyde: Local Boot = %ld\n", dwLocalBoot );
  2049. Msg ( "Clyde: Cache Delete = %ld\n", dwCacheDelete );
  2050. Msg ( "Clyde: \n" );
  2051. Msg ( "Clyde: TOTAL Space Required = %ld\n", dwTotal );
  2052. Msg ( "Clyde: \n" );
  2053. Msg ( "Clyde: \n" );
  2054. Msg ( "Clyde: %s Scenario 5 - Upgrade using Winnt32 (on NT 4.0 Workstation) over the network on a 1 partition %s cluster drive.\n", String, desString );
  2055. dwFreshInstall = dwFresh;
  2056. dwOsSizeDiff = x86From400;
  2057. dwLocalBoot = LOCAL_BOOT;
  2058. dwLocalSource = dwLocal;
  2059. dwCacheDelete = 0;
  2060. dwTotal = dwFreshInstall - dwOsSizeDiff + dwLocalBoot + dwLocalSource - dwCacheDelete;
  2061. Msg ( "Clyde: Fresh install = %ld\n", dwFreshInstall );
  2062. Msg ( "Clyde: OsSizeDiff = %ld\n", dwOsSizeDiff );
  2063. Msg ( "Clyde: Local Boot = %ld\n", dwLocalBoot );
  2064. Msg ( "Clyde: Local Source = %ld\n", dwLocalSource );
  2065. Msg ( "Clyde: Cache Delete = %ld\n", dwCacheDelete );
  2066. Msg ( "Clyde: \n" );
  2067. Msg ( "Clyde: TOTAL Space Required = %ld\n", dwTotal );
  2068. Msg ( "Clyde: \n" );
  2069. Msg ( "Clyde: \n" );
  2070. Msg ( "Clyde: %s Scenario 6 - Upgrade using Winnt32 (on Win9x) and a CD on a 1 partition %s cluster drive.\n", String, desString );
  2071. dwPageFile = (64+11) * 1024 * 1024;
  2072. dwFreshInstall = dwFresh;
  2073. dwLocalBoot = LOCAL_BOOT;
  2074. dwMigrationDlls = MigrationDllsK32;
  2075. dwCacheDelete = 0;
  2076. dwTotal = dwPageFile + dwFreshInstall + dwLocalBoot + dwMigrationDlls - dwCacheDelete;
  2077. Msg ( "Clyde: Pagefile for 64M RAM = %ld\n", dwPageFile );
  2078. Msg ( "Clyde: Fresh install = %ld\n", dwFreshInstall );
  2079. Msg ( "Clyde: Local Boot = %ld\n", dwLocalBoot );
  2080. Msg ( "Clyde: Migration DLLs = %ld\n", dwMigrationDlls );
  2081. Msg ( "Clyde: Cache Delete = %ld\n", dwCacheDelete );
  2082. Msg ( "Clyde: \n" );
  2083. Msg ( "Clyde: TOTAL Space Required = %ld\n", dwTotal );
  2084. Msg ( "Clyde: \n" );
  2085. Msg ( "Clyde: \n" );
  2086. Msg ( "Clyde: %s Scenario 7 - Upgrade using Winnt32 (on Win9x) over the network on a 1 partition %s cluster drive.\n", String, desString );
  2087. dwPageFile = (64+11) * 1024 * 1024;
  2088. dwFreshInstall = dwFresh;
  2089. dwLocalBoot = LOCAL_BOOT;
  2090. dwMigrationDlls = MigrationDllsK32;
  2091. dwLocalSource = dwLocal;
  2092. dwCacheDelete = 0;
  2093. dwTotal = dwPageFile + dwFreshInstall + dwLocalBoot + dwMigrationDlls + dwLocalSource - dwCacheDelete;
  2094. Msg ( "Clyde: Pagefile for 64M RAM = %ld\n", dwPageFile );
  2095. Msg ( "Clyde: Fresh install = %ld\n", dwFreshInstall );
  2096. Msg ( "Clyde: Local Boot = %ld\n", dwLocalBoot );
  2097. Msg ( "Clyde: Migration DLLs = %ld\n", dwMigrationDlls );
  2098. Msg ( "Clyde: Local Source = %ld\n", dwLocalSource );
  2099. Msg ( "Clyde: Cache Delete = %ld\n", dwCacheDelete );
  2100. Msg ( "Clyde: \n" );
  2101. Msg ( "Clyde: TOTAL Space Required = %ld\n", dwTotal );
  2102. Msg ( "Clyde: \n" );
  2103. Msg ( "Clyde: \n" );
  2104. }
  2105. void ShowTextModeSpace ( struct _ClusterSizes * FreshInstall,
  2106. struct _ClusterSizes * LocalSource,
  2107. struct _ClusterSizes * TextModeSavings,
  2108. char * String ) {
  2109. Msg ( "Clyde: TEXTMODE SPACE.\n" );
  2110. Msg ( "Clyde:\n" );
  2111. Msg ( "Clyde: %s 512 Cluster = %ld\n", String, TextModeSavings->Kh1 );
  2112. Msg ( "Clyde: %s 1K Cluster = %ld\n", String, TextModeSavings->K1 );
  2113. Msg ( "Clyde: %s 2K Cluster = %ld\n", String, TextModeSavings->K2 );
  2114. Msg ( "Clyde: %s 4K Cluster = %ld\n", String, TextModeSavings->K4 );
  2115. Msg ( "Clyde: %s 8K Cluster = %ld\n", String, TextModeSavings->K8 );
  2116. Msg ( "Clyde: %s 16K Cluster = %ld\n", String, TextModeSavings->K16);
  2117. Msg ( "Clyde: %s 32K Cluster = %ld\n", String, TextModeSavings->K32);
  2118. Msg ( "Clyde: %s 64K Cluster = %ld\n", String, TextModeSavings->K64);
  2119. Msg ( "Clyde: %s 128K Cluster = %ld\n", String, TextModeSavings->K128);
  2120. Msg ( "Clyde: %s 256K Cluster = %ld\n", String, TextModeSavings->K256);
  2121. Msg ( "Clyde:\n" );
  2122. Msg ( "Clyde: SCENARIOS VALUES FOLLOW\n" );
  2123. Msg ( "Clyde: \n" );
  2124. Msg ( "Clyde: \n" );
  2125. ClydeR ( String, "512 byte", FreshInstall->Kh1, LocalSource->Kh1, TextModeSavings->Kh1 );
  2126. ClydeR ( String, "4K byte", FreshInstall->K4 , LocalSource->K4, TextModeSavings->K4 );
  2127. ClydeR ( String, "32K byte", FreshInstall->K32 , LocalSource->K32, TextModeSavings->K32 );
  2128. }
  2129. int __cdecl main(argc,argv)
  2130. int argc;
  2131. char * argv[];
  2132. {
  2133. HANDLE h;
  2134. int records, i;
  2135. WIN32_FIND_DATA fd;
  2136. time_t t;
  2137. DWORD dwSize;
  2138. char szFileName[MFL];
  2139. #define MAKE_NEC98 "MAKE_NEC98"
  2140. #define SKIP_AS "SKIP_AS"
  2141. #define SKIP_SRV "SKIP_SRV"
  2142. #define SKIP_DC "SKIP_DC"
  2143. if ( getenv ( MAKE_NEC98 ) != NULL ) {
  2144. bNec98 = TRUE;
  2145. if ( argc != 9 ) {
  2146. printf ( "NEC98 special...\n" );
  2147. printf ( "You specified %d arguments - you need 9.\n\n", argc );
  2148. for ( i = 0; i < argc; ++i ) {
  2149. printf ( "Argument #%d >>>%s<<<\n", i, argv[i] );
  2150. }
  2151. printf ( "\n\n" );
  2152. Usage();
  2153. return(1);
  2154. }
  2155. }
  2156. else {
  2157. if ( argc != 7 ) {
  2158. printf ( "You specified %d arguments - you need 7.\n\n", argc );
  2159. for ( i = 0; i < argc; ++i ) {
  2160. printf ( "Argument #%d >>>%s<<<\n", i, argv[i] );
  2161. }
  2162. printf ( "\n\n" );
  2163. Usage();
  2164. return(1);
  2165. }
  2166. }
  2167. // Initialize the critical section object.
  2168. //
  2169. InitializeCriticalSection ( &CriticalSection );
  2170. // Retail %platform% files.
  2171. //
  2172. ix386.wNumFiles = 0;
  2173. Nec98.wNumFiles = 0;
  2174. strcpy ( szLogFile, argv[1] );
  2175. strcpy ( szProductName, argv[2] );
  2176. strcpy ( szEnlistDrv, argv[3] );
  2177. strcpy ( szX86Src, argv[4] );
  2178. strcpy ( szX86DstDrv, argv[5] );
  2179. strcpy ( szUnCompX86, argv[6] );
  2180. if ( bNec98 ) {
  2181. strcpy ( szNec98Src, argv[7] );
  2182. strcpy ( szUnCompNec98, argv[8] );
  2183. }
  2184. logFile = fopen ( argv[1], "a" );
  2185. if ( logFile == NULL ) {
  2186. printf("ERROR Couldn't open log file: %s\n",argv[1]);
  2187. return(1);
  2188. }
  2189. // Do bit comparison to release shares on all copies ?
  2190. //
  2191. #define VERIFY_COPIES "VERIFY"
  2192. if ( getenv ( VERIFY_COPIES ) != NULL ) {
  2193. bVerifyBits = TRUE;
  2194. Msg ( "Will verify copies...\n" );
  2195. }
  2196. if ( getenv ( SKIP_SRV ) && strstr ( szProductName, "Server" ) ) {
  2197. Msg ( "Warning: skipping making Server product.\n" );
  2198. exit ( 0 );
  2199. }
  2200. if ( getenv ( SKIP_AS ) && strstr ( szProductName, "AdvancedServer" ) ) {
  2201. Msg ( "Warning: skipping making Advanced Server product.\n" );
  2202. exit ( 0 );
  2203. }
  2204. if ( getenv ( SKIP_DC ) && strstr ( szProductName, "DataCenter" ) ) {
  2205. Msg ( "Warning: skipping making Data Center product.\n" );
  2206. exit ( 0 );
  2207. }
  2208. if ( strstr ( szX86Src, "chk." ) ||
  2209. strstr ( szX86Src, "CHK." ) ) {
  2210. Msg ( "Warning: We believe this is a checked build script, thus, we'll put put .dbgs in CHECKED directory...\n" );
  2211. bChecked = TRUE;
  2212. }
  2213. else {
  2214. Msg ( "Warning: We believe this is a free build script, thus, we'll put put .dbgs in FREE directory...\n" );
  2215. bChecked = FALSE;
  2216. }
  2217. Header(argv,argc);
  2218. CreateDestinationDirs ();
  2219. // Get files that product installs.
  2220. //
  2221. bGetSizeLater = TRUE;
  2222. PlatformFilesToCopy ( szX86Src, X86_F );
  2223. if ( bNec98 ) {
  2224. bNec98LikeX86 = TRUE;
  2225. PlatformFilesToCopy ( szNec98Src, NEC98_F );
  2226. }
  2227. bGetSizeLater = FALSE;
  2228. // Get the files from _media.inx in
  2229. // C:\nt\private\windows\setup\bom directory.
  2230. //
  2231. GetTheFiles ( "C:\\nt\\private\\windows\\setup\\bom",
  2232. "_media.inx",
  2233. DBGS_AND_NON_INSTALLED );
  2234. //ShowX86();
  2235. //ShowNec98 ();
  2236. Msg ( "# files i386 = %ld\n", ix386.wNumFiles );
  2237. if ( bNec98 ) {
  2238. Msg ( "# files Nec98 = %ld\n", Nec98.wNumFiles );
  2239. }
  2240. // Make some threads and copy all the files.
  2241. //
  2242. CopyTheFiles();
  2243. //
  2244. // Don't tally anything for checked builds since the INF sizes are off, ie. retail.
  2245. //
  2246. if ( bChecked ) {
  2247. Msg ( "Warning: We have a checked build here and will not tally file space...\n" );
  2248. goto END_MAIN;
  2249. }
  2250. Msg ( "========= Minimum setup install bytes required (all files uncompressed): ==========\n" );
  2251. TallyInstalled ( szUnCompX86, szX86Src, &ix386, &freshX86, &lX86, &tX86 );
  2252. if ( bNec98 ) {
  2253. TallyInstalled ( szUnCompNec98, szNec98Src, &Nec98, &freshNec98, &lNec98, &tNec98 );
  2254. }
  2255. // Give tally counts.
  2256. //
  2257. ShowCheckFreshSpace ( &freshX86, "freshX86", szX86Src );
  2258. if ( bNec98 ) {
  2259. ShowCheckFreshSpace ( &freshNec98, "freshNec98", szNec98Src );
  2260. }
  2261. Msg ( "Clyde: FreshInstall->K32 = %ld\n", freshX86.K32 );
  2262. Msg ( "Clyde: TextModeSavings->K32 = %ld\n", tX86.K32 );
  2263. Msg ( "Clyde: Local->K32 = %ld\n", lX86.K32 );
  2264. Msg ( "========= Maximum setup local-source bytes required (some files compressed) : =====\n" );
  2265. ShowCheckLocalSpace ( &lX86, "lX86", szX86Src );
  2266. if ( bNec98 ) {
  2267. ShowCheckLocalSpace ( &lNec98, "lNec98", szNec98Src );
  2268. }
  2269. Msg ( "========= Special TextMode files space =====\n" );
  2270. ShowTextModeSpace ( &freshX86, &lX86, &tX86, "X86" );
  2271. if ( bNec98 ) {
  2272. ShowTextModeSpace ( &freshNec98, &lNec98, &tNec98, "Nec98" );
  2273. }
  2274. END_MAIN:;
  2275. Msg ( "==============================\n");
  2276. time(&t);
  2277. Msg ( "Time: %s", ctime(&t) );
  2278. Msg ( "==============================\n\n");
  2279. fclose(logFile);
  2280. return(777);
  2281. }