C# 直接访问物理cdrom设备
我正在尝试访问物理cdrom设备,以检查它是否可启动,因此我需要从中读取字节。我尝试了以下两种方法,但都没有成功: 方法A: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
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,
///
///启用对象上的后续打开操作以请求删除访问。
///否则,其他进程将无法执行