2010-11-24 11 views
0

Ich ging heute durch meine Win32-Klasse, um an einigen dringend benötigten Verbesserungen zu arbeiten. Ich stecke auf meinem Festplatten-Geometrie-Code fest. Auf derProblem mit der Marshalklasse

var ob = (DiskGeometry) Marshal.PtrToStructure (geomp, typeof (DiskGeometry));

Linie, hält es eine Ausnahme zu werfen ..

Versuchte geschützten Speicher zu lesen oder zu schreiben. Dies ist oft ein Hinweis darauf, dass anderer Speicher beschädigt ist.

Mein Code ist ..

 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)); 

Was mache ich falsch?

+0

Können Sie uns zeigen, die Definition für 'DiskGeometry'? – JaredPar

+0

http://pastie.org/1324196 – Eaton

+0

Haben Sie noch etwas geändert? Hat sich die 'DiskGeometry' Struktur geändert? Was ist mit dem Code über dem, was Sie uns zeigen? Ich bin gespannt, woher 'Handle' kommt. –

Antwort

0

so etwas wie dieses Versuchen:

//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); 

Sie brauchen nur einen Block von Speicher zuzuweisen, die DiskIoControl mit einem nicht verwalteten Typ bevölkern werden. Nachdem der Zeiger auf diese Daten verweist, ordnen Sie ihn dem verwalteten Typ zu.

Sie auch Marshal.GetlastWin32Error() für ERROR_INSUFFICIENT_BUFFER nach DeviceIoControl Aufruf und stellen Sie sicher, überprüfen, dass returnedBytes == Marshal.SizeOf(typeof(DiskGeometry))

+0

Danke, aber das schien nicht zu funktionieren. Ich habe es auch wieder in eine Uinture geändert und es hatte auch keinen Einfluss. – Eaton

+0

@Eaton - Was ist mit der Überprüfung, dass Geomp nicht Null ist, bevor Sie versuchen, zurück zu marshallen? – scottm

+0

Geomp ist 60801 in der Länge, bevor es die Ob-Erklärung trifft. – Eaton

0

Wenn aus dem nicht verwalteten Speicher verwalteten Speicher Marshalling "Versuchte geschützten Speicher zu lesen oder schreiben. Dies ist häufig ein Hinweis darauf, dass andere Speicher ist beschädigt. "Fehler sind ein guter Hinweis, dass Sie nicht über die entsprechenden Berechtigungen verfügen, auf den Speicherort zuzugreifen, der an der angegebenen Zeigerposition angegeben wird.

Dies sind die Definitionen verwendet, um Ihren Code zu validieren funktioniert:

[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); 

(andere Code weggelassen)

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)); 
+0

Aktualisierter Code funktioniert immer noch nicht. http://pastie.org/1325666 Ich habe ungefähr 7 Stunden damit verbracht, einen Prozess zu reparieren, der als 5-Minuten-Job gedacht war. Irgendwelche Ideen? Ich werde wirklich frustriert damit. Frohes Thanksgiving! – Eaton