Hallo zusammen,
nach einiger Sucherei und eigenen Experimenten habe ich eine Funktion zum Ermitteln der hardwaremäßigen Seriennummer eines angeschlossenen USB-Sticks erstellt, die unter WinXP bis Win 7 funktioniert.
Übergeben wird eine Stringlist mit zu prüfenden Seriennummern. Ist eine der Nummern die Seriennummer eines angeschlossenen USB-Sticks, wird True zurückgeliefert. Bisher haben alle Sticks, die ich hier zur Verfügung habe funktioniert, darunter auch Werbesticks.
Man muss nur die SetupAPI aus dem Jediprojekt mit einbinden. Der CfgMgr ist nicht notwendig.
Getestet habe ich das Ganze bisher unter folgenden Betriebssystemen:
Win XP 32, Win7 32/64, Server 2003 R2, Server 2008 R2. (Vista sollte auch funktionieren. Vielleicht sogar Win2k.)
Quellen: Alles was man bei Google und hier zum Thema findet.
Vielleicht ist's ja was für die Codelib.
Grüße,
Uwe
Delphi-Quellcode:
// SetupApi muss eingebunden sein!
function FindUsbSerialNumber(SerialNumbers : TStrings): Boolean;
const
GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
var
StorageGUID: TGUID;
pHandle: HDEVINFO;
DevData: TSPDevInfoData;
DeviceInterfaceData: TSPDeviceInterfaceData;
FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
bSuccess: Boolean;
iDevn, i, iPos: Integer;
dwBytesReturned: DWORD;
sDevStr, sSerialNumber : string;
begin
Result := False;
StorageGUID := GUID_DEVINTERFACE_USB_DEVICE;
// alle angeschlossenen USB-Geräte prüfen
pHandle := SetupDiGetClassDevs(@StorageGUID, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
if pHandle = Pointer(INVALID_HANDLE_VALUE) then
Exit;
try
iDevn := 0;
repeat
DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
bSuccess := SetupDiEnumDeviceInterfaces(pHandle, nil, StorageGUID, iDevn, DeviceInterfaceData);
if bSuccess then
begin
DevData.cbSize := SizeOf(DevData);
dwBytesReturned := 0;
SetupDiGetDeviceInterfaceDetail(pHandle, @DeviceInterfaceData, nil, 0, dwBytesReturned, @DevData);
if (dwBytesReturned <> 0) then
begin
FunctionClassDeviceData := AllocMem(dwBytesReturned);
try
FunctionClassDeviceData.cbSize := SizeOf(TSPDeviceInterfaceDetailData);
if SetupDiGetDeviceInterfaceDetail(pHandle, @DeviceInterfaceData,
FunctionClassDeviceData, dwBytesReturned, dwBytesReturned, @DevData) then
begin
sDevStr := copy(PWideChar(@FunctionClassDeviceData.DevicePath), 0, MaxInt);
// Seriennummer aus sDevStr extrahieren
iPos := Pos('#', sDevStr);
if iPos > -1 then
begin
sSerialNumber := copy(sDevStr, iPos + 1, MaxInt);
iPos := Pos('#', sSerialNumber);
if iPos > -1 then
begin
sSerialNumber := copy(sSerialNumber, iPos + 1, MaxInt);
iPos := Pos('#', sSerialNumber);
if iPos > -1 then
begin
sSerialNumber := copy(sSerialNumber, 1, iPos - 1);
// alle übergebenen Seriennummern vergleichen
i := 0;
while (i < SerialNumbers.Count) and not Result do
begin
Result := AnsiUpperCase(sSerialNumber) = SerialNumbers[i];
Inc(i);
end;
end;
end;
end;
end;
finally
FreeMem(FunctionClassDeviceData);
end;
end;
end;
Inc(iDevn);
until Result or not bSuccess;
finally
SetupDiDestroyDeviceInfoList(pHandle);
end;
end;