AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi wie Hardware (HID) erkennen und via Programm verbinden/trennen?
Thema durchsuchen
Ansicht
Themen-Optionen

wie Hardware (HID) erkennen und via Programm verbinden/trennen?

Ein Thema von himitsu · begonnen am 12. Okt 2010 · letzter Beitrag vom 23. Nov 2010
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.343 Beiträge
 
Delphi 12 Athens
 
#1

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 08:32
Das IOCTL_STORAGE_LOAD_MEDIA, IOCTL_HID_ACTIVATE_DEVICE und IOCTL_HID_DEACTIVATE_DEVICE klingt schonmal gut.
Werd' ich dann mal ausprobieren.
Nja, wenn ich Pech hab, dann sind die für eine Nutzung in 'nem HID Minidriver, welchen ich nicht hab/nutze.

Das dort entdeckte IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER klingt och nett.

OK, danke erstmal und bis nach den Tests.






Zum Suchen hatte ich mir gestern auch dieses hier zusammengebastelt.
Delphi-Quellcode:
Uses JwaBluetoothAPIs;

Var
  RH: HBLUETOOTH_RADIO_FIND;
  RP: BLUETOOTH_FIND_RADIO_PARAMS;
  R: THandle;
  RI: BLUETOOTH_RADIO_INFO;
  DH: HBLUETOOTH_DEVICE_FIND;
  DP: BLUETOOTH_DEVICE_SEARCH_PARAMS;
  DI: BLUETOOTH_DEVICE_INFO;

RP.dwSize := SizeOf(RP);
RH := BluetoothFindFirstRadio(@RP, R);
If RH <> 0 Then Begin
  Repeat
    RI.dwSize := SizeOf(RI);
    If BluetoothGetRadioInfo(R, RI) = ERROR_SUCCESS Then Begin
      ShowMessage(Format('address (%02x:%02x:%02x:%02x:%02x:%02x)'#10 +
        'name "%s"'#10'class %d'#10'subversion %d'#10'manufacturer %d', [
        RI.address.rgBytes[0], RI.address.rgBytes[1], RI.address.rgBytes[2],
        RI.address.rgBytes[3], RI.address.rgBytes[4], RI.address.rgBytes[5],
        RI.szName, RI.ulClassofDevice, RI.lmpSubversion, RI.manufacturer]));
    End Else ShowMessage(SysErrorMessage(GetLastError));

    ZeroMemory(@DP, SizeOf(DP));
    DP.dwSize := SizeOf(DP);
    {DP.fReturnAuthenticated := True;{}
    {DP.fReturnRemembered := True;{}
    {DP.fReturnUnknown := True;{}
    {}DP.fReturnConnected := True;{}
    {DP.fIssueInquiry := True;{}
    DP.hRadio := R;
    DI.dwSize := SizeOf(DI);
    DH := BluetoothFindFirstDevice(DP, DI);
    If DH <> 0 Then Begin
      Repeat
        ShowMessage(Format('address (%02x:%02x:%02x:%02x:%02x:%02x)'#10'class %d'#10 +
          'connected %d'#10'remembered %d'#10'authenticated %d'#10'name "%s"', [
          DI.Address.rgBytes[0], DI.Address.rgBytes[1], DI.Address.rgBytes[2],
          DI.Address.rgBytes[3], DI.Address.rgBytes[4], DI.Address.rgBytes[5],
          DI.ulClassofDevice, Ord(DI.fConnected), Ord(DI.fRemembered),
          Ord(DI.fAuthenticated), DI.szName]));
      Until not BluetoothFindNextDevice(DH, DI);
      BluetoothFindDeviceClose(DH);
    End Else If GetLastError <> ERROR_NO_MORE_ITEMS Then ShowMessage(SysErrorMessage(GetLastError));

    CloseHandle(R);
  Until not BluetoothFindNextRadio(RH, R);
  BluetoothFindRadioClose(RH);
End Else If GetLastError <> ERROR_NO_MORE_ITEMS Then ShowMessage(SysErrorMessage(GetLastError));

ZeroMemory(@DP, SizeOf(DP));
DP.dwSize := SizeOf(DP);
{DP.fReturnAuthenticated := True;{}
{DP.fReturnRemembered := True;{}
{DP.fReturnUnknown := True;{}
{}DP.fReturnConnected := True;{}
{DP.fIssueInquiry := True;{}
//DP.hRadio := 0;
DI.dwSize := SizeOf(DI);
DH := BluetoothFindFirstDevice(DP, DI);
If DH <> 0 Then Begin
  Repeat
    ShowMessage(Format('address (%02x:%02x:%02x:%02x:%02x:%02x)'#10'class %d'#10 +
      'connected %d'#10'remembered %d'#10'authenticated %d'#10'name "%s"', [
      DI.Address.rgBytes[0], DI.Address.rgBytes[1], DI.Address.rgBytes[2],
      DI.Address.rgBytes[3], DI.Address.rgBytes[4], DI.Address.rgBytes[5],
      DI.ulClassofDevice, Ord(DI.fConnected), Ord(DI.fRemembered),
      Ord(DI.fAuthenticated), DI.szName]));
    //if BluetoothRemoveDevice(DI.Address) <> ERROR_SUCCESS then
    // ShowMessage(SysErrorMessage(GetLastError));
  Until Not BluetoothFindNextDevice(DH, DI);
  BluetoothFindDeviceClose(DH);
End Else If GetLastError <> ERROR_NO_MORE_ITEMS Then ShowMessage(SysErrorMessage(GetLastError));
Leider findet das garnichs oder nicht alles.
Jedenfalls schein ich es nicht hinzibekommen das BLUETOOTH_DEVICE_SEARCH_PARAMS (DP) so zu setzen, daß alles gefunden wird.

Weiteres, wie Nachfolgendes, hab ich noch nicht ausprobieren (können).
BluetoothRemoveDevice
BluetoothAuthenticateDevice
BluetoothSetServiceState
BluetoothEnumerateInstalledServices
BluetoothIsConnectable
BluetoothEnableIncomingConnections
BluetoothRegisterForAuthentication
BluetoothUnregisterAuthentication
BluetoothSendAuthenticationResponse


Mein Problem ist auch noch, daß ich es einmal hinbekommen hatte, mein Device zwar aufzulisten, aber eine "Verbindung" zum zugehörigen HID-Control war nicht möglich.
Im Prinzip könnte ich in meiner HID-Komponente noch sowas wie das "address (%02x:%02x:%02x:%02x:%02x:%02x)" benötigen,
denn wenn ich z.B. zwei gleiche Controls angeschlossen hab, dann weiß ich nicht direkt, welches meiner HID-Objekte welchem Control in der Bluetooth-Verwaltung entspricht.



[add]
Wenn ich BluetoothGetRadioInfo direkt auf ein FileHandle zu einem HID-Device loslaß, dann meint es zwar "alles OK" (ERROR_SUCCESS), aber der ganze Record ist nur mit Nullen gefüllt.
Und BluetoothGetDeviceInfo meint dann nur ERROR_NOT_FOUND.
(wär ja auch zu einfach gewesen)



[add]
Hab es nun ganz einfach erstmal mit dem Auswerfen versucht.
Bei IOCTL_HID_DEACTIVATE_DEVICE auf das DeviceHandle "\\?\hid#vid_057e&pid...0030}" angewendet sagt mir DeviceIoControl was von OK/True, aber nichts passiert.
Ich weiß allerdings nicht wie ich was genau als In-Parameter an DeviceIoControl übergeben soll, aber egal was, es bleibt beim True und es hat dennoch keinerlei Auswirkungen (Control bleibt angemeldet und nutzbar).

Wenn das Trennen/Deaktivieren eines verbundenen Gerätes schon nicht funktioniert, dann erspar ich mir die Versuche mit IOCTL_HID_ACTIVATE_DEVICE erstmal.

Auch bei IOCTL_STORAGE_LOAD_MEDIA wird True geliefert und ebenfalls nichts passiert.
(hier natürlich andersrum, also das Gerät befindet sich, laut der Bluetooth-Steuerung, im "Leerlauf" und war/ist noch nicht verbunden)
Wobei ich bei IOCTL_STORAGE_LOAD_MEDIA nicht viel falsch machen kann, da alle Parameter eh nil sind.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (13. Nov 2010 um 10:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

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

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 14:27
Hab es nun ganz einfach erstmal mit dem Auswerfen versucht.
Bei IOCTL_HID_DEACTIVATE_DEVICE auf das DeviceHandle "\\?\hid#vid_057e&pid...0030}" angewendet sagt mir DeviceIoControl was von OK/True, aber nichts passiert.
Ich weiß allerdings nicht wie ich was genau als In-Parameter an DeviceIoControl übergeben soll, aber egal was, es bleibt beim True und es hat dennoch keinerlei Auswirkungen (Control bleibt angemeldet und nutzbar).
Du öffnest aber das Gerät schon mit CreateFile?! ...

Du bist aber auch sicher, daß du bspw. erfolgreich ein Handle bekommst? Wenn ja, dann versuch mal bitte MSDN-Library durchsuchenZwDeviceIoControlFile (ntdll.dll, die Zw* und Nt* ist vom Usermode aus identisch) um den IOCTL zu senden. Da interessiert uns dann was der Treiber in IoStatusBlock einträgt. Speziell der Statuscode da drin wird uns interessieren. Die Win32-Funktion MSDN-Library durchsuchenDeviceIoControl ist etwas ... nunja ... da genau diese Fehlerinfo verlorengeht. Meines Wissens nach ist der Rückgabewert von ZwDeviceIoControlFile normalerweise identisch mit dem in IoStatusBlock, aber es mag auch Unterschiede geben. Einerlei, DeviceIoControl verschluckt alle diese Informationen.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.343 Beiträge
 
Delphi 12 Athens
 
#3

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 14:58
Delphi-Quellcode:
H := CreateFile(PChar(DeviceInfos.DeviceInterface.DevicePath),
  GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,
  nil, OPEN_EXISTING, 0, 0);
Und ja, das Handle ist gültig, jedenfalls kann ich es für die anderen HID-Funktionen problemlos nutzen.

Ansonsten gibt es im Netz leider nicht all zuviele Informationen zu IOCTL_HID_DEACTIVATE_DEVICE
und wenn doch, dann wird da fast immer über eine HID minidriver implementation geschrieben.
Tja, einen solchen Mini-Treiber habe ich nicht, bzw. ich wollte sowas nicht unbedingt selber schreiben.




BluetoothGetRadioInfo liefert mir nun wenigstens schonmal den BT-Master/Sender
und über BluetoothFindFirstDevice bekomm ich endlich mein BT-Gerät aufgelistet.

Nur gibt es da sowenige Informationen über dieses Gerät, daß ich keine Verbindung zu einem meiner HID-Geräte herstellen kann, geschweige denn diese zu Steuern (/verbinden/trennen/entfernen).




http://www.delphipraxis.net/155160-w...ml#post1061174
Da unten drann hab ich mal eine Version angehängt, welche aktuell funktionierende Aufrufe enthält.

Im #Log werden z.B. die erkannten BT-Geräte und die wenigen schon bekannten Daten aufgelistet.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

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

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 15:03
Okay, bleib mal locker. Alle diese Funktionen sind üblicherweise Frontends zu den IOCTLs.

Haste mal mit ZwDeviceIoControlFile probiert? Wenn ja, was sind die Ergebnisse im IoStatusBlock?!
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.343 Beiträge
 
Delphi 12 Athens
 
#5

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 15:31
So, hab's versucht.

Zitat:
Im Projekt HIDTest.exe ist eine Exception der Klasse EJwaLoadLibraryError mit der Meldung 'Library not found: ntdll.dll' aufgetreten.
OK, die JwaWinType ist nicht wirklich Unicode-fähig.

Und nun wo das Unicode angepaßt wurde, heißt es Result (NTSTATUS) = 0, IoStatusBlock bleibt leer und GetLastError meint
Zitat:
Im Projekt HIDTest.exe ist eine Exception der Klasse EOSError mit der Meldung 'Ein Aufruf einer Betriebssystemfunktion ist fehlgeschlagen' aufgetreten.

Delphi-Quellcode:
W := ZwDeviceIoControlFile(H, 0, nil, nil, @IOSB, IOCTL_HID_DEACTIVATE_DEVICE,
  nil, 0, nil, 0);

// oder

W := ZwDeviceIoControlFile(H, 0, nil, nil, @IOSB, IOCTL_HID_DEACTIVATE_DEVICE,
  @X, SizeOf(X), nil, 0);
Wobei ich halb immernoch nicht weiß, was man als X genau angeben muß.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#6

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 15:41
Was hat das mit Unicode zu tun und warum gerade JwaWinType?

Du hast kaum Ahnung, wie man die API benutzt und meinst aber, dass die Übersetzung schuld sei?
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.343 Beiträge
 
Delphi 12 Athens
 
#7

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 15:50
Weil ich grade diese Units hier rumliegen hatte?
Nja, als ich Letztens nach einigen APIs gesucht hatte, war ich darüber gestolpert und hatte es runtergeladen.

Das ZwDeviceIoControlFile wird vom JWA dynamisch geladen, was allerdings nicht klappte.
Delphi-Quellcode:
// unit Windows
type
  LPWSTR = PWideChar;

// unit JwaWinType
type
  LPTSTR = {$IFDEF USE_DELPHI_TYPES} Windows.LPWSTR {$ELSE} LPWSTR {$ENDIF};
  LPCTSTR = LPTSTR;
function GetModuleHandle(lpModuleName: LPCTSTR): HMODULE; stdcall;
function LoadLibrary(lpLibFileName: LPCTSTR): HMODULE; stdcall;

function GetModuleHandle; external kernel32 name 'GetModuleHandleA';
function LoadLibrary; external kernel32 name 'LoadLibraryA';
Also Unicode ... nja, es ist als PWideChar deklariert, aber es wurden die Ansi-APIs aufgerufen.
Nach W geändert und schon wurde die DLL und die Prozedur gefunden.


Eigentlich hab ich meine paar APIs selber deklariert,
aber da die Delphi-Suche (Strg+Shift+F) vorhin meinte, diese API sei darin vorhanden, hab ich es zu Testen halt einfach mal daraus aufgerufen.
Sonst nutzte ich dieses JWA eigentlich nicht direkt.



[add]
'ne Deklaration des Type3InputBuffer hatte ich eh noch nicht gefunden.
Aber ich sagte ja ... wenn ich Pech hab, dann haben diese APIs eh nur was mit diesen Miniport-Treibern zu tun.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (13. Nov 2010 um 15:57 Uhr)
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#8

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 15:54
Weil ich grade diese Units hier rumliegen hatte?
Nja, als ich Letztens nach einigen APIs gesucht hatte, war ich darüber gestolpert und hatte es runtergeladen.
Ah ok, mir dämmerts. Wo hast du die her?
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

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

AW: wie Hardware (HID) erkennen und via Programm verbinden/trennen?

  Alt 13. Nov 2010, 15:44
Ups, tut mir leid. Habe dich ohnehin auf die falsche Fährte geführt. MSDN-Library durchsuchenIOCTL_HID_DEACTIVATE_DEVICE erfordert Type3InputBuffer und dieser ist nur vom Kernelmode aus zugreifbar (zumindest Type3InputBuffer). Ohne extra Treiber kann man das also ohnehin nicht realisieren - zumindest nicht mit diesem IOCTL.

Sorry
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)

Geändert von Assarbad (13. Nov 2010 um 15:54 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz