Wie VID, PID und Seriennummer von USB-Stick auslesen?

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Wie VID, PID und Seriennummer von USB-Stick auslesen?

Beitrag von Kukulkan »

Hallo,

Ich möchte einen USB-Stick als Dongle verwenden. Dazu müsste ich zumindest die Hardware-Seriennummer auslesen. Ich weiss, dass Windows beim Formatieren eine solche Nummer anlegt. Aber diese meine ich nicht. Der Hersteller macht wohl sowas in den Stick.

Irgendwo hab ich gelesen, dass GetVolumeInformation_() nur die beim formatieren erzeugte Seriennummer ausliest. Diese kann natürlich auch gefälscht werden.

Hier hab ich noch was gefunden:
Q: Must a USB storage device contain a unique serial number?
Yes. To comply with the USB Mass Storage Class Bulk-Only Transport Specification, all USB storage devices must contain a unique (12 digits or longer) serial number, represented as a UNICODE string. Refer to section 4.1.1 of the USB Mass Storage Class (Bulk-Only Transport) specification and note that serial number characters must be 0x0030-0x0039 or 0x0041-0x0046.

A unique serial number on a USB device maintains the same device devnode as a user moves the device from USB port to port. This unique devnode ensures that properties (icons, policies, driver letters, and so on) associated with the device are not reset when the device is moved to a new port or when a second device with the same VID/PID/REV is added to the system.

IHVs must ensure that a device’s serial number is unique in order for that device to comply with Windows operating systems (refer to Microsoft Windows Logo Program System and Device Requirements B2.6.3.1) and to pass WHQL certification. (HCT version 10.0, and later HCTs, will test the uniqueness of a serial number on any USB device if one is specified.)


Weiss jemand wie ich an diese Seriennummer drankomme?

Grüsse,

Volker
Benutzeravatar
jpd
Beiträge: 380
Registriert: 14.02.2005 10:33

Beitrag von jpd »

Hallo Volker,

anbei ein link um ein usb drive zu entfehrnen:

http://www.purebasic.fr/english/viewtop ... mgetparent

es gibt ein bereich der ausgeremmt ist

Code: Alles auswählen


;              in case you are interested in the USB serial number: 
;              the device id string contains the serial number if the device has one, 
;              otherwise a generated id that contains the '&' char... 
;         Protected DevInstParent, DeviceIdString.s=Space(#MAX_PATH) 
;               CM_Get_Parent(@DevInstParent, spdd\DevInst, 0) 
;               CM_Get_Device_ID(DevInstParent, DeviceIdString, #MAX_PATH, 0) 
;          Debug "DeviceId= " + DeviceIdString 
vielleicht hilft dir das weiter!

Ciao
jpd
PB 5.10 Windows 7 x64
whitelion
Beiträge: 46
Registriert: 05.05.2008 18:16
Wohnort: Celle
Kontaktdaten:

Re: Wie VID, PID und Seriennummer von USB-Stick auslesen?

Beitrag von whitelion »

Volker Schmid hat geschrieben:Hallo,

Ich möchte einen USB-Stick als Dongle verwenden. Dazu müsste ich zumindest die Hardware-Seriennummer auslesen. Ich weiss, dass Windows beim Formatieren eine solche Nummer anlegt. Aber diese meine ich nicht. Der Hersteller macht wohl sowas in den Stick.

Irgendwo hab ich gelesen, dass GetVolumeInformation_() nur die beim formatieren erzeugte Seriennummer ausliest. Diese kann natürlich auch gefälscht werden.

Weiss jemand wie ich an diese Seriennummer drankomme?

Grüsse,

Volker
hi volker,

ich bin zwar selber ein PB noob und will hier nicht klugscheissen, aber falls du vorhast eine kopierschutzlösung über diese sache zu erstellen, würde ich dir davon abraten. bzw halte ich es in diesem fall für arbeit ohne besseren schutz.
...das leben ist wie ein schlechtes adventure-game, aber die grafik ist verdammt geil!
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Beitrag von Kukulkan »

@whitelion

Hallo,
aber falls du vorhast eine kopierschutzlösung über diese sache zu erstellen, würde ich dir davon abraten. bzw halte ich es in diesem fall für arbeit ohne besseren schutz.
Nein, darum geht es nicht. Ich möchte ein paar Informationen, die einen Benutzer identifizieren, auf dem USB-Stick ablegen. Sozusagen ein Key. Damit dieser nicht einfach dupliziert werden kann, möchte ich den Inhalt mit dem Hashcode der Stick-Seriennummer verschlüsseln (AES256). So wird der Key auf dem USB Stick ungültig, wenn er nicht auf dem Original-USB-Stick liegt. Das soll nicht vor dem Hacken der Anwendung schützen, sondern vor dem unbemerkten Diebstahl der Daten auf dem USB-Stick.

Leider haben manche Hersteller von USB-Sticks wohl immer die selbe Nummer auf allen Modellen, aber man muss erstmal einen gleichen Stick finden. Vor allem, weil meistens alte Sticks dafür recycled werden...

Ich komme mit dem Beispiel von jpd nicht voran, denn es scheint eine spezielle DLL (setupapi.dll) zu verwenden. Ich bin unsicher, ob diese einen bestimmten MSI Stand auf dem Rechner benötigt oder sowas. Das darf leider nicht sein.

Grüsse,

Volker

Grüsse,

Volker
Benutzeravatar
jpd
Beiträge: 380
Registriert: 14.02.2005 10:33

Beitrag von jpd »

Hallo Volker,


die verwendete funktionen sind ab win => 2000 zur verfügung!

Ciao
jpd
PB 5.10 Windows 7 x64
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Beitrag von Kukulkan »

Hallo jpd,

Ich hab deinen Link weiter verfolgt und das mal getestet. Als Serial kommt bei mir bei allen USB-Sticks immer nur "P" raus. Das kann nicht sein. Ich habe hier einen sehr guten Link gefunden:

http://home.hot.rr.com/graye/Articles/U ... umbers.htm

Aber dort geht der Autor ab einem bestimmten Punkt einen anderen Weg, indem er den HUB(!) identifiziert und dann alle Devices am Hub durchgeht und irgendwas mit GetDeviceDescriptor() macht. Ich bin in API einfach nicht fit genug um das aus diesem Beispiel nach PB umzusetzen. :-(

Sonst noch eine Idee?

Grüsse,

Volker
Benutzeravatar
jpd
Beiträge: 380
Registriert: 14.02.2005 10:33

Beitrag von jpd »

Hallo Volker,

habe mir den vbnet beispiel angeguckt und die ergebnisse,

sind gleich.

also ist der pb beispiel in ordnug.
ist bei dir unicode aktiv?

der author schreibt :


; in case you are interested in the USB serial number:
; the device id string contains the serial number if the device has one,
; otherwise a generated id that contains the '&' char...


vielleicht hat dein stick keine serialnumber?

ich kann dir per pn die kompilierte vb.net beispiel zuschicken so dass du testen/vergleichen kannst!


Ciao
jpd
PB 5.10 Windows 7 x64
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

Re: Wie VID, PID und Seriennummer von USB-Stick auslesen?

Beitrag von scholly »

Interessant dieses Thema ist für meinereiner auch :)
Darf ich fragen, woher Dein Quote im ersten Posting kommt?
Volker Schmid hat geschrieben:Weiss jemand wie ich an diese Seriennummer drankomme?
Hilft Dir das hier vielleicht weiter?
typedef struct _USB_DEVICE_DESCRIPTOR {
UCHAR bLength ;
UCHAR bDescriptorType ;
USHORT bcdUSB ;
UCHAR bDeviceClass ;
UCHAR bDeviceSubClass ;
UCHAR bDeviceProtocol ;
UCHAR bMaxPacketSize0 ;
USHORT idVendor ;
USHORT idProduct ;
USHORT bcdDevice ;
UCHAR iManufacturer ;
UCHAR iProduct ;
UCHAR iSerialNumber
UCHAR bNumConfigurations ;
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR ;
Versuch doch mal, das WMI-Script (Method 1) über das WMI-Include für PB auszuführen.

Achja, wenn ich mit "Scriptomatic" die Win32_DiskDrive - Klasse teste, erhalte ich für meinen Stick folgende Ausgabe:
Availability:
BytesPerSector: 512
Capabilities: 3,4,7
CapabilityDescriptions:
Caption: TOSHIBA TransMemory USB Device
CompressionMethod:
ConfigManagerErrorCode: 0
ConfigManagerUserConfig: Falsch
CreationClassName: Win32_DiskDrive
DefaultBlockSize:
Description: Laufwerk
DeviceID: \\.\PHYSICALDRIVE2
ErrorCleared:
ErrorDescription:
ErrorMethodology:
Index: 2

InterfaceType: USB
LastErrorCode:
Manufacturer: (Standardlaufwerke)
MaxBlockSize:
MaxMediaSize:
MediaLoaded: Wahr
MediaType: Removable media other than floppy
MinBlockSize:
Model: TOSHIBA TransMemory USB Device
Name: \\.\PHYSICALDRIVE2
NeedsCleaning:
NumberOfMediaSupported:
Partitions: 1
PNPDeviceID: USBSTOR\DISK&VEN_TOSHIBA&PROD_TRANSMEMORY&REV_6.50\0B310B6010004954&0
PowerManagementCapabilities:
PowerManagementSupported:
SCSIBus:
SCSILogicalUnit:
SCSIPort:
SCSITargetId:
SectorsPerTrack: 63
Signature: 0
Size: 995258880
Status: OK
StatusInfo:
SystemCreationClassName: Win32_ComputerSystem
SystemName: SEMPRON
TotalCylinders: 121
TotalHeads: 255
TotalSectors: 1943865
TotalTracks: 30855
TracksPerCylinder: 255
sorry, hab heute nich viel Zeit.
Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Beitrag von Kukulkan »

Hallo,

Die Ausgabe für PNPDeviceID schaut aus wie die Information aus der Registry. In diesem Pfad:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\Enum

Finde ich zB für meinen Stick die Angabe:
USB\Vid_090c&Pid_1000\AA04012700027146

Ich denke mal, die letzte Angabe nach dem Backslash ist die Seriennummer, oder? Die Frage ist jetzt nur, wie ich diese Angaben wieder dem Laufwerksbuchstaben zuordnen kann? Mit dem muss ich am Ende ja arbeiten. Das wäre so natürlich die aller einfachste Methode.

Volker
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Beitrag von Kukulkan »

Hallo,

Ich versuche es jetzt mit DeviceIoControl().

Hier der aktuelle Stand (PB 4.20 und WinXP SP2):

Code: Alles auswählen

; Get SerialNumber from drive

#IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER = 2952208 ; $2D0C10

Structure MEDIA_SERIAL_NUMBER_DATA
  SerialNumberLength.l
  Result.l
  Reserved1.l
  Reserved2.l
  Serial.s{2048}
EndStructure

Procedure.s GetDriveSerial(DriveLetter.s)
  Protected DevicePath.s
  Protected VolumeAccessPath.s
  Protected BytesReturned.l
  Protected drive.s
  Protected hVolume.l
  Protected res.l
  Protected media.MEDIA_SERIAL_NUMBER_DATA
  
  BytesReturned.l = 0
  
  drive.s = Left(UCase(DriveLetter.s), 1) 
  If drive.s < "A" Or drive.s > "Z" : ProcedureReturn "?" : EndIf 

  DevicePath.s = drive.s + ":"                ; "X:"      -> for QueryDosDevice 
  RootPath.s = DevicePath.s + "\"             ; "X:\"     -> for GetDriveType 
  VolumeAccessPath.s = "\\.\" + DevicePath.s  ; "\\.\X:"  -> to open the volume 
  
  ; open the storage volume 
  hVolume.l = CreateFile_(VolumeAccessPath.s, 0, #FILE_SHARE_READ|#FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0) 
  Debug "hVolume: " + Str(hVolume.l)
  If hVolume.l <> #INVALID_HANDLE_VALUE 
     ; get the volume's device number 
     res.l = DeviceIoControl_(hVolume.l, #IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, 0, 0, @media, SizeOf(MEDIA_SERIAL_NUMBER_DATA), @BytesReturned.l, 0) 
     Debug "res.l: " + Str(res.l)
     Debug "bytesreturned.l: " + Str(BytesReturned.l)
     Debug "media SizeOf: " + Str(SizeOf(MEDIA_SERIAL_NUMBER_DATA))
     Debug "Status: " + Str(media\Result)
     If res.l 
        Serial.s = media\Serial
     Else
        ProcedureReturn "? - can not get a result"
     EndIf
     CloseHandle_(hVolume.l)
  Else
    ProcedureReturn "? - invalid drive handle"
  EndIf
  
  ProcedureReturn Serial.s
EndProcedure

Debug GetDriveSerial("g")
G:\ ist mein USB Stick. Leider kommt absolut nix als Ergebnis. DeviceIoControl liefert immer 0 als Ergebnis und die Struktur bleibt leer. Woran liegts?

@scholly:
Das Zitat stammt irgendwo von hier:
http://www.microsoft.com/whdc/device/st ... fault.mspx

Volker
Antworten