AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage)

EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage)

Ein Thema von Andreas2k · begonnen am 3. Mär 2017 · letzter Beitrag vom 14. Mär 2017
Antwort Antwort
Seite 3 von 3     123
Benutzerbild von himitsu
himitsu

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

AW: EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage)

  Alt 13. Mär 2017, 17:01
Es muß nur mindestens so viel Speicher bereitgestellt werden, wie nötig.
Also wäre es kein Problem den Speicher auf ganze Recordgrößen aufzurunden.

Und nein, denn
* erstmal wäre der dritte Aufruf garnicht nötig, da man im Zweiten bereits beide Größen erfährt
** einfach ein SetLength zum Kürzen nach dem 2. Aufruf (was man aber nicht machen darf)
* außerdem würde man dann den Speicher mit den Strings freigeben, womit die PChars in den Records ins Nirvana zeigen täten
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Andreas2k

Registriert seit: 2. Jan 2003
108 Beiträge
 
Delphi XE5 Professional
 
#22

AW: EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage)

  Alt 14. Mär 2017, 11:45
Man kann ja dennoch das Array verwenden, aber dann eben nicht auf alle, sondern nur auf die richige Anzahl der Einträge zugreifen.
0 bis daswasdieapisagt-1

BOOL EnumPrinterDrivers(
_In_ LPTSTR pName,
_In_ LPTSTR pEnvironment,
_In_ DWORD Level,
_Out_ LPBYTE pDriverInfo,
_In_ DWORD cbBuf,
_Out_ LPDWORD pcbNeeded,
_Out_ LPDWORD pcReturned
);
Aber das Problem ist ja, dass pcbNeeded in Bytes angegeben ist und ausdrücklich nicht pcReturned * SizeOf(DRIVER_INFO_2) ist. Nichtmal ein Vielfaches von SizeOf(DRIVER_INFO_2) ist garantiert. Mit einem Array of DRIVER_INFO_2 zu arbeiten, macht doch rein von der Logik her einfach keinen Sinn.

Kann man das so machen oder ist das zu gefährlich / dümmlich ?
Macht wenig Sinn. Der 3. Aufruf der API wird fehlschlagen (bzw. noch schlimmer: zufälligen Speicher überschreiben), da dein Array nach wie vor die falsche Größe hat. Siehe oben: pcbNeeded ist kein Vielfaches von SizeOf(DRIVER_INFO_2) . Der Array Ansatz kann nicht funktionieren - du hast enweder zu wenig Platz = Buffer Overflow oder du reservierst zu viel = Logisch fragwürdig. Arrays sollte man wirklich nur dann verwenden, wenn man homogene Strukturen zusammenfassen will.

Delphi-Quellcode:
function EnumPrinterDriversW(pName: LPSTR; pEnvironment: LPSTR; Level: DWord; pDriverInfo: LPBYTE;
  cbBuf: DWord; var pcbNeeded: DWord; var cbReturned: DWord): BOOL; stdcall;
  external 'winspool.drv';

type
  DRIVER_INFO_2 = packed record
    cVersion: DWord;
    pName: LPTSTR;
    pEnvironment: LPTSTR;
    pDriverPath: LPTSTR;
    pDataFile: LPTSTR;
    pConfigFile: LPTSTR;
  end;
  PDriverInfo2 = ^TDriverInfo2;
  TDriverInfo2 = DRIVER_INFO_2;

procedure TForm6.FormCreate(Sender: TObject);
var
  Buf: Pointer;
  ErrorCode,
  pcbNeeded,
  cbReturned,
  I: DWord;
  Driver: PDriverInfo2;
begin
  EnumPrinterDriversW(nil, nil, 2, nil, 0, pcbNeeded, cbReturned);
  ErrorCode := GetLastError;
  if (ErrorCode <> ERROR_INSUFFICIENT_BUFFER) then
  begin
    RaiseLastOsError(ErrorCode);
  end;
  GetMem(Buf, pcbNeeded);
  try
    if (not EnumPrinterDriversW(nil, nil, 2, Buf, pcbNeeded, pcbNeeded, cbReturned)) then
    begin
      RaiseLastOsError;
    end;
    Driver := Buf;
    for I := 1 to cbReturned do
    begin
      ShowMessage(Driver^.pName);
      Inc(Driver);
    end;
  finally
    FreeMem(Buf);
  end;
end;
Vielen Dank,
ich glaube langsam verstehe ich die Problematik und es macht jetzt auch Sinn das ein Element von DriverInfo2 immer 24 Byte groß ist und somit das Array nicht funktioniert.

Ich werde es jetzt nach deinem Beispiel machen was für mich jetzt endlich Sinn ergibt
Andreas
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:50 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