Jump to content

Recommended Posts

Posted

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

Posted

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

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
×
×
  • Create New...