📄 floppyimagedlg.cpp
字号:
nState = stUnlockVolume; // next state: unlock volume
UpdateData(FALSE);
break;
}
case stUnlockVolume: // unlock volume
{
m_strUnlockVolume.Format("Unlocking volume ... ");
UpdateData(FALSE);
bResult = ::UnlockVolume(hDrive);
if(bResult)
{
m_strUnlockVolume += "OK";
}
else
{
m_strUnlockVolume += "failed";
}
nState = stCloseDrive; // next state: close drive
UpdateData(FALSE);
break;
}
case stCloseDrive: // close drive
{
m_strCloseDrive.Format("Closing drive ... ");
UpdateData(FALSE);
bResult = ::CloseHandle(hDrive);
if(bResult)
{
m_strCloseDrive += "OK";
}
else
{
m_strCloseDrive += "failed";
}
UpdateData(FALSE);
nState = stExit; // all done, next state: exit while loop
}
}
}
file.Close();
}
void CFloppyImageDlg::OnWriteFloppy()
{
// TODO: Add your control notification handler code here
HANDLE hDrive; // handle of drive
DISK_GEOMETRY Geometry; // disk geometry
DISK_GEOMETRY GeometryImg; // disk geometry read from image file
CString strFilePath; // full path of disk image file
BOOL bResult; // return value of IOCTRL
CFile file; // disk image file
enum {
stOpenDrive,
stLockVolume,
stGetGeometry,
stFormatDisk,
stWriteFloppy,
stDismountVolume,
stUnlockVolume,
stCloseDrive,
stExit
} nState; // state machine of processing
m_strOpenDrive = _T("");
m_strLockVolume = _T("");
m_strGetGeometry = _T("");
m_strProcessFloppy = _T("");
m_strDismountVolume = _T("");
m_strUnlockVolume = _T("");
m_strCloseDrive = _T("");
UpdateData(FALSE);
m_ctrlProgress.SetPos(0);
// use a file dialog to get the image file name to load
CFileDialog dlgLoad(FALSE, "*.img",
NULL,
0,
"Floppy image files (*.img)|*.img|All Files (*.*)|*.*||");
dlgLoad.m_ofn.lpstrTitle = "Load floppy image file";
if(dlgLoad.DoModal() != IDOK)
{
return;
}
strFilePath = dlgLoad.GetPathName();
// open a diak image file
if(!file.Open(strFilePath, CFile::typeBinary|CFile::modeRead))
{
CString strTmp;
strTmp.Format("Cannot open file %s!", strFilePath);
AfxMessageBox(strTmp);
return;
}
// read disk geometry from image file
file.Read(&GeometryImg, sizeof(DISK_GEOMETRY));
// wait cursor
CWaitCursor Wait;
nState = stOpenDrive;
// process loop
while (nState != stExit)
{
switch(nState)
{
case stOpenDrive: // open drive
{
m_strOpenDrive.Format("Opening drive ... ");
UpdateData(FALSE);
hDrive=::OpenDisk("\\\\.\\A:");
if(hDrive != INVALID_HANDLE_VALUE)
{
m_strOpenDrive += "OK";
nState = stLockVolume; // success, next state: lock volume
}
else
{
m_strOpenDrive += "failed";
nState = stExit; // failed, next state: exit
}
UpdateData(FALSE);
break;
}
case stLockVolume: // lock volume
{
m_strLockVolume.Format("Locking volume ... ");
UpdateData(FALSE);
bResult = ::LockVolume(hDrive);
if(bResult)
{
m_strLockVolume += "OK";
nState = stGetGeometry; // success, next state: get geometry
}
else
{
m_strLockVolume += "failed";
nState = stCloseDrive; // failed, next state: close drive
}
UpdateData(FALSE);
break;
}
case stGetGeometry: // // get geometry
{
m_strGetGeometry.Format("Getting geometry ... ");
UpdateData(FALSE);
bResult = ::GetDiskGeometry(hDrive, &Geometry);
if(bResult)
{
// calculate the cylinder size of geometry read from file and disk,
// Check to see if the image will fit on the floppy
DWORD dwSize = Geometry.Cylinders.LowPart * Geometry.TracksPerCylinder *
Geometry.SectorsPerTrack * Geometry.BytesPerSector;
DWORD dwSizeImg = GeometryImg.Cylinders.LowPart * GeometryImg.TracksPerCylinder *
GeometryImg.SectorsPerTrack * GeometryImg.BytesPerSector;
m_strGetGeometry += "OK";
if(dwSize != dwSizeImg)
{
nState = stFormatDisk; // need format, next state: format floppy disk
}
else
{
nState = stWriteFloppy; // format ok, next state: write to floppy disk
}
}
else
{
m_strGetGeometry += "failed";
nState = stUnlockVolume; // failed, next state: unlock volume
}
UpdateData(FALSE);
break;
}
case stFormatDisk: // format floppy disk
{
m_strProcessFloppy.Format("Fomatting floppy disk ... ");
UpdateData(FALSE);
m_ctrlProgress.SetRange(0, (short)GeometryImg.Cylinders.LowPart);
// Format one cylinder each step, in order to display in the progress bar
for(DWORD dwCylinder=0; dwCylinder<Geometry.Cylinders.LowPart; dwCylinder++)
{
bResult = ::LowLevelFormatTracks(hDrive, &GeometryImg, dwCylinder, 1);
m_ctrlProgress.StepIt();
if(!bResult) break;
}
if(bResult)
{
m_strProcessFloppy += "OK";
nState = stWriteFloppy; // success, next state: write floppy
}
else
{
m_strProcessFloppy += "failed";
nState = stDismountVolume; // failed, next state: dismount volume
}
UpdateData(FALSE);
break;
}
case stWriteFloppy: // Read from image file and write to floppy
{
m_strProcessFloppy.Format("Writing floppy ... ");
UpdateData(FALSE);
m_ctrlProgress.SetRange(0, (short)Geometry.Cylinders.LowPart);
// calculate buffer size needed
DWORD dwBufSize = Geometry.TracksPerCylinder * Geometry.SectorsPerTrack * Geometry.BytesPerSector;
BYTE* pBuf=new BYTE[dwBufSize];
// Write one cylinder each step, in order to display in the progress bar
for(DWORD dwCylinder=0; dwCylinder<Geometry.Cylinders.LowPart; dwCylinder++)
{
file.Read(pBuf, dwBufSize);
bResult = ::WriteTracks(hDrive, &Geometry, pBuf, dwCylinder, 1);
m_ctrlProgress.StepIt();
if(!bResult) break;
}
delete [] pBuf;
if(bResult)
{
m_strProcessFloppy += "OK";
nState = stDismountVolume; // success, next state: dismount volume
}
else
{
m_strProcessFloppy += "failed";
nState = stDismountVolume; // failed, next state: dismount volume
}
UpdateData(FALSE);
break;
}
case stDismountVolume: // Dismount volume
{
m_strDismountVolume.Format("Dismounting volume ... ");
UpdateData(FALSE);
bResult = ::DismountVolume(hDrive);
if(bResult)
{
m_strDismountVolume += "OK";
nState = stUnlockVolume; // success, next state: unlock volume
}
else
{
m_strDismountVolume += "failed";
nState = stUnlockVolume; // failed, next state: unlock volume
}
UpdateData(FALSE);
break;
}
case stUnlockVolume: // unlock volume
{
m_strUnlockVolume.Format("Unlocking volume ... ");
UpdateData(FALSE);
bResult = ::UnlockVolume(hDrive);
if(bResult)
{
m_strUnlockVolume += "OK";
}
else
{
m_strUnlockVolume += "failed";
}
nState = stCloseDrive; // next state: close drive
UpdateData(FALSE);
break;
}
case stCloseDrive: // close drive
{
m_strCloseDrive.Format("Closing drive ... ");
UpdateData(FALSE);
bResult = ::CloseHandle(hDrive);
if(bResult)
{
m_strCloseDrive += "OK";
}
else
{
m_strCloseDrive += "failed";
}
UpdateData(FALSE);
nState = stExit; // all done, next state: exit while loop
}
}
}
file.Close();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -