Jump to content
Sign in to follow this  
isar

USB device management

Recommended Posts

isar

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

Share this post


Link to post
Share on other sites
ptrex
isar

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 ...).

Regards

isar

@

Why don't you use WMI is much easier to program.

See my example

USB Monitor

regards,

ptrex

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.