Different disk serial number result from GetVolumeInformation()

DualCore picture DualCore · Jan 28, 2015 · Viewed 9.2k times · Source
DWORD disk_serialINT[MAX_PATH + 1];
GetVolumeInformationA(NULL, NULL, NULL, disk_serialINT, NULL, NULL, NULL, NULL);
char* disk_serialANSI;
sprintf(disk_serialANSI, "%d", disk_serialINT);
std::string HDDserial = disk_serialANSI;

This is my piece of code where I get the hdd serial number, but the problem is that every time when the program executes the value is different. Can someone explain that?

SOLVED:

DWORD disk_serialINT;
GetVolumeInformationA(NULL, NULL, NULL, &disk_serialINT, NULL, NULL, NULL, NULL);
std::string HDDserial = std::to_string(disk_serialINT);

Thanks.

Answer

Some programmer dude picture Some programmer dude · Jan 28, 2015

These two lines will give you undefined behavior:

char* disk_serialANSI;
sprintf(disk_serialANSI, "%d", disk_serialINT);

You declare a pointer variable, but you don't actually make it point anywhere. Uninitialized local variables have an indeterminate value (in practice it will be seemingly random), and by using that uninitialized pointer you don't know where the sprintf call will write.


Since you're programming in C++ there are a couple of solutions.

  • The old-fashioned is to make disk_serialANSI an array of characters, big enough to hold the number (including string terminator). An alternative is to manually allocate memory for the pointer, and then free that memory again when you're done with it.

  • Using std::ostringstream to format the data and get a std::string.

  • Using std::to_string to convert to a string directly.

  • Use Boost Lexical cast.