Eject USB drive
Eject USB drive
How do you eject a removeable USB drive?
I tried to search and only found this: http://purebasic.fr/english/viewtopic.p ... move+drive
The codes in that link removes all removeable drives. But I only need to remove one specified drive (like D:\). Thank you.
Another question:
So when you just ejcted the specified drive, and the user didn't remove physically the drive (USB) - how can you "install" it back, so it is available?
Thank you
I tried to search and only found this: http://purebasic.fr/english/viewtopic.p ... move+drive
The codes in that link removes all removeable drives. But I only need to remove one specified drive (like D:\). Thank you.
Another question:
So when you just ejcted the specified drive, and the user didn't remove physically the drive (USB) - how can you "install" it back, so it is available?
Thank you
Re: Eject USB drive
Hello,
You can test the devcon.exe (download from Microsoft):
Have fun!
Helle
P.S.: Don´t change the HID´s!!!
Edit: HID´s not switchable - too dangerous!
You can test the devcon.exe (download from Microsoft):
Code: Select all
;- Switch On-Off USB-Devices
;- "Helle" Klaus Helbing, 13.01.2010, PB v.4.40 x86, WinXP Prof. 32-Bit
;- Use the devcon.exe from Microsoft
;- Adjust the times (Delay(2000)) if necessary!
USBR$ = "USB\ROOT"
Activ$ = "running"
Dis$ = "disabled"
Structure USB
Name$
VID$
PID$
Status$
EndStructure
If OpenWindow(0, 0, 0, 400, 200, "Switch On-Off USB-Devices (Mouse LeftDoubleClick)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 10, 10, 380, 180, "Geräte-Name", 180, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "VID", 65)
AddGadgetColumn(0, 2, "PID", 65)
AddGadgetColumn(0, 3, "Status", 60)
;notice the path of devcon.exe
ProgID = RunProgram("devcon", "find usb\*", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
Delay(2000) ;muss sein! Bei Bedarf höher!
Laenge = AvailableProgramOutput(ProgID)
Buffer = AllocateMemory(Laenge)
ReadProgramData(ProgID, Buffer, Laenge)
Dim Geraet.USB(Laenge) ;gaaaanz sicher! Kann man natürlich verkleinern
For i = 0 To Laenge - 1
If PeekB(Buffer + i) = 13
USB$ = PeekS(Buffer + j, i-j, #PB_Ascii)
j = i
If FindString(USB$, USBR$, 1) = 0
AddGadgetItem(0, -1, "")
If FindString(USB$, "VID", 1) > 0 ;sonst Käse bei kein Gerät
USB$ = RTrim(USB$) ;zeigt hier auch ausgeschaltete Geräte an!
Geraet(z)\VID$ = Mid(USB$, 7, 8) ;8 Zeichen lang, Position ermittelt
SetGadgetItemText(0, z, Geraet(z)\VID$, 1)
Geraet(z)\PID$ = Mid(USB$, 16, 8)
SetGadgetItemText(0, z, Geraet(z)\PID$, 2)
k = FindString(USB$, ":", 20) ;oder mehr als 20
Geraet(z)\Name$ = Mid(USB$, k+2, i-k) ;oder bei bekannter VID/PID eigenen Namen setzen
SetGadgetItemText(0, z, Geraet(z)\Name$, 0)
ProgID2 = RunProgram("devcon", "status usb\"+Geraet(z)\VID$+Chr(38)+Geraet(z)\PID$, "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
Delay(2000)
Laenge2 = AvailableProgramOutput(ProgID2)
Buffer2 = AllocateMemory(Laenge2)
ReadProgramData(ProgID2, Buffer2, Laenge2)
Act$ = PeekS(Buffer2, Laenge2, #PB_Ascii)
KillProgram(ProgID2)
CloseProgram(ProgID2)
FreeMemory(Buffer2)
If FindString(Act$, Activ$, 1) <> 0
Geraet(z)\Status$ = Activ$
Else
Geraet(z)\Status$ = Dis$
EndIf
SetGadgetItemText(0, z, Geraet(z)\Status$, 3)
z + 1
If i > Laenge - 50 ;50 oder so in etwa
Break
EndIf
EndIf
EndIf
EndIf
Next
KillProgram(ProgID) ;sicher ist sicher
CloseProgram(ProgID)
Repeat
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until EventType() = #PB_EventType_LeftDoubleClick
z = GetGadgetState(0)
If z >= 0
;Status switchen
If Geraet(z)\Status$ = Activ$
If FindString(Geraet(z)\Name$, "USB-HID", 1) = 0 ;Not Keyboard and Mouse - too dangerous!
ProgID2 = RunProgram("devcon", "disable usb\" + Geraet(z)\VID$ + Chr(38) + Geraet(z)\PID$, "", #PB_Program_Open | #PB_Program_Hide)
EndIf
Else
ProgID2 = RunProgram("devcon", "enable usb\" + Geraet(z)\VID$ + Chr(38) + Geraet(z)\PID$, "", #PB_Program_Open | #PB_Program_Hide)
EndIf
;aktuellen Status des geswitchten Gerätes abfragen
Delay(2000) ;evtl. anpassen
ProgID3 = RunProgram("devcon", "status usb\"+Geraet(z)\VID$+Chr(38)+Geraet(z)\PID$, "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
Delay(2000)
Laenge3 = AvailableProgramOutput(ProgID3)
Buffer3 = AllocateMemory(Laenge3)
ReadProgramData(ProgID3, Buffer3, Laenge3)
Act$ = PeekS(Buffer3, Laenge3, #PB_Ascii)
KillProgram(ProgID3)
CloseProgram(ProgID3)
FreeMemory(Buffer3)
If FindString(Act$, Activ$, 1) <> 0
Geraet(z)\Status$ = Activ$
Else
Geraet(z)\Status$ = Dis$
EndIf
SetGadgetItemText(0, z, Geraet(z)\Status$, 3)
EndIf
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Helle
P.S.: Don´t change the HID´s!!!
Edit: HID´s not switchable - too dangerous!
Re: Eject USB drive
Hi,
One day I found this code I do not know who
, but he does his work
One day I found this code I do not know who
Code: Select all
; -------------------------------------
; Author unknown
; --------------------------------------
; USB Device remove... !!!
;
#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("H:") = #True
MessageRequester("USB","device can be safely removed.",#MB_ICONINFORMATION)
Else
MessageRequester("USB","The device can be disconnected !.",#MB_ICONEXCLAMATION)
EndIf
Sorry for my english
! (Windows Xp, Vista and Windows 7, Windows 10)
- doctorized
- Addict

- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Eject USB drive
Your code seems to work fine but after the messagerequester appears saying "device can be safely removed.",GeBonet wrote:One day I found this code I do not know who, but he does his work
![]()
the device is still listed on My Computer (without having removed it). Only when I take the device away, Windows
remove it from the list. I must say that it is not so big deal but I just refer it.
Re: Eject USB drive
I've found 'Remove all USBSTORs' - which should be updated to 4.4
Code: Select all
; bingo: http://www.purebasic.fr/english/viewtopic.php?p=135750#135750
#DIGCF_PRESENT = 2
#DIGCF_ALLCLASSES = 4
hDeviceInfoSet = SetupDiGetClassDevs_(0, 0, 0, #DIGCF_PRESENT | #DIGCF_ALLCLASSES)
Structure SP_DEVINFO_DATA
cbSize.l
ClassGuid.GUID
DevInst.l
Reserved.l
EndStructure
Global DeviceInfoData.SP_DEVINFO_DATA ;global für funktion
DeviceInfoData\cbSize = SizeOf(DeviceInfoData)
#SPDRP_SERVICE = 4
*MemoryID = AllocateMemory(500)
i.l
OpenLibrary(1, "setupapi.dll")
*F1 = GetFunction(1, "SetupDiGetDeviceInstanceIdA")
*F2 = GetFunction(1, "SetupDiGetDeviceRegistryPropertyA")
*F3 = GetFunction(1, "CM_Locate_DevNodeA")
*F4 = GetFunction(1, "CM_Request_Device_Eject_ExA")
While SetupDiEnumDeviceInfo_(hDeviceInfoSet, i, @DeviceInfoData)
i + 1
CallFunctionFast(*F2, hDeviceInfoSet, DeviceInfoData, #SPDRP_SERVICE, 0, *MemoryID, 500, 0)
If UCase(PeekS(*MemoryID)) = "USBSTOR"
CallFunctionFast(*F1, hDeviceInfoSet, DeviceInfoData, *MemoryID, 500, 0)
If CallFunctionFast(*F3, @devinst.l, PeekS(*MemoryID), 0) = 0
CallFunctionFast(*F4, devinst, 0, 0, 0, 0, 0)
EndIf
EndIf
Wend
SetupDiDestroyDeviceInfoList_(hDeviceInfoSet)
CloseLibrary(1)
FreeMemory(*MemoryID)
- doctorized
- Addict

- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Eject USB drive
Bad parameter type, number expected instead of string. Try this:eJan wrote:Code: Select all
If CallFunctionFast(*F3, @devinst.l, PeekS(*MemoryID), 0) = 0
Code: Select all
temp.s = PeekS(*MemoryID)
If CallFunctionFast(*F3, @devinst.l, @temp, 0) = 0The bad with this code is parameter i at:
Code: Select all
While SetupDiEnumDeviceInfo_(hDeviceInfoSet, i, @DeviceInfoData)Re: Eject USB drive
@doctorized
Will you please check the next snippet?
Updated
Will you please check the next snippet?
Code: Select all
#IOCTL_STORAGE_EJECT_MEDIA = $2D4808
#IOCTL_STORAGE_LOAD_MEDIA = $2D480C
Global CtrlCode.l,ReturnedBs.l,Status.l
Procedure EjectUSB(USBpath$,CtrlCode )
;obtain a handle to the device
hDevice = CreateFile_("\\.\"+ USBpath$,#GENERIC_READ,#FILE_SHARE_READ|#FILE_SHARE_WRITE,#Null,#OPEN_EXISTING,0,0)
If hDevice <> #INVALID_HANDLE_VALUE
Status = DeviceIoControl_(hDevice,CtrlCode,0,0,0,0,@ReturnedBs,0)
EndIf
CloseHandle_(hDevice)
If Status <> 0
MessageRequester("","Now it is Safe to Remove the Media")
EndIf
EndProcedure
For i = 67 To 90
VolumeName$ = Space(14)
Str$ = Space(32)
CDPath$ = Chr(i)+":\"
DriveType = GetDriveType_(CDPath$)
If DriveType = #DRIVE_REMOVABLE
GetVolumeInformation_(CDPath$,@VolumeName$,Len(VolumeName$),0,0,0,@Str$,Len(Str$))
Result = MessageRequester("", "Do you want to eject "+ CDPath$ + " " + VolumeName$, #PB_MessageRequester_YesNo)
If Result = #PB_MessageRequester_Yes
EjectUSB(Left(CDPath$,2), #IOCTL_STORAGE_EJECT_MEDIA)
EndIf
EndIf
Next
Last edited by RASHAD on Sun Jan 17, 2010 5:03 pm, edited 1 time in total.
Egypt my love
Re: Eject USB drive
Hello,
I have no problem with this procedure works.
This is normal if the key is still there, the message from Windows warned you disconnected software (writing the buffet on the key if necessary) and only after physically removing it disappears!doctorized wrote:Your code seems to work fine but after the messagerequester appears saying "device can be safely removed.",GeBonet wrote:One day I found this code I do not know who, but he does his work
![]()
the device is still listed on My Computer (without having removed it). Only when I take the device away, Windows
remove it from the list. I must say that it is not so big deal but I just refer it.
I have no problem with this procedure works.
Sorry for my english
! (Windows Xp, Vista and Windows 7, Windows 10)
- Psychophanta
- Always Here

- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: Eject USB drive
Updated:eJan wrote:I've found 'Remove all USBSTORs' - which should be updated to 4.4
Code: Select all
Prototype SetupDiGetDeviceInstanceIdA(a,b,c,d,e)
Prototype SetupDiGetDeviceRegistryPropertyA(a,b,c,d,e,f,g)
Prototype CM_Locate_DevNodeA(a,b.p-ascii,c)
Prototype CM_Request_Device_Eject_ExA(a,b,c,d,e,f)
hDeviceInfoSet=SetupDiGetClassDevs_(0,0,0,#DIGCF_PRESENT|#DIGCF_ALLCLASSES)
Global DeviceInfoData.SP_DEVICE_INTERFACE_DATA ;global für funktion
DeviceInfoData\cbSize=SizeOf(DeviceInfoData)
#SPDRP_SERVICE=4
If OpenLibrary(1,"setupapi.dll")=0:End:EndIf
*MemoryID=AllocateMemory(500)
F1.SetupDiGetDeviceInstanceIdA=GetFunction(1,"SetupDiGetDeviceInstanceIdA")
F2.SetupDiGetDeviceRegistryPropertyA=GetFunction(1,"SetupDiGetDeviceRegistryPropertyA")
F3.CM_Locate_DevNodeA=GetFunction(1,"CM_Locate_DevNodeA")
F4.CM_Request_Device_Eject_ExA=GetFunction(1,"CM_Request_Device_Eject_ExA")
While SetupDiEnumDeviceInfo_(hDeviceInfoSet,i.l,@DeviceInfoData)
i.l+1
F2(hDeviceInfoSet,DeviceInfoData,#SPDRP_SERVICE,0,*MemoryID,500,0)
If UCase(PeekS(*MemoryID))="USBSTOR"
F1(hDeviceInfoSet,DeviceInfoData,*MemoryID,500,0)
If F3(@devinst.l,PeekS(*MemoryID,-1,#PB_Ascii),0)=0
F4(devinst,0,0,0,0,0)
EndIf
EndIf
Wend
SetupDiDestroyDeviceInfoList_(hDeviceInfoSet)
CloseLibrary(1)
FreeMemory(*MemoryID)Re: Eject USB drive
I have tried all those codes, none of them works for ejecting one specified device.
- Psychophanta
- Always Here

- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: Eject USB drive
Yes, that's true. I've tried a little bit , but i am not able to get a relationship between the number 'devinst' reported by CM_Locate_DevNodeA() function and the windows letter.donSHAYA wrote:I have tried all those codes, none of them works for ejecting one specified device.
- doctorized
- Addict

- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Eject USB drive
The code is asking for every drive if I want to remove it, but when I select yes, the drive is still in the list.RASHAD wrote:@doctorized
Will you please check the next snippet?
Updated
Re: Eject USB drive
@doctorized Hi
Thank you very much for responding
Yes it remove the device from Explorer but not from My Computer
I am working now on another approach and I will inform you if I succedded
Thanks again
Thank you very much for responding
Yes it remove the device from Explorer but not from My Computer
I am working now on another approach and I will inform you if I succedded
Thanks again
Egypt my love
- Michael Vogel
- Addict

- Posts: 2821
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: Eject USB drive
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
- doctorized
- Addict

- Posts: 882
- Joined: Fri Mar 27, 2009 9:41 am
- Location: Athens, Greece
Re: Eject USB drive
@ RASHAD: No need to thank me. I am always here to help!
@ Michael Vogel: your code returns error: "Line 32: Structure not found: SP_DEVINFO_DATA."
@ Michael Vogel: your code returns error: "Line 32: Structure not found: SP_DEVINFO_DATA."


