delphiresourcesstring-table

Finding a stringtable resource ID


Where is a string-table resource ID stored? I am able to list the strings in a table but there doesn't appear to be any kind of identifier the "raw resource" it is just an (array of) USHORT (length) followed by wide chars (the string), there is no identifier.

PIMAGE_RESOURCE_DIR_STRING_U = ^TIMAGE_RESOURCE_DIR_STRING_U;
TIMAGE_RESOURCE_DIR_STRING_U = Record
  Count : USHORT;//Word;
  Name  : Array [0..0] of WideChar;
End;

PIMAGE_RESOURCE_DATA =^TIMAGE_RESOURCE_DATA;
TIMAGE_RESOURCE_DATA = Record
  rt_type :  DWORD; //RT_STRING
  lpName  :  ShortString; //tables name
  Address :  PDWORD; //address of the table
  dwSize  :  DWORD; //size of the data
end;

procedure GUIDataToString(IRD: TIMAGE_RESOURCE_DATA);
Type
  TStringArray = Array of String;


  Function SplitString(P: PByte; dwplen: Int32): TStringArray;
  //P is a Pointer to the string table, dwPLen is the size of the table
  Var
    Index : Int32;
    offset: Int32;
    dwLen : WORD;
    ST_ID : NativeUInt;
    rt_str: PIMAGE_RESOURCE_DIR_STRING_U;
  Begin
    Index := 0; //String Index
    offset:= 0;
    while (offset <= dwplen) do
    Begin
      SetLength(Result, Length(Result)+1);

      rt_str        := PIMAGE_RESOURCE_DIR_STRING_U(@P[offset]);
      Result[Index] := NameToStr(rt_str);
      //
      Inc(offset, (rt_str.Count * sizeof(WideChar) )+ sizeof(WORD));
      Inc(Index);
    End;
  End;

Var
  Table     : TStringArray;
  dwStrings : DWORD;
  I         : Int32;
  //d         :
begin
  Table   := SplitString(PByte(IRD.Address), IRD.dwSize);
  dwStrings := Length(Table);
  Memo1.Lines.Add('STRINGTABLE');
  Memo1.Lines.Add('{');

  for I := 0 to dwStrings-1 do
  Begin
    Memo1.Lines.Add(#9+Table[I]); //#9 is TAB
  End;
   Memo1.Lines.Add('}');
end;

I read resourcestring(type) can be cast to a PResStringRec whos .Identifier field will give an identifier but, I tried with my "raw strings" and it's a random large number (compared IDs resedit gives), any suggestions on how to find the IDs?

image


Solution

  • There are no IDs stored in the stringtable itself. String resources are organized in bundles of 16. A string ID is actually a 16bit integer where the high 12 bits identify the index of the bundle within the table, and the low 4 bits identify the index of the string within the bundle. Raymond Chen discusses this on his MSDN blog:

    The format of string resources

    What is the highest numerical resource ID permitted by Win32?