madRes - Editing String Tables

delphi package - madRes, madTools, madStrings, ...
Post Reply
Sigma
Posts: 7
Joined: Thu May 27, 2004 3:00 pm

madRes - Editing String Tables

Post by Sigma »

Hi,
I need to edit/change a value of a string in a string table,
but i couldn't figure i out.
I don't know how to specify a index of a string table.

this is what Resource Hacker looks like, when opening the string table

Code: Select all

  + String Table
  -- 1
     -- 1041

STRINGTABLE
LANGUAGE LANG_JAPANESE, 0x1
{
1, 	"SIGMAREC"
2, 	"SIGMA222"
}

any help, sample code will be very helpful



sorry for my sloppy english...
Sigma
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

I'm sorry to say but I don't know how string tables work internally. Maybe someone else can help out here.
Sigma
Posts: 7
Joined: Thu May 27, 2004 3:00 pm

Post by Sigma »

OK i'll wait, thanks for your fast reply.
this resource thing is really important for me.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Perhaps you can find something here:

http://www.wilsonc.demon.co.uk/delphi.htm
Sigma
Posts: 7
Joined: Thu May 27, 2004 3:00 pm

Post by Sigma »

good .. but i need the code more smaller
and i don't want it to have huge .pas files on the "uses"
because i'm trying to make my app small. using KOL too.
may i'll have to re-write it. But i'm not good in Delphi :sorry:
Sigma
Posts: 7
Joined: Thu May 27, 2004 3:00 pm

Post by Sigma »

This is how far i got to.

Code: Select all

function MAKELANGID(sPrimaryLanguage : Word;
                    sSubLanguage : Word) : Word;
begin
  result := (sSubLanguage shl 10) or
             sPrimaryLanguage;

end;


procedure WriteStr(exeFullPath:PWideChar; ResName: integer; S:String);
var update : dword;
  s2:WideChar;
begin
StringtoWideChar(s, @s2, sizeof(s));

  update := BeginUpdateResourceW(exeFullPath, false);
  if update <> 0 then
    try
      UpdateResourceW(update, PWideChar(RT_STRING), MAKEINTRESOURCEW(ResName), MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT ),  @s2,sizeof(s2));
    finally
      EndUpdateResourceW(update, false);
    end;
end;

procedure TForm1.Button1Click(Sender: PObj);
begin

WriteStr('C:\abc.exe',1,'abcdefghijklmno');
end;

It makes a correct section, but it doesn't write any data....

Code: Select all

STRINGTABLE
LANGUAGE LANG_JAPANESE, 0x1
{
}

any help appreciated.
Sigma
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Do not use "@strVar". That gives you the address of where the string variable itself is stored. Instead use "pointer(strVar)" or "@strVar[1]".
Sigma
Posts: 7
Joined: Thu May 27, 2004 3:00 pm

Post by Sigma »

If i do that, it doesn't even make the string SECTION... :(
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Don't use "sizeof(strVar)". A Delphi dynamic string is a kind of pointer, so "sizeof" always returns 4. Instead you need to use "Length(strVar)".
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

I'd try this:

Code: Select all

function MAKELANGID(sPrimaryLanguage : Word;
                    sSubLanguage : Word) : Word;
begin
  result := (sSubLanguage shl 10) or
             sPrimaryLanguage;
end;

procedure WriteStr(exeFullPath:PWideChar; ResName: integer; S:String);
var update : dword;
begin
  update := BeginUpdateResourceW(exeFullPath, false);
  if update <> 0 then
    try
      UpdateResourceW(update, PWideChar(RT_STRING), MAKEINTRESOURCEW(ResName), MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT ),  pointer(S),Length(S) + 1);
    finally
      EndUpdateResourceW(update, false);
    end;
end;

procedure TForm1.Button1Click(Sender: PObj);
begin

WriteStr('C:\abc.exe',1,'abcdefghijklmno');
end;
Or if that string has to be in wide format, do this:

Code: Select all

      UpdateResourceW(update, PWideChar(RT_STRING), MAKEINTRESOURCEW(ResName), MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT ),  PWideChar(wideString(S)),(Length(S) + 1) * 2);
But this all works only if the string table is just stored as some characters. But I guess that it has a specific format and probably some kind of header. I've no idea. As I said, I don't know how a string table looks like internally.
Sigma
Posts: 7
Joined: Thu May 27, 2004 3:00 pm

Post by Sigma »

the code doesn't work either wide string or not.
BUT the second code works !

Code: Select all

UpdateResourceW(update, PWideChar(RT_STRING), MAKEINTRESOURCEW(ResName), MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT ),  PWideChar(wideString(S)),(Length(S) + 1) * 2);
thanks very much.
BUT I STILL HAVE 2 PROBLEMS LEFT.

1. the first letter (S[0]) isn't written to the string table.
ex) WriteStr('C:\abc.exe',1,'abcdefghijklmno');
writes 0, "bcdefghijklmno"

2. I can't specify wich index to write to.
if i use your code, the string tabel starts from "0".
but when i changed "Length(S) + 1) * 2);" to "Length(S) + 1) * 2 +100);"
and wrote a larger string, it made index "1" too. may be a hint?
ex)
0, "2345678901234567890123456789012345678901234567890"
1, "2345678901234567890123456789012345678901234567890"

it doesn't write "1" due to problem #1


thanks anyway, if you can't figure it out, don't mind.
you've helped me alot.

thanks,
Sigma
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

If the first letter is missing, probably the string stable has a 2 byte header. Maybe the index of the string table must come before the string. Or maybe the length must come before the string data. strVar[0] does not exist!! The first characters is strVar[1].
Sigma
Posts: 7
Joined: Thu May 27, 2004 3:00 pm

Post by Sigma »

nah... doesn't work...
_pusher_
Posts: 5
Joined: Wed Apr 28, 2004 3:26 pm

Post by _pusher_ »

very nice, its almost the same function iam looking for..
how do i update Dialog box.. its a .rc dialog
i almost made it.. but its messed up

here is the functions i used:

function MAKELANGID(sPrimaryLanguage : Word;
sSubLanguage : Word) : Word;
begin
result := (sSubLanguage shl 10) or
sPrimaryLanguage;

end;

procedure WriteStr(exeFullPath:PWideChar; ResName: integer; S:String);
var update : dword;
begin
update := MadRes.BeginUpdateResourceW(exeFullPath, false);
if update <> 0 then
try
MadRes.UpdateResourceW( update, PWideChar(RT_DIALOG),
MAKEINTRESOURCEW(ResName),
MAKELANGID(SUBLANG_NEUTRAL,SUBLANG_DEFAULT ),

pointer(S),Length(S) + 1);
finally
MadRes.EndUpdateResourceW(update, false);
end;
end;
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Guys, I think you simply need to find out how the data is structured. madRes only does the basic work. It's your task to make sure that the data you put into the resources has the correct format. Sorry to say, but I can't help you with that (not enough time).
Post Reply