hard disk serial returned from DeviceIoControl and STORAGE_DESCRIPTOR_HEADER is empty or has spaces before actual serial
whydoyou wanttoknow
1
Reputation point
I could get the serial using WMI in a win32 application but I'm working now in a windows service and having problems with WMI so I tried to use DeviceIoControl for PhysicalDrive0 to get the serial number. I looked at some sites online and cam with this function:
std::string get_hard_disk_serial_string()
{
// file is a wrapper for HANDLE and CreateFile.
file drive_file{ L"\\\\.\\PhysicalDrive0", open_mode::existing, access::read, share_mode::read | share_mode::write };
STORAGE_PROPERTY_QUERY query{};
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
auto ioctl_size = [&]() -> uint32_t
{
STORAGE_DESCRIPTOR_HEADER header{};
DWORD bytes_returned = 0;
BOOL ret = ::DeviceIoControl(drive_file.native_handle().get(), IOCTL_STORAGE_QUERY_PROPERTY, &query,
sizeof(query), &header, sizeof(header), &bytes_returned, nullptr);
if (!ret)
throw std::system_error(GetLastError(), std::system_category());
return header.Size;
};
std::vector<char> out_buff;
out_buff.resize(ioctl_size());
[&]
{
DWORD bytes_returned = 0;
BOOL ret = ::DeviceIoControl(drive_file.native_handle().get(), IOCTL_STORAGE_QUERY_PROPERTY, &query,
sizeof(query), out_buff.data(), static_cast<DWORD>(out_buff.size()), &bytes_returned, nullptr);
if (!ret)
throw std::system_error(GetLastError(), std::system_category());
}();
STORAGE_DEVICE_DESCRIPTOR* descriptor = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(out_buff.data());
if (!descriptor->SerialNumberOffset || descriptor->SerialNumberOffset >= out_buff.size())
{
printf("serial offset is 0 or greater than buffer size !\n");
return "";
}
// serial is null terminated ansi string
std::string_view serial = &out_buff[descriptor->SerialNumberOffset];
printf("disk serial: %s\n", serial.data()); // prints spaces before serial or an empty serial !
return std::string{ serial };
}
The problem is that on one computer running windows 10 the serial contained spaces before the actual serial " SERIAL-HERE" and on another one which runs windows server 2012 R2 the serial was totally empty !
Windows development | Windows API - Win32
Developer technologies | C++
Developer technologies | C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
Sign in to answer