Por si fuera de interés, he estado experimentando otras vía más directa para obtener el número de serie que también trabaja con HD pero que no me convence porque no encuentra los números de serie USB en WinXP en las memorias que he probado y en Win10, al menos en una de ellas, cambia el último dígito del mismo al compararlo con el dato encontrado en el registro de Windows. Se basa en el uso de
IOCTL. Otra posibilidad puede ser con WMI.
Código Delphi
[-]
const
IOCTL_STORAGE_QUERY_PROPERTY = $2D1400;
type
PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR;
STORAGE_DEVICE_DESCRIPTOR = packed record
Version: ULONG;
Size: ULONG;
DeviceType: UCHAR;
DeviceTypeModifier: UCHAR;
RemovableMedia: Boolean;
CommandQueueing: Boolean;
VendorIdOffset: ULONG;
ProductIdOffset: ULONG;
ProductRevisionOffset: ULONG;
SerialNumberOffset: ULONG;
BusType: ULONG;
RawPropertiesLength: ULONG;
RawDeviceProperties: array[0..0] of UCHAR;
end;
PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY;
STORAGE_PROPERTY_QUERY = record
PropertyId: DWORD; QueryType: DWORD; AdditionalParameters: array[0..0] of UCHAR;
end;
function GetSerialNumber(Volume: Char; var SerialNumber: string): BOOL;
var
hFile: THANDLE;
SPQ: STORAGE_PROPERTY_QUERY;
SDD: STORAGE_DEVICE_DESCRIPTOR;
PSDD: PSTORAGE_DEVICE_DESCRIPTOR;
Size: DWORD;
begin
Result:= FALSE;
SerialNumber:= '';
hFile:= CreateFile(PAnsiChar('\\.\' + Volume + ':'),0,0,nil, OPEN_EXISTING, 0, 0);
if hFile <> INVALID_HANDLE_VALUE then
begin
ZeroMemory(@SPQ, sizeof(SPQ));
if DeviceIoControl(hFile, IOCTL_STORAGE_QUERY_PROPERTY, @SPQ, sizeof(SPQ), @SDD, sizeof(SDD), Size, nil) then
begin
PSDD:= VirtualAlloc(nil, SDD.Size, MEM_COMMIT, PAGE_READWRITE);
ZeroMemory(PSDD, SDD.Size);
if DeviceIoControl(hFile, IOCTL_STORAGE_QUERY_PROPERTY, @SPQ, sizeof(SPQ), PSDD, SDD.Size, Size, nil) then
begin
if PSDD.SerialNumberOffset <> 0 then
SerialNumber:= String(PCHAR(PSDD) + PSDD.SerialNumberOffset);
end;
VirtualFree(PSDD, 0, MEM_RELEASE);
end;
CloseHandle(hFile);
end;
Result:= Length(SerialNumber) <> 0;
end;
Saludos.