找回密码
 加入
搜索
查看: 7086|回复: 9

[系统综合] 如何修改卷的序列号?(已解决)

  [复制链接]
发表于 2010-3-1 13:00:13 | 显示全部楼层 |阅读模式
本帖最后由 wjc826194 于 2010-3-2 11:30 编辑

AU3函数中有DriveGetSerial  那有没有办法DriveSetSerial呢???高手帮帮忙``WMI似乎也只能读不能改.....

最新情况..在官方论坛找到一个原形  作者给出的编译过的文件是可以读取 也可以修改的``
但是给出的源代码却无法读 也无法修改... 源代码如下:
#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
 楼主| 发表于 2010-3-1 13:58:18 | 显示全部楼层
希望高手能修改一下....
发表于 2010-3-1 14:13:14 | 显示全部楼层
本帖最后由 pusofalse 于 2010-3-1 14:29 编辑

直接读写硬盘分区表。对于FAT32分区,第67~71这4个字节存取分区序列号;对于NTFS分区,序列号则在72~76字节处。
上面的代码不能正常工作,是因为没有先将卷锁定。调用DeviceIoControl函数发送IOCTL_LOCK_VOLUME控制码锁定之后再将新的数据写入。
 楼主| 发表于 2010-3-1 14:50:33 | 显示全部楼层
- -!
不会锁...
能不能直接把上面的代码修改一下``????多谢了 `
 楼主| 发表于 2010-3-2 01:15:27 | 显示全部楼层
再顶顶 看是否有人帮忙..
发表于 2010-3-2 02:19:58 | 显示全部楼层
#include <SetupApi.au3>

Const $IOCTL_LOCK_VOLUME = 0x90018
Const $IOCTL_UNLOCK_VOLUME = 0x9001C
Const $tagDRIVE_PER_SECTOR_DATA = "ubyte SectorData[512]"

Local $hDrive, $iAccessMask, $pBuffer, $pSerial
Local $tBuffer, $tSerial, $sDrive = "C:", $bNewSerial = 0xBEEFBEEF

$iAccessMask = bitOR($GENERIC_READ, $GENERIC_WRITE)
$pBuffer = _CM_Heap_Alloc(512)

Switch DriveGetFileSystem($sDrive)
Case "NTFS"
        $pSerial = $pBuffer + 72
Case "FAT32"
        $pSerial = $pBuffer + 67
Case Else
        _CM_Heap_Free($pBuffer)
        Msgbox(48, "Error!", $sDrive & " not support.")
        exit
EndSwitch

$hDrive = _CM_Create_File("\\." & $sDrive, $iAccessMask, 3, 0, 3, 0)
_CM_Device_IO_Control($hDrive, $IOCTL_LOCK_VOLUME, 0, 0, 0, 0)
_CM_Read_Device($hDrive, $pBuffer, 512)
_CM_Device_IO_Control($hDrive, $IOCTL_UNLOCK_VOLUME, 0, 0, 0, 0)
_CM_Close_Handle($hDrive)

$tBuffer = DllStructCreate($tagDRIVE_PER_SECTOR_DATA, $pBuffer)

$tSerial = DllStructCreate("hWnd Serial", $pSerial)
DllStructSetData($tSerial, "Serial", $bNewSerial)

$hDrive = _CM_Create_File("\\." & $sDrive, $iAccessMask, 3, 0, 3, 0)
_CM_Device_IO_Control($hDrive, $IOCTL_LOCK_VOLUME, 0, 0, 0, 0)
_CM_Write_Device($hDrive, $pBuffer, 512)
_CM_Device_IO_Control($hDrive, $IOCTL_UNLOCK_VOLUME, 0, 0, 0, 0)
_CM_Close_Handle($hDrive)

Msgbox(64, "", "Done!")
If (DriveGetFileSystem($sDrive) = "NTFS") Then
        Msgbox(48, "", "A system reboot is required to update the serial number.")
EndIf
Opt("TrayIconHide", 1)
ProcessClose(@AutoItPid)
 楼主| 发表于 2010-3-2 04:39:20 | 显示全部楼层
缺少2个函数

_CM_Read_Device
_CM_Write_Device
发表于 2010-3-2 08:06:06 | 显示全部楼层
udf区 ---- Au3 硬件设备管理UDF - SetupApi.au3
发表于 2012-2-12 09:15:18 | 显示全部楼层
P 版 真实 咱论坛的人才 为嘛不进群 胡砍呢
发表于 2019-8-19 13:15:40 | 显示全部楼层
下载看看,效果如何
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-19 21:21 , Processed in 0.086837 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表