Jump to content

Set and check Volume id for removable device


Beilby
 Share

Recommended Posts

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$s_ComputerName             = @ComputerName
$s_NewVolumeName            = "New Volume Name"
$s_NewVolumeSerialNumber    = "New Volume Serial Number"

$objWMIService              = ObjGet("winmgmts:\\" & $s_ComputerName & "\root\CIMV2")
$o_DiskDrive                = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
If IsObj($o_DiskDrive) then
    For $o_Item In $o_DiskDrive
        $o_Item.VolumeName = $s_NewVolumeName
        $o_Item.VolumeSerialNumber = $s_NewVolumeSerialNumber
        $o_Item.Put
    Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_LogicalDisk" )
Endif

Try this :P

EDIT: Didn't test this - won't work: $o_Item.VolumeSerialNumber can't be $o_Item.Put

Edited by cherdeg
Link to comment
Share on other sites

Thanks for this;

have removed what seems to be an extra $ from line 3. However this still does not run, returns this in XP SP3

C:\Dev\Autoit\Volumeid\volumeid02.au3 (13) : ==> The requested action with this object has failed.:

Link to comment
Share on other sites

C:\Dev\Autoit\Volumeid\volumeid02.au3 (13) : ==> The requested action with this object has failed.:

Yep - I see...my code was only a 1st shot...and, pitily, untested. Problem is that "$o_Item.VolumeSerialNumber" is a read-only property of the class Win32_LogicalDisk (see "http://msdn.microsoft.com/en-us/library/aa394173(VS.85).aspx"). So my approach may be formally correct (up to the $) but technically senseless; I'm sorry. If you really need to change it, look at these C-sources ("http://www.codeproject.com/KB/system/change_drive_sn.aspx").

But if you drop me an info for what you would need to change the VolumeSerialNumber, maybe I can find another way to reach the goal?

Link to comment
Share on other sites

Installer

So far I am able to set a volume serial number using VolumeID.exe from Sysinternals. However, as I cannot seem to pass a variable into the dos command line the code that I have generated works but seems a little long winded is it possible to simplify this?

CODE
;set drive volume serial number to removable drive then place two files on the drive

#include <Process.au3>

$i = 1

$drive = DriveGetDrive("REMOVABLE")

If Not @error Then

; Only 1 removable drive install now

If $drive[0] = 1 Then

If $drive[$i] = "c:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid c:\ FFFF-FFFF")

EndIf

If $drive[$i] = "d:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid d:\ FFFF-FFFF")

EndIf

If $drive[$i] = "e:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid e:\ FFFF-FFFF")

EndIf

If $drive[$i] = "f:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid f:\ FFFF-FFFF")

EndIf

If $drive[$i] = "g:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid g:\ FFFF-FFFF")

EndIf

If $drive[$i] = "h:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid h:\ FFFF-FFFF")

EndIf

If $drive[$i] = "i:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid i:\ FFFF-FFFF")

EndIf

If $drive[$i] = "j:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid j:\ FFFF-FFFF")

EndIf

If $drive[$i] = "k:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid k:\ FFFF-FFFF")

EndIf

If $drive[$i] = "l:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid l:\ FFFF-FFFF")

EndIf

If $drive[$i] = "m:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid m:\ FFFF-FFFF")

EndIf

If $drive[$i] = "n:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid n:\ FFFF-FFFF")

EndIf

If $drive[$i] = "o:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid o:\ FFFF-FFFF")

EndIf

If $drive[$i] = "p:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid p:\ FFFF-FFFF")

EndIf

If $drive[$i] = "q:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid q:\ FFFF-FFFF")

EndIf

If $drive[$i] = "r:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid r:\ FFFF-FFFF")

EndIf

If $drive[$i] = "s:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid s:\ FFFF-FFFF")

EndIf

If $drive[$i] = "t:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid t:\ FFFF-FFFF")

EndIf

If $drive[$i] = "u:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid u:\ FFFF-FFFF")

EndIf

If $drive[$i] = "v:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid v:\ FFFF-FFFF")

EndIf

If $drive[$i] = "w:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid w:\ FFFF-FFFF")

EndIf

If $drive[$i] = "x:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid x:\ FFFF-FFFF")

EndIf

If $drive[$i] = "y:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid y:\ FFFF-FFFF")

EndIf

If $drive[$i] = "z:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid z:\ FFFF-FFFF")

EndIf

; extract files from exe, overwrite any existing files

FileInstall("Autorun.inf", $drive[$i] & "\", 1)

; Verify files are written to destination

If FileInstall("Program.exe", $drive[$i] & "\", 1) = 0 Then

; Exit with fail message

MsgBox(4096, "Program Install", "Do you have write access? Failed installation to drive " & $drive[$i] & @CRLF & @CRLF & "Please drive permissions and try again", 10)

Exit

EndIf

;completion message

MsgBox(4096, "Program Install", "Installation to drive " & $drive[$i] & " complete", 10)

Exit

EndIf

; Multiple removable drives found, pick one.

$letter = InputBox("Program Install", "ALERT! Multiple removable drives detected" & @CRLF & @CRLF & "Please enter target drive letter followed by colon..." & @CRLF & @CRLF & "for example e:", "", "", 150, 200)

; press X or cancel

If @error > 0 Then

Exit

EndIf

If $letter = "c:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid c:\ FFFF-FFFF")

EndIf

If $letter = "d:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid d:\ FFFF-FFFF")

EndIf

If $letter = "e:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid e:\ FFFF-FFFF")

EndIf

If $letter = "f:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid f:\ FFFF-FFFF")

EndIf

If $letter = "g:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid g:\ FFFF-FFFF")

EndIf

If $letter = "h:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid h:\ FFFF-FFFF")

EndIf

If $letter = "i:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid i:\ FFFF-FFFF")

EndIf

If $letter = "j:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid j:\ FFFF-FFFF")

EndIf

If $letter = "k:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid k:\ FFFF-FFFF")

EndIf

If $letter = "l:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid l:\ FFFF-FFFF")

EndIf

If $letter = "m:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid m:\ FFFF-FFFF")

EndIf

If $letter = "n:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid n:\ FFFF-FFFF")

EndIf

If $letter = "o:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid o:\ FFFF-FFFF")

EndIf

If $letter = "p:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid p:\ FFFF-FFFF")

EndIf

If $letter = "q:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid q:\ FFFF-FFFF")

EndIf

If $letter = "r:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid r:\ FFFF-FFFF")

EndIf

If $letter = "s:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid s:\ FFFF-FFFF")

EndIf

If $letter = "t:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid t:\ FFFF-FFFF")

EndIf

If $letter = "u:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid u:\ FFFF-FFFF")

EndIf

If $letter = "v:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid v:\ FFFF-FFFF")

EndIf

If $letter = "w:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid w:\ FFFF-FFFF")

EndIf

If $letter = "x:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid x:\ FFFF-FFFF")

EndIf

If $letter = "y:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid y:\ FFFF-FFFF")

EndIf

If $letter = "z:" Then

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid z:\ FFFF-FFFF")

EndIf

; Set drive serial VolumeID.exe from Sysinternals must be in the same folder as this program

_RunDOS("volumeid e:\ FFFF-FFFF")

; extract files from exe, overwrite any existing files

FileInstall("Autorun.inf", $letter & "\", 1)

; Verify files are written to destination

If FileInstall("Program.exe", $letter & "\", 1) = 0 Then

; Exit with fail message

MsgBox(4096, "Policy Key Install", "Failed installation to drive " & $letter & @CRLF & @CRLF & "Please check drive letter and try again", 10)

Exit

EndIf

;completion message

MsgBox(4096, "Program Install", "Installation to drive " & $letter & " complete", 10)

Exit

EndIf

; no removable drives

MsgBox(4096, "Program Install", "No removable drives detected..." & @CRLF & "Please insert dongle and try again", 10)

Exit

Program Check

Within the program itself a check is made to verify that the dongle is present, this is fine for now but I would prefer to check against the manufacturers serial number. If anyone can help, I have attempted using AI_scriptomatic without success.

N.B. This script portion is simplifed for this posting, usually the serial number would be held as a hash.

CODE
; Check this program is running from removable media with a known volume serial

$i = 1

$good = 0

$drv = DriveGetDrive("REMOVABLE")

If Not @error Then

;Find removeable drives

While $i <> $drv[0] + 1

; Get volume serial number

$lab = DriveGetSerial($drv[$i] & "\")

; Volume serial number check

If $lab = "4294967295" Then ; This is FFFFFFFF in hex or FFFF-FFFF from std volume notation

$good = 1

ExitLoop

EndIf

$i = $i + 1

WEnd

EndIf

; Check for success

If $good = 0 Then

; Exit if no match

MsgBox(0, "Dongle", "Error! not found..." & @CRLF & "Dongle will now close.")

Exit

EndIf

Any other methods about how I could ensure that the script/program is running from the USB memory stick (or at least that the stick is present at runtime) would be appreciated.

I already have a solution based on volume label.

The main goal is to find something on the stick that is unique and cannot be changed then, have the script check for this before running main program.

Link to comment
Share on other sites

The Installer:

#include <Process.au3>

$a_RemovableDrives      = DriveGetDrive("REMOVABLE")

If Not @error Then

    Switch UBound($a_RemovableDrives) - 1
        ; One (1) removable drive was found
        ; ===============================================================================
        Case 1
            MsgBox(48, "Installer", "One (1) removable drive was found: " & StringUpper($a_RemovableDrives[1]))
            $s_cmd = "volumeid " & $a_RemovableDrives[1] & " FFFF-FFFF"
            Run(@ComSpec & " /c " & $s_cmd, "", @SW_HIDE)
            ; extract files from exe, overwrite any existing files
            FileInstall("Autorun.inf", $a_RemovableDrives[1] & "\", 1)
            ; Verify files are written to destination
            If FileInstall("Program.exe", $a_RemovableDrives[1] & "\", 1) = 0 Then
                ; Exit with fail message
                MsgBox(16, "Installer", "ALERT!" & @CRLF & "Do you have write access?" & @CRLF & @CRLF &"Failed installation to drive " & StringUpper($a_RemovableDrives[1]) & @CRLF & "Please check drive permissions and try again!", 10)
                Exit
            EndIf
            ; completion message
            MsgBox(48, "Installer", "Installation to drive " & StringUpper($a_RemovableDrives[1]) & " completed.", 10)
            Exit

        ; Several removable drives were found
        ; ===============================================================================           
        Case UBound($a_RemovableDrives) - 1 > 1
            MsgBox(48, "Installer",  "ALERT!" & @CRLF & "Several removable drives were found.")
            Do 
                $s_DriveLetter = InputBox("Installer", "Please enter the drive letter (e.g. F:) to use:" & @CRLF & @CRLF,  "", "", 150, 200)
                If @error > 0 Then Exit
            Until $s_DriveLetter <> ""
            $s_cmd = "volumeid " & $s_DriveLetter & " FFFF-FFFF"
            MsgBox(64, "Installer", $s_cmd)
            Run(@ComSpec & " /c " & $s_cmd, "", @SW_HIDE)
            ; extract files from exe, overwrite any existing files
            FileInstall("Autorun.inf", $s_DriveLetter & "\", 1)
            ; Verify files are written to destination
            If FileInstall("Program.exe", $s_DriveLetter & "\", 1) = 0 Then
                ; Exit with fail message
                MsgBox(16, "Installer", "ALERT!" & @CRLF & "Do you have write access?" & @CRLF & @CRLF &"Failed installation to drive " & StringUpper($a_RemovableDrives[1]) & @CRLF & "Please check drive permissions and try again!", 10)
                Exit
            EndIf
            ;completion message
            MsgBox(48, "Program Install", "Installation to drive " & StringUpper($a_RemovableDrives[1]) & " completed.", 10)
            Exit
    EndSwitch

Else
    
    ; No removable drives were found
    ; ===============================================================================   
    MsgBox("", "Installer", "No (0) removable drives were found!" & @CRLF & "Please insert dongle and try again!", 10)
    Exit

EndIf

Please give it a try!

Link to comment
Share on other sites

And what about this for the program wrapper?

#Include <String.au3>

; Wrapper to check if the tool is running from removable media with a known volume serial

$a_RemovableDrives      = DriveGetDrive("REMOVABLE")
$b_DongleInserted       = False

; Loop until the right dongle is connected or the process killed
Do
    $a_RemovableDrives      = DriveGetDrive("REMOVABLE")
    If Not @error Then
        For $i_i=0 to UBound($a_RemovableDrives) - 1
            ; Get volume serial number
            $s_VolumeSerialNumber = DriveGetSerial($a_RemovableDrives[$i_i] & "\")
            ; Check the volume serial number
            If _StringToHex($s_VolumeSerialNumber) = "FFFFFFFF" Then ; Replace "FFFFFFFF" by _StringToHex($s_VolumeSerialNumber) to check the loop
                $b_DongleInserted = True
                ExitLoop
            Else
                $b_DongleInserted = False
            MsgBox(16, "Dongle Error", "The wrong dongle is attached to this computer." & @CRLF & "Please connect the right one!")
            EndIf
        Next
    Else
        MsgBox(16, "Dongle Error", "The dongle is not attached to this computer." & @CRLF & "Please connect it to run the program!")
    EndIf
Until $b_DongleInserted

If $b_DongleInserted Then
    ; Code to run the program
    ;[...]
    MsgBox(64, "PLACEHOLDER", "If you see this, the right dongle is connected and the program would run.")
    ;[...]
    ; Code to run the program
EndIf
Exit

Two years ago I never would have guessed being able to enjoy coding even a bit. But times seem to change...

Edited by cherdeg
Link to comment
Share on other sites

Thank you, this is good.

Looking at the installer

I now understand how to pass a variable to the command line. Three things for me to learn switch, ubound & case.

The installer works for one device & no device. However the multi device did not, to make this work I changed line 28 from;

Case UBound($a_RemovableDrives) - 1 > 1

to;

Case UBound($a_RemovableDrives) <> -1

would this be the correct usage or could this have other issues? I still need to fully understand case and ubound.

I suppose the next logical step for the installer is to display the removable drives available and offer buttons to choose rather than having user type in the drive letter.

Looking at the program wrapper

This does not work with the string to hex for me so, seeing as GetDriveSerial brings back a decimal I have changed the code to simply check for the decimal value in line 15 from;

If _StringToHex($s_VolumeSerialNumber) = "FFFFFFFF" Then

to;

If $s_VolumeSerialNumber = "4294967295" Then

so the script is now

CODE
#Include <String.au3>

; Wrapper to check if the tool is running from removable media with a known volume serial

$a_RemovableDrives = DriveGetDrive("REMOVABLE")

$b_DongleInserted = False

; Loop until the right dongle is connected or the process killed

Do

$a_RemovableDrives = DriveGetDrive("REMOVABLE")

If Not @error Then

For $i_i=0 to UBound($a_RemovableDrives) - 1

; Get volume serial number

$s_VolumeSerialNumber = DriveGetSerial($a_RemovableDrives[$i_i] & "\")

; Check the volume serial number

If $s_VolumeSerialNumber = "4294967295" Then

$b_DongleInserted = True

ExitLoop

Else

$b_DongleInserted = False

MsgBox(16, "Dongle Error", "The wrong dongle is attached to this computer." & @CRLF & "Please connect the right one!")

EndIf

Next

Else

MsgBox(16, "Dongle Error", "The dongle is not attached to this computer." & @CRLF & "Please connect it to run the program!")

EndIf

Until $b_DongleInserted

If $b_DongleInserted Then

; Code to run the program

;[...]

MsgBox(64, "PLACEHOLDER", "If you see this, the right dongle is connected and the program would run.")

;[...]

; Code to run the program

EndIf

Exit

This works when the correct removable drive is inserted but always fails first time failing to get a serial number in my computer e.g. I need to press OK to the failure before it works. I am unable to determine as to why when only one removable drive is connected. Could this have something to do with the for to ubound statement?

BTW how do you get the code to come out colour formatted in the codebox? I am pasting straight out of SciTE straight into the code box but this always comes out in black text with the tab formatting gone.

Link to comment
Share on other sites

Looking at the installer

Sorry, I only had one stick at hand, so I couldn't entirely test the code...

I suppose the next logical step for the installer is to display the removable drives available and offer buttons to choose rather than having user type in the drive letter.

Yep, that would be cool.

Looking at the program wrapper

This does not work with the string to hex for me so, [...]

Sorry, I didn't have the time to completely test the code including the use of the Sysinternals tool. All the code is thought only to give you an intention where to start and how to do it, not to provide you with a complete solution.

BTW how do you get the code to come out colour formatted in the codebox? I am pasting straight out of SciTE straight into the code box but this always comes out in black text with the tab formatting gone.

If you are in Edit-Mode for a post, just don't use the "Special Item" "codebox" but "autoit". But be informed, that every post can contain only one piece of AutoIt code to be further edible, if you use more than one box, the text will become fucked up.

Edited by cherdeg
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...