mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-17 16:39:24 +02:00
165 lines
5.1 KiB
PHP
165 lines
5.1 KiB
PHP
|
|
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: ansistring; // 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;
|
|
{$ifdef FPC_HAS_RESOURCES}
|
|
FPCResourceSectionLocation : pFPCResourceSectionTable; external name 'FPC_RESLOCATION';
|
|
{$else}
|
|
FPCResourceSectionLocation : pFPCResourceSectionTable = Nil;
|
|
{$endif}
|
|
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);
|
|
{ we must zero out this because name is an ansistring }
|
|
fillchar(FPCRuntimeResourceInfoArray^,SizeOf(TFPCRuntimeResourceInfo)*ResInfoCount,0);
|
|
|
|
for i:=0 to ResInfoCount-1 do
|
|
begin
|
|
CurrentResource:=pFPCResourceInfo(pointer(FPCResourceSectionLocation^.reshash.ptr+i*sizeof(TFPCResourceInfo)));
|
|
FPCRuntimeResourceInfoArray[i].reshash:=CurrentResource^.reshash;
|
|
FPCRuntimeResourceInfoArray[i].restype:=CurrentResource^.restype;
|
|
FPCRuntimeResourceInfoArray[i].ptr:=pointer(CurrentResource^.ptr)+PtrInt(FPCResourceSectionLocation^.resdata.ptr);
|
|
FPCRuntimeResourceInfoArray[i].name:=pchar(CurrentResource^.name)+PtrInt(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;
|
|
{ resources aren't case sensitive }
|
|
n:=upcase(strpas(resourcename));
|
|
searchhash:=HashELF(n);
|
|
I:=0;
|
|
While (Result=0) and (I<ResInfoCount) do
|
|
begin
|
|
if (FPCRuntimeResourceInfoArray[i].reshash=searchhash) and (upcase(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;
|