[R] Alternative à DriveGetDrive ("REMOVABLE") ?

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
davzell
Niveau 5
Niveau 5
Messages : 105
Enregistré le : jeu. 26 sept. 2013 14:15
Status : Hors ligne

[R] Alternative à DriveGetDrive ("REMOVABLE") ?

#1

Message par davzell »

Bonjour à tous,

j'utilise la fonction DriveGetDrive ("REMOVABLE") dans un script afin de détecter si j'ai une clef usb de branché.

Ca marche très bien sauf que je viens de me rendre compte que certains disques durs usb (western digital 2to) sont reconnus comme disque dur et non pas comme périphérique USB...

C'est windows qui le détecte en disque dur.

Est ce que vous connaissez une autre méthode qui me permettrait de détecter ces disques USB ? Ou un moyen de modifier ce que vois Windows et de lui dire que c'est de l'usb ?

merci
Modifié en dernier par davzell le mer. 31 août 2016 15:32, modifié 1 fois.
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1037
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#2

Message par walkson »

Bonjour,
Ca marche très bien sauf que je viens de me rendre compte que certains disques durs usb (western digital 2to) sont reconnus comme disque dur et non pas comme périphérique USB...
Je viens de tester et en effet le disque USB est reconnu en Fixe.
Peut être en biaisant ?
#include <MsgBoxConstants.au3>

Local $aArray = DriveGetDrive("ALL")
If @error Then
   ; An error occurred when retrieving the drives.
   MsgBox($MB_SYSTEMMODAL, "", "It appears an error occurred.")
Else
   For $i = 1 To $aArray[0]
      ; Show all the drives found and convert the drive letter to uppercase.
      ConsoleWrite( "Drive " & $i & "/" & $aArray[0] & ":" & @CRLF & StringUpper($aArray[$i]) & @CRLF & DriveGetSerial(StringUpper($aArray[$i])&"\")& @CR)
      $serial = DriveGetSerial(StringUpper($aArray[$i])&"\")
      If $serial = 371812978 Then MsgBox(0,$serial,"On a gagné!")
   Next
EndIf
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
davzell
Niveau 5
Niveau 5
Messages : 105
Enregistré le : jeu. 26 sept. 2013 14:15
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#3

Message par davzell »

mais du coup le 371812978 est uniquement bon pour ton disque dur non ?

Je voudrais que ce soit détectable pour tous les disques durs externe
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1037
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#4

Message par walkson »

Il y a peut être plus simple (code de Guinness)
#include <Array.au3>
#include <WinAPI.au3>
#include <WinAPIFiles.au3>
#include <WinAPISys.au3>

Global Const $DIGCF_DEVICEINTERFACE = 0x10
Global Const $DIGCF_PRESENT = 0x2
Global Const $CR_SUCCESS = 0
Global Const $CR_ACCESS_DENIED = 0x33
Global Const $CM_REMOVE_UI_OK = 0
Global Const $CM_REMOVE_UI_NOT_OK = 0x1
Global Const $CM_REMOVE_NO_RESTART = 0x2
Global Const $CM_SETUP_DEVNODE_READY = 0
Global Const $CM_SETUP_DEVNODE_RESET = 0x4
Global Const $DN_REMOVABLE = 0x4000
Global Const $PNP_VetoTypeUnknown = 0 ; Name is unspecified
Global Enum $DRIVE_EJECT_DEVICENUMBER, _ ; int
        $DRIVE_EJECT_DEVICETYPE, _ ; int
        $DRIVE_EJECT_DEVICEDOSNAME, _ ; string
        $DRIVE_EJECT_DEVICEPATH, _ ; string
        $DRIVE_EJECT_DEVICEID, _ ; string
        $DRIVE_EJECT_DEVICEINSTANCE, _ ; int
        $DRIVE_EJECT_DEVICEINSTANCEPARENT, _ ; int
        $DRIVE_EJECT_DEVICEPARENTID, _ ; string
        $DRIVE_EJECT_ISREMOVEABLE, _ ; bool
        $DRIVE_EJECT_MAX

Global Const $tagSTORAGE_DEVICE_NUMBER = 'dword DeviceType;ulong DeviceNumber;ulong PartitionNumber'
Global Enum $DRIVENUMBER_TYPE, $DRIVENUMBER_NUMBER, $DRIVENUMBER_PARTITION
Global Const $LETTER_LENGTH = StringLen('A')
Global Const $MAX_PATH = 260

; Structures
Global Const $STORAGE_DEVICE_NUMBER = 'ulong DeviceType;ulong DeviceNumber;ulong PartitionNumber'
Global Const $SP_DEV_BUF = 'byte[2052]'
Global Const $SP_DEVICE_INTERFACE_DETAIL_DATA = 'dword cbSize;wchar DevicePath[1024]' ; Created at SP_DEV_BUF ptr
Global Const $SP_DEVICE_INTERFACE_DATA = 'dword cbSize;byte InterfaceClassGuid[16];dword Flags;ulong_ptr Reserved' ; GUID struct = 16 bytes
Global Const $SP_DEVINFO_DATA = 'dword cbSize;byte ClassGuid[16];dword DevInst;ulong_ptr Reserved'

; GUIDs
Global Const $tagGUID_DEVINTERFACE_DISK = DllStructCreate($tagGUID)
DllStructSetData($tagGUID_DEVINTERFACE_DISK, 'Data1', 0x53f56307)
DllStructSetData($tagGUID_DEVINTERFACE_DISK, 'Data2', 0xb6bf)
DllStructSetData($tagGUID_DEVINTERFACE_DISK, 'Data3', 0x11d0)
DllStructSetData($tagGUID_DEVINTERFACE_DISK, 'Data4', Binary('0x94f200a0c91efb8b'))
Global Const $tagGUID_DEVINTERFACE_CDROM = DllStructCreate($tagGUID)
DllStructSetData($tagGUID_DEVINTERFACE_CDROM, 'Data1', 0x53f56308)
DllStructSetData($tagGUID_DEVINTERFACE_CDROM, 'Data2', 0xb6bf)
DllStructSetData($tagGUID_DEVINTERFACE_CDROM, 'Data3', 0x11d0)
DllStructSetData($tagGUID_DEVINTERFACE_CDROM, 'Data4', Binary('0x94f200a0c91efb8b'))
Global Const $tagGUID_DEVINTERFACE_FLOPPY = DllStructCreate($tagGUID)
DllStructSetData($tagGUID_DEVINTERFACE_FLOPPY, 'Data1', 0x53f56311)
DllStructSetData($tagGUID_DEVINTERFACE_FLOPPY, 'Data2', 0xb6bf)
DllStructSetData($tagGUID_DEVINTERFACE_FLOPPY, 'Data3', 0x11d0)
DllStructSetData($tagGUID_DEVINTERFACE_FLOPPY, 'Data4', Binary('0x94f200a0c91efb8b'))

; http://www.codeproject.com/Articles/13839/How-to-Prepare-a-USB-Drive-for-Safe-Removal
; http://www.autoitscript.com/forum/topic/83470-safely-eject-a-usb-drive/
Local $aArray = DriveGetDrive("FIXED")
If @error Then
   ; An error occurred when retrieving the drives.
   MsgBox(0, "", "It appears an error occurred.")
Else
   For $i = 1 To $aArray[0]
      ConsoleWrite( "Drive " & $i & "/" & $aArray[0] & ":" & @CRLF & StringUpper($aArray[$i]) & @CRLF & DriveGetSerial(StringUpper($aArray[$i])&"\") & @CRLF & DriveGetType(StringUpper($aArray[$i])&"\")& @CR)
      $drive = StringLeft(StringUpper($aArray[$i]),1)
      ConsoleWrite($drive &  @CR)
      Example($drive)
   Next
EndIf


Func Example($drive)
   If $drive = "" Then Return SetError(1,1,0)
    Local $hDriveFind = _Drive($drive)
   If IsArray($hDriveFind) Then
    ;_ArrayDisplay($hDriveFind,$drive)
   $find = StringInStr($hDriveFind[3],"usbstor")
   If $find > 0 Then MsgBox(0,"", $drive & ": is removable")
   EndIf
EndFunc   ;==>Example

Func _Drive($sDrive)
    $sDrive = _GetDrive($sDrive) & ':'
    If Not FileExists($sDrive) Then Return Null

    Local $aQueryDrive[$DRIVE_EJECT_MAX]

    Local $aReturn = _WinAPI_GetDriveNumberEx($sDrive)
    $aQueryDrive[$DRIVE_EJECT_DEVICENUMBER] = (@error ? 0 : $aReturn[$DRIVENUMBER_NUMBER]) ; Device number.
    $aQueryDrive[$DRIVE_EJECT_DEVICETYPE] = _WinAPI_GetDriveType($sDrive)
    $aQueryDrive[$DRIVE_EJECT_DEVICEDOSNAME] = _WinAPI_QueryDosDevice($sDrive)

    Local $tGUID = 0
    Switch $aQueryDrive[$DRIVE_EJECT_DEVICETYPE]
        Case $DRIVE_REMOVABLE
            If StringInStr($aQueryDrive[$DRIVE_EJECT_DEVICEDOSNAME], '\Floppy') > 0 Then
                $tGUID = DllStructGetPtr($tagGUID_DEVINTERFACE_FLOPPY)
            Else
                $tGUID = DllStructGetPtr($tagGUID_DEVINTERFACE_DISK)
            EndIf

        Case $DRIVE_FIXED
            $tGUID = DllStructGetPtr($tagGUID_DEVINTERFACE_DISK)

        Case $DRIVE_CDROM
            $tGUID = DllStructGetPtr($tagGUID_DEVINTERFACE_CDROM)

        Case Default
            Return Null

    EndSwitch

    Local $hDevInfo = DllCall('setupapi.dll', 'ptr', 'SetupDiGetClassDevsW', _
            'ptr', $tGUID, _
            'ptr', Null, _
            'hwnd', Null, _
            'dword', BitOR($DIGCF_PRESENT, $DIGCF_DEVICEINTERFACE))
    If @error Or $hDevInfo[0] = $INVALID_HANDLE_VALUE Then Return Null
    $hDevInfo = $hDevInfo[0]

    Local $tBuffer = DllStructCreate($SP_DEV_BUF)
    Local $tpSP_DEVICE_INTERFACE_DETAIL_DATA = DllStructCreate($SP_DEVICE_INTERFACE_DETAIL_DATA, DllStructGetPtr($tBuffer))
    Local Const $SP_DEVICE_INTERFACE_DETAIL_DATA_SIZE = (@AutoItX64 ? 8 : 6) ; Fix for 64-bit systems.
    Local $tSP_DEVICE_INTERFACE_DETAIL_DATA = DllStructCreate($SP_DEVICE_INTERFACE_DATA)
    Local $tDevInfo = DllStructCreate($SP_DEVINFO_DATA)

    DllStructSetData($tSP_DEVICE_INTERFACE_DETAIL_DATA, 'cbSize', DllStructGetSize($tSP_DEVICE_INTERFACE_DETAIL_DATA))

    Local $iIndex = 0, $iSize = 0
    While 1
        $aReturn = DllCall('setupapi.dll', 'int', 'SetupDiEnumDeviceInterfaces', _
                'ptr', $hDevInfo, _
                'ptr', 0, _
                'ptr', $tGUID, _
                'dword', $iIndex, _
                'struct*', $tSP_DEVICE_INTERFACE_DETAIL_DATA)
        If @error Or Not $aReturn[0] Then
            ExitLoop
        EndIf

        $aReturn = DllCall('setupapi.dll', 'int', 'SetupDiGetDeviceInterfaceDetailW', _
                'ptr', $hDevInfo, _
                'struct*', $tSP_DEVICE_INTERFACE_DETAIL_DATA, _
                'ptr', 0, _
                'dword', 0, _
                'dword*', 0, _
                'ptr', 0)
        $iSize = (@error ? 0 : $aReturn[5])

        If $iSize > 0 And $iSize <= DllStructGetSize($tBuffer) Then
            DllStructSetData($tpSP_DEVICE_INTERFACE_DETAIL_DATA, 'cbSize', $SP_DEVICE_INTERFACE_DETAIL_DATA_SIZE)
            _WinAPI_ZeroMemory(DllStructGetPtr($tDevInfo), DllStructGetSize($tDevInfo))
            DllStructSetData($tDevInfo, 'cbSize', DllStructGetSize($tDevInfo))

            $aReturn = DllCall('setupapi.dll', 'int', 'SetupDiGetDeviceInterfaceDetailW', _
                    'ptr', $hDevInfo, _
                    'struct*', $tSP_DEVICE_INTERFACE_DETAIL_DATA, _
                    'struct*', $tpSP_DEVICE_INTERFACE_DETAIL_DATA, _
                    'dword', $iSize, _
                    'dword*', 0, _
                    'struct*', $tDevInfo)
            If Not @error And $aReturn[0] Then
                $aQueryDrive[$DRIVE_EJECT_DEVICEPATH] = DllStructGetData($tpSP_DEVICE_INTERFACE_DETAIL_DATA, 'DevicePath')
                $aReturn = _WinAPI_GetDriveNumberEx($aQueryDrive[$DRIVE_EJECT_DEVICEPATH])
                If Not @error Then
                    If $aQueryDrive[$DRIVE_EJECT_DEVICENUMBER] = $aReturn[$DRIVENUMBER_NUMBER] Then
                        $aQueryDrive[$DRIVE_EJECT_DEVICEID] = DllStructGetData($tDevInfo, 'DevInst')
                        ExitLoop
                    EndIf
                EndIf
            EndIf
        EndIf
        $iIndex += 1
    WEnd
    DllCall('setupapi.dll', 'int', 'SetupDiDestroyDeviceInfoList', _
            'ptr', $hDevInfo)

    If $aQueryDrive[$DRIVE_EJECT_DEVICEID] > 0 Then
        $aReturn = DllCall('setupapi.dll', 'dword', 'CM_Get_Device_IDW', _
                'ptr', $aQueryDrive[$DRIVE_EJECT_DEVICEID], _
                'wstr', '', _
                'ulong', DllStructGetSize($tBuffer), _ ; Was once 1024.
                'ulong', 0)
        $aQueryDrive[$DRIVE_EJECT_DEVICEINSTANCE] = (@error Or $aReturn[0] <> $CR_SUCCESS ? Null : $aReturn[2])

        $aReturn = DllCall('setupapi.dll', 'dword', 'CM_Get_Parent', _
                'dword*', 0, _
                'dword', $aQueryDrive[$DRIVE_EJECT_DEVICEID], _
                'ulong', 0)
        $aQueryDrive[$DRIVE_EJECT_DEVICEINSTANCEPARENT] = (@error Or $aReturn[0] <> $CR_SUCCESS ? Null : $aReturn[1])

        If $aQueryDrive[$DRIVE_EJECT_DEVICEINSTANCEPARENT] Then
            $aReturn = DllCall('setupapi.dll', 'dword', 'CM_Get_Device_IDW', _
                    'ptr', $aQueryDrive[$DRIVE_EJECT_DEVICEINSTANCEPARENT], _
                    'wstr', '', _
                    'ulong', DllStructGetSize($tBuffer), _ ; Was once 1024.
                    'ulong', 0)
            $aQueryDrive[$DRIVE_EJECT_DEVICEPARENTID] = (@error Or $aReturn[0] <> $CR_SUCCESS ? Null : $aReturn[2])

            $aReturn = DllCall('setupapi.dll', 'dword', 'CM_Get_DevNode_Status', _
                    'ulong*', 0, _
                    'ulong*', 0, _
                    'ptr', $aQueryDrive[$DRIVE_EJECT_DEVICEINSTANCEPARENT], _
                    'ulong', 0)
            $aQueryDrive[$DRIVE_EJECT_ISREMOVEABLE] = (Not @error And $aReturn[0] = $CR_SUCCESS And BitAND($aReturn[1], $DN_REMOVABLE))
        EndIf
    EndIf

    Return $aQueryDrive
EndFunc   ;==>_Drive

Func _GetDrive($sFilePath)
    Local $sDrive = StringUpper(StringLeft($sFilePath, $LETTER_LENGTH))
    Return _IsDriveLetter($sDrive) ? $sDrive : Null
EndFunc   ;==>_GetDrive

Func _IsDriveLetter($sDrive)
    ; Return StringRegExp($sDrive, '^[A-Za-z]$') = 1
    Return StringIsAlpha($sDrive) And StringLen($sDrive) = $LETTER_LENGTH
EndFunc   ;==>_IsDriveLetter

Func _IsDriveLetterFull($sDrive)
    ; Return StringRegExp($sDrive, '^[A-Za-z]:$') = 1
    Return _IsDriveLetter(_GetDrive($sDrive)) And StringLen($sDrive) = ($LETTER_LENGTH + $LETTER_LENGTH) And StringRight($sDrive, $LETTER_LENGTH) == ':'
EndFunc   ;==>_IsDriveLetterFull

Func _WinAPI_GetDriveNumberEx($sFilePath)
    If _IsDriveLetter($sFilePath) Or _IsDriveLetterFull($sFilePath) Then
        $sFilePath = '\\.\' & _GetDrive($sFilePath) & ':'
    EndIf
    Local Const $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error, @extended, 0)

    Local $tSTORAGE_DEVICE_NUMBER = DllStructCreate($tagSTORAGE_DEVICE_NUMBER)
    Local $vResult = [$DRIVENUMBER_TYPE, $DRIVENUMBER_NUMBER, $DRIVENUMBER_PARTITION]
    _WinAPI_DeviceIoControl($hFile, $IOCTL_STORAGE_GET_DEVICE_NUMBER, Null, 0, DllStructGetPtr($tSTORAGE_DEVICE_NUMBER), DllStructGetSize($tSTORAGE_DEVICE_NUMBER))
    If @error Then
        $vResult = 0
    Else
        $vResult[$DRIVENUMBER_TYPE] = DllStructGetData($tSTORAGE_DEVICE_NUMBER, 'DeviceType')
        $vResult[$DRIVENUMBER_NUMBER] = DllStructGetData($tSTORAGE_DEVICE_NUMBER, 'DeviceNumber')
        $vResult[$DRIVENUMBER_PARTITION] = DllStructGetData($tSTORAGE_DEVICE_NUMBER, 'PartitionNumber')
    EndIf
    _WinAPI_CloseHandle($hFile)
    Return $vResult
EndFunc   ;==>_WinAPI_GetDriveNumberEx
Le code fonctionne chez moi (2 disques durs, 1 disque usb en 2 partitions sous Win7)
J'ai l'impression que tous les petits verts sont partis en vacances :mrgreen:
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#5

Message par mikell »

Mais non, voyons
C'est juste que pour ne pas engendrer de frustration chez les users, on les laisse s'exprimer et donner les réponses
Ce qu'ils font très bien d'ailleurs :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1037
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#6

Message par walkson »

Merci
Je suis terriblement taquin mais si je blesse quelqu'un, je m'excuse.
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#7

Message par mikell »

Mon message précédent était la nécessaire (façon Desproges) réponse politiquement correcte un poil teintée de xyloglossie
En fait vu la chaleur il y a 78,4 % de chances que tu sois dans le vrai ou dans du similaire :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2515
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#8

Message par jguinch »

Sinon, y'a possibilité de faire ça à coup de requêtes WMI :
viewtopic.php?t=12593#p87533
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1037
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#9

Message par walkson »

Bonjour Jguinch
Le problème avec WMI est que le disque USB n'est pas toujours reconnu
Capture0.JPG
Capture0.JPG (19.68 Kio) Vu 2080 fois
Capture1.JPG
Capture1.JPG (13.16 Kio) Vu 2080 fois
Je précise que le disque USB est en 2 partitions dont l'une est cryptée. Le problème vient peut être de là ?
(Mais avec le code que j'ai proposé, je n'ai pas de problème)
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11798
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#10

Message par Tlem »

Pour archive :
Sur le forum US adamUL a écrit :Try using the the DriveGetType function with the $DT_BUSTYPE operation. It will return "USB" for USB drives



Envoyé de mon appareil mobile avec Tapatalk
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
davzell
Niveau 5
Niveau 5
Messages : 105
Enregistré le : jeu. 26 sept. 2013 14:15
Status : Hors ligne

Re: [..] Alternative à DriveGetDrive ("REMOVABLE") ?

#11

Message par davzell »

merci pour les deux scripts ca marche bien :)
Répondre