Jump to content

Detecting USB device connects & disconnects and log them to a file


Rumbles
 Share

Recommended Posts

Hello,

I have been looking at a way to do this for a while, and I've been looking at a lot of >examples which do >similar to what I was after, and while I understand some of what they are doing, I think my lack of programming/scripting experience lets me down in the end. I am unsure as to why some scipts I have seen call GUI objects, when to my mind this should be a service that the user shouldn't see (unless I choose to alert them), I am also concerned that a lot of the examples I have seen are from 5-7 years ago, since the code could have changed quite a lot in that time I expect that I would struggle to simply copy & paste other code, also I would rather not just copy other peoples work and try to glue it together, if I can understand the process I would be much happier!

The requirements I have for this script are:

  • It needs to detect a USB connect/disconnect event (all USB devices, including Keyboards and Hubs, not just USB Removable media)
  • It needs to log this information to a file, with a timestamp
  • Ideally it should be able to print some information which will help identify the device (e.g. dbcc info, or a serial number & friendly name)

 

So far I have got the following code together, from some examples I have seen:

#include <file.au3>

Local $sLogPath = "C:\Windows\Logs\usbconnections.log"

_FileWriteLog( $sLogPath, "Test" )

Dim $DBT_DEVICEARRIVAL = "0x00008000"
Dim $DBT_DEVICECOMPLETEREMOVAL = "0x00008004"
Dim $USB_ATTENTION = "0x00000007"
Dim $WM_DEVICECHANGE = 0x0219

I know I haven't got much down so far, but I have got the printing to a file with a timestamp part nailed!

The next bit I am less than certain with though, how do I detect a USB connect/disconnect event, I know the variables I have declared should be vital in seeing this process happen, but I am currently unsure about how next to proceed.

I want to be able to understand the script as well, I have looked at some other similar scripts (one in AHK which did a lot of this, but logged to a GUI) which I really couldn't get my head around it and I felt I would be better off starting from scratch if I wanted to udnerstand how this worked.

I'm quite happy read through docs, but at the moment I am at a loss as to where to go to next. Any tips on functions which I can use for this job, or other scripts which have explainations as to how they work would be appreciated.

Just to clarify why I am trying to do this, the end goal here is to have the log file collected by nxlog, nxlog will then encrypt the log file and ship that on to a centralised logging system (logstash), which will be able to parse the log and index it, as well as send an alert out if we need it to do so.

Link to comment
Share on other sites

Checkout RegisterDeviceNotifications in my sig.

 

Thanks for the response, it looks like a great little script. But as far as I can tell this script detects changes to USB Removable storage devices (It doesn't detect my keyboard/hub being dis/connected), do you think the same method you use in this script could be applied to detect all USB device connections & disconnections? Or is that outside of the scope of the methods used here?

Thanks for the help, I appreciate it!

Link to comment
Share on other sites

Windows has this feature built in, perhaps you could just use AutoIt to automate the activation of the USB trace event logging in Windows, then forward the logs.

http://msdn.microsoft.com/en-us/library/windows/hardware/jj151573(v=vs.85).aspx

If @error Then
    MsgBox(262192, "", @ComputerName & " slaps " & @UserName & " around a bit with a large trout!")
EndIf

"Yeah yeah yeah patience, how long will that take?"  -Ed Gruberman

REAL search results  |  SciTE4AutoIt3 Editor Full Version

Link to comment
Share on other sites

alienclone thanks for the info, I will look in to that further. Do you know if it's possible to use this functionality with AutoIT at all? andrewz thanks for the link to the script, but this is a script which looks for USB removable storage, not something which looks for all USB connect & disconnect events as far as I can see
Link to comment
Share on other sites

http://azjio.narod.ru/autoit3_docs/userfunctions/WM_DEVICECHANGE.htm

$DBT_DEVNODES_CHANGED = 0x0007

        $DBT_DEVTYP_OEM = 0x00000000 ; oem-defined device type
        $DBT_DEVTYP_DEVNODE = 0x00000001 ; devnode number
        $DBT_DEVTYP_VOLUME = 0x00000002; logical partition
        $DBT_DEVTYP_PORT = 0x00000003 ; serial, parallel
        $DBT_DEVTYP_NET = 0x00000004 ; network resource

Make experiments

Link to comment
Share on other sites

http://azjio.narod.ru/autoit3_docs/userfunctions/WM_DEVICECHANGE.htm

$DBT_DEVNODES_CHANGED = 0x0007

        $DBT_DEVTYP_OEM = 0x00000000 ; oem-defined device type
        $DBT_DEVTYP_DEVNODE = 0x00000001 ; devnode number
        $DBT_DEVTYP_VOLUME = 0x00000002; logical partition
        $DBT_DEVTYP_PORT = 0x00000003 ; serial, parallel
        $DBT_DEVTYP_NET = 0x00000004 ; network resource

Make experiments

 

Thanks, I've copied the example script from that site, and I can get this to work:

#include <GUIConstantsEx.au3>

Global Const $WM_DEVICECHANGE = 0x0219
Global Const $DBT_DEVICEARRIVAL = 0x8000 ; Found New Hardware
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; The device is disconnected

Global Const $DBT_DEVNODES_CHANGED = 0x0007
Global Const $DBT_DEVTYP_OEM = 0x00000000 ; oem-defined device type
Global Const $DBT_DEVTYP_DEVNODE = 0x00000001 ; devnode number
Global Const $DBT_DEVTYP_VOLUME = 0x00000002; logical partition
Global Const $DBT_DEVTYP_PORT = 0x00000003 ; serial, parallel
Global Const $DBT_DEVTYP_NET = 0x00000004 ; network resource

Global $k = 0

$Gui = GUICreate("WM_DEVICECHANGE", 370, 140)
GUICtrlCreateLabel('WM_DEVICECHANGE function is performed when connecting or disconnecting devices to the system. Try inserting the stick', 5, 5, 360, 70)

GUISetState()
GUIRegisterMsg($WM_DEVICECHANGE, "WM_DEVICECHANGE")

Do
Until GUIGetMsg() = -3

Func WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam)
    $k += 1
    WinSetTitle($Gui, '', 'Connection ' & $k)

    If ($wParam = $DBT_DEVICEARRIVAL) Or ($wParam = $DBT_DEVICEREMOVECOMPLETE) Then
        Local $DEV_BROADCAST_VOLUME = DllStructCreate("int dbcvsize;int dbcvdevicetype;int dbcvreserved;int dbcvunitmask;" & _
                "ushort dbcvflags", $lParam)
        Local $iDriveType = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvdevicetype")
    Else
        Return $GUI_RUNDEFMSG
    EndIf

    ; If the device is not a logical drive, the output of the function
    If $iDriveType <> $DBT_DEVTYP_VOLUME Then Return $GUI_RUNDEFMSG

    Local $iMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvunitmask")
    $iMask = Log($iMask) / Log(2)

    Local $iDrive = Chr(65 + $iMask) & ":"

    Switch $wParam
        Case $DBT_DEVICEARRIVAL ; detection device
            TrayTip("WM_DEVICECHANGE", "device connected", 5, 1)

        Case $DBT_DEVICEREMOVECOMPLETE ; Disconnecting
            TrayTip("WM_DEVICECHANGE", "device disconnected", 5, 2)
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc

This updates the tray message when a device is connected & disconnected.

But when I try using the extra functions you have mentioned I don't get anywhere... :

#include <GUIConstantsEx.au3>

Global Const $WM_DEVICECHANGE = 0x0219
Global Const $DBT_DEVICEARRIVAL = 0x8000 ; Found New Hardware
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; The device is disconnected

Global Const $DBT_DEVNODES_CHANGED = 0x0007
Global Const $DBT_DEVTYP_OEM = 0x00000000 ; oem-defined device type
Global Const $DBT_DEVTYP_DEVNODE = 0x00000001 ; devnode number
Global Const $DBT_DEVTYP_VOLUME = 0x00000002; logical partition
Global Const $DBT_DEVTYP_PORT = 0x00000003 ; serial, parallel
Global Const $DBT_DEVTYP_NET = 0x00000004 ; network resource

Global $k = 0

$Gui = GUICreate("WM_DEVICECHANGE", 370, 140)
GUICtrlCreateLabel('WM_DEVICECHANGE function is performed when connecting or disconnecting devices to the system. Try inserting the stick', 5, 5, 360, 70)

GUISetState()
GUIRegisterMsg($WM_DEVICECHANGE, "WM_DEVICECHANGE")

Do
Until GUIGetMsg() = -3

Func WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam)
    $k += 1
    WinSetTitle($Gui, '', 'Connection ' & $k)

    If ($lParam = $DBT_DEVNODES_CHANGED) Then
        Local $DEV_BROADCAST_VOLUME = DllStructCreate("int dbcvsize;int dbcvdevicetype;int dbcvreserved;int dbcvunitmask;" & _
                "ushort dbcvflags", $lParam)
        Local $iDriveType = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvdevicetype")
    Else
        Return $GUI_RUNDEFMSG
    EndIf

    ; If the device is not a logical drive, the output of the function
    If $iDriveType <> $DBT_DEVTYP_VOLUME Then Return $GUI_RUNDEFMSG

    Local $iMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvunitmask")
    $iMask = Log($iMask) / Log(2)

    Local $iDrive = Chr(65 + $iMask) & ":"

    Switch $lParam
        Case $DBT_DEVNODES_CHANGED ; detection device
            TrayTip("WM_DEVICECHANGE", "device connected", 5, 1)

        ;Case $DBT_DEVICEREMOVECOMPLETE ; Disconnecting
        ;    TrayTip("WM_DEVICECHANGE", "device disconnected", 5, 2)
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc

For example here I have replaced some wParam objects with lParam objects and I am trying to trigger off $DBT_DEVNODES_CHANGED but nothing hapens when I connect/disconnect the device.... I'm not really sure what I am doing wrong here....

I was also looking at how you might run something like this as a service, and I found this >page which might be a good way to get the functions to run in the background. Would you say this is a good way to go? It seems pretty complicated, and since I'm confused with what I have so far, I am not sure how well I will get on with this other script :)

Thanks for the help so far!

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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