home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / pmflp301.zip / diskcopy / dskim.c < prev    next >
C/C++ Source or Header  |  1997-01-01  |  27KB  |  773 lines

  1. /*
  2.            dskim.c
  3.            
  4.            disk handling routines for pmfloppy.c
  5.  
  6.            Copyright G. Bryant, 1990
  7.  
  8.    
  9.   Change Log
  10.     5/95 - ROB Extensive changes to seperate the utility functions (i.e.
  11.         reading and writing) from the tasking functions in readsource() and
  12.         writetarget().  These changes allow essentially the same code to 
  13.         be executed as a subroutine and as a task.
  14.  
  15. */
  16.  
  17. #define VOID void
  18.  
  19. #define INCL_DOSERRORS
  20. #define INCL_DOSFILEMGR
  21. #define INCL_DOSPROCESS
  22. #define INCL_BASE
  23. #define INCL_DOSDEVIOCTL
  24. #define INCL_DOSSESMGR
  25. #define INCL_DOSMISC
  26. #define INCL_DOSMEMMGR
  27. #include <os2.h>
  28. #include <malloc.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32.  
  33. #include "pmfloppy.h"
  34. #include "DskIm.h"
  35. #include "funcdefs.h"
  36.  
  37. /* Global variables ------------------------------------------------------ */
  38.  
  39. /* PM vbls*/
  40. extern HWND   hWndFrame ;
  41.  
  42. /* user response vbls*/
  43. extern DskImage ImageBuffers[NUM_IMAGES];
  44.  
  45. /* Thread variables*/
  46. extern ThreadContext tcThBufs[NUM_THREADS];
  47.  
  48. /* "local" global vbls*/
  49. ULONG        _fmtData;            /* Used with DSK_FORMATVERIFY         */
  50.  
  51. /* Global function prototypes*/
  52.  
  53. /* local function prototypes*/
  54. SHORT    fmttbl_bytessec(USHORT, USHORT *);
  55. SHORT    bspblkcmp(BSPBLK *, BSPBLK *);
  56. VOID     ThreadErrorHandler(USHORT, USHORT, HFILE);
  57. USHORT   SetBufferSel(USHORT);
  58. static PBYTE    MakeHugeP(USHORT, USHORT);
  59.  
  60.  
  61.  
  62.  
  63. /* Code ------------------------------------------------------------------ */
  64.  
  65. /* ************************** readsource ****************************** */
  66. /*   Read source disk into memory*/
  67. /**/
  68. /*  when done track data is in huge space starting with selector*/
  69. /*  stored in the global*/
  70. /*  sets global variables:*/
  71. /*     tcThBufs*/
  72. /*     ImageBuffers*/
  73. /**/
  74. VOID APIENTRY readsource(ULONG curTh) {
  75.  
  76. ULONG        bufferLengthInOut,
  77.             parameterLengthInOut;
  78. BYTE         parmCmd = 1;
  79. USHORT       trk, hd, cyl;
  80. HFILE        dHandle;
  81. ULONG       result;
  82. static CHAR  szdrive[] = "A:";
  83. ULONG        sourceBytes;         /* # bytes on source disk             */
  84. USHORT       sourceTracks;        /* # tracks on source disk            */
  85. USHORT       curBuff;
  86.  
  87. PBYTE        DskBuf;              /* pointer to track data*/
  88. ULONG        nextPercent = 0;
  89. CHAR        infoBuffer[20];
  90.  
  91.   curBuff = tcThBufs[curTh].ImageNumber;
  92.  
  93.   tcThBufs[curTh].ErrorCode = 0;
  94.   /* If this isn't the first time here, free memory from last time first */
  95.   if (ImageBuffers[curBuff].Percent == 100) {
  96.     free(ImageBuffers[curBuff].DskLayout);
  97.     /* if the following code has any problems we will free the code
  98.        twice unless we take precautions
  99.     */
  100.     ImageBuffers[curBuff].Percent = 0;
  101.   }
  102.  
  103.   /* Get source disk parameters */
  104.   DosError(FERR_DISABLEHARDERR);
  105.   szdrive[0] = ImageBuffers[curBuff].DriveID[0];
  106.   tcThBufs[curTh].ErrorCode = DosOpen(szdrive,
  107.                                       &dHandle,
  108.                                       &result,
  109.                                       0L,
  110.                                       0,
  111.                                       FILE_OPEN,
  112.                                       OPENFLAGS,
  113.                                       0L);
  114.  
  115.   if (tcThBufs[curTh].ErrorCode)
  116.     ThreadErrorHandler(UM_ERROR, curTh, dHandle);
  117.  
  118.   lockdrive(dHandle);
  119.   if (tcThBufs[curTh].ErrorCode)
  120.     ThreadErrorHandler(UM_ERROR, curTh, dHandle);
  121.  
  122. parameterLengthInOut = 1;
  123. bufferLengthInOut = sizeof(ImageBuffers[curBuff].DskParms);
  124.   tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
  125.                                     IOCTL_DISK,
  126.                                     DSK_GETDEVICEPARAMS,
  127.                                     &parmCmd, 
  128.                                     parameterLengthInOut, 
  129.                                     ¶meterLengthInOut,
  130.                                     &ImageBuffers[curBuff].DskParms,
  131.                                     bufferLengthInOut,
  132.                                     &bufferLengthInOut
  133.                                     );
  134.  
  135.   if (!tcThBufs[curTh].ErrorCode) {
  136.     /* Set all the informational variables and build a track layout table
  137.     **  for use with the following sector reads.
  138.     */
  139.     sourceBytes   = (ULONG)(ImageBuffers[curBuff].DskParms.usBytesPerSector) *
  140.                     (ULONG)(ImageBuffers[curBuff].DskParms.cSectors);
  141.     sourceTracks  = ImageBuffers[curBuff].DskParms.cSectors         /
  142.                     ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  143.  
  144.     ImageBuffers[curBuff].usLayoutSize = sizeof(TRACKLAYOUT)   +
  145.                           ((2 * sizeof(USHORT)) *
  146.                           (ImageBuffers[curBuff].DskParms.usSectorsPerTrack - 1));
  147.  
  148.     if (ImageBuffers[curBuff].DskLayout =
  149.         (PTRACKLAYOUT)malloc(ImageBuffers[curBuff].usLayoutSize * sizeof(BYTE))) {
  150.       ImageBuffers[curBuff].DskLayout->bCommand = 1;
  151.       ImageBuffers[curBuff].DskLayout->usFirstSector = 0;
  152.       ImageBuffers[curBuff].DskLayout->cSectors = ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  153.       for (trk = 0; trk < ImageBuffers[curBuff].DskParms.usSectorsPerTrack; trk++) {
  154.         ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorNumber = trk+1;
  155.         ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorSize = 
  156.                                                                       ImageBuffers[curBuff].DskParms.usBytesPerSector;
  157.       }
  158.     }
  159.     else
  160.       ThreadErrorHandler(UM_ERROR, curTh, dHandle);
  161.  
  162.  
  163.  
  164.     /* Allocate huge memory to hold the track data*/
  165.     if (tcThBufs[curTh].ErrorCode = SetBufferSel(curBuff))
  166.       ThreadErrorHandler(UM_ERROR, curTh, dHandle);
  167.  
  168.     /* For each track, set the pointer and read the sector into it*/
  169.     for (trk = 0, cyl = 0;
  170.          trk < sourceTracks;
  171.          trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++) {
  172.       ImageBuffers[curBuff].DskLayout->usCylinder = cyl;
  173.  
  174.       for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++) {
  175.         ImageBuffers[curBuff].Percent =
  176.           (USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
  177.             if(ImageBuffers[curBuff].Percent >= nextPercent)
  178.                 {nextPercent += 5;
  179.         WinPostMsg(hWndFrame,UM_STATUS,MPFROMSHORT(curTh),0);
  180.                 }
  181.         ImageBuffers[curBuff].DskLayout->usHead = hd;
  182.  
  183.         DskBuf = MakeHugeP(curBuff,trk+hd);
  184.             parameterLengthInOut = sizeof(ImageBuffers[curBuff].DskLayout);
  185.             bufferLengthInOut = 10000;        /* pick some arbitrary value 
  186.                                                and hope for the best  */
  187.         if (tcThBufs[curTh].ErrorCode = DosDevIOCtl(dHandle,
  188.                                     IOCTL_DISK,
  189.                                     DSK_READTRACK,
  190.                                     ImageBuffers[curBuff].DskLayout,
  191.                                     parameterLengthInOut,
  192.                                     ¶meterLengthInOut,
  193.                                     DskBuf,
  194.                                     bufferLengthInOut,
  195.                                     &bufferLengthInOut
  196.                                     ))
  197.                 ThreadErrorHandler(UM_ERROR, curTh, dHandle);
  198.       }
  199.     }
  200.     if (!DosQueryFSInfo ((ULONG) (toupper(ImageBuffers[curBuff].DriveID[0])-'A')+1,
  201.                                 FSIL_VOLSER, infoBuffer, 20))
  202.         {strcpy (ImageBuffers[curBuff].volumeLabel, infoBuffer+5);
  203.         }
  204.     else
  205.         *(ImageBuffers[curBuff].volumeLabel) = '\0';
  206.     ImageBuffers[curBuff].Percent = 100;
  207.     WinPostMsg(hWndFrame,UM_STATUS, MPFROMSHORT(curTh),0);
  208.   }
  209.   else {            /* error reading drive parameters */
  210.     ;        /* NOTHING */
  211.   }
  212. unlockdrive (dHandle);
  213.   if (dHandle) 
  214.     {APIRET        rc;
  215.     UCHAR        parameter = 0,
  216.                 data = 0;
  217.     ULONG        parameterLengthInOut = 1,
  218.                 dataLengthInOut = 1;
  219.  
  220.     rc = DosDevIOCtl ( dHandle, 8L, 1L, ¶meter, 1L, ¶meterLengthInOut,
  221.             &data, 1l, &dataLengthInOut);
  222.      DosClose(dHandle);
  223.     }
  224.   DosError(FERR_ENABLEHARDERR);
  225. return;
  226. /*  DosExit(EXIT_THREAD,0);*/
  227. }  /* readsource*/
  228.  
  229. /* *********************** fmttbl_bytessec *************************** */
  230.  
  231. /* --- Translate bytes per sector into 0-3 code ---
  232. **       the four sector sizes listed below are alluded to in the OS/2
  233. **        docs however only 512 byte sectors are allowed under OS/2 1.x
  234. **       returns the code or -1 and sets DiskError
  235. */
  236. SHORT fmttbl_bytessec(USHORT bytesPerSec, USHORT *DiskError)
  237. {
  238.  
  239.   *DiskError = NO_ERROR;
  240.   switch (bytesPerSec)  {
  241.     case 128:  return 0;
  242.     case 256:  return 1;
  243.     case 512:  return 2;
  244.     case 1024: return 3;
  245.   }
  246.   *DiskError = ERROR_BAD_FORMAT;
  247.   return -1;
  248. }
  249.  
  250.  
  251. /* ****************************** writetarget ************************* */
  252.  
  253. /* --- write information read by readsource() onto target disk ---
  254. **       parameter is drive handle as returned by opendrive()
  255. **       checks the target disk, if it's the same format as the source
  256. **        or not formatted at all, write the information contained in
  257. **        DskBuffer formatting if neccessary.
  258. **       returns 0 if successful else errorcode
  259. **
  260. */
  261. VOID APIENTRY writetarget(ULONG curTh) {
  262.  
  263. ULONG        parameterLengthInOut,
  264.             bufferLengthInOut;        
  265. BYTE         _parmCmd = 1;
  266. PTRACKFORMAT trkfmt;
  267. USHORT       sizeofTrkfmt;
  268. USHORT       i, trk, hd, cyl, needFormat = FALSE;
  269. HFILE        hf;
  270. ULONG       result;
  271. static CHAR  szdrive[] = "A:";
  272. BSPBLK       targetParms;
  273. USHORT       sourceTracks;        /* # tracks on source disk            */
  274. USHORT       curBuff;
  275. APIRET        rc;
  276. PBYTE        DskBuf;              /* huge pointer to track data*/
  277. ULONG nextPercent = 0;
  278.  
  279.   curBuff = tcThBufs[curTh].ImageNumber;
  280.  
  281.   tcThBufs[curTh].ErrorCode = 0;
  282.   /* Get source disk parameters */
  283.   DosError(FERR_DISABLEHARDERR);
  284.   szdrive[0] = ImageBuffers[curBuff].DriveID[0];
  285.   tcThBufs[curTh].ErrorCode = DosOpen(szdrive,
  286.                                       &hf,
  287.                                       &result,
  288.                                       0L,
  289.                                       0,
  290.                                       FILE_OPEN,
  291.                                       OPENFLAGS,
  292.                                       0L);
  293.  
  294.   if (tcThBufs[curTh].ErrorCode)
  295.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  296.  
  297.   lockdrive(hf);
  298.   if (tcThBufs[curTh].ErrorCode)
  299.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  300.  
  301.   /* Get target disk parameters */
  302. bufferLengthInOut = sizeof(targetParms);
  303. parameterLengthInOut = 1;
  304.   tcThBufs[curTh].ErrorCode = DosDevIOCtl(hf,
  305.                                           IOCTL_DISK,
  306.                                           DSK_GETDEVICEPARAMS,
  307.                                           &_parmCmd,
  308.                                         1, ¶meterLengthInOut,
  309.                                         &targetParms,
  310.                                         bufferLengthInOut,
  311.                                         &bufferLengthInOut
  312.                                         );
  313.  
  314.   if ((tcThBufs[curTh].ErrorCode == ERROR_READ_FAULT) &&
  315.       (ImageBuffers[curBuff].FormatOptions == IDD_WRF_NEVER))
  316.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  317.  
  318.   if (((tcThBufs[curTh].ErrorCode == ERROR_READ_FAULT) &&
  319.        (ImageBuffers[curBuff].FormatOptions == IDD_WRF_MAYBE)) ||
  320.       (ImageBuffers[curBuff].FormatOptions == IDD_WRF_ALWAYS))  {
  321.     /* If the disk needs formatting we build a format table for it based
  322.     **  on the source disk.
  323.     */
  324.     needFormat = TRUE;
  325.     tcThBufs[curTh].ErrorCode = 0;
  326.     /* Set all the informational variables needed for formatting*/
  327.  
  328.     sizeofTrkfmt = sizeof(TRACKFORMAT) +
  329.                     ((4 * sizeof(BYTE)) *
  330.                     (ImageBuffers[curBuff].DskParms.usSectorsPerTrack - 1));
  331.     if ((trkfmt = (PTRACKFORMAT)malloc(sizeofTrkfmt * sizeof(BYTE))) == NULL)
  332.       ThreadErrorHandler(UM_ERROR, curTh, hf);
  333.  
  334.     trkfmt->bCommand = 1;
  335.     trkfmt->cSectors = ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  336.     for (trk = 0; trk < trkfmt->cSectors; trk++) {
  337.       trkfmt->FormatTable[trk].idSector = (BYTE)(trk+1);
  338.       trkfmt->FormatTable[trk].bBytesSector =
  339.              fmttbl_bytessec(ImageBuffers[curBuff].DskParms.usBytesPerSector,
  340.                              &(tcThBufs[curTh].ErrorCode));
  341.     }
  342.   }
  343.   else if (!tcThBufs[curTh].ErrorCode)
  344.     /* Else if no other error, make sure that the target disk is the same
  345.     **  format as the source.
  346.     */
  347.     if (bspblkcmp(&(ImageBuffers[curBuff].DskParms), &targetParms))
  348.       tcThBufs[curTh].ErrorCode = DSKIM_ERROR_WRONG_FORMAT;
  349.  
  350.   sourceTracks  = ImageBuffers[curBuff].DskParms.cSectors         /
  351.                   ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  352.  
  353.   if (!tcThBufs[curTh].ErrorCode) {
  354.     for (trk = 0, cyl = 0; trk < sourceTracks; trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++) {
  355.       ImageBuffers[curBuff].DskLayout->usCylinder = cyl;
  356.       for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++) {
  357.         ImageBuffers[curBuff].Percent =
  358.           (USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
  359.             if (ImageBuffers[curBuff].Percent >= nextPercent)
  360.                 {nextPercent += 5;
  361.                 WinPostMsg(hWndFrame,UM_STATUS, MPFROMSHORT(curTh),0);
  362.                 }
  363.         ImageBuffers[curBuff].DskLayout->usHead = hd;
  364.         if (needFormat)  {
  365.           trkfmt->usHead = hd;
  366.           trkfmt->usCylinder = cyl;
  367.           for (i = 0; i < trkfmt->cSectors; i++) {
  368.             trkfmt->FormatTable[i].bHead = (BYTE)hd;
  369.             trkfmt->FormatTable[i].bCylinder = (BYTE)cyl;
  370.           }
  371.  
  372.                 parameterLengthInOut = sizeof(TRACKFORMAT);
  373.                 bufferLengthInOut = sizeof (ULONG);
  374.           if (tcThBufs[curTh].ErrorCode = DosDevIOCtl(hf,
  375.                                                       IOCTL_DISK,
  376.                                                       DSK_FORMATVERIFY,
  377.                                                       trkfmt,
  378.                                                     parameterLengthInOut,
  379.                                                     ¶meterLengthInOut,
  380.                                                     &_fmtData,
  381.                                                     bufferLengthInOut,
  382.                                                     &bufferLengthInOut
  383.                                                     ))
  384.             ThreadErrorHandler(UM_ERROR, curTh, hf);
  385.         }
  386.         DskBuf = MakeHugeP(curBuff,trk+hd);
  387.             parameterLengthInOut = sizeof(ImageBuffers[curBuff].DskLayout);
  388.             bufferLengthInOut = 10000;            /* Just a hopeful guess  */
  389.         if (tcThBufs[curTh].ErrorCode = DosDevIOCtl(hf,
  390.                                     IOCTL_DISK,
  391.                                     DSK_WRITETRACK,
  392.                                     ImageBuffers[curBuff].DskLayout,
  393.                                     parameterLengthInOut,
  394.                                     ¶meterLengthInOut,
  395.                                     DskBuf,
  396.                                     bufferLengthInOut,
  397.                                     &bufferLengthInOut
  398.                                     ))
  399.           ThreadErrorHandler(UM_ERROR, curTh, hf);
  400.       }
  401.     }
  402.     ImageBuffers[curBuff].Percent = 100;
  403.     WinPostMsg(hWndFrame,UM_STATUS, MPFROMSHORT(curTh),0);
  404.     if (needFormat)
  405.         free(trkfmt);
  406.   }
  407.   else {
  408.     ;        /* NOTHING */
  409.   }
  410. unlockdrive (hf);
  411.   if (hf) 
  412.     {UCHAR        parameter = 0,
  413.                 data = 0;
  414.     ULONG        parameterLengthInOut = 1,
  415.                 dataLengthInOut = 1;
  416.  
  417.     rc = DosDevIOCtl ( hf, 8L, 1L, ¶meter, 1L, ¶meterLengthInOut,
  418.             &data, 1l, &dataLengthInOut);
  419.      DosClose(hf);
  420.     }
  421.   DosError(FERR_ENABLEHARDERR);
  422. return;
  423. /*  DosExit(EXIT_THREAD,0);*/
  424. } /*writetarget*/
  425.  
  426.  
  427. /* **************************** bspblkcmp ******************************* */
  428.  
  429.   /* --- compare two BSPBLK structures ---
  430.   **       returns 0 if both are the same except for possibly the
  431.   **        abReserved field, else returns non-zero.
  432.   */
  433. SHORT bspblkcmp(BSPBLK *blk1, BSPBLK *blk2)  {
  434.  
  435. BSPBLK tmp1, tmp2;
  436.  
  437.   tmp1 = *blk1;
  438.   tmp2 = *blk2;
  439.   memset(tmp1.abReserved, 0, 6);
  440.   memset(tmp2.abReserved, 0, 6);
  441.   return memcmp(&tmp1, &tmp2, sizeof(BSPBLK));
  442. }
  443.  
  444. /* ************************** ThreadErrorHandler ************************** */
  445.  
  446. VOID ThreadErrorHandler(USHORT Msg, USHORT curTh, HFILE dHandle)
  447.  
  448. {APIRET        rc;
  449. UCHAR        parameter = 0,
  450.             data = 0;
  451. ULONG        parameterLengthInOut = 1,
  452.             dataLengthInOut = 1;
  453.  
  454.   WinPostMsg(hWndFrame,Msg,MPFROMSHORT(curTh),0);
  455.  
  456.   if (dHandle)
  457.     {
  458.     rc = DosDevIOCtl ( dHandle, 8L, 1L, ¶meter, 1L, ¶meterLengthInOut,
  459.             &data, 1l, &dataLengthInOut);
  460.     DosClose(dHandle);
  461.     }
  462.   DosError(FERR_ENABLEHARDERR);
  463. /*return;*/
  464.   DosExit(EXIT_THREAD, 0);
  465. }
  466.  
  467. /* ************************* SetBufferSel ******************************* */
  468.  
  469. /* Set the selectors for the buffers to hold to disk data*/
  470. /**/
  471. /* returns errnum if an error occurred, else 0*/
  472. /**/
  473. /* sets DskSel & SelOff in ImageBuffers[curBuff]*/
  474. /**/
  475. USHORT SetBufferSel(USHORT curBuff) {
  476.  
  477. USHORT TpSeg;     /* Tracks per Segment*/
  478. USHORT RemT;      /* Remaining tracks*/
  479. USHORT tSeg;      /* total segments*/
  480. USHORT srcT;      /* # tracks on disk*/
  481. USHORT bpT;       /* Bytes per track*/
  482. USHORT sCnt;      /* shift count*/
  483. ULONG  rc;        /* return code from AllocHuge*/
  484.  
  485. rc = 0;
  486.   srcT  = ImageBuffers[curBuff].DskParms.cSectors         /
  487.           ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  488.  
  489.   bpT   = ImageBuffers[curBuff].DskParms.usBytesPerSector *
  490.           ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  491. if (ImageBuffers[curBuff].diskBuffer)
  492.     DosFreeMem (ImageBuffers[curBuff].diskBuffer);
  493. rc = DosAllocMem (&(ImageBuffers[curBuff].diskBuffer), srcT*bpT,
  494.     PAG_COMMIT | PAG_READ | PAG_WRITE);
  495. return (rc? rc:    FALSE);
  496.  
  497. }
  498.  
  499. /* ***************************** MakeHugeP ******************************* */
  500.  
  501. static PBYTE MakeHugeP(USHORT curBuff, USHORT Trk) {
  502.  
  503. USHORT TpSeg;     /* Tracks per Segment*/
  504. USHORT Offs;      /* offset into segment*/
  505. USHORT nSel;      /* number of selector*/
  506. USHORT TSel;      /* Track selector*/
  507. USHORT bpT;       /* Bytes per track*/
  508.  
  509.   bpT   = ImageBuffers[curBuff].DskParms.usBytesPerSector *
  510.           ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  511.  
  512. return (PCHAR)ImageBuffers[curBuff].diskBuffer + bpT * Trk;
  513.  
  514.  
  515. }
  516.  
  517. /* ********************************* LoadImage *************************** */
  518.  
  519. /* Load the disk image.*/
  520. /**/
  521. /*  Note that although it is not used here, we will create the layout*/
  522. /*  table as it is needed by writetarget*/
  523. /**/
  524. VOID APIENTRY LoadImage(ULONG curTh) {
  525.  
  526. USHORT curBuff;
  527. USHORT bpT;            /* Bytes per track*/
  528. USHORT sourceTracks;   /* # tracks on source disk*/
  529. ULONG  sourceBytes;    /* # bytes on source disk*/
  530. USHORT trk;
  531. USHORT hd;
  532. USHORT cyl;
  533. HFILE  hf;
  534. ULONG result;
  535. CHAR   Header[] = "DskImage";
  536. CHAR   NewHead[9];     /* must be size of header*/
  537. PBYTE  DskBuf;         /* huge pointer to track data*/
  538.  
  539.   curBuff = tcThBufs[curTh].ImageNumber;
  540.   tcThBufs[curTh].ErrorCode = 0;
  541.  
  542. /* If this isn't the first time here, free memory from last time first */
  543.   if (ImageBuffers[curBuff].Percent == 100) {
  544.     free(ImageBuffers[curBuff].DskLayout);
  545.   }
  546. ImageBuffers[curBuff].volumeLabel[0] = '\0';
  547.  
  548.   if (tcThBufs[curTh].ErrorCode = DosOpen(ImageBuffers[curBuff].FileName,
  549.                                        &hf,
  550.                                        &result,
  551.                                        0L,
  552.                                        FILE_NORMAL,
  553.                                        FILE_OPEN,
  554.                                        OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE,
  555.                                        NULL
  556.                                        ))
  557.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  558.  
  559. /* read dskim header*/
  560.   if (tcThBufs[curTh].ErrorCode = DosRead(hf,&NewHead,sizeof NewHead,&result))
  561.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  562.  
  563.   if (strcmp(Header,NewHead)) {
  564.     tcThBufs[curTh].ErrorCode = DSKIM_ERROR_WRONG_FILE;
  565.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  566.   }
  567.  
  568. /* read parameter block*/
  569.   if (tcThBufs[curTh].ErrorCode = DosRead(hf,
  570.                                           &ImageBuffers[curBuff].DskParms,
  571.                                           sizeof ImageBuffers[curBuff].DskParms,
  572.                                           &result))
  573.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  574.  
  575.  
  576.   sourceBytes   = (ULONG)(ImageBuffers[curBuff].DskParms.usBytesPerSector) *
  577.                   (ULONG)(ImageBuffers[curBuff].DskParms.cSectors);
  578.   sourceTracks  = ImageBuffers[curBuff].DskParms.cSectors /
  579.                   ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  580.   bpT   = ImageBuffers[curBuff].DskParms.usBytesPerSector *
  581.           ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  582.  
  583.   ImageBuffers[curBuff].usLayoutSize = sizeof(TRACKLAYOUT)   +
  584.                         ((2 * sizeof(USHORT)) *
  585.                         (ImageBuffers[curBuff].DskParms.usSectorsPerTrack - 1));
  586.  
  587.   if (ImageBuffers[curBuff].DskLayout =
  588.       (PTRACKLAYOUT)malloc(ImageBuffers[curBuff].usLayoutSize * sizeof(BYTE))) {
  589.     ImageBuffers[curBuff].DskLayout->bCommand = 1;
  590.     ImageBuffers[curBuff].DskLayout->usFirstSector = 0;
  591.     ImageBuffers[curBuff].DskLayout->cSectors = ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  592.     for (trk = 0; trk < ImageBuffers[curBuff].DskParms.usSectorsPerTrack; trk++) {
  593.       ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorNumber = trk+1;
  594.       ImageBuffers[curBuff].DskLayout->TrackTable[trk].usSectorSize =
  595.                                                                     ImageBuffers[curBuff].DskParms.usBytesPerSector;
  596.     }
  597.   }
  598.   else
  599.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  600.  
  601.  
  602.  
  603.   /* Allocate huge memory to hold the track data*/
  604.   if (tcThBufs[curTh].ErrorCode = SetBufferSel(curBuff))
  605.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  606.  
  607. /* read disk data*/
  608.   for (trk = 0, cyl = 0;
  609.        trk < sourceTracks;
  610.        trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++) {
  611.     for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++) {
  612.       ImageBuffers[curBuff].Percent =
  613.         (USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
  614.       WinPostMsg(hWndFrame,UM_STATUS, MPFROMSHORT(curTh),0);
  615.  
  616.       DskBuf = MakeHugeP(curBuff,trk+hd);
  617.  
  618.       if (tcThBufs[curTh].ErrorCode = DosRead(hf,DskBuf,bpT,&result))
  619.         ThreadErrorHandler(UM_ERROR, curTh, hf);
  620.     }
  621.   }
  622.   ImageBuffers[curBuff].Percent = 100;
  623.   
  624.   if (hf) DosClose(hf);
  625. return;
  626. /*  DosExit(EXIT_THREAD,0);*/
  627. }
  628.  
  629. /* ******************************** SaveImage ************************** */
  630.  
  631. /* Save the following fields*/
  632. /**/
  633. /*  BSPBLK       DskParms*/
  634. /*  PTRACKLAYOUT DskLayout*/
  635. /*  USHORT       usLayoutSize*/
  636.  
  637. VOID APIENTRY SaveImage(ULONG curTh) {
  638.  
  639. USHORT curBuff;
  640. USHORT bpT;            /* Bytes per track*/
  641. USHORT sourceTracks;   /* # tracks on source disk*/
  642. USHORT trk;
  643. USHORT hd;
  644. USHORT cyl;
  645. HFILE  hf;
  646. ULONG result;
  647. ULONG  FileSize;
  648. CHAR   Header[] = "DskImage";
  649. PBYTE  DskBuf;              /* huge pointer to track data*/
  650.  
  651.   curBuff = tcThBufs[curTh].ImageNumber;
  652.   tcThBufs[curTh].ErrorCode = 0;
  653.  
  654. /* calculate file size*/
  655.   sourceTracks  = ImageBuffers[curBuff].DskParms.cSectors         /
  656.                   ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  657.  
  658.   bpT   = ImageBuffers[curBuff].DskParms.usBytesPerSector *
  659.           ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  660.  
  661.   FileSize = (sourceTracks * bpT) +
  662.               sizeof Header +
  663.               sizeof ImageBuffers[curBuff].DskParms;
  664.  
  665.   if (tcThBufs[curTh].ErrorCode = DosOpen(ImageBuffers[curBuff].FileName,
  666.                                        &hf,
  667.                                        &result,
  668.                                        FileSize,
  669.                                        FILE_NORMAL,
  670.                                        FILE_OPEN | FILE_CREATE,
  671.                                        OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYREADWRITE,
  672.                                        NULL
  673.                                        ))
  674.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  675.  
  676. /* write dskim header*/
  677.   if (tcThBufs[curTh].ErrorCode = DosWrite(hf,&Header,sizeof Header,&result))
  678.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  679.  
  680. /* write parameter block*/
  681.   if ((tcThBufs[curTh].ErrorCode = DosWrite(hf,
  682.                                            &ImageBuffers[curBuff].DskParms,
  683.                                            sizeof ImageBuffers[curBuff].DskParms,
  684.                                            &result)))
  685.     ThreadErrorHandler(UM_ERROR, curTh, hf);
  686.  
  687. /* write disk data*/
  688.   for (trk = 0, cyl = 0;
  689.        trk < sourceTracks;
  690.        trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++) {
  691.     for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++) {
  692.       ImageBuffers[curBuff].Percent =
  693.         (USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
  694.       WinPostMsg(hWndFrame,UM_STATUS, MPFROMSHORT(curTh),0);
  695.  
  696.       DskBuf = MakeHugeP(curBuff,trk+hd);
  697.  
  698.       if ( (tcThBufs[curTh].ErrorCode = DosWrite(hf,DskBuf,bpT,&result)))
  699.         ThreadErrorHandler(UM_ERROR, curTh, hf);
  700.     }
  701.   }
  702.   ImageBuffers[curBuff].Percent = 100;
  703.   
  704.   if (hf) DosClose(hf);
  705. return;
  706. /*  DosExit(EXIT_THREAD,0);*/
  707. }
  708.  
  709. /* ******************************** CompImages *************************** */
  710.  
  711. VOID APIENTRY CompImages(ULONG curTh) {
  712.  
  713. USHORT curBuff;
  714. USHORT compBuff;
  715. USHORT bpT;            /* Bytes per track*/
  716. USHORT sourceTracks;   /* # tracks on source disk*/
  717. USHORT trk;
  718. USHORT hd;
  719. USHORT cyl;
  720. HFILE  hf;              /* only needed for error handling*/
  721. PBYTE  DskBuf1;         /* huge pointer to track data*/
  722. PBYTE  DskBuf2;         /* huge pointer to track data*/
  723. int        nextPercent = 0;
  724.  
  725.   curBuff = tcThBufs[curTh].ImageNumber;
  726.   compBuff = tcThBufs[curTh].CompNumber;
  727.   tcThBufs[curTh].ErrorCode = 0;
  728.  
  729. /* compare BPB*/
  730.  
  731.   if (memcmp(&(ImageBuffers[curBuff].DskParms),
  732.              &(ImageBuffers[compBuff].DskParms),
  733.              sizeof(BSPBLK))) {
  734.     ThreadErrorHandler(UM_COMPERR, curTh, hf);
  735.     return;
  736. /*    DosExit(EXIT_THREAD,0);*/
  737.   }
  738.  
  739. /* compare data*/
  740.   sourceTracks  = ImageBuffers[curBuff].DskParms.cSectors         /
  741.                   ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  742.  
  743.   bpT   = ImageBuffers[curBuff].DskParms.usBytesPerSector *
  744.           ImageBuffers[curBuff].DskParms.usSectorsPerTrack;
  745.  
  746.   for (trk = 0, cyl = 0;
  747.        trk < sourceTracks;
  748.        trk += ImageBuffers[curBuff].DskParms.cHeads, cyl++) {
  749.     for (hd = 0; hd < ImageBuffers[curBuff].DskParms.cHeads; hd++) {
  750.       ImageBuffers[curBuff].Percent =
  751.         (USHORT)(((float)((cyl*2)+hd)/(float)sourceTracks)*100.0);
  752.         if(ImageBuffers[curBuff].Percent >= nextPercent)
  753.             {nextPercent += 10;
  754.       WinPostMsg(hWndFrame,UM_STATUS, MPFROMSHORT(curTh),0);
  755.             }
  756.  
  757.       DskBuf1 = MakeHugeP(curBuff,trk+hd);
  758.       DskBuf2 = MakeHugeP(compBuff,trk+hd);
  759.  
  760.       if (memcmp(DskBuf1,DskBuf2,bpT)) {
  761.         ThreadErrorHandler(UM_COMPERR, curTh, hf);
  762.             return;
  763. /*        DosExit(EXIT_THREAD,0);*/
  764.       }
  765.     }
  766.   }
  767.   ImageBuffers[curBuff].Percent = 100;
  768.   WinPostMsg(hWndFrame,UM_STATUS, MPFROMSHORT(curTh),0);
  769.   WinPostMsg(hWndFrame,UM_COMPOK,MPFROMSHORT(curTh),0);
  770. return;
  771. /*  DosExit(EXIT_THREAD,0);*/
  772. } /* CompImages*/
  773.