Solved

Replicate Computer / Disk Management eject procedure (in script)

Posted on 2009-06-29
5
823 Views
Last Modified: 2014-03-21
Within Disk Management (of Computer Management), I'd like to write a script, .bat, .vbs, visual basic etc, that will replicate the eject feature.

Ejecting via Windows Explorer won't work. The USB cartridge for backups that I'm using, will only eject via the computer management eject procedure, so I'd like to script this.

Using windows 2008... and have VB6.

Can anyone help?
Thanks.
0
Comment
Question by:gary_sland
  • 4
5 Comments
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 24742934
I am pretty syre they both perform the same routine.

Here is how you would eject a removable device using API.

1) Open a (volume) handle to the device using CreateFile()
2) Try to lock the volume using FSCTL_LOCK_VOLUME
3) If the call above succeeds it's safe to dismount the volume using FSCTL_DISMOUNT_VOLUME
4) You want to make sure there is no (prevent removal locks) on the volume so you call IOCTL_STORAGE_MEDIA_REMOVAL and set the structure parameter to False.
5) Use IOCTL_STORAGE_EJECT_MEDIA to eject the device.
6) Close the volume handle.

This is how all of them work but I will take a wild guess and say that maybe explorer doesn't go as far to disable any ejection locks but the disk managment eject option does.
0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 500 total points
ID: 24743057
Here is an example I wrote that should eject a removable device just like explorer or disk managment. This is an interesting question and I want to know myself if there is any difference between them. Give this a try and keep me updated! :)

Add code to a (module.bas)
Usage: SafeEject "e:\"
Option Explicit
' safe eject media vb6.
' author's name
 
Private Type PREVENT_MEDIA_REMOVAL
PreventMediaRemoval As Long
End Type
 
Private Const INVALID_HANDLE_VALUE As Long = (-1)
Private Const FSCTL_LOCK_VOLUME As Long = &H90018
Private Const FSCTL_UNLOCK_VOLUME As Long = &H9001C
Private Const FSCTL_DISMOUNT_VOLUME As Long = &H90020
Private Const IOCTL_STORAGE_MEDIA_REMOVA<wbr ></wbr>L As Long = &H2D4804
Private Const IOCTL_STORAGE_EJECT_MEDIA As Long = &H2D4808
Private Const OPEN_EXISTING As Long = 3
Private Const GENERIC_READ As Long = &H80000000
Private Const GENERIC_WRITE As Long = &H40000000
Private Const FILE_SHARE_READ As Long = &H1
Private Const FILE_SHARE_WRITE As Long = &H2
Private Const DRIVE_REMOVABLE As Long = 2
Private Const DRIVE_CDROM As Long = 5
 
Private Declare Function DeviceIoControl Lib "kernel32.dll" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, ByVal lpInBuffer As Long, ByVal nInBufferSize As Long, ByVal lpOutBuffer As Long, ByVal nOutBufferSize As Long, lpBytesReturned As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CreateFileW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function GetDriveTypeW Lib "kernel32.dll" (ByVal nDrive As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
 
Sub SafeEject(ByVal szDrive As String)
 
Dim udtPMR As PREVENT_MEDIA_REMOVAL
Dim dwAccess As Long
Dim dwDriveType As Long
Dim hDrive As Long
Dim cb As Long
 
' Check if trailing backslash exists.
If InStr(szDrive, "\") = 0 Then
  Debug.Print "Please specify a full drive letter. ex. X:\"
  Exit Sub
End If
' Backslash is required for this call.
dwDriveType = GetDriveTypeW(StrPtr(szDri<wbr ></wbr>ve))
' Check if this type of drive is removable.
Select Case dwDriveType
  Case DRIVE_REMOVABLE
    dwAccess = GENERIC_READ Or GENERIC_WRITE
  Case DRIVE_CDROM
    dwAccess = GENERIC_READ
  Case Else
    Debug.Print "This type of volume is not a removable device."
    Exit Sub
End Select
' Remove backslash.
szDrive = Replace$(szDrive, "\", vbNullString)
' This must not have a backslash.(open volume for direct access might need admin rights on vista/win7)
hDrive = CreateFileW(StrPtr("\\.\" & szDrive), dwAccess, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
' checksum
If hDrive = INVALID_HANDLE_VALUE Then
  Debug.Print "Bad handle. (try:run as admin)"
  Exit Sub
End If
' Attempt to lock the volume for safe ejection.
If DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, 0, 0, 0, 0, cb, 0) Then
  ' DISMOUNT the volume and flush cache and any associations on the systems.
  Call DeviceIoControl(hDrive, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0, cb, 0)
  ' Make sure there is no prevent removal locks.
  udtPMR.PreventMediaRemoval<wbr ></wbr> = 0
  Call DeviceIoControl(hDrive, IOCTL_STORAGE_MEDIA_REMOVA<wbr ></wbr>L, VarPtr(udtPMR), Len(udtPMR), 0, 0, cb, 0)
  ' Eject the media.
  Call DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA,<wbr ></wbr> 0, 0, 0, 0, cb, 0)
Else
  ' You could still force the ejection here but any
  ' data in process would get corrupted.
  Debug.Print "It's not safe to eject this media."
End If
' Close volume handle.
CloseHandle hDrive
 
End Sub

Open in new window

0
 

Author Closing Comment

by:gary_sland
ID: 31597917
Hi. Many thanks for your help. This worked! I really thought I'd be stuck with this problem. There does seem to be some difference between explorer and disk management, perhaps as you say it's to do the locks.
Many thanks though!
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 24747548
Great. So it seems that the computer managment is doing some additional work than explorer thats interesting.

I was messing around with the (Safe Remove Hardware option) and I noticed that it actually updates explorer and removes the drive from the explorer list. Which the code above doesn't do so in addition the safely remove hardware goes even one step further and updates explorer.

Here is how it works.

Option Explicit
 

Private Const SHCNE_DRIVEREMOVED As Long = &H80

Private Const SHCNF_PATHW As Long = 5
 

Private Declare Function SHChangeNotify Lib "shell32.dll" (ByVal wEventId As Long, _

  ByVal uFlags As Long, ByVal dwItem1 As Long, ByVal dwItem2 As Long) As Long
 

Private Sub Update(ByVal szDrive As String)

' Do some magic here.(must have trailing backslash)

Call SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATHW, StrPtr(szDrive), 0)

End Sub

Open in new window

0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 24747565
Just to make sure, you would call the above method after you call the eject part.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now