Nikolas92 Posted July 16, 2017 Share Posted July 16, 2017 I tried this, but it doesnt work correctly> expandcollapse popup; msdn.microsoft.com/en-us/library/aa363217%28VS.85%29.aspx ; www.autoitscript.com/forum/topic/121108-registerdevicenotifications ; www.autoitscript.com/forum/topic/47352-stringsplit-by-length ; stackoverflow.com/a/13880732 ; www.codeproject.com/articles/35212/wm-devicechange-problem #include <GUIConstants.au3> #include <Constants.au3> #include <WinAPI.au3> #include <Array.au3> Global Const $tagDEV_BROADCAST_HANDLE = "dword dbch_size; dword dbch_devicetype; dword dbch_reserved; handle dbch_handle; ptr dbch_hdevnotify; char dbch_eventguid[255]; long dbch_nameoffset; byte dbch_data[1]" Global Const $tagDEV_BROADCAST_HDR = "dword dbch_size; dword dbch_devicetype; dword dbch_reserved" Global Const $tagDEV_BROADCAST_VOLUME = "dword dbcv_size; dword dbcv_devicetype; dword dbcv_reserved; dword dbcv_unitmask; dword dbcv_flags" Global Const $DBT_DEVNODES_CHANGED = 0x00000007 Global Const $DBT_DEVICEARRIVAL = 0x00008000 Global Const $DBT_DEVICEREMOVECOMPLETE = 0x00008004 Global Const $DBT_CUSTOMEVENT = 0x00008006 Global Const $DBT_DEVTYP_HANDLE = 0x00000006 Global Const $DBT_DEVTYP_VOLUME = 0x00000002 Global Const $DBTF_MEDIA = 0x0001 Global Const $DBTF_NET = 0x0002 Global Const $device_notify_window_handle = 0x0000 Global $DrivesToMonitor = '' Global $NotificationHandlesOfDrives = '' Global $MonitoredDrives[1][3] = [[1]] Global $hGUI = GUICreate('', 0, 0, 0, 0, BitOR($DS_SETFOREGROUND, $WS_POPUP), BitOR($WS_EX_CONTROLPARENT, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) GUIRegisterMsg($wm_devicechange, window_proc) While 1 Sleep(1000) WEnd Func window_proc(Const $h_wnd, Const $msg, Const $w_param, Const $lParam) ConsoleWrite($w_param & @CRLF) Switch $w_param Case $DBT_CUSTOMEVENT $StructDevHDR = DllStructCreate($tagDEV_BROADCAST_HDR, $lParam) Switch DllStructGetData($StructDevHDR, "dbch_devicetype") Case $DBT_DEVTYP_HANDLE $StructDevHandle = DllStructCreate($tagDEV_BROADCAST_HANDLE, $lParam) $DeviceNotificationHandle = DllStructGetData($StructDevHandle, "dbch_hdevnotify") $GUID = _GuidCorrection(DllStructGetData($StructDevHandle, "dbch_eventguid")) StringRegExpReplace($GUID, '-', '-') If @extended > 3 Then $GUID = StringLeft($GUID, StringInStr($GUID, '-', 0, -1) - 1) & '}' If UBound($MonitoredDrives) - 1 > 0 Then For $i = 1 to UBound($MonitoredDrives) - 1 If $DeviceNotificationHandle = $MonitoredDrives[$i][2] Then ConsoleWrite('Drive ' & $MonitoredDrives[$i][0] & ' - Event: ' & $GUID & @CRLF) ExitLoop EndIf Next EndIf EndSwitch Case $DBT_DEVICEREMOVECOMPLETE $StructDevHDR = DllStructCreate($tagDEV_BROADCAST_HDR, $lParam) Switch DllStructGetData($StructDevHDR, "dbch_devicetype") Case $DBT_DEVTYP_HANDLE $StructDevHandle = DllStructCreate($tagDEV_BROADCAST_HANDLE, $lParam) $DeviceNotificationHandle = DllStructGetData($StructDevHandle, "dbch_hdevnotify") If StringInStr($NotificationHandlesOfDrives, $DeviceNotificationHandle) Then _UnregisterDeviceNotification($lParam) Case $DBT_DEVTYP_VOLUME $StructDevVolume = DllStructCreate($tagDEV_BROADCAST_VOLUME, $lParam) $iUnitMask = DllStructGetData($StructDevVolume, "dbcv_unitmask") $iFlags = DllStructGetData($StructDevVolume, "dbcv_flags") $sDrive = StringUpper(_GetDriveLetterFromUnitMask($iUnitMask)) $NewDrives = StringSplit($sDrive, ', ', $STR_ENTIRESPLIT) For $i = 1 to $NewDrives[0] ConsoleWrite($NewDrives[$i] & ' device removed'& @CRLF) If StringInStr($DrivesToMonitor, $NewDrives[$i]) Then _UnregisterDeviceNotification('', $NewDrives[$i]) Next EndSwitch Case $DBT_DEVICEARRIVAL $StructDevHDR = DllStructCreate($tagDEV_BROADCAST_HDR, $lParam) Switch DllStructGetData($StructDevHDR, "dbch_devicetype") Case $DBT_DEVTYP_VOLUME $StructDevVolume = DllStructCreate($tagDEV_BROADCAST_VOLUME, $lParam) $iUnitMask = DllStructGetData($StructDevVolume, "dbcv_unitmask") $iFlags = DllStructGetData($StructDevVolume, "dbcv_flags") $sDrive = StringUpper(_GetDriveLetterFromUnitMask($iUnitMask)) $NewDrives = StringSplit($sDrive, ', ', $STR_ENTIRESPLIT) For $i = 1 to $NewDrives[0] ConsoleWrite($NewDrives[$i] & ' device arrival'& @CRLF) If StringInStr($DrivesToMonitor, $NewDrives[$i]) Then _UnregisterDeviceNotification('', $NewDrives[$i]) _RegisterDeviceNotificationForVolume($NewDrives[$i]) Next EndSwitch EndSwitch EndFunc Func _GuidCorrection($sGuid) If StringLeft($sGuid, 2) = '0x' Then $sGuid = Binary($sGuid) Else $sGuid = StringToBinary($sGuid) EndIf If StringLeft($sGuid, 2) = '0x' Then $sGuid = StringTrimLeft($sGuid, 2) $length = StringLen($sGuid) Switch $length Case 0 to 19 Return '{}' Case 20 Return '{' & _FixOrder(StringLeft($sGuid, 8)) & '-' & _FixOrder(StringMid($sGuid, 9, 4)) & '-' & _FixOrder(StringMid($sGuid, 13, 4)) & '-' & StringRight($sGuid, 4) & '}' Case Else Return '{' & _FixOrder(StringLeft($sGuid, 8)) & '-' & _FixOrder(StringMid($sGuid, 9, 4)) & '-' & _FixOrder(StringMid($sGuid, 13, 4)) & '-' & StringMid($sGuid, 17, 4) & '-' & StringRight($sGuid, $length - 20) & '}' EndSwitch EndFunc Func _FixOrder($sString) $size = 2 $count = Ceiling(StringLen($sString)/$size) $start = 1 $tmp = '' For $i = 1 To $count $tmp = StringMid($sString, $start, $size) & $tmp $start += $size Next Return $tmp EndFunc Func _GetDriveLetterFromUnitMask($UnitMask) $ReceivedDrives = '' For $i = 0 to 25 If BitAND($UnitMask, 0x1) Then $ReceivedDrives = $ReceivedDrives & Chr($i + Asc('A')) & ':' & ', ' $UnitMask = BitShift($UnitMask, 1) Next Return StringTrimRight($ReceivedDrives, 2) EndFunc Func _RegisterDeviceNotificationForVolume($DriveLetter) $hVolume = _WinAPI_CreateFile('\\.\' & $DriveLetter, 2, 2+4, 2+4) If $hVolume = 0 Then Return SetError(1, 0, False) $NotificationFilter = DllStructCreate($tagDEV_BROADCAST_HANDLE) DllStructSetData($NotificationFilter, "dbch_size", DllStructGetSize($NotificationFilter)) DllStructSetData($NotificationFilter, "dbch_devicetype", $DBT_DEVTYP_HANDLE) DllStructSetData($NotificationFilter, "dbch_handle", $hVolume) $RegisteredHandle = DllCall("user32.dll", "handle", "RegisterDeviceNotificationW", "handle", $hGUI, "ptr", DllStructGetPtr($NotificationFilter), "dword", $device_notify_window_handle) If @error Then Return SetError(2, 0, False) $DrivesToMonitor = $DrivesToMonitor & $DriveLetter & '|' $NotificationHandlesOfDrives = $NotificationHandlesOfDrives & $RegisteredHandle[0] & '|' $MonitoredDrives[0][0] += 1 ReDim $MonitoredDrives[$MonitoredDrives[0][0]][3] $MonitoredDrives[$MonitoredDrives[0][0] - 1][0] = StringUpper($DriveLetter) $MonitoredDrives[$MonitoredDrives[0][0] - 1][1] = DriveGetType($DriveLetter) $MonitoredDrives[$MonitoredDrives[0][0] - 1][2] = $RegisteredHandle[0] _WinAPI_CloseHandle($hVolume) ConsoleWrite('Device ' & $DriveLetter & ' registered.' & @CRLF) ConsoleWrite('NotificationHandle: ' & $RegisteredHandle[0] & @CRLF) Return True EndFunc Func _UnregisterDeviceNotification($lParam = '', $DriveLetter = '') Local $NotificationHandle = '' If $lParam <> '' Then $broadcast_handle = DllStructCreate($tagDEV_BROADCAST_HANDLE, $lParam) $NotificationHandle = DllStructGetData($broadcast_handle, "dbch_hdevnotify") EndIf If $DriveLetter <> '' or $NotificationHandle <> '' Then If UBound($MonitoredDrives) - 1 > 0 Then For $i = 1 to UBound($MonitoredDrives) - 1 If $DriveLetter = $MonitoredDrives[$i][0] or ($DriveLetter = '' and $NotificationHandle = $MonitoredDrives[$i][2]) Then If $DriveLetter = '' Then $DriveLetter = $MonitoredDrives[$i][0] $DrivesToMonitor = StringReplace($DrivesToMonitor, $DriveLetter & '|', '') If $lParam = '' Then $NotificationHandle = $MonitoredDrives[$i][2] $NotificationHandlesOfDrives = StringReplace($NotificationHandlesOfDrives, $NotificationHandle & '|', '') _ArrayDelete($MonitoredDrives, $i) $MonitoredDrives[0][0] -= 1 ReDim $MonitoredDrives[$MonitoredDrives[0][0]][3] ExitLoop EndIf Next EndIf EndIf If $NotificationHandle <> '' and $DriveLetter <> '' Then $aRet = DllCall("user32.dll", "bool", "UnregisterDeviceNotification", "ptr", $NotificationHandle) If @error Then Return SetError(1, @error, False) ConsoleWrite('Notification handle: ' & $NotificationHandle & '. Device ' & $DriveLetter & ' unregistered.' & @CRLF) Return True Else Return False EndIf EndFunc on insertion only event GUID_IO_VOLUME_PHYSICAL_CONFIGURATION_CHANGE is detect, but nothing happens on sd card removal. Is there error in example or there is no event for sd card removal? Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted July 17, 2017 Share Posted July 17, 2017 (edited) Hi @Nikolas92 I don't have an SD card at the moment, so, I can't try your code... But, did you think to use DriveGetState() ? Maybe you can manage using that function, without all of this code... Let us know Edited July 17, 2017 by FrancescoDiMuro Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Nikolas92 Posted July 17, 2017 Author Share Posted July 17, 2017 DriveGetState? You mean DriveStatus? How would that work for detecting when is SD card inserted and removed (without using loop)? Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted July 17, 2017 Share Posted July 17, 2017 @Nikolas92 Yeah, I would mean DriveStatus... As I said, at the moment I don't have an SD to test any solution for you... But, where do you insert the SD Card? In a card reader via USB, in a card-slot of a Notebook? Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Nikolas92 Posted July 17, 2017 Author Share Posted July 17, 2017 (edited) in 3G modem (and phone), via usb. Edited July 17, 2017 by Nikolas92 Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted July 17, 2017 Share Posted July 17, 2017 So, when you plug the SD card in the modem, you have the drive in the drive list ( This PC -> C: , D: , ... ), right? In this case, you can keep the work with Drive* functions Tell me if you need any help Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Nikolas92 Posted July 17, 2017 Author Share Posted July 17, 2017 Question is not about how to use drive * functions, but how to detect sd card arrival and removal with wm_devicechange so that what I want to do will be started. Nevermind, solved. For SD card insertion event GUID_IO_VOLUME_PHYSICAL_CONFIGURATION_CHANGE, and for sd card removal to monitor change in registry key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2 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