Страница: 1 |
Страница: 1 |
Вопрос: Подключение переносного устройства
Добавлено: 30.08.08 18:26
Автор вопроса: AleXandr
Можно ли как нибудь отследить подключение к компьютеру флешки не переберая каждую минуту все устройства в поиске новых?
Ответы
Всего ответов: 5
Номер ответа: 1
Автор ответа:
Администратор
ICQ: 278109632
Вопросов: 42
Ответов: 3949
Web-сайт:
Профиль | | #1
Добавлено: 31.08.08 00:33
ну винда же не перебирает. значит можно. я даже код видел, но не помню где, к сожалению... вроде в одном из номеров "Хакера"
Номер ответа: 2
Автор ответа:
Skywalker
ICQ: 300-70-6пятьЪ
Вопросов: 62
Ответов: 545
Web-сайт:
Профиль | | #2
Добавлено: 31.08.08 01:56
из моего проекта кусок:
Public Class DriveDetectorEventArgs
Public Cancel As Boolean
Public Drive As String
Public HookQueryRemove As Boolean
Public Sub New()
Cancel = False
 rive = ""
HookQueryRemove = False
End Sub
End Class
Public Class DriveDetector
Implements IDisposable
Public Delegate Sub DriveDetectorEventHandler(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
Private disposedValue As Boolean = False
Public Event DeviceArrived As DriveDetectorEventHandler
Public Event DeviceRemoved As DriveDetectorEventHandler
Public Event QueryRemove As DriveDetectorEventHandler
Private mDirHandle As IntPtr = IntPtr.Zero
Private mFileOnFlash As IO.FileStream = Nothing
Private mFileToOpen As String
Private mDeviceNotifyHandle As IntPtr
Private mRecipientHandle As IntPtr
Private mCurrentDrive As String
Private Const DBT_DEVTYP_DEVICEINTERFACE As Integer = 5
Private Const DBT_DEVTYP_HANDLE As Integer = 6
Private Const BROADCAST_QUERY_DENY As Integer = &H424D5144
Private Const WM_DEVICECHANGE As Integer = &H219
Private Const DBT_DEVICEARRIVAL As Integer = &H8000
Private Const DBT_DEVICEQUERYREMOVE As Integer = &H8001
Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
Private Const DBT_DEVTYP_VOLUME As Integer = &H2
<StructLayout(LayoutKind.Sequential)> _
Public Structure DEV_BROADCAST_HANDLE
Public dbch_size As Integer
Public dbch_devicetype As Integer
Public dbch_reserved As Integer
Public dbch_handle As IntPtr
Public dbch_hdevnotify As IntPtr
Public dbch_eventguid As Guid
Public dbch_nameoffset As Long
Public dbch_data As Byte
Public dbch_data1 As Byte
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure DEV_BROADCAST_VOLUME
Public dbcv_size As Integer
Public dbcv_devicetype As Integer
Public dbcv_reserved As Integer
Public dbcv_unitmask As Integer
End Structure
Public Sub New()
mFileToOpen = Nothing
mFileOnFlash = Nothing
mDeviceNotifyHandle = IntPtr.Zero
mRecipientHandle = Helper.form.Handle
mDirHandle = IntPtr.Zero
mCurrentDrive = ""
End Sub
Public ReadOnly Property IsQueryHooked()
Get
Return Not (mDeviceNotifyHandle = IntPtr.Zero)
End Get
End Property
Public ReadOnly Property HookedDrive()
Get
Return mCurrentDrive
End Get
End Property
Public Function EnableQueryRemove(ByVal fileOnDrive As String) As Boolean
If (fileOnDrive = Nothing Or fileOnDrive.Length = 0) Then
Throw New ArgumentException("rive path must be supplied to register for Query remove."
End If
If (fileOnDrive.Length = 2 And fileOnDrive(1) = ":" Then
fileOnDrive += "\\"
End If
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
RegisterForDeviceChange(False, Nothing)
End If
If (IO.Path.GetFileName(fileOnDrive).Length = 0 Or Not IO.File.Exists(fileOnDrive)) Then
mFileToOpen = Nothing
Else
mFileToOpen = fileOnDrive
End If
RegisterQuery(IO.Path.GetPathRoot(fileOnDrive))
Return Not (mDeviceNotifyHandle = IntPtr.Zero)
End Function
Public Sub DisableQueryRemove()
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
RegisterForDeviceChange(False, Nothing)
End If
End Sub
Public Sub WndProc(ByRef m As Message)
Dim devType As Integer
Dim c As Char
If (m.Msg = WM_DEVICECHANGE) Then
Select Case m.WParam.ToInt32()
Case DBT_DEVICEARRIVAL
devType = Marshal.ReadInt32(m.LParam, 4)
If devType = DBT_DEVTYP_VOLUME Then
Dim vol As DEV_BROADCAST_VOLUME
vol = CType(Marshal.PtrToStructure(m.LParam, GetType(DEV_BROADCAST_VOLUME)), DEV_BROADCAST_VOLUME)
c = DriveMaskToLetter(vol.dbcv_unitmask)
Dim e As DriveDetectorEventArgs = New DriveDetectorEventArgs()
e.Drive = c + ":\\"
RaiseEvent DeviceArrived(Me, e)
If (e.HookQueryRemove) Then
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
RegisterForDeviceChange(False, Nothing)
End If
RegisterQuery(c + ":\\"
End If
End If
Exit Select
Case DBT_DEVICEQUERYREMOVE
devType = Marshal.ReadInt32(m.LParam, 4)
If (devType = DBT_DEVTYP_HANDLE) Then
Dim e As DriveDetectorEventArgs = New DriveDetectorEventArgs()
e.Drive = mCurrentDrive
RaiseEvent QueryRemove(Me, e)
If (e.Cancel) Then
m.Result = BROADCAST_QUERY_DENY
Else
RegisterForDeviceChange(False, Nothing)
End If
End If
Exit Select
Case DBT_DEVICEREMOVECOMPLETE
devType = Marshal.ReadInt32(m.LParam, 4)
If devType = DBT_DEVTYP_VOLUME Then
devType = Marshal.ReadInt32(m.LParam, 4)
If devType = DBT_DEVTYP_VOLUME Then
Dim vol As New DEV_BROADCAST_VOLUME
vol = CType(Marshal.PtrToStructure(m.LParam, GetType(DEV_BROADCAST_VOLUME)), DEV_BROADCAST_VOLUME)
c = DriveMaskToLetter(vol.dbcv_unitmask)
Dim e As DriveDetectorEventArgs = New DriveDetectorEventArgs()
e.Drive = c + ":\\"
RaiseEvent DeviceRemoved(Me, e)
End If
End If
End Select
End If
End Sub
Private Sub RegisterQuery(ByVal drive As String)
Dim register As Boolean = True
If (mFileToOpen Is Nothing) Then
Else
If (mFileToOpen.Contains(":") Then
Dim tmp As String = mFileToOpen.Substring(3)
Dim root As String = IO.Path.GetPathRoot(drive)
mFileToOpen = IO.Path.Combine(root, tmp)
Else
mFileToOpen = IO.Path.Combine(drive, mFileToOpen)
End If
End If
Try
If (mFileToOpen Is Nothing) Then
mFileOnFlash = Nothing
Else
mFileOnFlash = New IO.FileStream(mFileToOpen, IO.FileMode.Open)
End If
Catch ex As Exception
register = False
End Try
If (register) Then
If (mFileOnFlash Is Nothing) Then
RegisterForDeviceChange(drive)
Else
RegisterForDeviceChange(True, mFileOnFlash.SafeFileHandle)
End If
mCurrentDrive = drive
End If
End Sub
Private Sub RegisterForDeviceChange(ByVal dirPath As String)
Dim handle As IntPtr = Native.OpenDirectory(dirPath)
If (handle = IntPtr.Zero) Then
mDeviceNotifyHandle = IntPtr.Zero
Return
Else
mDirHandle = handle
End If
Dim data As DEV_BROADCAST_HANDLE = New DEV_BROADCAST_HANDLE()
data.dbch_devicetype = DBT_DEVTYP_HANDLE
data.dbch_reserved = 0
data.dbch_nameoffset = 0
data.dbch_handle = handle
data.dbch_hdevnotify = 0
Dim size As Integer = Marshal.SizeOf(data)
data.dbch_size = size
Dim buffer As IntPtr = Marshal.AllocHGlobal(size)
Marshal.StructureToPtr(data, buffer, True)
mDeviceNotifyHandle = Native.RegisterDeviceNotification(mRecipientHandle, buffer, 0)
End Sub
Private Sub RegisterForDeviceChange(ByVal register As Boolean, ByVal fileHandle As SafeFileHandle)
If register Then
Dim data As DEV_BROADCAST_HANDLE = New DEV_BROADCAST_HANDLE()
data.dbch_devicetype = DBT_DEVTYP_HANDLE
data.dbch_reserved = 0
data.dbch_nameoffset = 0
data.dbch_handle = fileHandle.DangerousGetHandle()
data.dbch_hdevnotify = 0
Dim size As Integer = Marshal.SizeOf(data)
data.dbch_size = size
Dim buffer As IntPtr = Marshal.AllocHGlobal(size)
Marshal.StructureToPtr(data, buffer, True)
mDeviceNotifyHandle = Native.RegisterDeviceNotification(mRecipientHandle, buffer, 0)
Else
If (mDirHandle <> IntPtr.Zero) Then
Native.CloseDirectoryHandle(mDirHandle)
End If
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
Native.UnregisterDeviceNotification(mDeviceNotifyHandle)
End If
mDeviceNotifyHandle = IntPtr.Zero
mDirHandle = IntPtr.Zero
mCurrentDrive = ""
If (mFileOnFlash IsNot Nothing) Then
mFileOnFlash.Close()
mFileOnFlash = Nothing
End If
End If
End Sub
Private Shared Function DriveMaskToLetter(ByVal mask As Integer) As Char
Dim letter As Char
Dim drives As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim cnt As Integer = 0
Dim pom As Integer = mask / 2
While (pom <> 0)
pom = pom / 2
cnt += 1
End While
If (cnt < drives.Length) Then
letter = drives(cnt)
Else
letter = "?"
End If
Return letter
End Function
Private Class Native
<llImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function RegisterDeviceNotification(ByVal hRecipient As IntPtr, ByVal NotificationFilter As IntPtr, ByVal Flags As UInteger) As IntPtr
End Function
<llImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function UnregisterDeviceNotification(ByVal hHandle As IntPtr) As UInteger
End Function
Const GENERIC_READ As Integer = &H80000000 '2147483648 '&H80000000
Const OPEN_EXISTING As UInteger = 3
Const FILE_SHARE_READ As UInteger = &H1
Const FILE_SHARE_WRITE As UInteger = &H2
Const FILE_ATTRIBUTE_NORMAL As UInteger = 128
Const FILE_FLAG_BACKUP_SEMANTICS As UInteger = &H2000000
Shared ReadOnly INVALID_HANDLE_VALUE As IntPtr = New IntPtr(-1)
<llImport("kernel32", SetLastError:=True)> _
Shared Function CreateFile( _
ByVal FileName As String, _
ByVal DesiredAccess As Integer, _
ByVal ShareMode As UInteger, _
ByVal SecurityAttributes As UInteger, _
ByVal CreationDisposition As UInteger, _
ByVal FlagsAndAttributes As UInteger, _
ByVal hTemplateFile As Integer _
  As IntPtr
End Function
<llImport("kernel32", SetLastError:=True)> _
Shared Function CloseHandle( _
ByVal hObject As IntPtr _
  As Boolean
End Function
Public Shared Function OpenDirectory(ByVal dirPath As String) As IntPtr
Dim handle As IntPtr = CreateFile( _
dirPath, _
GENERIC_READ, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
0, _
OPEN_EXISTING, _
FILE_FLAG_BACKUP_SEMANTICS Or FILE_ATTRIBUTE_NORMAL, _
0)
If (handle = INVALID_HANDLE_VALUE) Then
Return IntPtr.Zero
Else
Return handle
End If
End Function
Public Shared Function CloseDirectoryHandle(ByVal handle As IntPtr) As Boolean
Return CloseHandle(handle)
End Function
End Class
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
End If
RegisterForDeviceChange(False, Nothing)
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
 ispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overrides Sub Finalize()
 ispose(False)
MyBase.Finalize()
End Sub
End Class
Friend Class DiskManager
Implements IDisposable
Private drivedetector As DriveDetector
Public Sub New(ByVal width As Integer, ByVal height As Integer, ByVal pos As Vector3)
drivedetector = New DriveDetector
AddHandler drivedetector.DeviceArrived, New DriveDetector.DriveDetectorEventHandler(AddressOf OnDriveArrived)
AddHandler drivedetector.DeviceRemoved, New DriveDetector.DriveDetectorEventHandler(AddressOf OnDriveRemoved)
AddHandler drivedetector.QueryRemove, New DriveDetector.DriveDetectorEventHandler(AddressOf OnQueryRemove)
Helper.driveDetector = drivedetector
End Sub
Private Sub OnDriveArrived(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
'устройство подсоединено
'e.Drive - буква выданная диску
'e.HookQueryRemove = true перехватывать запросы на отключение
End Sub
Private Sub OnDriveRemoved(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
'устройство удалено
End Sub
Private Sub OnQueryRemove(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
'тыкнули на безопасное отключение
'вызывается, если e.HookQueryRemove = true
'если сделать e.Cancel = True, то винда скажет, что низя и не отключит
End Sub
Private disposedValue As Boolean = False
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
End If
drivedetector.Dispose()
drivedetector = Nothing
Helper.driveDetector = Nothing
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
 ispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overrides Sub Finalize()
 ispose(False)
MyBase.Finalize()
End Sub
End Class
Public Class Helper
Public Shared driveDetector As DriveDetector
Public Shared Sub WndProc(ByRef m As Message)
If driveDetector IsNot Nothing Then driveDetector.WndProc(m)
End Sub
End Class
Public Class Form1
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Helper.WndProc(m)
MyBase.WndProc(m)
End Sub
End Class
Номер ответа: 3
Автор ответа:
AleXandr
Вопросов: 1
Ответов: 3
Профиль | | #3
Добавлено: 31.08.08 18:25
Skywalker, чото не работает твой пример. Просидел над ним полдня и ничего не добился.
Номер ответа: 4
Автор ответа:
Skywalker
ICQ: 300-70-6пятьЪ
Вопросов: 62
Ответов: 545
Web-сайт:
Профиль | | #4
Добавлено: 31.08.08 22:48
епта, чо там не работает то, вот полностью рабочий код, копипасть, сам проверил:
Imports System.Runtime.InteropServices
Imports Microsoft.Win32.SafeHandles
Public Class Form1
Private dm As DriveDetector
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
dm = New DriveDetector(Me.Handle)
AddHandler dm.DeviceArrived, New DriveDetector.DriveDetectorEventHandler(AddressOf OnDriveArrived)
AddHandler dm.DeviceRemoved, New DriveDetector.DriveDetectorEventHandler(AddressOf OnDriveRemoved)
AddHandler dm.QueryRemove, New DriveDetector.DriveDetectorEventHandler(AddressOf OnQueryRemove)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If dm IsNot Nothing Then dm.WndProc(m)
MyBase.WndProc(m)
End Sub
Private Sub OnDriveArrived(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
MsgBox("rive: " + e.Drive + " was connected"
If MsgBox("Do you want to control this drive disconnecting?", MsgBoxStyle.YesNo, "iskManager" = MsgBoxResult.Yes Then
e.HookQueryRemove = True
End If
End Sub
Private Sub OnDriveRemoved(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
MsgBox("rive: " + e.Drive + " was removed"
End Sub
Private Sub OnQueryRemove(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
If MsgBox("Do you really want to disconnect this drive?", MsgBoxStyle.YesNo, "iskManager" = MsgBoxResult.No Then
e.Cancel = True
End If
End Sub
End Class
Friend Class DriveDetectorEventArgs
Public Cancel As Boolean
Public Drive As String
Public HookQueryRemove As Boolean
Public Sub New()
Cancel = False
 rive = ""
HookQueryRemove = False
End Sub
End Class
Friend Class DriveDetector
Implements IDisposable
Public Delegate Sub DriveDetectorEventHandler(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
Private disposedValue As Boolean = False
Public Event DeviceArrived As DriveDetectorEventHandler
Public Event DeviceRemoved As DriveDetectorEventHandler
Public Event QueryRemove As DriveDetectorEventHandler
Private mDirHandle As IntPtr = IntPtr.Zero
Private mFileOnFlash As IO.FileStream = Nothing
Private mFileToOpen As String
Private mDeviceNotifyHandle As IntPtr
Private mRecipientHandle As IntPtr
Private mCurrentDrive As String
Private Const DBT_DEVTYP_DEVICEINTERFACE As Integer = 5
Private Const DBT_DEVTYP_HANDLE As Integer = 6
Private Const BROADCAST_QUERY_DENY As Integer = &H424D5144
Private Const WM_DEVICECHANGE As Integer = &H219
Private Const DBT_DEVICEARRIVAL As Integer = &H8000
Private Const DBT_DEVICEQUERYREMOVE As Integer = &H8001
Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
Private Const DBT_DEVTYP_VOLUME As Integer = &H2
<StructLayout(LayoutKind.Sequential)> _
Public Structure DEV_BROADCAST_HANDLE
Public dbch_size As Integer
Public dbch_devicetype As Integer
Public dbch_reserved As Integer
Public dbch_handle As IntPtr
Public dbch_hdevnotify As IntPtr
Public dbch_eventguid As Guid
Public dbch_nameoffset As Long
Public dbch_data As Byte
Public dbch_data1 As Byte
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure DEV_BROADCAST_VOLUME
Public dbcv_size As Integer
Public dbcv_devicetype As Integer
Public dbcv_reserved As Integer
Public dbcv_unitmask As Integer
End Structure
Public Sub New(ByVal hwnd As IntPtr)
mFileToOpen = Nothing
mFileOnFlash = Nothing
mDeviceNotifyHandle = IntPtr.Zero
mRecipientHandle = hwnd
mDirHandle = IntPtr.Zero
mCurrentDrive = ""
End Sub
Public ReadOnly Property IsQueryHooked()
Get
Return Not (mDeviceNotifyHandle = IntPtr.Zero)
End Get
End Property
Public ReadOnly Property HookedDrive()
Get
Return mCurrentDrive
End Get
End Property
Public Function EnableQueryRemove(ByVal fileOnDrive As String) As Boolean
If (fileOnDrive = Nothing Or fileOnDrive.Length = 0) Then
Throw New ArgumentException("rive path must be supplied to register for Query remove."
End If
If (fileOnDrive.Length = 2 And fileOnDrive(1) = ":" Then
fileOnDrive += "\\"
End If
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
RegisterForDeviceChange(False, Nothing)
End If
If (IO.Path.GetFileName(fileOnDrive).Length = 0 Or Not IO.File.Exists(fileOnDrive)) Then
mFileToOpen = Nothing
Else
mFileToOpen = fileOnDrive
End If
RegisterQuery(IO.Path.GetPathRoot(fileOnDrive))
Return Not (mDeviceNotifyHandle = IntPtr.Zero)
End Function
Public Sub DisableQueryRemove()
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
RegisterForDeviceChange(False, Nothing)
End If
End Sub
Public Sub WndProc(ByRef m As Message)
Dim devType As Integer
Dim c As Char
If (m.Msg = WM_DEVICECHANGE) Then
Select Case m.WParam.ToInt32()
Case DBT_DEVICEARRIVAL
devType = Marshal.ReadInt32(m.LParam, 4)
If devType = DBT_DEVTYP_VOLUME Then
Dim vol As DEV_BROADCAST_VOLUME
vol = CType(Marshal.PtrToStructure(m.LParam, GetType(DEV_BROADCAST_VOLUME)), DEV_BROADCAST_VOLUME)
c = DriveMaskToLetter(vol.dbcv_unitmask)
Dim e As DriveDetectorEventArgs = New DriveDetectorEventArgs()
e.Drive = c + ":\\"
RaiseEvent DeviceArrived(Me, e)
If (e.HookQueryRemove) Then
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
RegisterForDeviceChange(False, Nothing)
End If
RegisterQuery(c + ":\\"
End If
End If
Exit Select
Case DBT_DEVICEQUERYREMOVE
devType = Marshal.ReadInt32(m.LParam, 4)
If (devType = DBT_DEVTYP_HANDLE) Then
Dim e As DriveDetectorEventArgs = New DriveDetectorEventArgs()
e.Drive = mCurrentDrive
RaiseEvent QueryRemove(Me, e)
If (e.Cancel) Then
m.Result = BROADCAST_QUERY_DENY
Else
RegisterForDeviceChange(False, Nothing)
End If
End If
Exit Select
Case DBT_DEVICEREMOVECOMPLETE
devType = Marshal.ReadInt32(m.LParam, 4)
If devType = DBT_DEVTYP_VOLUME Then
devType = Marshal.ReadInt32(m.LParam, 4)
If devType = DBT_DEVTYP_VOLUME Then
Dim vol As New DEV_BROADCAST_VOLUME
vol = CType(Marshal.PtrToStructure(m.LParam, GetType(DEV_BROADCAST_VOLUME)), DEV_BROADCAST_VOLUME)
c = DriveMaskToLetter(vol.dbcv_unitmask)
Dim e As DriveDetectorEventArgs = New DriveDetectorEventArgs()
e.Drive = c + ":\\"
RaiseEvent DeviceRemoved(Me, e)
End If
End If
End Select
End If
End Sub
Private Sub RegisterQuery(ByVal drive As String)
Dim register As Boolean = True
If (mFileToOpen Is Nothing) Then
Else
If (mFileToOpen.Contains(":") Then
Dim tmp As String = mFileToOpen.Substring(3)
Dim root As String = IO.Path.GetPathRoot(drive)
mFileToOpen = IO.Path.Combine(root, tmp)
Else
mFileToOpen = IO.Path.Combine(drive, mFileToOpen)
End If
End If
Try
If (mFileToOpen Is Nothing) Then
mFileOnFlash = Nothing
Else
mFileOnFlash = New IO.FileStream(mFileToOpen, IO.FileMode.Open)
End If
Catch ex As Exception
register = False
End Try
If (register) Then
If (mFileOnFlash Is Nothing) Then
RegisterForDeviceChange(drive)
Else
RegisterForDeviceChange(True, mFileOnFlash.SafeFileHandle)
End If
mCurrentDrive = drive
End If
End Sub
Private Sub RegisterForDeviceChange(ByVal dirPath As String)
Dim handle As IntPtr = Native.OpenDirectory(dirPath)
If (handle = IntPtr.Zero) Then
mDeviceNotifyHandle = IntPtr.Zero
Return
Else
mDirHandle = handle
End If
Dim data As DEV_BROADCAST_HANDLE = New DEV_BROADCAST_HANDLE()
data.dbch_devicetype = DBT_DEVTYP_HANDLE
data.dbch_reserved = 0
data.dbch_nameoffset = 0
data.dbch_handle = handle
data.dbch_hdevnotify = 0
Dim size As Integer = Marshal.SizeOf(data)
data.dbch_size = size
Dim buffer As IntPtr = Marshal.AllocHGlobal(size)
Marshal.StructureToPtr(data, buffer, True)
mDeviceNotifyHandle = Native.RegisterDeviceNotification(mRecipientHandle, buffer, 0)
End Sub
Private Sub RegisterForDeviceChange(ByVal register As Boolean, ByVal fileHandle As SafeFileHandle)
If register Then
Dim data As DEV_BROADCAST_HANDLE = New DEV_BROADCAST_HANDLE()
data.dbch_devicetype = DBT_DEVTYP_HANDLE
data.dbch_reserved = 0
data.dbch_nameoffset = 0
data.dbch_handle = fileHandle.DangerousGetHandle()
data.dbch_hdevnotify = 0
Dim size As Integer = Marshal.SizeOf(data)
data.dbch_size = size
Dim buffer As IntPtr = Marshal.AllocHGlobal(size)
Marshal.StructureToPtr(data, buffer, True)
mDeviceNotifyHandle = Native.RegisterDeviceNotification(mRecipientHandle, buffer, 0)
Else
If (mDirHandle <> IntPtr.Zero) Then
Native.CloseDirectoryHandle(mDirHandle)
End If
If (mDeviceNotifyHandle <> IntPtr.Zero) Then
Native.UnregisterDeviceNotification(mDeviceNotifyHandle)
End If
mDeviceNotifyHandle = IntPtr.Zero
mDirHandle = IntPtr.Zero
mCurrentDrive = ""
If (mFileOnFlash IsNot Nothing) Then
mFileOnFlash.Close()
mFileOnFlash = Nothing
End If
End If
End Sub
Private Shared Function DriveMaskToLetter(ByVal mask As Integer) As Char
Dim letter As Char
Dim drives As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Dim cnt As Integer = 0
Dim pom As Integer = mask / 2
While (pom <> 0)
pom = pom / 2
cnt += 1
End While
If (cnt < drives.Length) Then
letter = drives(cnt)
Else
letter = "?"
End If
Return letter
End Function
Private Class Native
<llImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function RegisterDeviceNotification(ByVal hRecipient As IntPtr, ByVal NotificationFilter As IntPtr, ByVal Flags As UInteger) As IntPtr
End Function
<llImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function UnregisterDeviceNotification(ByVal hHandle As IntPtr) As UInteger
End Function
Const GENERIC_READ As Integer = &H80000000 '2147483648 '&H80000000
Const OPEN_EXISTING As UInteger = 3
Const FILE_SHARE_READ As UInteger = &H1
Const FILE_SHARE_WRITE As UInteger = &H2
Const FILE_ATTRIBUTE_NORMAL As UInteger = 128
Const FILE_FLAG_BACKUP_SEMANTICS As UInteger = &H2000000
Shared ReadOnly INVALID_HANDLE_VALUE As IntPtr = New IntPtr(-1)
<llImport("kernel32", SetLastError:=True)> _
Shared Function CreateFile( _
ByVal FileName As String, _
ByVal DesiredAccess As Integer, _
ByVal ShareMode As UInteger, _
ByVal SecurityAttributes As UInteger, _
ByVal CreationDisposition As UInteger, _
ByVal FlagsAndAttributes As UInteger, _
ByVal hTemplateFile As Integer _
  As IntPtr
End Function
<llImport("kernel32", SetLastError:=True)> _
Shared Function CloseHandle( _
ByVal hObject As IntPtr _
  As Boolean
End Function
Public Shared Function OpenDirectory(ByVal dirPath As String) As IntPtr
Dim handle As IntPtr = CreateFile( _
dirPath, _
GENERIC_READ, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
0, _
OPEN_EXISTING, _
FILE_FLAG_BACKUP_SEMANTICS Or FILE_ATTRIBUTE_NORMAL, _
0)
If (handle = INVALID_HANDLE_VALUE) Then
Return IntPtr.Zero
Else
Return handle
End If
End Function
Public Shared Function CloseDirectoryHandle(ByVal handle As IntPtr) As Boolean
Return CloseHandle(handle)
End Function
End Class
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
End If
RegisterForDeviceChange(False, Nothing)
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
 ispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overrides Sub Finalize()
 ispose(False)
MyBase.Finalize()
End Sub
End Class
Номер ответа: 5
Автор ответа:
AleXandr
Вопросов: 1
Ответов: 3
Профиль | | #5
Добавлено: 02.09.08 17:49
Спасибо, ты меня спас!