C# 直接访问物理cdrom设备

C# 直接访问物理cdrom设备,c#,winapi,device,C#,Winapi,Device,我正在尝试访问物理cdrom设备,以检查它是否可启动,因此我需要从中读取字节。我尝试了以下两种方法,但都没有成功: 方法A: FileStream stream = new FileStream(H:, FileMode.Open); 但我在H:上被拒绝访问。我知道我有权限 方法B: 通过平沃克 IntPtr handle = CreateFile(source, FileAccess.Read, FileShare.ReadWrite, 0, FileMode.Open, 0, IntP

我正在尝试访问物理cdrom设备,以检查它是否可启动,因此我需要从中读取字节。我尝试了以下两种方法,但都没有成功:

方法A:

FileStream stream = new FileStream(H:, FileMode.Open);
但我在H:上被拒绝访问。我知道我有权限

方法B: 通过平沃克

  IntPtr handle = CreateFile(source, FileAccess.Read, FileShare.ReadWrite, 0, FileMode.Open, 0, IntPtr.Zero);
            binReader = new BinaryReader(new FileStream(handle, FileAccess.Read,true));
但我得到:

FileStream不会打开Win32设备,如磁盘分区和磁带机。 避免在路径中使用“\.\”

有什么办法可以在c#中实现我想要的吗


非常感谢

好的。。。问题是DVD和CD之间的区别。。。显然我们不能那样看DVD。。。但你看

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.ComponentModel;

namespace cdDvdAccess
{
    public class Program
    {

        //some interesting IOCTLs
        public const uint IOCTL_CDROM_READ_TOC = 0x00024000;
        public const uint IOCTL_CDROM_RAW_READ = 0x0002403E;
        public const uint IOCTL_STORAGE_EJECT_MEDIA = 0x002D4808;
        public const uint IOCTL_STORAGE_LOAD_MEDIA = 0x002D480C;


        // P/Invoke signatures
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool DeviceIoControl(
                SafeFileHandle hDevice,
                uint dwIoControlCode,
                IntPtr InBuffer, // arbitrary buffer
                int nInBufferSize,
                IntPtr OutBuffer,
                int nOutBufferSize,
                ref int pBytesReturned,
                IntPtr lpOverlapped);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool DeviceIoControl(
                SafeFileHandle hDevice,
                uint dwIoControlCode,
                ref RAW_READ_INFO InBuffer, // with RAW_READ_INFO
                int nInBufferSize,
                IntPtr OutBuffer,
                int nOutBufferSize,
                ref int pBytesReturned,
                IntPtr lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern SafeFileHandle CreateFile(
           string lpFileName,
           EFileAccess dwDesiredAccess,
           EFileShare dwShareMode,
           IntPtr lpSecurityAttributes,
           ECreationDisposition dwCreationDisposition,
           EFileAttributes dwFlagsAndAttributes,
           IntPtr hTemplateFile);

        [Flags]
        public enum EFileAccess : uint
        {
            //
            // Standart Section
            //

            AccessSystemSecurity = 0x1000000,   // AccessSystemAcl access type
            MaximumAllowed = 0x2000000,     // MaximumAllowed access type

            Delete = 0x10000,
            ReadControl = 0x20000,
            WriteDAC = 0x40000,
            WriteOwner = 0x80000,
            Synchronize = 0x100000,

            StandardRightsRequired = 0xF0000,
            StandardRightsRead = ReadControl,
            StandardRightsWrite = ReadControl,
            StandardRightsExecute = ReadControl,
            StandardRightsAll = 0x1F0000,
            SpecificRightsAll = 0xFFFF,

            FILE_READ_DATA = 0x0001,        // file & pipe
            FILE_LIST_DIRECTORY = 0x0001,       // directory
            FILE_WRITE_DATA = 0x0002,       // file & pipe
            FILE_ADD_FILE = 0x0002,         // directory
            FILE_APPEND_DATA = 0x0004,      // file
            FILE_ADD_SUBDIRECTORY = 0x0004,     // directory
            FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
            FILE_READ_EA = 0x0008,          // file & directory
            FILE_WRITE_EA = 0x0010,         // file & directory
            FILE_EXECUTE = 0x0020,          // file
            FILE_TRAVERSE = 0x0020,         // directory
            FILE_DELETE_CHILD = 0x0040,     // directory
            FILE_READ_ATTRIBUTES = 0x0080,      // all
            FILE_WRITE_ATTRIBUTES = 0x0100,     // all

            //
            // Generic Section
            //

            GenericRead = 0x80000000,
            GenericWrite = 0x40000000,
            GenericExecute = 0x20000000,
            GenericAll = 0x10000000,

            SPECIFIC_RIGHTS_ALL = 0x00FFFF,
            FILE_ALL_ACCESS =
            StandardRightsRequired |
            Synchronize |
            0x1FF,

            FILE_GENERIC_READ =
            StandardRightsRead |
            FILE_READ_DATA |
            FILE_READ_ATTRIBUTES |
            FILE_READ_EA |
            Synchronize,

            FILE_GENERIC_WRITE =
            StandardRightsWrite |
            FILE_WRITE_DATA |
            FILE_WRITE_ATTRIBUTES |
            FILE_WRITE_EA |
            FILE_APPEND_DATA |
            Synchronize,

            FILE_GENERIC_EXECUTE =
            StandardRightsExecute |
              FILE_READ_ATTRIBUTES |
              FILE_EXECUTE |
              Synchronize
        }

        [Flags]
        public enum EFileShare : uint
        {
            /// <summary>
            ///
            /// </summary>
            None = 0x00000000,
            /// <summary>
            /// Enables subsequent open operations on an object to request read access.
            /// Otherwise, other processes cannot open the object if they request read access.
            /// If this flag is not specified, but the object has been opened for read access, the function fails.
            /// </summary>
            Read = 0x00000001,
            /// <summary>
            /// Enables subsequent open operations on an object to request write access.
            /// Otherwise, other processes cannot open the object if they request write access.
            /// If this flag is not specified, but the object has been opened for write access, the function fails.
            /// </summary>
            Write = 0x00000002,
            /// <summary>
            /// Enables subsequent open operations on an object to request delete access.
            /// Otherwise, other processes cannot open the object if they request delete access.
            /// If this flag is not specified, but the object has been opened for delete access, the function fails.
            /// </summary>
            Delete = 0x00000004
        }

        public enum ECreationDisposition : uint
        {
            /// <summary>
            /// Creates a new file. The function fails if a specified file exists.
            /// </summary>
            New = 1,
            /// <summary>
            /// Creates a new file, always.
            /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
            /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
            /// </summary>
            CreateAlways = 2,
            /// <summary>
            /// Opens a file. The function fails if the file does not exist.
            /// </summary>
            OpenExisting = 3,
            /// <summary>
            /// Opens a file, always.
            /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
            /// </summary>
            OpenAlways = 4,
            /// <summary>
            /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
            /// The calling process must open the file with the GENERIC_WRITE access right.
            /// </summary>
            TruncateExisting = 5
        }

        [Flags]
        public enum EFileAttributes : uint
        {
            Readonly = 0x00000001,
            Hidden = 0x00000002,
            System = 0x00000004,
            Directory = 0x00000010,
            Archive = 0x00000020,
            Device = 0x00000040,
            Normal = 0x00000080,
            Temporary = 0x00000100,
            SparseFile = 0x00000200,
            ReparsePoint = 0x00000400,
            Compressed = 0x00000800,
            Offline = 0x00001000,
            NotContentIndexed = 0x00002000,
            Encrypted = 0x00004000,
            Write_Through = 0x80000000,
            Overlapped = 0x40000000,
            NoBuffering = 0x20000000,
            RandomAccess = 0x10000000,
            SequentialScan = 0x08000000,
            DeleteOnClose = 0x04000000,
            BackupSemantics = 0x02000000,
            PosixSemantics = 0x01000000,
            OpenReparsePoint = 0x00200000,
            OpenNoRecall = 0x00100000,
            FirstPipeInstance = 0x00080000
        }

        public enum TRACK_MODE_TYPE
        {
            YellowMode2 = 0,
            XAForm2 = 1,
            CDDA = 2,
            RawWithC2AndSubCode = 3,
            RawWithC2 = 4,
            RawWithSubCode = 5
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RAW_READ_INFO
        {
            public long DiskOffset;
            public uint SectorCount;
            public TRACK_MODE_TYPE TrackMode;

        }

        static void Main(string[] args)
        {
            Byte[] data; // a variable to hold our desired data...
            Win32Exception ex, ex2; //see using block below
            int outputBufferSize = 4096000;//just some buffer ... way to big, but hey ...
            var unmanagedOutputBuffer = Marshal.AllocHGlobal(outputBufferSize); // Marshal will give us an unmanaged buffer of desired size ... hopefully
            RAW_READ_INFO ri = new RAW_READ_INFO { DiskOffset = 0, SectorCount = 20, TrackMode = TRACK_MODE_TYPE.YellowMode2 }; // what do we want to read?
            var ri_size = Marshal.SizeOf(ri); // since we are giving ri to an unmanaged function, we need to tell that function the size of ri
            int bytesReturned = 0; // if everything works as expected, we will get something written in our unmanaged buffer ... here we can store how many bytes were written
            using (var hDev = CreateFile(@"\\.\H:", EFileAccess.GenericRead, EFileShare.Read | EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.Normal, IntPtr.Zero))
            {// since we are working with a handle, we have to make sure we release it after we are done ... "using" does that for us
                ex = new Win32Exception();//will tell you if CreateFile worked 
                var b = DeviceIoControl(hDev, IOCTL_CDROM_RAW_READ, ref ri, ri_size, unmanagedOutputBuffer, outputBufferSize, ref bytesReturned, IntPtr.Zero); // the magic happens here
                ex2 = new Win32Exception();//will tell you if DeviceIoControl worked
            }

            if (bytesReturned > 0)
            {
                data = new byte[bytesReturned]; //this time, a managed buffer to hold our data
                Marshal.Copy(unmanagedOutputBuffer, data, 0, bytesReturned); // copy from unmanaged buffer to managed buffer (from the land of dragons and monsters into the .net world)
            }
            Marshal.FreeHGlobal(unmanagedOutputBuffer);//release the unmanaged buffer

            // if everything worked as expected you should now have the first 20 sectors of a ordinary CD-Rom (Yellow Book - Mode 2) in the data array ...

        }
    }
}
使用系统;
使用System.Runtime.InteropServices;
使用Microsoft.Win32.SafeHandles;
使用系统组件模型;
命名空间CDDVD访问
{
公共课程
{
//一些有趣的IOCTL
公共const-uint-IOCTL\u-CDROM\u-READ\u-TOC=0x00024000;
公共const-uint-IOCTL\u-CDROM\u-RAW\u-READ=0x0002403E;
public const uint IOCTL_STORAGE_EJECT_MEDIA=0x002D4808;
公共构造IOCTL\u存储\u加载\u媒体=0x002D480C;
//P/调用签名
[DllImport(“Kernel32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
专用静态外部布尔设备控制(
SafeFileHandle hDevice,
uint dwIoControlCode,
IntPtr InBuffer,//任意缓冲区
整数和大小,
IntPtr突发事件,
int nOutBufferSize,
ref int PBytes返回,
IntPtr(重叠);
[DllImport(“Kernel32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
专用静态外部布尔设备控制(
SafeFileHandle hDevice,
uint dwIoControlCode,
buffer中的ref RAW\u READ\u INFO,//带有RAW\u READ\u INFO
整数和大小,
IntPtr突发事件,
int nOutBufferSize,
ref int PBytes返回,
IntPtr(重叠);
[DllImport(“kernel32.dll”,SetLastError=true,CharSet=CharSet.Auto)]
私有静态外部安全文件句柄CreateFile(
字符串lpFileName,
EFileAccess dwDesiredAccess,
EFileShare dwShareMode,
IntPtr lpSecurityAttributes,
ECreationDisposition,
EFileAttributes dwFlagsAndAttributes,
IntPtr-hTemplateFile);
[旗帜]
公共枚举EFileAccess:uint
{
//
//标准部分
//
AccessSystemSecurity=0x1000000,//AccessSystemAcl访问类型
MaximumAllowed=0x2000000,//MaximumAllowed访问类型
删除=0x10000,
ReadControl=0x20000,
WriteDAC=0x40000,
WriteOwner=0x80000,
同步=0x100000,
标准权利要求=0xF0000,
StandardRightsRead=ReadControl,
StandardRightsWrite=ReadControl,
StandardRightsExecute=ReadControl,
StandardRightsAll=0x1F0000,
SpecificRightsAll=0xFFFF,
文件读取数据=0x0001,//文件和管道
文件\u列表\u目录=0x0001,//目录
FILE\u WRITE\u DATA=0x0002,//文件和管道
FILE\u ADD\u FILE=0x0002,//目录
FILE\u APPEND\u DATA=0x0004,//文件
文件\添加\子目录=0x0004,//目录
文件\u创建\u管道\u实例=0x0004,//命名管道
FILE\u READ\u EA=0x0008,//文件和目录
FILE\u WRITE\u EA=0x0010,//文件和目录
FILE\u EXECUTE=0x0020,//文件
文件\u TRAVERSE=0x0020,//目录
文件\u DELETE\u CHILD=0x0040,//目录
文件读取属性=0x0080,//全部
文件\写入\属性=0x0100,//全部
//
//通用部分
//
GenericRead=0x8000000,
GenericWrite=0x40000000,
GenericExecute=0x20000000,
GenericAll=0x10000000,
特定权限所有=0x00FFFF,
文件\u所有\u访问权限=
要求的标准权利|
同步化|
0x1FF,
文件\u通用\u读取=
标准权利广告|
文件读取数据|
文件读取属性|
文件读取|
使同步
文件\u通用\u写入=
标准权利写入|
文件写入数据|
文件\写入\属性|
文件\u写入\u EA|
文件\附加\数据|
使同步
文件\u通用\u执行=
标准右键执行|
文件读取属性|
执行文件|
使同步
}
[旗帜]
公共枚举EFileShare:uint
{
/// 
///
/// 
无=0x00000000,
/// 
///启用对象上的后续打开操作以请求读取访问。
///否则,如果其他进程请求读取访问,则无法打开该对象。
///如果未指定此标志,但对象已打开以进行读取访问,则函数将失败。
/// 
读取=0x00000001,
/// 
///启用对象上的后续打开操作以请求写入访问权限。
///否则,如果其他进程请求写访问权限,则无法打开该对象。
///如果未指定此标志,但对象已打开以进行写访问,则函数将失败。
/// 
写入=0x00000002,
/// 
///启用对象上的后续打开操作以请求删除访问。
///否则,其他进程将无法执行