Get serial number of USB Drive (correctly) C++ version

  • Thread starter Thread starter RobHicSunt
  • Start date Start date
R

RobHicSunt

Guest
A post in the Visual Basic forum asked for getting the USB serial number correctly.

Get serial number of USB Drive (correctly)

I rewrote in C++ those ideas using some hints from a blog (Get Physical Drive Serial Number - Part 1 | codexpert blog).

For some reason I cannot add a reply to the former post, so I am creating one here in the right forum. Hence, this is not really a question, but I hope it helps anyone :)



#include <windows.h>
#include <ioapiset.h>
#include <iostream>
#include <string>


BOOL GetSerialNumberUSB(LPCWSTR sDriveName, std::string &strSerialNumber) {
// Get serial number of USB Drive (correctly)
// handle to physical drive
HANDLE hVolume = CreateFileW(
sDriveName, // lpFileName
GENERIC_READ, // dwDesiredAccess
FILE_SHARE_READ || FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
NULL // hTemplateFile
);
if (hVolume == INVALID_HANDLE_VALUE) {
// print GetLastError()
return FALSE;
}

// set the STORAGE_PROPERTY_QUERY input
STORAGE_PROPERTY_QUERY PropertyQuery;
ZeroMemory(&PropertyQuery, sizeof(STORAGE_PROPERTY_QUERY));
PropertyQuery.PropertyId = StorageDeviceProperty;
PropertyQuery.QueryType = PropertyStandardQuery;

// first call to DeviceIocontrol to get the size of the output
STORAGE_DEVICE_DESCRIPTOR DeviceDescriptor = { 0 };
DWORD nBytesDeviceDescriptor = 0;
if ( !DeviceIoControl(
hVolume, // hDevice
IOCTL_STORAGE_QUERY_PROPERTY, // dwIoControlCode
&PropertyQuery, // lpInBuffer
sizeof(STORAGE_PROPERTY_QUERY), // nInBufferSize
&DeviceDescriptor, // lpOutBuffer
sizeof(STORAGE_DESCRIPTOR_HEADER), // nOutBufferSize
&nBytesDeviceDescriptor, // lpBytesReturned
NULL // lpOverlapped
)) {
// print GetLastError()
CloseHandle(hVolume);
return FALSE;
}

// allocate the output
const DWORD dwOutBufferSize = DeviceDescriptor.Size;
char* pOutBuffer = new char[dwOutBufferSize];
ZeroMemory(pOutBuffer, dwOutBufferSize);
STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(pOutBuffer);

// second call to DeviceIocontrol to get the actual output STORAGE_DEVICE_DESCRIPTOR
if (!DeviceIoControl(
hVolume,
IOCTL_STORAGE_QUERY_PROPERTY,
&PropertyQuery,
sizeof(PropertyQuery),
pDeviceDescriptor,
dwOutBufferSize,
&nBytesDeviceDescriptor,
NULL
)) {
// print GetLastError()
delete[] pOutBuffer;
CloseHandle(hVolume);
return FALSE;
}

const DWORD nSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset;
if (nSerialNumberOffset == 0) {
// print GetLastError()
delete[] pOutBuffer;
CloseHandle(hVolume);
return FALSE;
}
strSerialNumber = static_cast<std::string>(pOutBuffer + nSerialNumberOffset);

delete[] pOutBuffer;
CloseHandle(hVolume);
return (strSerialNumber.empty()) ? FALSE : TRUE;
}

int main(void) {
std::string s;
GetSerialNumberUSB(L"\\\\.\\E:", s); // for USB drive E:
std::cout << s << std::endl;
return 0;
}

Continue reading...
 
Back
Top