Ejecter CD-Rom et Clé USB [Résolu]

Programmation d'applications complexes
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Message par GeBonet »

Ok... Alors ça se comprend... :lol: Je l'avais oublié celui là, très bien d'ailleurs...
Je dois encore le noter.. Très bien.
Mais maintenant que je suis dans le secret :roll:
Je vais garder une note : Très, Très bien avec la déconnexion de clef : :lol: :lol: :lol:
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

bon, je coince

j'arrive a associé la lettre des lecteurs de CD-Rom avec le device (le device, c'est a partir de ça que je peux éjecter proprement une clé)

mon problème c'est que je doit arriver à remonter dans l'arborescence.

En gros, ca donne ça, une arborescence pour ma clé U3

Code : Tout sélectionner

+ USBSTOR
   |  + disk
   |     |  volume générique
   |  cd-rom
donc en gros, pour un lecteur cd-rom en USB
je dois remonter d'un niveau pour trouver le USBSTOR (usb storage) qui me permet d'éjecter le matériel

pour un disque dur USB
je dois remonter d'un niveau pour trouver la lettre
et je dois encore remonter d'un niveau pour trouvé le USBSTOR qui me permet d'éjecter le matériel

voici mon code actuel

Code : Tout sélectionner

Procedure RemoveDrive(DriveLetter.s, Test.l = 0) ; To disconnect USB drive
  
  ; Constantes pour SetupDiGetDeviceRegistryProperty
  #SPDRP_ADDRESS = $1C
  #SPDRP_BUSNUMBER = $15
  #SPDRP_BUSTYPEGUID = $13
  #SPDRP_CAPABILITIES = $F
  #SPDRP_CHARACTERISTICS = $1B
  #SPDRP_CLASS = $7
  #SPDRP_CLASSGUID = $8
  #SPDRP_COMPATIBLEIDS = $2
  #SPDRP_CONFIGFLAGS = $A
  #SPDRP_DEVICEDESC = $0
  #SPDRP_DEVTYPE = $19
  #SPDRP_DRIVER = $9
  #SPDRP_ENUMERATOR_NAME = $16
  #SPDRP_EXCLUSIVE = $1A
  #SPDRP_FRIENDLYNAME = $C
  #SPDRP_HARDWAREID = $1
  #SPDRP_LEGACYBUSTYPE = $14
  #SPDRP_LOCATION_INFORMATION = $D
  #SPDRP_LOWERFILTERS = $12
  #SPDRP_MAXIMUM_PROPERTY = $1C
  #SPDRP_MFG = $B
  #SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = $E
  #SPDRP_SECURITY = $17
  #SPDRP_SECURITY_SDS = $18
  #SPDRP_SERVICE = $4
  #SPDRP_UI_NUMBER = $10
  #SPDRP_UI_NUMBER_DESC_FORMAT = $1E
  #SPDRP_UNUSED0 = $3
  #SPDRP_UNUSED1 = $5
  #SPDRP_UNUSED2 = $6
  #SPDRP_UPPERFILTERS = $11
  
  ; Caractéristiques du device
  #CM_DEVCAP_LOCKSUPPORTED  = $1
  #CM_DEVCAP_EJECTSUPPORTED  = $2
  #CM_DEVCAP_REMOVABLE  = $4
  #CM_DEVCAP_DOCKDEVICE  = $8
  #CM_DEVCAP_UNIQUEID  = $10
  #CM_DEVCAP_SILENTINSTALL  = $20
  #CM_DEVCAP_RAWDEVICEOK  = $40
  #CM_DEVCAP_SURPRISEREMOVALOK  = $80
  #CM_DEVCAP_HARDWAREDISABLED  = $100
  #CM_DEVCAP_NONDYNAMIC  = $200
  
  DataSection ; Pour retirer une clé USB
    GUID_DEVINTERFACE_FLOPPY: 
    Data.l $53F56311 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_DISK: 
    Data.l $53F56307 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_CDROM: 
    Data.l $53F56308 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_VOLUME:
    Data.l  $53F5630D 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B
  EndDataSection
  
  Structure PSP_DEVICE_INTERFACE_DETAIL_DATA 
    cbSize.l 
    DevicePath.s{255} 
  EndStructure 
  
  Structure SP_DEVINFO_DATA 
    cbSize.l 
    ClassGuid.GUID 
    DevInst.l 
    reserved.l 
  EndStructure 
  
  Structure RemoveDrive_DriveList
    Letter.s
    Volume.s
  EndStructure
  
  Protected Index, Retour, Memoire_Taille
  Protected *DeviceService, Service.s
  Protected DeviceLetter.s
  Protected *VolumeName, DeviceVolume.s
  Protected hDevice.l, *Guid.l, pspdidd.PSP_DEVICE_INTERFACE_DETAIL_DATA, spdid.SP_DEVICE_INTERFACE_DATA, spdd.SP_DEVINFO_DATA 
  Protected DriveVolume.s
  
  
  
  dll_Setupapi = OpenLibrary(#PB_Any, "setupapi.dll")
  If dll_Setupapi
    dll_Kernel32 = OpenLibrary(#PB_Any, "Kernel32.dll")
    If dll_Kernel32
      *CM_Locate_DevNode = GetFunction(dll_Setupapi, "CM_Locate_DevNodeA")
      *CM_Request_Device_Eject = GetFunction(dll_Setupapi, "CM_Request_Device_Eject_ExA")
      *CM_Get_Parent = GetFunction(dll_Setupapi, "CM_Get_Parent")
      *GetVolumeNameForVolumeMountPoint = GetFunction(dll_Kernel32, "GetVolumeNameForVolumeMountPointA")
      
      ;////////////////////////
      ; Provisoire, pour test
      Protected NewList Drive.RemoveDrive_DriveList()
      Protected DriveString_Length.l, DriveIndex.l
      ; On récupère la liste des lecteurs
      DriveString_Length = GetLogicalDriveStrings_(0, 0) 
      *DriveString = AllocateMemory(DriveString_Length) 
      GetLogicalDriveStrings_(DriveString_Length, *DriveString) 
      For DriveIndex = 0 To DriveString_Length - 4 Step 4
        AddElement(Drive())
        Drive()\Letter = PeekS(*DriveString + DriveIndex) ; lettre du lecteur
        Debug Drive()\Letter
        *VolumeName = AllocateMemory(255)
        CallFunctionFast(*GetVolumeNameForVolumeMountPoint, @Drive()\Letter, *VolumeName, 255)
        Drive()\Volume =  PeekS(*VolumeName)
        FreeMemory(*VolumeName)
        Debug Drive()\Volume
      Next
      Debug ""
      ; Fin de cette partie de test
      ;////////////////////////
      
      ; On récupère le nom de volume du lecteur
      *VolumeName = AllocateMemory(255)
      CallFunctionFast(*GetVolumeNameForVolumeMountPoint, DriveLetter + ":\", *VolumeName, 255)
      DriveVolume=  PeekS(*VolumeName)
      FreeMemory(*VolumeName)
      Debug DriveLetter
      Debug DriveVolume
      Debug ""
      
      ; On recherche le volume qui correspond a chaque lettre de lecteur
      *Guid = ?GUID_DEVINTERFACE_VOLUME
      hDevice = SetupDiGetClassDevs_(*Guid, 0, 0, #DIGCF_PRESENT|#DIGCF_DEVICEINTERFACE) 
      
      If hDevice <> #INVALID_HANDLE_VALUE 
        
        ; Paramétrage
        spdid\cbSize = SizeOf(SP_DEVICE_INTERFACE_DATA) 
        
        ; On liste les interfaces
        Index= 0 
        While SetupDiEnumDeviceInterfaces_(hDevice, 0, *Guid, Index, @spdid) 
          
          ; Taille du buffer nécessaire pour lkire l'information
          SetupDiGetDeviceInterfaceDetail_(hDevice, @spdid, 0, 0, @Memoire_Taille, 0)
          If Memoire_Taille <> 0 And Memoire_Taille <= SizeOf(PSP_DEVICE_INTERFACE_DETAIL_DATA) 
            
            pspdidd\cbSize = 5    ; Unicode=6, ASCII=5 
            spdd\cbSize = SizeOf(SP_DEVINFO_DATA) 
            
            If SetupDiGetDeviceInterfaceDetail_(hDevice, @spdid, @pspdidd, Memoire_Taille, 0, @spdd) 
              
              Debug pspdidd\DevicePath
              
              *VolumeName = AllocateMemory(255)
              CallFunctionFast(*GetVolumeNameForVolumeMountPoint, pspdidd\DevicePath + "\", *VolumeName, 255)
              DeviceVolume =  PeekS(*VolumeName)
              FreeMemory(*VolumeName)
              Debug DeviceVolume
              
              ;////////////////////////
              ; Provisoire, test
              DeviceLetter = ""
              ForEach Drive()
                If Drive()\Volume = DeviceVolume
                  DeviceLetter = Drive()\Letter
                EndIf
              Next
              Debug DeviceLetter
              ; Fin de cette partie de test
              ;////////////////////////
              
              *DeviceService = AllocateMemory(255)
              SetupDiGetDeviceRegistryProperty_(hDevice, spdd, #SPDRP_SERVICE, 0, *DeviceService, 255, 0)
              Service = LCase(PeekS(*DeviceService))
              FreeMemory(*DeviceService)
              Debug Service
              
              If DriveVolume = DeviceVolume
                ; On a trouvé le volume correspondant à la lettre de lecteur
                Debug "Volume trouvé"
                
              EndIf
              
            EndIf
            
          EndIf
          
          ; On passe à l'élément suivant
          Index + 1
        Wend
        
        SetupDiDestroyDeviceInfoList_(hDevice) ; On ferme
      EndIf
      CloseLibrary(dll_Kernel32)
    EndIf
    CloseLibrary(dll_Setupapi)
  EndIf
  
  ProcedureReturn Retour
EndProcedure
Procedure IsRemovableDrive(DriveLetter.s) ; To check if drive is USB drive
  ProcedureReturn RemoveDrive(DriveLetter, 1)
EndProcedure




;- Test
Lecteur.s = "L"
If IsRemovableDrive(Lecteur)
  RemoveDrive(Lecteur)
EndIf
Si quelqu'un peut m'aider à trouver le parent d'un device, merci :)
Dernière modification par Le Soldat Inconnu le lun. 02/févr./2009 21:41, modifié 1 fois.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

trouvé ma connerie, ca marche nickel, j'avais mis un "\" en trop et ca me foutait la merde

Code précédent modifier.
J'arrive à trouver pour tous les lecteurs le device

Donc il faut juste que je test si le device est monter sur un USBSTOR
puis ensuite l'éjecter, donc mon histoire de remonter de niveau.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

ca avance, j'arrive a trouver les parents de mon Device

il me manque encore la fonction qui va me permettre de dire que le device est un port USB, pas évident

je regarde CM_Get_Class_Registry_Property mais ... je sais pas trop encore comment utiliser la bestiole.

Code : Tout sélectionner

Procedure RemoveDrive(DriveLetter.s, Test.l = 0) ; To disconnect USB drive
  
  DataSection ; GUID
    GUID_DEVINTERFACE_FLOPPY: 
    Data.l $53F56311 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_DISK: 
    Data.l $53F56307 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_CDROM: 
    Data.l $53F56308 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_VOLUME:
    Data.l  $53F5630D 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B
  EndDataSection
  
  Structure PSP_DEVICE_INTERFACE_DETAIL_DATA 
    cbSize.l 
    DevicePath.s{255} 
  EndStructure 
  
  Structure SP_DEVINFO_DATA 
    cbSize.l 
    ClassGuid.GUID 
    DevInst.l 
    reserved.l 
  EndStructure 
  
  Structure RemoveDrive_DriveList
    Letter.s
    Volume.s
  EndStructure
  
  Protected Index, Retour, *VolumeName
  Protected DevicePath_Length.l, *DeviceService, Service.s, DeviceLetter.s, DeviceVolume.s, DeviceInstance.l
  Protected hDevice.l, *Guid.l, pspdidd.PSP_DEVICE_INTERFACE_DETAIL_DATA, spdid.SP_DEVICE_INTERFACE_DATA, spdd.SP_DEVINFO_DATA 
  Protected DriveVolume.s
  
  ; On ouvre les librairies et on charge les fonctions utiles
  dll_Setupapi = OpenLibrary(#PB_Any, "setupapi.dll")
  If dll_Setupapi
    dll_Kernel32 = OpenLibrary(#PB_Any, "Kernel32.dll")
    If dll_Kernel32
      *CM_Locate_DevNode = GetFunction(dll_Setupapi, "CM_Locate_DevNodeA")
      *CM_Request_Device_Eject = GetFunction(dll_Setupapi, "CM_Request_Device_Eject_ExA")
      *CM_Get_Parent = GetFunction(dll_Setupapi, "CM_Get_Parent")
      *CM_Get_Class_Registry_Property = GetFunction(dll_Setupapi, "CM_Get_Class_Registry_Property")
      *CM_Get_Device_ID = GetFunction(dll_Setupapi, "CM_Get_Device_IDA")
      *GetVolumeNameForVolumeMountPoint = GetFunction(dll_Kernel32, "GetVolumeNameForVolumeMountPointA")
      
      ; On récupère le nom de volume du lecteur
      *VolumeName = AllocateMemory(255)
      CallFunctionFast(*GetVolumeNameForVolumeMountPoint, DriveLetter + ":\", *VolumeName, 255)
      DriveVolume=  PeekS(*VolumeName)
      FreeMemory(*VolumeName)

      ; On recherche le volume qui correspond a chaque lettre de lecteur
      *Guid = ?GUID_DEVINTERFACE_VOLUME ; On recherche tous les volumes
      hDevice = SetupDiGetClassDevs_(*Guid, 0, 0, #DIGCF_PRESENT|#DIGCF_DEVICEINTERFACE) 
      
      If hDevice <> #INVALID_HANDLE_VALUE 
        
        ; Paramétrage
        spdid\cbSize = SizeOf(SP_DEVICE_INTERFACE_DATA) 
        
        ; On liste les interfaces
        Index= 0 
        While SetupDiEnumDeviceInterfaces_(hDevice, 0, *Guid, Index, @spdid) 
          
          ; Taille du buffer nécessaire pour lire l'information
          SetupDiGetDeviceInterfaceDetail_(hDevice, @spdid, 0, 0, @DevicePath_Length, 0)
          If DevicePath_Length <> 0 And DevicePath_Length < 255 ; On teste pour savoir si le texte n'est pas trop long
            
            pspdidd\cbSize = 5    ; Unicode=6, ASCII=5 
            spdd\cbSize = SizeOf(SP_DEVINFO_DATA) 
            
            If SetupDiGetDeviceInterfaceDetail_(hDevice, @spdid, @pspdidd, DevicePath_Length, 0, @spdd) 
              
              *VolumeName = AllocateMemory(255)
              CallFunctionFast(*GetVolumeNameForVolumeMountPoint, pspdidd\DevicePath + "\", *VolumeName, 255)
              DeviceVolume =  PeekS(*VolumeName)
              FreeMemory(*VolumeName)
              
              If DriveVolume = DeviceVolume
                ; On a trouvé le volume correspondant à la lettre de lecteur
                
                DeviceInstance = spdd\DevInst
                Repeat ; On parcourt la liste des parents à la recherche d'un périphérique amovible
                  If CallFunctionFast(*CM_Get_Parent, @DeviceParent, DeviceInstance, 0) = 0
                    Debug DeviceParent
                    DeviceInstance = DeviceParent

                    
                    If 0 ; Si le lecteur est amovible
                      Retour = 1 ; On retourne une rpéonse positive
                      If Test = 0 ; Si on veut retirer le lecteur
                        *DeviceId = AllocateMemory(255)
                        CallFunctionFast(*CM_Get_Device_ID, DeviceInstance, *DeviceId, 255, 0) ; On récupère l'ID du device
                        If CallFunctionFast(*CM_Locate_DevNode, @DeviceInstance.l, PeekS(*DeviceId), 0) = 0 ; On va sur le noeud du device
                          CallFunctionFast(*CM_Request_Device_Eject, DeviceInstance, 0, 0, 0, 0, 0) ; On éjecte le device
                        EndIf
                        FreeMemory(*DeviceId)
                      EndIf
                      Break 2 ; On s'arrête sur le premier périphérique amovible
                    EndIf
                    
                  EndIf
                Until DeviceInstance <> DeviceParent ; on a listé tous les parents
                
              EndIf
            EndIf
          EndIf
          
          ; On passe à l'élément suivant
          Index + 1
        Wend
        
        SetupDiDestroyDeviceInfoList_(hDevice) ; On ferme
      EndIf
      CloseLibrary(dll_Kernel32)
    EndIf
    CloseLibrary(dll_Setupapi)
  EndIf
  
  ProcedureReturn Retour
EndProcedure
Procedure IsRemovableDrive(DriveLetter.s) ; To check if drive is USB drive
  ProcedureReturn RemoveDrive(DriveLetter, 1)
EndProcedure




;- Test
Lecteur.s = "L"
If IsRemovableDrive(Lecteur)
  RemoveDrive(Lecteur)
EndIf
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

Tiens, j'ai tiré ça d'un code récupéré je sais plus où qui était en mode console. Je viens de le passer en mode fenêtré et ça marche :)
T'as plus qu'à l'intégrer à ton code.

Code : Tout sélectionner

Structure STORAGE_PROPERTY_QUERY
    PropertyId.l;STORAGE_PROPERTY_ID
    QueryType.l;STORAGE_QUERY_TYPE
    AdditionalParameters.l
EndStructure

Structure STORAGE_DEVICE_DESCRIPTOR
    Version.l
    Size.l;                                    As Long
    DeviceType.b;                              As Byte
    DeviceTypeModifier.b;                      As Byte
    RemovableMedia.b;                          As Byte
    CommandQueueing.b;                         As Byte
    VendorIdOffset.l;                          As Long
    ProductIdOffset.l;                         As Long
    ProductRevisionOffset.l;                   As Long
    SerialNumberOffset.l;                      As Long
    BusType.w;                                 As Integer
    RawPropertiesLength.l;                     As Long
    RawDeviceProperties.b;                     As Byte
    Reserved.b[1024]
EndStructure

    #BusTypeUnknown = 0
    #BusTypeScsi=1
    #BusTypeAtapi=2
    #BusTypeAta=3
    #BusType1394=4
    #BusTypeSsa=5
    #BusTypeFibre=6
    #BusTypeUsb=7
    #BusTypeRAID=8
    #BusTypeMaxReserved = $7F
   
#IOCTL_STORAGE_QUERY_PROPERTY  = $2D1400


Procedure.l Hex_2_Dec(h$)
  h$=UCase(h$)
  For r=1 To Len(h$)
    d<<4 : a$=Mid(h$,r,1)
    If Asc(a$)>60
      d+Asc(a$)-55
    Else
      d+Asc(a$)-48
    EndIf
  Next
  ProcedureReturn d
EndProcedure

Procedure DeviceInfo()

For Drives=1 To 26 
  strDrive.s="\\.\" + Chr(64+Drives) + ":" 
  hDrive = CreateFile_(strDrive, 0,#FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
  If hDrive<>-1
 
   udtQuery.STORAGE_PROPERTY_QUERY
   udtOut.STORAGE_DEVICE_DESCRIPTOR

   For p=0 To 1023
    udtOut\Reserved[p]=0
   Next p
   
   lngResult = DeviceIoControl_(hDrive, #IOCTL_STORAGE_QUERY_PROPERTY, udtQuery,SizeOf(udtQuery), @udtOut, SizeOf(udtout), @dwOutBytes, 0)
   If lngResult
    Select(udtOut\Bustype)    
       Case #BusTypeUnknown
        type.s=" Unknow"
       Case #BusTypeScsi
        type.s=" SCSI Device"
       Case #BusTypeAtapi
        type.s=" Atapi Device"
       Case #BusTypeAta
        type.s=" Ata Device"
       Case #BusTypeUsb
        type.s=" USB Device"
       Case #BusTypeMaxReserved
       Default
       type.s="Bustype=" + Str(udtOut\BusType)
    EndSelect

    If udtout\RemovableMedia
     device.s="Removable Media"
    EndIf

    If udtOut\ProductIdOffset > 0
     Productid.s= PeekS(@udtOut + udtOut\ProductIdOffset)
    EndIf

    If udtOut\ProductRevisionOffset > 0
     ProductRevision.s=PeekS(@udtOut +  udtOut\ProductRevisionOffset)
    EndIf

    If udtOut\VendorIdOffset  > 0
     VendorID.s=PeekS(@udtOut +  udtOut\VendorIdOffset )
    EndIf

    If udtOut\SerialNumberOffset  > 0
     SerialNumber.s=PeekS(@udtOut +  udtOut\SerialNumberOffset )
     sdummy.s=""
     For t=1 To Len(SerialNumber) Step 2
        sdummy + Chr(Hex_2_Dec(Mid(SerialNumber,t,2)))
     Next t
     SerialNumber.s = sdummy
    EndIf
    
      AddGadgetItem(0,-1, Chr(64+Drives)+Chr(10)+type+Chr(10)+device+Chr(10)+Productid+Chr(10)+ProductRevision+Chr(10)+VendorID+Chr(10)+SerialNumber+Chr(10)+"")
 
   Else
     
    state.s="No Device-IO info available.. for "+Chr(64+Drives) + ":"
    AddGadgetItem(0,-1, Chr(64+Drives)+Chr(10)+""+Chr(10)+""+Chr(10)+""+Chr(10)+""+Chr(10)+""+Chr(10)+""+Chr(10)+state)

   EndIf
  EndIf
  CloseHandle_(hDrive)

 Next Drives
 
 
EndProcedure


If OpenWindow(0, 0, 0, 800, 500, "Available Drives", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_TitleBar) 

  ListIconGadget(0, 10, 10, 780, 440, "Drive", 50, #PB_ListIcon_GridLines) 
    AddGadgetColumn(0, 1, "type", 100) 
    AddGadgetColumn(0, 2, "Device", 150)
    AddGadgetColumn(0, 3, "ProductID", 100)
    AddGadgetColumn(0, 4, "ProductRevision", 100)
    AddGadgetColumn(0, 5, "VendorID", 100)
    AddGadgetColumn(0, 6, "SerialNumber", 100)
    AddGadgetColumn(0, 7, "Défaut", 100) 
    
  If CreateStatusBar(0, WindowID(0)) 
    StatusBarText(0, 0, "Drive infos USBSTORAGE", 0) 
  EndIf
    
EndIf     
    
  DeviceInfo() 
   
Repeat 
 Event = WaitWindowEvent() 
 Select Event
  
 EndSelect
Until Event=#PB_Event_CloseWindow
End    
   
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

merci

j'ai fait autrement et miracle ca marche !

J'arrive a retirer ma clé U3
soit par la lettre du disque dur USB
soit par la lettre du CD-ROM USB

donc besoin de testeur pour valider.
Je remets le code complet dans le tout premier message.


Si vous pouvez faire des tests sous XP, 2000 et Vista
Avec vos clé USB, disque dur USB, Graveur USB, ...
Merci
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Message par GeBonet »

Sorry voir ci après
Dernière modification par GeBonet le mar. 03/févr./2009 16:13, modifié 1 fois.
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Message par GeBonet »

Sous XP Pro Driver... J'ai sur ma machine HP :

J'ai comme lecteur :

Lecteur C:
Lecteur D: (restore drive)

Graveur CD/DVD E:
Lecteur DVD F:

Lecteurs USB contrôlé par USBSTOR.SYS

Carte mem G: Diverses cartes
Carte mem I: ""
Carte mem J: ""
Carte mem K: ""
ET Port USB Flash H: Qui reçoit la clef...
-------------------------------
Et Lecteur L: Disque dur Amovible

Quand je lance le premier programme demandant d'éjecter
le lecteur "i" ou "g"


Il ejecte l'ensemble USBSTOR.... Soit les cartes (de G: à K:)
Et ce y inclus la clef USB H:
(Un message m'avise que je peut retirer ma clef)

Donc ça fonctionne, mais considère n'importe quel des média de G à K comme étant la même chose...
Les AUTRES lecteurs eux restent autonome...

Quand je réintroduit ma clef, dans le "H:" elle est reconnue comme "H:"

J'ai été clair ?
A+
Gerhard
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Pas totalement :roll:

La clé USB H:\ est connecté sur le lecteur de carte USB, c'est ça ?

Et donc quand je veux retirer le périphérique a partir de G, ca retire l'ensemble lecteur de carte et la clé usb connecté sur le lecteur de carte, c'est ça ?

ca me semble normal

Parce que si sur ton lecteur de carte, quand tu le branches, ca te mets les lecteurs G à K, un retirant l'un d'entre eux, ca retire forcément l'ensemble.
Je déconnecte le périphérique. Donc tout les lecteurs qui en dépendent

Ta clé H est sur le lecteur de carte qui G I J K
Si je retire G, ca va retirer le périphérique qui a le lecteur G
donc je retire le lecteur de carte, et forcément tout ce qui est branché dessus.

Par contre, si tu retires H, ca doit retirer que la clé USB H, G I J K doivent rester car tu as retiré la clé USB et pas le lecteur de carte.

C'est du à l'architecture du branchement, comme si tu avais 36 rallonge électrique pour alimenter ton PC
Si tu en débranche une au milieu, le PC n'aura plus de courant. On peut pas dire, oui ,mais j'ai pas débrancher le cable du PC, j'ai débranché l'autre avant
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Message par GeBonet »

Quand je place ma CLEF elle est reconnue comme faisant partie d'un ensemble contrôlé par USBSTOR.SYS... qui contrôle aussi le lecteur de Cartes mémoires (sur ma machine 4 types de cartes).

Et chaque type de carte reçoit une identification USB et une lettre de G à K.
sauf la lettre H: qui est réservé et ne se montre que lorsque je mets la CLEF dans un port USB.

Il y a donc une gestion des lecteurs CD/DVD
et une gestion des amovibles comme montré sur la photo...

Image

D'où si j'éjecte une carte mémoire qui n'est pas placé, il "éjecte" aussi la Clef puisque l'action implique USBSTOR qui contrôle le tout...

Sauf le lecteur (ici Disque dur) amovible L: qui lui n'est pas contrôlé par USBSTOR.SYS...
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

oui, donc le comportement est normal

car je déconnecte le périphérique de stockage de masse USB.

Tu aurais voulu éjecté quoi toi ?
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Message par GeBonet »

Moi... Rien :lol:

Mais le soft que tu vois sur l'image, lui il "éjecte" ou plutôt te permet de retirer, ta clef,
ou la carte que tu lui désigne (écrit les buffers qui trainent sur le support) puis t'avertis que tu peux le retirer.

ET cela sans pour autant neutraliser les autres... En fait, il y a deux drivers en causes...
Le principal qui est le gestionnaire principal USBSTOR.sys (tous les USB) et un second qui lui s'occupe en particulier
de chacun des dépendant ou "sous lecteur"... et c'est : VolSnap.sys
Maintenant comment le contrôler c'est une autre affaire... :(

Toutefois la plupart du temps ta solution est largement suffisante :lol: :lol:
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

pigé, en fait, ton logiciel force Windows à écrire le Buffer du lecteur puis mais un Véto sur le lecteur pour que personne ne puisse l'utiliser.

Si le véto a réussi, tu peux tirer sur la carte.
J'ai vu des codes de ce type trainé sur le net quand je cherchais des exemples.
Mais c'est pas ce que je veux faire, je voulais reproduire le "retirer le périphérique en toute sécurité de Windows", l'icone vers l'horloge après avec mis une clé USB

a tout hazard, essaie ce code, peut-être que ca change qlqchose pour toi, dis moi

Code : Tout sélectionner

Procedure RemoveDrive2(DriveLetter.s, Test.l = 0) ; To disconnect USB drive

  #SPDRP_CAPABILITIES = $F
  #CM_DEVCAP_REMOVABLE  = $4
  
  DataSection ; GUID
    GUID_DEVINTERFACE_FLOPPY: 
    Data.l $53F56311 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_DISK: 
    Data.l $53F56307 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_CDROM: 
    Data.l $53F56308 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B 
    GUID_DEVINTERFACE_VOLUME:
    Data.l  $53F5630D 
    Data.w $B6BF, $11D0 
    Data.b $94, $F2, $00, $A0, $C9, $1E, $FB, $8B
  EndDataSection
  
  Structure PSP_DEVICE_INTERFACE_DETAIL_DATA 
    cbSize.l 
    DevicePath.s{255} 
  EndStructure 
  
  Structure SP_DEVINFO_DATA 
    cbSize.l 
    ClassGuid.GUID 
    DevInst.l 
    reserved.l 
  EndStructure 
  
  Protected Index, Retour, *VolumeName, *DeviceInstanceId
  Protected DevicePath_Length.l, DeviceLetter.s, DeviceVolume.s, DeviceInstance.l, DeviceID.s
  Protected hDevice.l, *Guid.l, pspdidd.PSP_DEVICE_INTERFACE_DETAIL_DATA, spdid.SP_DEVICE_INTERFACE_DATA, spdd.SP_DEVINFO_DATA 
  Protected Removable_hDevice, Removable_Index, Removable_spdd.SP_DEVINFO_DATA, Removable_DeviceCapabilities.l, Removable_Service.s, RemovableDevice.l, Removable_DeviceID.s
  Protected DeviceCapabilities.l
  Protected DriveVolume.s
  
  ; On ouvre les librairies et on charge les fonctions utiles
  dll_Setupapi = OpenLibrary(#PB_Any, "setupapi.dll")
  If dll_Setupapi
    dll_Kernel32 = OpenLibrary(#PB_Any, "Kernel32.dll")
    If dll_Kernel32
      *CM_Locate_DevNode = GetFunction(dll_Setupapi, "CM_Locate_DevNodeA")
      *CM_Request_Device_Eject = GetFunction(dll_Setupapi, "CM_Request_Device_Eject_ExA")
      *CM_Get_Parent = GetFunction(dll_Setupapi, "CM_Get_Parent")
      *CM_Get_Device_ID = GetFunction(dll_Setupapi, "CM_Get_Device_IDA")
      *GetVolumeNameForVolumeMountPoint = GetFunction(dll_Kernel32, "GetVolumeNameForVolumeMountPointA")
      
      ; On récupère le nom de volume du lecteur
      *VolumeName = AllocateMemory(255)
      CallFunctionFast(*GetVolumeNameForVolumeMountPoint, DriveLetter + ":\", *VolumeName, 255)
      DriveVolume=  PeekS(*VolumeName)
      FreeMemory(*VolumeName)

      ; On recherche le volume qui correspond a chaque lettre de lecteur
      *Guid = ?GUID_DEVINTERFACE_VOLUME ; On recherche tous les volumes
      hDevice = SetupDiGetClassDevs_(*Guid, 0, 0, #DIGCF_PRESENT|#DIGCF_DEVICEINTERFACE) 
      
      If hDevice <> #INVALID_HANDLE_VALUE 
        
        ; Paramétrage
        spdid\cbSize = SizeOf(SP_DEVICE_INTERFACE_DATA) 
        
        ; On liste les interfaces
        Index= 0 
        While SetupDiEnumDeviceInterfaces_(hDevice, 0, *Guid, Index, @spdid) 
          
          ; Taille du buffer nécessaire pour lire l'information
          SetupDiGetDeviceInterfaceDetail_(hDevice, @spdid, 0, 0, @DevicePath_Length, 0)
          If DevicePath_Length <> 0 And DevicePath_Length < 255 ; On teste pour savoir si le texte n'est pas trop long
            
            pspdidd\cbSize = 5    ; Unicode=6, ASCII=5 
            spdd\cbSize = SizeOf(SP_DEVINFO_DATA) 
            
            If SetupDiGetDeviceInterfaceDetail_(hDevice, @spdid, @pspdidd, DevicePath_Length, 0, @spdd) 
              
              *VolumeName = AllocateMemory(255)
              CallFunctionFast(*GetVolumeNameForVolumeMountPoint, pspdidd\DevicePath + "\", *VolumeName, 255)
              DeviceVolume =  PeekS(*VolumeName)
              FreeMemory(*VolumeName)
              
              If DriveVolume = DeviceVolume
                ; On a trouvé le volume correspondant à la lettre de lecteur
                
                DeviceInstance = spdd\DevInst
                Repeat ; On parcourt la liste des parents à la recherche d'un périphérique amovible
                  If CallFunctionFast(*CM_Get_Parent, @DeviceParent, DeviceInstance, 0) = 0
                    DeviceInstance = DeviceParent
                    *DeviceInstanceId = AllocateMemory(255)
                    CallFunctionFast(*CM_Get_Device_ID, DeviceInstance, *DeviceInstanceId, 255, 0) ; On récupère l'ID du device
                    DeviceID = PeekS(*DeviceInstanceId)
                    FreeMemory(*DeviceInstanceId)
                    
                    ; On recherche si le device est amovible
                    RemovableDevice = 0
                    Removable_hDevice = SetupDiGetClassDevs_(0, 0, 0, #DIGCF_PRESENT | #DIGCF_ALLCLASSES)
                    If Removable_hDevice <> #INVALID_HANDLE_VALUE
                      Removable_spdd\cbSize = SizeOf(SP_DEVINFO_DATA)
                      Removable_Index = 0
                      While SetupDiEnumDeviceInfo_(Removable_hDevice, Removable_Index, @Removable_spdd)
                        *DeviceInstanceId = AllocateMemory(255)
                        SetupDiGetDeviceInstanceId_(Removable_hDevice, Removable_spdd, *DeviceInstanceId, 255, 0)
                        Removable_DeviceID = PeekS(*DeviceInstanceId)
                        FreeMemory(*DeviceInstanceId)
                        If Removable_DeviceID = DeviceID
                          SetupDiGetDeviceRegistryProperty_(Removable_hDevice, Removable_spdd, #SPDRP_CAPABILITIES, 0, @DeviceCapabilities, 4, 0)
                          If DeviceCapabilities & #CM_DEVCAP_REMOVABLE
                            RemovableDevice = 1
                            Break
                          EndIf
                        EndIf
                        Removable_Index + 1
                      Wend
                      SetupDiDestroyDeviceInfoList_(Removable_hDevice)
                    EndIf
                    
                    If RemovableDevice ; Si le lecteur est amovible
                      Retour = 1 ; On retourne une réponse positive
                      If Test = 0 ; Si on veut retirer le lecteur
                        
                        If CallFunctionFast(*CM_Locate_DevNode, @DeviceInstance.l, DeviceID, 0) = 0 ; On va sur le noeud du device
                          CallFunctionFast(*CM_Request_Device_Eject, DeviceInstance, 0, 0, 0, 0, 0) ; On éjecte le device
                        EndIf
                        
                      EndIf
                      Break 2 ; On s'arrête sur le premier périphérique amovible
                    EndIf
                    
                  EndIf
                Until DeviceInstance <> DeviceParent ; on a listé tous les parents
                
              EndIf
            EndIf
          EndIf
          
          ; On passe à l'élément suivant
          Index + 1
        Wend
        
        SetupDiDestroyDeviceInfoList_(hDevice) ; On ferme
      EndIf
      CloseLibrary(dll_Kernel32)
    EndIf
    CloseLibrary(dll_Setupapi)
  EndIf
  
  ProcedureReturn Retour
EndProcedure
Procedure IsRemovableDrive2(DriveLetter.s) ; To check if drive is USB drive
  ProcedureReturn RemoveDrive2(DriveLetter, 1)
EndProcedure




;- Test
Lecteur.s = "m"
If IsRemovableDrive2(Lecteur)
  RemoveDrive2(Lecteur)
EndIf
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

J'arrive apres la guerre, mais juste pour info.
Le code du dessus marche nickel sur une machine W2000 :D
Merci SOLDAT 8)
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Message par GeBonet »

Ben voilà... J'ai donné comme lecteur à déconnecté le K: (image ci-dessus) soit lecteur de carte MemStick et il y en avait une.

Résultat : C'est la même chose que le précédent d'ailleurs regarde l'image et tu comprendra de suite... Par rapport à la précédente.
Il vire l'ensemble géré par USBSTOR...
Pour vérifier j'appelle le Soft qui me montre cette image :

Image

Pour compléter le test après ça je place ma Clef USB... Elle est reconnue.

Mais si je replace le MemStick... Lui, il ne réapparait pas, et ça c'est gênant ! c'est donc G, I, J, K qui sont partis en bloc au lieu de K: tout seul.

Bien entendu pas pour moi, je sais gérer le tout... Mais pour ton application.

Reprend ce que je te dis plus haut : USBSTOR "dans ce cas" Gère l'ensemble du lecteur de carte comme si c'était UN lecteur (ce qu'il est).
Mais chaque carte est répertorié comme une unité de lecture/écriture G:, I:, J:, K: indépendante et "éjectable" indépendamment !

Et c'est rendu possible par le fait que c'est un Driver indépendant qui s'occupe des cartes mémoire... Et c'est : VolSnap.sys (quand je demande d'éjecter une carte... C'est lui qui autorise et pas USBSTOR). Enfin je suppose.

Et la preuve qui semble me donner raison sur l'hypothèse, c'est que lorsque je replace la Clef USB, elle est reconnue comme lecteur de mémoire de masse et en second comme Clef Flash... Et non plus simplement comme Clef Flash par le lecteur de carte comme cela se produit d'habitude.

Donc tes procédures quand elles s'adressent à un lecteur de Carte contrôlant la Clef USB ou un MemStick "déconnecte" le lecteur et ne le reconnait plus APRES (sauf reboot).

Voilà, voilà... :(
Répondre