Нахождение строкового идентификатора ресурса
Где хранится идентификатор ресурса таблицы строк? Я могу перечислить строки в таблице, но не существует какого-либо идентификатора "необработанный ресурс", это просто (массив) USHORT (длина), за которым следуют широкие символы (строка), есть без идентификатора.
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;
Я прочитал ресурсную строку (тип) может быть приведен к PResStringRec
Whos .Identifier
поле даст идентификатор, но, я попробовал с моими "необработанными строками", и это случайное большое число (сравниваемые идентификаторы, которые дает resedit), какие-либо предложения о том, как найти идентификаторы?
2 ответа
В самой строковой таблице нет идентификаторов. Строковые ресурсы организованы в пакеты по 16. Строковый идентификатор на самом деле представляет собой 16-битное целое число, где старшие 12 бит идентифицируют индекс пакета в таблице, а младшие 4 бита идентифицируют индекс строки в пакете. Раймонд Чен обсуждает это в своем блоге MSDN:
Какой максимальный числовой идентификатор ресурса разрешен Win32?
Решено, где dwGroups - это число групп, dwGroup - индекс группы, содержащий строку, index - индекс строки (0..15) в группе.
Function MakeRtStringId(dwGroups, dwGroup, Index: DWORD): DWORD;
Var
dwIndex : DWORD;
Begin
dwIndex := 4096 - (dwGroups - dwGroup);
Result := (dwIndex shl 4) or Index;
End;
пожалуйста, отправьте альтернативные ответы, если вы придумали какие-либо.
[Править] серьезно, почему отрицательные голоса? Это потому что я не объясняю? Существует максимум 65535 строк, разделенных на группы по 16, что дает максимум 4096 групп. Строковые идентификаторы "начинаются" с 65535 и уменьшаются, поэтому, если у вас есть 15 строк, идентификаторы будут 65519, 65520, 65521, [...], 65535. и так далее, потому что последний идентификатор всегда 65535. Последняя цифра - это строка ее индекса в группе, потому что одна шестнадцатеричная цифра - 0-F (0-15). подсказки "группы по 16". спасибо Реми Лебо за информацию