Code: Select all
Procedure EjectUSBDrive(Drive.s, EjectNow.l=#True)
#SPDRP_CAPABILITIES = $F
#CM_DEVCAP_REMOVABLE = $4
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
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
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
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")
*VolumeName = AllocateMemory(255)
CallFunctionFast(*GetVolumeNameForVolumeMountPoint, Drive + "\", *VolumeName, 255)
DriveVolume= PeekS(*VolumeName)
FreeMemory(*VolumeName)
*Guid = ?GUID_DEVINTERFACE_VOLUME
hDevice = SetupDiGetClassDevs_(*Guid, 0, 0, #DIGCF_PRESENT|#DIGCF_DEVICEINTERFACE)
If hDevice <> #INVALID_HANDLE_VALUE
spdid\cbSize = SizeOf(SP_DEVICE_INTERFACE_DATA)
Index= 0
While SetupDiEnumDeviceInterfaces_(hDevice, 0, *Guid, Index, @spdid)
SetupDiGetDeviceInterfaceDetail_(hDevice, @spdid, 0, 0, @DevicePath_Length, 0)
If DevicePath_Length <> 0 And DevicePath_Length < 255
pspdidd\cbSize = 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
DeviceInstance = spdd\DevInst
Repeat
If CallFunctionFast(*CM_Get_Parent, @DeviceParent, DeviceInstance, 0) = 0
DeviceInstance = DeviceParent
*DeviceInstanceId = AllocateMemory(255)
CallFunctionFast(*CM_Get_Device_ID, DeviceInstance, *DeviceInstanceId, 255, 0)
DeviceID = PeekS(*DeviceInstanceId)
FreeMemory(*DeviceInstanceId)
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
Retour = 1
If EjectNow
If CallFunctionFast(*CM_Locate_DevNode, @DeviceInstance.l, DeviceID, 0) = 0
CallFunctionFast(*CM_Request_Device_Eject, DeviceInstance, 0, 0, 0, 0, 0)
EndIf
EndIf
Break 2
EndIf
EndIf
Until DeviceInstance <> DeviceParent
EndIf
EndIf
EndIf
Index + 1
Wend
SetupDiDestroyDeviceInfoList_(hDevice)
EndIf
CloseLibrary(dll_Kernel32)
EndIf
CloseLibrary(dll_Setupapi)
EndIf
ProcedureReturn Retour
EndProcedure