2010-11-24 34 views
0

Je suivais ma classe Win32 aujourd'hui pour travailler sur quelques améliorations nécessaires depuis longtemps. Je suis coincé sur mon code de géométrie de disque. Sur leProblème avec la classe Marshal

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

ligne, il continue à lancer une exception ..

Tentative de lecture ou d'écriture de mémoire protégée. C'est souvent une indication que l'autre mémoire est corrompue.

Mon code est ..

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

Qu'est-ce que je fais mal?

+0

Pouvez-vous nous montrer la définition de 'DiskGeometry'? – JaredPar

+0

http://pastie.org/1324196 – Eaton

+0

Avez-vous changé quelque chose d'autre? La structure 'DiskGeometry' a-t-elle changé? Qu'en est-il du code au-dessus de ce que vous nous montrez? Je suis curieux de savoir d'où vient "Handle". –

Répondre

0

Essayez quelque chose comme ceci:

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

Vous avez juste besoin d'allouer un bloc de mémoire qui DiskIoControl renseignera avec un type non géré. Une fois que votre pointeur pointe sur ces données, vous le placez dans votre type géré.

Vous pouvez également consulter Marshal.GetlastWin32Error() pour ERROR_INSUFFICIENT_BUFFER après avoir appelé DeviceIoControl et assurez-vous que returnedBytes == Marshal.SizeOf(typeof(DiskGeometry))

+0

Merci, mais cela n'a pas semblé fonctionner. Je l'ai aussi changé en uint et cela n'a eu aucun effet non plus. – Eaton

+0

@Eaton - Qu'en est-il de vérifier que geomp n'est pas nul avant d'essayer de revenir en arrière? – scottm

+0

geomp est 60801 de longueur avant qu'il ne frappe la déclaration ob. – Eaton

0

Lorsque marshaling de la mémoire non géré à la mémoire gérée », Tentative de lecture ou d'écriture de mémoire protégée. Cela est souvent une indication qu'une autre mémoire est corrompu "Les erreurs sont une bonne indication que vous n'avez pas les permissions appropriées pour accéder à l'emplacement de mémoire spécifié à l'emplacement du pointeur donné.

Ce sont les définitions utilisées pour valider votre code fonctionne très bien:

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

(autre code omis)

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

Code mis à jour, ne fonctionne toujours pas. http://pastie.org/1325666 J'ai passé environ 7 heures à essayer de réparer un processus qui devait être un travail de 5 minutes .. Des idées plus anormales? Je suis vraiment frustré avec ça. Joyeux Action de Graces! – Eaton