Jump to content

Recommended Posts

Posted (edited)

WHOA! I'm for serial this go 'round. I see a DeviceQueryRemove message! I sees it wif my own two eyes!

I just now tried this on a WindowsXP x86 virtual machine running on top of Windows7 x64 and it worked just fine.

[10-09-2010] Latest Update

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_AU3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d
#AutoIt3Wrapper_Run_Tidy=y
#Tidy_Parameters=/tc 0
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <WinAPI.au3>
#include <FileConstants.au3>
#include <GUIConstantsEX.au3>
#include <Misc.au3>

_Singleton(@ScriptName)

#region GUI
Opt("GUIOnEventMode", 1)

Global Const $hRecipient = GUICreate("USB Handler", 400, 400, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "term", $hRecipient)

Global Const $WM_DEVICECHANGE = 0x0219
Global Const $RegisterStatus = GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE")

Global Const $EditBox = GUICtrlCreateEdit('', 5, 5, 350, 350)

Global Const $AllowDenyCheckBox = GUICtrlCreateCheckbox("Check to deny device removal.", 5, 355, 162, 40)
GUICtrlSetState($AllowDenyCheckBox, $GUI_CHECKED)

GUISetState(@SW_SHOW)
#endregion GUI

#region Global constants
Global Const $DBT_CONFIGCHANGECANCELED = 0x0019 ; A request To change the current configuration(dock or undock) has been canceled.
Global Const $DBT_CONFIGCHANGED = 0x0018 ; The current configuration has changed due To a dock or undock.
Global Const $DBT_CUSTOMEVENT = 0x8006 ; A custom event has occurred.
Global Const $DBT_DEVICEARRIVAL = 0x8000 ; A device or piece of media has been inserted and is now available.
Global Const $DBT_DEVICEQUERYREMOVE = 0x8001 ; Permission is requested To remove a device or piece of media. Any application can deny this request and cancel the removal.
Global Const $DBT_DEVICEQUERYREMOVEFAILED = 0x8002 ; A request To remove a device or piece of media has been canceled.
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; A device or piece of media has been removed.
Global Const $DBT_DEVICEREMOVEPENDING = 0x8003 ; A device or piece of media is about to be removed. Cannot be denied.
Global Const $DBT_DEVICETYPESPECIFIC = 0x8005 ; A device-specific event has occurred.
Global Const $DBT_DEVNODES_CHANGED = 0x0007 ; A device has been added to or removed from the system.
Global Const $DBT_QUERYCHANGECONFIG = 0x0017 ; Permission is requested to change the current configuration(dock or undock).
Global Const $DBT_USERDEFINED = 0xFFFF ; The meaning of this message is user-defined.

Global Const $DBT_DEVTYP_VOLUME = 2
Global Const $DBT_DEVTYP_HANDLE = 6

Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0

Global Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 ; _WinAPI_CreateFileEx()

#endregion Global constants

HotKeySet("{ESC}", "term")

OnAutoItExitRegister("_exit")

Global $DeviceHandle

While 1
    Sleep(100)
WEnd

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func MY_WM_DEVICECHANGE($hWnd, $msg, $wParam, $lParam)

    If $msg = $WM_DEVICECHANGE Then

        ; Create a struct from $lParam which contains a pointer to a Windows-created struct.
        Local Const $tagDEV_BROADCAST_VOLUME = "dword dbcv_size; dword dbcv_devicetype; dword dbcv_reserved; dword dbcv_unitmask; word dbcv_flags"
        Local Const $DEV_BROADCAST_VOLUME = DllStructCreate($tagDEV_BROADCAST_VOLUME, $lParam)

        Local Const $DeviceType = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcv_devicetype")

        Switch $wParam

            Case $DBT_DEVICEARRIVAL

                If $DeviceType = $DBT_DEVTYP_VOLUME Then

                    Write("DEVICEARRIVAL: ", False)

                    Local Const $UnitMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcv_unitmask")

                    Local Const $DriveLetter = GetDriveLetterFromUnitMask($UnitMask)

                    Write($DriveLetter)

                    Local Const $tmpDeviceHandle = DoRegisterDeviceInterfaceToHwnd($DriveLetter)

                    If Not @error Then
                        $DeviceHandle = $tmpDeviceHandle
                    Else
                        Return SetError(-1, 0, 1)
                    EndIf
                EndIf

            Case $DBT_DEVICEQUERYREMOVE

                If $DeviceType = $DBT_DEVTYP_HANDLE Then

                    Write("DEVICEQUERYREMOVE")

                    ; Check/Uncheck to allow/disallow device removal
                    Switch GUICtrlRead($AllowDenyCheckBox)
                        Case $GUI_UNCHECKED ; allow
                            UnregisterDeviceNotification()

                        Case $GUI_CHECKED ; deny
                            Local Const $BROADCAST_QUERY_DENY = 0x424D5144
                            Return $BROADCAST_QUERY_DENY
                    EndSwitch
                EndIf

            Case $DBT_DEVICEREMOVECOMPLETE

                Write("DEVICEREMOVECOMPLETE")

            Case $DBT_CONFIGCHANGECANCELED
                Write("CONFIGCHANGECANCELED")

            Case $DBT_CONFIGCHANGED
                Write("CONFIGCHANGED")

            Case $DBT_CUSTOMEVENT
                Write("CUSTOMEVENT")

            Case $DBT_DEVICEQUERYREMOVEFAILED
                Write("DEVICEQUERYREMOVEFAILED")

            Case $DBT_DEVICEREMOVEPENDING
                Write("DEVICEREMOVEPENDING")

            Case $DBT_DEVICETYPESPECIFIC
                Write("DEVICETYPESPECIFIC")

            Case $DBT_DEVNODES_CHANGED
                Write("DEVNODES_CHANGED")

            Case $DBT_QUERYCHANGECONFIG
                Write("QUERYCHANGECONFIG")

            Case $DBT_USERDEFINED
                Write("USERDEFINED")

        EndSwitch
    EndIf
EndFunc ;==>MY_WM_DEVICECHANGE

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func DoRegisterDeviceInterfaceToHwnd($DriveLetter)

    Local Const $tagDEV_BROADCAST_HANDLE = "dword dbch_size; dword dbch_devicetype; dword dbch_reserved; handle dbch_handle; ptr dbch_hdevnotify; char dbch_eventguid[128]; long dbch_nameoffset; byte dbch_data[1]"
    Local Const $DEV_BROADCAST_HANDLE = DllStructCreate($tagDEV_BROADCAST_HANDLE)
    Local Const $ptrDEV_BROADCAST_HANDLE = DllStructGetPtr($DEV_BROADCAST_HANDLE)
    Local Const $ODhandle = OpenDirectory($DriveLetter)
    Local Const $Size = DllStructGetSize($DEV_BROADCAST_HANDLE)

    DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_size", $Size)
    DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_devicetype", $DBT_DEVTYP_HANDLE)
    DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_reserved", 0)
    DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_handle", $ODhandle)
    DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_hdevnotify", 0)
    DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_nameoffset", 0)

    Local Const $RDNhandle = DllCall("User32.dll", "handle", "RegisterDeviceNotification", "hwnd", $hRecipient, "ptr", $ptrDEV_BROADCAST_HANDLE, "uint", $DEVICE_NOTIFY_WINDOW_HANDLE)

    If $RDNhandle[0] Then
        Return $RDNhandle[0]
    Else
        Return SetError(-1, 0, 1)
    EndIf
EndFunc ;==>DoRegisterDeviceInterfaceToHwnd

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func UnregisterDeviceNotification()

    Local Const $Check = DllCall("User32.dll", "bool", "UnregisterDeviceNotification", "ptr", $DeviceHandle)

    If Not $Check[0] Then
        Write("UnregisterDeviceNotification @error: " & @error)
        Return SetError(-1, 0, 1)
    EndIf
EndFunc ;==>UnregisterDeviceNotification

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func OpenDirectory($DevicePath)

    Local Const $FileName = $DevicePath & ":\\"
    Local Const $DesiredAccess = $GENERIC_READ
    Local Const $ShareMode = BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE)
    Local Const $SecurityAttributes = 0
    Local Const $CreationDisposition = $OPEN_EXISTING
    Local Const $FlagsAndAttributes = BitOR($FILE_FLAG_BACKUP_SEMANTICS, $FILE_ATTRIBUTE_NORMAL)

    Local Const $DevHandle = _WinAPI_CreateFileEx($FileName, $DesiredAccess, $ShareMode, $SecurityAttributes, $CreationDisposition, $FlagsAndAttributes)

    If $DevHandle Then
        Return $DevHandle
    Else
        Return SetError(-1, 0, 1)
    EndIf
EndFunc ;==>OpenDirectory

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func GetDriveLetterFromUnitMask($UnitMask)

    Local Const $Drives[26] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    Local $Count = 1
    Local $Pom = $UnitMask / 2

    While $Pom <> 0
        ; $Pom = BitShift($Pom, 1)
        $Pom = Int($Pom / 2)
        $Count += 1
    WEnd

    If $Count >= 1 And $Count <= 26 Then
        Return $Drives[$Count - 1]
    Else
        Return SetError(-1, 0, '?')
    EndIf
EndFunc ;==>GetDriveLetterFromUnitMask

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func Write($msg, $CRLF = True)
    If $CRLF Then
        GUICtrlSetData($EditBox, $msg & @CRLF, ' ')
    Else
        GUICtrlSetData($EditBox, $msg, ' ')
    EndIf
EndFunc ;==>Write

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func term()
    Exit
EndFunc ;==>term

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func _exit()
    If $RegisterStatus Then GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE")
    If IsHWnd($hRecipient) Then GUIDelete()
    OnAutoItExitUnregister("_exit")
EndFunc ;==>_exit

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

; This was taken from Yashied's "WinAPIEx" which can be found here: (http://www.autoitscript.com/forum/index.php?showtopic=98712&hl=WinAPIEx&st=0).
; Slightly modified to suit my needs. 10/09/2010 Jaberwocky6669

Func _WinAPI_CreateFileEx($sFile, $iAccess, $iShare, $tSecurity, $iCreation, $iFlagsAndAttributes, $hTemplate = 0)

    Local Const $Ret = DllCall("Kernel32.dll", "handle", "CreateFileW", "wstr", $sFile, "dword", $iAccess, "dword", $iShare, "ptr", DllStructGetPtr($tSecurity), "dword", $iCreation, "dword", $iFlagsAndAttributes, "handle", $hTemplate)

    If @error Or $Ret[0] = -1 Then
        Return SetError(-1, 0, 1)
    Else
        Return $Ret[0]
    EndIf
EndFunc ;==>_WinAPI_CreateFileEx

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Edited by jaberwocky6669
Posted

GREAT!!! It works! :) jaberwocky6669 you are a hero. ;)

I never thought that is such complicate.

Now I have to unregister the device instead of "return 0". But I hope that this will be easier. And than finally I can realize then real functionality.

Thank you very much.

Posted (edited)

Hey, you are welcome. It was no problem at all. I had tons of fun if you can believe that. I'd still like to develop this script further if you don't mind.

I'm sure it wasn't as complicated as I made it out to be! I've been known to over-complicate things from time to time.

Edited by jaberwocky6669
Posted (edited)

So, now the foundation stone is laid. I've fixed the Unregister functionality:

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_AU3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <WinAPI.au3>
#include <Array.au3>
#include <udf\WinAPIEx.au3>
#include <GUIConstantsEX.au3>
#include <Misc.au3>

_Singleton(@ScriptName)

HotKeySet("{ESC}", "term")

Global Const $hRecipient = GUICreate("USB-Handler")
Global Const $EditBox = GUICtrlCreateEdit('', 0, 0, 400, 400)

GUISetState()

Global Const $WM_DEVICECHANGE = 0x0219

Global $hDevNotify
Global $hFile

GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            GUIRegisterMsg($WM_DEVICECHANGE, '')
            GUIDelete()
            Exit
    EndSwitch
WEnd

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func MY_WM_DEVICECHANGE(Const $hWnd, Const $msg, Const $lParam, Const $wParam)
    Local $DBT_DEVICEARRIVAL = 0x00008000 ; A device or piece of media has been inserted and is now available.
    Local $DBT_DEVICEQUERYREMOVE = 0x00008001 ; A device or piece of media is attemped to remove.
    Local $DBT_DEVICEREMOVECOMPLETE = 0x00008004 ; A device or piece of media has been removed.

    Local Const $CheckError = False

    Switch $lParam
        Case $DBT_DEVICEARRIVAL
            Write("DEVICEARRIVAL")

            Local Const $DEV_BROADCAST_VOLUME = DllStructCreate("int dbcv_size; int dbcv_devicetype; int dbcv_reserved; int dbcv_unitmask", $wParam)
            If $CheckError Then Write("DEV_BROADCAST_VOLUME @Error: " & @error)

            Local Const $unitMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcv_unitmask")

            Local Const $driveLetter = GetDriveLetterFromUnitMask($unitMask) & ":\\"

            $hDevNotify = DoRegisterDeviceInterfaceToHwnd($driveLetter)

            If $hDevNotify Then _OnInsert()

        Case $DBT_DEVICEQUERYREMOVE
            Write("DEVICEQUERYREMOVE")

            If _OnRemove() Then    
                If $hDevNotify Then UnregisterDeviceNotification($hDevNotify)
                Return 0
            Else
                Local $BROADCAST_QUERY_DENY = 0x424D5144
                Return $BROADCAST_QUERY_DENY
            EndIf

        Case $DBT_DEVICEREMOVECOMPLETE
            Write("DEVICEREMOVECOMPLETE")

    EndSwitch
EndFunc ;==>MY_WM_DEVICECHANGE

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func _OnInsert()
    ;...
EndFunc ;==>_OnInsert

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func _OnRemove()
    ; To be replaced...
    Local Const $Option = MsgBox(4, "Allow or Deny", "Remove the device?")
    If $Option = 6 Then
        Return True
    ElseIf $Option = 7 Then
        Return False
    EndIf
EndFunc ;==>_OnRemove

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func DoRegisterDeviceInterfaceToHwnd($driveLetter, $CheckError = False)
    Local Const $DBT_DEVTYP_HANDLE = 0x00000006

    $hFile = OpenDirectory($driveLetter, $CheckError)

    Local Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000

    Local Const $NotificationFilter = DllStructCreate("int dbch_size; int dbch_devicetype; int dbch_reserved; ptr dbch_handle; ptr dbch_hdevnotify; char dbch_eventguid[128]; long dbch_nameoffset; byte dbch_data[1]")
    If $CheckError Then Write("DEV_BROADCAST_HANDLE @Error: " & @error)

    DllStructSetData($NotificationFilter, "dbch_size", DllStructGetSize($NotificationFilter))
    DllStructSetData($NotificationFilter, "dbch_devicetype", $DBT_DEVTYP_HANDLE)
    DllStructSetData($NotificationFilter, "dbch_reserved", 0)
    DllStructSetData($NotificationFilter, "dbch_nameoffset", 0)
    DllStructSetData($NotificationFilter, "dbch_handle", $hFile)
    DllStructSetData($NotificationFilter, "dbch_hdevnotify", 0)

    Local Const $pNotificationFilter = DllStructGetPtr($NotificationFilter)

    Local Const $check = DllCall("User32.dll", "handle", "RegisterDeviceNotification", "hwnd", $hRecipient, "ptr", $pNotificationFilter, "uint", $DEVICE_NOTIFY_WINDOW_HANDLE)
    If $CheckError Then Write("$check: " & $check & " @error: " & @error)
    If $CheckError Then Write("RegisterDeviceNotification: " & _WinAPI_GetLastErrorMessage())

    Return $check[0]
EndFunc ;==>DoRegisterDeviceInterfaceToHwnd

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func UnregisterDeviceNotification($handle, $CheckError = False)
    
    _WinAPI_CloseHandle($hFile)
    
    Local Const $check = DllCall("User32.dll", "UINT", "UnregisterDeviceNotification", "handle", $handle)
    If $CheckError Then Write("$check: " & $check & " @error: " & @error)
    If $CheckError Then Write("UnregisterDeviceNotification: " & _WinAPI_GetLastErrorMessage())
EndFunc ;==>UnregisterDeviceNotification

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func OpenDirectory($dirPath, $CheckError = False)
    Local Const $handle = _WinAPI_CreateFileEx($dirPath, _
            $OPEN_EXISTING, _
            $GENERIC_READ, _
            BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), _
            BitOR($FILE_FLAG_BACKUP_SEMANTICS, $FILE_ATTRIBUTE_NORMAL), _
            0, _
            0)

    If $CheckError Then Write("_WinAPI_CreateFile: " & _WinAPI_GetLastErrorMessage())

    If Not $handle Then
        Return SetError(-1, 0, 1)
    Else
        Return $handle
    EndIf
EndFunc ;==>OpenDirectory

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func GetDriveLetterFromUnitMask($unitMask)
    Local Const $Drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    Local $Count = 1
    Local $Pom = Round($unitMask / 2)

    While $Pom <> 0
        $Pom = BitShift($Pom, 1)
        $Count += 1
    WEnd

    If $Count >= 1 And $Count <= 26 Then
        Return StringMid($Drives, $Count, 1)
    Else
        Return '?'
    EndIf
EndFunc ;==>GetDriveLetterFromUnitMask

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func Write($msg)
    GUICtrlSetData($EditBox, $msg & @CRLF, ' ')
;~     ConsoleWrite($msg & @CRLF)
EndFunc ;==>Write

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Func term()
    Exit
EndFunc ;==>term

; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Many thanks to jaberwocky6669!

Edited by Joline
Posted (edited)

See this post for another version: (#838452)

No, nevermind, it's too buggy at this point

(Magically mysteriously, it's working again and I didn't even do nothing to it)

Please share your app with the forum when you're done, please.

See the links in my signature to keep apprised of the latest updates to the RegisterDeviceNotifications script.

Edited by jaberwocky6669
  • 4 years later...
Posted (edited)

hello,

Can someone make an example Snippet for this so it doesn't clash with #include <WinAPIFiles.au3> 

Im mainly looking to get the $DBT_DEVICEARRIVAL part right
Finding at what point in the script can I be sure the device is fully accessible 
so I can run commands on files inside

With what IM using now ,when using $DBT_DEVICEARRIVAL the device is not always fully ready for operations
 The symptoms  are: the device is partly loaded ,  ruining files from commands that had run prematurely on them, in explorer the device hesitates to fully load ,causing the device to hang ..

Any small example for this will be great 

Thanks in advance

 

Edit: solved

Edited by Deye
  • 8 years later...
Posted (edited)

This reply may be ten years late but I hope it will be helpful to future learners.

 

How to use :

1.Run this code 

2.Plugin or Unplug usb device

3.It is will pop-up message

 



 

#include <WinAPI.au3>
#include <Array.au3>
#include <WinAPIDiag.au3>

HotKeySet("{ESC}", "_exit")


Global Const $WM_DEVICECHANGE = 537


Global Const $DBT_CONFIGCHANGECANCELED = 0x0019
Global Const $DBT_CONFIGCHANGED = 0x0018
Global Const $DBT_CUSTOMEVENT = 0x8006
Global Const $DBT_DEVICEARRIVAL = 0x8000
Global Const $DBT_DEVICEQUERYREMOVE = 0x8001
Global Const $DBT_DEVICEQUERYREMOVEFAILED = 0x8002
Global Const $DBT_DEVICEREMOVEPENDING = 0x8003
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004
Global Const $DBT_DEVICETYPESPECIFIC = 0x8005
Global Const $DBT_DEVNODES_CHANGED = 0x0007
Global Const $DBT_QUERYCHANGECONFIG = 0x0017
Global Const $DBT_USERDEFINED = 0xFFFF
Global Const $DBT_DEVTYP_OEM = 0x00000000
Global Const $DBT_DEVTYP_DEVNODE = 0x00000001
Global Const $DBT_DEVTYP_VOLUME = 0x00000002
Global Const $DBT_DEVTYP_PORT = 0x00000003
Global Const $DBT_DEVTYP_NET = 0x00000004
Global Const $DBT_DEVTYP_DEVICEINTERFACE = 0x00000005
Global Const $DBT_DEVTYP_HANDLE = 0x00000006
Global Const $DBT_DEVTYP_DEVINST = 0x00000007
Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000
Global Const $DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001
Global Const $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004
Global $RegisterDeviceInterface_Handle[0][2]
Global $GUI_hwnd = GUICreate("Detect device change")
Global Const $tagPack = "align 1;"
Global Const $tagDEV_BROADCAST_HDR = _
                "dword size;" & _
                "dword devicetype;" & _
                "dword reserved;"
Global $DEV_BROADCAST_HDR = DllStructCreate($tagDEV_BROADCAST_HDR)
Global Const $tagDEV_BROADCAST_USERDEFINED = _
                $tagDEV_BROADCAST_HDR & _
                "char szName[1];"
Global $DEV_BROADCAST_USERDEFINED = DllStructCreate($tagDEV_BROADCAST_USERDEFINED)
Global Const $tagDEV_BROADCAST_HANDLE = _
                $tagDEV_BROADCAST_HDR & _
                "handle handle;" & _
                "ptr hdevnotify;" & _
                $tagGUID & ";" & _
                "long nameoffset;" & _
                "byte data[1];"
Global $DEV_BROADCAST_HANDLE = DllStructCreate($tagDEV_BROADCAST_HANDLE)
Global Const $tagDEV_BROADCAST_DEVICEINTERFACE = _
                $tagDEV_BROADCAST_HDR & _
                $tagGUID & ";" & _
                "WCHAR name[256];"
Global $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate($tagDEV_BROADCAST_DEVICEINTERFACE)
Global Const $tagDEV_BROADCAST_OEM = _
                $tagDEV_BROADCAST_HDR & _
                "dword identifier;" & _
                "dword suppfunc"
Global $DEV_BROADCAST_OEM = DllStructCreate($tagDEV_BROADCAST_OEM)
Global Const $tagDEV_BROADCAST_PORT = _
                $tagDEV_BROADCAST_HDR & _
                "WCHAR name[256];"
Global $DEV_BROADCAST_PORT = DllStructCreate($tagDEV_BROADCAST_PORT)
Global Const $tagDEV_BROADCAST_VOLUME = _
                $tagDEV_BROADCAST_HDR & _
                "dword unitmask;" & _
                "word flags;"
Global $DEV_BROADCAST_VOLUME = DllStructCreate($tagDEV_BROADCAST_VOLUME)
Local $Flags = $DEVICE_NOTIFY_WINDOW_HANDLE
DoRegisterDeviceInterface($GUI_hwnd, "{A5DCBF10-6530-11D2-901F-00C04FB951ED}", $Flags) 
DoRegisterDeviceInterface($GUI_hwnd, "{f18a0e88-c30c-11d0-8815-00a0c906bed8}", $Flags) 
;_ArrayDisplay($RegisterDeviceInterface_Handle)


;UnregisterDeviceNotification($RegisterDeviceInterface_Handle[1][1])
;UnregisterDeviceNotification($RegisterDeviceInterface_Handle[0][1])
;UnregisterDeviceNotification("{A5DCBF10-6530-11D2-901F-00C04FB951ED}")
;_ArrayDisplay($RegisterDeviceInterface_Handle)

GUIRegisterMsg($WM_DEVICECHANGE, 'Detect_device')

Do
Until GUIGetMsg() = -3

Func Detect_device($hWnd, $Msg, $wParam, $lParam)

    Local $DEV_BROADCAST_GetDeviceType = DllStructCreate($tagDEV_BROADCAST_HDR, $lParam)
    Local $DeviceType = DllStructGetData($DEV_BROADCAST_GetDeviceType, "devicetype")

    Switch $wParam
        Case $DBT_DEVICEARRIVAL

            if $DeviceType = 5 Then
            $dddd = DllStructCreate($tagDEV_BROADCAST_DEVICEINTERFACE,$lParam)
            msgbox(0,"",'Detect device - ' & DEVTYP($DeviceType)&$dddd.name)
            ConsoleWrite('Detect device - ' & DEVTYP($DeviceType)&$dddd.name&@CRLF)
            EndIf

        Case $DBT_DEVICEQUERYREMOVE

        Case $DBT_DEVICEQUERYREMOVEFAILED

        Case $DBT_DEVICEREMOVEPENDING

        Case $DBT_DEVICEREMOVECOMPLETE
            if $DeviceType = 5 Then
            $dddd = DllStructCreate($tagDEV_BROADCAST_DEVICEINTERFACE,$lParam)
            msgbox(0,"",'Detect device remove - ' & DEVTYP($DeviceType)&$dddd.name)
            ConsoleWrite('Detect device remove - ' & DEVTYP($DeviceType)&$dddd.name&@CRLF)
            EndIf

        Case $DBT_DEVICETYPESPECIFIC

        Case $DBT_DEVNODES_CHANGED

        Case $DBT_CONFIGCHANGECANCELED

        Case $DBT_CONFIGCHANGED

        Case $DBT_CUSTOMEVENT

        Case $DBT_QUERYCHANGECONFIG

        Case $DBT_USERDEFINED

    EndSwitch
    Return 'GUI_RUNDEFMSG'
EndFunc


Func DEVTYP($lParam)
    Switch $lParam
        Case $DBT_DEVTYP_OEM
            Return "Type ( OEM ) "

        Case $DBT_DEVTYP_DEVNODE
            Return "Type ( DEVNODE ) "

        Case $DBT_DEVTYP_VOLUME
            Return "Type ( VOLUME ) "

        Case $DBT_DEVTYP_PORT
            Return "Type ( PORT ) "

        Case $DBT_DEVTYP_NET
            Return "Type ( NET ) "

        Case $DBT_DEVTYP_HANDLE
            Return "Type ( HANDLE ) "

        Case $DBT_DEVTYP_DEVICEINTERFACE
            Return "Type ( DEVICEINTERFACE ) "

        Case $DBT_DEVTYP_DEVINST
            Return "Type ( DEVINST ) "
    EndSwitch
EndFunc

Func DoRegisterDeviceInterface($hGUI, $Device_Class_GUID, $flags )
    Local $ptrDEV_BROADCAST_DEVICEINTERFACE  = DllStructGetPtr($DEV_BROADCAST_DEVICEINTERFACE)
    Local $Size = DllStructGetSize($DEV_BROADCAST_DEVICEINTERFACE)

    DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "size", $Size)
    DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "devicetype", $DBT_DEVTYP_DEVICEINTERFACE)
    Local $CameraGUID =_WinAPI_GUIDFromString($Device_Class_GUID)
    DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "Data1", $CameraGUID.Data1)
    DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "Data2", $CameraGUID.Data2)
    DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "Data3", $CameraGUID.Data3)
    DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "Data4", $CameraGUID.Data4)

    Local $RDNhandle = DllCall("User32.dll", "handle", "RegisterDeviceNotification", "hwnd", $hGUI, "ptr", $ptrDEV_BROADCAST_DEVICEINTERFACE, "long", $flags)
    _ArrayAdd($RegisterDeviceInterface_Handle, $RDNhandle[0]&"|"&StringUpper($Device_Class_GUID))

EndFunc

Func UnregisterDeviceNotification($GUID)
    Local $delete_number = _ArraySearch($RegisterDeviceInterface_Handle,$GUID, 0, 0, 0, 0, 1, 2)
    Local $check = DllCall("User32.dll", "UINT", "UnregisterDeviceNotification", "handle", $RegisterDeviceInterface_Handle[$delete_number][0])
    _ArrayDelete($RegisterDeviceInterface_Handle,$delete_number)
EndFunc


Func _exit()
    Exit
EndFunc

 

Edited by konya

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...