瀏覽代碼

+ Initial implementation of RTL resource support

git-svn-id: trunk@991 -
michael 20 年之前
父節點
當前提交
c15d1b280f
共有 8 個文件被更改,包括 253 次插入7 次删除
  1. 3 0
      .gitattributes
  2. 156 0
      rtl/inc/elfres32.inc
  3. 16 0
      rtl/inc/resh.inc
  4. 41 0
      rtl/inc/sysres.inc
  5. 13 0
      rtl/inc/system.inc
  6. 5 0
      rtl/inc/systemh.inc
  7. 10 2
      rtl/linux/system.pp
  8. 9 5
      rtl/win32/system.pp

+ 3 - 0
.gitattributes

@@ -3464,6 +3464,7 @@ rtl/inc/dosh.inc svneol=native#text/plain
 rtl/inc/dynarr.inc svneol=native#text/plain
 rtl/inc/dynarrh.inc svneol=native#text/plain
 rtl/inc/dynlibs.pp svneol=native#text/plain
+rtl/inc/elfres32.inc svneol=native#text/plain
 rtl/inc/except.inc svneol=native#text/plain
 rtl/inc/fexpand.inc svneol=native#text/plain
 rtl/inc/file.inc svneol=native#text/plain
@@ -3510,6 +3511,7 @@ rtl/inc/printer.inc svneol=native#text/plain
 rtl/inc/printerh.inc svneol=native#text/plain
 rtl/inc/readme -text
 rtl/inc/real2str.inc svneol=native#text/plain
+rtl/inc/resh.inc svneol=native#text/plain
 rtl/inc/rtti.inc svneol=native#text/plain
 rtl/inc/sockets.inc svneol=native#text/plain
 rtl/inc/socketsh.inc svneol=native#text/plain
@@ -3519,6 +3521,7 @@ rtl/inc/sstrings.inc svneol=native#text/plain
 rtl/inc/stdsock.inc svneol=native#text/plain
 rtl/inc/strings.pp svneol=native#text/plain
 rtl/inc/stringsi.inc svneol=native#text/plain
+rtl/inc/sysres.inc svneol=native#text/plain
 rtl/inc/system.fpd -text
 rtl/inc/system.inc svneol=native#text/plain
 rtl/inc/systemh.inc svneol=native#text/plain

+ 156 - 0
rtl/inc/elfres32.inc

@@ -0,0 +1,156 @@
+
+const 
+  fpcres2elf_version=1;
+
+type
+  TFPCResourceSectionInfo = packed record
+    ptr: pointer;     // This always contains the absolute memory address of the section at runtime
+    size: longint;    // The size of the section in bytes
+  end;
+  PTFPCResourceSectionInfo = ^TFPCResourceSectionInfo;
+
+  TFPCResourceSectionTable = packed record
+    version: longint;
+    resentries: longint;
+    ressym: TFPCResourceSectionInfo;
+    reshash: TFPCResourceSectionInfo;
+    resdata: TFPCResourceSectionInfo;
+    resspare: TFPCResourceSectionInfo;
+    resstr: TFPCResourceSectionInfo;
+  end;
+  PFPCResourceSectionTable = ^TFPCResourceSectionTable;
+
+  TFPCResourceInfo = packed record
+    reshash: longint;   // always 32bit, contains an ELF hash of the resource entries name
+    restype: longint;   // always 32bit, contains the resource type ID compatible with Windows RES IDs
+    ptr:     pointer;   // This contains the offset to the resource inside the resdata
+                        // section.
+    name:    pChar;     // The byte offset to the the resource name inside the ressym section.
+    size:    longint;   // The size of the resource entry - 32/64 Bit, depending on platform
+  end;
+  PFPCResourceInfo = ^TFPCResourceInfo;
+
+  TFPCRuntimeResourceInfo = packed record
+    reshash: longint;   // always 32bit, contains an ELF hash of the resource entries name
+    restype: longint;   // always 32bit, contains the resource type ID compatible with Windows RES IDs
+    ptr:     pointer;   // Memory pointer to the reosource
+    name:    string;    // String containing the name of the resource
+    size:    longint;   // The size of the resource entry - 32/64 Bit, depending on platform
+  end;
+  PFPCRuntimeResourceInfo = ^TFPCRuntimeResourceInfo;
+
+Var
+  InitRes : Boolean = False;
+  FPCResourceSectionLocation : pFPCResourceSectionTable; external name 'FPC_RESLOCATION';
+  FPCRuntimeResourceInfoArray : PFPCRuntimeResourceInfo;
+  ResInfoCount : Cardinal;
+
+function HashELF(const S : string) : longint;
+{Note: this hash function is described in "Practical Algorithms For
+       Programmers" by Andrew Binstock and John Rex, Addison Wesley,
+       with modifications in Dr Dobbs Journal, April 1996}
+var
+  G : longint;
+  i : longint;
+begin
+  Result := 0;
+  for i := 1 to length(S) do begin
+    Result := (Result shl 4) + ord(S[i]);
+    G := Result and $F0000000;
+    if (G <> 0) then
+      Result := Result xor (G shr 24);
+    Result := Result and (not G);
+  end;
+end;
+  
+procedure InitializeResources;
+
+var 
+  i:longint;
+  CurrentResource:pFPCResourceInfo;
+  
+begin
+  If (FPCResourceSectionLocation=Nil) then
+    ResInfoCount:=0
+  else  
+    ResInfoCount:=FPCResourceSectionLocation^.resentries;
+  If (ResInfoCount<>0) then
+    begin
+    FPCRuntimeResourceInfoArray:=GetMem(SizeOf(TFPCRuntimeResourceInfo)*ResInfoCount);
+    for i:=0 to ResInfoCount-1 do
+      begin
+      CurrentResource:=pFPCResourceInfo(pointer(longint(FPCResourceSectionLocation^.reshash.ptr)+i*sizeof(TFPCResourceInfo)));
+      FPCRuntimeResourceInfoArray[i].reshash:=CurrentResource^.reshash;
+      FPCRuntimeResourceInfoArray[i].restype:=CurrentResource^.restype;
+      FPCRuntimeResourceInfoArray[i].ptr:=pointer(longint(CurrentResource^.ptr)+longint(FPCResourceSectionLocation^.resdata.ptr));
+      FPCRuntimeResourceInfoArray[i].name:=pchar(pointer(longint(CurrentResource^.name)+longint(FPCResourceSectionLocation^.ressym.ptr)));
+      FPCRuntimeResourceInfoArray[i].size:=CurrentResource^.size;
+      end;
+    end;  
+  InitRes:=true;
+end;
+
+Function HINSTANCE : HMODULE;
+
+begin
+  Result:=0;
+end;
+
+function FindResource(ModuleHandle: HMODULE; ResourceName: PChar; ResourceType: PChar): TResourceHandle;
+
+var 
+  i:longint;
+  searchhash:longint;
+  n : string;
+  
+begin
+  Result:=0;
+  if (ResourceName=nil) then 
+    Exit;
+  If Not InitRes then 
+    InitializeResources;
+  searchhash:=HashELF(ResourceName);
+  n:=strpas(resourcename);
+  I:=0;
+  While (Result=0) and (I<ResInfoCount) do
+    begin
+    if (FPCRuntimeResourceInfoArray[i].reshash=searchhash) and (FPCRuntimeResourceInfoArray[i].name=n) then
+      result:=i+1;
+    Inc(I);  
+    end;
+end;
+
+function LoadResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): HGLOBAL;
+begin
+  If Not InitRes then 
+    InitializeResources;
+  if (ResHandle>0) and (ResHandle-1<=ResInfoCount) then
+    result:=HGLOBAL(FPCRuntimeResourceInfoArray[ResHandle-1].ptr)
+  else
+    result:=0;
+end;
+
+function SizeofResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): Integer;
+begin
+  If Not InitRes then 
+    InitializeResources;
+  if (ResHandle>0) and (ResHandle-1<=ResInfoCount) then
+    result:=FPCRuntimeResourceInfoArray[ResHandle-1].size
+  else
+    result:=0;
+end;
+
+function LockResource(ResData: HGLOBAL): Pointer;
+begin
+  result:=Pointer(ResData);
+end;
+
+function UnlockResource(ResData: HGLOBAL): LongBool;
+begin
+  result:=False;
+end;
+
+function FreeResource(ResData: HGLOBAL): LongBool;
+begin
+  result:=True;
+end;

+ 16 - 0
rtl/inc/resh.inc

@@ -0,0 +1,16 @@
+type
+  TResourceHandle = Cardinal;
+  HMODULE = Cardinal;
+  HGLOBAL = Cardinal;
+      
+// Win32 API compatible Resource functions
+Function HINSTANCE : HMODULE;
+Function FindResource(ModuleHandle: HMODULE; ResourceName, ResourceType: PChar): TResourceHandle;
+Function FindResource(ModuleHandle: HMODULE; ResourceName, ResourceType: AnsiString): TResourceHandle;
+Function LoadResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): HGLOBAL;
+Function SizeofResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): Integer;
+Function LockResource(ResData: HGLOBAL): Pointer;
+Function UnlockResource(ResData: HGLOBAL): LongBool;
+Function FreeResource(ResData: HGLOBAL): LongBool;
+
+      

+ 41 - 0
rtl/inc/sysres.inc

@@ -0,0 +1,41 @@
+Function HINSTANCE : HMODULE;
+
+begin
+  Result:=0;
+end;
+
+Function FindResource(ModuleHandle: HMODULE; ResourceName, ResourceType: PChar): TResourceHandle;
+
+begin
+  Result:=0;
+end;
+
+Function LoadResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): HGLOBAL;
+
+begin
+  Result:=0;
+end;
+
+Function SizeofResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): Integer;
+
+begin
+  Result:=-1;
+end;
+
+Function LockResource(ResData: HGLOBAL): Pointer;
+
+begin
+  Result:=Nil;
+end;
+
+Function UnlockResource(ResData: HGLOBAL): LongBool;
+
+begin
+  Result:=False;
+end;
+
+Function FreeResource(ResData: HGLOBAL): LongBool;
+
+begin
+  Result:=False;
+end;

+ 13 - 0
rtl/inc/system.inc

@@ -1012,4 +1012,17 @@ end;
 { OS dependent dir functions }
 {$i sysdir.inc}
 
+{*****************************************************************************
+                            Resources support
+*****************************************************************************}
+
+
+{$ifndef HAS_RESOURCES}
+{$i sysres.inc}
+{$endif}
+
+Function FindResource(ModuleHandle: HMODULE; ResourceName, ResourceType: AnsiString): TResourceHandle;
 
+begin
+  Result:=FindResource(ModuleHandle,PChar(ResourceName),PChar(ResourceType));
+end;

+ 5 - 0
rtl/inc/systemh.inc

@@ -683,6 +683,11 @@ const
 { Generic threadmanager }
 {$i threadh.inc}
 
+{*****************************************************************************
+                          Resources support
+*****************************************************************************}
+
+{$i resh.inc}
 
 {*****************************************************************************
                    FPDoc phony declarations.

+ 10 - 2
rtl/linux/system.pp

@@ -16,11 +16,13 @@
 
 { These things are set in the makefile, }
 { But you can override them here.}
-
-
 { If you use an aout system, set the conditional AOUT}
 { $Define AOUT}
 
+{$ifdef i386}
+{$DEFINE ELFRES32}
+{$endif}
+
 Unit System;
 
 Interface
@@ -33,6 +35,12 @@ Interface
 
 Implementation
 
+{ Include ELF resources }
+
+{$ifdef ELFRES32}
+{$define HAS_RESOURCES}
+{$i elfres32.inc}
+{$endif}
 
 {$I system.inc}
 

+ 9 - 5
rtl/win32/system.pp

@@ -90,7 +90,6 @@ var
 { Win32 Info }
   startupinfo : tstartupinfo;
   hprevinst,
-  HInstance,
   MainInstance,
   cmdshow     : longint;
   DLLreason,DLLparam:longint;
@@ -106,11 +105,16 @@ const
   Dll_Thread_Attach_Hook : TDLL_Entry_Hook = nil;
   Dll_Thread_Detach_Hook : TDLL_Entry_Hook = nil;
 
-type
-  HMODULE = THandle;
-
 implementation
 
+var
+  SysInstance : Longint;
+
+{$ifdef i386}
+{$define HAS_RESOURCES}
+{$i win32res.inc}
+{$endif}
+
 { used by wstrings.inc because wstrings.inc is included before sysos.inc
   this is put here (FK) }
 
@@ -1127,7 +1131,7 @@ begin
   { some misc Win32 stuff }
   hprevinst:=0;
   if not IsLibrary then
-    HInstance:=getmodulehandle(GetCommandFile);
+    SysInstance:=getmodulehandle(GetCommandFile);
   MainInstance:=HInstance;
   cmdshow:=startupinfo.wshowwindow;
   { Setup heap }