isar Posted April 17, 2007 Posted April 17, 2007 Hi, I want to control the USB devices to realize a import Routine for digitalphotos of registered digicameras. In this Autoit-Forum I found several WONDERFULL Scripts which I could combine. But I´ve still some requirements, I can not solve, because I do not know, how to use (to programm) Microsofts device management calls to read the Vendor-Information and Type of the inserted USB-Device. For example, the inserted digicam will be registered in The registry with "USB Device: Vid_11f5&Pid_0002". When I connect the digicam, a arrival-function (see below) is called from which I want to read the uniqe identifier of the usb-device. The Autoit function "DriveGetSerial" is not usable, because when the media will be new formatted, a new serialnumber will be created. Can anybody help me? The script: Global CONST $LOCK_TIMEOUT = 10000 Global CONST $LOCK_RETRIES = 20 Global CONST $GENERIC_READ = 0x80000000 Global CONST $GENERIC_WRITE = 0x40000000 Global CONST $FILE_SHARE_READ = 0x00000001 Global CONST $FILE_SHARE_WRITE = 0x00000002 Global CONST $OPEN_EXISTING = 3 Global CONST $INVALID_HANDLE_VALUE = 0xFFFFFFFF Global CONST $FSCTL_LOCK_VOLUME = 0x00090018 Global CONST $FSCTL_DISMOUNT_VOLUME = 0x00090020 Global CONST $IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D0804 Global CONST $IOCTL_STORAGE_EJECT_MEDIA = 0x002D0808 $DBT_DEVICEARRIVAL = "0x00008000" $WM_DEVICECHANGE = 0x0219 GUICreate("") GUIRegisterMsg($WM_DEVICECHANGE , "MyFunc") Func MyFunc($hWndGUI, $MsgID, $WParam, $LParam) If $WParam == $DBT_DEVICEARRIVAL Then $dg = DriveGetDrive( "REMOVABLE" ) For $i = 1 to $dg[0] $dt = DriveGetType( $dg[$i] ) If $dt = "REMOVABLE" And $dg[$i] <> "a:" And $dg[$i] <> "b:" Then RB($LParam) ; Testoutine to read the _DEV_BROADCAST_HDR ;; HERE I WANT TO CHECK THE VENDOR ID OF THE DEVICE ;; $mymsg = $dg[$i] & " = " & $dt & @CRLF & "Serial-Id: " & DriveGetSerial( $dg[$i] ) $srcpath=($dg[$i] & "\DCIM") $file = FileExists ($dg[$i] & "\DCIM\nul") ;; ----------- If Folder DCIM exists - import Pictures ------- ; in future : If this is a registered Digicam, import pictures If $file = 1 Then ;;Hier gehts zur Sache ...... MsgBox(0,"Drive " & $i, $mymsg & " Fotoimport wird durchgeführt ..."); info to start Import $tmpname=@YEAR &"-" &@MON &"-"& @MDAY &"__"&@HOUR &"-"& @MIN &"-"& @SEC ;$backpath = "D:\Backups\Mypicturestest\"&$tmpname ; please set YOUR Backuppath and uncoment the Line $srcsize = DirGetSize ( $srcpath ,0 ) ;Run("D:\autoit\Progress.exe "&$srcsize &" " & $backpath) ;; Show Progress in an independent Routine >>Not available here $ret=0 $ret=DirCopy($dg[$i] & "\DCIM", $backpath, 0) if $ret = 0 Then MsgBox(0,"Fotoimport", "Es ist ein Fehler aufgetreten!") ; an Error occured Else MsgBox(0,"Fotoimport", "Der Import wurde erfolgreich durchgeführt!"), Import OK EjectVolume(StringLeft ( $dg[$i], 1 )); Start unmount EndIf Else ; disable Input, wait for unplugging USB-Device ;; ----- Kein DCIM-Verzeichnis vorhanden, irgendein USB-Stick, soll gesperrt werden ---- ;; Sperren des Bildschirmes und der Eingabe --- Disable Input BlockInput(1) MsgBox(0,"Drive "& $i, $mymsg & " ist nicht registriert!" & @CRLF & "Gerät sofort entfernen!",5) ; Device not registered ;; Block Input while wrong device inserted While DriveStatus($dg[$i]) = "READY" ;WinActivate($gui) ;DllCall($user32, "int", "SendMessage", "hwnd", $hwnd, "int", $lciWM_SYSCommand, "int", $lciSC_MonitorPower, "int", $lciPower_Off) BlockInput(1) Sleep(20) WEnd BlockInput(0) ; release EndIf EndIf Next EndIf EndFunc While 1 $GuiMsg = GUIGetMsg() WEnd ;;------------------------------------------------------------------------------------ ;; Read LPARM _DEV_BROADCAST_HDR info ;;------------------------------------------------------------------------------------ Func RB($dpointer) #cs From MSDN: typedef struct _DEV_BROADCAST_HDR { DWORD dbch_size; DWORD dbch_devicetype; DWORD dbch_reserved; } DEV_BROADCAST_HDR, #ce $p = DllStructCreate("dword;dword;dword",$dpointer) if @error Then MsgBox(0,"","Error in DllStructCreate " & @error); exit endif ;DllStructSetData($p, 1, DllStructGetSize($p)) $dbchsize = DllStructGetData($p,1) $dvtype = DllStructGetData($p,2) $reserved = DllStructGetData($p,3) MsgBox(0,"LPARM _DEV_BROADCAST_HDR info", "dbch_size: " & $dbchsize & @CRLF & "dbch_devicetype: "& $dvtype & @CRLF & "dbch_reserved: "& $reserved &@CRLF) Return EndFunc ;;------------------------------------------------------------------------------------ ;; Eject-Routines ;;------------------------------------------------------------------------------------ Func ReportError($szMsg) $ret = DLLCall("kernel32.dll","int","GetLastError") MsgBox(4096,"Error","Error " & $ret[0] & ": " & $szMsg) EndFunc ; HANDLE OpenVolume(TCHAR cDriveLetter) Func OpenVolume($cDriveLetter) Local $hVolume, $uDriveType, $szVolumeName, $dwAccessFlags Local $szRootName = $cDriveLetter & ":\" $uDriveType = DriveGetType($szRootName) Select Case $uDriveType == "Removable" $dwAccessFlags = BitOR($GENERIC_READ,$GENERIC_WRITE) Case $uDriveType == "CDROM" $dwAccessFlags = $GENERIC_READ Case Else MsgBox(4096,"Error","Cannot eject. Drive type is incorrect.") Return $INVALID_HANDLE_VALUE EndSelect $szVolumeName = "\\.\" & $cDriveLetter & ":" $hVolume = DllCall( "kernel32.dll", "hwnd", "CreateFile", "str", $szVolumeName, _ "long", $dwAccessFlags, "long", BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), _ "ptr", 0, "long", $OPEN_EXISTING, "long", 0, "long", 0 ) If $hVolume[0] = $INVALID_HANDLE_VALUE Then ReportError("CreateFile") Return $hVolume[0] EndFunc Func CloseVolume(ByRef $hVolume) Local $ret = DLLCall("kernel32.dll","int","CloseHandle","hwnd",$hVolume) Return $ret[0] EndFunc Func LockVolume(ByRef $hVolume) Local $dwBytesReturned, $nTryCount, $ret Local $dwSleepAmount = $LOCK_TIMEOUT / $LOCK_RETRIES ; Do this in a loop until a timeout period has expired For $nTryCount = 0 To $LOCK_RETRIES $ret = DLLCall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume, _ "int",$FSCTL_LOCK_VOLUME,"ptr",0,"int",0,"ptr",0,"int",0, _ "int_ptr",$dwBytesReturned,"ptr",0) If $ret[0] Then Return 1 Sleep($dwSleepAmount) Next return 0 EndFunc Func DismountVolume(ByRef $hVolume) Local $dwBytesReturned Local $ret = DLLCall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume, _ "int",$FSCTL_DISMOUNT_VOLUME,"ptr",0,"int",0,"ptr",0,"int",0, _ "int_ptr",$dwBytesReturned,"ptr",0) Return $ret[0] EndFunc Func PreventRemovalOfVolume(ByRef $hVolume, $fPreventRemoval) Local $dwBytesReturned Local $PMRBuffer = DLLStructCreate("int") DLLStructSetData($PMRBuffer,1,$fPreventRemoval) Local $ret = DLLCall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume, _ "int",$IOCTL_STORAGE_MEDIA_REMOVAL,"ptr",DllStructGetPtr($PMRBuffer), _ "int",DllStructGetSize($PMRBuffer),"ptr",0,"int",0,"int_ptr",$dwBytesReturned,"ptr",0) Return $ret[0] EndFunc Func AutoEjectVolume(ByRef $hVolume) Local $dwBytesReturned Local $ret = DLLCall("kernel32.dll","int","DeviceIoControl","hwnd",$hVolume, _ "int",$IOCTL_STORAGE_EJECT_MEDIA,"ptr",0,"int",0,"ptr",0,"int",0, _ "int_ptr",$dwBytesReturned,"ptr",0) Return $ret[0] EndFunc Func EjectVolume($cDriveLetter) Local $hVolume Local $fRemoveSafely = 0 Local $fAutoEject = 0 ; Open the volume. $hVolume = OpenVolume($cDriveLetter) If $hVolume = $INVALID_HANDLE_VALUE Then Return 0 ; Lock and dismount the volume. If LockVolume($hVolume) And DismountVolume($hVolume) Then $fRemoveSafely = 1 ; Set prevent removal to false and eject the volume. If PreventRemovalOfVolume($hVolume, 0) And AutoEjectVolume($hVolume) Then $fAutoEject = TRUE EndIf ; Close the volume so other processes can use the drive. If Not CloseVolume($hVolume) Then Return 0 If $fAutoEject Then MsgBox(4096,"","Das Medium in Laufwerk " & $cDriveLetter & " wurde sicher entfernt.") Else If $fRemoveSafely Then MsgBox(4096,"","Das Medium in Laufwerk " & $cDriveLetter & " kann nun sicher entfernt werden.") EndIf Return 1 EndFunc ;Func CTL_CODE($DeviceType, $Function, $Method, $Access) ; Return BitOR(BitShift($DeviceType,-16),BitShift($Access,-14),BitShift($Function,-2),$Method) ;EndFunc
ptrex Posted April 18, 2007 Posted April 18, 2007 @Why don't you use WMI is much easier to program.See my example USB Monitorregards,ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
isar Posted April 22, 2007 Author Posted April 22, 2007 Hi ptrex,thank You for Your Tip, I will now look how to use WMI. I will post when I´ll be successful (or hang because I don´t know how ...).Regardsisar@Why don't you use WMI is much easier to program.See my example USB Monitorregards,ptrex
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