DrThrax
Messages postés38Date d'inscriptiondimanche 29 janvier 2006StatutMembreDernière intervention17 août 2008
-
12 août 2006 à 20:10
DrThrax
Messages postés38Date d'inscriptiondimanche 29 janvier 2006StatutMembreDernière intervention17 août 2008
-
14 août 2006 à 21:42
Bonjour a tous,
Voilà j'essaye d'utiliser l'api IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, pour obtenir la geométrie du disque, pour se faire j'ai suivi les instruction de msdn j'ai creer toutes les structutres nécéssaires, j'ai essayé de mettre les bon types donnée, mais rien a faire j'ai toujours cette erreur:
PInvokeStackImbalance a été détecté
Message: Un appel à la fonction PInvoke 'hddtools!WindowsApplication1.Form1::DeviceIoControl' a déséquilibré la pile. Cela peut se produire, car la signature PInvoke managée ne correspond pas à la signature cible non managée. Vérifiez que la convention d'appel et les paramètres de la signature PInvoke correspondent à la signature non managée cible.
Voici le code source de mon application (elle assez brouillon a cause des nombreux teste effectué, veuillez m'en excusé):
Imports Microsoft.VisualBasic
Public Class Form1
'appel de CTL_CODE pour obtneir le code d'optention de la géométrie
Private Function CTL_CODE(ByVal DeviceType As UInteger, ByVal Fct As UInteger, ByVal Method As UInteger, ByVal Access As UInteger) As UInteger
Return ((DeviceType) << 16) Or ((Access) << 14) Or ((Fct) << 2) Or (Method)
End Function
'calul du code d'optention de la geométrie
Private IOCTL_DISK_GET_DRIVE_GEOMETRY_EX As Long = CTL_CODE(IOCTL_DISK_BASE, &H28, METHOD_BUFFERED, FILE_ANY_ACCESS)
'déclaration de l'api CreateFile de kernel32.dll
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As UInteger, ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As UInteger, ByVal dwFlagsAndAttributes As UInteger, ByVal hTemplateFile As IntPtr) As IntPtr
'declaration de l'api DeviceIoControl deKernel32.dll
Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, ByVal lpInBuffer As Object, ByVal nInBufferSize As Long, ByVal lpOutBuffer As DISK_GEOMETRY_EX, ByVal nOutBufferSize As Long, ByVal lpBytesReturned As Long, ByVal lpOverlapped As Object) As Long
Structure DISK_GEOMETRY
Dim Cylinders As Int64
Dim MediaType As MEDIA_TYPE
Dim TracksPerCylinder As Int64
Dim SectorsPerTrack As Int64
Dim BytesPerSector As Int64
End Structure
Structure DISK_GEOMETRY_EX
Dim Geometry As DISK_GEOMETRY
Dim DiskSize As Int64
Dim Data() As Byte
End Structure
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'instruction pour plus tard
'Dim allDrives() As DriveInfo = DriveInfo.GetDrives()
'Dim d As DriveInfo
Dim dg As New DISK_GEOMETRY_EX
Dim drive As String
drive = "c:"
Dim hwndDevice As Long = CreateFile("\\." & drive, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero)
Dim result As Long
result = DeviceIoControl(hwndDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, Nothing, System.Convert.ToByte(0), dg, System.Convert.ToByte(255), System.Convert.ToByte(255), Nothing)
End Sub
End Class
J'aimerais que quelqu'un m'explique ce qu j'ai mal fait ou oublié de faire,
je remercie toutes les personne qui m'aiderons, je remerci aussi willi pour l'aide déjà approtée
cs_Willi
Messages postés2375Date d'inscriptionjeudi 12 juillet 2001StatutModérateurDernière intervention15 décembre 201822 12 août 2006 à 22:07
Bonsoir,
J'ai commenté pour que tu comprennes un miminum ce que j'ai fais.
J'ai typé tes constantes également ! Pense y par la suite pour plus de clarté.
J'ai modifié quelque peu les déclarations API et y ai ajouté CloseHandle pour libérer le handle ouvert par CreateFile à la fin.
Dans ton bouton1 je n'ai laissé que le nécessaire pour récupérer les datas de ta structure DISK_GEOMETRY_EX.
Declare
Function CreateFile
Lib
"kernel32.dll"
Alias
"CreateFileA" (
ByVal lpFileName
As
String,
ByVal dwDesiredAccess
As
Integer,
ByVal dwShareMode
As
UInteger,
ByVal lpSecurityAttributes
As IntPtr,
ByVal dwCreationDisposition
As
UInteger,
ByVal dwFlagsAndAttributes
As
UInteger,
ByVal hTemplateFile
As IntPtr)
As IntPtr
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As Boolean
Declare
Function DeviceIoControl
Lib
"kernel32.dll" (
ByVal hDevice
As IntPtr,
ByVal dwIoControlCode
As
UInteger,
ByVal lpInBuffer
As IntPtr,
ByVal nInBufferSize
As
UInteger,
ByVal lpOutBuffer
As IntPtr,
ByVal nOutBufferSize
As
UInteger,
ByRef lpBytesReturned
As
UInteger,
ByVal lpOverlapped
As IntPtr)
As
Boolean
'declaration des constantes
Const GENERIC_READ
As
Integer = &H80000000
Const FILE_SHARE_READ
As
Integer = &H1
Const FILE_SHARE_WRITE
As
Integer = &H2
Const OPEN_EXISTING
As
Integer = 3
'déclaratiob des constante DeviceIoControl
Const METHOD_BUFFERED As
Integer
= 0
Const FILE_ANY_ACCESS As
Integer
= 0
Const FILE_DEVICE_DISK As
Integer
= &H7
Const IOCTL_DISK_BASE = FILE_DEVICE_DISK
cs_Willi
Messages postés2375Date d'inscriptionjeudi 12 juillet 2001StatutModérateurDernière intervention15 décembre 201822 12 août 2006 à 22:19
Je ne sais plus si ton problème était de récupérer les datas dans ta structures ou bien utiliser correctement la méthode DeviceIoControl. Du coup je t'ai tout fais....
Tiens nous au courant si sa marche ou pas.
Vous n’avez pas trouvé la réponse que vous recherchez ?
DrThrax
Messages postés38Date d'inscriptiondimanche 29 janvier 2006StatutMembreDernière intervention17 août 2008 12 août 2006 à 22:36
Maintenant elle fonctionne (je suis pas mito pourtant) mais parfois si on appuye trop vite sur le boutton ou parfois a la fermeture sa se plante merci quand même sans toi je serais toujours nul par
cs_Willi
Messages postés2375Date d'inscriptionjeudi 12 juillet 2001StatutModérateurDernière intervention15 décembre 201822 12 août 2006 à 23:01
Quelles opérations de lecture ?
Compile ton projet en mode release et execute l'exe généré à partir de l'explorer.
Très rarement j'ai des blocage de quelques secondes suivuis d'un message d'erreurs quand je travaille en debug pas à pas.
DrThrax
Messages postés38Date d'inscriptiondimanche 29 janvier 2006StatutMembreDernière intervention17 août 2008 14 août 2006 à 18:39
Voila j'ai ecrit un petit programme qui devrait afficher les nombre de cylindre, de pistes... mais les résultat sont incohérent et l'application plante aléatoirement avec une preference pour la fermeture quand on a lancé l'application plus qu'une fois.
Est-ce que quelqu'un pourrait (encore) m'aider svp.
'appel de CTL_CODE pour obtneir le code d'optention de la géométrie
Private Function CTL_CODE(ByVal DeviceType As UInteger, ByVal Fct As UInteger, ByVal Method As UInteger, ByVal Access As UInteger) As UInteger
Return ((DeviceType) << 16) Or ((Access) << 14) Or ((Fct) << 2) Or (Method)
End Function
'calul du code d'optention de la geométrie
Private IOCTL_DISK_GET_DRIVE_GEOMETRY_EX As Long = CTL_CODE(IOCTL_DISK_BASE, &H28, METHOD_BUFFERED, FILE_ANY_ACCESS)
Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As UInteger, ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As UInteger, ByVal dwFlagsAndAttributes As UInteger, ByVal hTemplateFile As IntPtr) As IntPtr
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As Boolean
Declare Function DeviceIoControl Lib "kernel32.dll" (ByVal hDevice As IntPtr, ByVal dwIoControlCode As UInteger, ByVal lpInBuffer As IntPtr, ByVal nInBufferSize As UInteger, ByVal lpOutBuffer As IntPtr, ByVal nOutBufferSize As UInteger, ByRef lpBytesReturned As UInteger, ByVal lpOverlapped As IntPtr) As Boolean
'declaration des constantes
Const GENERIC_READ As Integer = &H80000000
Const FILE_SHARE_READ As Integer = &H1
Const FILE_SHARE_WRITE As Integer = &H2
Const OPEN_EXISTING As Integer = 3
'déclaratiob des constante DeviceIoControl
Const METHOD_BUFFERED As Integer = 0
Const FILE_ANY_ACCESS As Integer = 0
Const FILE_DEVICE_DISK As Integer = &H7
Const IOCTL_DISK_BASE = FILE_DEVICE_DISK
Structure DISK_GEOMETRY
Dim Cylinders As Int64
Dim MediaType As MEDIA_TYPE
Dim TracksPerCylinder As Int64
Dim SectorsPerTrack As Int64
Dim BytesPerSector As Int64
End Structure
Structure DISK_GEOMETRY_EX
Dim Geometry As DISK_GEOMETRY
Dim DiskSize As Int64
Dim Data() As Byte
End Structure
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim dg As New DISK_GEOMETRY_EX
Dim drive As String = "c:"
Dim hwndDevice As IntPtr = CreateFile("\\." & drive, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero)
If hwndDevice <> -1 Then 'handle ok
Dim gcHwnd As GCHandle = GCHandle.Alloc(Marshal.SizeOf(dg), GCHandleType.Pinned)
Dim pBuff As IntPtr = gcHwnd.AddrOfPinnedObject 'pointeur sur le buffer qui va contenir les datas de ta structure
Dim uiRet As UInteger = 0 'octets retournés
Dim bIO As Boolean = DeviceIoControl(hwndDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, Nothing, 0, pBuff, Marshal.SizeOf(dg), uiRet, IntPtr.Zero)
'DeviceIoControl OK
If bIO Then
'Récupération de ta structure DISK_GEOMETRY_EX
dg = Marshal.PtrToStructure(pBuff, dg.GetType)
End If
'Libération du GCHandle et du handle ouvert par CreateFile
gcHwnd.Free()
CloseHandle(hwndDevice)
End If
'Affichage des resultats
Me.ListBox1.Items.Add("Type de média:")
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add(dg.Geometry.MediaType)
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add("Nombre de cylindre:")
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add(dg.Geometry.Cylinders)
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add("Nombre de piste par cylindre:")
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add(dg.Geometry.TracksPerCylinder)
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add("Nombre de sercteur par piste:")
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add(dg.Geometry.SectorsPerTrack)
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add("Nombre de byte par secteur:")
Me.ListBox1.Items.Add("")
Me.ListBox1.Items.Add(dg.Geometry.BytesPerSector)
cs_Willi
Messages postés2375Date d'inscriptionjeudi 12 juillet 2001StatutModérateurDernière intervention15 décembre 201822 14 août 2006 à 21:17
Si tu ne veux pas te faire chi** utilise le fonctions suivante de l'api, tu auras les infos que tu recherches.
Fais une recherche sur le site ou sur google si tu ne sais pas les appeler.
DrThrax
Messages postés38Date d'inscriptiondimanche 29 janvier 2006StatutMembreDernière intervention17 août 2008 14 août 2006 à 21:42
OK merci je vais y regarder demain n'empeche j'ai trouvé une source en c++ qui utilise l'autre méthode mais je comprend pas pourquoi elle elle marche pas grave si cette méthode est plus simple je vais "oublier" l'autre