Einzelnen Beitrag anzeigen

Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#11

AW: USB-Stick - Seriennummer/Produktname auslesen

  Alt 24. Nov 2010, 01:22
Ein Weg scheint darin zu bestehen direkt in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\U SB nachzugucken.

WMI ginge auch noch.

Aber ich habe mich für den schon beschriebenen Weg entschieden:

Delphi-Quellcode:
program usbkey;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows,
  SetupApi,
  Cfg,
  CfgMgr32;

// From WDK/DDK (ntddstor.h, winioctl.h)
const GUID_DEVINTERFACE_DISK: TGUID = '{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}';

const props : array[0..12] of DWORD = (
  SPDRP_CLASS,
  SPDRP_CLASSGUID,
  SPDRP_DEVICEDESC,
  SPDRP_DRIVER,
  SPDRP_ENUMERATOR_NAME,
  SPDRP_FRIENDLYNAME,
  SPDRP_LOCATION_INFORMATION,
  SPDRP_MFG,
  SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
  SPDRP_SECURITY_SDS,
  SPDRP_SERVICE,
  SPDRP_UI_NUMBER_DESC_FORMAT,
  SPDRP_UI_NUMBER
  );

function GetDeviceRegProperty(hDevInfo: THandle; const spdevid : TSPDevInfoData; dwProperty: DWORD): String;
var
  dwTemp, dwRequired : DWORD;
begin
  case dwProperty of
  // REG_DWORD
  SPDRP_ADDRESS,
  SPDRP_BUSNUMBER,
  SPDRP_CAPABILITIES,
  SPDRP_CHARACTERISTICS,
  SPDRP_CONFIGFLAGS,
  SPDRP_DEVTYPE,
  SPDRP_INSTALL_STATE,
  SPDRP_UI_NUMBER:
  begin
    if(SetupDiGetDeviceRegistryProperty(hDevInfo, spdevid, dwProperty, PDWORD(nil)^, @dwTemp, sizeof(dwTemp), dwRequired)) then
    begin
      Result := Format('%u (0x%8.8X)', [dwTemp, dwTemp]);
      exit;
    end;
  end;
  // REG_SZ
  SPDRP_CLASS,
  SPDRP_CLASSGUID,
  SPDRP_DEVICEDESC,
  SPDRP_DRIVER,
  SPDRP_ENUMERATOR_NAME,
  SPDRP_FRIENDLYNAME,
  SPDRP_LOCATION_INFORMATION,
  SPDRP_MFG,
  SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
  SPDRP_SECURITY_SDS,
  SPDRP_SERVICE,
  SPDRP_UI_NUMBER_DESC_FORMAT:
  begin
    // We expect this call to fail
    if(not SetupDiGetDeviceRegistryProperty(hDevInfo, spdevid, dwProperty, PDWORD(nil)^, nil, 0, dwRequired)) then
    begin
      if(ERROR_INSUFFICIENT_BUFFER = GetLastError()) then
      begin
        SetLength(Result, (dwRequired + 1) div sizeof(Char));
        if(SetupDiGetDeviceRegistryProperty(hDevInfo, spdevid, dwProperty, PDWORD(nil)^, PByte(@Result[1]), dwRequired, dwRequired)) then
        begin
          // Result now contains the property string
          exit;
        end;
      end;
    end;
  end
  else
    Result := Format('<unsupported property %u>', [dwProperty]);
    exit;
  end;
  if(ERROR_INVALID_DATA = GetLastError()) then
    Result := ''
  else
    Result := Format('<Win32 error: %u>', [GetLastError()]);
end;

procedure GetDetailedData(hDevInfo : THandle ; dwIdx : DWORD; const spdevid : TSPDevInfoData);
var
  cmret : CONFIGRET;
  ulStatus, ulProblem : DWORD;
  str : String;
  i: Integer;
begin
  cmret := CM_Get_DevNode_Status(ulStatus, ulProblem, spdevid.DevInst, 0);
  // Something went wrong
  if(CR_SUCCESS <> cmret) then
  begin
    // Aaah, it's just that the device isn't plugged in (or otherwise present)
    if(CR_NO_SUCH_DEVNODE <> cmret) then // shut up about non-present devices
      WriteLn('CM_Get_DevNode_Status returned error: ', cmret);
    exit;
  end;
  if(DN_STARTED = (DN_STARTED and ulStatus)) then
  begin
    WriteLn(dwIdx, ' started:');
    for i := Low(props) to High(props) do
    begin
      str := GetDeviceRegProperty(hDevInfo, spdevid, props[i]);
      if(str <> '') then
        WriteLn(Format('%8.8X', [props[i]]), ': ', str);
    end;
  end
end;

procedure ListUsbDisks();
var
  hDevInfo : THandle;
  iErr : Integer;
  spdevid: TSPDevInfoData;
  dwIdx: DWORD;
begin
  hDevInfo := SetupDiGetClassDevs(@GUID_DEVINTERFACE_DISK, nil, 0, DIGCF_DEVICEINTERFACE);
  if(INVALID_HANDLE_VALUE <> hDevInfo) then
  try
    dwIdx := 0;
    iErr := ERROR_SUCCESS;
    repeat
      spdevid.cbSize := sizeof(spdevid);
      if(not SetupDiEnumDeviceInfo(hDevInfo, dwIdx, spdevid)) then
      begin
        iErr := GetLastError();
        if(ERROR_NO_MORE_ITEMS <> iErr) then
        begin
          WriteLn('Error from SetupDiEnumDeviceInterfaces: ', iErr);
          break;
        end;
      end;
      GetDetailedData(hDevInfo, dwIdx, spdevid);
      Inc(dwIdx);
    until (iErr = ERROR_NO_MORE_ITEMS);
  finally
    if(not SetupDiDestroyDeviceInfoList(hDevInfo)) then
      WriteLn('Could not destroy device list: ', GetLastError());
  end
  else
    WriteLn('Could not retrieve list for devices of GUID_DEVINTERFACE_DISK class: ', GetLastError());
end;

begin
  try
    ListUsbDisks();
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Download: https://assarbad.net/stuff/!export/usbkey.rar bzw. http://assarbad.net/stuff/!export/usbkey.rar (D2009-Projekt)

Ein paar Details fehlen noch, aber damit haste zumindest erstmal den Anfang.

NB: MSDN-Library durchsuchenSetupDiGetDriverInfoDetail oder MSDN-Library durchsuchenSetupDiGetDeviceProperty (nur Vista und höher) kannst du vermutlich dann zusätzlich anstrengen wenn es noch mehr Daten sein sollen.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat