.net 下直接读分区数据,并生成ISO光盘镜像文件,含DEMO

简介:

ISO文件格式被很多虚拟光驱软件和刻录软件支持,比较典型的有WinISO ,Alcohol 120%这些软件.有的时候需要自己制作一个ISO文件的话,则需要找专门的工具;其实要做一个ISO的文件可以很简单,就是把光盘的所有数据映射到文件,只要你可以读光盘的数据就可以生成它.但是,它不是单纯的把光盘上的文件都读入,而是要把整个磁盘信息读入,那么你必须访问磁盘数据,而不是文件;

在WINDOWS下读取磁盘的方法很简单,按该方法也可以读取引导区信息;具体如下:

None.gifCreateFile("\\\\.\\"+driverName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

在.net 下,要作到这种模式的访问,使用FileStream可行不通,程序运行的时候会直接报个异常,阻止你访问Win32 设备磁盘.那么只能使用原始的做法,声明API.通过SafeFileHandle将文件句柄传递给托管的流进行读写操作.具体做法如下:
ContractedBlock.gif ExpandedBlockStart.gif 使用 SafeFileHandle 类和非托管 CreateFile 函数打开 Win32 设备
1ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
2InBlock.gif/// 使用 SafeFileHandle 类和非托管 CreateFile 函数打开 Win32 设备
3ExpandedBlockEnd.gif/// </summary>

4None.gifclass UnmanagedDriverLoader
5ExpandedBlockStart.gifContractedBlock.gifdot.gif{
6InBlock.gifpublic const short FILE_ATTRIBUTE_NORMAL = 0x80;
7InBlock.gifpublic const short INVALID_HANDLE_VALUE = -1;
8InBlock.gifpublic const uint GENERIC_READ = 0x80000000;
9InBlock.gifpublic const uint GENERIC_WRITE = 0x40000000;
10InBlock.gifpublic const uint FILE_SHARE_READ = 0x00000001;
11InBlock.gifpublic const uint CREATE_NEW = 1;
12InBlock.gifpublic const uint CREATE_ALWAYS = 2;
13InBlock.gifpublic const uint OPEN_EXISTING = 3;
14InBlock.gif
15InBlock.gif [DllImport("kernel32.dll", SetLastError = true)]
16InBlock.gifstatic extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
17InBlock.gifuint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
18InBlock.gifuint dwFlagsAndAttributes, IntPtr hTemplateFile);
19InBlock.gif
20InBlock.gifprivate SafeFileHandle handleValue = null;
21InBlock.gif
22InBlock.gifpublic UnmanagedDriverLoader(string driverName)
23ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
24InBlock.gif Load(driverName);
25ExpandedSubBlockEnd.gif }

26InBlock.gif
27InBlock.gifpublic void Load(string driverName)
28ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
29InBlock.gifif (driverName == null && driverName.Length == 0)
30ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
31InBlock.gifthrow new ArgumentNullException("driverName");
32ExpandedSubBlockEnd.gif }

33InBlock.gif
34InBlock.gif handleValue = CreateFile("\\\\.\\"+driverName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
35InBlock.gif
36InBlock.gifif (handleValue.IsInvalid)
37ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
38InBlock.gif Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
39ExpandedSubBlockEnd.gif }

40ExpandedSubBlockEnd.gif }

41InBlock.gif
42InBlock.gifpublic SafeFileHandle Handle
43ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
44InBlock.gifget
45ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
46InBlock.gifif (!handleValue.IsInvalid)
47ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
48InBlock.gifreturn handleValue;
49ExpandedSubBlockEnd.gif }

50InBlock.gifelse
51ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
52InBlock.gifreturn null;
53ExpandedSubBlockEnd.gif }

54ExpandedSubBlockEnd.gif }

55ExpandedSubBlockEnd.gif }

56ExpandedBlockEnd.gif }
有了SafeFileHandle 之后,就可以使用FileStream 流来对其操作了;

首先确定磁盘的大小,再建立一个缓冲区,和一个目标文件用于写入;我建立的缓冲区是10兆,因为光驱比较快,内存也够用。
ExpandedBlockStart.gif ContractedBlock.gif /**/ ///10兆一个块
None.gif int bufferSize = 10240;
None.gif byte[] buffer = new byte[bufferSize];

剩下的事情就简单多了;只需要按块读入,并写到目标文件内:
ExpandedBlockStart.gif ContractedBlock.gif /**/ ///计算块的分页大小
None.gif long icount = ( long)(GetCDROMSize(driverName) / bufferSize);
None.gif if ((GetCDROMSize(driverName) % bufferSize) != 0)
None.gif icount++;
None.gif long length = bufferSize;
None.gif
None.gif hDriver.Seek(0, SeekOrigin.Begin);
None.gif hIso.Seek(0, SeekOrigin.Begin);
None.gif
ExpandedBlockStart.gif ContractedBlock.gif /**/ ///遍历块写到文件
None.gif for ( long i = 0; i < icount; i++)
ExpandedBlockStart.gif ContractedBlock.gif dot.gif {
InBlock.gif hDriver.Read(buffer, 0, (int)length);
InBlock.gif hIso.Write(buffer, 0, (int)length);
InBlock.gif
InBlock.gif length = GetCDROMSize(driverName) - hDriver.Position;
InBlock.gif
InBlock.gifif (OnProgress != null)
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
InBlock.gif OnProgress(this, 0, GetCDROMSize(driverName), hIso.Length);
ExpandedSubBlockEnd.gif }

InBlock.gifif (length > bufferSize)
InBlock.gif length = bufferSize;
ExpandedBlockEnd.gif }

None.gif
None.gif hDriver.Close();
None.gif hIso.Close();

OK,一个磁盘的镜像文件就建立好了,那么可以试试用 WinRar 或 Daemon Tools 装入试试;一切很正常。

根据以上的代码,我作了个DEMO,用于对光盘创建ISO镜像.一样很简单,可以先看看界面.
ISO.NET.JPG



本文转自suifei博客园博客,原文链接:http://www.cnblogs.com/Chinasf/archive/2006/04/29/388658.html,如需转载请自行联系原作者
相关文章
|
29天前
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
8 0
|
9月前
|
存储 前端开发 API
30分钟玩转Net MVC 基于WebUploader的大文件分片上传、断网续传、秒传(文末附带demo下载)
30分钟玩转Net MVC 基于WebUploader的大文件分片上传、断网续传、秒传(文末附带demo下载)
30分钟玩转Net MVC 基于WebUploader的大文件分片上传、断网续传、秒传(文末附带demo下载)
|
29天前
|
SQL 数据库
使用ADO.NET查询和操作数据
使用ADO.NET查询和操作数据
9 0
|
2月前
|
SQL 开发框架 .NET
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
67 0
|
4月前
|
Oracle 关系型数据库 数据管理
.NET医院检验系统LIS源码,使用了oracle数据库,保证数据的隔离和安全性
LIS系统实现了实验室人力资源管理、标本管理、日常事务管理、网络管理、检验数据管理(采集、传输、处理、输出、发布)、报表管理过程的自动化,使实验室的操作人员和管理者从繁杂的手工劳作中解放出来,提高了检验人员的工作效率和效益,降低了劳动成本和差错发生率。
|
5月前
|
开发框架 .NET API
.net gRPC初探 - 从一个简单的Demo中了解并学习gRPC
.net gRPC初探 - 从一个简单的Demo中了解并学习gRPC
40 0
|
6月前
|
调度
Quartz.NET 任务调度框架的demo实例
​ # 1、新建项目 简单实例,新建一个控制台程序 # 2、Nuget安装Quartz ![请在此添加图片描述](https://developer-private-1258344699.cos.ap-guangzhou.myqcloud.com/column/article/5877188/20231031-52d48c93.png?x-cos-security-token=baeOYKJ0BOuKXaDG6L8qKX7pdH823CLa740df95695ddd90763a204f7cd7172afjLbyfjQS2rqYm0waz5Rlsx3p2jhWg-yj9JZ3WKDq32bpX
25 0
|
6月前
|
前端开发 JavaScript
.net core 前端传递参数有值 后端接收到的数据却是null
1、问题分析 在做接口测试时,偶然出现了前端输出有值,但是后端断点调试时却出现接收参数总是为null的情况 2、解决办法 前端打印log,看前端的每一个传值的数据类型,与后端请求参数类进行认真的一一比对 小技巧: ① 直接打印调用接口的传参值的数据类型,例如 console.log(type of this.form.name) --string console.log(type of this.form.age) --number 打印的数据类型与后端接口的参数类比对,查出不对应的类型 ② 关于非必填的值,默认传值可能出现空字符串(' ')、NaN值(Not a Number
98 0
|
7月前
|
JSON 数据格式
.NET Core - 配置绑定:使用强类型对象承载配置数据
.NET Core - 配置绑定:使用强类型对象承载配置数据
|
9月前
|
数据库 C#
C#,.net,winform导入Excel功能以及下载Excel文件到本地,并使用SqlBulkCopy把DataTable类型的数据写入到sqlserver数据库中
C#,.net,winform导入Excel功能以及下载Excel文件到本地,并使用SqlBulkCopy把DataTable类型的数据写入到sqlserver数据库中
215 0