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.

708 lines
23 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* WFSYS.C - */
  4. /* */
  5. /* Routines for Making Bootable Floppies */
  6. /* */
  7. /****************************************************************************/
  8. #include "winfile.h"
  9. #include "winnet.h"
  10. #include "lfn.h"
  11. #include "wfcopy.h"
  12. #define CSYSFILES 3 /* Three system files are to be copied */
  13. #define SYSFILENAMELEN 16 /* Example "A:\????????.???\0" */
  14. #define SEEK_END 2 /* Used by _llseek() */
  15. /* Error Codes. NOTE: Don't change this order! */
  16. #define NOERROR 0 /* No error */
  17. #define NOMEMORY 1 /* Insufficient memory */
  18. #define NOSRCFILEBIOS 2 /* BIOS is missing */
  19. #define NOSRCFILEDOS 3 /* DOS is missing */
  20. #define NOSRCFILECMD 4 /* Command.Com is missing */
  21. #define COPYFILEBIOS 5 /* Error in copying BIOS */
  22. #define COPYFILEDOS 6 /* Error in copying DOS */
  23. #define COPYFILECMD 7 /* Error in copying Command.com */
  24. #define INVALIDBOOTSEC 8
  25. #define INVALIDDSTDRIVE 9
  26. #define DSTDISKERROR 10
  27. #define NOTSYSABLE 11 /* First N clusters are NOT empty */
  28. #define NOTSYSABLE1 12 /* First 2 entries in ROOT are not sys files */
  29. #define NOTSYSABLE2 13 /* First N clusters are not allocated to SYS files */
  30. #define NODISKSPACE 14 /* There is not sufficient disk space */
  31. #define BUFFSIZE 8192
  32. #define SECTORSIZE 512
  33. LONG SysFileSize[CSYSFILES];
  34. CHAR BIOSfile[SYSFILENAMELEN];
  35. CHAR DOSfile[SYSFILENAMELEN];
  36. CHAR COMMANDfile[130]; /* Command.com can have a full path name in COMSPEC= */
  37. CHAR *SysFileNamePtr[CSYSFILES]; /* Ptrs to source file names */
  38. /* SysNameTable contains the names of System files; First for PCDOS, the
  39. * second set for MSDOS.
  40. */
  41. CHAR *SysNameTable[2][3] = {
  42. {"IBMBIO.COM", "IBMDOS.COM", "COMMAND.COM"},
  43. {"IO.SYS", "MSDOS.SYS", "COMMAND.COM"}
  44. };
  45. BOOL
  46. IsSYSable(
  47. WORD iSrceDrive,
  48. WORD iDestDrive,
  49. CHAR DestFileNames[][SYSFILENAMELEN], /* NOTE: 2-dimensional array */
  50. LPSTR lpFileBuff
  51. );
  52. /*--------------------------------------------------------------------------*/
  53. /* */
  54. /* SameFilenames() - */
  55. /* */
  56. /*--------------------------------------------------------------------------*/
  57. /* This checks whether the two filenames are the same or not.
  58. * The problem lies in the fact that lpDirFileName points to the
  59. * filename as it appears in a directory (filename padded with blanks
  60. * up to eight characters and then followed by extension). But
  61. * szFileName is an ASCII string with no embedded blanks and has a
  62. * dot that seperates the extension from file name.
  63. */
  64. BOOL
  65. SameFilenames(
  66. LPSTR lpDirFileName,
  67. LPSTR szFileName
  68. )
  69. {
  70. INT i;
  71. CHAR c1;
  72. CHAR c2;
  73. /* lpDirFileName definitely has 11 characters (8+3). Nothing more!
  74. * Nothing less!
  75. */
  76. for (i=0; i < 11; i++) {
  77. c1 = *lpDirFileName++;
  78. c2 = *szFileName++;
  79. if (c2 == '.') {
  80. /* Skip all the blanks at the end of the filename */
  81. while (c1 == ' ' && i < 11) {
  82. c1 = *lpDirFileName++;
  83. i++;
  84. }
  85. c2 = *szFileName++;
  86. }
  87. if (c1 != c2)
  88. break;
  89. }
  90. return (i != 11);
  91. }
  92. /*--------------------------------------------------------------------------*/
  93. /* */
  94. /* HasSystemFiles() - */
  95. /* */
  96. /*--------------------------------------------------------------------------*/
  97. /* See if the specified disk has IBMBIO.COM and IBMDOS.COM (or IO.SYS and
  98. * MSDOS.SYS). If so, store their sizes in SysFileSize[].
  99. */
  100. BOOL
  101. APIENTRY
  102. HasSystemFiles(
  103. WORD iDrive
  104. )
  105. {
  106. INT i;
  107. HFILE fh;
  108. DPB DPB;
  109. BOOL rc;
  110. CHAR ch;
  111. LPSTR lpStr;
  112. LPSTR lpFileBuff;
  113. OFSTRUCT OFInfo;
  114. HANDLE hFileBuff;
  115. /* Initialise the source filename pointers */
  116. SysFileNamePtr[0] = &BIOSfile[0];
  117. SysFileNamePtr[1] = &DOSfile[0];
  118. SysFileNamePtr[2] = &COMMANDfile[0];
  119. hFileBuff = NULL;
  120. lpFileBuff = NULL;
  121. /* Acertain the presence of BIOS/DOS/COMMAND and grab their sizes.
  122. * First we will try IBMBIO.COM. If it does not exist, then we will try
  123. * IO.SYS. It it also does not exist, then it is an error.
  124. */
  125. /* Get the DPB */
  126. if (GetDPB(iDrive, &DPB) != NOERROR)
  127. goto HSFError;
  128. /* Check if the iDrive has standard sector size; If it doesn't then report
  129. * error; (We can allocate a bigger buffer and proceed at this point, but
  130. * int25 to read an abosolute sector may not work in pmodes, because they
  131. * assume standard sector sizes;)
  132. * Fix for Bug #10632 --SANKAR-- 03-21-90
  133. */
  134. if (HIWORD(GetClusterInfo(iDrive)) > SECTORSIZE)
  135. goto HSFError;
  136. /* Allocate enough memory to read the first cluster of root dir. */
  137. if (!(hFileBuff = LocalAlloc(LHND, (DWORD)SECTORSIZE)))
  138. goto HSFError;
  139. if (!(lpFileBuff = LocalLock(hFileBuff)))
  140. goto HSFError;
  141. /* Read the first cluster of the root directory. */
  142. if (MyInt25(iDrive, lpFileBuff, 1, DPB.dir_sector))
  143. goto HSFError;
  144. /* Let us start with the first set of system files. */
  145. for (i=0; i <= CSYSFILES-1; i++) {
  146. lstrcpy((LPSTR)SysFileNamePtr[i], "C:\\");
  147. lstrcat((LPSTR)SysFileNamePtr[i], SysNameTable[0][i]);
  148. *SysFileNamePtr[i] = (BYTE)('A'+iDrive);
  149. }
  150. /* Get the command.com from the COMSPEC= environment variable */
  151. lpStr = MGetDOSEnvironment();
  152. /* Find the COMSPEC variable. */
  153. while (*lpStr != TEXT('\0')) {
  154. if (lstrlen(lpStr) > 8) {
  155. ch = lpStr[7];
  156. lpStr[7] = TEXT('\0');
  157. if (lstrcmpi(lpStr, (LPSTR)"COMSPEC") == 0) {
  158. lpStr[7] = ch;
  159. break;
  160. }
  161. }
  162. lpStr += lstrlen(lpStr)+1;
  163. }
  164. /* If no COMSPEC then things are really roached... */
  165. if (*lpStr == TEXT('\0'))
  166. goto HSFError;
  167. /* The environment variable is COMSPEC; Look for '=' char */
  168. while (*lpStr != '=')
  169. lpStr = AnsiNext(lpStr);
  170. /* Copy the command.com with the full pathname */
  171. lstrcpy((LPSTR)SysFileNamePtr[2], lpStr);
  172. /* Check if the IBMBIO.COM and IBMDOS.COM exist. */
  173. if (SameFilenames(lpFileBuff, (LPSTR)(SysFileNamePtr[0]+3)) ||
  174. SameFilenames(lpFileBuff+sizeof(DIRTYPE), (LPSTR)(SysFileNamePtr[1]+3))) {
  175. /* Check if at least IO.SYS and MSDOS.SYS exist. */
  176. lstrcpy((LPSTR)(SysFileNamePtr[0]+3), SysNameTable[1][0]);
  177. lstrcpy((LPSTR)(SysFileNamePtr[1]+3), SysNameTable[1][1]);
  178. if (SameFilenames(lpFileBuff, (SysFileNamePtr[0]+3)) ||
  179. SameFilenames(lpFileBuff+sizeof(DIRTYPE), (SysFileNamePtr[1]+3)))
  180. goto HSFError;
  181. }
  182. /* Check if COMMAND.COM exists in the source drive. */
  183. if ((fh = MOpenFile((LPSTR)SysFileNamePtr[2], (LPOFSTRUCT)&OFInfo, OF_READ)) == -1)
  184. goto HSFError;
  185. /* Get the file sizes. */
  186. SysFileSize[0] = ((LPDIRTYPE)lpFileBuff)->size;
  187. SysFileSize[1] = ((LPDIRTYPE)(lpFileBuff+sizeof(DIRTYPE)))->size;
  188. SysFileSize[2] = M_llseek(fh, 0L, SEEK_END);
  189. M_lclose(fh);
  190. rc = TRUE;
  191. goto HSFExit;
  192. HSFError:
  193. rc = FALSE;
  194. HSFExit:
  195. if (lpFileBuff)
  196. LocalUnlock(hFileBuff);
  197. if (hFileBuff)
  198. LocalFree(hFileBuff);
  199. MFreeDOSEnvironment(lpStr);
  200. return (rc);
  201. }
  202. /*--------------------------------------------------------------------------*/
  203. /* */
  204. /* CalcFreeSpace() - */
  205. /* */
  206. /*--------------------------------------------------------------------------*/
  207. /* Given an array of filenames and the number of files, this function
  208. * calculates the freespace that would be created if those files are deleted.
  209. *
  210. * NOTE: This function returns TOTAL free space, (i.e) the summation of
  211. * already existing free space and the space occupied by those files.
  212. */
  213. INT
  214. CalcFreeSpace(
  215. CHAR DestFiles[][SYSFILENAMELEN],
  216. INT cFiles,
  217. INT cbCluster,
  218. WORD wFreeClusters,
  219. WORD wReqdClusters
  220. )
  221. {
  222. INT i;
  223. HFILE fh;
  224. LONG lFileSize;
  225. OFSTRUCT OFInfo;
  226. ENTER("CalcFreeSpace");
  227. /* Find out the space already occupied by SYS files, if any. */
  228. for (i=0; i < cFiles; i++) {
  229. fh = MOpenFile(&DestFiles[i][0], &OFInfo, OF_READ);
  230. if (fh != (HFILE)-1) {
  231. /* Get the file size */
  232. lFileSize = M_llseek(fh, 0L, SEEK_END);
  233. if (lFileSize != -1L)
  234. wFreeClusters += LOWORD((lFileSize + cbCluster - 1)/cbCluster);
  235. M_lclose(fh);
  236. if (wFreeClusters >= wReqdClusters)
  237. return (wFreeClusters);
  238. }
  239. }
  240. LEAVE("CalcFreeSpace");
  241. return (wFreeClusters);
  242. }
  243. /*--------------------------------------------------------------------------*/
  244. /* */
  245. /* CheckDiskSpace() - */
  246. /* */
  247. /*--------------------------------------------------------------------------*/
  248. BOOL
  249. CheckDiskSpace(
  250. WORD iDestDrive,
  251. INT cbCluster, /* Bytes/Cluster of dest drive */
  252. CHAR DestFileNames[][SYSFILENAMELEN], /* NOTE: 2-dimensional array */
  253. BOOL bDifferentSysFiles,
  254. CHAR DestSysFiles[][SYSFILENAMELEN]
  255. )
  256. {
  257. INT i;
  258. INT wFreeClusters;
  259. INT wReqdClusters;
  260. /* Compute the number of clusters required. */
  261. wReqdClusters = 0;
  262. for (i=0; i < CSYSFILES; i++)
  263. wReqdClusters += LOWORD((SysFileSize[i] + cbCluster - 1) / cbCluster);
  264. /* Calculate the free disk space in clusters in the destination disk */
  265. wFreeClusters = LOWORD(GetFreeDiskSpace(iDestDrive) / cbCluster);
  266. if (wFreeClusters >= wReqdClusters)
  267. /* We have enough space. */
  268. return (TRUE);
  269. wFreeClusters = CalcFreeSpace(DestFileNames, CSYSFILES, cbCluster, (WORD)wFreeClusters, (WORD)wReqdClusters);
  270. if (wFreeClusters >= wReqdClusters)
  271. return (TRUE);
  272. /* Check if the sys files in the dest disk are different. */
  273. if (bDifferentSysFiles) {
  274. wFreeClusters = CalcFreeSpace(DestSysFiles, 2, cbCluster, (WORD)wFreeClusters, (WORD)wReqdClusters);
  275. if (wFreeClusters >= wReqdClusters)
  276. return (TRUE);
  277. }
  278. /* Insufficient disk space even if we delete the sys files. */
  279. return (FALSE);
  280. }
  281. /*--------------------------------------------------------------------------*/
  282. /* */
  283. /* IsSYSable() - */
  284. /* */
  285. /*--------------------------------------------------------------------------*/
  286. /* The requirements for the destination disk to be sysable are either:
  287. *
  288. * 1) first two directory entries are empty
  289. * 2) the first N clusters free where N = ceil (size IBMBIO/secPerClus)
  290. * 3) there is enough room on the disk for IBMBIO/IBMDOS/COMMAND
  291. *
  292. * - or -
  293. *
  294. * 1) the first two directory entries are IBMBIO.COM and IBMDOS.COM
  295. * or IO.SYS and MSDOS.SYS
  296. * 2) the first N clusters are alloced to these files where N is defines above.
  297. * 3) there is enough room on the disk for IBMBIO/IBMDOS/COMMAND after
  298. * deleting the IBMBIO/IBMDOS/COMMAND on the disk.
  299. *
  300. * IMPORTANT NOTE:
  301. * DestFileNames[][] contain the names of the sys files that would be
  302. * created on the Destination diskette;
  303. * DestSysFiles[][] contain the names of the sys files already
  304. * present in the destination diskette, if any; Please Note that
  305. * these two sets of filenames need not be the same, because you can
  306. * install MSDOS on to a diskette that already has PCDOS and
  307. * vice-versa.
  308. */
  309. BOOL
  310. IsSYSable(
  311. WORD iSrceDrive,
  312. WORD iDestDrive,
  313. CHAR DestFileNames[][SYSFILENAMELEN], /* NOTE: 2-dimensional array */
  314. LPSTR lpFileBuff
  315. )
  316. {
  317. #ifdef LATER
  318. INT i;
  319. DPB DPB;
  320. WORD clusTmp1, clusTmp2;
  321. WORD clusBIOS, clusDOS;
  322. INT cBytesPerCluster;
  323. INT cBIOSsizeInClusters;
  324. BOOL bDifferentDestFiles = FALSE;
  325. CHAR chVolLabel[11]; /* This is NOT null terminated */
  326. DWORD dwSerialNo;
  327. CHAR DestSysFiles[2][SYSFILENAMELEN];
  328. INT cContigClusters;
  329. DWORD dwClusterInfo;
  330. CHAR szTemp[SYSFILENAMELEN];
  331. /* Grab DPB for destination. */
  332. if (GetDPB(iDestDrive, &DPB))
  333. return (FALSE);
  334. /* Has the user aborted? */
  335. if (WFQueryAbort())
  336. return (FALSE);
  337. /* Get bytes per cluster for destination. */
  338. dwClusterInfo = GetClusterInfo(iDestDrive);
  339. /* Bytes per cluster = sectors per cluster * size of a sector */
  340. cBytesPerCluster = LOWORD(dwClusterInfo) * HIWORD(dwClusterInfo);
  341. if (!cBytesPerCluster)
  342. return (FALSE);
  343. /* Has the user aborted? */
  344. if (WFQueryAbort())
  345. return (FALSE);
  346. /* Convert size of BIOS into full clusters */
  347. cBIOSsizeInClusters = LOWORD((SysFileSize[0] + cBytesPerCluster - 1) / cBytesPerCluster);
  348. /* Number of clusters required to be contiguous depends on DOS versions.
  349. * DOS 3.2 and below expect all clusters of BIOS to be contiguos.
  350. * But 3.3 and above expect only the first stub loader (<2K) to be contiguous.
  351. */
  352. cContigClusters = (GetDOSVersion() > 0x314) ?
  353. ((2048 + cBytesPerCluster - 1)/cBytesPerCluster) :
  354. cBIOSsizeInClusters;
  355. /* Grab first sector of destination root directory */
  356. if (MyInt25(iDestDrive, lpFileBuff, 1, DPB.dir_sector))
  357. return (FALSE);
  358. /* Has the user aborted? */
  359. if (WFQueryAbort())
  360. return (FALSE);
  361. /* Are the first two directory entries empty? */
  362. if ((lpFileBuff[0] == 0 || (BYTE)lpFileBuff[0] == 0xE5) &&
  363. (lpFileBuff[sizeof(DIRTYPE)] == 0 || (BYTE)lpFileBuff[sizeof(DIRTYPE)] == 0xE5)) {
  364. /* Any of first N (= BIOS size) clusters not empty? */
  365. for (i=0; i < cContigClusters; i++) {
  366. /* Has the user aborted? */
  367. if (WFQueryAbort())
  368. return (FALSE);
  369. }
  370. } else {
  371. /* Are the first two directory entries NOT BIOS/DOS? */
  372. for (i=0; i < 2; i++) {
  373. if ((!SameFilenames(lpFileBuff, SysNameTable[i][0])) ||
  374. (!SameFilenames(lpFileBuff+sizeof(DIRTYPE), SysNameTable[i][1]))) {
  375. /* Check if the destination files are the same as the source files */
  376. if (lstrcmpi(&DestFileNames[0][3], SysNameTable[i][0])) {
  377. /* No! Delete the other set of filenames. */
  378. DestSysFiles[0][0] = DestSysFiles[1][0] = (BYTE)('A'+iDestDrive);
  379. lstrcpy(&DestSysFiles[0][1], ":\\");
  380. lstrcpy(&DestSysFiles[0][3], SysNameTable[i][0]);
  381. lstrcpy(&DestSysFiles[1][1], ":\\");
  382. lstrcpy(&DestSysFiles[1][3], SysNameTable[i][1]);
  383. bDifferentDestFiles = TRUE;
  384. }
  385. break;
  386. }
  387. }
  388. /* Did we find a match? */
  389. if (i == 2)
  390. /* Nope, the 2 entries are occupied by non-system files. */
  391. return (FALSE);
  392. /* Any of first N clusters NOT allocated to BIOS/DOS? */
  393. clusBIOS = ((LPDIRTYPE)lpFileBuff)->first;
  394. clusDOS = ((LPDIRTYPE)(lpFileBuff + sizeof(DIRTYPE)))->first;
  395. /* Do it the hard way, for each cluster 2..N+2 see if it is in the chain.
  396. */
  397. for (i=0; i < cContigClusters; i++) {
  398. clusTmp1 = clusBIOS;
  399. clusTmp2 = clusDOS;
  400. /* Check if cluster #i+2 is allocated to either of these files. */
  401. while (TRUE) {
  402. if (i+2 == (INT)clusTmp1 || i+2 == (INT)clusTmp2)
  403. break;
  404. // if (clusTmp1 != -1)
  405. if (clusTmp1 < 0xFFF0)
  406. clusTmp1 = 0;
  407. // if (clusTmp2 != -1)
  408. if (clusTmp2 < 0xFFF0)
  409. clusTmp2 = 0;
  410. // if (clusTmp1 == -1 && clusTmp2 == -1)
  411. if (clusTmp1 >= 0xFFF0 && clusTmp2 >= 0xFFF0)
  412. return FALSE;
  413. /* Did the user abort? */
  414. if (WFQueryAbort())
  415. return FALSE;
  416. }
  417. }
  418. }
  419. /* Let us check if there is enough space on the dest disk. */
  420. if (CheckDiskSpace(iDestDrive, cBytesPerCluster, DestFileNames, bDifferentDestFiles, DestSysFiles) == FALSE)
  421. return (FALSE);
  422. /* Has the user aborted? */
  423. if (WFQueryAbort())
  424. return (FALSE);
  425. /* Get the Present Volume label and preserve it. */
  426. GetVolumeLabel(iDestDrive, (LPSTR)chVolLabel, FALSE);
  427. /*** NOTE: chVolLabel remains in OEM characters! ***/
  428. /* Get the serial no if any and preserve it. */
  429. dwSerialNo = ReadSerialNumber(iDestDrive, lpFileBuff);
  430. /* Copy and adjust boot sector from source to destination */
  431. if (WriteBootSector(iSrceDrive, iDestDrive, NULL, lpFileBuff) != NOERROR)
  432. return (FALSE);
  433. /* Restore the old volume label and serial number in the boot rec. */
  434. if (ModifyVolLabelInBootSec(iDestDrive, (LPSTR)chVolLabel, dwSerialNo, lpFileBuff))
  435. return (FALSE);
  436. /* Delete destination BIOS/DOS/COMMAND. */
  437. for (i=0; i < CSYSFILES; i++) {
  438. AnsiToOem(DestFileNames[i], szTemp);
  439. SetFileAttributes(szTemp, 0);
  440. DosDelete(szTemp);
  441. if ((bDifferentDestFiles) && (i < 2)) {
  442. SetFileAttributes(szTemp, 0);
  443. DosDelete(szTemp);
  444. }
  445. /* Has the user aborted? */
  446. if (WFQueryAbort())
  447. return (FALSE);
  448. }
  449. /* Reset the DPB_next_free field of the DPB to 2, sothat when IBMBIO.COM is
  450. * copied into this disk, the clusters will get allocated starting from 2.
  451. */
  452. ModifyDPB(iDestDrive);
  453. #endif // LATER
  454. return (TRUE);
  455. }
  456. /*--------------------------------------------------------------------------*/
  457. /* */
  458. /* MakeSystemDiskette() - */
  459. /* */
  460. /*--------------------------------------------------------------------------*/
  461. /* This routine is intended to mimic the functions of the SYS command
  462. * under MSDOS: to transfer a version of the operating system from a source
  463. * disk to a destination such that the destination will be bootable.
  464. *
  465. * The requirements of the source disk is that it contain:
  466. *
  467. * 1) a command processor (COMMAND.COM)
  468. * 2) a default set of device drivers (IBMBIO.COM)
  469. * 3) an operating system (IBMDOS.COM)
  470. * 4) a boot sector appropriate to the device drivers
  471. *
  472. * The requirements for the destination disk are either:
  473. *
  474. * 1) first two directory entries are empty
  475. * 2) the first N clusters free where N = ceil (size IBMBIO/secPerClus)
  476. * 3) there is enough room on the disk for IBMBIO/IBMDOS/COMMAND
  477. *
  478. * - or -
  479. *
  480. * 1) the first two directory entries are IBMBIO.COM and IBMDOS.COM
  481. * or IO.SYS and MSDOS.SYS
  482. * 2) the first N clusters are alloced to these files where N is defined
  483. * above
  484. * 3) there is enough room on the disk for IBMBIO/IBMDOS/COMMAND after
  485. * deleting the IBMBIO/IBMDOS/COMMAND on the disk.
  486. *
  487. * Inputs:
  488. * iDestDrive 0-based drive number of formatted drive
  489. * for destination.
  490. * bEmptyFloppy : TRUE if the floppy is empty; Useful when
  491. * the floppy is just formatted; No need to check if
  492. * it is Sysable;
  493. * Returns: 0 Successful transferral of boot sector and files
  494. * <> 0 error code.
  495. */
  496. BOOL
  497. APIENTRY
  498. MakeSystemDiskette(
  499. WORD iDestDrive,
  500. BOOL bEmptyFloppy
  501. )
  502. {
  503. INT i;
  504. HANDLE hFileBuff; /* Buffer to read in file contents etc., */
  505. LPSTR lpFileBuff;
  506. CHAR DestFileName[CSYSFILES][SYSFILENAMELEN];
  507. CHAR szTemp1[SYSFILENAMELEN];
  508. CHAR szTemp2[SYSFILENAMELEN];
  509. WORD nSource;
  510. nSource = (WORD)GetBootDisk();
  511. if (!HasSystemFiles(nSource)) {
  512. LoadString(hAppInstance, IDS_SYSDISKNOFILES, szMessage, sizeof(szMessage));
  513. MessageBox(hdlgProgress, szMessage, szTitle, MB_OK | MB_ICONSTOP);
  514. bUserAbort = TRUE;
  515. return FALSE;
  516. }
  517. if (iDestDrive == nSource) {
  518. LoadString(hAppInstance, IDS_SYSDISKSAMEDRIVE, szMessage, sizeof(szMessage));
  519. MessageBox(hdlgProgress, szMessage, szTitle, MB_OK | MB_ICONSTOP);
  520. bUserAbort = TRUE;
  521. return FALSE;
  522. }
  523. /* Initialize variables for cleanup. */
  524. hFileBuff = NULL;
  525. lpFileBuff = NULL;
  526. /* Flush the DOS buffers. */
  527. DiskReset();
  528. if (!(hFileBuff = LocalAlloc(LHND, (DWORD)BUFFSIZE)))
  529. return (1);
  530. lpFileBuff = LocalLock(hFileBuff);
  531. for (i=0; i < (CSYSFILES - 1); i++) {
  532. /* Create the destination file names */
  533. lstrcpy((LPSTR)&DestFileName[i][0], (LPSTR)SysFileNamePtr[i]);
  534. DestFileName[i][0] = (BYTE)('A' + iDestDrive);
  535. }
  536. /* Copy just the Command.COM without any path name */
  537. lstrcpy((LPSTR)DestFileName[2], "X:\\");
  538. lstrcat((LPSTR)DestFileName[2], (LPSTR)SysNameTable[0][2]);
  539. DestFileName[2][0] = (BYTE)('A' + iDestDrive);
  540. /* Check if it is an empty floppy; If so, there is no need to check if it
  541. * is 'SYSable'. It is bound to be 'Sysable'. So, skip all the checks and
  542. * go ahead with copying the sys files.
  543. */
  544. if (!bEmptyFloppy) {
  545. /* Check if the Destination floppy is SYS-able */
  546. if (!IsSYSable(nSource, iDestDrive, DestFileName, lpFileBuff))
  547. goto MSDErrExit;
  548. /* Did the user abort? */
  549. if (WFQueryAbort())
  550. goto MSDErrExit;
  551. }
  552. /* Copy files */
  553. bCopyReport = FALSE;
  554. DisableFSC();
  555. for (i=0; i < CSYSFILES; i++) {
  556. /* Copy all files except command.com with sys attributes */
  557. AnsiToOem(SysFileNamePtr[i], szTemp1);
  558. AnsiToOem(DestFileName[i], szTemp2);
  559. /* Make sure the destination file is deleted first */
  560. SetFileAttributes(szTemp2, ATTR_ALL);
  561. WFRemove(szTemp2);
  562. // copy code preserves the attributes
  563. if (FileCopy(szTemp1, szTemp2))
  564. goto MSDErrExit2;
  565. if (WFQueryAbort())
  566. goto MSDErrExit2;
  567. }
  568. if (EndCopy()) // empty the copy queue
  569. goto MSDErrExit2;
  570. EnableFSC();
  571. /* Normal Exit. */
  572. LocalUnlock(hFileBuff);
  573. LocalFree(hFileBuff);
  574. return FALSE; // success
  575. MSDErrExit2:
  576. EnableFSC();
  577. MSDErrExit:
  578. CopyAbort(); // Purge any copy commands in copy queue
  579. LocalUnlock(hFileBuff);
  580. LocalFree(hFileBuff);
  581. return TRUE; // failure
  582. }