Einzelnen Beitrag anzeigen

Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#8

AW: Re: Drucker auslesen (Systemsteuerung --> Drucker & F

  Alt 27. Jul 2010, 08:54
Leider knallt es beim Auslesen der PPRinterInfo2 -Struktur ( FPrinterListName.Add(PPrinter^.pPrinterName); // Zeile 528 in GetPrinterListName)
Was kann das sein? (Auf einem XP-Rechner funktioniert es!)
Da ist wohl ein Bug in folgender Methode (und auch anderen Methoden)
Erklärung:
Es wird ein neuer Record von PPrinterInfo2 im Speicher angelegt,
dann werden alle Daten aus dem Speicherblock Buffer übertragen
und dann wird der Record an die Liste FAllInfos angehängt.

Das ist die Idee hinter dem Code.
In Wirklichkeit werden hier aber keine Daten kopiert, sondern hauptsächlich Zeiger.
Und die Zeiger zeigen direkt in den Buffer hinein.
Mit dem letzten Befehl FreeMem(Buffer); wird der Puffer allerdings freigegeben
und die Zeiger verweisen auf freigegebenen Speicher.

Es hängt vom Zufall ab, wie lange es dauert bis es eine Zugriffsverletzung gibt.

Delphi-Quellcode:
procedure TPrinterCustom.GetAllPrinterInfos;
var
  pcbNeeded : DWORD;
  pcReturned : DWORD;
  Buffer : PChar;
  PrinterInfo: PChar;
  I : Integer;
  PPrinter : PPrinterInfo2;
  Flags : DWORD;
  Level : Byte;
begin
  if Win32Platform = VER_PLATFORM_WIN32_NT then
  begin
    Flags := PRINTER_ENUM_CONNECTIONS or PRINTER_ENUM_LOCAL;
    Level := 2;
  end
  else
  begin
    Flags := PRINTER_ENUM_LOCAL;
    Level := 2;
  end;
  EnumPrinters(Flags, nil, Level, nil, 0, pcbNeeded, pcReturned);
  GetMem(Buffer, pcbNeeded);
  EnumPrinters(Flags, nil, Level, PByte(Buffer), pcbNeeded, pcbNeeded, pcReturned);
  PrinterInfo := Buffer;
  for I := 0 to pcReturned - 1 do
  begin
    New(PPrinter);
    with PPrinterInfo2(PrinterInfo)^ do
    begin
      PPrinter^.pServerName := pServerName; // kopiere PChar-Zeiger
      PPrinter^.pPrinterName := pPrinterName; // dito
      PPrinter^.pShareName := pShareName; // ...
      PPrinter^.pPortName := pPortName;
      PPrinter^.pDriverName := pDriverName;
      PPrinter^.pComment := pComment;
      PPrinter^.pLocation := pLocation;
      PPrinter^.pSepFile := pSepFile;
      PPrinter^.pPrintProcessor := pPrintProcessor;
      PPrinter^.pDatatype := pDatatype;
      PPrinter^.pParameters := pParameters;
      PPrinter^.Attributes := Attributes;
      PPrinter^.Priority := Priority;
      PPrinter^.DefaultPriority := DefaultPriority;
      PPrinter^.StartTime := StartTime;
      PPrinter^.UntilTime := UntilTime;
      PPrinter^.Status := Status;
      PPrinter^.cJobs := cJobs;
      PPrinter^.AveragePPM := AveragePPM;
      FAllInfos.Add(Pointer(PPrinter));
      Inc(PrinterInfo, SizeOf(TPrinterInfo2));
    end;
  end;
  FreeMem(Buffer);
end;
  Mit Zitat antworten Zitat