matthew1471
asked on
Safely Remove Hardware
I have just spent a good hour or two googling for this and have returned varying results with varying words
I want to run whatever API the "Safely Remove Hardware" uses to remove devices... I know there is always "rundll32.exe shell32.dll,Control_RunDLL hotplug.dll" and then I could use SendKeys.. I'll accept that as an answer if someone can maybe get that to work (removing a device using Sendkeys)
Top marks goes to whoever can somehow get me to perform the exact equivallant of "Safely Remove Hardware" using Visual Basic 6
I have a flash drive, I want to remove it so I can safely unplug it.
Many google results returned people asking the same question
Keywords Tried : Device Removal, API, "Safely Remove Hardware", Hotplug.dll, Eject Device, Unplug Device, Unplug Hardware, Flash Drive, Remove Device, Stop Device, shell32.dll,Control_RunDLL hotplug.dll, API Spy, API Viewer, devcon.exe, Programmatically Safely Remove Hardware, Remove Hardware from batch file ... etc etc
I want to run whatever API the "Safely Remove Hardware" uses to remove devices... I know there is always "rundll32.exe shell32.dll,Control_RunDLL
Top marks goes to whoever can somehow get me to perform the exact equivallant of "Safely Remove Hardware" using Visual Basic 6
I have a flash drive, I want to remove it so I can safely unplug it.
Many google results returned people asking the same question
Keywords Tried : Device Removal, API, "Safely Remove Hardware", Hotplug.dll, Eject Device, Unplug Device, Unplug Hardware, Flash Drive, Remove Device, Stop Device, shell32.dll,Control_RunDLL
ASKER
Hey 2Angel, Thanks for offering your assistance :)
Unfortunatly the first link only ejects a CD or device with data marked as removable, for a pen drive this doesnt work... it doesnt mark the hardware as now removable..
The second link requires me to know the code to send to the device...and it isn't really a device control to remove itself Im imagining, but I may be wrong
the close handle is way beyond my depth (aka I dont understand it).. It doesn't look useable but I may be mistaken
apparantly what im looking for is something like devcon.exe but that cant be redistributed and to aquire the source code to it I have to be an MSDN subscriber with access to the DDK (Driver Development Kit) very posh for something so simple :P
I tried using an API Spy, rather unsuccessfully though, is there maybe some way of easily working out what HotPlug.dll calls on? I know it interfaces with APIs I think..
Sorry to be a pain, this is asked about so much on the internet
Unfortunatly the first link only ejects a CD or device with data marked as removable, for a pen drive this doesnt work... it doesnt mark the hardware as now removable..
The second link requires me to know the code to send to the device...and it isn't really a device control to remove itself Im imagining, but I may be wrong
the close handle is way beyond my depth (aka I dont understand it).. It doesn't look useable but I may be mistaken
apparantly what im looking for is something like devcon.exe but that cant be redistributed and to aquire the source code to it I have to be an MSDN subscriber with access to the DDK (Driver Development Kit) very posh for something so simple :P
I tried using an API Spy, rather unsuccessfully though, is there maybe some way of easily working out what HotPlug.dll calls on? I know it interfaces with APIs I think..
Sorry to be a pain, this is asked about so much on the internet
Hi,
Well, I hope this is what you are looking for (because this is seems to be very simple so I am not sure this is what you looked for). Please place on a form a command button "Command1" and paste this code:
Private Sub Command1_Click()
Shell "RUNDLL32.EXE shell32.dll,Control_RunDLL
SendKeys "{DEL}"
End Sub
The first line is bringing up the "Safely Remove Hardware" window (using the HotPulg.dll).
The secund line is sending the key "Delete" to bring up the "Stop a Hardware Device" window to select the device to be stop from that window list.
Now you can add lines to send keys to select the device and "Press" OK (AltO).
Hope this is it.....
Good luck and have fun!
2Angel
ASKER
Say I had 3 devices in there, how would It know which one to kill? I kind of wanted a way through APIs to hide it from the user.. (As HotPlug is just an interface for device manager)
Sorry if your not sure what im looking for, I'm not very good at explaining things... basically I have a PenDrive, I want to make a little manager for it, on the manager I want a button "Unload" when you click that button it then makes it "Safe" to just unplug the drive... If you "just unplug" when it's accessing data or you have it set in a certain way unsafely unplugging it can cause a blue screen.. I want the program to safely remove it without having to keep manually doing it from the tray.. I know HotPlug.dll is a helper app for DeviceManager, the process should be possible, but I don't know enough about device programming nor API spying to be able to find out how to do it..
There are many posts on Google asking to do this exact same thing (Marking a device safe for removal in windows) "Programmatically Using "Safely Remove Hardware" to remove a device"
Sorry if your not sure what im looking for, I'm not very good at explaining things... basically I have a PenDrive, I want to make a little manager for it, on the manager I want a button "Unload" when you click that button it then makes it "Safe" to just unplug the drive... If you "just unplug" when it's accessing data or you have it set in a certain way unsafely unplugging it can cause a blue screen.. I want the program to safely remove it without having to keep manually doing it from the tray.. I know HotPlug.dll is a helper app for DeviceManager, the process should be possible, but I don't know enough about device programming nor API spying to be able to find out how to do it..
There are many posts on Google asking to do this exact same thing (Marking a device safe for removal in windows) "Programmatically Using "Safely Remove Hardware" to remove a device"
Hi,
I have 3 Q:
1. What is your OS?
2. What is the name or/and the letter of the device?
3. Is it 3rd on the list of "Stop a Hardware Device"?
I'll try to help you with 2 diferent approach....
Best regards
ASKER
1. Windows XP Professional SP2
2. It Varies but it's currently F:\
3. It is third, the card reader has gone first and the external HDD has gone second...
The HotPlug.dll must be calling some APIs maybe the "SetupAPI" but I can't for the life of me find out what or how (Most of Micrsofts DDK is based on C# programming anyway which I don't understand)
2. It Varies but it's currently F:\
3. It is third, the card reader has gone first and the external HDD has gone second...
The HotPlug.dll must be calling some APIs maybe the "SetupAPI" but I can't for the life of me find out what or how (Most of Micrsofts DDK is based on C# programming anyway which I don't understand)
Hi,
I am sorry for time past I hadn't got the time...
I wanted to go for a different approach but again the time...
I thought to read the content of the window "Stop a Hardware Device" and then search the text for your device, determin in which line it is and then to point this line ( by SendKey "{DOWN}" ) and clikc the OK button.
Second thought I had, is to use the "Device Manager" window and to disable the device....
So, for now I have for you a "SendKey" solution that will work for you and maybe you will devlope a different approach.
Private Sub Command1_Click()
Shell "RUNDLL32.EXE shell32.dll,Control_RunDLL hotplug.dll"
SendKeys "{DEL}", True
SendKeys "{TAB 2}", True
SendKeys "{DOWN 3}", True
SendKeys "{ENTER}", True
End Sub
Thats working for sure and stops the 3rd device....
Ones again I'm sorry and if I will have the time for it I will send to you additional solution.
Have fun & luck!
I am sorry for time past I hadn't got the time...
I wanted to go for a different approach but again the time...
I thought to read the content of the window "Stop a Hardware Device" and then search the text for your device, determin in which line it is and then to point this line ( by SendKey "{DOWN}" ) and clikc the OK button.
Second thought I had, is to use the "Device Manager" window and to disable the device....
So, for now I have for you a "SendKey" solution that will work for you and maybe you will devlope a different approach.
Private Sub Command1_Click()
Shell "RUNDLL32.EXE shell32.dll,Control_RunDLL
SendKeys "{DEL}", True
SendKeys "{TAB 2}", True
SendKeys "{DOWN 3}", True
SendKeys "{ENTER}", True
End Sub
Thats working for sure and stops the 3rd device....
Ones again I'm sorry and if I will have the time for it I will send to you additional solution.
Have fun & luck!
ASKER
Hi there sorry for the time taken to reply, i'm still testing your method, but i'm having a job getting it to fully work..
1. There might not be more than 3 devices there might be more
2. It wont for the life of it accept and escape or a ALT & F4 command with either waits on or off...
However I found this VERY interesting, (http://www.webtropy.com/articles/dll-api.aspx?dll=hotplug)
[ ] HOTPLUG.DLL
Import Ordinal Hint Function Entry Point
------ ----------- ----------- -------------------------- ----- -----------
Export Ordinal Hint Function Entry Point
------ ----------- ----------- -------------------------- ----- -----------
[C ] 1 (0x0001) 0 (0x0000) CPlApplet 0x0000534D
[C ] 2 (0x0002) 1 (0x0001) CreateLocalServerW 0x000026A6
[C ] 12 (0x000C) 2 (0x0002) DllCanUnloadNow 0x000025BF
[C ] 13 (0x000D) 3 (0x0003) DllGetClassObject 0x000025CB
[C ] 14 (0x000E) 4 (0x0004) DllRegisterServer 0x000025E4
[C ] 15 (0x000F) 5 (0x0005) DllUnregisterServer 0x000025F3
[C ] 3 (0x0003) 6 (0x0006) HotPlugDeviceTree 0x00004FD0
[C ] 4 (0x0004) 7 (0x0007) HotPlugDriverBlockedW 0x000052C1
[C ] 5 (0x0005) 8 (0x0008) HotPlugEjectDevice 0x0000504B
[C ] 6 (0x0006) 9 (0x0009) HotPlugEjectVetoedW 0x00005410
[C ] 7 (0x0007) 10 (0x000A) HotPlugHibernateVetoedW 0x0000542C
[C ] 8 (0x0008) 11 (0x000B) HotPlugRemovalVetoedW 0x00005402
[C ] 9 (0x0009) 12 (0x000C) HotPlugSafeRemovalNotifica tionW 0x00005141
[C ] 10 (0x000A) 13 (0x000D) HotPlugStandbyVetoedW 0x0000541E
[C ] 11 (0x000B) 14 (0x000E) HotPlugWarmEjectVetoedW 0x0000543A
************************** *| Module Dependency Tree |*********
* *
* Legend: F Forwarded Module ? Missing Module 6 64-bit Module *
* D Delay Load Module ! Invalid Module *
* * Dynamic Module E Import/Export Mismatch or Load Failure *
* ^ Duplicate Module *
* *
* O Ordinal Function E Import/Export Error F Forwarded Function *
* C C Function R Called At Least Once * Dynamic Function *
* + C++ Function *
* *
************************** ********** ********** **********
can someone PLEASE tell me how to call the "HotPlugEjectDevice" API in its correct syntax
1. There might not be more than 3 devices there might be more
2. It wont for the life of it accept and escape or a ALT & F4 command with either waits on or off...
However I found this VERY interesting, (http://www.webtropy.com/articles/dll-api.aspx?dll=hotplug)
[ ] HOTPLUG.DLL
Import Ordinal Hint Function Entry Point
------ ----------- ----------- --------------------------
Export Ordinal Hint Function Entry Point
------ ----------- ----------- --------------------------
[C ] 1 (0x0001) 0 (0x0000) CPlApplet 0x0000534D
[C ] 2 (0x0002) 1 (0x0001) CreateLocalServerW 0x000026A6
[C ] 12 (0x000C) 2 (0x0002) DllCanUnloadNow 0x000025BF
[C ] 13 (0x000D) 3 (0x0003) DllGetClassObject 0x000025CB
[C ] 14 (0x000E) 4 (0x0004) DllRegisterServer 0x000025E4
[C ] 15 (0x000F) 5 (0x0005) DllUnregisterServer 0x000025F3
[C ] 3 (0x0003) 6 (0x0006) HotPlugDeviceTree 0x00004FD0
[C ] 4 (0x0004) 7 (0x0007) HotPlugDriverBlockedW 0x000052C1
[C ] 5 (0x0005) 8 (0x0008) HotPlugEjectDevice 0x0000504B
[C ] 6 (0x0006) 9 (0x0009) HotPlugEjectVetoedW 0x00005410
[C ] 7 (0x0007) 10 (0x000A) HotPlugHibernateVetoedW 0x0000542C
[C ] 8 (0x0008) 11 (0x000B) HotPlugRemovalVetoedW 0x00005402
[C ] 9 (0x0009) 12 (0x000C) HotPlugSafeRemovalNotifica
[C ] 10 (0x000A) 13 (0x000D) HotPlugStandbyVetoedW 0x0000541E
[C ] 11 (0x000B) 14 (0x000E) HotPlugWarmEjectVetoedW 0x0000543A
**************************
* *
* Legend: F Forwarded Module ? Missing Module 6 64-bit Module *
* D Delay Load Module ! Invalid Module *
* * Dynamic Module E Import/Export Mismatch or Load Failure *
* ^ Duplicate Module *
* *
* O Ordinal Function E Import/Export Error F Forwarded Function *
* C C Function R Called At Least Once * Dynamic Function *
* + C++ Function *
* *
**************************
can someone PLEASE tell me how to call the "HotPlugEjectDevice" API in its correct syntax
ASKER
The solution provided only works if I have exactly 3 devices (or however many page downs I sent) This is not useful in a production enviroment (or any other enviroment where I may have a different number of USB devices plugged in)
I was hoping for a solution whereby the keys would be sent to the program and it would shut down that exact device, the solution provided is more of a manual way...
Could an administrator please advise me on what to do? Should I accept one or class it as a problem which is not yet fully solved (Seen as it wont work in any cases where It doesnt go to the bottom of the list)?
I was hoping for a solution whereby the keys would be sent to the program and it would shut down that exact device, the solution provided is more of a manual way...
Could an administrator please advise me on what to do? Should I accept one or class it as a problem which is not yet fully solved (Seen as it wont work in any cases where It doesnt go to the bottom of the list)?
quote:
>>>>I could use SendKeys.. I'll accept that as an answer if someone can maybe get that to work (removing a device using Sendkeys)
well, it's worknig - but somtimes there are things that can't be perfect...
>>>>I could use SendKeys.. I'll accept that as an answer if someone can maybe get that to work (removing a device using Sendkeys)
well, it's worknig - but somtimes there are things that can't be perfect...
ASKER
I accept it does work, but if I add another device to the system it refuses to work.. if I use someone elses' computer to run the pen drive program it will refuse to work...
However it does work provided I know the order in the list it is at which is why I hope to award you points for your effort :)
I hope this has not caused bad feeling and that you understand that I am (although not having found the perfect solution) I am very greatful you submitted your comments..
Is there maybe a way of getting the program to "Read off" the screen as such, e.g. in the window "Safely Remove Hardware", locate the text "USB Mass Storage Device" click it and hit enter? This would then be our solution
Matt
However it does work provided I know the order in the list it is at which is why I hope to award you points for your effort :)
I hope this has not caused bad feeling and that you understand that I am (although not having found the perfect solution) I am very greatful you submitted your comments..
Is there maybe a way of getting the program to "Read off" the screen as such, e.g. in the window "Safely Remove Hardware", locate the text "USB Mass Storage Device" click it and hit enter? This would then be our solution
Matt
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Sorry for the delay, I looked at the above and it looks impressive :) but understanding it is another problem :P
Thanks for your help anyway, I feel so bad not using your solution but don't feel disheartened, hundreds of users on the internet have asked this question and virtually no1 has a valid answer, I was taking a peek at some C# source code (I can't program a single thing in C# but was willing to maybe try and hack up a simple EXE to do it)
However the C# wouldnt compile because I havn't spent a few grand and bought the Microsoft Drivers Developer kit..
Thanks for your help anyway, I feel so bad not using your solution but don't feel disheartened, hundreds of users on the internet have asked this question and virtually no1 has a valid answer, I was taking a peek at some C# source code (I can't program a single thing in C# but was willing to maybe try and hack up a simple EXE to do it)
However the C# wouldnt compile because I havn't spent a few grand and bought the Microsoft Drivers Developer kit..
Thank you !
Good luck....
Dear Matthew:
If it's ok with you to use VB, I found the perfect solution(!). Here it is:
Place the following code into the general declarations area of a bas module:
Option Explicit
Public Const IOCTL_STORAGE_EJECT_MEDIA As Long = &H2D4808
Public Const IOCTL_STORAGE_LOAD_MEDIA As Long = &H2D480C
Public Const DRIVE_REMOVABLE = 2
Public Const DRIVE_CDROM = 5
Public Const INVALID_HANDLE_VALUE As Long = -1&
Public Const GENERIC_READ As Long = &H80000000
Public Const FILE_SHARE_READ As Long = &H1
Public Const FILE_SHARE_WRITE As Long = &H2
Public Const FILE_ANY_ACCESS As Long = &H0
Public Const FILE_READ_ACCESS As Long = &H1
Public Const FILE_WRITE_ACCESS As Long = &H2
Public Const OPEN_EXISTING As Long = 3
Public Const IOCTL_STORAGE_MEDIA_REMOVA
Public Type PREVENT_MEDIA_REMOVAL
PreventMediaRemoval As Byte
End Type
Public Declare Function GetLogicalDriveStrings Lib "kernel32" _
Alias "GetLogicalDriveStringsA" _
(ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Public Declare Function GetDriveType Lib "kernel32" _
Alias "GetDriveTypeA" _
(ByVal lpRootPathName As String) As Long
Public Declare Function DeviceIoControl Lib "kernel32" _
(ByVal hDevice As Long, _
ByVal dwIoControlCode As Long, _
lpInBuffer As Any, _
ByVal nInBufferSize As Long, _
lpOutBuffer As Any, _
ByVal nOutBufferSize As Long, _
lpBytesReturned As Long, _
lpOverlapped As Any) As Long
Public Declare Function CreateFile Lib "kernel32" _
Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
lpSecurityAttributes As Any, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Public Function DeviceLock(sDrive As String, fLock As Boolean) As Boolean
Dim hDevice As Long
Dim PMR As PREVENT_MEDIA_REMOVAL
Dim bytesReturned As Long
Dim success As Long
'the drive letter has to be passed
'to CreateFile without a trailing slash (ie 'G:')
sDrive = UnQualifyPath(sDrive)
'obtain a handle to the device
'using the correct device syntax
hDevice = CreateFile("\\.\" & sDrive, _
GENERIC_READ, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
ByVal 0&, _
OPEN_EXISTING, _
0&, 0&)
If hDevice <> INVALID_HANDLE_VALUE Then
'assign the fLock value to the
'PREVENT_MEDIA_REMOVAL type
PMR.PreventMediaRemoval = CByte(Abs(fLock))
'If the operation succeeds,
'DeviceIoControl returns a nonzero value
success = DeviceIoControl(hDevice, _
IOCTL_STORAGE_MEDIA_REMOVA
PMR, _
Len(PMR), _
ByVal 0&, _
0&, _
bytesReturned, _
ByVal 0&)
End If
Call CloseHandle(hDevice)
DeviceLock = success
End Function
Private Function UnQualifyPath(ByVal sPath As String) As String
'removes any trailing slash from the path
sPath = Trim$(sPath)
If Right$(sPath, 1) = "\" Then
UnQualifyPath = Left$(sPath, Len(sPath) - 1)
Else
UnQualifyPath = sPath
End If
End Function
Public Function DeviceSetMedia(sDrive As String, ctrlCode As Long) As Boolean
Dim hDevice As Long
Dim bytesReturned As Long
Dim success As Long
'the drive letter has to be passed
'without a trailing slash (ie 'G:')
sDrive = UnQualifyPath(sDrive)
'obtain a handle to the device
hDevice = CreateFile("\\.\" & sDrive, _
GENERIC_READ, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
ByVal 0&, _
OPEN_EXISTING, _
0&, 0&)
If hDevice <> INVALID_HANDLE_VALUE Then
'If the operation succeeds,
'DeviceIoControl returns zero
success = DeviceIoControl(hDevice, _
ctrlCode, _
0&, _
0&, _
ByVal 0&, _
0&, _
bytesReturned, _
ByVal 0&) = 0
End If
Call CloseHandle(hDevice)
DeviceSetMedia = success
End Function
Add a listbox (List1), a command button array (Command1(0), Command1(1)), and a label (Label1) to a form. A third button (End) is optional. add two additional command buttons in a control array (Command2(0), Command2(1)).
Add the following code to the form:
Option Explicit
Private Sub Form_Load()
'load the removable drives and
'disable the command buttons until
'a drive is selected
LoadAvailableDrives List1
Command1(0).Enabled = False
Command1(1).Enabled = False
End Sub
Private Sub List1_Click()
Command1(0).Enabled = List1.ListIndex > -1
Command1(1).Enabled = List1.ListIndex > -1
End Sub
Private Sub Command1_Click(Index As Integer)
Dim fLock As Boolean
Dim result As Boolean
Dim sDrive As String
'nothing to do if a drive's not selected
If List1.ListIndex > -1 Then
'get the selected drive
sDrive = List1.List(List1.ListIndex
'DeviceIoControl requires the
'IOCTL_STORAGE_MEDIA_REMOV
'control code and a Boolean
'indicating the lock state.
'Passing False unlocks the device;
'passing True locks it. This handily
'corresponds to the 0/1 indices of
'the Command button array.
fLock = CBool(Index)
result = DeviceLock(sDrive, fLock)
'display result
If result Then
Select Case Index
Case 0: Label1.Caption = "Device " & sDrive & " is unlocked."
Case 1: Label1.Caption = "Device " & sDrive & " is locked."
End Select
Else
Label1.Caption = "Call failed - perhaps no media in device."
End If
End If
End Sub
Private Sub LoadAvailableDrives(lst As ListBox)
Dim lpBuffer As String
Dim drvType As Long
Dim currDrive As String
'get list of available drives
lpBuffer = GetDriveString()
'Separate the drive strings
'and add to the combo. StripNulls
'will continually shorten the
'string. Loop until a single
'remaining terminating null is
'encountered.
Do Until lpBuffer = Chr(0)
'strip off one drive item
'and check for removable (or CD) status,
'and add to the combo
currDrive = StripNulls(lpBuffer)
drvType = GetDriveType(currDrive)
If (drvType = DRIVE_CDROM) Or _
(drvType = DRIVE_REMOVABLE) Then
lst.AddItem currDrive
End If
Loop
End Sub
Private Function StripNulls(startstr As String) As String
'Take a string separated by chr$(0)
'and split off 1 item, shortening the
'string so next item is ready for removal.
Dim pos As Long
pos = InStr(startstr, Chr$(0))
If pos Then
StripNulls = Mid$(startstr, 1, pos - 1)
startstr = Mid$(startstr, pos + 1, Len(startstr))
End If
End Function
Private Function GetDriveString() As String
'returns of available drives each
'separated by a null
Dim sBuffer As String
'possible 26 drives, three characters each, plus trailing null
sBuffer = Space$(26 * 4)
If GetLogicalDriveStrings(Len
'trim string but do not
'remove trailing null
GetDriveString = Trim$(sBuffer)
End If
End Function
Private Sub Command2_Click(Index As Integer)
Dim sDrive As String
If List1.ListIndex > -1 Then
sDrive = List1.List(List1.ListIndex
Select Case Index
Case 0: Call DeviceSetMedia(sDrive, IOCTL_STORAGE_EJECT_MEDIA)
Case 1: Call DeviceSetMedia(sDrive, IOCTL_STORAGE_LOAD_MEDIA)
End Select
End If
End Sub
Works perfect for me........... Let me know
Have fun
Angel
Hi,
Did you checked the above solution?
Tks
Did you checked the above solution?
Tks
ASKER
"Call failed - perhaps no media in device." when I try to lock the pendrive,
The program you provided is excellent in locking and unlocking devices so media can't be removed, but it doesnt actually remove them
Thanks anyway though for your suggestion :)
The program you provided is excellent in locking and unlocking devices so media can't be removed, but it doesnt actually remove them
Thanks anyway though for your suggestion :)
Hi,
It's working fine for me.
I don't have a pendrive but for all other devices I do have it's "doing the job"...
Well,
BeyBey
It's working fine for me.
I don't have a pendrive but for all other devices I do have it's "doing the job"...
Well,
BeyBey
Hi,
Is this helps?
http://www.mentalis.org/vbexamples/vbexample.php?vbexample=DSDRIVE&category=MISC
Or this?
http://www.mentalis.org/apilist/DeviceIoControl.shtml
Or this?
http://www.mentalis.org/apilist/CloseHandle.shtml