![]() |
EnumDeviceDrivers EA bei ListView
Hallo Leute,
ich muss mal wieder nerven. :-D 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:
Also es stehen grundsätzlich bei jedem Durchgang die richtigen Namen der Treiberdateien zur Verfügung. Hab den ganzen Bulk mehrfach debugt.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; 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, :wall: 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. :coder2: Gruß BlackDragon PS: Ja ich weiß, ist alles nicht besonders sauber, ist aber eben nur ein Test. |
Re: EnumDeviceDrivers EA bei ListView
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 ![]() |
Re: EnumDeviceDrivers EA bei ListView
Zitat:
![]() Du musst also zuerst einmal so viel Speicher reservieren wie du als Größe dieses Buffers als dritten Parameter übergibst. |
Re: EnumDeviceDrivers EA bei ListView
Hi.
@quendolineDD: Erst mal Danke für deine Antwort. Das Beispiel auf MSDN macht prinzipiell das selbe, kürzer isses auch. :-D @jaenicke: Oh Mann, du hast vollkommen Recht. :shock: 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. :oops: Und dann auch noch an der falschen Stelle gesucht. Vielen Dank. :dp: Habs jetzt so:
Delphi-Quellcode:
Das funktioniert prima. :thumb:
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; Noch mal vielen Dank an euch beide... Gruß BlackDragon |
AW: EnumDeviceDrivers EA bei ListView
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; lpcbNeeded:DWORD; 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; //---- |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:01 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