Browse Source

* Patch from Anton Kavalenka to fix bug #17805 (load resources from libraries)

git-svn-id: trunk@30574 -
michael 10 years ago
parent
commit
0c76b8e656
1 changed files with 70 additions and 23 deletions
  1. 70 23
      rtl/inc/intres.inc

+ 70 - 23
rtl/inc/intres.inc

@@ -29,6 +29,8 @@ type
   end;
   PResHdr = ^TResHdr;
 
+  TLibGetResHdr=function():PResHdr;
+
 var
 {$ifdef FPC_HAS_WINLIKERESOURCES}
   ResHeader : PResHdr; external name 'FPC_RESLOCATION';
@@ -40,6 +42,31 @@ var
                              Private Helper Functions
 *****************************************************************************)
 
+function ExtGetResHdr(ModuleHandle : TFPResourceHMODULE):PResHdr;
+var
+  p:TLibGetResHdr;
+  pp:pointer;
+begin
+  ExtGetResHdr:=nil;
+  if ModuleHandle=0 then
+    ExtGetResHdr:=ResHeader // internal
+  else
+  begin
+    // 1-st way to get resource location
+    p:=TLibGetResHdr(GetProcAddress(ModuleHandle,'rsrc'));
+    if p<>nil then // there is public
+      ExtGetResHdr:=p();
+    if ExtGetResHdr=nil then // try another way
+    begin
+      // 2-nd way to get resource location
+      pp:=GetProcAddress(ModuleHandle,'FPC_RESLOCATION');
+      if pp<>nil then
+      ExtGetResHdr:=PResHDR(pp^);
+    end;
+  end;
+end;
+
+
 //resource functions are case insensitive... copied from genstr.inc
 function ResStrIComp(Str1, Str2 : PChar): SizeInt;
 var
@@ -135,12 +162,12 @@ begin
 end;
 
 //Returns a pointer to a name node.
-function InternalFindResource(ResourceName, ResourceType: PChar):
+function InternalFindResource(ResHdr:PResHdr;ResourceName, ResourceType: PChar):
  PResInfoNode;
 begin
   InternalFindResource:=nil;
-  if ResHeader=nil then exit;
-  InternalFindResource:=ResHeader^.rootptr;
+  if ResHdr=nil then exit;
+  InternalFindResource:=ResHdr^.rootptr;
 
   InternalFindResource:=BinSearchRes(InternalFindResource,ResourceType);
   if InternalFindResource<>nil then
@@ -165,6 +192,9 @@ begin
   end;
 end;
 
+
+
+
 (*****************************************************************************
                              Public Resource Functions
 *****************************************************************************)
@@ -177,11 +207,13 @@ end;
 Function IntEnumResourceTypes(ModuleHandle : TFPResourceHMODULE; EnumFunc : EnumResTypeProc; lParam : PtrInt) : LongBool;
 var ptr : PResInfoNode;
     tot, i : integer;
+    res_hdr:PResHdr;
 begin
   IntEnumResourceTypes:=False;
-  if ResHeader=nil then exit;
-  tot:=ResHeader^.rootptr^.ncounthandle+ResHeader^.rootptr^.idcountsize;
-  ptr:=ResHeader^.rootptr^.subptr;
+  res_hdr:=ExtGetResHdr(ModuleHandle);
+  if res_hdr=nil then exit;
+  tot:=res_hdr^.rootptr^.ncounthandle+res_hdr^.rootptr^.idcountsize;
+  ptr:=res_hdr^.rootptr^.subptr;
   IntEnumResourceTypes:=true;
   i:=0;
   while i<tot do
@@ -194,10 +226,12 @@ end;
 Function IntEnumResourceNames(ModuleHandle : TFPResourceHMODULE; ResourceType : PChar; EnumFunc : EnumResNameProc; lParam : PtrInt) : LongBool;
 var ptr : PResInfoNode;
     tot, i : integer;
+    res_hdr:PResHdr;
 begin
   IntEnumResourceNames:=False;
-  if ResHeader=nil then exit;
-  ptr:=ResHeader^.rootptr;
+  res_hdr:=ExtGetResHdr(ModuleHandle);
+  if res_hdr=nil then exit;
+  ptr:=res_hdr^.rootptr;
 
   ptr:=BinSearchRes(ptr,ResourceType);
   if ptr=nil then exit;
@@ -216,9 +250,12 @@ end;
 Function IntEnumResourceLanguages(ModuleHandle : TFPResourceHMODULE; ResourceType, ResourceName : PChar; EnumFunc : EnumResLangProc; lParam : PtrInt) : LongBool;
 var ptr : PResInfoNode;
     tot, i : integer;
+    res_hdr:PResHdr;
 begin
   IntEnumResourceLanguages:=False;
-  ptr:=InternalFindResource(ResourceName,ResourceType);
+  res_hdr:=ExtGetResHdr(ModuleHandle);
+  if res_hdr=nil then exit;
+  ptr:=InternalFindResource(res_hdr,ResourceName,ResourceType);
   if ptr=nil then exit;
 
   tot:=ptr^.idcountsize;
@@ -235,18 +272,21 @@ end;
 Function IntFindResource(ModuleHandle: TFPResourceHMODULE; ResourceName,
   ResourceType: PChar): TFPResourceHandle;
 var ptr : PResInfoNode;
+    res_hdr: PresHdr;
 begin
   IntFindResource:=0;
-  ptr:=InternalFindResource(ResourceName,ResourceType);
+  res_hdr:=ExtGetResHdr(ModuleHandle);
+  if res_hdr=nil then exit;
+  ptr:=InternalFindResource(res_hdr,ResourceName,ResourceType);
   if ptr=nil then exit;
 
   //first language id
   ptr:=ptr^.subptr;
   if ptr^.ncounthandle=0 then
   begin
-    ResHeader^.handles[ResHeader^.usedhandles]:=PtrUint(ptr);
-    inc(ResHeader^.usedhandles);
-    ptr^.ncounthandle:=ResHeader^.usedhandles;
+    res_hdr^.handles[res_hdr^.usedhandles]:=PtrUint(ptr);
+    inc(res_hdr^.usedhandles);
+    ptr^.ncounthandle:=res_hdr^.usedhandles;
   end;
   IntFindResource:=ptr^.ncounthandle;
 end;
@@ -256,9 +296,12 @@ Function IntFindResourceEx(ModuleHandle: TFPResourceHMODULE; ResourceType,
 const LANG_NEUTRAL = 0;
       LANG_ENGLISH = 9;
 var nameptr,ptr : PResInfoNode;
+    res_hdr: PResHdr;
 begin
   IntFindResourceEx:=0;
-  nameptr:=InternalFindResource(ResourceName,ResourceType);
+  res_hdr:=ExtGetResHdr(ModuleHandle);
+  if res_hdr=nil then exit;
+  nameptr:=InternalFindResource(res_hdr,ResourceName,ResourceType);
   if nameptr=nil then exit;
 
   //try exact match
@@ -278,27 +321,31 @@ begin
 
   if ptr^.ncounthandle=0 then
   begin
-    ResHeader^.handles[ResHeader^.usedhandles]:=PtrUint(ptr);
-    inc(ResHeader^.usedhandles);
-    ptr^.ncounthandle:=ResHeader^.usedhandles;
+    res_hdr^.handles[res_hdr^.usedhandles]:=PtrUint(ptr);
+    inc(res_hdr^.usedhandles);
+    ptr^.ncounthandle:=res_hdr^.usedhandles;
   end;
   IntFindResourceEx:=ptr^.ncounthandle;
 end;
 
 Function IntLoadResource(ModuleHandle: TFPResourceHMODULE; ResHandle: TFPResourceHandle): TFPResourceHGLOBAL;
+var res_hdr: PResHdr;
 begin
   IntLoadResource:=0;
-  if ResHeader=nil then exit;
-  if (ResHandle<=0) or (ResHandle>ResHeader^.usedhandles) then exit;
-  IntLoadResource:=TFPResourceHGLOBAL(PResInfoNode(ResHeader^.handles[ResHandle-1])^.subptr);
+  res_hdr:=ExtGetResHdr(ModuleHandle);
+  if res_hdr=nil then exit;
+  if (ResHandle<=0) or (ResHandle>res_hdr^.usedhandles) then exit;
+  IntLoadResource:=TFPResourceHGLOBAL(PResInfoNode(res_hdr^.handles[ResHandle-1])^.subptr);
 end;
 
 Function IntSizeofResource(ModuleHandle: TFPResourceHMODULE; ResHandle: TFPResourceHandle): LongWord;
+var res_hdr: PResHdr;
 begin
   IntSizeofResource:=0;
-  if ResHeader=nil then exit;
-  if (ResHandle<=0) or (ResHandle>ResHeader^.usedhandles) then exit;
-  IntSizeofResource:=PResInfoNode(ResHeader^.handles[ResHandle-1])^.idcountsize;
+  res_hdr:=ExtGetResHdr(ModuleHandle);
+  if res_hdr=nil then exit;
+  if (ResHandle<=0) or (ResHandle>res_hdr^.usedhandles) then exit;
+  IntSizeofResource:=PResInfoNode(res_hdr^.handles[ResHandle-1])^.idcountsize;
 end;
 
 Function IntLockResource(ResData: TFPResourceHGLOBAL): Pointer;