Home > OS >  How to change disk serial numbers using WinAPI?
How to change disk serial numbers using WinAPI?

Time:10-13

To get the disk serial number I would use function GetVolumeInformation but I couldn't find a way to change it using windows api like VolumeID program from Sysinternals does.

CodePudding user response:

There is no Windows API to do this easily, you will have to manually overwrite the volume ID in the boot sector of the drive. This involves (at least) three different operations:

  1. Get an handle to the volume.
  2. Read the boot sector and parse it to recognize the filesystem type (FAT vs FAT32 vs NTFS, etc.).
  3. Overwrite the Volume ID field and re-write the modified boot sector back to the disk.

It's not that simple of an operation, but this is how Sysinternals VolumeID does it. Note that boot sector fields and offsets are different for every filesystem.

CodePudding user response:

The way SysInternals Volume ID does this. First open the volume with CreateFile API

char volumeName[8];
char const driveLetter = 'F';
char const volumeFormat[] = "\\\\.\\%c:";
sprintf_s(volumeName,8,volumeFormat, driveLetter);
HANDLE hVolume = CreateFileA(volumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

Next read 512 bytes (This is read into a struct, i'm not sure the exact structure)

DWORD dwBytesRead;
 ReadFile(hVolume,&volumeHeader, 512, &dwBytesRead, NULL);

Using struct defined like this:

struct VOLUME_HEADER
    {
        char v1[3];
        char v2[36];
        int v3;
        char v4[13]; 
        int v5;
        int v6;
        char v7[430]; 
        char v8[12];
       
    };

The structure is checked if it is NTFS, FAT, FAT32 etc.

 if (!strncmp(volumeHeader.v2, "NTFS", 4u))
        {
            printf("Volume is NTFS!\n");
        }
        else if (!strncmp(volumeHeader.v7, "FAT32", 5u))
        {
            printf("Volume is FAT32!\n");
        }
        else
        {
            if (strncmp(volumeHeader.v4, "FAT", 3u))
            {
                printf("\n\nUnrecognized drive type\n");
                return 0;                
            }
            printf(":Volume is FAT!\n");
        }

Then a 32-bit integer is updated in this structure with the new volume ID. If you retrieve a specific volume like NTFS you can find the offset of the volume ID if you know the existing one. Then file pointer is set back to beginning of file and data is written back with WriteFile API.

SetFilePointer ( hVolume, 0, NULL, FILE_BEGIN );
WriteFile ( hVolume, &volumeHeader, 512, &dwBytesWritten, NULL );
  • Related