您的位置:首页 > 其它

实战 DeviceIoControl 系列 之三:制作磁盘镜像文件

2010-07-01 13:04 399 查看
Q: DOS命令 DISKCOPY
给我很深的印象,现在也有许多“克隆”软件,可以对磁盘进行全盘复制。我想,要制作磁盘镜像文件,DeviceIoControl 应该很有用武之地吧?


A:

是的。这里举一个制作软盘镜像文件,功能类似于“DISKCOPY”的例子。

  本例实现其功能的核心代码如下: 

//
打开磁盘

HANDLE OpenDisk(LPCTSTR filename)

{

   HANDLE hDisk;

 
  // 打开设备

   hDisk = ::CreateFile(filename,      // 文件名

    
GENERIC_READ | GENERIC_WRITE,    // 读写方式

     FILE_SHARE_READ |
FILE_SHARE_WRITE, // 共享方式

     NULL,                // 默认的安全描述符

  
   OPEN_EXISTING,            // 创建方式

     0,                  //
不需设置文件属性

     NULL);                // 不需参照模板文件

   return hDisk;

}

//
获取磁盘参数

BOOL GetDiskGeometry(HANDLE hDisk, PDISK_GEOMETRY lpGeometry)

{

 
  DWORD dwOutBytes;

   BOOL bResult;

   //
用IOCTL_DISK_GET_DRIVE_GEOMETRY 取磁盘参数

   bResult =
::DeviceIoControl(hDisk,    // 设备句柄

    
IOCTL_DISK_GET_DRIVE_GEOMETRY,    // 取磁盘参数

     NULL,
0,               // 不需要输入数据

     lpGeometry,
sizeof(DISK_GEOMETRY),  // 输出数据缓冲区

    
&dwOutBytes,             // 输出数据长度

    
(LPOVERLAPPED)NULL);         // 用同步I/O

   return bResult;

}

//
从指定磁道开始读磁盘

BOOL ReadTracks(HANDLE hDisk, PDISK_GEOMETRY lpGeometry,
LPVOID pBuf, DWORD dwStartCylinder, DWORD dwCylinderNumber)

{

  
DWORD VirtBufSize;

   DWORD BytesRead;

   // 大小

   VirtBufSize
= lpGeometry->TracksPerCylinder * lpGeometry->SectorsPerTrack *
lpGeometry->BytesPerSector;

  // 偏移

   ::SetFilePointer(hDisk,
VirtBufSize*dwStartCylinder, NULL, FILE_BEGIN);

  return
::ReadFile(hDisk, pBuf, VirtBufSize*dwCylinderNumber, &BytesRead,
NULL);

}

 // 从指定磁道开始写磁盘

BOOL WriteTracks(HANDLE hDisk,
PDISK_GEOMETRY lpGeometry, LPVOID pBuf, DWORD dwStartCylinder, DWORD dwCylinderNumber)

{

 
 DWORD VirtBufSize;

   DWORD BytesWritten;

   // 大小

  
VirtBufSize = lpGeometry->TracksPerCylinder *
lpGeometry->SectorsPerTrack * lpGeometry->BytesPerSector;

   //
偏移

   ::SetFilePointer(hDisk, VirtBufSize*dwStartCylinder, NULL,
FILE_BEGIN);

   return ::WriteFile(hDisk, pBuf,
VirtBufSize*dwCylinderNumber, &BytesWritten, NULL);

}

//
从指定磁道开始格式化磁盘

BOOL LowLevelFormatTracks(HANDLE hDisk, PDISK_GEOMETRY
lpGeometry, DWORD dwStartCylinder, DWORD dwCylinderNumber)

{

  
FORMAT_PARAMETERS FormatParameters;

   PBAD_TRACK_NUMBER lpBadTrack;

 
 DWORD dwOutBytes;

   DWORD dwBufSize; 

   BOOL bResult;

  
FormatParameters.MediaType = lpGeometry->MediaType;

  
FormatParameters.StartCylinderNumber = dwStartCylinder;

  
FormatParameters.EndCylinderNumber = dwStartCylinder + dwCylinderNumber -
1;

   FormatParameters.StartHeadNumber = 0;

  
FormatParameters.EndHeadNumber = lpGeometry->TracksPerCylinder - 1;

 
 dwBufSize = lpGeometry->TracksPerCylinder *
sizeof(BAD_TRACK_NUMBER);

   lpBadTrack = (PBAD_TRACK_NUMBER) new
BYTE[dwBufSize];

   // 用IOCTL_DISK_FORMAT_TRACKS 对连续磁道进行低级格式化

  
bResult = ::DeviceIoControl(hDisk,        // 设备句柄

   
IOCTL_DISK_FORMAT_TRACKS,          // 低级格式化

    
&FormatParameters, sizeof(FormatParameters), // 输入数据缓冲区

    
lpBadTrack, dwBufSize,            // 输出数据缓冲区

    
&dwOutBytes,                 // 输出数据长度

    
(LPOVERLAPPED)NULL);             // 用同步I/O

   delete lpBadTrack;

 
 return bResult;

}

// 将卷锁定

BOOL LockVolume(HANDLE hDisk)

{

 
 DWORD dwOutBytes;

   BOOL bResult;

   // 用FSCTL_LOCK_VOLUME 锁卷

 
 bResult = ::DeviceIoControl(hDisk,    // 设备句柄

  
FSCTL_LOCK_VOLUME,          // 锁卷

       NULL, 0,               //
不需要输入数据

      NULL, 0,               // 不需要输出数据

    
&dwOutBytes,             // 输出数据长度

    
(LPOVERLAPPED)NULL);         // 用同步I/O

   return bResult;

}

//
将卷解锁

BOOL UnlockVolume(HANDLE hDisk)

{

   DWORD dwOutBytes;

 
 BOOL bResult;

   // 用FSCTL_UNLOCK_VOLUME 开卷锁

   bResult =
::DeviceIoControl(hDisk,    // 设备句柄

       FSCTL_UNLOCK_VOLUME,         // 开卷锁

      NULL, 0,               //
不需要输入数据

     NULL, 0,               // 不需要输出数据

    
&dwOutBytes,             // 输出数据长度

    
(LPOVERLAPPED)NULL);         // 用同步I/O

   return bResult;

}

//
将卷卸下

// 该操作使系统重新辨识磁盘,等效于重新插盘

BOOL DismountVolume(HANDLE hDisk)

{

 
 DWORD dwOutBytes;

   BOOL bResult;

   // 用FSCTL_DISMOUNT_VOLUME 卸卷

 
 bResult = ::DeviceIoControl(hDisk,    // 设备句柄

    
FSCTL_DISMOUNT_VOLUME,        // 卸卷

     NULL, 0,               //
不需要输入数据

     NULL, 0,               // 不需要输出数据

    
&dwOutBytes,             // 输出数据长度

    
(LPOVERLAPPED)NULL);         // 用同步I/O

   return bResult;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: