[Lazarus] Extracting a resource from an exe file & adding it back in
Reinier Olislagers
reinierolislagers at gmail.com
Sun Oct 16 19:46:52 CEST 2011
On 15-10-2011 14:26, Reinier Olislagers wrote:
> Hi list,
>
> Therefore, I'm looking for a way to extract the compressed resource to a
> zip, extract the zip, let the user edit the file, zip it back up and add
> it back into the executable.
>
> 1. Can I load the exe into a stream and then copy that over to a
> TResourceStream? If so, I can do the extracting/editing.
> 2. I suppose I'd have to call windres.exe to extract the .rc file from
> the resource*) & compile the zipped resource back into the exe. Can I do
> that & overwrite the exiting resources in the exe?
Step 2: of course I could just compress the .rc file used for generating
the resource in the first place, and use that when recompiling the
resource ;)
I've had a look see and there is some (Delphi) code that uses the Win
API calls BeginUpdateResource/EndUpdateResource. I've copied it below.
I noticed jwawinbase.pas defines this as well as unifun.inc/ascfun.inc
Other options:
- use windres.exe but it will only extract resources as hex dumps. I'd
need to convert that (or do step 1)
- use another editor such as resedit (haven't tested that yet)
I'll fiddle around with these options unless somebody has a better
solution ;)
Source:
http://www.delphi3000.com/articles/article%5F3215.asp
This little snippet works great for small files, but for some currently
unknown reason it screws up the exe file when you try to add a large
resource on 1mb. If anyone know how to bypass this, please post a little
note on how to do this! :)
Uses Classes, Windows, SysUtils, Dialogs;
Type
TBuffer = Array[0..0] of Byte;
PBuffer = ^TBuffer;
Var
FS : TFileStream;
ResourceHandle : THandle;
DataLength : DWord;
Data : PBuffer;
Ok : Boolean;
Begin
ResourceHandle := BeginUpdateResource(pChar('d:\someexefile.exe'),
False);
IF (ResourceHandle <> 0) Then
Begin
FS := TFileStream.Create('d:\somebitmap.bmp', fmOpenRead);
FS.Seek(0, soFromBeginning);
DataLength := FS.Size;
GetMem(Data, DataLength);
FS.Read(Data^, DataLength);
FS.Free;
Ok := True;
//Passing nil (I suppose 0 in Delphi) as the lpData parameter will
cause the resource to be deleted.
IF (not UpdateResource(ResourceHandle, RT_RCDATA,
pChar('MyNewResource'), LANG_SYSTEM_DEFAULT{MakeLangID(LANG_NEUTRAL,
SUBLANG_NEUTRAL)}, Data, DataLength)) Then Ok := False;
IF (not EndUpdateResource(ResourceHandle, False)) Then Ok := False;
IF (Ok) Then ShowMessage('Update of resources successful!')
Else ShowMessage('Update of resources failed!');
FreeMem(Data);
End;
End.
More information about the Lazarus
mailing list