Ecriture secteur disque en VB net

Résolu
Profil bloqué - 28 sept. 2008 à 02:19
 Profil bloqué - 11 oct. 2008 à 02:16
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.

GRENIER Alain

35 réponses

Profil bloqué
11 oct. 2008 à 02:16
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.

GRENIER Alain
3
gillardg Messages postés 3275 Date d'inscription jeudi 3 avril 2008 Statut Membre Dernière intervention 14 septembre 2014 2
28 sept. 2008 à 11:01
salut Galain , comment as tu traduit les déclarations d'apis de  vb6 à vb2008 ???

pour ma pârt j'utilise P/invoke interrop assistant qui me donne toujours la bonne déclaration

 

<System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)> _

Public

Structure OVERLAPPED

'''ULONG_PTR->unsigned int

Public Internal
As
UInteger

'''ULONG_PTR->unsigned int

Public InternalHigh
As
UInteger

'''Anonymous_7416d31a_1ce9_4e50_b1e1_0f2ad25c0196

Public Union1
As Anonymous_7416d31a_1ce9_4e50_b1e1_0f2ad25c0196

'''HANDLE->void*

Public hEvent
As System.IntPtr
End

Structure<System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)> _

Public

Structure Anonymous_7416d31a_1ce9_4e50_b1e1_0f2ad25c0196

'''Anonymous_ac6e4301_4438_458f_96dd_e86faeeca2a6<System.Runtime.InteropServices.FieldOffsetAttribute(0)> _

Public Struct1
As Anonymous_ac6e4301_4438_458f_96dd_e86faeeca2a6

'''PVOID->void*<System.Runtime.InteropServices.FieldOffsetAttribute(0)> _

Public Pointer
As System.IntPtr
End

Structure<System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)> _

Public

Structure Anonymous_ac6e4301_4438_458f_96dd_e86faeeca2a6

'''DWORD->unsigned int

Public Offset
As
UInteger

'''DWORD->unsigned int

Public OffsetHigh
As
UIntegerEnd

Structure<System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)> _

Public

Structure SECURITY_ATTRIBUTES

'''DWORD->unsigned int

Public nLength
As
UInteger

'''LPVOID->void*

Public lpSecurityDescriptor
As System.IntPtr

'''BOOL->int<System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)> _

Public bInheritHandle
As
BooleanEnd

Structure 

Partial

Public
Class NativeMethods

<System.Runtime.InteropServices.DllImportAttribute(

"kernel32.dll", EntryPoint:=
"WriteFile")> _

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(

"kernel32.dll", EntryPoint:=
"FlushFileBuffers")> _

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

End
FunctionEnd

Class 

Bonjour chez vous !
0
Profil bloqué
28 sept. 2008 à 11:20
salut gillardg

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.

GRENIER Alain
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Profil bloqué
28 sept. 2008 à 11:47
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.

GRENIER Alain
0
gillardg Messages postés 3275 Date d'inscription jeudi 3 avril 2008 Statut Membre Dernière intervention 14 septembre 2014 2
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"

Bonjour chez vous !
0
Profil bloqué
28 sept. 2008 à 14:43
Salut gillardg

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.

GRENIER Alain
0
gillardg Messages postés 3275 Date d'inscription jeudi 3 avril 2008 Statut Membre Dernière intervention 14 septembre 2014 2
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

Bonjour chez vous !
0
Profil bloqué
28 sept. 2008 à 17:45
Salut Gillardg

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.

GRENIER Alain
0
gillardg Messages postés 3275 Date d'inscription jeudi 3 avril 2008 Statut Membre Dernière intervention 14 septembre 2014 2
28 sept. 2008 à 18:01
alors c'est le framework
as tu installé le sp1 du framework 3.5???

Bonjour chez vous !
0
Profil bloqué
28 sept. 2008 à 18:15
Salut Gillardg

Je suis en train de l'installer

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.

GRENIER Alain
0
gillardg Messages postés 3275 Date d'inscription jeudi 3 avril 2008 Statut Membre Dernière intervention 14 septembre 2014 2
28 sept. 2008 à 18:37
pourquoi ne pas compiler ses routines dans une dll vb6 et l'utiliser dans un projet vb2008 ??

Bonjour chez vous !
0
Profil bloqué
28 sept. 2008 à 18:45
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.

GRENIER Alain
0
gillardg Messages postés 3275 Date d'inscription jeudi 3 avril 2008 Statut Membre Dernière intervention 14 septembre 2014 2
28 sept. 2008 à 18:48
alors si tu ne trouves pas d'aide ici yu peux toujours éssayer sur msnews

Bonjour chez vous !
0
Profil bloqué
28 sept. 2008 à 21:11
Salut Gillardg

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.

GRENIER Alain
0
cs_Willi Messages postés 2375 Date d'inscription jeudi 12 juillet 2001 Statut Modérateur Dernière intervention 15 décembre 2018 22
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

Bon courage ++
0
Profil bloqué
30 sept. 2008 à 23:43
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.

GRENIER Alain
0
Profil bloqué
1 oct. 2008 à 06:54
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

URL de l'article en question ---> http://www.programmez.com/forum/viewtopic.php?t=1176&postdays=0&postorder=asc&start=30
Merci 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.

GRENIER Alain
0
cs_Willi Messages postés 2375 Date d'inscription jeudi 12 juillet 2001 Statut Modérateur Dernière intervention 15 décembre 2018 22
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.
0
Profil bloqué
1 oct. 2008 à 18:45
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.

GRENIER Alain
0
Rejoignez-nous