
Je dois encore le noter.. Très bien.
Mais maintenant que je suis dans le secret

Je vais garder une note : Très, Très bien avec la déconnexion de clef :



Code : Tout sélectionner
+ USBSTOR
| + disk
| | volume générique
| cd-rom
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
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
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
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