Results 1 to 10 of 10

Thread: Safely Remove USB Flash Drive

  1. #1

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Safely Remove USB Flash Drive

    Thanks to rm_03 for linking this solution. I pared down the German code to the barest essentials. This will be included in my XP library next time I update it, but until then:
    vb Code:
    1. Option Explicit
    2.  
    3. Private Declare Function CM_Get_DevNode_Status Lib "setupapi.dll" (lStatus As Long, lProblem As Long, ByVal hDevice As Long, ByVal dwFlags As Long) As Long
    4. Private Declare Function CM_Get_Parent Lib "setupapi.dll" (hParentDevice As Long, ByVal hDevice As Long, ByVal dwFlags As Long) As Long
    5. Private Declare Function CM_Locate_DevNodeA Lib "setupapi.dll" (hDevice As Long, ByVal lpDeviceName As Long, ByVal dwFlags As Long) As Long
    6. Private Declare Function CM_Request_Device_EjectA Lib "setupapi.dll" (ByVal hDevice As Long, lVetoType As Long, ByVal lpVetoName As Long, ByVal cbVetoName As Long, ByVal dwFlags As Long) As Long
    7. Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    8. Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
    9. Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpszValueName As String, ByVal lpdwReserved As Long, lpdwType As Long, lpData As Any, lpcbData As Long) As Long
    10.  
    11. ' Safely remove USB flash drive
    12. Public Function SafelyRemove(ByVal pstrDrive As String) As Boolean
    13.     Const DN_REMOVABLE = &H4000
    14.     Dim strDeviceInstance As String
    15.     Dim lngDevice As Long
    16.     Dim lngStatus As Long
    17.     Dim lngProblem As Long
    18.     Dim lngVetoType As Long
    19.     Dim strVeto As String * 255
    20.    
    21.     pstrDrive = UCase$(Left$(pstrDrive, 1)) & ":"
    22.     strDeviceInstance = StrConv(GetDeviceInstance(pstrDrive), vbFromUnicode)
    23.     If CM_Locate_DevNodeA(lngDevice, StrPtr(strDeviceInstance), 0) = 0 Then
    24.         If CM_Get_DevNode_Status(lngStatus, lngProblem, lngDevice, 0) = 0 Then
    25.             Do While Not (lngStatus And DN_REMOVABLE) > 0
    26.                 If CM_Get_Parent(lngDevice, lngDevice, 0) <> 0 Then Exit Do
    27.                 If CM_Get_DevNode_Status(lngStatus, lngProblem, lngDevice, 0) <> 0 Then Exit Do
    28.             Loop
    29.             If (lngStatus And DN_REMOVABLE) > 0 Then SafelyRemove = (CM_Request_Device_EjectA(lngDevice, lngVetoType, StrPtr(strVeto), 255, 0) = 0)
    30.         End If
    31.     End If
    32. End Function
    33.  
    34. Private Function GetDeviceInstance(pstrDrive As String) As String
    35.     Const HKEY_LOCAL_MACHINE = &H80000002
    36.     Const KEY_QUERY_VALUE = &H1
    37.     Const REG_BINARY = &H3
    38.     Const ERROR_SUCCESS = 0&
    39.     Dim strKey As String
    40.     Dim strValue As String
    41.     Dim lngHandle As Long
    42.     Dim lngType As Long
    43.     Dim strBuffer As String
    44.     Dim lngLen As Long
    45.     Dim bytArray() As Byte
    46.    
    47.     strKey = "SYSTEM\MountedDevices"
    48.     strValue = "\DosDevices\" & pstrDrive
    49.     If RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, 0&, KEY_QUERY_VALUE, lngHandle) = ERROR_SUCCESS Then
    50.         If RegQueryValueEx(lngHandle, strValue, 0&, lngType, 0&, lngLen) = 234 Then
    51.             If lngType = REG_BINARY Then
    52.                 strBuffer = Space$(lngLen)
    53.                 If RegQueryValueEx(lngHandle, strValue, 0&, 0&, ByVal strBuffer, lngLen) = ERROR_SUCCESS Then
    54.                     If lngLen > 0 Then
    55.                         ReDim bytArray(lngLen - 1)
    56.                         bytArray = Left$(strBuffer, lngLen)
    57.                         strBuffer = StrConv(bytArray, vbFromUnicode)
    58.                         Erase bytArray
    59.                         If Left$(strBuffer, 4) = "\??\" Then
    60.                             strBuffer = Mid$(strBuffer, 5, InStr(1, strBuffer, "{") - 6)
    61.                             GetDeviceInstance = Replace(strBuffer, "#", "\")
    62.                         End If
    63.                     End If
    64.                 End If
    65.             End If
    66.         End If
    67.         RegCloseKey lngHandle
    68.     End If
    69. End Function
    Sample usage:
    Code:
    If SafelyRemove("F:") Then
        MsgBox "Safe to remove", vbInformation, "Notice"
    End If
    Last edited by Ellis Dee; Jun 22nd, 2008 at 11:42 AM.

  2. #2
    New Member
    Join Date
    May 2009
    Posts
    8

    Re: Safely Remove USB Flash Drive

    Dear Ellis Dee and Others,
    It been a month for me searching for how to safely remove USB drive using VB.net. I found no place better than vbforums.com for VB.net. So, thank you all for everything your doing here.

    Ellis Dee, the code above looks very neat code but for some reason I can't get it run. I use VB express 2008 and it gives errors which you can see in RED:

    Code:
    Private Declare Function CM_Get_DevNode_Status Lib "setupapi.dll" (lStatus As Long, lProblem As Long, ByVal hDevice As Long, ByVal dwFlags As Long) As Long
    Private Declare Function CM_Get_Parent Lib "setupapi.dll" (hParentDevice As Long, ByVal hDevice As Long, ByVal dwFlags As Long) As Long
    Private Declare Function CM_Locate_DevNodeA Lib "setupapi.dll" (hDevice As Long, ByVal lpDeviceName As Long, ByVal dwFlags As Long) As Long
    Private Declare Function CM_Request_Device_EjectA Lib "setupapi.dll" (ByVal hDevice As Long, lVetoType As Long, ByVal lpVetoName As Long, ByVal cbVetoName As Long, ByVal dwFlags As Long) As Long
    Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
    Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpszValueName As String, ByVal lpdwReserved As Long, lpdwType As Long, lpData As Any, lpcbData As Long) As Long
    
    ' Safely remove USB flash drive
    Public Function SafelyRemove(ByVal pstrDrive As String) As Boolean
        Const DN_REMOVABLE = &H4000
        Dim strDeviceInstance As String
        Dim lngDevice As Long
        Dim lngStatus As Long
        Dim lngProblem As Long
        Dim lngVetoType As Long
        Dim strVeto As String * 255
        
        pstrDrive = UCase$(Left$(pstrDrive, 1)) & ":"
        strDeviceInstance = StrConv(GetDeviceInstance(pstrDrive), vbFromUnicode)
        If CM_Locate_DevNodeA(lngDevice, StrPtr(strDeviceInstance), 0) = 0 Then
            If CM_Get_DevNode_Status(lngStatus, lngProblem, lngDevice, 0) = 0 Then
                Do While Not (lngStatus And DN_REMOVABLE) > 0
                    If CM_Get_Parent(lngDevice, lngDevice, 0) <> 0 Then Exit Do
                    If CM_Get_DevNode_Status(lngStatus, lngProblem, lngDevice, 0) <> 0 Then Exit Do
                Loop
                If (lngStatus And DN_REMOVABLE) > 0 Then SafelyRemove = (CM_Request_Device_EjectA(lngDevice, lngVetoType, StrPtr(strVeto), 255, 0) = 0)
            End If
        End If
    End Function
    
    Private Function GetDeviceInstance(pstrDrive As String) As String
        Const HKEY_LOCAL_MACHINE = &H80000002
        Const KEY_QUERY_VALUE = &H1
        Const REG_BINARY = &H3
        Const ERROR_SUCCESS = 0&
        Dim strKey As String
        Dim strValue As String
        Dim lngHandle As Long
        Dim lngType As Long
        Dim strBuffer As String
        Dim lngLen As Long
        Dim bytArray() As Byte
        
        strKey = "SYSTEM\MountedDevices"
        strValue = "\DosDevices\" & pstrDrive
        If RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, 0&, KEY_QUERY_VALUE, lngHandle) = ERROR_SUCCESS Then
            If RegQueryValueEx(lngHandle, strValue, 0&, lngType, 0&, lngLen) = 234 Then
                If lngType = REG_BINARY Then
                    strBuffer = Space$(lngLen)
                    If RegQueryValueEx(lngHandle, strValue, 0&, 0&, ByVal strBuffer, lngLen) = ERROR_SUCCESS Then
                        If lngLen > 0 Then
                            ReDim bytArray(lngLen - 1)
                            bytArray = Left$(strBuffer, lngLen)
                            strBuffer = StrConv(bytArray, vbFromUnicode)
                            Erase bytArray
                            If Left$(strBuffer, 4) = "\??\" Then
                                strBuffer = Mid$(strBuffer, 5, InStr(1, strBuffer, "{") - 6)
                                GetDeviceInstance = Replace(strBuffer, "#", "\")
                            End If
                        End If
                    End If
                End If
            End If
            RegCloseKey lngHandle
        End If
    End Function
    I'm totally a beginner in VB all I need is to make this code works as it should be.

    thank you very much.

  3. #3

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Safely Remove USB Flash Drive

    This is VB6 code. You need .NET code.

  4. #4
    Lively Member SNIPER.PS's Avatar
    Join Date
    Dec 2009
    Posts
    96

    Re: Safely Remove USB Flash Drive

    thanks

  5. #5
    Junior Member
    Join Date
    Aug 2010
    Posts
    26

    Re: Safely Remove USB Flash Drive

    :thumbs:

  6. #6
    New Member
    Join Date
    Nov 2010
    Posts
    2

    Thumbs up Re: Safely Remove USB Flash Drive

    Thanks Ellis; Well done!

  7. #7
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,344

    Re: Safely Remove USB Flash Drive

    @ Ellis Dee

    Could you modify the above source to detect which processes are still using the usb device if any before running the above code? If so how?
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  8. #8

    Thread Starter
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Safely Remove USB Flash Drive

    That's beyond my ability. I'd recommend posting a question in the main forum asking how to identify which processes are using a flash drive. I could name at least a couple people still posting who might have the expertise.

  9. #9
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,344

    Re: Safely Remove USB Flash Drive

    Quote Originally Posted by Ellis Dee View Post
    That's beyond my ability. I'd recommend posting a question in the main forum asking how to identify which processes are using a flash drive. I could name at least a couple people still posting who might have the expertise.
    I have started a new thread in the Visual Basic 6 section on the subject.
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  10. #10
    Junior Member
    Join Date
    Aug 2010
    Posts
    26

    Re: Safely Remove USB Flash Drive

    so which 1 is an updated code?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width