#AutoIt3Wrapper_Icon=.\Resources\vsc.ico
#AutoIt3Wrapper_Res_Description=Tool for modify the drive Volume Serial Number
#AutoIt3Wrapper_Res_Fileversion=1.0
#AutoIt3Wrapper_Res_LegalCopyright=Copyright ?R.Gilman (a.k.a. rasim) 2008
#NoTrayIcon
;============# Prevent from secondary run #============================================================
Dim $hMutex = DllCall("kernel32.dll", "hwnd", "OpenMutex", "int", 0x1F0001, "int", False, "str", "VSC")
If $hMutex[0] Then
WinActivate("VSC v1.0")
Exit
EndIf
DllCall("kernel32.dll", "hwnd", "CreateMutex", "int", 0, "int", False, "str", "VSC")
;=======================================================================================================
Global Const $INVALID_HANDLE_VALUE = 0xFFFFFFFF
If $CmdLine[0] > 0 Then
Switch $CmdLine[0]
Case 1
MsgBox(64, "VSC", "Command Line Parameters:" & @LF & @LF & _
"VSC.exe <DriveLetter> <SerialNumber>")
Case 2
If DriveStatus(StringLeft($CmdLine[1], 1) & ":") <> "READY" Then
MsgBox(16, "VSC error", 'Drive "' & $CmdLine[1] & '" not ready')
ElseIf (StringIsXDigit($CmdLine[2]) = 0) Or (StringLen($CmdLine[2]) <> 8) Then
MsgBox(16, "VSC error", "Please enter the valid serial number")
Else
If _SerialNumberSet(StringLeft($CmdLine[1], 1), StringUpper($CmdLine[2])) Then
MsgBox(64, "VSC", "Volume Serial Number changed successfully!" & @LF & _
"Please restart your computer for changes to take effect.")
Else
MsgBox(16, "VSC error", "Could not read sector")
EndIf
EndIf
EndSwitch
Exit
EndIf
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
FileInstall(".\Resources\Help\Help.htm", @TempDir & "\Help.htm", 1)
FileInstall(".\Resources\Help\vsc.png", @TempDir & "\vsc.png", 1)
FileInstall(".\Resources\Help\serial.png", @TempDir & "\serial.png", 1)
#Region GUI
$hGUI = GUICreate("VSC v1.0", 340, 238)
$Group = GUICtrlCreateGroup("Info", 11, 10, 320, 90, 0x0300)
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlCreateLabel("The format of volume serial number is: XXXX-XXXX, X maybe 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F" & @LF & @LF & _
"Reboot is required for changes to take effect", 20, 30, 300, 55)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUICtrlCreateLabel("Drive:", 11, 120, 30, 15)
Dim $strDrives = _DriveGetDrive()
Dim $strDefault, $i
For $i = 1 To StringLen($strDrives) Step 2
$strDefault = StringMid($strDrives, $i, 1)
If StringRegExp($strDefault, "A|B") = 0 Then ExitLoop
Next
$Drive_Combo = GUICtrlCreateCombo("", 161, 115, 170, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST))
GUICtrlSetData(-1, $strDrives, $strDefault)
GUICtrlCreateLabel("Current Volume Serial Number:", 11, 147, 150, 15)
Dim $sCurrentSerial = _SerialNumberGet(GUICtrlRead($Drive_Combo))
$CurrentSerial_Input = GUICtrlCreateInput($sCurrentSerial, 161, 142, 170, 20, BitOR($ES_LEFT, $ES_READONLY))
GUICtrlCreateLabel("New Volume Serial Number:", 11, 174, 135, 15)
$NewSerial_Input = GUICtrlCreateInput("", 161, 169, 170, 20, BitOR($ES_LEFT, $ES_UPPERCASE))
GUICtrlSetLimit(-1, 9)
$Change_Button = GUICtrlCreateButton("Change", 11, 204, 75, 23)
$Help_Button = GUICtrlCreateButton("Help", 135, 204, 75, 23)
$Close_Button = GUICtrlCreateButton("Close", 255, 204, 75, 23)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUISetState()
_ProcessReduceMemory(@AutoItPID)
#EndRegion GUI
;
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE, $Close_Button
FileDelete(@TempDir & "\Help.htm")
FileDelete(@TempDir & "\vsc.png")
Exit
Case $Drive_Combo
GUICtrlSetData($CurrentSerial_Input, _SerialNumberGet(GUICtrlRead($Drive_Combo)))
If GUICtrlRead($CurrentSerial_Input) = "N/A" Then
GUICtrlSetState($NewSerial_Input, $GUI_DISABLE)
Else
GUICtrlSetState($NewSerial_Input, $GUI_ENABLE)
EndIf
Case $Change_Button
$sSerial = GUICtrlRead($NewSerial_Input)
If ($sSerial = "") Or (StringLen($sSerial) < 9) Then
MsgBox(16, "VSC error", "Please enter the valid serial number", 0, $hGUI)
GUICtrlSetState($NewSerial_Input, $GUI_FOCUS)
Else
If _SerialNumberSet(GuiCtrlRead($Drive_Combo), StringReplace($sSerial, "-", "")) Then
GUICtrlSetData($CurrentSerial_Input, GUICtrlRead($NewSerial_Input))
MsgBox(64, "VSC", "Volume Serial Number changed successfully!" & @LF & _
"Please restart your computer for changes to take effect.", 0, $hGUI)
Else
MsgBox(16, "VSC error", "Could not read sector", 0, $hGUI)
EndIf
EndIf
Case $Help_Button
ShellExecute(@TempDir & "\Help.htm")
EndSwitch
WEnd
#Region functions
Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
Local $iIDFrom = BitAND($wParam, 0x0000FFFF)
Local $iCode = BitShift($wParam, 16)
Switch $iIDFrom
Case $NewSerial_Input
Switch $iCode
Case $EN_UPDATE
Local $iRead = GUICtrlRead($NewSerial_Input)
If StringIsXDigit($iRead) = 0 Then $iRead = StringRegExpReplace($iRead, "[^A-F0-9]", "")
If (StringLen($iRead) > 4) Then $iRead = StringLeft($iRead, 4) & "-" & StringTrimLeft($iRead, 4)
GUICtrlSetData($NewSerial_Input, $iRead)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==> WM_COMMAND
Func _DriveGetDrive()
Local $aDrive = DriveGetDrive("ALL")
If @error Then Return False
Local $iDriveString, $i
For $i = 1 To $aDrive[0]
If StringRegExp(DriveGetType($aDrive[$i]), "(?i)Fixed|Removable") Then $iDriveString &= StringLeft(StringUpper($aDrive[$i]), 1) & "|"
Next
Return StringTrimRight($iDriveString, 1)
EndFunc ;==> _DriveGetDrive
Func _SerialNumberGet($sDrive)
Local $hDrive = _CreateFile($sDrive)
If $hDrive = $INVALID_HANDLE_VALUE Then Return "N/A"
If _SetFilePointer($hDrive) = -1 Then
_CloseHandle($hDrive)
Return "N/A"
EndIf
Local $iReadSector = _ReadFile($hDrive)
If $iReadSector = 0 Then
_CloseHandle($hDrive)
Return "N/A"
EndIf
_CloseHandle($hDrive)
Local $iOffset
Switch DriveGetFileSystem($sDrive & ":")
Case "FAT"
$iOffset = Dec("27") * 2 + 2
Case "FAT32"
$iOffset = Dec("43") * 2 + 2
Case "NTFS"
$iOffset = Dec("48") * 2 + 2
Case Else
Return "N/A"
EndSwitch
Local $strSerial = StringMid($iReadSector, $iOffset + 1, 8)
Local $iSubString, $iSerial
For $i = 1 To StringLen($strSerial) Step 2
$iSubString = StringMid($strSerial, $i, 2)
If $i = 5 Then $iSubString &= "-"
$iSerial = $iSubString & $iSerial
Next
Return $iSerial
EndFunc ;==>_SerialNumberGet
Func _SerialNumberSet($sDrive, $sSerial)
Local $hDrive = _CreateFile($sDrive)
If $hDrive = $INVALID_HANDLE_VALUE Then Return False
If _SetFilePointer($hDrive) = -1 Then
_CloseHandle($hDrive)
Return False
EndIf
Local $iReadSector = _ReadFile($hDrive)
If $iReadSector = 0 Then
_CloseHandle($hDrive)
Return False
EndIf
Local $iOffset
Switch DriveGetFileSystem($sDrive & ":")
Case "FAT"
$iOffset = Dec("27") * 2 + 2
Case "FAT32"
$iOffset = Dec("43") * 2 + 2
Case "NTFS"
$iOffset = Dec("48") * 2 + 2
Case Else
_CloseHandle($hDrive)
Return False
EndSwitch
Local $iSubString, $iNewSerial, $iWriteResult
For $i = 1 To StringLen($sSerial) Step 2
$iSubString = StringMid($sSerial, $i, 2)
$iNewSerial = $iSubString & $iNewSerial
Next
$iReadSector = StringLeft($iReadSector, $iOffset) & $iNewSerial & StringTrimLeft($iReadSector, $iOffset + 8)
If _SetFilePointer($hDrive) = -1 Then
_CloseHandle($hDrive)
Return False
EndIf
$iWriteResult = _WriteFile($hDrive, $iReadSector)
_CloseHandle($hDrive)
Return $iWriteResult
EndFunc ;==>_SerialNumberSet
Func _CreateFile($sDrive)
Local Const $GENERIC_READ = 0x80000000
Local Const $GENERIC_WRITE = 0x40000000
Local Const $FILE_SHARE_READ = 0x1
Local Const $FILE_SHARE_WRITE = 0x2
Local Const $OPEN_EXISTING = 3
Local $szVolumeName = "\\." & $sDrive & ":"
$aRet = DllCall("kernel32.dll", "hwnd", "CreateFile", _
"str", $szVolumeName, _
"int", BitOR($GENERIC_READ, $GENERIC_WRITE), _
"int", BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), _
"ptr", 0, _
"int", $OPEN_EXISTING, _
"int", 0, _
"int", 0)
Return $aRet[0]
EndFunc ;==>_CreateFile
Func _SetFilePointer($hDrive, $sDistance = 0)
$aRet = DllCall("kernel32.dll", "int", "SetFilePointer", _
"hwnd", $hDrive, _
"long", $sDistance, _
"ptr", 0, _
"dword", 0)
Return $aRet[0]
EndFunc ;==>_SetFilePointer
Func _ReadFile($hDrive)
Local $lpBUFFER = DllStructCreate("byte[512]")
$aRet = DllCall("kernel32.dll", "int", "ReadFile", _
"hwnd", $hDrive, _
"ptr", DllStructGetPtr($lpBUFFER), _
"dword", 512, _
"dword*", 0, _
"ptr", 0)
If $aRet[0] = 0 Then Return 0
Return DllStructGetData($lpBUFFER, 1)
EndFunc ;==>_ReadFile
Func _WriteFile($hDrive, $sData)
Local $lpBUFFER = DllStructCreate("byte[512]")
DllStructSetData($lpBUFFER, 1, $sData)
$aRet = DllCall("Kernel32.dll", "int", "WriteFile", _
"hwnd", $hDrive, _
"ptr", DllStructGetPtr($lpBUFFER), _
"dword", 512, _
"dword*", 0, _
"ptr", 0)
Return $aRet[0]
EndFunc ;==>_WriteFile
Func _CloseHandle($hDrive)
$aRet = DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDrive)
Return $aRet[0]
EndFunc ;==>_CloseHandle
Func _ProcessReduceMemory($iPID)
Local Const $PROCESS_ALL_ACCESS = 0x1F0FFF
Local $iProcExists = ProcessExists($iPID) ;To get the PID and check process existence
Local $hOpenProc, $aResult
If Not $iProcExists Then Return SetError(1, 0, 0)
If IsString($iPID) Then $iPID = $iProcExists
$hOpenProc = DllCall("Kernel32.dll", "int", "OpenProcess", "int", $PROCESS_ALL_ACCESS, "int", False, "int", $iPID)
$aResult = DllCall("Kernel32.dll", "int", "SetProcessWorkingSetSize", "hwnd", $hOpenProc[0], "int", -1, "int", -1)
DllCall("Kernel32.dll", "int", "CloseHandle", "int", $hOpenProc[0])
If Not IsArray($aResult) Or $aResult[0] = 0 Then Return SetError(2, 0, 0)
Return $aResult[0]
EndFunc ;==>_ProcessReduceMemory
#EndRegion functions