elfres32.inc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. const
  2. fpcres2elf_version=1;
  3. type
  4. TFPCResourceSectionInfo = packed record
  5. ptr: pointer; // This always contains the absolute memory address of the section at runtime
  6. size: longint; // The size of the section in bytes
  7. end;
  8. PTFPCResourceSectionInfo = ^TFPCResourceSectionInfo;
  9. TFPCResourceSectionTable = packed record
  10. version: longint;
  11. resentries: longint;
  12. ressym: TFPCResourceSectionInfo;
  13. reshash: TFPCResourceSectionInfo;
  14. resdata: TFPCResourceSectionInfo;
  15. resspare: TFPCResourceSectionInfo;
  16. resstr: TFPCResourceSectionInfo;
  17. end;
  18. PFPCResourceSectionTable = ^TFPCResourceSectionTable;
  19. TFPCResourceInfo = packed record
  20. reshash: longint; // always 32bit, contains an ELF hash of the resource entries name
  21. restype: longint; // always 32bit, contains the resource type ID compatible with Windows RES IDs
  22. ptr: pointer; // This contains the offset to the resource inside the resdata
  23. // section.
  24. name: pChar; // The byte offset to the the resource name inside the ressym section.
  25. size: longint; // The size of the resource entry - 32/64 Bit, depending on platform
  26. end;
  27. PFPCResourceInfo = ^TFPCResourceInfo;
  28. Var
  29. {$ifdef FPC_HAS_RESOURCES}
  30. FPCResourceSectionLocation : pFPCResourceSectionTable; external name 'FPC_RESLOCATION';
  31. {$else}
  32. FPCResourceSectionLocation : pFPCResourceSectionTable = Nil;
  33. {$endif}
  34. const
  35. LCase: set of char = ['a'..'z'];
  36. function HashELFUppercase(S: PChar) : longint;
  37. {Note: this hash function is described in "Practical Algorithms For
  38. Programmers" by Andrew Binstock and John Rex, Addison Wesley,
  39. with modifications in Dr Dobbs Journal, April 1996}
  40. var
  41. G: longint;
  42. C: Char;
  43. begin
  44. Result := 0;
  45. while S^ <> #0 do begin
  46. C := S^;
  47. if C in LCase then Dec(ord(C), 32);
  48. Result := (Result shl 4) + ord(C);
  49. Inc(S);
  50. G := Result and $F0000000;
  51. if (G <> 0) then
  52. Result := Result xor (G shr 24);
  53. Result := Result and (not G);
  54. end;
  55. end;
  56. Function HINSTANCE : HMODULE;
  57. begin
  58. Result:=0;
  59. end;
  60. function _StrIComp(S1, S2: PChar): LongInt;
  61. var
  62. C1, C2: Char;
  63. begin
  64. Result := 0;
  65. repeat
  66. C1 := S1^;
  67. C2 := S2^;
  68. Result := ord(C1) - ord(C2);
  69. if Result <> 0 then
  70. begin
  71. if C1 in LCase then Dec(ord(C1), 32);
  72. if C2 in LCase then Dec(ord(C2), 32);
  73. Result := ord(C1) - ord(C2);
  74. end;
  75. Inc(S1);
  76. Inc(S2);
  77. until (Result <> 0) or ((S1^ = #0) or (S2^ = #0));
  78. end;
  79. function FindResource(ModuleHandle: HMODULE; ResourceName: PChar; ResourceType: PChar): TResourceHandle;
  80. var
  81. i:longint;
  82. searchhash:longint;
  83. ResEntry: PFPCResourceInfo;
  84. pResName: PChar;
  85. tmp: array[0..7] of char;
  86. begin
  87. Result:=0;
  88. if (ResourceName=nil) or (FPCResourceSectionLocation = nil) then
  89. Exit;
  90. { This is a temporary fix to stay compatible with fpcres
  91. which currently converts all string types to RT_RCDATA. }
  92. if ResourceType > PChar($FFFF) then
  93. ResourceType := PChar(10);
  94. { support numeric resource IDs }
  95. if ResourceName <= PChar($FFFF) then
  96. begin
  97. { convert number to string inline, this should be faster than messing with strings }
  98. i := LongInt(ResourceName);
  99. ResourceName := @tmp[7];
  100. ResourceName^ := #0;
  101. Dec(ResourceName);
  102. repeat
  103. ResourceName^ := Char((i mod 10) + ord('0'));
  104. Dec(ResourceName);
  105. i := i div 10;
  106. until i = 0;
  107. ResourceName^ := '#';
  108. end;
  109. { resources aren't case sensitive }
  110. searchhash := HashELFUppercase(ResourceName);
  111. ResEntry := FPCResourceSectionLocation^.reshash.ptr;
  112. for i:=0 to FPCResourceSectionLocation^.resentries-1 do
  113. with ResEntry[I] do
  114. begin
  115. if (PChar(ResType) = ResourceType) and (reshash = searchhash) then
  116. begin
  117. pResName := PChar(FPCResourceSectionLocation^.ressym.ptr);
  118. Inc(pResName, PtrUInt(Name));
  119. if _StrIComp(pResName, ResourceName) = 0 then
  120. begin
  121. result:=i+1;
  122. break;
  123. end;
  124. end;
  125. end;
  126. end;
  127. function LoadResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): HGLOBAL;
  128. var
  129. ResEntry: PFPCResourceInfo;
  130. begin
  131. if FPCResourceSectionLocation = nil then
  132. Exit;
  133. if (ResHandle>0) and (LongInt(ResHandle)-1<=FPCResourceSectionLocation^.resentries) then
  134. begin
  135. ResEntry := FPCResourceSectionLocation^.reshash.ptr;
  136. result := HGLOBAL(PtrUInt(FPCResourceSectionLocation^.resdata.ptr) + PtrUInt(ResEntry[LongInt(ResHandle)-1].ptr));
  137. end
  138. else
  139. result:=0;
  140. end;
  141. function SizeofResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): Integer;
  142. var
  143. ResEntry: PFPCResourceInfo;
  144. begin
  145. if FPCResourceSectionLocation = nil then
  146. Exit;
  147. if (ResHandle>0) and (LongInt(ResHandle)-1<=FPCResourceSectionLocation^.resentries) then
  148. begin
  149. ResEntry := FPCResourceSectionLocation^.reshash.ptr;
  150. result := ResEntry[LongInt(ResHandle)-1].size;
  151. end
  152. else
  153. result:=0;
  154. end;
  155. function LockResource(ResData: HGLOBAL): Pointer;
  156. begin
  157. result:=Pointer(ResData);
  158. end;
  159. function UnlockResource(ResData: HGLOBAL): LongBool;
  160. begin
  161. result:=False;
  162. end;
  163. function FreeResource(ResData: HGLOBAL): LongBool;
  164. begin
  165. result:=True;
  166. end;