Jump to content

Joline

Active Members
  • Posts

    21
  • Joined

  • Last visited

Everything posted by Joline

  1. Yippie! It is working! I've inserted the "interesting" parts in my software and everything works fine now. Thank you very much. Good Job.
  2. Oh, fine. No idea what I've tested/seen yesterday. As I said, maybe to much wine... Did you also test to remove first the second inserted device?
  3. I've extended your lines: Local $FileHandle = OpenFile($VolumeAccessPath, True) and $FileHandle = GetFileHandle($lParam, True) into: Local $FileHandle = OpenFile($VolumeAccessPath, True) Write("$FileHandle: " & $FileHandle) and $FileHandle = GetFileHandle($lParam, True) Write("$FileHandle: " & $FileHandle) Plug in 2 devices and try to remove them in different sequence. Just compare the results of $FileHandle... I think it hasn't worked all the times but maybe I couldn't see straight yesterday in the evening. To much wine...
  4. Oh, interesting news. I've no idea what happen internally in AutoIt but I know what every (I think so) compiler will do with switch-case constructs. This will be translated into (assembly-)code with many jump labels. Jumping inside code... Uhhh! If...Then...Else constructs have only one jump label. Seems to be better, isn't it. Sorry. Maybe my (old-school-)knowledge is based on availability of limited resources. But in times with inexhaustible resources nobody cares with memory, cpu etc. ... Stop the religious war here! It was just an advise not a must.
  5. That is not a criticism but just an advice. I'm in this business since a long time... To realize that in C++ / C# / what ever is not the problem. The initial idea was to realize this _quickly_ in a scripting language because I didn't want to start the compiler for such a trivial thing. I did not suspect such problems. And I had no time to solve it. You did a good job. So see this not as a bad thing but a well meant advice. There is a strange behaviour if you plug in 2 devices after each other and then try to remove. Sometimes it works, sometimes not. The good news is that the filehandle from DEVICEQUERYREMOVE is one of those from DEVICEARRIVAL. I've just inserted a write("$FileHandle: " & $FileHandle) to check this. So at the end the filehandle should be saved in an array and tested at DEVICEQUERYREMOVE to find out the right one. I've such array already in my code but the wrong GetFileHandle function. So at the weekend I'll insert your code snippet and hopefully this will work. I'll report.
  6. Hi, jaberwocky, did you test this also with more than one usb device? P.S. Even I see that you use "switch-case" constructs extensively. Better you should use "if-then-else" if there are a single or 2 choices because of performance reasons.
  7. I have this already defined as global. But the problem is how to detect WHICH drive is meant on DEVICEQUERYREMOVE... E.g.: There are 2 devices connected, f: and g:. Now one of them should be removed. How can I determine in DEVICEQUERYREMOVE which of both is it? Do you know if this is passed in any way/form?
  8. This is also my thought. But there must be a relationship between both. How is otherwise possible that an application can release the right file(handle) if DEVICEQUERYREMOVE occurs? So maybe in case of DEVICEARRIVAL there is also a pointer to a handle which can be stored and compared with the pointer to the DEV_BROADCAST_HANDLE struct when DEVICEQUERYREMOVE occurs.
  9. Hi everybody, having solved my problem with getting informed when a usb device is attempted to remove (RegisterDeviceNotification) I fall into the next problem: How can I determine the right drive or handle using the lParam in case of wParam = DBT_DEVICEQUERYREMOVE? Here are parts of my code: Func MY_WM_DEVICECHANGE(Const $hWnd, Const $msg, Const $wParam, Const $lParam) ;... Local Const $DeviceType = GetDeviceType($lParam) Switch $wParam Case $DBT_DEVICEARRIVAL ;... If $DeviceType = $DBT_DEVTYP_VOLUME Then ; <= VOLUME!!! Local Const $UnitMask = GetUnitMask($lParam) Local Const $driveLetter = GetDriveLetterFromUnitMask($unitMask) & ":\" ;this works, I get the right drive ;... Case $DBT_DEVICEQUERYREMOVE ;... If $DeviceType = $DBT_DEVTYP_HANDLE Then ; <= HANDLE!!! Local Const $UnitMask = GetUnitMask($lParam) Local Const $driveLetter = GetDriveLetterFromUnitMask($unitMask) & ":\" ;this works NOT, I get the WRONG drive ;maybe I have to find the filehandle? ;... Case $DBT_DEVICEREMOVECOMPLETE ;... If $DeviceType = $DBT_DEVTYP_VOLUME Then ; <= VOLUME!!! Local Const $UnitMask = GetUnitMask($lParam) Local Const $driveLetter = GetDriveLetterFromUnitMask($unitMask) & ":\" ;this works, I get the right drive ;... EndSwitch EndFunc ;==>MY_WM_DEVICECHANGE Func GetUnitMask($lParam) ; 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 $UnitMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcv_unitmask") Return $UnitMask EndFunc ;==>GetUnitMask Func GetDeviceType($lParam) ; 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") Return $DeviceType EndFunc ;==>GetDeviceType This works if I use it while wParam = DBT_DEVICEARRIVAL but NOT while wParam = DBT_DEVICEQUERYREMOVE. Here I get the wrong drive. Maybe I have to determine the file handle (from the opened file) because of DeviceType = Handle (and not volume) but how? Does anybody have an idea?
  10. 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!
  11. 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.
  12. 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...
  13. 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. )
  14. 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?
  15. 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?
  16. 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.
  17. 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?
  18. 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.
  19. Oh, the $hDevNotify has a value now. Great. But unfortunately it doesn't work as expected. #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.
  20. 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
  21. 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? 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 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
×
×
  • Create New...