UpdateResource

Hello,
I have a question on How to use UpdateResource on a DLL File...

The DLL File contains a section which name is IMAGES inside of this section there a a few images names are 5031, 5032 and so on... Type is JPEG

So I wonder how to use UpdateResource to update e.g. 5031 with a JPEG of my choice?
I think while UpdateResource asked me for a Restype I can not simple use it here?

kindest regards
s!
LVL 1
stOrMAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CodedKSenior Software EngineerCommented:
Hi Storm.

Check this:
http://help.madshi.net/madResUnit.htm

Its very straight forward.
Hope this helps.
CodedKSenior Software EngineerCommented:
Also another unit for easy editing the resources is :

Unit Resources by Russell...
See this PAQ:
http:\\www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_23134070.html
dougaugCommented:
You can try the code below. Since there isn't a JPEG Resource type, I've tested using RCDATA (raw data).

var
  ResLanguage: Word;

function EnumResLangProc(hModule: HMODULE; lpType, lpName: PChar; wIDLanguage: Word;
  lParam: Longint): BOOL; stdcall;
begin
  ResLanguage := wIDLanguage;
  Result := False;
end;

procedure UpdateJPEGResource(const ModulePath, JPEGName, ResourceName: string);
var
  hModule, hUpdate: THandle;
  fs: TFileStream;
  Data: Pointer;
begin
  Data := nil;

  hModule := LoadLibrary(PChar(ModulePath));
  try
    if hModule = 0 then
      RaiseLastOSError;

    EnumResourceLanguages(hModule, RT_RCDATA, PChar(ResourceName), @EnumResLangProc, 0);
  finally
    FreeLibrary(hModule);
  end;

  hUpdate := BeginUpdateResource(PChar(ModulePath), False);

  try
    if hUpdate = 0 then
      RaiseLastOSError;

    fs := TFileStream.Create(JPEGName, fmOpenRead);

    Data := AllocMem(fs.Size);
    fs.Read(Data^, fs.Size);

    if not UpdateResource(hUpdate, RT_RCDATA, PChar(ResourceName), ResLanguage, Data, fs.Size) then
      RaiseLastOSError;

    if not EndUpdateResource(hUpdate, False) then
      RaiseLastOSError;
  finally
    if Data <> nil then
      FreeMem(Data);

    FreeAndNil(fs);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  UpdateJPEGResource('c:\temp\project1.dll', 'c:\temp\image.jpeg', '5031');
end;
Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

stOrMAuthor Commented:
dougaug:
Well your code does not work at all because instead of updating the 5031 image in the IMAGES section it adds a new section which isnt what i was searching for :-(

just to make it clear again
the DLL file i'm trying to update contains an IMAGES Section inside of this section it Contains JPEG images where for e.g. the first Image had a name of 5031 while the second one had 5032 and so on...

Now I want to load a JPEG image from my HDD and update e.g. the 5031 Image inside of the DLL with my new one, instead of adding a new section to the dll that wont help...

Btw.
The JPEG's inside of the DLL had Language LANG_ENGLISH, SUBLANG_ENGLISH_US if that is important to know too...?!

kindest regards
s!
stOrMAuthor Commented:
BTW. dougaug When I change your code like this:

 UpdateResource(hUpdate, 'IMAGE', PChar(ResourceName), ResLanguage, Data, fs.Size)  

instead of:
 UpdateResource(hUpdate, RT_RCDATA, PChar(ResourceName), ResLanguage, Data, fs.Size)

The New JPEG is added to the IMAGE section of the DLL which is mostly correct but the old 5031 JPEG remains too so I have both now which is also wrong :-(
dougaugCommented:
Try to change the following line too:

    EnumResourceLanguages(hModule, 'IMAGE', PChar(ResourceName), @EnumResLangProc, 0);
stOrMAuthor Commented:
dougaug:
Try to change the following line too:

    EnumResourceLanguages(hModule, 'IMAGE', PChar(ResourceName), @EnumResLangProc, 0);

I did with the result that I still have two 5031 resources now instead of one...
Maybe you can try yourself too? Make a copy of your ImageRes.dll from System32 there you find that stuff inside I'm trying to update.

Still another problem is that the new JPEG Image Language is set to Neutral instead of English, can be a problem later which I'm not sure about yet.

kindest regards
s!
dougaugCommented:
Have you done the last test with the updated dll or original?

You should test with the original version (that has only the resource with english language).

Try to delete the added resource using a program like resource hacker.
stOrMAuthor Commented:
dougaug:
I did the test with both versions the updated and the original one both with the same result of having 2 resources called 5031 inside of the dll now :-(
dougaugCommented:
stOrm

Try the code below. I've made some changes and for me it worked fine.

var
  ResLanguage: Word;

function EnumResLangProc(hModule: HMODULE; lpType, lpName: PChar; wIDLanguage: Word;
  lParam: Longint): BOOL; stdcall;
begin
  ResLanguage := wIDLanguage;
  Result := False;
end;

function Is_INTResource(ResID: Integer): Boolean;
var
  i: Integer;
begin
  i := ResID shr 16;
  Result := i = 0;
end;

procedure UpdateJPEGResource(const ModulePath, JPEGName: string; ResourceType, ResourceName: PChar);
var
  hModule, hUpdate: THandle;
  fs: TFileStream;
  Data: Pointer;
begin
  Data := nil;

  hModule := LoadLibrary(PChar(ModulePath));
  try
    if hModule = 0 then
      RaiseLastOSError;

    if Is_INTResource(Integer(ResourceName)) then
      ResourceName := PChar(MakeIntResourceA(ResourceName));

    EnumResourceLanguages(hModule, ResourceType, Pchar(ResourceName), @EnumResLangProc, 0);
  finally
    FreeLibrary(hModule);
  end;

  hUpdate := BeginUpdateResource(PChar(ModulePath), False);

  try
    if hUpdate = 0 then
      RaiseLastOSError;

    fs := TFileStream.Create(JPEGName, fmOpenRead);

    Data := AllocMem(fs.Size);
    fs.Read(Data^, fs.Size);

    if not UpdateResource(hUpdate, ResourceType, Pchar(ResourceName), ResLanguage, Data, fs.Size) then
      RaiseLastOSError;

    if not EndUpdateResource(hUpdate, False) then
      RaiseLastOSError;
  finally
    if Data <> nil then
      FreeMem(Data);

    FreeAndNil(fs);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  UpdateJPEGResource('c:\temp\imageres.dll', 'c:\temp\image.jpg', 'IMAGE', PChar(5031));
end;

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
stOrMAuthor Commented:
dougaug: Perfect job!
Thank you very very much!

kindest regards
s!

BTW. would you mind a short question to your code?
Will this all work also with other image types like png and so on? That would be cool :-P
dougaugCommented:
I haven't tested with PNG. With bitmap you should add the resource excluding the "header's bytes" of the image.

To see what I'm saying, follow this link:
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_24578934.html
stOrMAuthor Commented:
dougaug:
Ah ok I understand!
Thank you for your help it was really useful!

kindest regards
s!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.