Bonsoir à tous
Dans le cadre du projet "Acces Direct Disques et Partitions VB net" je cherche à écrire des secteurs disque en VB net
J'utilise les Api Createfile,SetFilePointer,Lockfile,Writefile,Flushfilebuffer et Unlockfile
Createfile et SetfilePointer fonctionnent correctement car utilisées aussi pour la lecture des secteurs mais je bloque sur les 4 autres (Lockfile me renvoie une erreur 87 : paramètre incorrect))
voici mon code de ma fonction DirectWritebytes : iStartSect est le secteur début de l'écriture et nbytes est le nombre d'octets à écrire
Public Sub DirectWriteBytes(ByVal iStartSec As UInt32, ByVal nbytes As Int32)
' Attention le nombre d'octets lus ou écrits ainsi que l'offset du premier octet lu ou écrit
' doivent impérativement être un multiple de la taille d'un secteur de disque
' pointeur et nbytes doivent être des multiples de 512 ( taille standard des secteurs des disques)
Dim BytesWrite As Int32, ret As Int32
dskerr = False
GetSeekDrive(iStartSec) ' voir le code de cette fonction plus bas dans le texte)
If dskerr = True Then Exit Sub
'verrouilage de la zone du disque à écrire
ret = LockFile(hDevice, hexlow, hexhigh, nbytes, 0)
If ret <> 0 Then
'écriture disque
ret = WriteFile(hDevice, writeoctet, nbytes, BytesWrite, IntPtr.Zero)
If ret <> 0 Then
'on vide les buffers internes et on dévérouille la zone
ret = FlushFileBuffers(hDevice)
If ret <> 0 Then
ret = UnlockFile(hDevice, hexlow, hexhigh, nbytes, 0)
End If
End If
End If
If ret = 0 Then
errorVal = Marshal.GetLastWin32Error()
dskerr = True
End If
End Sub
Private Sub GetSeekDrive(ByVal StartSec As UInt32)
Dim pointeur As UInt64
Dim ptsecteurlow As UInt64, ptsecteurhigh As UInt64
Dim ret As Int32
'ouvre le drive la premiére fois
If opendrive = False Then
hDevice = CreateFile(ldrive, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0&)
'quitte si le handle n'est pas valide
If hDevice = INVALID_HANDLE_VALUE Then
MessageBox.Show("Erreur accès disque")
dskerr = True
Exit Sub
End If
opendrive = True
End If
'move pointer
pointeur = Convert.ToInt64(StartSec) * Convert.ToInt64(BytesPerSector) ptsecteurlow pointeur Mod (2 ^ 32) : ptsecteurhigh pointeur \ (2 ^ 32) hexlow Convert.ToInt32(ptsecteurlow.ToString("X8"), 16) : hexhigh Convert.ToInt32(ptsecteurhigh.ToString("X8"), 16)
ret = SetFilePointer(hDevice, hexlow, hexhigh, FILE_BEGIN)
If ret = -1 Then
MessageBox.Show("Erreur accès disque")
dskerr = True
Exit Sub
End If
End Sub
Je n'ai pas mis les déclarations des fonctions ni des variables mais celles-ci sont correctement effectuées
De plus ce code est une adaption d'un code Vb 6.0 (c'est le même projet en vb 6.0) et l'écriture disque sur les secteurs fonctionne correctement en VB 6.0 mais je n'arrive pas à l'adapter en VB net
Je travaille sous windows vista home premium avec visual Basic 2008 Express
Merci d'avance à tous ceux qui essaieront de m'aider et aussi à ceux qui me liront
Et vive Codes-sources
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
salut à Willi principalement et à ceux qui liront ce topic
L'écriture secteur disque avec Vista et VB 6.0 ou NET me semble impossible pour le petit programmeur que je suis
Je laisse tomber. donc Vista : 1 et Galain : 0
Ce n'est pas une fonction indispensable au projet "Acces Direct Disques et Partitions en VB Net"
Merci pour toute l'aide et l'attention que l'on m'a donnée
A+ et bonne prog
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Public
Shared
Function WriteFile(<System.Runtime.InteropServices.InAttribute()>
ByVal hFile
As System.IntPtr, <System.Runtime.InteropServices.InAttribute()>
ByVal lpBuffer
As System.IntPtr,
ByVal nNumberOfBytesToWrite
As
UInteger,
ByVal lpNumberOfBytesWritten
As System.IntPtr,
ByVal lpOverlapped
As System.IntPtr)
As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)>
Boolean
End
Function<System.Runtime.InteropServices.DllImportAttribute(
"kernel32.dll", EntryPoint:=
"LockFile")> _
Public
Shared
Function LockFile(<System.Runtime.InteropServices.InAttribute()>
ByVal hFile
As System.IntPtr,
ByVal dwFileOffsetLow
As
UInteger,
ByVal dwFileOffsetHigh
As
UInteger,
ByVal nNumberOfBytesToLockLow
As
UInteger,
ByVal nNumberOfBytesToLockHigh
As
UInteger)
As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)>
Boolean
End
Function<System.Runtime.InteropServices.DllImportAttribute(
Public
Shared
Function FlushFileBuffers(<System.Runtime.InteropServices.InAttribute()>
ByVal hFile
As System.IntPtr)
As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)>
Boolean
End
Function<System.Runtime.InteropServices.DllImportAttribute(
"kernel32.dll", EntryPoint:=
"UnlockFile")> _
Public
Shared
Function UnlockFile(<System.Runtime.InteropServices.InAttribute()>
ByVal hFile
As System.IntPtr,
ByVal dwFileOffsetLow
As
UInteger,
ByVal dwFileOffsetHigh
As
UInteger,
ByVal nNumberOfBytesToUnlockLow
As
UInteger,
ByVal nNumberOfBytesToUnlockHigh
As
UInteger)
As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)>
Boolean
End
Function<System.Runtime.InteropServices.DllImportAttribute(
"kernel32.dll", EntryPoint:=
"CreateFileW")> _
Public
Shared
Function CreateFileW(<System.Runtime.InteropServices.InAttribute(), System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)>
ByVal lpFileName
As
String,
ByVal dwDesiredAccess
As
UInteger,
ByVal dwShareMode
As
UInteger, <System.Runtime.InteropServices.InAttribute()>
ByVal lpSecurityAttributes
As System.IntPtr,
ByVal dwCreationDisposition
As
UInteger,
ByVal dwFlagsAndAttributes
As
UInteger, <System.Runtime.InteropServices.InAttribute()>
ByVal hTemplateFile
As System.IntPtr)
As System.IntPtr
End
Function<System.Runtime.InteropServices.DllImportAttribute(
"kernel32.dll", EntryPoint:=
"SetFilePointer")> _
Public
Shared
Function SetFilePointer(<System.Runtime.InteropServices.InAttribute()>
ByVal hFile
As System.IntPtr,
ByVal lDistanceToMove
As
Integer, <System.Runtime.InteropServices.InAttribute()>
ByVal lpDistanceToMoveHigh
As System.IntPtr,
ByVal dwMoveMethod
As
UInteger)
As
UInteger
Merci bien de me répondre
P/invoke interrop assistant : c'est quoi car je ne connais pas du tout et surtout comment l'utilise-t-on ?
si tu as un lien je suis preneur
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Merci bien
j'ai téléchargé l'éxécutable du P/invoke interrop assistant et j'avance tout doucement
Je vais regarder tes liens avec soin et tenter de comprendre
J'ai déjà compris qu'il faut faire une transition entre du code "managed" et du code "unmanaged"
Je ne mets pas réponse acceptée pour l'instant et je pense avoir encore besoin d'aide ensuite
a+ et merci encore
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
gillardg
Messages postés3275Date d'inscriptionjeudi 3 avril 2008StatutMembreDernière intervention14 septembre 20142 28 sept. 2008 à 13:30
P/invoke peut etre utilisé pour traduire du c++ en vb.net => onglet "SigImp translate snippet"
toutes les déclarations d'apis sont contenues dans sa base de données => onglet " SigImp Search"
Mon niveau en anglais est beaucoup trop faible pour pouvoir comprendre toutes les subtilités de P/invoke
Je sens que je vais être obligé d'abandonner la fonction "écriture de secteurs en vb net"
C'est quand même bien dommage que Vb 6.0 et VB net soient aussi différents ce qui complique beaucoup le passage de l'un à l'autre
Je vais regarder ce que me donne le convertisseur vb 6.0 ---> VB net : cela me donnera peut-être une piste à suivre
A+ et merci encore
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
gillardg
Messages postés3275Date d'inscriptionjeudi 3 avril 2008StatutMembreDernière intervention14 septembre 20142 28 sept. 2008 à 15:11
ben je pense que c'est par la que tu aurais du commencer
si cela ne fonctionne toujours pas , j'ai peut-être une autre piste :)
le Framework.net /SP1 règle certains problèmes liés à la sécurité
il y a aussi le fait que vista est *****
et les paramètres UAC de ton application
Excuses-moi de te répondre si tard mais j'ai regardé le championnat du monde cyclisme sur route ( rien à voir avec VB mais c'est ma seconde passion)
Le convertisseur vb 6.0 ---> VB net ne me donne rien de nouveau et ne change rien aux déclarations de ces 4 Apis
Pour les paramètres UAC je suis administrateur sur mon poste et mon Framework.net est le 3.5 fourni avec Visual Basic 2008 Express
Je ne pense pas que cela vienne de Vista lui-même car le même projet en version VB 6.0 m'autorise sans problème l'écriture sur les secteurs d'un disque physique ou d'une partition logique
je ne désespère pas néanmoins
a+ et merci
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
De toute façon je finirais bien par y arriver : les routines en vb 6.0 pour les accès direct disque du projet en VB 6.0 m'ont pris plusieurs semaines avant d'être opérationnelles à 100% et sans faille ni bug
Je te tiendrai au courant de la suite de mes recherches et trouvailles sur ce sujet
A+
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Cela serait une bonne idée
Ces routines ont des paramètres en entrée et en sortie
Mais j'aimerais bien le faire en VB net surtout que la lecture de secteurs disque fonctionne nickel en VB net en se basant sur le code VB 6.0
C'est assez frustrant !!!!!
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Après un bon repas je reprends mes recherches
Je vais aller faire un tour sur MSNews
Je mets le projet VB net tel quel sur le site en signalant le problème : ainsi le problème sur l'écriture des secteurs sera plus clair au yeux des membres de Codes-sources et j'aurais peut-être d'autres pistes
Le problème n'est pas pénalisant pour le projet (c'est juste pour purger les clusters librs d'une partition logique FAT ou NTFS) et une gestion d'erreur a été implantée
Merci pour tout et A+
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
cs_Willi
Messages postés2375Date d'inscriptionjeudi 12 juillet 2001StatutModérateurDernière intervention15 décembre 201822 30 sept. 2008 à 23:07
Bonsoir,
Le code erreur de retour sur LockFile indique qu'il y a un ou plusieurs paramètre(s) incorrect(s).
Cela veut dire que dans les paramètres que tu passes tu as surement une voir plusieurs valeurs qui ne peuvent pas être correctes.
Vérifies bien avec ton code vb6 et avec ton code en vb.net si LockFile reçoit bien les mêmes valeurs. Vérifies si ton handle est valide...
Quand à la déclaration ont reconnait bien la le passage du vb6 au vb.net mais elle est "correcte" même si on préfère les déclarations suivantes:
---------------------
<DllImport("kernel32.dll",SetLastError:=True), _
Private Function LockFile(ByVal hFile as SafeFileHandle,ByVal dwFileOffsetLow as Integer,ByVal dwFileOffsetHigh as Integer, _
ByVal nNumberOfBytesToLockLow as Integer,ByVal nNumberOfBytesToLockHigh as Integer) as Boolean
End Function
---------------------
<DllImport("kernel32.dll",SetLastError:=True), _
Private Function LockFile(ByVal hFile as Intptr,ByVal dwFileOffsetLow as Integer,ByVal dwFileOffsetHigh as Integer, _
ByVal nNumberOfBytesToLockLow as Integer,ByVal nNumberOfBytesToLockHigh as Integer) as Boolean
End Function
---------------------
J'ai raccourci ce type Microsoft.Win32.SafeFileHandle dans la 1ière déclaration
Salut Willi
Merci de t'intéresser au problème
J'ai vérifié avec le projet Vb 6.0 et dans les mêmes conditions de fonctionnement (purge des clusters libres de la même partition et sur la même zone) les paramètres de Lockfile sont identiques pour DwFileOffsetLow,DwFileOffsethigh,NumberOfBytesToLockLow et NumberOfBytesToLockHigh
Quand au handle c'est celui-ci qui me permet d'ouvrir la partition la première fois que j'essaie de faire une lecture ou une écriture secteur(ensuite vu que la variable booléenne "Opendrive" = True je ne refais plus de Createfile car la partition est ouverte si on peut dire
Je vais rechercher dans le code s'il n'y aurait pas un CloseHandle de trop (ce qui m'étonnerait car toutes les opérations de lecture des secteurs fonctionnent nickel et celles-ci sont nombreuses car tout le projet est bâti principalement sur la lecture des secteurs pour restituer les détails sur la MFT,les enregistrements,etc..... en NTFS et les entrées de répertoires 32 bits,le chainage des clusters,etc...... en FAT
J'ai lu cet article qui me redonnait espoir ---> http://www.programmez.com/forum/viewtopic.php?t=1176&postdays=0&postorder=asc&start=30 mais ceci ne me paraît pas logique car il concerne Windows vista avec l'écriture secteurs. Or j'ai Vista et avec VB 6.0 l'écriture secteurs fonctionne mais avec VB Net 2008 j'ai cette erreur
si jamais tu as une piste contactes moi (cela fait bientôt 3 semaines que je galère avec ce problème)
A+ et merci
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Salut à tous et principalement Gillardg et Willi
L'écriture des secteurs disque du projet VB 6.0 ne fonctionne pas non plus
Pour les 4 Apis concernées je les appelais par de simples Call sans tester leurs valeurs de retour pour savoir si la fonction était réussie ou pas.
De ce fait la piste de l'article trouvé sur le Net incriminant Vista est plus que relancée.De mémoire sous XP cela fonctionnait vraiement car j'avais implanté à cette époque sur le projet VB 6.0 une possibilité d'éditer et de modifier des octets sur un secteur donné et la modification était effective.
Pour résumer c'est Vista qui nous bloque les accés directs en écriture pour les secteurs disque
cs_Willi
Messages postés2375Date d'inscriptionjeudi 12 juillet 2001StatutModérateurDernière intervention15 décembre 201822 1 oct. 2008 à 08:24
J'ai testé ta source version .net sous xp c'est pareil que sous vista ! (Pour les apps .net il faut regarder du côté de la sécurité de l'assembly également sa peut jouer.
Bref, des tests sont à faire une app vierge, comme cela nous serons fixés.
Salut Willi
Au sujet de l'écriture des secteurs la version VB 6.0 fonctionnait vraiment mais sous XP. A cette époque je ne possédais point encore Vista.
En résumé on a
- XP et projet VB 6.0 ----> Ok ça marche
- XP et projet VB Net ----> Pas testé mais tu me dis que cela ne fonctionne pas
- Vista et projet VB 6.0 ----> Ne fonctionne pas
- Vista et projet VB Net ----> Ne fonctionne pas
tu me dis aussi ; Pour les apps .net il faut regarder du côté de la sécurité de l'assembly mais cela n'explique pas le fait que "Vista et projet VB 6.0" ne fonctionne pas. Pour moi l'assembly est lié au projet mais non au système d'exploitation. Par contre le Framework est commun à Vista et à VB Net. Le fait d'avoir Net (soit Vista ou VB Net ou les deux) nous bloque la fonction écriture secteurs.
J'espère que mon raisonnement est correct
J'envisage de faire une application toute simple de lecture et écriture secteurs (un seul formulaire) afin de faire des tests
Merci pour ton aide et A +
La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.