param_sfo_info

This commit is contained in:
Pavel 2022-12-21 13:33:40 +03:00
parent 5760dfc059
commit f243cfcfd5
2 changed files with 262 additions and 0 deletions

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<Flags>
<SaveClosedFiles Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
<MainUnitHasScaledStatement Value="False"/>
<SaveJumpHistory Value="False"/>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<Title Value="param_sfo_info"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<Units Count="1">
<Unit0>
<Filename Value="param_sfo_info.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="param_sfo_info"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2"/>
</Debugging>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,193 @@
uses
{$IFDEF Linux}
cmem,
cthreads,
{$ENDIF}
Classes,
sysutils;
const
//sfo_value_format
SFO_FORMAT_STRING_SPECIAL=$004;
SFO_FORMAT_STRING =$204;
SFO_FORMAT_UINT32 =$404;
SFO_MAGIC=$46535000;
SFO_HEADER_SIZE =$14;
SFO_TABLE_ENTRY_SIZE=$10;
type
t_sfo_header=packed record
magic :DWORD;
version :DWORD;
key_table_offset :DWORD;
value_table_offset:DWORD;
entry_count :DWORD;
end;
p_sfo_table_entry=^t_sfo_table_entry;
t_sfo_table_entry=packed record
key_offset :WORD; //<-key_table
format :WORD;
size :DWORD;
max_size :DWORD;
value_offset:DWORD; //<-value_table
end;
function get_str_format(format:WORD):RawByteString;
begin
Case format of
SFO_FORMAT_STRING_SPECIAL:Result:='STRING_SPECIAL';
SFO_FORMAT_STRING :Result:='STRING';
SFO_FORMAT_UINT32 :Result:='UINT32';
else
Result:='0x'+HexStr(format,4);
end;
end;
function LoadParamSfoFile(Const name:RawByteString):Boolean;
Var
F:THandle;
fsize:Int64;
i:DWORD;
key_table_size :DWORD;
value_table_size:DWORD;
hdr:t_sfo_header;
entry_table:p_sfo_table_entry;
key_table:PChar;
value_table:PByte;
function load_chunk(offset,size:DWORD):Pointer;
begin
Result:=AllocMem(size);
FileSeek(F,offset,fsFromBeginning);
FileRead(F,Result^,size);
end;
begin
Result:=False;
if (name='') then Exit;
F:=FileOpen(name,fmOpenRead or fmShareDenyNone);
if (F=feInvalidHandle) then
begin
Writeln('Error open file:',name);
Exit;
end;
hdr:=Default(t_sfo_header);
FileRead(F,hdr,SizeOf(hdr));
Writeln('magic :0x',HexStr(hdr.magic,8));
if (hdr.magic<>SFO_MAGIC) then
begin
Writeln('Invalid sfo file:',name);
FileClose(F);
Exit;
end;
Writeln('version :0x',HexStr(hdr.version,8));
Writeln('key_table_offset :',hdr.key_table_offset);
Writeln('value_table_offset :',hdr.value_table_offset);
Writeln('entry_count :',hdr.entry_count);
entry_table:=load_chunk(SizeOf(hdr),hdr.entry_count*SizeOf(t_sfo_table_entry));
fsize:=FileSeek(F,0,fsFromEnd);
if (hdr.key_table_offset>hdr.value_table_offset) then
begin
key_table_size :=fsize -hdr.key_table_offset;
value_table_size:=hdr.key_table_offset-hdr.value_table_offset;
end else
begin
key_table_size :=hdr.value_table_offset-hdr.key_table_offset;
value_table_size:=fsize -hdr.value_table_offset;
end;
key_table :=load_chunk(hdr.key_table_offset ,key_table_size);
value_table:=load_chunk(hdr.value_table_offset,value_table_size);
if (hdr.entry_count<>0) then
begin
For i:=0 to hdr.entry_count-1 do
begin
Writeln('[entry]:',i);
//Writeln('key_offset :',entry_table[i].key_offset);
Writeln('format :',get_str_format(entry_table[i].format));
//Writeln('size :',entry_table[i].size);
//Writeln('max_size :',entry_table[i].max_size);
//Writeln('value_offset:',entry_table[i].value_offset);
Writeln('key :',PChar(key_table+entry_table[i].key_offset));
Case entry_table[i].format of
SFO_FORMAT_STRING_SPECIAL,
SFO_FORMAT_STRING :
begin
Writeln('value :',PChar(value_table+entry_table[i].value_offset));
end;
SFO_FORMAT_UINT32 :
begin
Writeln('value :0x',HexStr(PQWORD(value_table+entry_table[i].value_offset)^,entry_table[i].max_size*2));
end;
else;
end;
end;
end;
FileClose(F);
end;
var
i,n:Integer;
label
promo;
begin
DefaultSystemCodePage:=CP_UTF8;
DefaultUnicodeCodePage:=CP_UTF8;
DefaultFileSystemCodePage:=CP_UTF8;
DefaultRTLFileSystemCodePage:=CP_UTF8;
UTF8CompareLocale:=CP_UTF8;
if (ParamCount=0) then
begin
promo:
Writeln('Tool for print param.sfo data');
Writeln(' Parameters:');
Writeln(' -i <name> //file name to load param.sfo');
Exit;
end;
n:=-1;
For i:=1 to ParamCount do
begin
case LowerCase(ParamStr(i)) of
'-i':n:=0;
else
if (n<>-1) then
begin
Case n of
0:LoadParamSfoFile(ParamStr(i));
end;
n:=-1;
end;
end;
end;
writeln;
end.