Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage) (https://www.delphipraxis.net/191919-enumprinterdrivers-%3D-zugriffsverletzung-anfaengerfrage.html)

himitsu 13. Mär 2017 16:01

AW: EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage)
 
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

Andreas2k 14. Mär 2017 10:45

AW: EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage)
 
Zitat:

Zitat von Zacherl (Beitrag 1364044)
Zitat:

Zitat von himitsu (Beitrag 1363790)
Man kann ja dennoch das Array verwenden, aber dann eben nicht auf alle, sondern nur auf die richige Anzahl der Einträge zugreifen.

Zitat:

Zitat von himitsu (Beitrag 1363798)
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
Delphi-Quellcode:
pcbNeeded
in Bytes angegeben ist und ausdrücklich nicht
Delphi-Quellcode:
pcReturned * SizeOf(DRIVER_INFO_2)
ist. Nichtmal ein Vielfaches von
Delphi-Quellcode:
SizeOf(DRIVER_INFO_2)
ist garantiert. Mit einem
Delphi-Quellcode:
Array of DRIVER_INFO_2
zu arbeiten, macht doch rein von der Logik her einfach keinen Sinn.

Zitat:

Zitat von Andreas2k (Beitrag 1364040)
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:
Delphi-Quellcode:
pcbNeeded
ist kein Vielfaches von
Delphi-Quellcode:
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 :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:18 Uhr.
Seite 3 von 3     123   

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