gpt4 book ai didi

c# - DeviceIoControl 不设置输出缓冲区

转载 作者:行者123 更新时间:2023-11-30 22:23:49 28 4
gpt4 key购买 nike

我在使用 DeviceIOControl 时遇到一些问题。我正在尝试从物理驱动器读取磁盘几何结构,但从未设置输出缓冲区。

这是我的代码示例,一个简单的函数,应该获取磁盘几何形状并返回磁盘是否可移动:

public static bool IsDeviceRemovable(int DriveNo) {
string Filename=@"\\.\Physicaldrive"+DriveNo;

SafeFileHandle drive=CreateFile(
Filename,
FileAccess_e.None,
FileShare_e.Write|FileShare_e.Read,
IntPtr.Zero,
CreationDisposition_e.OpenExisting,
FileAttributes_e.None,
IntPtr.Zero
);

if(drive.IsInvalid) {
throw new IOException("Unable to access drive. Win32 Error Code: "+Marshal.GetLastWin32Error());
}

uint bytesReturned=0;
DISK_GEOMETRY dg=new DISK_GEOMETRY();

if(!DeviceIoControl(
drive,
IOControlCode_e.DiskGetDriveGeometry,
IntPtr.Zero,
0,
dg,
(uint)Marshal.SizeOf(dg),
ref bytesReturned,
IntPtr.Zero
)) {
throw new Exception("Unable to get properties from device. Win32 Error Code: "+Marshal.GetLastWin32Error());
}

drive.Close();
return dg.MediaType==MEDIA_TYPE.RemovableMedia;
}

还有一些数据结构:

[DllImport("Kernel32.dll", SetLastError=false, CharSet=CharSet.Auto)]
private static extern bool DeviceIoControl(
SafeFileHandle hDevice,
IOControlCode_e IoControlCode,
[MarshalAs(UnmanagedType.AsAny)]
[In] object InBuffer,
uint nInBufferSize,
[MarshalAs(UnmanagedType.AsAny)]
[Out] object OutBuffer,
uint nOutBufferSize,
ref uint pBytesReturned,
IntPtr Overlapped
);

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
private static extern SafeFileHandle CreateFile(
string lpFileName,
FileAccess_e dwDesiredAccess,
FileShare_e dwShareMode,
IntPtr lpSecurityAttributes,
CreationDisposition_e dwCreationDisposition,
FileAttributes_e dwFlagsAndAttributes,
IntPtr hTemplateFile
);

private enum MEDIA_TYPE {
Unknown=0x00,
F5_1Pt2_512=0x01,
F3_1Pt44_512=0x02,
F3_2Pt88_512=0x03,
F3_20Pt8_512=0x04,
F3_720_512=0x05,
F5_360_512=0x06,
F5_320_512=0x07,
F5_320_1024=0x08,
F5_180_512=0x09,
F5_160_512=0x0a,
RemovableMedia=0x0b,
FixedMedia=0x0c,
F3_120M_512=0x0d,
F3_640_512=0x0e,
F5_640_512=0x0f,
F5_720_512=0x10,
F3_1Pt2_512=0x11,
F3_1Pt23_1024=0x12,
F5_1Pt23_1024=0x13,
F3_128Mb_512=0x14,
F3_230Mb_512=0x15,
F8_256_128=0x16,
F3_200Mb_512=0x17,
F3_240M_512=0x18,
F3_32M_512=0x19
}

[StructLayout(LayoutKind.Sequential)]
private struct DISK_GEOMETRY {
public Int64 Cylinders;
public MEDIA_TYPE MediaType;
public Int32 TracksPerCylinder;
public Int32 SectorsPerTrack;
public Int32 BytesPerSector;
}

我使用的枚举来自

bytesReturned 变量已设置(在本例中为 24),但 dg 变量全为零。

我已经尝试了 DeviceIoControl 的其他几个函数,结果相同:bytesReturned 已设置,但输出缓冲区全为零。

我的测试环境

  • 操作系统:Windows 7 Pro 64
  • 集成开发环境:Visual Studio 2010
  • 目标框架:.Net 4.0

最佳答案

DISK_GEOMETRY 声明是问题所在。它被编码为一个对象,但它被声明为一个结构。这意味着它将被装箱,pinvoke 调用只会更新装箱副本。您正在读取原始值,因此得到全零。

简单的解决方法是将其声明为 而不是结构。

关于c# - DeviceIoControl 不设置输出缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13192616/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com