Joline Posted September 30, 2010 Share Posted September 30, 2010 (edited) I want to use the "RegisterDeviceNotification" function from "user32.dll" to get a notification if a usb device is attempt to remove (WM_DEVICECHANGE -> $DBT_DEVICEQUERYREMOVE). Can anybody help me to translate the Visual Basic call into a correct AutoIt-call? expandcollapse popupPublic Type DEV_BROADCAST_DEVICEINTERFACE dbcc_size As Long dbcc_devicetype As Long dbcc_reserved As Long dbcc_classguid As GUID dbcc_name As Long End Type Public Const DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = &H4 Public Const DEVICE_NOTIFY_WINDOW_HANDLE = 0 Public Const DBT_DEVTYP_DEVICEINTERFACE As Long = 5 Public Declare Function RegisterDeviceNotification Lib "user32.dll" _ Alias "RegisterDeviceNotificationA" ( _ ByVal hRecipient As Long, _ NotificationFilter As Any, _ ByVal Flags As Long) As Long Public Declare Function UnregisterDeviceNotification Lib "user32.dll" _ (ByVal hRecipient As Long) As Long Public Function DoRegisterDeviceInterface(hWnd As Long, ByRef hDevNotify As Long) As Boolean Dim NotificationFilter As DEV_BROADCAST_DEVICEINTERFACE NotificationFilter.dbcc_size = Len(NotificationFilter) NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE hDevNotify = RegisterDeviceNotification(hWnd, NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE Or DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) If hDevNotify = 0 Then MsgBox "RegisterDeviceNotification failed: " & CStr(Err.LastDllError), vbOKOnly DoRegisterDeviceInterface = False Exit Function End If DoRegisterDeviceInterface = True End Function Dim hDevNotify As Long Sub Main() '... Call DoRegisterDeviceInterface(Me.hWnd, hDevNotify) '... Call UnregisterDeviceNotification(hDevNotify) '... End Sub I've no idea how to define a type DEV_BROADCAST_DEVICEINTERFACE, how to fill it and how to pass all parameters to the function call. Dim $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = &H4 Dim $DEVICE_NOTIFY_WINDOW_HANDLE = 0 Dim $DBT_DEVTYP_DEVICEINTERFACE As Long = 5 $hwnd = WinGetHandle(???) ; How to find my own window handle? $Flags = $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES + $DEVICE_NOTIFY_WINDOW_HANDLE ; How to do the boolean operation "OR"? $hDevNotify = DllCall("user32.dll", "long", "RegisterDeviceNotification", "hwnd", $hwnd, ??? , "long", $Flags) ; How to pass a type/structure? $result = DllCall("user32.dll", "long", "UnregisterDeviceNotification", "hRecipient", $hDevNotify) Thank you. Joline Edited October 11, 2010 by Joline Link to comment Share on other sites More sharing options...
jaberwacky Posted October 1, 2010 Share Posted October 1, 2010 (edited) I'd imagine that you could do something like this: #cs this is a struct -- I assume Public Type DEV_BROADCAST_DEVICEINTERFACE dbcc_size As Long dbcc_devicetype As Long dbcc_reserved As Long dbcc_classguid As GUID dbcc_name As Long End Type #ce ; now you can store and retrieve data with DllStructSetData and DllStructGetData DllStructCreate("long dbcc_size; long dbcc_devicetype; long dbcc_reserved; int dbcc_classguid; long dbcc_name") 1) Use DllStructGetPtr() 2) Pass that pointer to a struct when using DllCall() quick example: $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate("long dbcc_size; long dbcc_devicetype; long dbcc_reserved; int dbcc_classguid; long dbcc_name") $DllPtr = DllStructGetPtr($DEV_BROADCAST_DEVICEINTERFACE) $hDevNotify = DllCall("user32.dll", "long", "RegisterDeviceNotification", "hwnd", $hwnd, $DllPtr , "long", $Flags) Edited October 1, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Joline Posted October 1, 2010 Author Share Posted October 1, 2010 Thanks for your answer. This is my code now: #include <GUIConstantsEx.au3> Global $aDrives = DriveGetDrive('ALL') Global Const $WM_DEVICECHANGE = 0x0219 GUICreate('USB-Handler') GUIRegisterMsg($WM_DEVICECHANGE, 'MY_WM_DEVICECHANGE') ;ToDo -> RegisterDeviceNotification Global Const $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004 Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000 Global Const $DBT_DEVTYP_DEVICEINTERFACE = 0x00000005 $hWnd = WinGetHandle('USB-Handler') ConsoleWrite("$hWnd: " & $hWnd & @CR) $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate("long dbcc_size; long dbcc_devicetype; long dbcc_reserved; int dbcc_classguid; long dbcc_name") $DllPtr = DllStructGetPtr($DEV_BROADCAST_DEVICEINTERFACE) ConsoleWrite("$DllPtr: " & $DllPtr & @CR) $Flags = $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES + $DEVICE_NOTIFY_WINDOW_HANDLE ; How to do the boolean operation "OR"? ConsoleWrite("$Flags: " & $Flags & @CR) $hDevNotify = DllCall("user32.dll", "long", "RegisterDeviceNotification", "hwnd", $hWnd, $DllPtr , "long", $Flags) ConsoleWrite("$hDevNotify: " & $hDevNotify & @CR) While 1 Sleep(100) WEnd Func MY_WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) ;ToDo ... EndFunc ;==>MY_WM_DEVICECHANGE But unfortunately the return code of the DllCall "RegisterDeviceNotification" is 0. $hWnd: 0x008109E6 $DllPtr: 0x00CD69A0 $Flags: 4 $hDevNotify: 0 How can I find out what is wrong? Best regards Joline Link to comment Share on other sites More sharing options...
jaberwacky Posted October 1, 2010 Share Posted October 1, 2010 (edited) OK, I think I made some progress here. Please run this and tell me if it returns anything useful. expandcollapse popup#include <Array.au3> Global $aDrives = DriveGetDrive("ALL") Global $hWnd = GUICreate("USB-Handler") Global Const $WM_DEVICECHANGE = 0x0219 GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE") ;ToDo -> RegisterDeviceNotification Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000 Global Const $DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001 Global Const $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004 Global Const $DBT_DEVTYP_DEVICEINTERFACE = 0x00000005 Global Const $Flags = BitOR($DEVICE_NOTIFY_ALL_INTERFACE_CLASSES, $DEVICE_NOTIFY_WINDOW_HANDLE) Global $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate("dword dbcc_size; dword dbcc_devicetype; dword dbcc_reserved; char dbcc_classguid[128]; char dbcc_name[1]") ;~ ConsoleWrite("$DEV_BROADCAST_DEVICEINTERFACE @ERROR: " & @error & @CR) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_size", DllStructGetSize($DEV_BROADCAST_DEVICEINTERFACE)) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_devicetype", $DBT_DEVTYP_DEVICEINTERFACE) Global $PtrDEV_BROADCAST_DEVICEINTERFACE = DllStructGetPtr($DEV_BROADCAST_DEVICEINTERFACE) Global $hDevNotify = DllCall("user32.dll", "handle", "RegisterDeviceNotification", "handle", $hWnd, "ptr", $PtrDEV_BROADCAST_DEVICEINTERFACE, "dword", $Flags) ConsoleWrite("USB-Handler hwnd: " & $hWnd & @CR) ConsoleWrite("$PtrDEV_BROADCAST_DEVICEINTERFACE: " & $PtrDEV_BROADCAST_DEVICEINTERFACE & @CR) ConsoleWrite("$Flags: " & $Flags & @CR) ConsoleWrite("$hDevNotify: " & $hDevNotify[0] & @CR) _ArrayDisplay($hDevNotify) While 1 Sleep(100) WEnd Func MY_WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) ;ToDo ... ConsoleWrite("Something" & @CR) EndFunc ;==>MY_WM_DEVICECHANGE Oh and when you run the script, insert or disconnect a usb device. Edited October 2, 2010 by jaberwocky6669 Xandy 1 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Joline Posted October 2, 2010 Author Share Posted October 2, 2010 Oh, the $hDevNotify has a value now. Great. But unfortunately it doesn't work as expected. expandcollapse popup#include <Array.au3> Global $aDrives = DriveGetDrive("ALL") Global $hWnd = GUICreate("USB-Handler") Global Const $WM_DEVICECHANGE = 0x0219 GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE") ;ToDo -> RegisterDeviceNotification Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000 Global Const $DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001 Global Const $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004 Global Const $DBT_DEVTYP_DEVICEINTERFACE = 0x00000005 Global Const $Flags = BitOR($DEVICE_NOTIFY_ALL_INTERFACE_CLASSES, $DEVICE_NOTIFY_WINDOW_HANDLE) Global $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate("dword dbcc_size; dword dbcc_devicetype; dword dbcc_reserved; char dbcc_classguid[128]; char dbcc_name[1]") ;~ ConsoleWrite("$DEV_BROADCAST_DEVICEINTERFACE @ERROR: " & @error & @CR) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_size", DllStructGetSize($DEV_BROADCAST_DEVICEINTERFACE)) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_devicetype", $DBT_DEVTYP_DEVICEINTERFACE) Global $PtrDEV_BROADCAST_DEVICEINTERFACE = DllStructGetPtr($DEV_BROADCAST_DEVICEINTERFACE) Global $hDevNotify = DllCall("user32.dll", "handle", "RegisterDeviceNotification", "handle", $hWnd, "ptr", $PtrDEV_BROADCAST_DEVICEINTERFACE, "dword", $Flags) ConsoleWrite("USB-Handler hwnd: " & $hWnd & @CR) ConsoleWrite("$PtrDEV_BROADCAST_DEVICEINTERFACE: " & $PtrDEV_BROADCAST_DEVICEINTERFACE & @CR) ConsoleWrite("$Flags: " & $Flags & @CR) ConsoleWrite("$hDevNotify: " & $hDevNotify[0] & @CR) _ArrayDisplay($hDevNotify) While 1 Sleep(100) WEnd Func MY_WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) ;ToDo ... Local Const $DBT_DEVICEARRIVAL = 0x8000 ; A device or piece of media has been inserted and is now available. Local Const $DBT_DEVICEQUERYREMOVE = 0x8001 ; A device or piece of media is attemped to remove. Local Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; A device or piece of media has been removed. ConsoleWrite("$wParam: " & $wParam & @CR) EndFunc ;==>MY_WM_DEVICECHANGE I get notifications for DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE but not for DBT_DEVICEQUERYREMOVE. This is the same behaviour as without "RegisterDeviceNotification". So I think RegisterDeviceNotification doesn't work properly. Applications can use the RegisterDeviceNotification function to register to receive device notifications. DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE will get EVERY application even without RegisterDeviceNotification. If the application is registered and the DBT_DEVICEQUERYREMOVE is received, a permission is requested to remove a device or piece of media. Any application can deny this request and cancel the removal. Maybe a parameter is missing or wrong. So I'll try a little bit but without any real idea. Link to comment Share on other sites More sharing options...
jaberwacky Posted October 3, 2010 Share Posted October 3, 2010 Ok, maybe I don't understand fully what it is that you're trying to achieve. Could you break it down for me more clearly? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
jaberwacky Posted October 3, 2010 Share Posted October 3, 2010 Does this bring you any closer? expandcollapse popup#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 <Misc.au3> _Singleton(@ScriptName) HotKeySet("{ESC}", "term") Global $LastErr Global $hWnd = GUICreate("USB-Handler") Global Const $WM_DEVICECHANGE = 0x0219 Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000 Global Const $DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001 Global Const $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004 Global Const $InterfaceClassGuid = CreateGUIDStruct("D16A55E8-1059-11D2-8FFD-00A0C9A06D32") ;~ Global Const $Flags = BitOr($DEVICE_NOTIFY_WINDOW_HANDLE, $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) Global Const $Flags = $DEVICE_NOTIFY_WINDOW_HANDLE Global Const $DBT_DEVTYP_OEM = 0x00000000 Global Const $DBT_DEVTYP_VOLUME = 0x00000002 Global Const $DBT_DEVTYP_PORT = 0x00000003 Global Const $DBT_DEVTYP_DEVICEINTERFACE = 0x00000005 Global Const $DBT_DEVTYP_HANDLE = 0x00000006 Global $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate(StringStripWS("uint dbcc_size; uint dbcc_devicetype; uint dbcc_reserved; char dbcc_classguid[128]; char dbcc_name[1]", 7)) ;~ ConsoleWrite("$DEV_BROADCAST_DEVICEINTERFACE @ERROR: " & @error & @CR) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_size", DllStructGetSize($DEV_BROADCAST_DEVICEINTERFACE)) ;~ ConsoleWrite("@ERROR: " & @error & @CR) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_devicetype", $DBT_DEVTYP_DEVICEINTERFACE) ;~ ConsoleWrite("@ERROR: " & @error & @CR) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_classguid", $InterfaceClassGuid) ;~ ConsoleWrite("@ERROR: " & @error & @CR) Global $PtrDEV_BROADCAST_DEVICEINTERFACE = DllStructGetPtr($DEV_BROADCAST_DEVICEINTERFACE) Global Const $User32 = DllOpen("User32.dll") Global Const $hDevNotify = DllCall($User32, "handle", "RegisterDeviceNotificationA", "handle", $hWnd, "ptr", $PtrDEV_BROADCAST_DEVICEINTERFACE, "long", $Flags) ConsoleWrite("$hDevNotify: " & $hDevNotify[0] & " @error: " & @error & @CR) If $hDevNotify[0] Then OnAutoItExitRegister("UnRegisterDevice") GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE") Else ConsoleWrite("Bye" & @LF) Exit EndIf While 1 Sleep(100) WEnd Func MY_WM_DEVICECHANGE(Const $hWnd, Const $Msg, Const $wParam, Const $lParam) Local Const $DBT_DEVICEARRIVAL = 0x8000 ; A device or piece of media has been inserted and is now available. Local Const $DBT_DEVICEQUERYREMOVE = 0x8001 ; A device or piece of media is attemped to remove. Local Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; A device or piece of media has been removed. Switch $wParam Case $DBT_DEVICEARRIVAL ConsoleWrite(@LF & "DEVICEARRIVAL" & @LF) ConsoleWrite(GUIGetMsg() & @LF) DeviceData() Case $DBT_DEVICEQUERYREMOVE ConsoleWrite(@LF & "DEVICEQUERYREMOVE" & @LF) ConsoleWrite(GUIGetMsg() & @LF) DeviceData() Case $DBT_DEVICEREMOVECOMPLETE ConsoleWrite(@LF & "DEVICEREMOVECOMPLETE" & @LF) ConsoleWrite(GUIGetMsg() & @LF) DeviceData() EndSwitch EndFunc ;==>MY_WM_DEVICECHANGE Func DeviceData() ConsoleWrite("dbcc_size: " & DllStructGetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_size") & @LF) ConsoleWrite("dbcc_devicetype: " & DllStructGetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_devicetype") & @LF) ConsoleWrite("dbcc_classguid: " & DllStructGetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_classguid") & @LF) ConsoleWrite("dbcc_dbcc_name: " & DllStructGetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_dbcc_name") & @LF) EndFunc ;==>DeviceData Func term() Exit EndFunc ;==>term Func UnRegisterDevice() Global Const $UnregStatus = DllCall($User32, "BOOL", "UnRegisterDeviceNotificationA", "HDEVNOTIFY", $hDevNotify[0]) ConsoleWrite($UnregStatus & " @error: " & @error & @CR) $LastErr = DllCall("Kernal32.dll", "dword", "GetLastError") ;~ ConsoleWrite("@error: " & @error & @CR) ConsoleWrite("Last Error: " & $LastErr & @CR) DllClose($User32) GUIRegisterMsg($WM_DEVICECHANGE, "") EndFunc ;==>UnRegisterDevice ; = Function ========================================================================================================== ; Name .....: CreateGUIDStruct ; Syntax ...: CreateGUIDStruct($GUIDstr) ; Param(s) .: $GUIDstr -- String containing a GUID. Cannot be longer or shorter than 36 characters. ; Success ..: A pointer to a _GUID struct containing the GUID string. ; Fail .....: 1 & @error: -1: String was formatted incorrectly. ; Desc. ....: http://msdn.microsoft.com/en-us/library/aa373931%28VS.85%29.aspx Func CreateGUIDStruct(Const $GUIDstr) Switch (IsString($GUIDstr)) And ($GUIDstr <> '') And ($GUIDstr <> ' ') And (StringLen($GUIDstr) = 36) Case 1 Local Const $tmpGUIDstr = StringStripWS($GUIDstr, 8) Local Const $GUIDArr = StringSplit($tmpGUIDstr, '-', 2) Local Const $dllGUID = DllStructCreate("dword Data1; word Data2; word Data3; byte Data4[8]") If StringLen($GUIDArr[0]) = 8 Then DllStructSetData($dllGUID, "Data1", $GUIDArr[0]) EndIf If StringLen($GUIDArr[1]) = 4 Then DllStructSetData($dllGUID, "Data2", $GUIDArr[1]) EndIf If StringLen($GUIDArr[2]) = 4 Then DllStructSetData($dllGUID, "Data3", $GUIDArr[2]) EndIf If StringLen($GUIDArr[3]) = 4 Then DllStructSetData($dllGUID, "Data4", StringLeft($GUIDArr[3], 2), 1) DllStructSetData($dllGUID, "Data4", StringRight($GUIDArr[3], 2), 2) EndIf If StringLen($GUIDArr[4]) = 12 Then DllStructSetData($dllGUID, "Data4", StringLeft($GUIDArr[4], 2), 3) DllStructSetData($dllGUID, "Data4", StringTrimLeft(StringTrimRight($GUIDArr[4], 2), 8), 4) DllStructSetData($dllGUID, "Data4", StringTrimLeft(StringTrimRight($GUIDArr[4], 4), 6), 5) DllStructSetData($dllGUID, "Data4", StringTrimLeft(StringTrimRight($GUIDArr[4], 6), 4), 6) DllStructSetData($dllGUID, "Data4", StringTrimLeft(StringTrimRight($GUIDArr[4], 8), 2), 7) DllStructSetData($dllGUID, "Data4", StringRight($GUIDArr[4], 2), 8) EndIf Return DllStructGetPtr($dllGUID) Case 0 Return SetError(-1, 0, 1) EndSwitch EndFunc ;==>CreateGUIDStruct Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Joline Posted October 3, 2010 Author Share Posted October 3, 2010 Does this bring you any closer?Unfortunately no. The goal is: I want to safe some files on the USB device BEFORE the USB device is removed. The notification DBT_DEVICEREMOVECOMPLETE is to late for that because there is no access to the device anymore. So if the USB device is attempted to remove (Left mouse click on tray icon and click "remove") I want to be informed about that (DBT_DEVICEQUERYREMOVE) so that I can do something and after that I will release the USB device.What I've now:1. A USB device was inserted (DBT_DEVICEARRIVAL). This will happen just if I plug in a USB device. -> working.2. A USB device is attempted to remove (DBT_DEVICEQUERYREMOVE). Left mouse click on tray icon and click "remove". (After doing this I get immediately the information about finishing remove.) -> not working.3. A USB device was removed (DBT_DEVICEREMOVECOMPLETE). I get this notification if I pull out (or safely remove -> click on tray icon) a USB device. (But this is to late to d something with this device.) -> working.Because the notifications DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE get every application. To receive any other notification (like DBT_DEVICEQUERYREMOVE) the application has to call RegisterDeviceNotification. And if I never get DBT_DEVICEQUERYREMOVE I think the registration was not really successful. But otherwise there is no error (=0). Curious. Link to comment Share on other sites More sharing options...
jaberwacky Posted October 3, 2010 Share Posted October 3, 2010 (edited) From what I gather, DBT_DEVICEQUERYREMOVE will only be announced when the driver for the usb is uninstalled. Well, I really wanted to help you out but I've come to the limits of my knowledge. There are some people here that are far more advanced than myself. Hopefully they will chime in. Edited October 3, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
wolf9228 Posted October 3, 2010 Share Posted October 3, 2010 (edited) I want to use the "RegisterDeviceNotification" function from "user32.dll" to get a notification if a usb device is attempt to remove (WM_DEVICECHANGE -> $DBT_DEVICEQUERYREMOVE). Can anybody help me to translate the Visual Basic call into a correct AutoIt-call? expandcollapse popupPublic Type DEV_BROADCAST_DEVICEINTERFACE dbcc_size As Long dbcc_devicetype As Long dbcc_reserved As Long dbcc_classguid As GUID dbcc_name As Long End Type Public Const DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = &H4 Public Const DEVICE_NOTIFY_WINDOW_HANDLE = 0 Public Const DBT_DEVTYP_DEVICEINTERFACE As Long = 5 Public Declare Function RegisterDeviceNotification Lib "user32.dll" _ Alias "RegisterDeviceNotificationA" ( _ ByVal hRecipient As Long, _ NotificationFilter As Any, _ ByVal Flags As Long) As Long Public Declare Function UnregisterDeviceNotification Lib "user32.dll" _ (ByVal hRecipient As Long) As Long Public Function DoRegisterDeviceInterface(hWnd As Long, ByRef hDevNotify As Long) As Boolean Dim NotificationFilter As DEV_BROADCAST_DEVICEINTERFACE NotificationFilter.dbcc_size = Len(NotificationFilter) NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE hDevNotify = RegisterDeviceNotification(hWnd, NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE Or DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) If hDevNotify = 0 Then MsgBox "RegisterDeviceNotification failed: " & CStr(Err.LastDllError), vbOKOnly DoRegisterDeviceInterface = False Exit Function End If DoRegisterDeviceInterface = True End Function Dim hDevNotify As Long Sub Main() '... Call DoRegisterDeviceInterface(Me.hWnd, hDevNotify) '... Call UnregisterDeviceNotification(hDevNotify) '... End Sub I've no idea how to define a type DEV_BROADCAST_DEVICEINTERFACE, how to fill it and how to pass all parameters to the function call. Dim $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = &H4 Dim $DEVICE_NOTIFY_WINDOW_HANDLE = 0 Dim $DBT_DEVTYP_DEVICEINTERFACE As Long = 5 $hwnd = WinGetHandle(???) ; How to find my own window handle? $Flags = $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES + $DEVICE_NOTIFY_WINDOW_HANDLE ; How to do the boolean operation "OR"? $hDevNotify = DllCall("user32.dll", "long", "RegisterDeviceNotification", "hwnd", $hwnd, ??? , "long", $Flags) ; How to pass a type/structure? $result = DllCall("user32.dll", "long", "UnregisterDeviceNotification", "hRecipient", $hDevNotify) Thank you. Joline expandcollapse popup#Include <WinAPI.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $TegDEV_BROADCAST_DEVICEINTERFACE = _ "long dbccsize;long dbccdevicetype;long dbccreserved;" & _ "int Data1;short Data2;short Data3;byte Data4[8];long dbccname" Const $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004 Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0 Const $DBT_DEVTYP_DEVICEINTERFACE = 5 Main() Func DoRegisterDeviceInterface($hWnd, ByRef $hDevNotify) $NotificationFilter = DllStructCreate($TegDEV_BROADCAST_DEVICEINTERFACE) DllStructSetData($NotificationFilter,"dbccsize",DllStructGetSize($NotificationFilter)) DllStructSetData($NotificationFilter,"dbccdevicetype",$DBT_DEVTYP_DEVICEINTERFACE) $hDevNotify = DllCall("User32.dll","HANDLE","RegisterDeviceNotification","HANDLE",$hWnd,"ptr", _ DllStructGetPtr($NotificationFilter),"DWORD",BitOR($DEVICE_NOTIFY_WINDOW_HANDLE,$DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)) if (@error) Then $hDevNotify = 0 Else $hDevNotify = $hDevNotify[0] EndIf If $hDevNotify = 0 Then MsgBox(0,"MSG","RegisterDeviceNotification failed: " & _WinAPI_GetLastError()) $DoRegisterDeviceInterface = False Return $DoRegisterDeviceInterface EndIf $DoRegisterDeviceInterface = True Return $DoRegisterDeviceInterface EndFunc Func Main() Dim $hDevNotify $hWnd = GUICreate("My GUI") GUISetState(@SW_SHOW) Local $WM_DEVICECHANGE = 0x0219 GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE") ;'... $DoRegisterDeviceInterface = DoRegisterDeviceInterface($hWnd, $hDevNotify) ;'... ;DllCall("User32.dll","HANDLE","UnregisterDeviceNotification","HANDLE",$hDevNotify) ;'... MsgBox(0,"MSG",$DoRegisterDeviceInterface) While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd GUIDelete() Exit EndFunc Func MY_WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) Local $DBT_CONFIGCHANGECANCELED = 0x0019 , _ $DBT_CONFIGCHANGED = 0x0018 , _ $DBT_CUSTOMEVENT = 0x8006 , _ $DBT_DEVICEARRIVAL = 0x8000 , _ $DBT_DEVICEQUERYREMOVE = 0x8001 , _ $DBT_DEVICEQUERYREMOVEFAILED = 0x8002 , _ $DBT_DEVICEREMOVECOMPLETE = 0x8004 , _ $DBT_DEVICEREMOVEPENDING = 0x8003 , _ $DBT_DEVICETYPESPECIFIC = 0x8005 , _ $DBT_DEVNODES_CHANGED = 0x0007 , _ $DBT_QUERYCHANGECONFIG = 0x0017 , _ $DBT_USERDEFINED = 0xFFFF Switch($wParam) Case $DBT_CONFIGCHANGECANCELED MsgBox(0,"MSG","DBT_CONFIGCHANGECANCELED") Case $DBT_CONFIGCHANGED MsgBox(0,"MSG","DBT_CONFIGCHANGED") Case $DBT_CUSTOMEVENT MsgBox(0,"MSG","DBT_CUSTOMEVENT") Case $DBT_DEVICEARRIVAL MsgBox(0,"MSG","DBT_DEVICEARRIVAL") Case $DBT_DEVICEQUERYREMOVE MsgBox(0,"MSG","DBT_DEVICEQUERYREMOVE") Case $DBT_DEVICEQUERYREMOVEFAILED MsgBox(0,"MSG","DBT_DEVICEQUERYREMOVEFAILED") Case $DBT_DEVICEREMOVECOMPLETE MsgBox(0,"MSG","DBT_DEVICEREMOVECOMPLETE") Case $DBT_DEVICEREMOVEPENDING MsgBox(0,"MSG","DBT_DEVICEREMOVEPENDING") Case $DBT_DEVICETYPESPECIFIC MsgBox(0,"MSG","DBT_DEVICETYPESPECIFIC") Case $DBT_DEVNODES_CHANGED MsgBox(0,"MSG","DBT_DEVNODES_CHANGED") Case $DBT_QUERYCHANGECONFIG MsgBox(0,"MSG","DBT_QUERYCHANGECONFIG") Case $DBT_USERDEFINED MsgBox(0,"MSG","DBT_USERDEFINED") EndSwitch Return 1 EndFunc Edited October 3, 2010 by wolf9228 ØµØ±Ø Ø§Ù„Ø³Ù…Ø§Ø¡ كان هنا  Link to comment Share on other sites More sharing options...
Joline Posted October 4, 2010 Author Share Posted October 4, 2010 Thank you all but it doesn't work. Here is a snippet from MSDN: "The system broadcasts the DBT_DEVICEQUERYREMOVE device event to request permission to remove a device or piece of media. This message is the last chance for applications and drivers to prepare for this removal. However, any application can deny this request and cancel the operation." (DBT_DEVICEQUERYREMOVE Event) This is what I want to do. As I described, I want to safe some files to the USB device BEFORE it is removed. And as I understand DBT_DEVICEQUERYREMOVE is the right thing to do it.My understanding:A USB device is inserted and working. I left-click on the tray icon to remove this device. DBT_DEVICEQUERYREMOVE is sent to any application which has registered. Each of these application now can allow or deny this operation. I want to save something and after that allow the operation. But I get the DEVICEREMOVECOMPLETE message. And this is to late because the device is already removed. Maybe there is an other idea to do this? Link to comment Share on other sites More sharing options...
jaberwacky Posted October 5, 2010 Share Posted October 5, 2010 (edited) Found this: Capturing Device Events. The part that may be interesting to you is the "DBT_DEVICEQUERYREMOVE" section. Even though I'm sure it's the key I'm at a loss as to what to do with the information.What I've gathered so far is this: REgister for device notification (done). Use the information sent with a deviceArrival message to find the handle of the new device. Use filecreate with the information to get a handle to the device then use that to load up a dev_braodcast_handle structure.Found that info here: (http://www.techtalkz.com/microsoft-device-drivers/252416-help-createfile-wm_devicechange-surprise-removal.html)That's it so far.Edit:Got much closer! $lParam contains a pointer to a struct which contains detailed info about the inserted device. I created a DEV_BRADCAST_VOLUME struct which contains the drive letter of the USB device. I will use that drive to open a file stream device and then call RegisterDeviceNotification again but this time with different input data. I hope...Edit: Currently stuck on opening a file stream to the device.Edit: Stopping for the night. Here is my current code for all eyes to see.expandcollapse popup#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 <Misc.au3> _Singleton(@ScriptName) HotKeySet("{ESC}", "term") Global Const $hWnd = GUICreate("USB-Handler") Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x0 Global Const $PtrDEV_BROADCAST_DEVICEINTERFACE = DllStructGetPtr(DEV_BROADCAST_DEVICEINTERFACE()) Global Const $hDevNotify = RegisterDevice($PtrDEV_BROADCAST_DEVICEINTERFACE, $DEVICE_NOTIFY_WINDOW_HANDLE, True) If $hDevNotify[0] Then Global Const $WM_DEVICECHANGE = 0x219 GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE") OnAutoItExitRegister("UnRegisterDeviceNotification") Else ConsoleWrite("Bye" & @LF) Exit EndIf While 1 Sleep(100) WEnd Func MY_WM_DEVICECHANGE(Const $hWnd, Const $Msg, Const $wParam, Const $lParam) Local Static $DBT_CONFIGCHANGECANCELED = 0x19 Local Static $DBT_CONFIGCHANGED = 0x18 Local Static $DBT_CUSTOMEVENT = 0x8006 Local Static $DBT_DEVICEARRIVAL = 0x8000 ; A device or piece of media has been inserted and is now available. Local Static $DBT_DEVICEQUERYREMOVE = 0x8001 ; A device or piece of media is attemped to remove. Local Static $DBT_DEVICEQUERYREMOVEFAILED = 0x8002 Local Static $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; A device or piece of media has been removed. Local Static $DBT_DEVICEREMOVEPENDING = 0x8003 Local Static $DBT_DEVICETYPESPECIFIC = 0x8005 Local Static $DBT_DEVNODES_CHANGED = 0x7 Local Static $DBT_QUERYCHANGECONFIG = 0x17 Local Static $DBT_USERDEFINED = 0xFFFF Switch $wParam Case $DBT_DEVICEARRIVAL ConsoleWrite("DEVICEARRIVAL" & @LF) Local $DEV_BROADCAST_HANDLE = DllStructCreate("dword dbcv_size; dword dbcv_devicetype; dword dbcv_reserved; word dbcv_unitmask; word dbcv_flags", $lParam) Local Const $UnitMask = DllStructGetData($DEV_BROADCAST_HANDLE, "dbcv_unitmask") Local Const $DriveLetter = GetDriveLetterFromUnitMask($UnitMask) _WinAPI_CreateFile("\\\\.\" & $DriveLetter, 2) Error("_WinAPI_CreateFile") Case $DBT_DEVICEQUERYREMOVE ConsoleWrite("DEVICEQUERYREMOVE" & @LF) Case $DBT_DEVICEREMOVECOMPLETE ConsoleWrite("DEVICEREMOVECOMPLETE" & @LF) Case $DBT_CONFIGCHANGECANCELED ConsoleWrite("$DBT_CONFIGCHANGECANCELED" & @LF) Case $DBT_CONFIGCHANGED ConsoleWrite("$DBT_CONFIGCHANGED" & @LF) Case $DBT_CUSTOMEVENT ConsoleWrite("$DBT_CUSTOMEVENT" & @LF) Case $DBT_DEVICEQUERYREMOVEFAILED ConsoleWrite("$DBT_DEVICEQUERYREMOVEFAILED" & @LF) Case $DBT_DEVICEREMOVEPENDING ConsoleWrite("$DBT_DEVICEREMOVEPENDING" & @LF) Case $DBT_DEVICETYPESPECIFIC ConsoleWrite("$DBT_DEVICETYPESPECIFIC" & @LF) ;~ Case $DBT_DEVNODES_CHANGED ;~ ConsoleWrite("$DBT_DEVNODES_CHANGED" & @LF) Case $DBT_QUERYCHANGECONFIG ConsoleWrite("$DBT_QUERYCHANGECONFIG" & @LF) Case $DBT_USERDEFINED ConsoleWrite("$DBT_USERDEFINED" & @LF) EndSwitch EndFunc ;==>MY_WM_DEVICECHANGE Func GetDriveLetterFromUnitMask(Const $UnitMask) Local Const $Drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Local $Count = 1 Local $Pom = $UnitMask / 2 While $Pom <> 0 $Pom = BitShift($Pom, 1) $Count += 1 WEnd Return StringMid($Drives, $Count, 1) EndFunc ;==>GetDriveLetterFromUnitMask Func RegisterDevice(Const $StructPtr, Const $Flags, Const $CheckError = False) Local COnst $hDevNotify = DllCall("User32.dll", "handle", "RegisterDeviceNotification", "handle", $hWnd, "ptr", $StructPtr, "long", $Flags) If $CheckError then Error("RegisterDeviceNotification") return $hDevNotify EndFunc ;==>RegisterDevice Func DEV_BROADCAST_HANDLE(Const $handle, Const $CheckError = False) Local Const $tagDEV_BROADCAST_HANDLE = "dword dbch_size; dword dbch_devicetype; dword dbch_reserved; handle dbch_handle; long dbch_hdevnotify; char dbch_eventguid[128]; long dbch_nameoffset; byte dbch_data[1]" Local Const $DEV_BROADCAST_HANDLE = DllStructCreate($tagDEV_BROADCAST_HANDLE) If $CheckError Then Error("$DEV_BROADCAST_HANDLE") Local Const $DBT_DEVTYP_HANDLE = 0x00000006 DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_size", DllStructGetSize($DEV_BROADCAST_HANDLE)) DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_devicetype", $DBT_DEVTYP_HANDLE) DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_handle", $handle) DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_hdevnotify", $hDevNotify) Return $DEV_BROADCAST_HANDLE EndFunc ;==>DEV_BROADCAST_HANDLE Func DEV_BROADCAST_DEVICEINTERFACE(Const $CheckError = False) Local Const $tagDEV_BROADCAST_DEVICEINTERFACE = "dword dbcc_size; dword dbcc_devicetype; dword dbcc_reserved; char dbcc_classguid[128]; char dbcc_name[1];" Local Const $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate($tagDEV_BROADCAST_DEVICEINTERFACE) If $CheckError Then Error("DEV_BROADCAST_DEVICEINTERFACE") Local Const $DBT_DEVTYP_DEVICEINTERFACE = 0x00000005 DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_size", DllStructGetSize($DEV_BROADCAST_DEVICEINTERFACE)) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_devicetype", $DBT_DEVTYP_DEVICEINTERFACE) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_name", '0', 1) Return $DEV_BROADCAST_DEVICEINTERFACE EndFunc ;==>DEV_BROADCAST_DEVICEINTERFACE Func term() Exit EndFunc ;==>term Func UnRegisterDeviceNotification() Local Const $UnregStatus = DllCall("User32.dll", "bool", "UnRegisterDeviceNotification", "hdevnotify", $hDevNotify[0]) GUIRegisterMsg($WM_DEVICECHANGE, '') EndFunc ;==>UnRegisterDeviceNotification Func Error(Const $Oper) ConsoleWrite($Oper & ": " & _WinAPI_GetLastErrorMessage() & @LF) EndFunc ;==>Error Edited October 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
jaberwacky Posted October 5, 2010 Share Posted October 5, 2010 (edited) YES! OK, ok, I lied, lawlz, but I decided to fiddle around and finally got a handle to the usb device! I have this code which displays a message box asking you if you want to continue with ejecting. I dunno if that's exactly what you want but it's a definate step in the right direction. Tell me if this does what you want, please... expandcollapse popup#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 <Misc.au3> _Singleton(@ScriptName) HotKeySet("{ESC}", "term") Global Const $hWnd = GUICreate("USB-Handler") Global Const $DBT_DEVTYP_HANDLE = 0x00000006 Global Const $DBT_DEVTYP_DEVICEINTERFACE = 0x00000005 Global Const $DEVICE_NOTIFY_WINDOW_HANDLE = 0x0 Global Const $PtrDEV_BROADCAST_DEVICEINTERFACE = DllStructGetPtr(DEV_BROADCAST_DEVICEINTERFACE()) Global Const $hDevNotify = RegisterDevice($PtrDEV_BROADCAST_DEVICEINTERFACE, $DEVICE_NOTIFY_WINDOW_HANDLE, True) If $hDevNotify[0] Then Global Const $WM_DEVICECHANGE = 0x219 GUIRegisterMsg($WM_DEVICECHANGE, "MY_WM_DEVICECHANGE") OnAutoItExitRegister("UnRegisterDeviceNotification") Else ConsoleWrite("Bye" & @LF) Exit EndIf While 1 Sleep(100) WEnd Func MY_WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam) Local Static $DBT_CONFIGCHANGECANCELED = 0x19 Local Static $DBT_CONFIGCHANGED = 0x18 Local Static $DBT_CUSTOMEVENT = 0x8006 Local Static $DBT_DEVICEARRIVAL = 0x8000 ; A device or piece of media has been inserted and is now available. Local Static $DBT_DEVICEQUERYREMOVE = 0x8001 ; A device or piece of media is attemped to remove. Local Static $DBT_DEVICEQUERYREMOVEFAILED = 0x8002 Local Static $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; A device or piece of media has been removed. Local Static $DBT_DEVICEREMOVEPENDING = 0x8003 Local Static $DBT_DEVICETYPESPECIFIC = 0x8005 Local Static $DBT_DEVNODES_CHANGED = 0x7 Local Static $DBT_QUERYCHANGECONFIG = 0x17 Local Static $DBT_USERDEFINED = 0xFFFF Switch $wParam Case $DBT_DEVICEARRIVAL ConsoleWrite("DEVICEARRIVAL" & @LF) Local $DEV_BROADCAST_HANDLE = DllStructCreate("dword dbcv_size; dword dbcv_devicetype; dword dbcv_reserved; word dbcv_unitmask; word dbcv_flags", $lParam) Local Const $UnitMask = DllStructGetData($DEV_BROADCAST_HANDLE, "dbcv_unitmask") Local Const $DriveLetter = GetDriveLetterFromUnitMask($UnitMask) Local Const $Handle = _WinAPI_CreateFile("\\.\" & $DriveLetter & ":", 2) ;~ Error("_WinAPI_CreateFile") Global Const $ptrDEV_BROADCAST_HANDLE = DllStructGetPtr(DEV_BROADCAST_HANDLE($Handle)) RegisterDevice($ptrDEV_BROADCAST_HANDLE, $DBT_DEVTYP_HANDLE) Case $DBT_DEVICEQUERYREMOVE ConsoleWrite("DEVICEQUERYREMOVE" & @LF) Case $DBT_DEVICEREMOVECOMPLETE ConsoleWrite("DEVICEREMOVECOMPLETE" & @LF) Case $DBT_CONFIGCHANGECANCELED ConsoleWrite("$DBT_CONFIGCHANGECANCELED" & @LF) Case $DBT_CONFIGCHANGED ConsoleWrite("$DBT_CONFIGCHANGED" & @LF) Case $DBT_CUSTOMEVENT ConsoleWrite("$DBT_CUSTOMEVENT" & @LF) Case $DBT_DEVICEQUERYREMOVEFAILED ConsoleWrite("$DBT_DEVICEQUERYREMOVEFAILED" & @LF) Case $DBT_DEVICEREMOVEPENDING ConsoleWrite("$DBT_DEVICEREMOVEPENDING" & @LF) Case $DBT_DEVICETYPESPECIFIC ConsoleWrite("$DBT_DEVICETYPESPECIFIC" & @LF) ;~ Case $DBT_DEVNODES_CHANGED ;~ ConsoleWrite("$DBT_DEVNODES_CHANGED" & @LF) Case $DBT_QUERYCHANGECONFIG ConsoleWrite("$DBT_QUERYCHANGECONFIG" & @LF) Case $DBT_USERDEFINED ConsoleWrite("$DBT_USERDEFINED" & @LF) EndSwitch EndFunc ;==>MY_WM_DEVICECHANGE Func GetDriveLetterFromUnitMask($UnitMask) Local Const $Drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Local $Count = 1 Local $Pom = $UnitMask / 2 While $Pom <> 0 $Pom = BitShift($Pom, 1) $Count += 1 WEnd Return StringMid($Drives, $Count, 1) EndFunc ;==>GetDriveLetterFromUnitMask Func RegisterDevice($StructPtr, $Flags, $CheckError = False) Local $hDevNotify = DllCall("User32.dll", "handle", "RegisterDeviceNotification", "handle", $hWnd, "ptr", $StructPtr, "long", $Flags) If $CheckError Then Error("RegisterDeviceNotification") Return $hDevNotify EndFunc ;==>RegisterDevice Func UnRegisterDeviceNotification() Local Const $UnregStatus = DllCall("User32.dll", "bool", "UnRegisterDeviceNotification", "hdevnotify", $hDevNotify[0]) GUIRegisterMsg($WM_DEVICECHANGE, '') EndFunc ;==>UnRegisterDeviceNotification Func DEV_BROADCAST_HANDLE($Handle, $CheckError = False) Local Const $tagDEV_BROADCAST_HANDLE = "dword dbch_size; dword dbch_devicetype; dword dbch_reserved; handle dbch_handle; long dbch_hdevnotify; char dbch_eventguid[128]; long dbch_nameoffset; byte dbch_data[1]" Local Const $DEV_BROADCAST_HANDLE = DllStructCreate($tagDEV_BROADCAST_HANDLE) If $CheckError Then Error("$DEV_BROADCAST_HANDLE") DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_size", DllStructGetSize($DEV_BROADCAST_HANDLE)) DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_devicetype", $DBT_DEVTYP_HANDLE) DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_handle", $Handle) DllStructSetData($DEV_BROADCAST_HANDLE, "dbch_hdevnotify", $hDevNotify) Return $DEV_BROADCAST_HANDLE EndFunc ;==>DEV_BROADCAST_HANDLE Func DEV_BROADCAST_DEVICEINTERFACE($CheckError = False) Local Const $tagDEV_BROADCAST_DEVICEINTERFACE = "dword dbcc_size; dword dbcc_devicetype; dword dbcc_reserved; char dbcc_classguid[128]; char dbcc_name[1];" Local Const $DEV_BROADCAST_DEVICEINTERFACE = DllStructCreate($tagDEV_BROADCAST_DEVICEINTERFACE) If $CheckError Then Error("DEV_BROADCAST_DEVICEINTERFACE") DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_size", DllStructGetSize($DEV_BROADCAST_DEVICEINTERFACE)) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_devicetype", $DBT_DEVTYP_DEVICEINTERFACE) DllStructSetData($DEV_BROADCAST_DEVICEINTERFACE, "dbcc_name", '0', 1) Return $DEV_BROADCAST_DEVICEINTERFACE EndFunc ;==>DEV_BROADCAST_DEVICEINTERFACE Func term() Exit EndFunc ;==>term Func Error($Oper) ConsoleWrite($Oper & ": " & _WinAPI_GetLastErrorMessage() & @LF) EndFunc ;==>Error Edited October 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Joline Posted October 5, 2010 Author Share Posted October 5, 2010 (edited) I have this code which displays a message box asking you if you want to continue with ejecting.There is no message box... Because of $CheckError=True (line: If $CheckError Then Error("RegisterDeviceNotification")) I get the following messages: Windows 7: "RegisterDeviceNotification: The operation completed successfully." Windows XP: "RegisterDeviceNotification: The data is invalid." But $hDevNotify[0] has a value. Therefore I never get a notification but as long as the script is running, I can not remove the device... This -> Detecting USB Drive Removal is exactly what I want (but in AutoIt ). I have so less time. Maybe to night I have some time to fiddle around. Edited October 5, 2010 by Joline Link to comment Share on other sites More sharing options...
jaberwacky Posted October 5, 2010 Share Posted October 5, 2010 (edited) There is no message box... Because of $CheckError=True (line: If $CheckError Then Error("RegisterDeviceNotification")) I get the following messages: Windows 7: "RegisterDeviceNotification: The operation completed successfully." Windows XP: "RegisterDeviceNotification: The data is invalid." But $hDevNotify[0] has a value. Therefore I never get a notification but as long as the script is running, I can not remove the device... This -> Detecting USB Drive Removal is exactly what I want (but in AutoIt ). I have so less time. Maybe to night I have some time to fiddle around. I wonder why I get a messagebox but you dont. I'm running win7 x64. Do you unhook the device before you run the script? Edited October 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Joline Posted October 5, 2010 Author Share Posted October 5, 2010 After trying something I can lock the device from removing but I never get the DBT_DEVICEQUERYREMOVE notification. If I run the script and then insert a device, this device will be locked. I have to finish the script to remove the device properly. This might be ok but if I never get a notification there is no chance to release the device automatically. As described in the link in the previous post (and also what you have detected) it is necessary to open a file on the USB device and pass the handle to RegisterDeviceNotification. That should be all (if I look to the C# example) but doesn't work in the script. What the hell is different? Link to comment Share on other sites More sharing options...
Joline Posted October 5, 2010 Author Share Posted October 5, 2010 I wonder why I get a messagebox but you dont. I'm running win7 x64.Which message box? There is no MsgBox in the script code. Or do you mean the message box from windows that the device is locked? Link to comment Share on other sites More sharing options...
Joline Posted October 5, 2010 Author Share Posted October 5, 2010 I've tried the demo from here: Detecting USB Drive Removal and read the associated description. Because this works exactly like that what I want, I have to analyze this C# code. Maybe this brings me to a solution. (But not tonight. ) Link to comment Share on other sites More sharing options...
jaberwacky Posted October 7, 2010 Share Posted October 7, 2010 (edited) **FACEPALM** I realize that the reason why the message box popped up was not because the device had been properly registered but because I opened a stream to the device. Edited October 7, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Joline Posted October 7, 2010 Author Share Posted October 7, 2010 I realize that the reason why the message box popped up was not because the device had been properly registered but because I opened a stream to the device.That's right. Me too. But after stare into the C# code (mentioned above) and fiddling around for hours I couldn'd whats wrong. This C#-Example works properly. And the explanation describes exactly to open a file/stream and register with this handle. blah. That's what you have done with your last code.Maybe something is still wrong/missing in the NotificationFilter structure. Sadly I'm very busy at the moment but hopefully I'll found some time in the evening to continue... Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now