|
@@ -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;
|