65.9K
CodeProject 正在变化。 阅读更多。
Home

更改卷的序列号

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (68投票s)

2004年1月12日

3分钟阅读

viewsIcon

722493

downloadIcon

23750

一篇介绍如何更改驱动器序列号的文章

引言

本文将演示如何在三种不同的文件系统上更改驱动器的序列号:FAT、FAT32 和 NTFS。本文的源代码文件带有一个自制的 DiskSector 读/写类,适用于 WinNt/2k/XP 和 Win9x 系统。本文还附带一个方便的基于对话框的应用程序,允许您以可视方式更改序列号。

工作原理

通常,驱动器的序列号是在每次格式化硬盘驱动器时生成的,并且没有记录在案的方法可以在之后更改它。

值得注意的是,“dir”命令或 GetVolumeInformation() API 返回的序列号不是来自制造商的硬件序列号,而是由文件系统分配并存储在硬盘驱动器(主要在引导扇区中)中的序列号,并且*可以*通过软件更改。

了解到序列号存储在硬盘驱动器中,我开始查找有关三种不同文件系统的信息:FAT、FAT32、NTFS。 最相关的部分是查看每个不同文件系统的引导扇区格式。通常,引导扇区保存对于文件系统的完整性和操作至关重要的数据。

在这些字段中,我们列出了包含字段名称、文件系统和引导扇区中相应偏移量(十六进制)的表

表 1

字段/文件系统 FAT FAT32 NTFS
卷标 0x2B 0x47 ?
文件系统 ID 0x36 0x52 0x3
序列号 0x27 0x43 0x48

例如,我们可以将此表中的一个条目读取为:“在 FAT 文件系统中,'序列号' 存储在从引导扇区起始位置偏移 0x27 的位置”。 重要的是要知道引导扇区从扇区零开始,长度为 512 字节。 下一部分将解释如何编写 ChangeSerialNumber() 函数。

解释代码

首先,我将解释代码流程

  1. 打开硬盘驱动器设备以读取/写入扇区。
  2. 读取引导扇区
  3. 识别所讨论驱动器的文件系统
  4. 根据当前文件系统修改序列号字段(参考表 1)
  5. 写回修改后的引导扇区
  6. 关闭硬盘驱动器设备
void CVolumeSerialDlg::ChangeSerialNumber(DWORD Drive, const DWORD newSerial)
{
  const max_pbsi = 3;

  struct partial_boot_sector_info
  {
    LPSTR Fs; // file system name
    DWORD FsOffs; // offset of file system name in the boot sector
    DWORD SerialOffs; // offset of the serialnumber in the boot sector
  };

  partial_boot_sector_info pbsi[max_pbsi] =
  {
   {"FAT32", 0x52, 0x43},
   {"FAT",   0x36, 0x27},
   {"NTFS",  0x03, 0x48}
  };

  TCHAR szDrive[12];

  char Sector[512];

  DWORD i;

  sprintf(szDrive, "%c:\\", Drive & 0xFF);

  if (!disk.Open(szDrive))
  {
    ShowErrorString("Could not open disk!");
    return;
  }

  // read sector
  if (!disk.ReadSector(0, Sector))
  {
    ShowErrorString("Could not read sector!");
    return;
  }

  // try to search for a valid boot sector
  for (i=0;i<max_pbsi;i++)
  {
    if (strncmp(pbsi[i].Fs, Sector+pbsi[i].FsOffs, strlen(pbsi[i].Fs)) == 0)
    {
      // we found a valid signature
      break;
    }
  }

  if (i >= max_pbsi)
  {
    MessageBox(_T("Cannot change serial number of this file system!"),
       _T("Error"), MB_ICONERROR);
    return;
  }
  
  // patch serial number
  *(PDWORD)(Sector+pbsi[i].SerialOffs) = newSerial;

  // write boot sector
  if (!disk.WriteSector(0, Sector))
  {
    ShowErrorString("Could not write sector!");
    return;
  }

  ShowErrorString("Volume serial number changed successfully!\r"
        "You might want to restart your system for changes to take effect!");
}

此函数的核心是“partial_boot_sector_info/pbsi”表,它由表 1 构建。此表将允许我们检查此引导扇区属于哪个文件系统,然后它允许我们正确修补序列号字段。 似乎如果您更改 NTFS 卷的序列号,则更改在您重新启动系统之前不会生效。

另请注意,更改分区的序列号将使某些许可程序失效,因此在尝试更改之前写下原始序列号,以防万一您想将其恢复。

参考

更新

  • v1.0
    • 初始版本:仅支持 WinNT
  • v1.2
    • 添加了 Win9x 和 WinNT 支持
    • 文档更新
© . All rights reserved.