Beilby Posted October 28, 2008 Posted October 28, 2008 Hi, This is my first post How can I set the volume id or volume serial number of a drive? DriveGetSerial will display the current volume serial number in decimal format
cherdeg Posted October 28, 2008 Posted October 28, 2008 (edited) $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 EDIT: Didn't test this - won't work: $o_Item.VolumeSerialNumber can't be $o_Item.Put Edited October 29, 2008 by cherdeg
Beilby Posted October 28, 2008 Author Posted October 28, 2008 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.:
cherdeg Posted October 29, 2008 Posted October 29, 2008 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?
Beilby Posted October 30, 2008 Author Posted October 30, 2008 InstallerSo 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) ExitEndIf; no removable drivesMsgBox(4096, "Program Install", "No removable drives detected..." & @CRLF & "Please insert dongle and try again", 10)ExitProgram CheckWithin 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 WEndEndIf; Check for successIf $good = 0 Then ; Exit if no match MsgBox(0, "Dongle", "Error! not found..." & @CRLF & "Dongle will now close.") ExitEndIfAny 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.
cherdeg Posted October 31, 2008 Posted October 31, 2008 The Installer: expandcollapse popup#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!
cherdeg Posted October 31, 2008 Posted October 31, 2008 (edited) 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 October 31, 2008 by cherdeg
Beilby Posted November 1, 2008 Author Posted November 1, 2008 Thank you, this is good.Looking at the installerI 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 > 1to;Case UBound($a_RemovableDrives) <> -1would 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 wrapperThis 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" Thenso the script is nowCODE#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 killedDo $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!") EndIfUntil $b_DongleInsertedIf $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 programEndIfExitThis 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.
cherdeg Posted November 3, 2008 Posted November 3, 2008 (edited) 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 November 3, 2008 by cherdeg
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