我今天正在通过我的Win32课程来完成一些长期需要的改进。我被困在我的磁盘几何代码上。在
var ob = (DiskGeometry)Marshal.PtrToStructure(geomp, typeof(DiskGeometry));
行,它不断抛出异常..
尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
我的代码是..
if (Handle.IsInvalid)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return new DiskGeometry();
}
var geom = new DiskGeometry();
var geomp = Marshal.AllocHGlobal(Marshal.SizeOf(geom));
Marshal.StructureToPtr(geom, geomp, false);
uint returnedBytes;
if (!DeviceIoControl(Handle, (uint) IOCTL_CONTROL_CODE_CONSTANTS.IOCTL_DISK_GET_DRIVE_GEOMETRY, IntPtr.Zero, 0, ref geomp, (uint)Marshal.SizeOf(typeof(DiskGeometry)), out returnedBytes, IntPtr.Zero))
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return new DiskGeometry();
}
var ob = (DiskGeometry)Marshal.PtrToStructure(geomp, typeof (DiskGeometry));
我做错了什么?
答案 0 :(得分:0)
尝试这样的事情:
//you don't need to instantiate the managed type before this
var geomp = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DiskGeometry)));
//remove this
Marshal.StructureToPtr(geom, geomp, false);
您只需要分配DiskIoControl将使用非托管类型填充的内存块。在指针引用该数据后,您将其编组为托管类型。
您还可以在致电Marshal.GetlastWin32Error()
后查看ERROR_INSUFFICIENT_BUFFER
DeviceIoControl
,并确保returnedBytes == Marshal.SizeOf(typeof(DiskGeometry))
答案 1 :(得分:0)
当从非托管内存编组到托管内存时,“尝试读取或写入受保护的内存。这通常表示其他内存已损坏。”错误表明您没有访问在给定指针位置指定的内存位置的适当权限。
这些是用于验证代码工作正常的定义:
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode,
IntPtr lpInBuffer, uint nInBufferSize,
IntPtr lpOutBuffer, uint nOutBufferSize,
out uint lpBytesReturned, IntPtr lpOverlapped);
(其他代码省略)
IntPtr Handle = CreateFile("\\\\.\\PhysicalDrive0", (EFileAccess)0, EFileShare.Read | EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, (EFileAttributes)0, IntPtr.Zero);
var geom = new DiskGeometry();
var geomp = Marshal.AllocHGlobal(Marshal.SizeOf(geom));
uint returnedBytes = 0;
Marshal.StructureToPtr(geom, geomp, false);
if (!DeviceIoControl(Handle, (uint)IOCTL_DISK_GET_DRIVE_GEOMETRY, IntPtr.Zero, 0, geomp,
(uint)Marshal.SizeOf(typeof(DiskGeometry)),
out returnedBytes,
IntPtr.Zero))
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return;
}
var ob = (DiskGeometry)Marshal.PtrToStructure(geomp, typeof(DiskGeometry));