|
|
/****************************************************************************/ /* */ /* WFDCOPY.C - */ /* */ /* File Manager Diskette Copying Routines */ /* */ /****************************************************************************/
#include "winfile.h"
LONG APIENTRY LongPtrAdd(LPSTR, DWORD);
PBPB GetBootBPB(INT nSrceDrive); PBPB GetBPB(INT nDrive, PDevPB pDevicePB); BOOL CheckBPBCompatibility(PBPB pSrceBPB, int nSrcDriveType, PBPB pDestBPB, int nDestDriveType);
BOOL ModifyDeviceParams( INT nDrive, PDevPB pdpbParams, HANDLE *phSaveParams, PBPB pDriveBPB, PBPB pMediaBPB);
BOOL FormatAllTracks( PDISKINFO pDisketteInfo, WORD wStartCylinder, WORD wStartHead, LPSTR lpDiskBuffer);
BOOL AllocDiskCopyBuffers(PDISKINFO pDisketteInfo); VOID FreeBuffers(VOID); VOID GetDisketteInfo(PDISKINFO pDisketteInfo, PBPB pBPB); VOID DCopyMessageBox(HWND hwnd, WORD idString, WORD wFlags); VOID PromptDisketteChange(HWND hwnd, BOOL bWrite); INT ReadWriteMaxPossible(BOOL bWrite, WORD wStartCylinder, PDISKINFO pDisketteInfo); INT ReadWrite(BOOL bWrite, WORD wStartCylinder, PDISKINFO pDisketteInfo); BOOL RestoreDPB(INT nDisk, HANDLE hSavedParams); INT ReadWriteCylinder(BOOL bWrite, WORD wCylinder, PDISKINFO pDisketteInfo);
/* The following structure is the Parameter block for the read-write
* operations using the IOCTL calls in DOS */ struct RW_PARMBLOCK { BYTE bSplFn; WORD wHead; WORD wCylinder; WORD wStSector; WORD wCount; LPSTR lpBuffer; };
/* Global Variables */ BOOL bFormatDone; BOOL bSingleDrive = TRUE; WORD wCompletedCylinders = 0; DWORD dwDisketteBufferSize; LPSTR lpDosMemory; LPSTR lpFormatBuffer; LPSTR lpReadWritePtr; LPSTR hpDisketteBuffer; HANDLE hFormatBuffer; HANDLE hDosMemory; HANDLE hDisketteBuffer; PDevPB pTrackLayout; /* DevPB with the track layout */ BOOTSEC BootSec;
/* External Variables */ extern BPB bpbList[];
/*--------------------------------------------------------------------------*/ /* */ /* GetBootBPB() - */ /* */ /*--------------------------------------------------------------------------*/
/* This reads the boot sector of a floppy and returns a ptr to
* the BIOS PARAMETER BLOCK in the Boot sector. */
PBPB GetBootBPB( INT nSrceDrive ) { INT rc;
/* Make sure that the source diskette's boot sector is valid. */ rc = GenericReadWriteSector((LPSTR)&BootSec, INT13_READ, (WORD)nSrceDrive, 0, 0, 1);
if ((rc < 0) || ((BootSec.jump[0] != 0xE9) && (BootSec.jump[0] != 0xEB))) return (PBPB)NULL;
return (PBPB)&(BootSec.BPB); }
/*--------------------------------------------------------------------------*/ /* */ /* GetBPB() - */ /* */ /*--------------------------------------------------------------------------*/
/* Gets get the BPB of the Physical Drive.
* * This uses the IOCTL calls if DOS ver >= 3.2; Otherwise it uses the * BIOS calls to find out the drive type and picks us the BPB from a table. * It also returns the DeviceParameterBlock thro params if DOS >= 3.2. * Sets devType field of DeviceParameterBlock in any case (11.12.91) v-dougk */
PBPB GetBPB( INT nDrive, PDevPB pDevicePB ) { INT iDisketteType; PBPB pBPB = NULL;
/* Check the DOS version */ if (wDOSversion >= DOS_320) { /* All fields in pDevicePB must be initialized to zero. */ memset(pDevicePB, 0, sizeof(DevPB));
/* Spl Function field must be set to get parameters */ pDevicePB->SplFunctions = 0; pBPB = &(pDevicePB->BPB); } else { /* Find out the Drive type using the BIOS. */ if ((iDisketteType = GetDriveCapacity((WORD)nDrive)) == 0) goto GBPB_Error;
/* Lookup this drive's default BPB. */ pBPB = &bpbList[iDisketteType+2];
switch (iDisketteType) { case 1: pDevicePB->devType = 0; // 360K
break; case 2: pDevicePB->devType = 1; // 1.2M
break; } }
GBPB_Error: return (pBPB); }
/*--------------------------------------------------------------------------*/ /* */ /* CheckBPBCompatibility() - */ /* */ /*--------------------------------------------------------------------------*/
/* Checks whether the two BPB are compatible for the purpose of performing
* the diskcopy operation. */
BOOL CheckBPBCompatibility( PBPB pSrceBPB, int nSrcDriveType, PBPB pDestBPB, int nDestDriveType ) { /* Let us compare the media byte */ if (pSrceBPB->bMedia == 0xF9) { /* If the source and dest have the same number of sectors,
* or if srce is 720KB and Dest is 1.44MB floppy drive, * thnigs are kosher. */ if ((pSrceBPB->cSec == pDestBPB->cSec) || ((pSrceBPB->secPerTrack == 9) && (pDestBPB -> bMedia == 0xF0))) return (TRUE); } else { /* If they have the same media byte */ if ((pSrceBPB->bMedia == pDestBPB->bMedia) && (pSrceBPB->cbSec == pDestBPB->cbSec) && // bytes per sector are the same
(pSrceBPB->cSec == pDestBPB->cSec)) // total sectors on drive are the same
return (TRUE); /* They are compatible */ else if /* srce is 160KB and dest is 320KB drive */ (((pSrceBPB->bMedia == MEDIA_160) && (pDestBPB->bMedia == MEDIA_320)) || /* or if srce is 180KB and dest is 360KB drive */ ((pSrceBPB->bMedia == MEDIA_180) && (pDestBPB->bMedia == MEDIA_360)) || /* or if srce is 1.44MB and dest is 2.88MB drive */ ((pSrceBPB->bMedia == MEDIA_1440) && (pDestBPB->bMedia == MEDIA_2880) && ((nSrcDriveType == 7) || (nSrcDriveType == 9)) && (nDestDriveType == 9)) || /* or if srce is 360KB and dest is 1.2MB drive */ ((pSrceBPB->bMedia == MEDIA_360) && (pDestBPB->secPerTrack == 15))) return (TRUE); /* They are compatible */ }
/* All other combinations are currently incompatible. */ return (FALSE); }
/*--------------------------------------------------------------------------*/ /* */ /* ModifyDeviceParams() - */ /* */ /*--------------------------------------------------------------------------*/
/* Saves a copy of the drive parameters block and
* Checks if the BPB of Drive and BPB of disk are different and if * so, modifies the drive parameter block accordingly. */
BOOL ModifyDeviceParams( INT nDrive, PDevPB pdpbParams, HANDLE *phSaveParams, PBPB pDriveBPB, PBPB pMediaBPB) { INT iDriveCode; HANDLE hNewDPB; PDevPB pNewDPB;
if (!(*phSaveParams = BuildDevPB(pdpbParams))) return FALSE;
/* Check if the Disk and Drive have the same parameters */ if (pMediaBPB->bMedia != pDriveBPB->bMedia) { /* They are not equal; So, it must be a 360KB floppy in a 1.2MB drive
* or a 720KB floppy in a 1.44MB drive kind of situation!. * So, modify the DriveParameterBlock's BPB. */ *(PBPB)&(pdpbParams->BPB) = *pMediaBPB; }
if (wDOSversion >= DOS_320) { /* Build a DPB with TrackLayout */ if (!(hNewDPB = BuildDevPB(pdpbParams))) goto MDP_Error;
pNewDPB = (PDevPB)LocalLock(hNewDPB);
pNewDPB->SplFunctions = 4; /* To Set parameters */
/* Check if this is a 360KB floppy; And if it is a 1.2MB drive, the
* number of cylinders and mediatype field are wrong; So, we modify * these fields here anyway; * This is required to format a 360KB floppy on a NCR PC916 machine; * Fix for Bug #6894 --01-10-90-- SANKAR */ if (pMediaBPB->bMedia == MEDIA_360) { pNewDPB->NumCyls = 40; pNewDPB->bMediaType = 1; }
LocalUnlock(hNewDPB); LocalFree(hNewDPB); } else { iDriveCode = 0; switch (pMediaBPB->bMedia) { case MEDIA_360: case MEDIA_320: if ((pDriveBPB->bMedia == MEDIA_360) || (pDriveBPB->bMedia == MEDIA_320)) iDriveCode = 1; /* Must be 360/320KB in 360KB drive */ else iDriveCode = 2; /* Must be 360/320Kb in 1.2MB drive */ break;
case MEDIA_1200: iDriveCode = 3; /* Must be 1.2MB in 1.2MB drive */ break; } if (iDriveCode) SetDASD((WORD)nDrive, (BYTE)iDriveCode); } return (TRUE);
/* Error handling */ MDP_Error: if (hNewDPB) LocalFree(hNewDPB); if (*phSaveParams) { LocalFree(*phSaveParams); *phSaveParams = NULL; } return (FALSE); }
/*--------------------------------------------------------------------------*/ /* */ /* FormatAllTracks() - */ /* */ /*--------------------------------------------------------------------------*/
BOOL FormatAllTracks( PDISKINFO pDisketteInfo, WORD wStartCylinder, WORD wStartHead, LPSTR lpDiskBuffer) { INT iErrCode; BOOL bRetValue = TRUE; WORD wTotalCylinders; WORD wSecPerTrack; WORD wHeads; WORD wDrive;
LoadString(hAppInstance, IDS_FORMATTINGDEST, szMessage, 128); SendDlgItemMessage(hdlgProgress, IDD_PROGRESS, WM_SETTEXT, 0, (LPARAM)szMessage);
bFormatDone = TRUE; wDrive = pDisketteInfo->wDrive;
if (wDOSversion >= DOS_320) { pTrackLayout->SplFunctions = 5; } else { if ((pTrackLayout->BPB.bMedia == 0xF9) && /* high density */ (pTrackLayout->BPB.secPerTrack == 15)) /* 1.2 Meg Drive */ SetDASD(wDrive, 3); /* 1.2 MB floppy in 1.2MB drive */ }
wTotalCylinders = pDisketteInfo->wLastCylinder + 1; wSecPerTrack = pDisketteInfo->wSectorsPerTrack; wHeads = pDisketteInfo->wHeads;
/* Format tracks one by one, checking if the user has "Aborted"
* after each track is formatted; DlgProgreeProc() will set the global * bUserAbort, if the user has aborted; */ while (wStartCylinder < wTotalCylinders) { /* Has the user aborted? */ if (WFQueryAbort()) { bRetValue = FALSE; break; }
/* If no message is pending, go ahead and format one track */ if ((iErrCode = GenericFormatTrack(wDrive, wStartCylinder, wStartHead, wSecPerTrack, lpDiskBuffer))) { /* Check if it is a fatal error */ if (iErrCode == -1) { bRetValue = FALSE; break; } }
if (++wStartHead >= wHeads) { wStartHead = 0; wStartCylinder++; } }
if (wDOSversion >= DOS_320) { pTrackLayout->SplFunctions = 4; }
return (bRetValue); }
/*--------------------------------------------------------------------------*/ /* */ /* GenericReadWriteSector() - */ /* */ /*--------------------------------------------------------------------------*/
/* Checks the DOS version number; If it is >= 3.2, then IOCTL
* calls are made to read/write; Else it calls int13 read/write. */
INT APIENTRY GenericReadWriteSector( LPSTR lpBuffer, WORD wFunction, WORD wDrive, WORD wCylinder, WORD wHead, WORD wCount) { struct RW_PARMBLOCK RW_ParmBlock;
/* If the DOS version is >= 3.2, we use DOS IOCTL function calls. */ if (wDOSversion >= DOS_320) { RW_ParmBlock.bSplFn = 0; RW_ParmBlock.wHead = wHead; RW_ParmBlock.wCylinder = wCylinder; RW_ParmBlock.wStSector = 0; RW_ParmBlock.wCount = wCount; RW_ParmBlock.lpBuffer = lpBuffer;
return (0); } else /* Use Int13 function calls. */ return (MyReadWriteSector(lpBuffer, wFunction, wDrive, wCylinder, wHead, wCount)); }
/*--------------------------------------------------------------------------*/ /* */ /* AllocDiskCopyBuffers() - */ /* */ /*--------------------------------------------------------------------------*/
BOOL AllocDiskCopyBuffers( PDISKINFO pDisketteInfo ) { HANDLE hMemTemp;
ENTER("AllocDiskCopyBuffers");
hFormatBuffer = LocalAlloc(LHND, (LONG)(2*CBSECTORSIZE)); if (!hFormatBuffer) return FALSE; lpFormatBuffer = (LPSTR)LocalLock(hFormatBuffer);
// We will try to reserve 16K for dialog boxes that comeup during diskcopy
hMemTemp = LocalAlloc(LHND, (16 * 1024)); if (!hMemTemp) goto Failure;
hDosMemory = (HANDLE)NULL;
// now, lets try to allocate a buffer for the whole disk, and
// if that fails try smaller
// note, standard mode will only give us 1M chuncks
dwDisketteBufferSize = pDisketteInfo->wCylinderSize * (pDisketteInfo->wLastCylinder + 1);
// we will try down to 8 cylinders worth, less than that means
// there will be too much disk swapping so don't bother
do { hDisketteBuffer = LocalAlloc(LHND, dwDisketteBufferSize);
if (hDisketteBuffer) { hpDisketteBuffer = (LPSTR)LocalLock(hDisketteBuffer); break; } else { // reduce request by 4 cylinders.
dwDisketteBufferSize -= pDisketteInfo->wCylinderSize * 4; }
} while (dwDisketteBufferSize > (DWORD)(8 * pDisketteInfo->wCylinderSize));
LocalFree(hMemTemp); // now free this up for user
if (hDisketteBuffer) return TRUE;
// fall through here to the failure case
Failure:
if (lpFormatBuffer) { LocalUnlock(hFormatBuffer); LocalFree(hFormatBuffer); }
if (hDosMemory) // +++GlobalDosFree - NO 32BIT FORM+++(hDosMemory);
LocalFree(hDosMemory);
LEAVE("AllocDiskCopyBuffers"); return FALSE; }
/*--------------------------------------------------------------------------*/ /* */ /* FreeBuffers() - */ /* */ /*--------------------------------------------------------------------------*/
VOID FreeBuffers() { if (lpFormatBuffer) { LocalUnlock(hFormatBuffer); LocalFree(hFormatBuffer); }
if (hDosMemory) // +++GlobalDosFree - NO 32BIT FORM+++(hDosMemory);
LocalFree(hDosMemory);
if (hpDisketteBuffer) { LocalUnlock(hDisketteBuffer); LocalFree(hDisketteBuffer); } }
/*--------------------------------------------------------------------------*/ /* */ /* GetDisketteInfo() - */ /* */ /*--------------------------------------------------------------------------*/
VOID GetDisketteInfo( PDISKINFO pDisketteInfo, PBPB pBPB ) { WORD secPerTrack;
secPerTrack = pBPB->secPerTrack;
/* Fill the DisketteInfo with the info from the default BPB. */ pDisketteInfo->wCylinderSize = secPerTrack * pBPB->cbSec * pBPB->cHead; pDisketteInfo->wLastCylinder = (pBPB->cSec / (secPerTrack * pBPB->cHead))-1; pDisketteInfo->wHeads = pBPB->cHead; pDisketteInfo->wSectorsPerTrack = secPerTrack; pDisketteInfo->wSectorSize = pBPB->cbSec;
}
/*--------------------------------------------------------------------------*/ /* */ /* DCopyMessageBox() - */ /* */ /*--------------------------------------------------------------------------*/
VOID DCopyMessageBox( HWND hwnd, WORD idString, WORD wFlags ) { LoadString(hAppInstance, IDS_COPYDISK, szTitle, sizeof(szTitle)); LoadString(hAppInstance, idString, szMessage, sizeof(szMessage));
MessageBox(hwnd, szMessage, szTitle, wFlags); }
/*--------------------------------------------------------------------------*/ /* */ /* PromptDisketteChange() - */ /* */ /*--------------------------------------------------------------------------*/
VOID PromptDisketteChange( HWND hwnd, BOOL bWrite ) { WORD idString;
if (bWrite) idString = IDS_INSERTDEST; else idString = IDS_INSERTSRC;
/* These dialogs have to be sysmodal because the DiskCopy progress dialog
* is now made a SysModal one; The following messagebox will hang if it * is NOT sysmodal; * A part of the Fix for Bug #10075 --SANKAR-- 03-05-90 */ DCopyMessageBox(hwnd, idString, MB_OK | MB_SYSTEMMODAL | MB_ICONINFORMATION); }
/*--------------------------------------------------------------------------*/ /* */ /* ReadWriteCylinder() - */ // BOOL bWrite; TRUE for Write, FALSE for Read
/* */ /*--------------------------------------------------------------------------*/
INT ReadWriteCylinder( BOOL bWrite, WORD wCylinder, PDISKINFO pDisketteInfo ) { register INT rc; WORD wHead; WORD wDrive; WORD wSectorCount; WORD wTrackSize; LPSTR lpBuffer;
wDrive = pDisketteInfo->wDrive; wSectorCount = pDisketteInfo->wSectorsPerTrack; wTrackSize = (wSectorCount * pDisketteInfo->wSectorSize);
if (hDosMemory) lpBuffer = lpDosMemory;
/* Perform the operation for all the heads for a given cylinder */ for (wHead=0; wHead < pDisketteInfo->wHeads; wHead++) { if (!hDosMemory) lpBuffer = lpReadWritePtr;
if (bWrite) { if (hDosMemory) memcpy(lpBuffer, lpReadWritePtr, wTrackSize);
rc = GenericReadWriteSector((LPSTR)lpBuffer, INT13_WRITE, wDrive, wCylinder, wHead, wSectorCount); if (rc) { /* Format all tracks starting from the given track */ if (!bFormatDone) { if (!FormatAllTracks(pDisketteInfo, wCylinder, wHead, lpFormatBuffer)) return (-1); /* Failure */ rc = GenericReadWriteSector((LPSTR)lpBuffer, INT13_WRITE, wDrive, wCylinder, wHead, wSectorCount); } else break; } } else { rc = GenericReadWriteSector((LPSTR)lpBuffer, INT13_READ, wDrive, wCylinder, wHead, wSectorCount); if (hDosMemory) memcpy(lpReadWritePtr, lpBuffer, wTrackSize);
/*** FIX30: What about the DOS 4.0 volume stuff??? ***/ }
if (rc) return (-1);
lpReadWritePtr += wTrackSize; } return (0); }
/*--------------------------------------------------------------------------*/ /* */ /* ReadWriteMaxPossible() - */ // BOOL bWrite TRUE for Write, FALSE for Read
/* */ /*--------------------------------------------------------------------------*/
/* This reads or writes as many cylinders as possible into the hpDisketteBuffer.
* It returns the next cylinder to be read. */
INT ReadWriteMaxPossible( BOOL bWrite, WORD wStartCylinder, PDISKINFO pDisketteInfo ) { MSG msg; WORD wPercentDone; DWORD dwBufferSize;
dwBufferSize = dwDisketteBufferSize;
/* We will read a cylinder only if we can read the entire cylinder. */ while (dwBufferSize >= pDisketteInfo->wCylinderSize) { /* Check if any messages are pending */ if (!PeekMessage((LPMSG)&msg, (HWND)NULL, 0, 0, PM_REMOVE)) { /* No message; So, go ahead with read/write */ if (ReadWriteCylinder(bWrite, wStartCylinder, pDisketteInfo)) return (-1);
wStartCylinder++; wCompletedCylinders++;
/* Have we read/written all the cylinders? */ if (wStartCylinder > pDisketteInfo->wLastCylinder) break;
/* Since each cylinder is counted once during read and once during
* write, number of cylinders is multiplied by 50 and not 100. */ wPercentDone = (wCompletedCylinders * 50) / (pDisketteInfo->wLastCylinder + 1); if (LoadString(hAppInstance, IDS_PERCENTCOMP, szTitle, 32)) { wsprintf(szMessage, szTitle, wPercentDone); SendDlgItemMessage(hdlgProgress, IDD_PROGRESS, WM_SETTEXT, 0, (LPARAM)szMessage); }
dwBufferSize -= pDisketteInfo->wCylinderSize; } else { /* Check if this is a message for the ProgressDlg */ if (!IsDialogMessage(hdlgProgress, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { /* That message might have resulted in a Abort */ if (bUserAbort) return (-1); } } } return (wStartCylinder); }
/*--------------------------------------------------------------------------*/ /* */ /* ReadWrite() - */ // BOOL bWrite TRUE for Write, FALSE for Read
/* */ /*--------------------------------------------------------------------------*/
/* This reads or writes as many cylinders as possible into the hpDisketteBuffer.
* It returns the next cylinder to be read. */
INT ReadWrite( BOOL bWrite, WORD wStartCylinder, PDISKINFO pDisketteInfo ) { INT iRetVal = 0; return (iRetVal); }
/*--------------------------------------------------------------------------*/ /* */ /* RestoreDPB() - */ /* */ /*--------------------------------------------------------------------------*/
BOOL RestoreDPB( INT nDisk, HANDLE hSavedParams ) { register PDevPB pDevPB;
if (!(pDevPB = (PDevPB)LocalLock(hSavedParams))) return (FALSE);
pDevPB->SplFunctions = 4; LocalUnlock(hSavedParams); LocalFree(hSavedParams); return (TRUE); }
/*--------------------------------------------------------------------------*/ /* */ /* CopyDiskette() - */ /* */ /*--------------------------------------------------------------------------*/
/* NOTE: Returns positive value for success otherwise failure. */
INT APIENTRY CopyDiskette( HWND hwnd, WORD nSourceDisk, WORD nDestDisk ) { INT rc = -1; register WORD wCylinder; WORD wNextCylinder; PBPB pIoctlBPB; /* Source Drive's BPB (taken from DevicePB) */ PBPB pBootBPB; /* Boot Drive's BPB (taken from Boot sector) */ PBPB pDestBPB; DevPB dpbSrceParams; DevPB dpbDestParams; HANDLE hTrackLayout = NULL; HANDLE hSaveSrceParams; HANDLE hSaveDestParams; FARPROC lpfnDialog; DISKINFO SourceDisketteInfo; DISKINFO DestDisketteInfo;
/* Check if it is a two drive system; put message to insert both floppies */ if (nSourceDisk != nDestDisk) { bSingleDrive = FALSE; DCopyMessageBox(hwnd, IDS_INSERTSRCDEST, MB_OK); } else { bSingleDrive = TRUE; DCopyMessageBox(hwnd, IDS_INSERTSRC, MB_OK); }
/* Get the BiosParameterBlock of source drive */ if (!(pIoctlBPB = GetBPB(nSourceDisk, &dpbSrceParams))) return (0);
/* Get the BiosParameterBlock of the Source Diskette */ if (!(pBootBPB = GetBootBPB(nSourceDisk))) return (0);
/* Get the BPB and DPB for the Destination drive also; */ if (!bSingleDrive) { if (!(pDestBPB = GetBPB(nDestDisk, &dpbDestParams))) return (0);
/* Compare BPB of source and Dest to see if they are compatible */ if (!(CheckBPBCompatibility(pIoctlBPB, dpbSrceParams.devType, pDestBPB, dpbDestParams.devType))) { DCopyMessageBox(hwnd, IDS_COPYSRCDESTINCOMPAT, MB_ICONHAND | MB_OK); return (0); } }
if (!ModifyDeviceParams(nSourceDisk, &dpbSrceParams, &hSaveSrceParams, pIoctlBPB, pBootBPB)) return (0);
if (!bSingleDrive) { if (!ModifyDeviceParams(nDestDisk, &dpbDestParams, &hSaveDestParams, pDestBPB, pBootBPB)) { RestoreDPB(nSourceDisk, hSaveSrceParams); return (0); } }
GetDisketteInfo((PDISKINFO)&SourceDisketteInfo, pBootBPB);
/* The Destination Diskette must have the same format as the source */ DestDisketteInfo = SourceDisketteInfo;
/* Except the drive number */ SourceDisketteInfo.wDrive = nSourceDisk; DestDisketteInfo.wDrive = nDestDisk;
/* In case we need to format the destination diskette, we need to know the
* track layout; So, build a DPB with the required track layout; */ if (wDOSversion >= DOS_320) { if (!(hTrackLayout = BuildDevPB(&dpbSrceParams))) goto Failure0;
pTrackLayout = (PDevPB)LocalLock(hTrackLayout);
/* The following is required to format a 360KB floppy in a 1.2MB
* drive of NCR PC916 machine; We do formatting, if the destination * floppy is an unformatted one; * Fix for Bug #6894 --01-10-90-- SANKAR -- */ if (pTrackLayout->BPB.bMedia == MEDIA_360) { pTrackLayout->NumCyls = 40; pTrackLayout->bMediaType = 1; } }
/* We wish we could do the following allocation at the begining of this
* function, but we can not do so, because we need SourceDisketteInfo * and we just got it; */ if (!AllocDiskCopyBuffers((PDISKINFO)&SourceDisketteInfo)) { DCopyMessageBox(hwnd, IDS_REASONS+DE_INSMEM, MB_ICONHAND | MB_OK); goto Failure0; }
bUserAbort = FALSE; wCompletedCylinders = 0;
hdlgProgress = CreateDialog(hAppInstance, (LPSTR)MAKEINTRESOURCE(DISKCOPYPROGRESSDLG), hwnd, ProgressDlgProc); if (!hdlgProgress) goto Failure2;
EnableWindow(hwnd, FALSE);
/* Start with the first cylinder. */ wCylinder = 0; while (wCylinder <= SourceDisketteInfo.wLastCylinder) { /* If this is a single drive system, ask the user to insert
* the source diskette. * Do not prompt for the first time, because the Source diskette is * already in the drive. */ if (bSingleDrive && (wCylinder > 0)) PromptDisketteChange(hdlgProgress, FALSE);
/* Read in the current cylinder. */ rc = ReadWrite(FALSE, wCylinder, (PDISKINFO)&SourceDisketteInfo); if (rc < 0) break; else wNextCylinder = (WORD)rc;
/* If this is a single drive system, ask the user to insert
* the destination diskette. */ if (bSingleDrive) PromptDisketteChange(hdlgProgress, TRUE);
/* Write out the current cylinder. */ bFormatDone = FALSE; rc = ReadWrite(TRUE, wCylinder, (PDISKINFO)&DestDisketteInfo); if (rc < 0) break;
wCylinder = wNextCylinder; }
EnableWindow(hwnd, TRUE); DestroyWindow(hdlgProgress); hdlgProgress = NULL; Failure2: FreeBuffers(); Failure0: if (wDOSversion >= DOS_320) { /* Reset the Source drive parameters to the same as old */ RestoreDPB(nSourceDisk, hSaveSrceParams); if (!bSingleDrive) { /* Reset the Dest drive parameters to the same as old */ RestoreDPB(nDestDisk, hSaveDestParams); } }
if ((wDOSversion >= DOS_320) && hTrackLayout) { LocalUnlock(hTrackLayout); LocalFree(hTrackLayout); }
return (rc); }
|