Page 1 sur 1

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

Posté : ven. 12 août 2016 10:37
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

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

Posté : ven. 12 août 2016 11:23
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

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

Posté : ven. 12 août 2016 12:29
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

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

Posté : ven. 12 août 2016 17:42
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:

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

Posté : ven. 12 août 2016 19:13
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:

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

Posté : ven. 12 août 2016 19:51
par walkson
Merci
Je suis terriblement taquin mais si je blesse quelqu'un, je m'excuse.

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

Posté : ven. 12 août 2016 20:36
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:

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

Posté : dim. 14 août 2016 20:57
par jguinch
Sinon, y'a possibilité de faire ça à coup de requêtes WMI :
viewtopic.php?t=12593#p87533

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

Posté : mar. 16 août 2016 10:49
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 2090 fois
Capture1.JPG
Capture1.JPG (13.16 Kio) Vu 2090 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)

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

Posté : ven. 19 août 2016 10:25
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

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

Posté : mer. 31 août 2016 15:32
par davzell
merci pour les deux scripts ca marche bien :)