Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#1

ShareMem ohne ShareMem.dll und Co.

  Alt 13. Jun 2009, 16:36
Hier habt ihr noch ein kleines "Abfallprodukt" meines Hier im Forum suchenhimXML

Es schleift praktisch jeden Speichermanager von einer Delphi-EXE in eine Delphi-DLL durch.

Dabei ist es egal, ob nun der Standard-SpeicherManager verwendet wird oder ein Anderer.

Und es wird auch keine zusätzliche Datei benötigt, wie es bei Delphi-Referenz durchsuchenShareMem der Fall ist.


Systemvorausstzung:
die DLL (bzw. die himiSM.pas) benötigt mindestens ein Delphi, wo TMemoryManagerEx verfügbar ist
und die EXE sollte vermutlich mindestens mit Delphi 4 erstellt werden.


Diese Unit muß in die DLL aufgenommen werden:
> erster Uses-Eintrag in deren .DPR
Delphi-Quellcode:
Unit himiSM_DLLInit;

Interface

Implementation
  {$WARN SYMBOL_DEPRECATED OFF}

  Uses Windows;

  Var Name: Array[0..29] of AnsiChar = 'himiShareMem_xxxxxxxxxxxxxxxx'#0;
    i, i2: Integer;
    Map: THandle;
    View: PAnsiChar;
    MemMgr: TMemoryManager;
    MemMgrEx: TMemoryManagerEx;
    OldMemMgr: TMemoryManagerEx;

Initialization
  GetMemoryManager(OldMemMgr);

  i2 := GetCurrentProcessId;
  For i := 15 downto 0 do Begin
    If Byte(i2 and $0F) <= 9 Then Name[i + 13] := AnsiChar((i2 and $0F) + Ord('0'))
    Else Name[i + 13] := AnsiChar((i2 and $0F) - 10 + Ord('A'));
    i2 := i2 shr 4;
  End;
  Map := OpenFileMappingA(FILE_MAP_READ, False, @Name);
  View := MapViewOfFile(Map, FILE_MAP_READ, 0, 0, 0);
  If (Map <> 0) and Assigned(View) Then
    If Assigned(PPointer(View + 3 * SizeOf(Pointer))^) Then Begin
      CopyMemory(@MemMgrEx, View, SizeOf(MemMgrEx));
      SetMemoryManager(MemMgrEx);
    End Else Begin
      CopyMemory(@MemMgr, View, SizeOf(MemMgr));
      SetMemoryManager(MemMgr);
    End;
  UnmapViewOfFile(View);
  CloseHandle(Map);

Finalization
  SetMemoryManager(OldMemMgr);

End.
Und zum Laden der DLL wird dann "einfach" nur noch statt LoadLibrary das LoadLibrarySM verwendet
Delphi-Quellcode:
Function LoadLibrarySM(LibFileName: PChar): HMODULE;
  Var Name: Array[0..29] of AnsiChar;
    i, i2: Integer;
    Map: THandle;
    View: PAnsiChar;
    MemMgr: {$IF Declared(TMemoryManagerEx)}TMemoryManagerEx{$ELSE}TMemoryManager{$IFEND};
    Error: HRESULT;

  Begin
    Error := ERROR_INVALID_FUNCTION;
    Name := 'himiShareMem_xxxxxxxxxxxxxxxx'#0;
    i2 := GetCurrentProcessId;
    For i := 15 downto 0 do Begin
      If Byte(i2 and $0F) <= 9 Then Name[i + 13] := AnsiChar((i2 and $0F) + Ord('0'))
      Else Name[i + 13] := AnsiChar((i2 and $0F) - 10 + Ord('A'));
      i2 := i2 shr 4;
    End;
    Map := CreateFileMappingA(INVALID_HANDLE_VALUE, nil, FILE_MAP_READ, 0, 6 * SizeOf(Pointer), @Name);
    View := MapViewOfFile(Map, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, 0);
    _DLL := 0;
    Try
      If (Map <> 0) and Assigned(View) Then Begin
        GetMemoryManager(MemMgr);
        ZeroMemory(View, 6 * SizeOf(Pointer));
        CopyMemory(View, @MemMgr, SizeOf(MemMgr));
        Result := LoadLibrary(LibFileName);
        Error := GetLastError;
      End Else Begin
        Result := 0;
        Error := ERROR_ACCESS_DENIED;
      End;
    Finally
      UnmapViewOfFile(View);
      CloseHandle(Map);
      SetLastError(Error);
    End;
  End;

Info:
Es macht übrigens auch nichts aus, wenn in einem von Beiden (EXE und DLL) keiner der Codes eingebaut ist ... in diesem Falls wird einfach nur keine Umleitung eingerichtet.

Also wenn die DLL mit deim "einfachen" LoadLibrary geladen wird oder die DLL den Code nicht enthält.



Anhang:
himiSM_DLLInit.pas * » * kommt in die DLL
himiSM_LoadLibrary.pas * » * kommt in die EXE (oder eine andere DLL) und enthällt die LoadLibrarySM
Angehängte Dateien
Dateityp: zip himism_205.zip (1,8 KB, 14x aufgerufen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat