Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Подключение переносного устройства Добавлено: 30.08.08 18:26  

Автор вопроса:  AleXandr
Можно ли как нибудь отследить подключение к компьютеру флешки не переберая каждую минуту все устройства в поиске новых?

Ответить

  Ответы Всего ответов: 5  

Номер ответа: 1
Автор ответа:
 



Администратор

ICQ: 278109632 

Вопросов: 42
Ответов: 3949
 Web-сайт: domkratt.com
 Профиль | | #1
Добавлено: 31.08.08 00:33
ну винда же не перебирает. значит можно. я даже код видел, но не помню где, к сожалению... вроде в одном из номеров "Хакера"

Ответить

Номер ответа: 2
Автор ответа:
 Skywalker



ICQ: 300-70-6пятьЪ 

Вопросов: 62
Ответов: 545
 Web-сайт: iSkywalker.ru
 Профиль | | #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
        ;Drive = ""
        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(";Drive 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
        <;DllImport("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
        <;DllImport("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)
        <;DllImport("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
        <;DllImport("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
        ;Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
    Protected Overrides Sub Finalize()
        ;Dispose(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
        ;Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
    Protected Overrides Sub Finalize()
        ;Dispose(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-сайт: iSkywalker.ru
 Профиль | | #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(";Drive: " + e.Drive + " was connected";)
        If MsgBox("Do you want to control this drive disconnecting?", MsgBoxStyle.YesNo, ";DiskManager";) = MsgBoxResult.Yes Then
            e.HookQueryRemove = True
        End If
    End Sub
    Private Sub OnDriveRemoved(ByVal sender As Object, ByVal e As DriveDetectorEventArgs)
        MsgBox(";Drive: " + 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, ";DiskManager";) = 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
        ;Drive = ""
        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(";Drive 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
        <;DllImport("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
        <;DllImport("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)
        <;DllImport("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
        <;DllImport("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
        ;Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
    Protected Overrides Sub Finalize()
        ;Dispose(False)
        MyBase.Finalize()
    End Sub
End Class

Ответить

Номер ответа: 5
Автор ответа:
 AleXandr



Вопросов: 1
Ответов: 3
 Профиль | | #5 Добавлено: 02.09.08 17:49
Спасибо, ты меня спас!:-)

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам