Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CoDOMDocument40.Create --> Prozess friert ein (https://www.delphipraxis.net/102773-codomdocument40-create-prozess-friert-ein.html)

Neotracer64 4. Nov 2007 16:29


CoDOMDocument40.Create --> Prozess friert ein
 
Hallo,
Ich befürchte entweder einen ganz ekligen undurchschaubaren Fehler oder einen Leichtsinnsfehler. (Habe bisher fast garnichts mit COM gemacht).

Ich habe folgende DLL, die ich in einen anderen Prozess injeziere (was alles klappt und eigentlich nichts zur Sache tut). Von dort aus möchte ich XML Dateien parsen. Doch es scheitert schon beim instanzieren von IXMLDomDocument2. Der Aufruf "DOMDocument40.Create" friert gleich den ganzen Prozess ein.

Hier mal vereinfacht der Code:

Die DLL:
Delphi-Quellcode:
library DllMain;

uses
  Windows,
  Sysutils,
  ActiveX,
  ComObj,
  ...
  uSettings in 'uSettings.pas';

{$R *.res}

//============================================================================//
procedure Main(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
      begin
       DisableThreadLibraryCalls(hInstance);
       OleCheck(CoInitialize(nil));

        // Init Classes
        ...
        gSet := CSettings.Create(gLog,cvar,ModulePath+'\settings.xml');
        ...
      end;
    DLL_PROCESS_DETACH:
      begin
        ...
        gSet.Free;
        CoUninitialize;
      end;
  end;
end;
//============================================================================//
begin
  DllProc := @Main;
  Main(DLL_PROCESS_ATTACH);
end.
In der uSettings.pas
Delphi-Quellcode:
type
  CSettings = class(TObject)
    public
      constructor Create(log: CDeepLog; cvar: CCVAR; xmlfile: String);
    private
      xmlDoc: IXMLDomDocument2;
      outLog: CDeepLog;
      DoLog : Boolean;
      useXML: Boolean;
      procedure LoadDefaults(var cvar: CCVAR);
      procedure LoadXMLSettings(var cvar: CCVAR);
    end;
implementation
//***************************************************************************//
//                                                                           //
//                        CSettings - Implementation                        //
//                                                                           //
//***************************************************************************//
constructor CSettings.Create(log: CDeepLog; cvar: CCVAR; xmlfile: String);
begin
  inherited Create;
  outlog := log;
  If Assigned(outlog) Then
    DoLog := True
  Else
    DoLog := False;

  If FileExists(xmlFile) Then
    begin
      // asm
       // db $EB, $FE
     // end;
      xmlDoc := CoDOMDocument40.Create;
      MessageBox(0,'I do never appear :(',':(',$40);
     ...  
end;
Das habe ich in OllyDbg mal untersucht. Mal alle Function Calls ab CoDOMDocument40.Create getraced und es läuft darauf hinaus, dass ein Syscall "NtMapViewOfSection" nie zurückkehrt und gleich den ganzen prozess einfrieren lässt.

Delphi-Quellcode:
7C91DC55   B8 6C000000      MOV EAX,6C              //0x6C -> NtMapViewOfSection
7C91DC5A  BA 0003FE7F     MOV EDX,7FFE0300
7C91DC5F  FF12             CALL DWORD PTR DS:[EDX] //KiFastSystemCall
7C91DC61   C2 2800          RETN 28                 //Kehrt nicht zurück :/

Stack:
 [ESP]    7C91DC61  RETURN to 7C91DC61
0379EE08   7C92C3DA RETURN to 7C92C3DA from 7C91DC55
0379EE0C  00002F64
0379EE10   FFFFFFFF
0379EE14   0379EEDC
0379EE18   00000000
0379EE1C  00000000
0379EE20   00000000
0379EE24   0379EED0
0379EE28   00000001
0379EE2C  00000000
0379EE30   00000004
http://undocumented.ntinternals.net/...OfSection.html

Ich bin eigentlich nicht sehr optimistisch, aber vielleicht hat einer eine Idee. :)
Danke schonmal für jeden Hinweis.

Bernhard Geyer 4. Nov 2007 16:34

Re: CoDOMDocument40.Create --> Prozess friert ein
 
Muss es denn der MS-XML-Parser sein? Nimm doch einen Parser der 100% Delphi ist. Damit kann dir COM-Technisch nix in die Suppe spucken. Könnte sein das du bei einer injezierten DLL nicht nochmal ein COM-Threadingmodell anmelden mußt da ja (i.d.R.) die Hauptanwendung das ja schon erledigt hat. U.u. strört ja das nochmalige Anmelden.

grenzgaenger 4. Nov 2007 16:43

Re: CoDOMDocument40.Create --> Prozess friert ein
 
an deiner stelle würde ich auf TXMLDocument zurückgreifen. ist zwar kein interface, sondern eine komponente... hat aber bei mir immer gut funktioniert.

Neotracer64 4. Nov 2007 16:47

Re: CoDOMDocument40.Create --> Prozess friert ein
 
@Bernhard:
Ich hatte ja zuerst CoInitialize vergessen, was dazu führte, dass er mich angemeckert hat. ;)
Beim Hinzufügen von CoInitialize friert er wie oben beschrieben ein.
Ich werd mich Wohl oder Übel nach einem reinen Delphi Parser umsehen müssen.

@grenzgaenger:
Oh, roter Kasten funktioniert. Schau ich mir auf jedenfall mal an. ;)

EDIT: TXMLDocument braucht auch den ganzen COM-Kram. Habs auch ausprobiert. Geht leider nicht, selbes problem.

grenzgaenger 4. Nov 2007 17:07

Re: CoDOMDocument40.Create --> Prozess friert ein
 
kurz noch 'n nachtrag, die komponente ist folgendermassen definiert TXMLDocument = class(TComponent, IInterface, IXMLDocument, IXMLDocumentAccess). damit haste auch die interfaces... ;-)

Neotracer64 4. Nov 2007 18:14

Re: CoDOMDocument40.Create --> Prozess friert ein
 
Ich benutze jetzt Muetzes XMLLib [1].
Somit markiere ich den Thread mal als gelöst. ;)

[1] http://www.muetze1.de/?pl=3&c=1&fid=XMLLib.php&lang=ger

Bernhard Geyer 4. Nov 2007 19:29

Re: CoDOMDocument40.Create --> Prozess friert ein
 
Zitat:

Zitat von grenzgaenger
kurz noch 'n nachtrag, die komponente ist folgendermassen definiert TXMLDocument = class(TComponent, IInterface, IXMLDocument, IXMLDocumentAccess). damit haste auch die interfaces... ;-)

Das Problem sind u.U. nur die COM-Interfaces. Wenn er per TXMLDocument den alternativen XML-Parser OpenXML (ging jedenfalls bei D7) einstellt sollte es u.U. auch gehen.

mr2 4. Nov 2007 21:14

Re: CoDOMDocument40.Create --> Prozess friert ein
 
nur mal so zur Info:

in der Main-Prozedur einer DLL darf man nie andere DLLs nachladen

Zitat:

Zitat von Microsoft
The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.

DllMain Callback Function

wenn man jedoch ein COM-Objekt erzeugt, welches in einer DLL liegt, die der Prozess nicht schon zuvor geladen hat, macht man genau das

mr2

Neotracer64 4. Nov 2007 23:39

Re: CoDOMDocument40.Create --> Prozess friert ein
 
Oh, daran habe ich nicht gedacht. Die Lösung für mich sähe dann wohl so aus die nötigen DLLs (wie Ole32.dll?) in einem seperaten Thread zu laden richtig? (Ich habe ja keinen Einfluss auf den Main-Thread, ich injeziere ja meine DLL)
Wie dem auch sei, ich hab jetzt so ziemlich das meiste auf Mützes XMLLib umgeschrieben und bin sehr zufrieden eigentlich. ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:43 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