Registriert seit: 2. Jan 2003
108 Beiträge
Delphi XE5 Professional
|
AW: EnumPrinterDrivers = Zugriffsverletzung (Anfängerfrage)
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
|
|
Zitat
|