高手救命! 如何实现将移动磁盘做成镜像文件?

plutolxl 2008-11-17 11:37:59
我想像ghost那样把移动磁盘的文件做成镜像文件,查了资料,
觉得这样应该行的通
http://www.moon-soft.com/doc/11146.htm
但具体怎么从磁盘读出所有数据然后存入文件不太明白,希望会的指点下.
或者有别的好的办法也教教我,万分感谢!!
...全文
881 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
plutolxl 2008-11-19
  • 打赏
  • 举报
回复
另外有点不明白,要按你所说,http://www.moon-soft.com/doc/11146.htm 的例子怎么回事呢?
plutolxl 2008-11-19
  • 打赏
  • 举报
回复
你说直接取磁盘大小,这个大小应该是512的整数倍吧!
然后读遍整个磁盘写入文件?
cnzdgs 2008-11-19
  • 打赏
  • 举报
回复
磁盘的TracksPerCylinder、SectorsPerTrack、BytesPerSector其实都是逻辑概念,实际的物理构造不是这样的,所以通过这些参数计算出的磁盘容量经常与实际容量不等,应该直接取磁盘大小。
plutolxl 2008-11-19
  • 打赏
  • 举报
回复
满天星老大!谢谢!
我按你说的做了,可行,不过我做出来的镜像好像有点问题,
镜像大小 972 MB (1,019,934,744 字节)
占用空间 972 MB (1,019,936,768 字节)

我的U盘是1,025,363,968字节 977M
大小对不上啊,这是为什么呢?
DWORD dwStartCylinder=0;
DWORD VirtBufSize;

// 大小
VirtBufSize = (DiskGeometry.TracksPerCylinder) * (DiskGeometry.SectorsPerTrack) * (DiskGeometry.BytesPerSector);

PBYTE pBuf = new BYTE[VirtBufSize];


do
{
memset(pBuf,0,VirtBufSize);

// 偏移
SetFilePointer(DiskHandle, VirtBufSize*dwStartCylinder, NULL, FILE_BEGIN);
BytesRead=0;
ReadFile(DiskHandle, pBuf, VirtBufSize, &BytesRead, NULL);


// 偏移
SetFilePointer(hMirror, sizeof(DISK_GEOMETRY)+VirtBufSize*dwStartCylinder, NULL, FILE_BEGIN);
BytesWritten=0;
WriteFile(hMirror, pBuf, VirtBufSize, &BytesWritten, NULL);

dwStartCylinder++;

} while (dwStartCylinder<(DiskGeometry.Cylinders.QuadPart));

delete [] pBuf;

其中程序读出来
DiskGeometry.TracksPerCylinder =255
DiskGeometry.SectorsPerTrack =63
DiskGeometry.BytesPerSector =512
DiskGeometry.Cylinders.QuadPart =124
plutolxl 2008-11-19
  • 打赏
  • 举报
回复
我测试了下,按http://www.moon-soft.com/doc/11146.htm 所说的那种按扇区读取,虽然会出现我14楼所说的大小不一致的情况,但再按扇区恢复回去是没问题的。原因应该就是满天星老大15楼所说的。

这个问题就先到这里了,关于如何恢复到不同大小的磁盘,或者要排除磁盘中的无效数据,满天星老大你说需要熟悉文件系统的原理,有这方面的资料吗?或者谁有告诉我下,我邮箱lxl-19085-11@163.com

再次感谢各位,特别是满天星老大的帮忙:)
cnzdgs 2008-11-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 plutolxl 的回复:]
你说直接取磁盘大小,这个大小应该是512的整数倍吧!
然后读遍整个磁盘写入文件?
[/Quote]
对。
[Quote=引用 17 楼 plutolxl 的回复:]
另外有点不明白,要按你所说,http://www.moon-soft.com/doc/11146.htm 的例子怎么回事呢?
[/Quote]
只能说作者对磁盘方面了解的不是十分清楚。
plutolxl 2008-11-18
  • 打赏
  • 举报
回复
1、创建空的镜像文件。
2、调用OpenDisk打开软盘。成功转3,失败转8。
3、调用LockVolume将卷锁定。成功转4,失败转7。
4、调用GetDiskGeometry获取参数。成功转5,失败转6。
5、将磁盘参数写入镜像文件作为文件头。调用ReadTracks按柱面读出数据,保存在镜像文件中。循环次数等于柱面数。
6、调用UnlockVolume将卷解锁。
7、调用CloseDisk关闭软盘。
8、关闭镜像文件。
也就是5怎么实现
matrixnull 2008-11-18
  • 打赏
  • 举报
回复
DeviceIoControl 之三:制作磁盘镜像文件
http://dev.csdn.net/article/17/17036.shtm
plutolxl 2008-11-18
  • 打赏
  • 举报
回复
谢谢cnzdgs 和zhoujianhei ,我不用在实模式下做,在NT里做就行,cnzdgs 你说的这个流程我知道,现在关键是创建一个什么样的文件,怎么循环读出磁盘的所有数据并写入文件,另外和磁盘格式有关系吗?比如FAT和NTFS有什么不同
zhoujianhei 2008-11-18
  • 打赏
  • 举报
回复
ghost是在实模式下做到的,难道你也想在实模式下做?
cnzdgs 2008-11-18
  • 打赏
  • 举报
回复
局部数组是在栈中分配的,栈的默认大小是1MB,所以分配1MB的数组会溢出,改成用new分配,用完后delete。
PBYTE pBuf = new BYTE[0x100000];
ReadFile(DiskHandle, pBuf, 0x100000, &BytesRead, NULL);
plutolxl 2008-11-18
  • 打赏
  • 举报
回复
又碰到问题了--、
ReadFile(DiskHandle, pBuf, VirtBufSize*dwCylinderNumber, &BytesRead, NULL);
读不到东西,我把pBuf和参数3设一样时可以读到,是不是必须一样啊?
另外pBuf我设1MB(0x100000)运行就出错,说stack overflow
cnzdgs 2008-11-18
  • 打赏
  • 举报
回复
前面说的意思就是备份128M的磁盘就要恢复到128M的磁盘上。
如果恢复到大于128M的磁盘上也是可以的,但剩余的容量就不能使用了,(可以另划一个分区来用)。
128M磁盘备份出来的镜像文件大小也是128M,根据文件大小就可以知道磁盘容量,所以不需要另外记录磁盘大小;至于物理信息,对于相同大小的磁盘几乎都是一样的,也不需要记录。
缓冲区的大小应该用扇区大小(512字节)的整数倍,另外不要太小,以免影响读写效率,建议至少用1MB(0x100000),也不要过大,浪费资源而且没有实际意义。
plutolxl 2008-11-18
  • 打赏
  • 举报
回复
再次感谢满天星及各位大侠的帮忙!!
plutolxl 2008-11-18
  • 打赏
  • 举报
回复
嗯,满天星你说的意思就是128M的U盘的镜像也只能恢复到128M的U盘上对吧?
但不同磁盘它的信息是不是会不一样,就是DISK_GEOMETRY的信息。
我把A磁盘的信息记录下来,做好镜像后,然后根据信息格式化B磁盘,再把文件写入B,可以吗?
这样能不能解决A,B磁盘必须一样的问题?
另外,ReadFile读取数据时,参数2,也就是缓存区大小有没要求?
// 大小
VirtBufSize = (DiskGeometry.TracksPerCylinder) * (DiskGeometry.SectorsPerTrack) * (DiskGeometry.BytesPerSector);

// 偏移
SetFilePointer(DiskHandle, VirtBufSize*dwStartCylinder, NULL, FILE_BEGIN);

ReadFile(DiskHandle, pBuf, VirtBufSize*dwCylinderNumber, &BytesRead, NULL);
我的程序是上边这样,VirtBufSize=8225280,感觉不太放心


cnzdgs 2008-11-18
  • 打赏
  • 举报
回复
对于简单的镜像,把磁盘中的所有数据复制到一个文件中就可以了,不用加任何信息。FlushFileBuffers没有实际意义,不需要调用。
恢复的时候就是反过来,从文件中读数据写到磁盘上,在开始恢复前需要LockVolume,恢复完后需要DismountVolume。
这种是最简单的镜像,只能恢复到同样大小的磁盘上,如果要恢复到不同大小的磁盘,或者要排除磁盘中的无效数据,需要熟悉文件系统的原理。
plutolxl 2008-11-18
  • 打赏
  • 举报
回复
那要实现镜像的功能,我首先要把磁盘的信息作为文件头写入文件吧?
然后再写入整个磁盘的数据?
FlushFileBuffers()这个是不是每次写完都需要啊?
还是写了,再读出来前才需要?
另外做好的镜像怎么恢复到别的磁盘呢?
比如我写了一个128M的U盘的镜像,我怎么回复到别的地方?
cnzdgs 2008-11-18
  • 打赏
  • 举报
回复
对于读数据,3、6步是多余的。
第5步用ReadFile就可以,不用考虑物理结构。
cnzdgs 2008-11-17
  • 打赏
  • 举报
回复
跟复制文件差不多。用CreateFile打开移动磁盘设备(例如\\.\X:),再创建镜像文件,获取磁盘容量,循环ReadFile从磁盘读数据、WriteFile写入镜像文件,最后关闭句柄。
Re: 《 Linux磁盘与文件系统管理命令 》   ---------------------------------------内容提要: 01/16)命令fdisk           :磁盘分区工具02/16)命令partprobe  :更新内核的硬盘分区表信息(即分区即刻生效)03/16)命令 tune2fs     :调整 ext2/ext3/ext4 文件系统参数04/16)命令 parted       :磁盘分区工具(大小通吃)05/16)命令 mkfs          :创建Linux文件系统06/16)命令 dumpe2fs :导出ext2/ext3/ext4文件系统信息07/16)命令 resize2fs   :调整ext2/ext3/ext4文件系统大小08/16)命令 fsck           :检查并修复Linux文件系统09/16)命令 dd             :转换或复制文件10/16)命令 mount       :挂载文件系统11/16)命令 umount     :卸载文件系统12/16)命令 df              :报告文件系统磁盘空间的使用情况13/16)命令 mkswap    :创建交换分区14/16)命令 swapon     :激活交换分区15/16)命令 swapoff     :关闭交换分区16/16)命令 sync           :刷新文件系统缓冲区17/17)附录                   :NFS 网络文件服务器到安装;客户端的挂载 -t nfs;及新分区的权限测试  本人在教学和实战过程中发现,即便是有一定运维经验的人,可能已经能够搭建一定复杂度的Linux架构,但是在来来回回的具体操作中,还是体现出CLI(命令界面)功底不够扎实,甚至操作的非常‘拙’、处处露‘怯’。 对一个士兵来说,枪就是他的武器,对于一个程序员来说,各种library(工具库)就是他的武器;而对于Linux运维人员来说,无疑命令行工具CLI(命令界面)就是他们的武器;高手和小白之间的差距往往就体现在对于这些“武器”的掌握和熟练程度上。有时候一个参数就能够解决的事情,小白们可能要写一个复杂的Shell脚本才能搞定,这就是对CLI(命令界面)没有理解参悟透彻导致。 研磨每一个命令就是擦拭手中的作战武器,平时不保养不理解,等到作战的时候,一定不能够将手中的武器发挥到最好,所以我们要平心、静气和专注,甘坐冷板凳一段时间,才能练就一身非凡的内功! 本教程从实战出发,结合当下流行或最新的Linux(v6/7/8 版本)同时演示,将命令行结合到解决企业实战问题中来,体现出教学注重实战的务实精神,希望从事或未来从事运维的同学,能够认真仔细的学完Linux核心命令的整套课程。 本课程系列将逐步推出,看看我教学的进度和您学习的步伐,孰占鳌头! 注:关于教学环境搭建,可以参考本人其它课程系列,本教学中就不再赘述! 《参透 VMware 桌面级虚拟化》 《在虚拟机中安装模版机(包括应用软件等)》 《SecureCRT 连接 GNS3/Linux 的安全精密工具》 

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧