unit LoadGlobal;

{$mode objfpc}{$H+}

interface

uses windows,sysutils;


function StartHook:boolean; stdcall;
procedure StopHook; stdcall;

implementation
//==============================GLOBAL PART==================================
//used in the every instance

type TFileMap=record
  HookHandle: THandle;
end;

var
  initializated: boolean=false;
  HookHandle: THandle=0;

  hookID: string='';



procedure initDLL;
var tempModuleName: array[1..MaxPathLen]of char;
    len:longint;
    
    filemaphandle:THandle;
    filemap:^TFileMap;
begin
  len:=GetModuleFileName(HINSTANCE,@tempModuleName[1],length(tempModuleName));
  SetLength(hookID,len);
  move(tempModuleName[1],hookID[1],len);
  hookID:=StringReplace(hookID,'\','#',[rfReplaceAll]);
  hookID+='BeniBela-Hook-DLL:'+hookID;
  initializated:=true;
  
  filemaphandle:=openFileMapping(FILE_MAP_READ,false,pchar(hookID));
  if filemaphandle<>0 then begin
    filemap:=MapViewOfFile(filemaphandle,FILE_MAP_READ,0,0,sizeof(TFileMap));
    HookHandle:=filemap^.HookHandle;
    UnmapViewOfFile(filemap);
    CloseHandle(filemaphandle);
  end;
  
end;



//===============================INJECTED PART==================================
//used in the remote application only

function GetMsgProc(code: Integer; removal: wparam; Msg: lparam): Integer; stdcall;
begin
  if not initializated then initDLL;
  if (code=HC_ACTION) or (HookHandle=0) then exit(0)
  else Result := CallNextHookEx(HookHandle,code,removal,Msg);
end;


//==============================LOCAL PART===============================
//used in the calling application only
var filemaphandle: THandle;
    fileMap: ^TFileMap;

function StartHook:boolean; stdcall;
begin
  if not initializated then initDLL;
  if HookHandle<>0 then exit(false);
  HookHandle := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, 0);
  if HookHandle=0 then exit(false);
  result:=true;
  
  filemaphandle:=CreateFileMapping(INVALID_HANDLE_VALUE,nil,PAGE_READWRITE,0,sizeof(TFileMap),pchar(hookID));
  fileMap:=MapViewOfFile(filemaphandle,FILE_MAP_WRITE,0,0,sizeof(TFileMap));
  fileMap^.HookHandle:=HookHandle;
end;

procedure StopHook; stdcall;
begin
  if HookHandle=0 then exit;
  HookHandle:=0;
  UnhookWindowsHookEx(HookHandle);
  UnmapViewOfFile(fileMap);
  CloseHandle(filemaphandle);
end;



initialization
  initDLL;
end.

