Search by Tags

Reading the Serial Number of an USB Mass Storage Device

 

Tags
USB

Article updated at 25 Feb 2020

Introduction

The serial number of a USB mass storage device can be queried on most of the newer Toradex BSPs. This article shows a simple example, assuming that there is only one mass storage device connected.

Example Code

The initial definitions are part of diskio.h. This header file is not in the Toradex SDK by default, therefore we duplicated the definitions as part of the example.

#include "windows.h"
#include "winioctl.h"
 
// Definitions for the IOCTL code
#define IOCTL_DISK_BASE FILE_DEVICE_DISK
#define IOCTL_DISK_GET_STORAGEID   \
        CTL_CODE(IOCTL_DISK_BASE, 0x709, \
		         METHOD_BUFFERED, FILE_ANY_ACCESS)
 
// Structure for use with IOCTL_DISK_GET_STORAGEID
typedef struct _STORAGE_IDENTIFICATION {
    DWORD dwSize;
    DWORD dwFlags;
    DWORD dwManufactureIDOffset;
    DWORD dwSerialNumOffset;
} STORAGE_IDENTIFICATION, *PSTORAGE_IDENTIFICATION;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
	// first mass storage device (DSK1 is the on-module FlashDisk)
	const WCHAR *storageName = L"DSK2:";
	HANDLE hVolume;
	PSTORAGE_IDENTIFICATION psid = (PSTORAGE_IDENTIFICATION)malloc(128);
	BOOL fSuccess;
	DWORD numBytes;
 
    hVolume = CreateFile(storageName, GENERIC_READ|GENERIC_WRITE, 
		                 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hVolume == INVALID_HANDLE_VALUE)
		return -1;
 
	fSuccess = DeviceIoControl(
		hVolume,
		IOCTL_DISK_GET_STORAGEID,
		NULL, 0,
		psid, 128,
		&numBytes,
		0);
	CloseHandle(hVolume);
 
	NKDbgPrintfW(L"DeviceIoControl(0x%08x) returns %d\r\n", 
		         IOCTL_DISK_GET_STORAGEID, fSuccess);
	if (!fSuccess)
		NKDbgPrintfW(L"\tError Code: %d\r\n", GetLastError());
 
	NKDbgPrintfW(L"\tIOCTL returned %d bytes. Flags=0x%08x\r\n", 
				 psid->dwSize, psid->dwFlags);
	NKDbgPrintfW(L"\tManufactureID = %S\r\n", 
				 (char*)psid + psid->dwManufactureIDOffset);
	NKDbgPrintfW(L"\tSerialNum = %S\r\n", 
				 (char*)psid + psid->dwSerialNumOffset);
}