Einzelnen Beitrag anzeigen

brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#15

AW: Vollständigen Datei- oder Verzeichnisnamen über das Handle ermitteln

  Alt 26. Apr 2012, 19:17
Du kannst den Code der WinAPI übersetzen indem du einfach die in/outs weglässt, das "out" in der MSDN API Beschreibung hat rein gar nichts mit dem Delphi "out" zu tun.
Delphi-Quellcode:
NtQueryObject(
IN HANDLE ObjectHandle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
Korrekterweise wird ein "in/out" als "VAR typ" übersetzt, ein "out_opt" als "pointer typ" und ein "out" als "OUT typ" wobei Typ der entsprechende Bezeichner ohne dem P ist.
Indem Fall ist die korrekte Übersetzung ein

ResultLength: PULONG; VAR typ / CONST typ / OUT typ /Ptyp unterscheiden sich rein von der Übergabe nicht voneinander, es sind alles Pointer auf den TYP. Der einzige Unterschied ist, dass Delphi zusätzliche Überprüfungen durchführen kann.

VAR: der Parameter muss vorher initalisiert werden (Warnung)
CONST: der Parameter darf nicht abgeändert werden (Fehler)
OUT: initalisierter Parameter wird nie verwendet (Warnung)

In dem Fall sollte es mit PULONG oder OUT LONG übersetzt werden, richtigerweise aber PULONG, da es optional ist, d.h. eine Übergabe von NIL ist erlaubt! Dies funktioniert aber nicht mit OUT LONG, da dann immer ein Parameter angegeben werden muss.

Logisch wäre also folgender Aufruf:

Delphi-Quellcode:
  ReturnLength: LONG;
  
  NtQueryObject(x, nil, x, x, @ReturnLength); // Laenge ermitteln
  NtQueryObject(x, @Info, x, x, nil); // auslesen, Laenge ist total egal und wollen wir nicht mehr haben
Im übrigen hast du (ASM) es komischerweise ja auch bei der ObjektInformation richtig übersetzt und übergibst im ersten Aufruf auch NIL.

Die AccessViolation kommt, weil bei dir ein zufälliger Wert für die Adresse verwendet wird (da nie initalisiert). Wenn es trotzdem funktioniert (reiner Zufall), dann hast du im Rückgabewert den du überprüfst auch immer etwas <> 0 stehen.
D.h. dein VirtualAlloc funktioniert auch mit hoher Wahrscheinlichkeit (sofern genug Speicher vorhanden). Wäre der Rückgabewert aber zu klein (für die ObjektInformation) dann funktioniert es trotzdem, da VirtualAlloc dir IMMER genügend Speicher reserviert (PageSize, 0x1000).

Das Problem ist ObjectInformationClass, die EnumTyp-Größe. Du kannst nicht einfach ein Enum von Delphi übergeben, entweder passt du das mit dem Compilerschalter an ob der du übersetzt einen Enum als DWORD und castest den Delphi-Enum. Wenn du das bedachtest dann klappt das auch bei dir.

Im übrigen solltest du in dem Fall bei dir mal die Optimierung einschalten und die Bugs beheben. Du wirst bei deinen Übersetzungen bestimmt viele Fehler eingebaut haben (doppelter Pointer, Enums).

Du hast zumindest auch in einem älteren Thread (C Callback)
http://www.delphipraxis.net/159876-c...aus-c-dll.html
eine Aussage gemacht
Zitat:
Deshalb können grundsätzlich auch nur die mit cdecl deklarierten Funktionen/Prozeduren Variablenparameter haben, während an die mit stdcall deklarierten Funktionen/Prozeduren ausschließlich Werteparameter übergeben werden dürfen.
die überhaupt nicht stimmt, da bis auf das Aufräumen des Stacks kein Unterschied zwischen CDECL/STDCALL besteht.

Geändert von brechi (26. Apr 2012 um 19:22 Uhr)
  Mit Zitat antworten Zitat