Eject USB drive

Just starting out? Need help? Post your questions and find answers here.
donSHAYA
User
User
Posts: 95
Joined: Wed Mar 25, 2009 9:57 am

Eject USB drive

Post by donSHAYA »

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
Helle
Enthusiast
Enthusiast
Posts: 178
Joined: Wed Apr 12, 2006 7:59 pm
Location: Germany
Contact:

Re: Eject USB drive

Post by Helle »

Hello,
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 
Have fun!
Helle

P.S.: Don´t change the HID´s!!!
Edit: HID´s not switchable - too dangerous!
User avatar
GeBonet
Enthusiast
Enthusiast
Posts: 135
Joined: Fri Apr 04, 2008 6:20 pm
Location: Belgium

Re: Eject USB drive

Post by GeBonet »

Hi,

One day I found this code I do not know who :cry: , but he does his work :wink:

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 :wink: ! (Windows Xp, Vista and Windows 7, Windows 10)
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Eject USB drive

Post by doctorized »

GeBonet wrote:One day I found this code I do not know who :cry: , but he does his work :wink:
Your code seems to work fine but after the messagerequester appears saying "device can be safely removed.",
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.
eJan
Enthusiast
Enthusiast
Posts: 366
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Re: Eject USB drive

Post by eJan »

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)
Image
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Eject USB drive

Post by doctorized »

eJan wrote:

Code: Select all

If CallFunctionFast(*F3, @devinst.l, PeekS(*MemoryID), 0) = 0
Bad parameter type, number expected instead of string. Try this:

Code: Select all

temp.s = PeekS(*MemoryID)
If CallFunctionFast(*F3, @devinst.l, @temp, 0) = 0
I tried the code with two flash drives. The code removed them both. The point should be the removal of one, user specific, drive.
The bad with this code is parameter i at:

Code: Select all

While SetupDiEnumDeviceInfo_(hDeviceInfoSet, i, @DeviceInfoData)
In first case i was 175 and in the second was 176. I think that there is no easy way to know the handle of the drive just before running the above command.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4996
Joined: Sun Apr 12, 2009 6:27 am

Re: Eject USB drive

Post by RASHAD »

@doctorized
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

Updated
Last edited by RASHAD on Sun Jan 17, 2010 5:03 pm, edited 1 time in total.
Egypt my love
User avatar
GeBonet
Enthusiast
Enthusiast
Posts: 135
Joined: Fri Apr 04, 2008 6:20 pm
Location: Belgium

Re: Eject USB drive

Post by GeBonet »

Hello,
doctorized wrote:
GeBonet wrote:One day I found this code I do not know who :cry: , but he does his work :wink:
Your code seems to work fine but after the messagerequester appears saying "device can be safely removed.",
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.
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!
I have no problem with this procedure works.
Sorry for my english :wink: ! (Windows Xp, Vista and Windows 7, Windows 10)
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Re: Eject USB drive

Post by Psychophanta »

eJan wrote:I've found 'Remove all USBSTORs' - which should be updated to 4.4
Updated:

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)
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
donSHAYA
User
User
Posts: 95
Joined: Wed Mar 25, 2009 9:57 am

Re: Eject USB drive

Post by donSHAYA »

I have tried all those codes, none of them works for ejecting one specified device.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Re: Eject USB drive

Post by Psychophanta »

donSHAYA wrote:I have tried all those codes, none of them works for ejecting one specified device.
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. :?
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Eject USB drive

Post by doctorized »

RASHAD wrote:@doctorized
Will you please check the next snippet?
Updated
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
PureBasic Expert
PureBasic Expert
Posts: 4996
Joined: Sun Apr 12, 2009 6:27 am

Re: Eject USB drive

Post by RASHAD »

@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
Egypt my love
User avatar
Michael Vogel
Addict
Addict
Posts: 2821
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Eject USB drive

Post by Michael Vogel »

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
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: Eject USB drive

Post by doctorized »

@ 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."
Post Reply