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

本文介绍了一种在Windows环境下创建ISO文件的方法,通过使用SafeFileHandle类和非托管CreateFile函数来实现对光盘数据的读取,并将其映射到文件中形成ISO镜像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

26InBlock.gif
27InBlock.gif        public void Load(string driverName)
28ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
29InBlock.gif            if (driverName == null && driverName.Length == 0)
30ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
31InBlock.gif                throw 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.gif            if (handleValue.IsInvalid)
37ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
38InBlock.gif                Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
39ExpandedSubBlockEnd.gif            }

40ExpandedSubBlockEnd.gif        }

41InBlock.gif
42InBlock.gif        public SafeFileHandle Handle
43ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
44InBlock.gif            get
45ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
46InBlock.gif                if (!handleValue.IsInvalid)
47ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
48InBlock.gif                    return handleValue;
49ExpandedSubBlockEnd.gif                }

50InBlock.gif                else
51ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
52InBlock.gif                    return 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.gifContractedBlock.gif            
/**/ ///遍历块写到文件
None.gif              for  ( long  i  =   0 ; i  <  icount; i ++ )
ExpandedBlockStart.gifContractedBlock.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.gif                
if (OnProgress != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    OnProgress(
this0, GetCDROMSize(driverName), hIso.Length);
ExpandedSubBlockEnd.gif                }

InBlock.gif                
if (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

以下是它的源码,直接下载
/Files/Chinasf/ISO.NET.rar

2006年4月29日

转载于:https://www.cnblogs.com/Chinasf/archive/2006/04/29/388658.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值