Reputation:
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.
Upvotes: 0
Views: 688
Reputation: 2576
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 );
Upvotes: 0
Reputation: 69346
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:
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.
Upvotes: 1