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 »

Comme avec le code VB une clef normale apparait, chez toi la carte photo...

C'est que c'est l'U3 qui pose problème et comme U3 est censé être autorun donc comme un lecteur... Elle n'est peut-être détectée que comme lecteur...
Aussi comme le code VB offre "Détails" et que détails donne tout les périphériques vérifie ce qu'il y a sans U3... ET

Place la Clef U3, relance le code VB puis
vérifie si rien n'a été changé dans les périphériques.

Si U3 agit comme lecteur il devrait apparaitre... Sinon ???
A+
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

elle apparait comme ça :
_____________________
USBSTOR
U3 Cruzer Micro

Périphérique de stockage de masse USB
20
CM_DEVCAP_REMOVABLE
USB\VID_0781&PID_5406\0000167837740F5A
_____________________
cdrom

SanDisk U3 Cruzer Micro USB Device
Lecteur de CD-ROM
16
_____________________
disk

SanDisk U3 Cruzer Micro USB Device
Lecteur de disque
16
Pour l'éjecter, il faut éjecter le premier, le USBSTOR
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 »

Chez moi ce code fonctionne...

Code : Tout sélectionner

#IOCTL_STORAGE_EJECT_MEDIA  = $2D4808 
  Procedure EjectCD(LW.s) 
    Protected hLwStatus.l 
    hLwStatus = CreateFile_("\\.\"+LW,#GENERIC_READ|#GENERIC_WRITE, 0, 0, #OPEN_EXISTING, 0, 0) 
    If hLwStatus 
      DeviceIoControl_(hLwStatus,#IOCTL_STORAGE_EJECT_MEDIA,0,0,0,0,@Ret,0) 
      CloseHandle_(hLwStatus)
      ProcedureReturn #True  
    EndIf 
  EndProcedure
 If EjectCD("N:") = #True 
  MessageRequester("USB","Le périphérique peut-être retiré en toute sécurité.",#MB_ICONINFORMATION)
  Else 
  MessageRequester("USB","Le périphérique ne peut être déconnecté!.",#MB_ICONEXCLAMATION)
 EndIf
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 »

pas chez moi, enfin, juste pour les cds

d'ailleurs j'ai amélioré

Ejecte le lecteur de CD et si le lecteur est déjà ouvert, ca ferme le lecteur cd

Code : Tout sélectionner

Procedure EjectDrive(DriveLetter.s)
  DriveLetter = Left(DriveLetter, 1)
  If GetDriveType_(DriveLetter + ":\") = 5 ; Lecteur cd-rom
    
    #IOCTL_STORAGE_EJECT_MEDIA = $D4808
    #IOCTL_STORAGE_LOAD_MEDIA = $2D480C
    
    hDevice = CreateFile_("\\.\" + DriveLetter + ":", #GENERIC_READ, #FILE_SHARE_READ, 0, #OPEN_EXISTING, 0, 0)
    
    If hDevice <> #INVALID_HANDLE_VALUE
      ; Ejecter cd rom
      Temps = ElapsedMilliseconds()
      DeviceIoControl_(hDevice, #IOCTL_STORAGE_EJECT_MEDIA, 0, 0, 0, 0, @Retour, 0)
      If ElapsedMilliseconds() - Temps < 50
        ; rentrer cd rom
        DeviceIoControl_(hDevice, #IOCTL_STORAGE_LOAD_MEDIA, 0, 0, 0, 0, @Retour, 0)
      EndIf
      
      CloseHandle_(hDevice)
      
    EndIf
    
  Else ; Sinon, on tente de retirer le périphérique
    
    
    
  EndIf  
  
EndProcedure

EjectDrive("f")
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 »

Pour tester le code que j'ai posté j'ai ouvert le poste de travail (Ordinateur sur Vista) où j'ai pu constater en temps réél l'éjection de la clé usb par suppression du label.

Par contre avec ton code ça ne fonctionne pas du tout. à part pour les CD's
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.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

pour éjecter un cd , ya plus simple :)


Code : Tout sélectionner

; ouvre le tiroir du cd 

mciSendString_( "set cdaudio door open", "", 0,0)
Delay(5000)
 ;ferme le tiroire du CD
  mciSendString_( "set cdaudio door closed", "", 0,0)
@Jacobus : ton code marche chez moi aussi pour l'USB (Xp sp3)
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

Ah ok, alors ça roule.
Tu devrais essayer à nouveau Régis...
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 »

Dobro : Comment tu choisis la lettre du lecteur à éjecter avec ton code ?



pour ma clé USB, seul ce code marche :

Sauf que j'éjecte toutes les clés USB, donc je cherche le nom du lecteur associé au device que j'éjecte

Code : Tout sélectionner

Procedure RemoveDevice(DriveLetter.s)
  #DIGCF_PRESENT = $2
  #DIGCF_ALLCLASSES = $4
  
  ; 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
  
  Structure SP_DEVINFO_DATA
    cbSize.l
    ClassGuid.GUID
    DevInst.l
    reserved.l
  EndStructure
  
  #Memoire_Taille = 200
  
  Protected DeviceInfoData.SP_DEVINFO_DATA, DeviceCapabilities.l
  Protected *Memoire, Index
  
  DeviceInfoData\cbSize = SizeOf(DeviceInfoData)
  
  hDeviceInfoSet = SetupDiGetClassDevs_(0, 0, 0, #DIGCF_PRESENT | #DIGCF_ALLCLASSES)
  If hDeviceInfoSet <> #INVALID_HANDLE_VALUE
    Library = OpenLibrary(#PB_Any, "setupapi.dll")
    If Library
      
      *CM_Locate_DevNode = GetFunction(Library, "CM_Locate_DevNodeA")
      *CM_Request_Device_Eject = GetFunction(Library, "CM_Request_Device_Eject_ExA")
      
      While SetupDiEnumDeviceInfo_(hDeviceInfoSet, Index, @DeviceInfoData)
        
        *DeviceService = AllocateMemory(#Memoire_Taille)
        *DevicePhysicalName = AllocateMemory(#Memoire_Taille)
        *DeviceName = AllocateMemory(#Memoire_Taille)
        *DeviceDescription = AllocateMemory(#Memoire_Taille)
        
        SetupDiGetDeviceRegistryProperty_(hDeviceInfoSet, DeviceInfoData, #SPDRP_SERVICE, 0, *DeviceService, #Memoire_Taille, 0)
        Debug PeekS(*DeviceService)
        SetupDiGetDeviceRegistryProperty_(hDeviceInfoSet, DeviceInfoData, #SPDRP_LOCATION_INFORMATION, 0, *DevicePhysicalName, #Memoire_Taille, 0)
        Debug PeekS(*DevicePhysicalName)
        SetupDiGetDeviceRegistryProperty_(hDeviceInfoSet, DeviceInfoData, #SPDRP_FRIENDLYNAME, 0, *DeviceName, #Memoire_Taille, 0)
        Debug PeekS(*DeviceName)
        SetupDiGetDeviceRegistryProperty_(hDeviceInfoSet, DeviceInfoData, #SPDRP_CLASSGUID, 0, *DeviceDescription, #Memoire_Taille, 0)
        Debug PeekS(*DeviceDescription)
        SetupDiGetDeviceRegistryProperty_(hDeviceInfoSet, DeviceInfoData, #SPDRP_CAPABILITIES, 0, @DeviceCapabilities, 4, 0)
        Debug DeviceCapabilities
        ; If DeviceCapabilities & #CM_DEVCAP_LOCKSUPPORTED
          ; Debug "CM_DEVCAP_LOCKSUPPORTED"
        ; EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_EJECTSUPPORTED
          ; Debug "CM_DEVCAP_EJECTSUPPORTED"
        ; EndIf
        If DeviceCapabilities & #CM_DEVCAP_REMOVABLE
          Debug "CM_DEVCAP_REMOVABLE"
        EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_DOCKDEVICE
          ; Debug "CM_DEVCAP_DOCKDEVICE"
        ; EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_UNIQUEID
          ; Debug "CM_DEVCAP_UNIQUEID"
        ; EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_SILENTINSTALL
          ; Debug "CM_DEVCAP_SILENTINSTALL"
        ; EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_RAWDEVICEOK
          ; Debug "CM_DEVCAP_RAWDEVICEOK"
        ; EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_SURPRISEREMOVALOK
          ; Debug "CM_DEVCAP_RAWDEVICEOK"
        ; EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_HARDWAREDISABLED
          ; Debug "CM_DEVCAP_HARDWAREDISABLED"
        ; EndIf
        ; If DeviceCapabilities & #CM_DEVCAP_NONDYNAMIC
          ; Debug "CM_DEVCAP_NONDYNAMIC"
        ; EndIf
        
        
        
        ;- Pour éjecter toutes les clés USB
        If UCase(PeekS(*DeviceService)) = "USBSTOR"
          *DeviceId = AllocateMemory(#Memoire_Taille)
          SetupDiGetDeviceInstanceId_(hDeviceInfoSet, DeviceInfoData, *DeviceId, #Memoire_Taille, 0)
          Debug PeekS(*DeviceId)
          If CallFunctionFast(*CM_Locate_DevNode, @DevInst.l, PeekS(*DeviceId), 0) = 0
            CallFunctionFast(*CM_Request_Device_Eject, DevInst, 0, 0, 0, 0, 0)
          EndIf
          FreeMemory(*DeviceId)
        EndIf
        
        FreeMemory(*DeviceService)
        FreeMemory(*DevicePhysicalName)
        FreeMemory(*DeviceName)
        FreeMemory(*DeviceDescription)
        
        
        Debug "_____________________"
        Index + 1
      Wend
      
      CloseLibrary(Librairie)
    EndIf
    SetupDiDestroyDeviceInfoList_(hDeviceInfoSet)
  EndIf
  
  
  Debug "Fin"
  
EndProcedure

RemoveDevice("M:\")
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)]
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Le Soldat Inconnu a écrit :Dobro : Comment tu choisis la lettre du lecteur à éjecter avec ton code ?
peut etre comme ça : (j'ai pas testé :) )

Code : Tout sélectionner

; ouvre le tiroir du cd 

mciSendString_("open F:\ type cdaudio alias cdaudio"); // le lecteur est ici F

mciSendString_( "set cdaudio door open", "", 0,0)
Delay(5000)
 ;ferme le tiroire du CD
mciSendString_( "set cdaudio door closed", "", 0,0)

mciSendString_("close cdaudio", 0, 0, 0);
 
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Message par GeBonet »

Une image de ce que devrait-être une fermeture de clef USB ou lecteur amovible !!!

http://home.euphonynet.be/bonet/Ejecteur_HP.jpg

Bonne nuit...
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

voila un code qui me semble correct
http://groups.google.com/group/microsof ... 7adc?pli=1

sur la plupart de mes recherches, la pistes semble êtres de lister les interfaces

mais je cale la dessus

Code : Tout sélectionner

Structure SP_DEVINFO_DATA
  cbSize.l
  ClassGuid.GUID
  DevInst.l
  reserved.l
EndStructure
  ; Structure SP_DEVICE_INTERFACE_DATA
    ; cbSize.l
    ; InterfaceClassGuid.GUID
    ; flags.l
    ; reserved.l
  ; EndStructure
Structure PSP_DEVICE_INTERFACE_DETAIL_DATA
  cbSize.l
  DevicePath.l
EndStructure
  
HDEVINFO = SetupDiGetClassDevs_(0, 0, 0, #DIGCF_PRESENT | #DIGCF_DEVICEINTERFACE)
  
If HDEVINFO <> #INVALID_HANDLE_VALUE
  Index = 0
  
  Debug "handle ok"
  
  pspdidd.PSP_DEVICE_INTERFACE_DETAIL_DATA
  spdid.SP_DEVICE_INTERFACE_DATA
  spdd.SP_DEVINFO_DATA
  dwSize.l
  
  spdid\cbSize = SizeOf(SP_DEVICE_INTERFACE_DATA)
  
  While SetupDiEnumDeviceInterfaces_(HDEVINFO, 0, 0, Index, @spdid)
    
    dwSize = 0
    SetupDiGetDeviceInterfaceDetail_(HDEVINFO, @spdid, 0, 0, @dwSize, 0)
    Debug dwSize
    
    Index + 1
    Debug "_____________________"
  Wend
  SetupDiDestroyDeviceInfoList_(HDEVINFO)
  Debug "Fin"
EndIf
Je n'arrive pas à avoir de handle correct sur mon SetupDiGetClassDevs
et quand je pense trouvé qlqchose, ca ne retourne rien avec SetupDiEnumDeviceInterfaces
Je cale
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 »

Allez, j'ai enfin trouvé un code qui marche

Code : Tout sélectionner

; 
; RemoveDriveByLetter.cpp by Uwe Sieber - www.uwe-sieber.de 
; 
; Simple demonstration how to prepare a disk drive for save removal 
; 
; Works with removable and fixed drives under W2K, XP, W2K3, Vista 
; 
; Console application - expects the drive letter of the drive to remove as parameter 
; 
; you are free to use this code in your projects 
; 

EnableExplicit 


Macro CTL_CODE(DeviceType, Function, Method, Access) 
  (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) 
EndMacro 

#FILE_DEVICE_MASS_STORAGE = $0000002D 
#IOCTL_STORAGE_BASE = #FILE_DEVICE_MASS_STORAGE 
#FILE_ANY_ACCESS = 0 
#METHOD_BUFFERED = 0 
#IOCTL_STORAGE_GET_DEVICE_NUMBER = CTL_CODE(#IOCTL_STORAGE_BASE, $0420, #METHOD_BUFFERED, #FILE_ANY_ACCESS) 

#CM_REMOVE_NO_RESTART = $00000002 

#DIGCF_PRESENT         = $00000002 
#DIGCF_ALLCLASSES      = $00000004 
#DIGCF_PROFILE         = $00000008 
#DIGCF_DEVICEINTERFACE = $00000010 

#PNP_VetoTypeUnknown = 0 
#CR_SUCCESS = 0 

Structure PSP_DEVICE_INTERFACE_DETAIL_DATA 
  cbSize.l 
  DevicePath.s{1024} 
EndStructure 

Structure SP_DEVINFO_DATA 
  cbSize.l 
  ClassGuid.GUID 
  DevInst.l 
  reserved.l 
EndStructure 

; Structure SP_DEVICE_INTERFACE_DATA 
  ; cbSize.l 
  ; InterfaceClassGuid.GUID 
  ; flags.l 
  ; reserved.l 
; EndStructure 

; Structure STORAGE_DEVICE_NUMBER 
  ; DeviceType.l      ;// The FILE_DEVICE_XXX type For this device. 
  ; DeviceNumber.l    ;// The number of this device 
  ; PartitionNumber.l ;// If the device is partitionable, the partition number of the device. Otherwise -1 
; EndStructure 

Prototype.l CM_Get_Parent(*DevInst, DevInst, flags) 
; CM_Get_Parent( 
;              OUT PDEVINST pdnDevInst, 
;              IN  DEVINST  dnDevInst, 
;              IN  ULONG    ulFlags 
;              ); 
Prototype.l CM_Get_Device_IDA(DevInst, DeviceIdString.s, BufferLen, flags) 
; CM_Get_Device_IDW( 
;              IN  DEVINST  dnDevInst, 
;              OUT PWCHAR   Buffer, 
;              IN  ULONG    BufferLen, 
;              IN  ULONG    ulFlags 
;              ); 
Prototype.l CM_Request_Device_EjectA(DevInst, *VetoType, VetoName.s, NameLength, flags) 
; CM_Request_Device_EjectW( 
;             IN  DEVINST         dnDevInst, 
;             OUT PPNP_VETO_TYPE  pVetoType, 
;             OUT LPWSTR          pszVetoName, 
;             IN  ULONG           ulNameLength, 
;             IN  ULONG           ulFlags 
;             ); 
Prototype.l CM_Query_And_Remove_SubTreeA(Ancestor, *VetoType, VetoName.s, NameLength, flags) 
; CM_Query_And_Remove_SubTreeW( 
;              IN  DEVINST        dnAncestor, 
;              OUT PPNP_VETO_TYPE pVetoType, 
;              OUT LPWSTR         pszVetoName, 
;              IN  ULONG          ulNameLength, 
;              IN  ULONG          ulFlags 
;              ); 
Prototype.l SetupDiEnumDeviceInterfaces(DeviceInfoSet, DeviceInfoData, *InterfaceClassGuid, MemberIndex, *DeviceInterfaceData) 
; SetupDiEnumDeviceInterfaces( 
;     IN  HDEVINFO                   DeviceInfoSet, 
;     IN  PSP_DEVINFO_DATA           DeviceInfoData,     OPTIONAL 
;     IN  CONST GUID                *InterfaceClassGuid, 
;     IN  DWORD                      MemberIndex, 
;     OUT PSP_DEVICE_INTERFACE_DATA  DeviceInterfaceData 
;     ); 
Prototype.l SetupDiGetDeviceInterfaceDetailA(DeviceInfoSet, DeviceInterfaceData, *DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize, *RequiredSize, *DeviceInfoData) 
; SetupDiGetDeviceInterfaceDetailW( 
;     IN  HDEVINFO                           DeviceInfoSet, 
;     IN  PSP_DEVICE_INTERFACE_DATA          DeviceInterfaceData, 
;     OUT PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,     OPTIONAL 
;     IN  DWORD                              DeviceInterfaceDetailDataSize, 
;     OUT PDWORD                             RequiredSize,                  OPTIONAL 
;     OUT PSP_DEVINFO_DATA                   DeviceInfoData                 OPTIONAL 
;     ); 

Global CM_Get_Parent.CM_Get_Parent 
Global CM_Get_Device_ID.CM_Get_Device_IDA
Global CM_Request_Device_EjectA.CM_Request_Device_EjectA
Global CM_Query_And_Remove_SubTreeA.CM_Query_And_Remove_SubTreeA 
Global SetupDiEnumDeviceInterfaces.SetupDiEnumDeviceInterfaces 
Global SetupDiGetDeviceInterfaceDetail.SetupDiGetDeviceInterfaceDetailA 


; ---------------------------------------------------------------------- 
;  returns the device instance handle of a storage volume or 0 on error 
; ---------------------------------------------------------------------- 
Procedure.l GetDrivesDevInstByDeviceNumber(DeviceNumber, DriveType, DosDeviceName.s) 
  Protected IsFloppy, *guid, Index, res, Size, hDevInfo 
  Protected pspdidd.PSP_DEVICE_INTERFACE_DETAIL_DATA, spdid.SP_DEVICE_INTERFACE_DATA, spdd.SP_DEVINFO_DATA 
  Protected sdn.STORAGE_DEVICE_NUMBER 
  Protected hDrive, BytesReturned 
  
  IsFloppy = FindString(DosDeviceName, "\Floppy", 1)  ; // who knows a better way? 
  
  Select DriveType 
    Case #DRIVE_REMOVABLE 
      If IsFloppy 
        *guid = ?GUID_DEVINTERFACE_FLOPPY 
      Else 
        *guid = ?GUID_DEVINTERFACE_DISK 
      EndIf 
    Case #DRIVE_FIXED 
      *guid = ?GUID_DEVINTERFACE_DISK 
    Case #DRIVE_CDROM 
      *guid = ?GUID_DEVINTERFACE_CDROM 
    Default 
      ProcedureReturn 0 
  EndSelect 
  
  ; Get device interface info set handle for all devices attached to system 
  hDevInfo = SetupDiGetClassDevs_(*guid, 0, 0, #DIGCF_PRESENT|#DIGCF_DEVICEINTERFACE) 
  
  If hDevInfo = #INVALID_HANDLE_VALUE 
    ProcedureReturn 0 
  EndIf 
  
  ; Retrieve a context structure for a device interface of a device information set 
  
  spdid\cbSize = SizeOf(SP_DEVICE_INTERFACE_DATA) 
  
  Repeat 
    res = SetupDiEnumDeviceInterfaces(hDevInfo, 0, *guid, Index, @spdid) 
    
    If res = 0 
      Break 
    EndIf 
    
    SetupDiGetDeviceInterfaceDetail(hDevInfo, @spdid, 0, 0, @Size, 0) ; check the buffer size 
    If Size<>0 And Size<=SizeOf(PSP_DEVICE_INTERFACE_DETAIL_DATA) 
      pspdidd\cbSize = 5    ; Unicode=6, ASCII=5 
      
      spdd\cbSize = SizeOf(SP_DEVINFO_DATA) 
      
      ;res = SetupDiGetDeviceInterfaceDetail(hDevInfo, @spdid, @pspdidd, Size, @Size, @spdd) 
      res = SetupDiGetDeviceInterfaceDetail(hDevInfo, @spdid, @pspdidd, Size, 0, @spdd) 
      If res 
        ; in case you are interested in the USB serial number: 
        ; the device id string contains the serial number if the device has one, 
        ; otherwise a generated id that contains the '&' char... 
        ;         Protected DevInstParent, DeviceIdString.s=Space(#MAX_PATH) 
        ;              CM_Get_Parent(@DevInstParent, spdd\DevInst, 0) 
        ;              CM_Get_Device_ID(DevInstParent, DeviceIdString, #MAX_PATH, 0) 
        ;         Debug "DeviceId= " + DeviceIdString 
        
        Debug pspdidd\DevicePath
        
        ; open the disk or cdrom or floppy 
        hDrive = CreateFile_(@pspdidd\DevicePath, 0, #FILE_SHARE_READ|#FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0) 
        If hDrive <> #INVALID_HANDLE_VALUE 
          ; get its device number 
          BytesReturned = 0 
          res = DeviceIoControl_(hDrive, #IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, @sdn, SizeOf(STORAGE_DEVICE_NUMBER), @BytesReturned, 0) 
          If res 
            If DeviceNumber = sdn\DeviceNumber  ; match the given device number with the one of the current device 
              CloseHandle_(hDrive) 
              SetupDiDestroyDeviceInfoList_(hDevInfo) 
              ProcedureReturn spdd\DevInst 
            EndIf 
          EndIf 
          CloseHandle_(hDrive) 
        EndIf 
      EndIf 
    EndIf 
    Index + 1 
  ForEver 
  
  SetupDiDestroyDeviceInfoList_(hDevInfo) 
  
  ProcedureReturn 0 
EndProcedure 

Procedure RemoveDrive(drive$) 
  Protected RootPath.s, DevicePath.s, VolumeAccessPath.s, hVolume 
  Protected sdn.STORAGE_DEVICE_NUMBER, res, DriveType, DeviceNumber=-1 
  Protected DosDeviceName.s 
  Protected DevInst, BytesReturned, DevInstParent 
  Protected VetoType, VetoNameW.s, tries, bSuccess=#False 
  
  drive$ = Left(UCase(drive$), 1) 
  If drive$<"A" Or drive$>"Z" : Goto exit : EndIf 
  
  DevicePath = drive$ + ":"       ; "X:"   -> for QueryDosDevice 
  RootPath = DevicePath + "\"     ; "X:\"  -> for GetDriveType 
  VolumeAccessPath = "\\.\" + DevicePath  ; "\\.\X:"  -> to open the volume 
  
  ; open the storage volume 
  hVolume = CreateFile_(VolumeAccessPath, 0, #FILE_SHARE_READ|#FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0) 
  
  If hVolume <> #INVALID_HANDLE_VALUE 
    ; get the volume's device number 
    res = DeviceIoControl_(hVolume, #IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, @sdn, SizeOf(STORAGE_DEVICE_NUMBER), @BytesReturned, 0) 
    If res 
      DeviceNumber = sdn\DeviceNumber 
    EndIf 
    CloseHandle_(hVolume) 
    
    If DeviceNumber = -1 
      Goto exit 
    EndIf 
    
    ; get the drive type which is required To match the device numbers correctely 
    DriveType = GetDriveType_(RootPath) 
    
    ; get the dos device name (like \device\floppy0) to decide if it's a floppy or not - who knows a better way? 
    DosDeviceName = Space(#MAX_PATH) 
    res = QueryDosDevice_(DevicePath, DosDeviceName, #MAX_PATH) 
    Debug DosDeviceName
    
    If res = 0 
      Goto exit 
    EndIf 
    
    ; get the device instance handle of the storage volume by means of a SetupDi enum and matching the device number 
    DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber, DriveType, DosDeviceName) 
    
    If DevInst = 0 
      Goto exit 
    EndIf 
    
    ;VetoType = #PNP_VetoTypeUnknown  ;#PNP_VetoTypeUnknown=0 
    VetoNameW = Space(#MAX_PATH) 
    
    ; get drives's parent, e.g. the USB bridge, the SATA port, an IDE channel with two drives! 
    If CM_Get_Parent(@DevInstParent, DevInst, 0) 
      CM_Request_Device_EjectA(DevInstParent, 0, "", 0, 0) 
    EndIf
   
  EndIf 
  
  exit: 
  
  ProcedureReturn 
EndProcedure 


; ----------------------- 
; test code 
; ----------------------- 

Define drive$ 
#setupapi = 1 

If OpenLibrary(#setupapi, "setupapi.dll") 
  CM_Get_Parent = GetFunction(#setupapi, "CM_Get_Parent") 
  CM_Get_Device_ID = GetFunction(#setupapi, "CM_Get_Device_IDA") 
  CM_Request_Device_EjectA = GetFunction(#setupapi, "CM_Request_Device_EjectA") 
  CM_Query_And_Remove_SubTreeA = GetFunction(#setupapi, "CM_Query_And_Remove_SubTreeA") 
  SetupDiEnumDeviceInterfaces = GetFunction(#setupapi, "SetupDiEnumDeviceInterfaces") 
  SetupDiGetDeviceInterfaceDetail = GetFunction(#setupapi, "SetupDiGetDeviceInterfaceDetailA") 
  
  drive$ = "h"    ;any drive letter to want to remove. 
  RemoveDrive(drive$) 
  
  CloseLibrary(#setupapi) 
EndIf 

End 

DataSection 
  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 
EndDataSection
Je vais fignoler tout ça :)
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 »

Content que tu ai trouvé...
Maintenant question stupide... :wink:

Sous quelle appellation apparait la clef U3 avec Explorer de Windows ?
Une lettre pour : Un lecteur et une clef ou une clef ?

Car par exemple : Ma clef USB dans un port USB est lu comme une Clef.. Gerhard
Tandis que une carte mémoire dans le lecteur de carte apparait comme un lecteur amovible "n:" ?


Et tout les deux sont gérer par le même driver : USBSTOR.SYS

Ne pas oublier que :

L'éjection doit provoquer l'écriture du Tampon mémoire vers la clef s'il y a eu écriture sur la clef...
Avec demande de confirmation d'éjection !
Et avertissement que la clef est libre pour être retirer !
C'est ce que l'on doit (devrais) toujours faire avant d'éjecter... (retirer une clef)
Et normalement, Windows pourvoit à ça ?
Alors pourquoi vouloir le faire indépendamment ?
Bon ! Si c'est secret OK...: :lol:

Note : USBSTOR.SYS c'est le driver Windows des "lecteurs USB amovibles... Que ce soit lecteurs de disquettes, de Cartes mémoire, clef USB ou Disque Dur"
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

en tout cas le code de Jacobus provoque l'affichage de la fenetre system
qui dit quon peut retirer la clef sans danger !! :)
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

pas chez moi, seul le code que j'ai posté fonctionne, avec une clé USB classique et ma clé U3

Ce que je veux faire ?

Dans mon Bi-Exploreur, quand je fais clic droit sur un lecteur avoir l'option "Retirer le périphérique en toute sécurité"
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)]
Répondre