AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi EnumDeviceDrivers EA bei ListView
Thema durchsuchen
Ansicht
Themen-Optionen

EnumDeviceDrivers EA bei ListView

Ein Thema von _BlackDragon_ · begonnen am 2. Apr 2009 · letzter Beitrag vom 2. Aug 2014
Antwort Antwort
_BlackDragon_

Registriert seit: 4. Dez 2007
Ort: Eschweiler
64 Beiträge
 
#1

EnumDeviceDrivers EA bei ListView

  Alt 2. Apr 2009, 22:30
Hallo Leute,

ich muss mal wieder nerven.

Bin mir jetzt nicht ganz sicher ob das nun unter WinApi oder unter VCL hingehört, da ja iregendwie beides
betroffen ist.

Versuche gerade die Geräte Treiber aufzulisten. Allerdings bekomme ich immer eine EA mit Zugriffsverletzung.
Hier erstmal der betroffene Code:

Delphi-Quellcode:

type
TImageBase = Array of Pointer;

TForm3 = class(TForm)
//...
private
  lpImageBase: TImageBase;
  CountDrivers: Integer;
//...
end;

// hier werden die Pointer der Treiber ermittelt
procedure TForm3.Button1Click(Sender: TObject);
var
  lpcbNeeded: Cardinal;
  success: Boolean;
begin
  success := EnumDeviceDrivers(0, 0, lpcbNeeded); // einmal aufrufen um die benötigte Größe zu ermitteln
  if success then
  begin
    CountDrivers := (lpcbNeeded div SizeOf(Pointer)); // Anzahl Treiber
    SetLength(lpImageBase, CountDrivers);
    success := EnumDeviceDrivers(Pointer(@lpImageBase[0]), lpcbNeeded, lpcbNeeded);
    if success then
    begin
      AddDeviceDrivers;
    end;
  end;

  if not success then
    MessageDlg('Could not enum drivers', mtError, [mbOK], MB_OK);

end;

// Hier die Treiber dem ListView hinzufügen
procedure TForm3.AddDeviceDrivers;
var
  item: TListItem;
  iIndex: Integer;
  name: String;
begin
  for iIndex := 0 to CountDrivers - 1 do
  begin
    item := lvDrivers.Items.Add; // diese und die nächste Zeile machen nie Probleme
    item.Caption := Format('0x%s (%s)', [IntToHex(Cardinal(lpImageBase[iIndex]), 8), IntToStr(Cardinal(lpImageBase[iIndex]))]);

    name := GetDriverBaseName(lpImageBase[iIndex]);
    item.SubItems.Add(name); // hier kracht es bei jedem Durchlauf
// Memo1.Lines.Add(name); // nur zum testen, hier kracht es nachdem alles durchgelaufen ist
  end;
end;

// hier den Namen eines Treibers anhand des Pointers ermitteln
function TForm3.GetDriverBaseName(pImageBase: Pointer): String;
var
  lpBaseName: PChar;
  size: Cardinal;
begin
  size := GetDeviceDriverBaseName(pImageBase, lpBaseName, MAX_PATH);
  Result := StrPas(lpBaseName);
end;
Also es stehen grundsätzlich bei jedem Durchgang die richtigen Namen der Treiberdateien zur Verfügung. Hab den ganzen Bulk mehrfach debugt.

Füge ich die Namen dem ListView hinzu, kracht es bei jedem Durchgang mit einer EA. Bei dem Memo wird fleißig hinzugefügt und
beim Verlassen der "ButtonClick"-Routine kracht es ebenfalls mit einer EA.

Hoffe ich hab nix vergessen. Aber ich sehe absolut nicht wo der Fehler herkommt, wie gesagt alle Routinen ermitteln korrekte Werte und geben auch keine Fehlschlags-Meldungen zurück. Der AufrufStack ist nicht hilfreich gewesen, ebenso wenig wie das
CPU-Fenster.

Vielleicht kann das ja mal einer Testen.


Gruß

BlackDragon

PS: Ja ich weiß, ist alles nicht besonders sauber, ist aber eben nur ein Test.
  Mit Zitat antworten Zitat
quendolineDD

Registriert seit: 19. Apr 2007
Ort: Dresden
781 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: EnumDeviceDrivers EA bei ListView

  Alt 2. Apr 2009, 23:36
Also die AV tritt nicht an deiner gekennzeichneten Stelle auf, sondern erst dann, wenn die for-Schleife verlassen wird.
Vielleicht solltest du dir auch mal dieses Beispiel in der MSDN dazu anschauen. Ist viel kürzer finde ich und funktioniert auch 100%-ig
Lars S.
Wer nicht mit der Zeit geht, geht mit der Zeit.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: EnumDeviceDrivers EA bei ListView

  Alt 3. Apr 2009, 00:17
Zitat von _BlackDragon_:
Delphi-Quellcode:
// hier den Namen eines Treibers anhand des Pointers ermitteln
function TForm3.GetDriverBaseName(pImageBase: Pointer): String;
var
  lpBaseName: PChar;
  size: Cardinal;
begin
  size := GetDeviceDriverBaseName(pImageBase, lpBaseName, MAX_PATH);
  Result := StrPas(lpBaseName);
end;
Wie soll das so auch klappen? Du übergibst als Zieladresse für lpBaseName einen uninitialisierten Pointer. Das ist aber ein out Parameter, wie du auch in der Dokumentation siehst:
http://msdn.microsoft.com/en-us/library/ms683184.aspx
Du musst also zuerst einmal so viel Speicher reservieren wie du als Größe dieses Buffers als dritten Parameter übergibst.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
_BlackDragon_

Registriert seit: 4. Dez 2007
Ort: Eschweiler
64 Beiträge
 
#4

Re: EnumDeviceDrivers EA bei ListView

  Alt 3. Apr 2009, 00:33
Hi.

@quendolineDD:

Erst mal Danke für deine Antwort.

Das Beispiel auf MSDN macht prinzipiell das selbe, kürzer isses auch.

@jaenicke:

Oh Mann, du hast vollkommen Recht.
Hab mir die ganze Zeit den Speicherbereich "zerhauen". Hab mich da wohl von der Delphi-Deklaration
verleiten lassen und nicht drauf geachtet ob die Routine den Speicher selbst reserviert.
Und dann auch noch an der falschen Stelle gesucht.

Vielen Dank.

Habs jetzt so:

Delphi-Quellcode:
function TForm3.GetDriverBaseName(pImageBase: Pointer): String;
var
  lpBaseName: PChar;
  size: Cardinal;
begin
  Result := '';
  GetMem(lpBaseName, 255);
  try
    size := GetDeviceDriverBaseName(pImageBase, lpBaseName, 255);
    Result := StrPas(lpBaseName);
  finally
    FreeMem(lpBaseName);
  end;
end;
Das funktioniert prima.


Noch mal vielen Dank an euch beide...

Gruß

BlackDragon
  Mit Zitat antworten Zitat
nghwaya

Registriert seit: 31. Okt 2007
1 Beiträge
 
#5

AW: EnumDeviceDrivers EA bei ListView

  Alt 2. Aug 2014, 06:21
Hallo!

Ein PPointer hat keine Speicherreservierung - deshalb die Zugriffsverletzung. Einfach ein Array von DWORD vereinbaren. Ich bevorzuge einen festen Array. Einen dynamischen kann man aber auch probieren und es muss prinzipiell auch gehen. Vielspass und es geht so:

//----
uses PsApi;
//----

function EnumerateDeviceDrivers(aList:TStringList):boolean;
var drivers:array [0..4096]of DWORD;
//Bid enough or a dynamic array
szDriver:array[0..max_path]of char;
lpcbNeededWORD;
i,cbDrivers:integer;
begin

Result:=EnumDeviceDrivers(NIL,0,lpcbNeeded);
if(Result)and(lpcbNeeded < sizeof(drivers))then begin

EnumDeviceDrivers(@drivers, sizeof(drivers), lpcbNeeded);

cbDrivers:=lpcbNeeded div sizeof(DWORD);

for i:=0 to cbDrivers-1 do begin

if(GetDeviceDriverBaseName(Pointer(drivers[i]), szDriver, sizeof(szDriver))>0)then begin

aList.Add(szDriver);
end;//end if

end;//end for i


end;//end if

//----

procedure TForm1.Button1Click(Sender: TObject);
var aList:TStringList;
begin

aList:=TStringList.Create;

CheckBox1.Checked:=
EnumerateDeviceDrivers(aList);
Memo1.Text:=aList.Text;

aList.Free;

end;

//----
  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 08:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz