elfres32.inc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. TFPCRuntimeResourceInfo = packed record
  29. reshash: longint; // always 32bit, contains an ELF hash of the resource entries name
  30. restype: longint; // always 32bit, contains the resource type ID compatible with Windows RES IDs
  31. ptr: pointer; // Memory pointer to the reosource
  32. name: ansistring; // String containing the name of the resource
  33. size: longint; // The size of the resource entry - 32/64 Bit, depending on platform
  34. end;
  35. PFPCRuntimeResourceInfo = ^TFPCRuntimeResourceInfo;
  36. Var
  37. InitRes : Boolean = False;
  38. {$ifdef FPC_HAS_RESOURCES}
  39. FPCResourceSectionLocation : pFPCResourceSectionTable; external name 'FPC_RESLOCATION';
  40. {$else}
  41. FPCResourceSectionLocation : pFPCResourceSectionTable = Nil;
  42. {$endif}
  43. FPCRuntimeResourceInfoArray : PFPCRuntimeResourceInfo;
  44. ResInfoCount : Cardinal;
  45. function HashELF(const S : string) : longint;
  46. {Note: this hash function is described in "Practical Algorithms For
  47. Programmers" by Andrew Binstock and John Rex, Addison Wesley,
  48. with modifications in Dr Dobbs Journal, April 1996}
  49. var
  50. G : longint;
  51. i : longint;
  52. begin
  53. Result := 0;
  54. for i := 1 to length(S) do begin
  55. Result := (Result shl 4) + ord(S[i]);
  56. G := Result and $F0000000;
  57. if (G <> 0) then
  58. Result := Result xor (G shr 24);
  59. Result := Result and (not G);
  60. end;
  61. end;
  62. procedure InitializeResources;
  63. var
  64. i:longint;
  65. CurrentResource:pFPCResourceInfo;
  66. begin
  67. If (FPCResourceSectionLocation=Nil) then
  68. ResInfoCount:=0
  69. else
  70. ResInfoCount:=FPCResourceSectionLocation^.resentries;
  71. If (ResInfoCount<>0) then
  72. begin
  73. FPCRuntimeResourceInfoArray:=GetMem(SizeOf(TFPCRuntimeResourceInfo)*ResInfoCount);
  74. { we must zero out this because name is an ansistring }
  75. fillchar(FPCRuntimeResourceInfoArray^,SizeOf(TFPCRuntimeResourceInfo)*ResInfoCount,0);
  76. for i:=0 to ResInfoCount-1 do
  77. begin
  78. CurrentResource:=pFPCResourceInfo(pointer(FPCResourceSectionLocation^.reshash.ptr+i*sizeof(TFPCResourceInfo)));
  79. FPCRuntimeResourceInfoArray[i].reshash:=CurrentResource^.reshash;
  80. FPCRuntimeResourceInfoArray[i].restype:=CurrentResource^.restype;
  81. FPCRuntimeResourceInfoArray[i].ptr:=pointer(CurrentResource^.ptr)+ptruint(FPCResourceSectionLocation^.resdata.ptr);
  82. FPCRuntimeResourceInfoArray[i].name:=pchar(CurrentResource^.name)+ptruint(FPCResourceSectionLocation^.ressym.ptr);
  83. FPCRuntimeResourceInfoArray[i].size:=CurrentResource^.size;
  84. end;
  85. end;
  86. InitRes:=true;
  87. end;
  88. Function HINSTANCE : HMODULE;
  89. begin
  90. Result:=0;
  91. end;
  92. function FindResource(ModuleHandle: HMODULE; ResourceName: PChar; ResourceType: PChar): TResourceHandle;
  93. var
  94. i:longint;
  95. searchhash:longint;
  96. n : string;
  97. begin
  98. Result:=0;
  99. if (ResourceName=nil) then
  100. Exit;
  101. If Not InitRes then
  102. InitializeResources;
  103. { resources aren't case sensitive }
  104. n:=upcase(strpas(resourcename));
  105. searchhash:=HashELF(n);
  106. for i:=0 to ResInfoCount-1 do
  107. if (FPCRuntimeResourceInfoArray[i].reshash=searchhash) and (upcase(FPCRuntimeResourceInfoArray[i].name)=n) then
  108. begin
  109. result:=i+1;
  110. break;
  111. end;
  112. end;
  113. function LoadResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): HGLOBAL;
  114. begin
  115. If Not InitRes then
  116. InitializeResources;
  117. if (ResHandle>0) and (ResHandle-1<=ResInfoCount) then
  118. result:=HGLOBAL(FPCRuntimeResourceInfoArray[ResHandle-1].ptr)
  119. else
  120. result:=0;
  121. end;
  122. function SizeofResource(ModuleHandle: HMODULE; ResHandle: TResourceHandle): Integer;
  123. begin
  124. If Not InitRes then
  125. InitializeResources;
  126. if (ResHandle>0) and (ResHandle-1<=ResInfoCount) then
  127. result:=FPCRuntimeResourceInfoArray[ResHandle-1].size
  128. else
  129. result:=0;
  130. end;
  131. function LockResource(ResData: HGLOBAL): Pointer;
  132. begin
  133. result:=Pointer(ResData);
  134. end;
  135. function UnlockResource(ResData: HGLOBAL): LongBool;
  136. begin
  137. result:=False;
  138. end;
  139. function FreeResource(ResData: HGLOBAL): LongBool;
  140. begin
  141. result:=True;
  142. end;