Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : Problème Marshal.StructureToPtr [ Système / Fichier & Disque ] (Galain)

lundi 24 mars 2008 à 03:47:06 | Problème Marshal.StructureToPtr

Galain

Membre Club
Salut à tous
Cela fait 3 jours que je galère avec VB net et j'appelle au secours

 'execute a command through the SPTI

    Private Function SPTICmd(ByRef cmd() As Byte, ByVal CmdLen As Integer, ByVal WFE As Boolean, ByVal eDir As e_SPTIDirection, ByVal Pointer As Long, ByVal PointerLen As Long, Optional ByVal Timeout As Long = 5) As Boolean

        Dim pswb As t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
        Dim Lengthpswb As Int32, returned As Int32
        Dim status As Int32, i As Byte

        dskerr = False
        ReDim pswb.spt.cdb(0 To 15)
        ReDim pswb.spt.Fill(0 To 2)
        ReDim pswb.SenseBuffer(0 To 35)

        'check the timeout
        If WFE Then Timeout = 9999 Else If Timeout = 0 Then Timeout = 10
        With pswb.spt
            .Length = 44    ' size of the substructure
            .DataIn = eDir    ' data dir
            .TimeOutValue = Timeout    ' Timeout
            .SenseInfoLength = (pswb.SenseBuffer.Length - 1) - 4    ' Sense Info size
            .SenseInfoOffset = Marshal.SizeOf(pswb.spt) + 4    ' Sense Info Offset
            .DataTransferLength = PointerLen    ' data len
            .DataBuffer = Pointer    ' data buffer pointer
            For i = 0 To CmdLen - 1
                .cdb(i) = cmd(i) ' CDB from Array
            Next i
            .CdbLength = CmdLen    ' CDB len
        End With
        Lengthpswb = pswb.spt.Length + pswb.SenseBuffer.Length    ' size of the structure

        ' allocation mémoire por la structure
        Dim uiSpace As Int32 = Convert.ToInt32(Lengthpswb) 'Représente la taille de la structure
        Dim pbuffout As IntPtr = Marshal.AllocHGlobal(uiSpace) 'Alloue un espace mémoire

        ' Copie de la structure dans la zone mémoire allouée
        Marshal.StructureToPtr(pswb, pbuffout, True) ' ICI erreur : Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.

        ' opération disque
        status = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, pbuffout, Lengthpswb, pbuffout, Lengthpswb, returned, IntPtr.Zero)

        ' Copie de la mémoire allouée dans la structure
        Marshal.PtrToStructure(pbuffout, pswb)

        ' on libère la zone mémoire
        Marshal.FreeHGlobal(pbuffout)

        ' on a réussi ?
        SPTICmd = status = 1 And pswb.spt.ScsiStatus = 0
        If SPTICmd = False Then dskerr = True

    End Function

On copie la structure pswb dans une zone mémoire allouée
On détermine  le pointeur de cette zone mémoire
On copie la structure dans la zone mémoire
On appelle DeviceIoControl
On recopie la zone mémoire dans la structure
On teste si l'opération a réussie

Mon raisonnement est-il juste?
Que signifie l'erreur à ICI Erreur ?

Les paramètres de la structure pswb sont corrects car ceux-ci fonctionnent correctement à l'identique sur un projet VB 6.0. Mais en VB net c'est la cata

Merci pour l'aide et bonne prog à tous

GRENIER Alain

lundi 24 mars 2008 à 04:10:29 | Re : Problème Marshal.StructureToPtr

Galain

Membre Club
J'ai corrigé l'appel de la fonction : Pointer est un Intptr et 2 valeurs Long (VB 6.0) sont devenes Int32 (VB net) mais le problème reste entier
J'ai mis aussi le Imports System.Interopservices en debiut de module

Private Function SPTICmd(ByRef cmd() As Byte, ByVal CmdLen As Integer, ByVal WFE As Boolean, ByVal eDir As e_SPTIDirection, ByVal Pointer As Intptr, ByVal PointerLen As Int32, Optional ByVal Timeout As Int32 = 5) As Boolean

Je cherche et j'attends une piste de votre part
Merci

GRENIER Alain

lundi 24 mars 2008 à 12:31:08 | Re : Problème Marshal.StructureToPtr

akim77

Bonjour,

Difficile de trouver ton problème, sans savoir comment est declaré t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER

le calcul de uiSpace semble compliqué, as-tu essayé :
Marshal.AllocHGlobal(Marshal.SizeOf(pswb))

Akim



lundi 24 mars 2008 à 14:06:04 | Re : Problème Marshal.StructureToPtr

Galain

Membre Club
Merci Akim 77 de t'intéresser au problème
voici la déclaration de la structure pswb as t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER

Public Structure t_SPTD
        Dim Length As Int16            ' data len
        Dim ScsiStatus As Byte           ' SCSI Status
        Dim PathId As Byte               ' Bus Number
        Dim TargetId As Byte             ' Target
        Dim Lun As Byte                  ' Logical Unit Number
        Dim CdbLength As Byte            ' CDB (Command Descriptor Block)
        Dim SenseInfoLength As Byte      ' Sense Info len
        Dim DataIn As Byte               ' data direction
        Dim DataTransferLength As Int32  ' data transfer length
        Dim TimeOutValue As Int32        ' command timeout
        Dim DataBuffer As Int32          ' Pointer to the data buffer
        Dim SenseInfoOffset As Int32     ' Sense Info Offset
        Dim cdb() As Byte                ' Command Descriptor Block (0 to 15)
        Dim Fill() As Byte               ' (0 to 2)
    End Structure

    Public Structure t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
        Dim spt As t_SPTD              ' SPTD structure
        Dim SenseBuffer() As Byte    ' Debugging-Info from the drive (0 to 35)
    End Structure

Dans le code on calcule 2 paramètres de cette structure
Voici les calculs en VB Net
.SenseInfoLength = (pswb.SenseBuffer.Length - 1) - 4    ' Sense Info size
.SenseInfoOffset = Marshal.SizeOf(pswb.spt) + 4    ' Sense Info Offset

et leus équivalents en VB 6.0
.SenseInfoLength = UBound(pswb.SenseBuffer) - 4    ' Sense Info size
.SenseInfoOffset = Len(pswb.spt) + 4    ' Sense Info Offset

Ceci vous donnera peut-être un début de piste

Autre chose en rapport
Lorsque l'on fait Dim pswb As t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER on réserve  bien en mémoire une zone pour cette structure. Comment avoir son pointeur en Intptr ( c'est à dire son adresse mémoire si j'ai bien compris) ?

Avec mes remerciements

GRENIER Alain

lundi 24 mars 2008 à 15:27:54 | Re : Problème Marshal.StructureToPtr

akim77

Ici [ Lien ]
MSDN nous dit:
StructureToPtr copies the contents of structure to the pre-allocated block of memory pointed to by the ptr parameter.
If the fDeleteOld parameter is true, the buffer originally pointed to by ptr is deleted with the appropriate delete API
on the embedded pointer, but the buffer must contain valid data.

Notre pbuffout fraichement créé ne contient aucune donnée valide donc on doit utiliser:
Marshal.StructureToPtr(pswb, pbuffout, False)

Je n'ai plus d'erreur mais je ne pas être sûr que ça fonctionne.

@+

Akim



lundi 24 mars 2008 à 21:39:44 | Re : Problème Marshal.StructureToPtr

Galain

Membre Club
Salut Akim77 et à tous les autres
Désolé de ne pas avoir pu répondre avant mais les connections internet sur ma région( Cergy et le Val d'Oise) sont très mauvaises

Je n'ai plus la première erreur et la commande DeviceIoControl ne renvoie un status correct prouvant qu'elle s'est bien déroulée.
par contre l'erreur se situe maintenant à la ligne suivante au Marshal.PtrToStructure qui renvoie la mémoire pointée vert la structure d'entrée de DeviceIoControl

' Copie de la mémoire allouée dans la structure
 Marshal.PtrToStructure(pbuffout, pswb)   <------- ICI Erreur

L'erreur est : La structure ne doit pas être une classe Valeur

Je t'envoie le message sur le forum et cherche de mon côté

Merci d'avoir solutionné à plus de 80% mon problème

Merci à tous et bonne prog
GRENIER Alain

mardi 25 mars 2008 à 06:55:52 | Re : Problème Marshal.StructureToPtr

akim77

Réponse acceptée !

Avec VB.NET il n'y a pas moyen de se passer de la documentation sur MSDN
ici: [ Lien ]

Il suffit de copier l'exemple et ça donne:

Dim pswb_bis As t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
pswb_bis = CType(Marshal.PtrToStructure(pbuffout, GetType(t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)), t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)

@+

Akim


mardi 25 mars 2008 à 07:16:10 | Re : Problème Marshal.StructureToPtr

Galain

Membre Club
Merci Akim 77 pout ton aide

GRENIER Alain

lundi 31 mars 2008 à 15:21:39 | Re : Problème Marshal.StructureToPtr

Galain

Membre Club
Réponse acceptée !
Pour ceux que cela intéresse voici le module qui permet l'accès bas niveau au CDROM ou DVDROM en vb Net
En exemple la fonction CDRomGetSectorMode donne le mode du support inséré( mode 0 = audio, mode 1 : data, etc....)

Ce module sera inclus dans la gestion des CDROMs etDVDROMs du projet "Accés Disques et Partions VB Net" qui est en chantier

Imports System.Runtime.InteropServices

Module Module3

    Private Enum e_SPTIDirection
        SCSI_IOCTL_DATA_OUT = 0          ' send data to the drive
        SCSI_IOCTL_DATA_IN = 1           ' retrieve data from the drive
        SCSI_IOCTL_DATA_UNSPECIFIED = 2  ' no transfer
    End Enum

    Public Enum e_AspiDirection
        SRB_DIR_IN = &H8      ' retrieve data from the drive
        SRB_DIR_OUT = &H10    ' send data to the drive
    End Enum

    Public Enum e_READCD_FLAGS
        RCD_SYNC = &H80                                   ' sync pattern
        RCD_HDR_4BT = &H20                                ' 4-Bytes Header
        RCD_HDR_8BT = &H40                                ' 8-Bytes Header
        RCD_USRDATA = &H10                                ' userdata
        RCD_EDC_ECC = &H8                                 ' EDC+ECC correction
        RCD_RAW = &HF8                                    ' full sector
    End Enum

    Public Enum e_READCD_SUBCH_FLAGS
        RCD_SUBCH_PW_RAW = &H1                            ' Raw Channels P-W
        RCD_SUBCH_Q = &H2                                 ' only Q channel
        RCD_SUBCH_PW_CORRECTED = &H4                      ' Channels P-W corrected
    End Enum

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
        Dim Lengthdata As Int16          ' data len
        Dim ScsiStatus As Byte           ' SCSI Status
        Dim PathId As Byte               ' Bus Number
        Dim TargetId As Byte             ' Target
        Dim Lun As Byte                  ' Logical Unit Number
        Dim CdbLength As Byte            ' CDB (Command Descriptor Block)
        Dim SenseInfoLength As Byte      ' Sense Info len
        Dim DataIn As Byte               ' data direction
        Dim DataTransferLength As Int32  ' data transfer length
        Dim TimeOutValue As Int32        ' command timeout
        Dim DataBuffer As Int32          ' Pointer to the data buffer
        Dim SenseInfoOffset As Int32     ' Sense Info Offset
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=16)> Dim Cdb() As Byte ' commande SPTI
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim Fill() As Byte
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=36)> Dim SenseBuffer() As Byte ' Debugging-Info from the drive (0 to 35)
    End Structure

    Public SYNCPATTERN As String = "00FFFFFFFFFFFFFFFFFFFF00"
    Private IOCTL_SCSI_PASS_THROUGH_DIRECT As UInt32 = &H4D014
    Public buffer() As Byte

    Public Function CDRomGetSectorMode(ByVal SectorLBA As Int32) As Int32 ' (fonction exemple)

        Dim sync As String, cnt As Integer

        'read sector raw
        ReDim buffer(0 To 2351)
        'read sector raw
        If Not CDRomReadCD(SectorLBA, 1, e_READCD_FLAGS.RCD_RAW) Then
            CDRomGetSectorMode = -1
            dskerr = True
            Exit Function
        End If

        'get the first 12 bytes and convert them to hex
        sync = ""
        For cnt = 0 To 11
            sync = sync & buffer(cnt).ToString("X2")
        Next

        'is a sync pattern?
        If sync = SYNCPATTERN Then
            'Byte 16 is the mode
            Select Case buffer(15)
                Case 1
                    'Mode-1 Track (2048 Bytes data)
                    CDRomGetSectorMode = 1
                Case 2
                    'compare pattern
                    If (buffer(16) = buffer(20)) And (buffer(17) = buffer(21)) _
                       And (buffer(18) = buffer(22)) And (buffer(19) = buffer(23)) Then
                        If Not buffer(18) And &H20 = 0 Then
                            'Mode 2 Form 2 Track
                            CDRomGetSectorMode = 4
                        Else
                            'Mode 2 Form 1 Track
                            CDRomGetSectorMode = 3
                        End If
                    Else
                        'Mode-2 Track (2336 Bytes data)
                        CDRomGetSectorMode = 2
                    End If
            End Select
        Else
            'Audio or Mode-0 (2352 Bytes data/2352 Bytes completely empty)
            CDRomGetSectorMode = 0
        End If

    End Function

    Public Function CDRomReadCD(ByVal LBA As Int32, ByVal NumSectors As Int32, ByVal ReadFlags As e_READCD_FLAGS, Optional ByVal SubchBits As e_READCD_SUBCH_FLAGS = 0) As Boolean

        Dim cmd(11) As Byte

        cmd(0) = &HBE                               ' READ CD OpCode
        cmd(2) = (LBA >> 24) And &HFF           ' LBA
        cmd(3) = (LBA >> 16) And &HFF
        cmd(4) = (LBA >> 8) And &HFF
        cmd(5) = LBA And &HFF                       ' LBA
        cmd(6) = (NumSectors >> 16) And &HFF    ' num. sectors
        cmd(7) = (NumSectors >> 8) And &HFF
        cmd(8) = NumSectors And &HFF                ' num. sectors
        cmd(9) = ReadFlags                          ' read flags
        cmd(10) = SubchBits                         ' Sub-Channel Flags

        CDRomReadCD = ExecCMD(cmd, 12, False, e_AspiDirection.SRB_DIR_IN, 40)

    End Function

    Private Function ExecCMD(ByRef cmd() As Byte, ByVal CmdLen As Int16, ByVal WFE As Boolean, ByVal eDir As e_AspiDirection, Optional ByVal Timeout As Int32 = 5) As Boolean

        Dim DataDir As Int32

        'SPTI
        If eDir = e_AspiDirection.SRB_DIR_IN Then
            DataDir = e_SPTIDirection.SCSI_IOCTL_DATA_IN
        Else
            DataDir = e_SPTIDirection.SCSI_IOCTL_DATA_OUT
        End If
        ExecCMD = SPTICmd(cmd, CmdLen, WFE, DataDir, Timeout)

    End Function

    'execute a command through the SPTI

    Private Function SPTICmd(ByRef cmd() As Byte, ByVal CmdLen As Int16, ByVal WFE As Boolean, ByVal eDir As e_SPTIDirection, Optional ByVal Timeout As Int32 = 5) As Boolean

        Dim pswb As t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
        Dim Lengthpswb As UInt32, returned As UInt32
        Dim status As Int32, i As Byte
        Dim pointerdata As IntPtr, pointerpswb As IntPtr

        dskerr = False
        ReDim pswb.cdb(0 To 15)
        ReDim pswb.Fill(0 To 2)
        ReDim pswb.SenseBuffer(0 To 35)

        ' création du pointeur du buffer des Datas
        pointerdata = Marshal.AllocHGlobal(Convert.ToInt32(buffer.Length))

        ' création du pointeur du buffer de la structure pswb
        pointerpswb = Marshal.AllocHGlobal(80)

        'check the timeout
        If WFE Then Timeout = 9999 Else If Timeout = 0 Then Timeout = 10
        With pswb
            .Lengthdata = 44    ' taille de la structure
            .DataIn = eDir    ' data dir
            .TimeOutValue = Timeout    ' Timeout
            .SenseInfoLength = (pswb.SenseBuffer.Length - 1) - 4    ' Sense Info size
            .SenseInfoOffset = (pswb.Lengthdata) + 4    ' Sense Info Offset
            .DataTransferLength = buffer.Length    ' data len
            .DataBuffer = pointerdata    ' data buffer pointer
            For i = 0 To CmdLen - 1 : .cdb(i) = cmd(i) : Next i    ' CDB from Array
            .CdbLength = CmdLen    ' CDB len
            Lengthpswb = .Lengthdata + .SenseBuffer.Length   ' size of the structure
        End With
        Marshal.StructureToPtr(pswb, pointerpswb, False)

        'SPTD
        status = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, pointerpswb, Lengthpswb, pointerpswb, Lengthpswb, returned, IntPtr.Zero)

        'success?
        pswb.ScsiStatus = Marshal.ReadByte(pointerpswb, 2)
        SPTICmd = (status = 1) And (pswb.ScsiStatus = 0)
        If SPTICmd = False Then dskerr = True
        Marshal.Copy(pointerdata, buffer, 0, buffer.Length)
        Marshal.FreeHGlobal(pointerdata)
        Marshal.FreeHGlobal(pointerpswb)

    End Function

End Module

Un grand merci à Akim77 qui m'a bien aidé ainsi quàWilli (je lui ai pris un bout de code pour l'analyse des partitions NTFS)
bonne prog à tous et A+


GRENIER Alain



Cette discussion est classé dans : mémoire, structure, timeout, marshal, pswb


Répondre à ce message

Sujets en rapport avec ce message

Pb : Vérification de la mémoire prise par une structure de donnée [ par Cyrik ] Salut tout le monde,Mon problème est simple, j'aimerais trouver un moyen de calculer l'espace pris par certains type de données (collection, tableau d Obtenir l'adresse mémoire d'une structure [ par Dlofret ] Bonjour,Dans un code, j'utilise une structure que j'ai definit avec l'instruction TYPE. J'aimerais savoir son adresse en mémoire. Je ne peux pas utili Tableau de structures dans de la mémoire non-managé [ par Kevin.Ory ] Bonjour,Je suis en train de faire un Wrapper de l'API Mixer en VB.NET. Je n'ai pas eu de problèmes particuliers jusqu'à ce que je sois apparement obli Probleme Tableau 1dimension avec structure [ par zlatan40 ] Bonjour Voila j'ai un probleme avec un tableau a une dimension structuré 1. Public Structure mouvement 2. Dim datemv As String 3. erreur [ par ddove53 ] Bonjour, avez-vous une idée sur ce genre d'erreur?l'instruction à "0x770e4bee" emploie l'adresse mémoire "0x03911000" la mémoire ne peut etre "read".Q Lier 2 Processus [ par Nowid50 ] Bonjour,Après avoir demandé comment faire une DLL COM, j'ai trouvé une autre solution qui me semblerait plus simple. Pour exepliquer le but de mon pro Garder en mémoire l'état d'un programme [ par beezzers ] Bonjour, je suis a développer un programme qui enregistre des image selon certain critère.Je voudrais qu'il puisse garder le compte même s'il est ferm API taille de fenetre [ par rvp68 ] Bonjour,J'ai un probleme avec les API Windows, je m'explique:Je souhaite connaitre la position ainsi que la taille d'une fenetre.Je recupere une struc Lire un offset en mémoire [ par VladDracula ] Salut ^^Voilà, je voudrais lire certaine adresse mémoire d'une application avec ReadProcessMemory. J'ai le Handle et PID de mon appli, pas trop dur à Lecture secteur CDROM en mode RAW [ par Galain ] Salut à tousJe cherche à lire un secteur sur un CDROM en mode RAW ( les 2352 octets)J'ai le code suivant mais Deviceiocontrol me renvoie une erreurJe


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,577 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.