home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / device_inf2048792192007.psc / modDevEject.bas < prev    next >
BASIC Source File  |  2007-02-18  |  6KB  |  151 lines

  1. Attribute VB_Name = "modDevEject"
  2. Option Explicit
  3.  
  4. ' safe ejection of devices (e.g. USB sticks)
  5. '
  6. ' written by Daniel Aue (http://www.activevb.de/)
  7.  
  8. Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
  9. Alias "RegOpenKeyExA" ( _
  10.     ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
  11.     ByVal samDesired As Long, phkResult As Long _
  12. ) As Long
  13.  
  14. Private Declare Function RegCloseKey Lib "advapi32.dll" ( _
  15.     ByVal hKey As Long _
  16. ) As Long
  17.         
  18. Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
  19. Alias "RegQueryValueExA" ( _
  20.     ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _
  21.     lpType As Long, lpData As Any, lpcbData As Any _
  22. ) As Long
  23.  
  24. Private Const HKEY_LOCAL_MACHINE        As Long = &H80000002
  25.  
  26. Private Const KEY_QUERY_VALUE           As Long = &H1
  27. Private Const KEY_ENUMERATE_SUB_KEYS    As Long = &H8
  28. Private Const KEY_NOTIFY                As Long = &H10
  29. Private Const SYNCHRONIZE               As Long = &H100000
  30. Private Const STANDARD_RIGHTS_READ      As Long = &H20000
  31.  
  32. Private Const KEY_READ                  As Long = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
  33.  
  34. Private Const ERROR_SUCCESS             As Long = 0&
  35.  
  36. Private Declare Function CM_Request_Device_EjectA Lib "setupapi.dll" ( _
  37.     ByVal hDevice As Long, lVetoType As Long, lpVetoName As Any, _
  38.     ByVal cbVetoName As Long, ByVal dwFlags As Long _
  39. ) As Long
  40.  
  41. Private Declare Function CM_Locate_DevNodeA Lib "setupapi.dll" ( _
  42.     hDevice As Long, lpDeviceName As Any, ByVal dwFlags As Long _
  43. ) As Long
  44.         
  45. Private Declare Function CM_Get_Device_IDA Lib "setupapi.dll" ( _
  46.     ByVal hDevice As Long, ByVal lpIDBuffer As Long, _
  47.     ByVal cbIDBuffer As Long, ByVal dwFlags As Long _
  48. ) As Long
  49.  
  50. Private Declare Function CM_Get_Device_ID_Size Lib "setupapi.dll" ( _
  51.     ByRef lSize As Long, ByVal hDevice As Long, ByVal dwFlags As Long _
  52. ) As Long
  53.  
  54. Private Declare Function CM_Get_Parent Lib "setupapi.dll" ( _
  55.     hParentDevice As Long, ByVal hDevice As Long, ByVal dwFlags As Long _
  56. ) As Long
  57.         
  58. Private Declare Function CM_Get_Child Lib "setupapi.dll" ( _
  59.     hChildDevice As Long, ByVal hDevice As Long, ByVal dwFlags As Long _
  60. ) As Long
  61.         
  62. Private Declare Function CM_Get_Sibling Lib "setupapi.dll" ( _
  63.     hSiblingDevice As Long, ByVal hDevice As Long, ByVal dwFlags As Long _
  64. ) As Long
  65.  
  66. Private Declare Function CM_Get_DevNode_Status Lib "setupapi.dll" ( _
  67.     lStatus As Long, lProblem As Long, ByVal hDevice As Long, _
  68.     ByVal dwFlags As Long _
  69. ) As Long
  70.  
  71. Private Const DN_REMOVABLE      As Long = &H4000
  72. Private Const CR_SUCCESS        As Long = 0
  73.  
  74. Private Const REG_PATH_MOUNT    As String = "SYSTEM\MountedDevices"
  75. Private Const REG_VALUE_DOSDEV  As String = "\DosDevices\"
  76.  
  77. Public Function EjectDevice(ByVal DriveLetter As String) As Boolean
  78.     Dim strDeviceInstance   As String
  79.     Dim btRegData()         As Byte
  80.     Dim hDevice             As Long
  81.     Dim lngStatus           As Long
  82.     Dim lngProblem          As Long
  83.  
  84.     DriveLetter = UCase$(Left$(DriveLetter, 1)) & ":"
  85.     
  86.     If Not HKLMRegBinaryRead(REG_PATH_MOUNT, REG_VALUE_DOSDEV & DriveLetter, btRegData) Then
  87.         Exit Function
  88.     End If
  89.     
  90.     strDeviceInstance = btRegData
  91.     If Not Left$(strDeviceInstance, 4) = "\??\" Then Exit Function
  92.     
  93.     strDeviceInstance = Mid$(strDeviceInstance, 5, InStr(1, strDeviceInstance, "{") - 6)
  94.     strDeviceInstance = Replace$(strDeviceInstance, "#", "\")
  95.     
  96.     If CR_SUCCESS <> CM_Locate_DevNodeA(hDevice, ByVal strDeviceInstance, 0) Then
  97.         Exit Function
  98.     End If
  99.  
  100.     If CR_SUCCESS <> CM_Get_DevNode_Status(lngStatus, lngProblem, hDevice, 0) Then
  101.         Exit Function
  102.     End If
  103.     
  104.     Do While Not (lngStatus And DN_REMOVABLE) > 0
  105.         If CR_SUCCESS <> CM_Get_Parent(hDevice, hDevice, 0) Then Exit Do
  106.         If CR_SUCCESS <> CM_Get_DevNode_Status(lngStatus, lngProblem, hDevice, 0) Then Exit Do
  107.     Loop
  108.     
  109.     If (lngStatus And DN_REMOVABLE) > 0 Then
  110.         EjectDevice = CR_SUCCESS = CM_Request_Device_EjectA(hDevice, 0, ByVal Space$(255), 255, 0)
  111.     End If
  112. End Function
  113.  
  114. Private Function HandleToDeviceID(hDevice As Long) As String
  115.     Dim strDeviceID As String
  116.     Dim cDeviceID   As Long
  117.     
  118.     If CM_Get_Device_ID_Size(cDeviceID, hDevice, 0) = 0 Then
  119.         strDeviceID = Space(cDeviceID)
  120.         
  121.         If CM_Get_Device_IDA(hDevice, StrPtr(strDeviceID), cDeviceID, 0) > 0 Then
  122.             strDeviceID = StrConv(strDeviceID, vbUnicode)
  123.             strDeviceID = Left(strDeviceID, cDeviceID)
  124.         Else
  125.             strDeviceID = ""
  126.         End If
  127.     End If
  128.     
  129.     HandleToDeviceID = strDeviceID
  130. End Function
  131.  
  132. Private Function HKLMRegBinaryRead(ByVal strPath As String, ByVal strValueName As String, btValue() As Byte) As Boolean
  133.     Dim hKey        As Long
  134.     Dim lngDataLen  As Long
  135.     Dim lngResult   As Long
  136.     Dim regType     As Long
  137.     Dim btDataBuf() As Byte
  138.     
  139.     If RegOpenKeyEx(HKEY_LOCAL_MACHINE, strPath, 0, KEY_READ, hKey) = ERROR_SUCCESS Then
  140.         If RegQueryValueEx(hKey, strValueName, 0, regType, ByVal 0&, lngDataLen) = ERROR_SUCCESS Then
  141.             ReDim btDataBuf(lngDataLen - 1) As Byte
  142.             If RegQueryValueEx(hKey, strValueName, 0, regType, btDataBuf(0), lngDataLen) = ERROR_SUCCESS Then
  143.                 btValue = btDataBuf
  144.                 HKLMRegBinaryRead = True
  145.             End If
  146.         End If
  147.         
  148.         RegCloseKey hKey
  149.     End If
  150. End Function
  151.