From 415e6b952672f1aca3bf1cbb1d55659661aeaf3b Mon Sep 17 00:00:00 2001
From: Pavel <68122101+red-prig@users.noreply.github.com>
Date: Tue, 8 Aug 2023 16:52:07 +0300
Subject: [PATCH] +
---
sys/kern/kern_dlsym.pas | 42 ++
sys/kern/kern_dynlib.pas | 4 +-
sys/kern/kern_rtld.pas | 2 +
sys/kern/subr_dynlib.pas | 303 ++++++++++-
sys/kern/trap.pas | 9 +-
sys/test/project1.lpi | 5 +
sys/test/project1.lpr | 5 +-
sys/test/ps4_libscedialogs.pas | 719 +++++++++++++++++++++++++++
sys/test/ps4_libsceipmi.pas | 29 ++
sys/test/ps4_libscesystemservice.pas | 474 ++++++++++++++++++
10 files changed, 1585 insertions(+), 7 deletions(-)
create mode 100644 sys/test/ps4_libscedialogs.pas
create mode 100644 sys/test/ps4_libsceipmi.pas
create mode 100644 sys/test/ps4_libscesystemservice.pas
diff --git a/sys/kern/kern_dlsym.pas b/sys/kern/kern_dlsym.pas
index 7463924f..a060823a 100644
--- a/sys/kern/kern_dlsym.pas
+++ b/sys/kern/kern_dlsym.pas
@@ -32,6 +32,7 @@ type
end;
function do_dlsym(obj:p_lib_info;symbol,libname:pchar;flags:DWORD):Pointer;
+function name_dlsym(name,symbol:pchar;addrp:ppointer):Integer;
function find_symdef(symnum:QWORD;
refobj:p_lib_info;
var defobj_out:p_lib_info;
@@ -44,6 +45,7 @@ implementation
uses
hamt,
errno,
+ systm,
elf_nid_utils,
kern_stub,
vm_patch_link,
@@ -349,6 +351,46 @@ begin
end;
end;
+function name_dlsym(name,symbol:pchar;addrp:ppointer):Integer;
+label
+ _exit;
+var
+ obj:p_lib_info;
+ flags:Integer;
+ ptr:Pointer;
+
+ fname:array[0..31] of char;
+ fsymb:array[0..2560-1] of char;
+begin
+ Result:=copyinstr(name,@fname,sizeof(fname),nil);
+ if (Result<>0) then Exit;
+
+ Result:=copyinstr(symbol,@fsymb,sizeof(fsymb),nil);
+ if (Result<>0) then Exit;
+
+ dynlibs_lock;
+
+ obj:=find_obj_by_name(@fname);
+ if (obj=nil) then
+ begin
+ Result:=ESRCH;
+ goto _exit;
+ end;
+
+ ptr:=do_dlsym(obj,@fsymb,nil,0);
+
+ if (ptr=nil) then
+ begin
+ Result:=ESRCH;
+ goto _exit;
+ end;
+
+ Result:=copyout(@ptr,addrp,SizeOf(Pointer));
+
+ _exit:
+ dynlibs_unlock;
+end;
+
//48 8D 3D 00 00 00 00 lea rdi,[rip+$00000000] lea (%rip),%rdi
type
diff --git a/sys/kern/kern_dynlib.pas b/sys/kern/kern_dynlib.pas
index b0fe36d4..9c16bb1a 100644
--- a/sys/kern/kern_dynlib.pas
+++ b/sys/kern/kern_dynlib.pas
@@ -114,7 +114,6 @@ var
flags:Integer;
ptr:Pointer;
- len:ptruint;
fsym:array[0..2560-1] of char;
begin
if not_dynamic then
@@ -123,8 +122,7 @@ begin
Exit(EPERM);
end;
- len:=0;
- Result:=copyinstr(symbol,@fsym,sizeof(fsym),@len);
+ Result:=copyinstr(symbol,@fsym,sizeof(fsym),nil);
if (Result<>0) then Exit;
dynlibs_lock;
diff --git a/sys/kern/kern_rtld.pas b/sys/kern/kern_rtld.pas
index 2e3244f2..bbb4ba90 100644
--- a/sys/kern/kern_rtld.pas
+++ b/sys/kern/kern_rtld.pas
@@ -1159,6 +1159,8 @@ var
idx:pchar;
chr:char;
begin
+ if (path=nil) then Exit(nil);
+
chr:=get_char_sep(path);
idx:=strrscan(path,chr);
diff --git a/sys/kern/subr_dynlib.pas b/sys/kern/subr_dynlib.pas
index b57a1dab..5e7613d2 100644
--- a/sys/kern/subr_dynlib.pas
+++ b/sys/kern/subr_dynlib.pas
@@ -16,6 +16,15 @@ uses
kern_sx;
type
+ TLIBRARY=object
+ lib:Pointer;
+ function set_symb(nid:QWORD;info:Byte;value:Pointer):Boolean;
+ function set_proc(nid:QWORD;value:Pointer):Boolean;
+ function set_data(nid:QWORD;value:Pointer):Boolean;
+ function set_weak(nid:QWORD;value:Pointer):Boolean;
+ function get_value(nid:QWORD):Pointer;
+ end;
+
p_rel_data=^t_rel_data;
t_rel_data=record
obj :Pointer;
@@ -120,6 +129,7 @@ type
is_system :Byte;
dag_inited :Byte;
jmpslots_done:Byte;
+ internal :Byte;
dldags :TAILQ_HEAD; //Objlist_Entry
dagmembers:TAILQ_HEAD; //Objlist_Entry
@@ -131,6 +141,11 @@ type
fingerprint:array[0..19] of Byte;
module_param:pSceModuleParam;
+
+ procedure init_rel_data;
+ function add_str(str:pchar):QWORD;
+ function add_lib(lib_name:pchar):TLIBRARY;
+ procedure add_mod(mod_name:pchar);
end;
p_Objlist_Entry=^Objlist_Entry;
@@ -220,10 +235,26 @@ type
dyn_non_exist:Integer;
end;
+const
+ IF_PRELOAD =1;
+ IF_POSTLOAD=2;
+
+type
+ t_int_load=function(name:pchar):p_lib_info;
+
+ p_int_file=^t_int_file;
+ t_int_file=record
+ link:SLIST_ENTRY;
+ name:pchar;
+ icbs:t_int_load;
+ flag:ptruint;
+ end;
+
procedure dynlibs_lock;
procedure dynlibs_unlock;
function obj_new():p_lib_info;
+function obj_new_int(mod_name:pchar):p_lib_info;
procedure obj_free(obj:p_lib_info);
procedure objlist_push_tail(var list:TAILQ_HEAD;obj:p_lib_info);
@@ -305,12 +336,17 @@ function free_obj_id (id:Integer):Boolean;
function find_obj_id (id:Integer):p_lib_info;
function find_obj_by_handle(id:Integer):p_lib_info;
+function find_obj_by_name (name:pchar):p_lib_info;
function dynlib_load_needed_shared_objects():Integer;
var
dynlibs_info:t_dynlibs_info;
+ dynlibs_intf:SLIST_HEAD=(slh_first:nil);
+
+Procedure reg_int_file(var stub:t_int_file;name:pchar;icbs:t_int_load;flag:ptruint=IF_PRELOAD);
+
implementation
uses
@@ -344,6 +380,170 @@ begin
sx_xunlock(@dynlibs_info.lock);
end;
+Procedure reg_int_file(var stub:t_int_file;name:pchar;icbs:t_int_load;flag:ptruint=IF_PRELOAD);
+begin
+ stub.name:=name;
+ stub.icbs:=icbs;
+ stub.flag:=flag;
+ //
+ SLIST_INSERT_HEAD(@dynlibs_intf,@stub,@stub.link);
+end;
+
+procedure t_lib_info.init_rel_data;
+begin
+ if (rel_data=nil) then
+ begin
+ rel_data:=AllocMem(SizeOf(t_rel_data));
+ end;
+end;
+
+function t_lib_info.add_str(str:pchar):QWORD;
+var
+ len,size:QWORD;
+begin
+ init_rel_data;
+
+ len:=strlen(str)+1;
+ size:=rel_data^.strtab_size;
+
+ rel_data^.strtab_addr:=ReAllocMem(rel_data^.strtab_addr,size+len);
+
+ Result:=size;
+
+ Move(str^,rel_data^.strtab_addr[size],len);
+
+ rel_data^.strtab_size:=size+len;
+end;
+
+function t_lib_info.add_lib(lib_name:pchar):TLIBRARY;
+label
+ rep;
+var
+ lib_entry:p_Lib_Entry;
+ v:TLibraryValue;
+begin
+ Result.lib:=nil;
+
+ v:=Default(TLibraryValue);
+
+ rep:
+ lib_entry:=TAILQ_FIRST(@lib_table);
+ while (lib_entry<>nil) do
+ begin
+ if (lib_entry^.dval.id=v.id) then
+ begin
+ Inc(v.id);
+ goto rep;
+ end;
+ lib_entry:=TAILQ_NEXT(lib_entry,@lib_entry^.link)
+ end;
+
+ lib_entry:=Lib_Entry_new(QWORD(v),0);
+ lib_entry^.dval.name_offset:=add_str(lib_name);
+
+ TAILQ_INSERT_TAIL(@lib_table,lib_entry,@lib_entry^.link);
+
+ Result.lib:=lib_entry;
+end;
+
+procedure t_lib_info.add_mod(mod_name:pchar);
+label
+ rep;
+var
+ mod_entry:p_Lib_Entry;
+ v:TLibraryValue;
+begin
+ v:=Default(TLibraryValue);
+
+ rep:
+ mod_entry:=TAILQ_FIRST(@mod_table);
+ while (mod_entry<>nil) do
+ begin
+ if (mod_entry^.dval.id=v.id) then
+ begin
+ Inc(v.id);
+ goto rep;
+ end;
+ mod_entry:=TAILQ_NEXT(mod_entry,@mod_entry^.link)
+ end;
+
+ mod_entry:=Lib_Entry_new(QWORD(v),0);
+ mod_entry^.dval.name_offset:=add_str(mod_name);
+
+ TAILQ_INSERT_TAIL(@mod_table,mod_entry,@mod_entry^.link);
+end;
+
+function TLIBRARY.set_symb(nid:QWORD;info:Byte;value:Pointer):Boolean;
+var
+ lib_entry:p_Lib_Entry;
+ h_entry:p_sym_hash_entry;
+ data:PPointer;
+begin
+ lib_entry:=lib;
+ //
+ h_entry:=AllocMem(SizeOf(t_sym_hash_entry));
+ //
+ h_entry^.nid :=nid;
+ h_entry^.mod_id:=0; //export
+ h_entry^.lib_id:=lib_entry^.dval.id;
+ //
+ h_entry^.sym.st_info :=info;
+ h_entry^.sym.st_value:=Elf64_Addr(value);
+
+ //
+ if (Lib_Entry^.hamt=nil) then
+ begin
+ Lib_Entry^.hamt:=HAMT_create64;
+ TAILQ_INIT(@Lib_Entry^.syms);
+ end;
+ //
+ data:=HAMT_insert64(Lib_Entry^.hamt,nid,h_entry);
+ if (data=nil) then Exit(False); //NOMEM
+ //
+ if (data^<>h_entry) then
+ begin
+ //is another exists
+ FreeMem(h_entry);
+ Result:=False;
+ end else
+ begin
+ //new
+ TAILQ_INSERT_TAIL(@Lib_Entry^.syms,h_entry,@h_entry^.link);
+ Result:=True;
+ end;
+end;
+
+function TLIBRARY.set_proc(nid:QWORD;value:Pointer):Boolean;
+begin
+ Result:=set_symb(nid,(STB_GLOBAL shl 4) or STT_FUN,value);
+end;
+
+function TLIBRARY.set_data(nid:QWORD;value:Pointer):Boolean;
+begin
+ Result:=set_symb(nid,(STB_GLOBAL shl 4) or STT_OBJECT,value);
+end;
+
+function TLIBRARY.set_weak(nid:QWORD;value:Pointer):Boolean;
+begin
+ Result:=set_symb(nid,(STB_WEAK shl 4) or STT_FUN,value);
+end;
+
+function TLIBRARY.get_value(nid:QWORD):Pointer;
+var
+ lib_entry:p_Lib_Entry;
+ h_entry:p_sym_hash_entry;
+ data:PPointer;
+begin
+ lib_entry:=lib;
+ //
+ if (Lib_Entry^.hamt=nil) then Exit(nil);
+ data:=HAMT_search64(Lib_Entry^.hamt,nid);
+ if (data=nil) then Exit(nil);
+ h_entry:=data^;
+ if (h_entry=nil) then Exit(nil);
+ Result:=Pointer(h_entry^.sym.st_value);
+end;
+
function obj_new():p_lib_info;
begin
Result:=AllocMem(SizeOf(t_lib_info));
@@ -362,6 +562,13 @@ begin
//*puVar1:=*puVar1 | 2;
end;
+function obj_new_int(mod_name:pchar):p_lib_info;
+begin
+ Result:=obj_new();
+ Result^.internal:=1;
+ Result^.add_mod(mod_name);
+end;
+
function preprocess_dt_entries(new:p_lib_info;hdr_e_type:Integer):Integer;
label
_unsupp;
@@ -2344,6 +2551,7 @@ begin
init_relo_bits(new);
init_sym_hash(new);
dynlibs_add_obj(new);
+
new^.loaded:=1;
Exit(new);
@@ -2417,6 +2625,65 @@ begin
end;
+const
+ internal_module_param:TsceModuleParam=(
+ Size :SizeOf(TsceModuleParam);
+ Magic :$23C13F4BF;
+ SDK_version:$010010001;
+ );
+
+function preload_prx_internal(name:pchar;flag:ptruint):p_lib_info;
+var
+ entry:p_int_file;
+ path:pchar;
+begin
+ Result:=nil;
+
+ entry:=SLIST_FIRST(@dynlibs_intf);
+ while (entry<>nil) do
+ begin
+ if ((entry^.flag and flag)<>0) then
+ if (entry^.icbs<>nil) then
+ if (StrComp(name,entry^.name)=0) then
+ begin
+ Result:=entry^.icbs(entry^.name);
+ if (Result<>nil) then
+ begin
+
+ //fix module_param
+ if (Result^.module_param=nil) then
+ begin
+ Result^.module_param:=@internal_module_param;
+ end;
+
+ //fix name
+ path:=dynlib_basename(Result^.lib_path);
+ if (path=nil) then
+ begin
+ path:=entry^.name;
+ end;
+
+ //reg name
+ obj_set_lib_path(Result,path);
+ object_add_name(Result,dynlib_basename(Result^.lib_path));
+
+ ///Result^.lib_dirname neded???
+
+ //reg lib
+ dynlibs_add_obj(Result);
+ //
+ Result^.internal:=1;
+ Result^.loaded:=1;
+
+ //
+ Exit;
+ end;
+ end;
+ entry:=SLIST_NEXT(entry,@entry^.link);
+ end;
+
+end;
+
function preload_prx_modules(path:pchar;flags:DWORD;var err:Integer):p_lib_info;
label
_do_load;
@@ -2440,6 +2707,13 @@ begin
obj:=TAILQ_NEXT(obj,@obj^.link);
end;
+ //try internal preload
+ fname:=pbase;
+ fname:=ChangeFileExt(fname,'.prx');
+
+ Result:=preload_prx_internal(pchar(fname),IF_PRELOAD);
+ if (Result<>nil) then Exit;
+
//try original
fname:=path;
@@ -2469,6 +2743,13 @@ begin
fname:=ChangeFileExt(fname,'.prx');
if rtld_file_exists(pchar(fname)) then goto _do_load;
+ //try internal postload
+ fname:=pbase;
+ fname:=ChangeFileExt(fname,'.prx');
+
+ Result:=preload_prx_internal(pchar(fname),IF_POSTLOAD);
+ if (Result<>nil) then Exit;
+
Writeln(StdErr,' prx_module_not_found:',dynlib_basename(path));
err:=ENOENT;
@@ -2669,7 +2950,7 @@ begin
obj^.desc.free:=nil;
obj^.objt:=NAMED_DYNL;
- obj^.name:='';
+ obj^.name:=dynlib_basename(obj^.lib_path);
key:=-1;
if id_name_new(@named_table,obj,@key) then
@@ -2720,6 +3001,26 @@ begin
end;
end;
+function find_obj_by_name(name:pchar):p_lib_info;
+var
+ obj:p_lib_info;
+ str:pchar;
+begin
+ Result:=nil;
+
+ obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
+ while (obj<>nil) do
+ begin
+ str:=get_mod_name_by_id(obj,0);
+ if (StrComp(str,name)=0) then
+ begin
+ Exit(obj);
+ end;
+ //
+ obj:=TAILQ_NEXT(obj,@obj^.link);
+ end;
+end;
+
function dynlib_load_needed_shared_objects():Integer;
var
obj:p_lib_info;
diff --git a/sys/kern/trap.pas b/sys/kern/trap.pas
index bebd3a84..ff492702 100644
--- a/sys/kern/trap.pas
+++ b/sys/kern/trap.pas
@@ -338,6 +338,7 @@ var
obj:p_lib_info;
r:TLQRec;
adr:QWORD;
+ len:ptruint;
begin
Result:=False;
dynlibs_lock;
@@ -353,7 +354,11 @@ begin
r.Base:=fuptr(obj^.map_base);
info.base_addr:=QWORD(r.Base);
- info.source:=dynlib_basename(obj^.lib_path);
+
+ len:=0;
+ copyinstr(@obj^.name,@info.source[1],SizeOf(obj^.name),@len);
+ if (len<>0) then Dec(len);
+ SetLength(info.source,len);
if (find_proc_obj(obj,r)<>0) then
begin
@@ -520,7 +525,7 @@ begin
print_backtrace(StdErr,Pointer(td_frame^.tf_rip),Pointer(td_frame^.tf_rbp),0);
- //Assert(false,sysent_table[td_frame^.tf_rax].sy_name);
+ Assert(false,sysent_table[td_frame^.tf_rax].sy_name);
end;
end else
if (td_frame^.tf_rax<=$1000) then
diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi
index b2292556..e0693f5f 100644
--- a/sys/test/project1.lpi
+++ b/sys/test/project1.lpi
@@ -665,6 +665,11 @@
+
+
+
+
+
diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr
index 807e5b21..75cb41cf 100644
--- a/sys/test/project1.lpr
+++ b/sys/test/project1.lpr
@@ -99,7 +99,10 @@ uses
kern_dmem,
kern_bnet,
uipc_syscalls,
- kern_ipmimgr;
+ kern_ipmimgr{,
+ ps4_libSceSystemService,
+ ps4_libSceIpmi,
+ ps4_libSceDialogs};
const
PAGE_MAP_COUNT=(qword(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT);
diff --git a/sys/test/ps4_libscedialogs.pas b/sys/test/ps4_libscedialogs.pas
new file mode 100644
index 00000000..6de1043d
--- /dev/null
+++ b/sys/test/ps4_libscedialogs.pas
@@ -0,0 +1,719 @@
+unit ps4_libSceDialogs;
+
+{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
+
+interface
+
+uses
+ subr_dynlib{,
+ ps4_libSceSaveData};
+
+implementation
+
+Const
+ //SceCommonDialogStatus
+ SCE_COMMON_DIALOG_STATUS_NONE = 0;
+ SCE_COMMON_DIALOG_STATUS_INITIALIZED = 1;
+ SCE_COMMON_DIALOG_STATUS_RUNNING = 2;
+ SCE_COMMON_DIALOG_STATUS_FINISHED = 3;
+
+ //SceCommonDialogResult
+ SCE_COMMON_DIALOG_RESULT_OK =0;
+ SCE_COMMON_DIALOG_RESULT_USER_CANCELED=1;
+ SCE_NP_COMMERCE_DIALOG_RESULT_PURCHASED=2;
+
+ SCE_COMMON_DIALOG_MAGIC_NUMBER=$C0D1A109;
+
+ //SceMsgDialogMode
+ SCE_MSG_DIALOG_MODE_INVALID =(0);
+ SCE_MSG_DIALOG_MODE_USER_MSG =(1);
+ SCE_MSG_DIALOG_MODE_PROGRESS_BAR=(2);
+ SCE_MSG_DIALOG_MODE_SYSTEM_MSG =(3);
+
+ //SceMsgDialogButtonType
+ SCE_MSG_DIALOG_BUTTON_TYPE_OK =(0);
+ SCE_MSG_DIALOG_BUTTON_TYPE_YESNO =(1);
+ SCE_MSG_DIALOG_BUTTON_TYPE_NONE =(2);
+ SCE_MSG_DIALOG_BUTTON_TYPE_OK_CANCEL =(3);
+ SCE_MSG_DIALOG_BUTTON_TYPE_WAIT =(5);
+ SCE_MSG_DIALOG_BUTTON_TYPE_WAIT_CANCEL =(6);
+ SCE_MSG_DIALOG_BUTTON_TYPE_YESNO_FOCUS_NO =(7);
+ SCE_MSG_DIALOG_BUTTON_TYPE_OK_CANCEL_FOCUS_CANCEL=(8);
+ SCE_MSG_DIALOG_BUTTON_TYPE_2BUTTONS =(9);
+
+ //SceMsgDialogProgressBarType
+ SCE_MSG_DIALOG_PROGRESSBAR_TYPE_PERCENTAGE =(0);
+ SCE_MSG_DIALOG_PROGRESSBAR_TYPE_PERCENTAGE_CANCEL=(1);
+
+ //SceMsgDialogSystemMessageType;
+ SCE_MSG_DIALOG_SYSMSG_TYPE_TRC_EMPTY_STORE =(0);
+ SCE_MSG_DIALOG_SYSMSG_TYPE_TRC_PSN_CHAT_RESTRICTION=(1);
+ SCE_MSG_DIALOG_SYSMSG_TYPE_TRC_PSN_UGC_RESTRICTION =(2);
+
+ //SceSaveDataDialogAnimation
+ SCE_SAVE_DATA_DIALOG_ANIMATION_ON =(0);
+ SCE_SAVE_DATA_DIALOG_ANIMATION_OFF =(1);
+
+function ps4_sceCommonDialogInitialize():Integer;
+begin
+ Writeln('sceCommonDialogInitialize');
+ Result:=0;
+end;
+
+function ps4_sceCommonDialogIsUsed():Boolean;
+begin
+ Result:=True;
+end;
+
+//
+
+var
+ status_err_dialog:Integer=0; //SCE_ERROR_DIALOG_STATUS_NONE
+
+function ps4_sceErrorDialogInitialize():Integer;
+begin
+ Writeln('sceErrorDialogInitialize');
+ status_err_dialog:=1; //SCE_ERROR_DIALOG_STATUS_INITIALIZED
+ Result:=0;
+end;
+
+type
+ pSceErrorDialogParam=^SceErrorDialogParam;
+ SceErrorDialogParam=packed record
+ size:Integer;
+ errorCode:Integer;
+ userId:Integer;
+ reserved:Integer;
+ end;
+
+const
+ SCE_ERROR_DIALOG_ERROR_PARAM_INVALID=Integer($80ED0003);
+
+function ps4_sceErrorDialogOpen(param:pSceErrorDialogParam):Integer;
+begin
+ if (param=nil) then Exit(SCE_ERROR_DIALOG_ERROR_PARAM_INVALID);
+ Writeln('sceErrorDialogOpen:',HexStr(param^.errorCode,4));
+ status_err_dialog:=3; //SCE_ERROR_DIALOG_STATUS_FINISHED
+ Result:=0;
+end;
+
+function ps4_sceErrorDialogUpdateStatus():Integer;
+begin
+ Result:=status_err_dialog;
+end;
+
+function ps4_sceErrorDialogGetStatus():Integer;
+begin
+ Result:=status_err_dialog;
+end;
+
+function ps4_sceErrorDialogTerminate():Integer;
+begin
+ Writeln('sceErrorDialogTerminate');
+ status_err_dialog:=0; //SCE_ERROR_DIALOG_STATUS_NONE
+ Result:=0;
+end;
+
+//
+
+var
+ status_profile_dialog:Integer=SCE_COMMON_DIALOG_STATUS_NONE;
+
+function ps4_sceNpProfileDialogInitialize():Integer;
+begin
+ Writeln('sceNpProfileDialogInitialize');
+ status_profile_dialog:=SCE_COMMON_DIALOG_STATUS_INITIALIZED;
+ Result:=0;
+end;
+
+function ps4_sceNpProfileDialogUpdateStatus():Integer;
+begin
+ Result:=status_profile_dialog;
+end;
+
+//
+
+var
+ status_save_dialog:Integer=SCE_COMMON_DIALOG_STATUS_NONE;
+
+function ps4_sceSaveDataDialogInitialize():Integer;
+begin
+ Writeln('sceSaveDataDialogInitialize');
+ status_save_dialog:=SCE_COMMON_DIALOG_STATUS_INITIALIZED;
+ Result:=0;
+end;
+
+//SceSaveDataDialogParam
+function ps4_sceSaveDataDialogOpen(param:Pointer):Integer;
+begin
+ if (param=nil) then Exit(SCE_ERROR_DIALOG_ERROR_PARAM_INVALID);
+ Writeln('sceSaveDataDialogOpen:');
+ status_save_dialog:=SCE_COMMON_DIALOG_STATUS_FINISHED;
+ Result:=0;
+end;
+
+function ps4_sceSaveDataDialogIsReadyToDisplay:Integer;
+begin
+ Result:=1;
+end;
+
+function ps4_sceSaveDataDialogUpdateStatus():Integer;
+begin
+ Result:=status_save_dialog;
+end;
+
+function ps4_sceSaveDataDialogGetStatus():Integer;
+begin
+ Result:=status_save_dialog;
+end;
+
+type
+ pSceSaveDataDirName=pchar;
+ pSceSaveDataParam=Pointer;
+
+ pSceSaveDataDialogResult=^SceSaveDataDialogResult;
+ SceSaveDataDialogResult=packed record
+ mode:Integer;//SceSaveDataDialogMode; //Mode of function
+ result:Integer; //Result of executing function
+ buttonId:Integer;//SceSaveDataDialogButtonId; //Id of button user selected
+ _align:Integer;
+ dirName:pSceSaveDataDirName; //savedata directory name
+ param:pSceSaveDataParam; //Buffer to receive savedata information ( can be set NULL if you don't need it)
+ userData:Pointer; //Userdata specified at calling function
+ reserved:array[0..31] of Byte; //Reserved range (must be filled by zero)
+ end;
+
+
+function ps4_sceSaveDataDialogProgressBarSetValue(target:Integer;rate:DWORD):Integer;
+begin
+ Writeln('sceSaveDataDialogProgressBarSetValue:',rate);
+ Result:=0;
+end;
+
+function ps4_sceSaveDataDialogTerminate():Integer;
+begin
+ Writeln('sceSaveDataDialogTerminate');
+ status_save_dialog:=SCE_COMMON_DIALOG_STATUS_NONE;
+ Result:=0;
+end;
+
+const
+ SCE_COMMON_DIALOG_ERROR_NOT_FINISHED=-2135425019;//0x80B80005
+
+function ps4_sceSaveDataDialogGetResult(_result:pSceSaveDataDialogResult):Integer;
+begin
+ //Writeln('sceSaveDataDialogGetResult');
+ Result:=0;
+end;
+
+type
+ pSceSaveDataDialogCloseParam=^SceSaveDataDialogCloseParam;
+ SceSaveDataDialogCloseParam=packed record
+ anim:Integer;
+ reserved:array[0..31] of Byte;
+ end;
+
+function ps4_sceSaveDataDialogClose(closeParam:pSceSaveDataDialogCloseParam):Integer;
+begin
+ Writeln('sceSaveDataDialogClose');
+ status_save_dialog:=SCE_COMMON_DIALOG_STATUS_FINISHED;
+ Result:=0;
+end;
+
+//
+
+var
+ status_msg_dialog:Integer=SCE_COMMON_DIALOG_STATUS_NONE;
+
+function ps4_sceMsgDialogInitialize():Integer;
+begin
+ Writeln('sceMsgDialogInitialize');
+ status_msg_dialog:=SCE_COMMON_DIALOG_STATUS_INITIALIZED;
+ Result:=0;
+end;
+
+type
+ SceCommonDialogBaseParam=packed record
+ size:QWORD;
+ reserved:array[0..35] of Byte;
+ magic:DWORD;
+ end; //__attribute__ ((__aligned__(8)));
+
+ pSceMsgDialogButtonsParam=^SceMsgDialogButtonsParam;
+ SceMsgDialogButtonsParam=packed record
+ msg1,msg2:Pchar;
+ reserved:array[0..31] of Byte;
+ end;
+
+ pSceMsgDialogUserMessageParam=^SceMsgDialogUserMessageParam;
+ SceMsgDialogUserMessageParam=packed record
+ buttonType:Integer; //SceMsgDialogButtonType
+ _align:Integer;
+ msg:PChar;
+ buttonsParam:pSceMsgDialogButtonsParam;
+ reserved:array[0..23] of Byte;
+ end;
+
+ pSceMsgDialogProgressBarParam=^SceMsgDialogProgressBarParam;
+ SceMsgDialogProgressBarParam=packed record
+ barType:Integer; //SceMsgDialogProgressBarType
+ _align:Integer;
+ msg:PChar;
+ reserved:array[0..63] of Byte;
+ end;
+
+ pSceMsgDialogSystemMessageParam=^SceMsgDialogSystemMessageParam;
+ SceMsgDialogSystemMessageParam=packed record
+ sysMsgType:Integer; //SceMsgDialogSystemMessageType
+ reserved:array[0..31] of Byte;
+ end;
+
+ pSceMsgDialogParam=^SceMsgDialogParam;
+ SceMsgDialogParam=packed record
+ baseParam:SceCommonDialogBaseParam;
+ size:QWORD;
+ mode:Integer; //SceMsgDialogMode
+ _align1:Integer;
+ userMsgParam:pSceMsgDialogUserMessageParam;
+ progBarParam:pSceMsgDialogProgressBarParam;
+ sysMsgParam:pSceMsgDialogSystemMessageParam;
+ userId:Integer; //SceUserServiceUserId
+ reserved:array[0..39] of Byte;
+ _align2:Integer;
+ end;
+
+const
+ SCE_COMMON_DIALOG_ERROR_PARAM_INVALID=-2135425014; // 0x80B8000A
+ SCE_COMMON_DIALOG_ERROR_ARG_NULL =-2135425011; // 0x80B8000D
+
+function ps4_sceMsgDialogOpen(param:pSceMsgDialogParam):Integer;
+begin
+ if (param=nil) then Exit(SCE_COMMON_DIALOG_ERROR_ARG_NULL);
+
+ Writeln('sceMsgDialogOpen');
+
+ Case param^.mode of
+ SCE_MSG_DIALOG_MODE_USER_MSG:
+ begin
+ if (param^.userMsgParam=nil) then Exit(SCE_COMMON_DIALOG_ERROR_PARAM_INVALID);
+
+ Writeln(param^.userMsgParam^.msg);
+
+ //TODO
+ end;
+ //else
+ // Assert(false,'TODO');
+ end;
+
+ status_msg_dialog:=SCE_COMMON_DIALOG_STATUS_FINISHED;
+
+ Result:=0;
+end;
+
+function ps4_sceMsgDialogClose():Integer;
+begin
+ Writeln('sceMsgDialogClose');
+ status_msg_dialog:=SCE_COMMON_DIALOG_STATUS_FINISHED;
+ Result:=0;
+end;
+
+function ps4_sceMsgDialogUpdateStatus():Integer;
+begin
+ Result:=status_msg_dialog;
+end;
+
+function ps4_sceMsgDialogGetStatus():Integer;
+begin
+ Result:=status_msg_dialog;
+end;
+
+type
+ pSceMsgDialogResult=^SceMsgDialogResult;
+ SceMsgDialogResult=packed record
+ mode:Integer; //SceMsgDialogMode
+ result:Integer;
+ buttonId:Integer; //SceMsgDialogButtonId
+ reserved:array[0..31] of Byte;
+ end;
+
+function ps4_sceMsgDialogGetResult(pResult:pSceMsgDialogResult):Integer;
+begin
+ //Writeln('sceMsgDialogGetResult');
+ if (pResult<>nil) then
+ begin
+ pResult^.result:=0;
+ pResult^.buttonId:=1;
+ end;
+ Result:=0;
+end;
+
+function ps4_sceMsgDialogTerminate():Integer;
+begin
+ Writeln('sceMsgDialogTerminate');
+ status_msg_dialog:=SCE_COMMON_DIALOG_STATUS_NONE;
+ Result:=0;
+end;
+
+//
+
+var
+ status_commerce_dialog:Integer=SCE_COMMON_DIALOG_STATUS_NONE;
+
+function ps4_sceNpCommerceDialogInitialize():Integer;
+begin
+ Writeln('sceNpCommerceDialogInitialize');
+ status_commerce_dialog:=SCE_COMMON_DIALOG_STATUS_INITIALIZED;
+ Result:=0;
+end;
+
+type
+ pSceNpCommerceDialogParam=^SceNpCommerceDialogParam;
+ SceNpCommerceDialogParam=packed record
+ baseParam:SceCommonDialogBaseParam;
+ size:Integer;
+ userId:Integer;
+ mode:Integer; //SceNpCommerceDialogMode
+ serviceLabel:DWORD; //SceNpServiceLabel
+ targets:PPChar;
+ numTargets:DWORD;
+ align:Integer;
+ features:QWORD;
+ userData:Pointer;
+ reserved:array[0..31] of Byte;
+ end;
+
+function ps4_sceNpCommerceDialogOpen(param:pSceNpCommerceDialogParam):Integer;
+begin
+ Writeln('sceNpCommerceDialogOpen');
+ status_commerce_dialog:=SCE_COMMON_DIALOG_STATUS_FINISHED;
+ Result:=0;
+end;
+
+function ps4_sceNpCommerceDialogUpdateStatus():Integer;
+begin
+ Result:=status_commerce_dialog;
+end;
+
+type
+ pSceNpCommerceDialogResult=^SceNpCommerceDialogResult;
+ SceNpCommerceDialogResult=packed record
+ result:Integer;
+ authorized:Boolean;
+ align1:Byte;
+ align2:Word;
+ userData:Pointer;
+ reserved:array[0..31] of Byte;
+ end;
+
+function ps4_sceNpCommerceDialogGetResult(pResult:pSceNpCommerceDialogResult):Integer;
+begin
+ //Writeln('sceNpCommerceDialogGetResult');
+ if (pResult<>nil) then
+ begin
+ pResult^.result:=SCE_NP_COMMERCE_DIALOG_RESULT_PURCHASED;
+ pResult^.authorized:=false;
+ end;
+ Result:=0;
+end;
+
+function ps4_sceNpCommerceDialogTerminate():Integer;
+begin
+ Writeln('sceNpCommerceDialogTerminate');
+ status_commerce_dialog:=SCE_COMMON_DIALOG_STATUS_NONE;
+ Result:=0;
+end;
+
+const
+ //SceNpCommercePsStoreIconPos
+ SCE_NP_COMMERCE_PS_STORE_ICON_CENTER=0;
+ SCE_NP_COMMERCE_PS_STORE_ICON_LEFT =1;
+ SCE_NP_COMMERCE_PS_STORE_ICON_RIGHT =2;
+
+function ps4_sceNpCommerceShowPsStoreIcon(pos:Integer):Integer;
+begin
+ Writeln('sceNpCommerceShowPsStoreIcon:',pos);
+ Result:=0;
+end;
+
+function ps4_sceNpCommerceHidePsStoreIcon():Integer;
+begin
+ Writeln('sceNpCommerceHidePsStoreIcon');
+ Result:=0;
+end;
+
+//
+
+const
+ SCE_SIGNIN_DIALOG_STATUS_NONE =0;
+ SCE_SIGNIN_DIALOG_STATUS_INITIALIZED=1;
+ SCE_SIGNIN_DIALOG_STATUS_RUNNING =2;
+ SCE_SIGNIN_DIALOG_STATUS_FINISHED =3;
+
+var
+ status_signin_dialog:Integer=SCE_SIGNIN_DIALOG_STATUS_NONE;
+
+function ps4_sceSigninDialogInitialize():Integer;
+begin
+ Writeln('sceSigninDialogInitialize');
+ status_signin_dialog:=SCE_SIGNIN_DIALOG_STATUS_INITIALIZED;
+ Result:=0;
+end;
+
+function ps4_sceSigninDialogTerminate():Integer;
+begin
+ Writeln('sceSigninDialogTerminate');
+ status_signin_dialog:=SCE_SIGNIN_DIALOG_STATUS_NONE;
+ Result:=0;
+end;
+
+type
+ pSceSigninDialogParam=^SceSigninDialogParam;
+ SceSigninDialogParam=packed record
+ size:Integer;
+ userId:Integer;
+ reserved:array[0..1] of Integer;
+ end;
+
+function ps4_sceSigninDialogOpen(param:pSceSigninDialogParam):Integer;
+begin
+ Writeln('sceSigninDialogOpen');
+ status_signin_dialog:=SCE_SIGNIN_DIALOG_STATUS_FINISHED;
+ Result:=0;
+end;
+
+function ps4_sceSigninDialogUpdateStatus:Integer;
+begin
+ Result:=status_signin_dialog;
+end;
+
+function ps4_scePlayerInvitationDialogTerminate():Integer;
+begin
+ Writeln('scePlayerInvitationDialogTerminate');
+ Result:=0;
+end;
+
+//
+
+const
+ SCE_IME_DIALOG_STATUS_NONE =0;
+ SCE_IME_DIALOG_STATUS_RUNNING =1;
+ SCE_IME_DIALOG_STATUS_FINISHED=2;
+
+var
+ status_ime_dialog:Integer=SCE_IME_DIALOG_STATUS_NONE;
+
+//function ps4_sceImeDialogInit(param:pSceImeDialogParam;
+// extended:pSceImeParamExtended
+// ):Integer;
+//
+//nop nid:libSceImeDialog:354781ACDEE1CDFD:sceImeDialogInit
+
+function ps4_sceImeDialogGetStatus:Integer;
+begin
+ Result:=status_ime_dialog;
+end;
+
+//
+
+function ps4_sceLoginDialogInitialize():Integer;
+begin
+ Result:=0;
+end;
+
+//
+
+function ps4_sceHmdSetupDialogInitialize():Integer;
+begin
+ Result:=0;
+end;
+
+function ps4_sceHmdSetupDialogOpen(param:Pointer):Integer;
+begin
+ Result:=0;
+end;
+
+function ps4_sceHmdSetupDialogUpdateStatus():Integer;
+begin
+ Result:=SCE_COMMON_DIALOG_STATUS_FINISHED;
+end;
+
+function ps4_sceHmdSetupDialogGetResult(pResult:Pointer):Integer;
+begin
+ Result:=0;
+end;
+
+function ps4_sceHmdSetupDialogTerminate():Integer;
+begin
+ Result:=0;
+end;
+
+//
+
+function Load_libSceCommonDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceCommonDialog');
+
+ lib:=Result^.add_lib('libSceCommonDialog');
+ lib.set_proc($BA85292C6364CA09,@ps4_sceCommonDialogInitialize);
+ lib.set_proc($050DED7B2D099903,@ps4_sceCommonDialogIsUsed);
+end;
+
+//
+
+function Load_libSceErrorDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceErrorDialog');
+
+ lib:=Result^.add_lib('libSceErrorDialog');
+ lib.set_proc($23CF0A0A19729D2B,@ps4_sceErrorDialogInitialize);
+ lib.set_proc($336645FC294B8606,@ps4_sceErrorDialogOpen);
+ lib.set_proc($596886BA1F577E04,@ps4_sceErrorDialogUpdateStatus);
+ lib.set_proc($B7616F1D15F382A9,@ps4_sceErrorDialogGetStatus);
+ lib.set_proc($F570312B63CCC24F,@ps4_sceErrorDialogTerminate);
+end;
+
+//
+
+function Load_libSceNpProfileDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceNpProfileDialog');
+
+ lib:=Result^.add_lib('libSceNpProfileDialog');
+ lib.set_proc($2E0F8D084EA94F04,@ps4_sceNpProfileDialogInitialize);
+ lib.set_proc($85A55913D1602AA1,@ps4_sceNpProfileDialogUpdateStatus);
+end;
+
+//
+
+function Load_libSceSaveDataDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceSaveDataDialog');
+
+ lib:=Result^.add_lib('libSceSaveDataDialog');
+ lib.set_proc($B3D7B7F98A519F3C,@ps4_sceSaveDataDialogInitialize);
+ lib.set_proc($E2D3E1B0FE85A432,@ps4_sceSaveDataDialogOpen);
+ lib.set_proc($7A7EE03559E1F3BF,@ps4_sceSaveDataDialogIsReadyToDisplay);
+ lib.set_proc($28ADC1760D5158AD,@ps4_sceSaveDataDialogUpdateStatus);
+ lib.set_proc($1112B392C6AE0090,@ps4_sceSaveDataDialogGetStatus);
+ lib.set_proc($85ACB509F4E62F20,@ps4_sceSaveDataDialogProgressBarSetValue);
+ lib.set_proc($62E1F6140EDACEA4,@ps4_sceSaveDataDialogTerminate);
+ lib.set_proc($C84889FEAAABE828,@ps4_sceSaveDataDialogGetResult);
+ lib.set_proc($7C7E3A2DA83CF176,@ps4_sceSaveDataDialogClose);
+end;
+
+function Load_libSceMsgDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceMsgDialog');
+
+ lib:=Result^.add_lib('libSceMsgDialog');
+ lib.set_proc($943AB1698D546C4A,@ps4_sceMsgDialogInitialize);
+ lib.set_proc($6F4E878740CF11A1,@ps4_sceMsgDialogOpen);
+ lib.set_proc($1D3ADC0CA9452AE3,@ps4_sceMsgDialogClose);
+ lib.set_proc($E9F202DD72ADDA4D,@ps4_sceMsgDialogUpdateStatus);
+ lib.set_proc($096556EFC41CDDF2,@ps4_sceMsgDialogGetStatus);
+ lib.set_proc($2EBF28BC71FD97A0,@ps4_sceMsgDialogGetResult);
+ lib.set_proc($78FC3F92A6667A5A,@ps4_sceMsgDialogTerminate);
+end;
+
+function Load_libSceNpCommerce(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceNpCommerce');
+
+ lib:=Result^.add_lib('libSceNpCommerce');
+ lib.set_proc($D1A4766969906A5E,@ps4_sceNpCommerceDialogInitialize);
+ lib.set_proc($0DF4820D10371236,@ps4_sceNpCommerceDialogOpen);
+ lib.set_proc($2D1E5CC0530C0951,@ps4_sceNpCommerceDialogUpdateStatus);
+ lib.set_proc($AF8D9B59C41BB596,@ps4_sceNpCommerceDialogGetResult);
+ lib.set_proc($9BF23DD806F9D16F,@ps4_sceNpCommerceDialogTerminate);
+ lib.set_proc($0C79B0B1AE92F137,@ps4_sceNpCommerceShowPsStoreIcon);
+ lib.set_proc($76CA8256C34CD198,@ps4_sceNpCommerceHidePsStoreIcon);
+end;
+
+function Load_libSceSigninDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceSigninDialog');
+
+ lib:=Result^.add_lib('libSceSigninDialog');
+ lib.set_proc($9A56067E6A84DDF4,@ps4_sceSigninDialogInitialize);
+ lib.set_proc($265A49568456BFB5,@ps4_sceSigninDialogOpen);
+ lib.set_proc($070DF59624C54F70,@ps4_sceSigninDialogUpdateStatus);
+ lib.set_proc($2D79664BA3EF25D5,@ps4_sceSigninDialogTerminate);
+end;
+
+function Load_libScePlayerInvitationDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libScePlayerInvitationDialog');
+
+ lib:=Result^.add_lib('libScePlayerInvitationDialog');
+ lib.set_proc($8039B96BA19213DE,@ps4_scePlayerInvitationDialogTerminate);
+end;
+
+function Load_libSceImeDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceImeDialog');
+
+ lib:=Result^.add_lib('libSceImeDialog');
+ lib.set_proc($2000E60F8B527016,@ps4_sceImeDialogGetStatus);
+end;
+
+function Load_libSceLoginDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceLoginDialog');
+
+ lib:=Result^.add_lib('libSceLoginDialog');
+ lib.set_proc($A8FFC4BD0465D877,@ps4_sceLoginDialogInitialize);
+end;
+
+function Load_libSceHmdSetupDialog(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceHmdSetupDialog');
+
+ lib:=Result^.add_lib('libSceHmdSetupDialog');
+ lib.set_proc($341D58DA40368C26,@ps4_sceHmdSetupDialogInitialize);
+ lib.set_proc($34D8225784FE6A45,@ps4_sceHmdSetupDialogOpen);
+ lib.set_proc($51DEE3DFE4432018,@ps4_sceHmdSetupDialogUpdateStatus);
+ lib.set_proc($EA55511CC5792D8D,@ps4_sceHmdSetupDialogGetResult);
+ lib.set_proc($FB3E0E26616B7997,@ps4_sceHmdSetupDialogTerminate);
+end;
+
+var
+ stub:array[0..10] of t_int_file;
+
+initialization
+ reg_int_file(stub[0] ,'libSceCommonDialog.prx' ,@Load_libSceCommonDialog );
+ reg_int_file(stub[1] ,'libSceErrorDialog.prx' ,@Load_libSceErrorDialog );
+ reg_int_file(stub[2] ,'libSceNpProfileDialog.prx' ,@Load_libSceNpProfileDialog );
+ reg_int_file(stub[3] ,'libSceSaveDataDialog.prx' ,@Load_libSceSaveDataDialog );
+ reg_int_file(stub[4] ,'libSceMsgDialog.prx' ,@Load_libSceMsgDialog );
+ reg_int_file(stub[5] ,'libSceNpCommerce.prx' ,@Load_libSceNpCommerce );
+ reg_int_file(stub[6] ,'libSceSigninDialog.prx' ,@Load_libSceSigninDialog );
+ reg_int_file(stub[7] ,'libScePlayerInvitationDialog.prx',@Load_libScePlayerInvitationDialog);
+ reg_int_file(stub[8] ,'libSceImeDialog.prx' ,@Load_libSceImeDialog );
+ reg_int_file(stub[9] ,'libSceLoginDialog.prx' ,@Load_libSceLoginDialog );
+ reg_int_file(stub[10],'libSceHmdSetupDialog.prx' ,@Load_libSceHmdSetupDialog );
+
+end.
+
diff --git a/sys/test/ps4_libsceipmi.pas b/sys/test/ps4_libsceipmi.pas
new file mode 100644
index 00000000..243965ba
--- /dev/null
+++ b/sys/test/ps4_libsceipmi.pas
@@ -0,0 +1,29 @@
+unit ps4_libSceIpmi;
+
+{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
+
+interface
+
+uses
+ subr_dynlib;
+
+implementation
+
+function Load_libSceIpmi(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceIpmi');
+
+ lib:=Result^.add_lib('libSceIpmi');
+end;
+
+var
+ stub:t_int_file;
+
+initialization
+ reg_int_file(stub,'libSceIpmi.prx',@Load_libSceIpmi);
+
+end.
+
diff --git a/sys/test/ps4_libscesystemservice.pas b/sys/test/ps4_libscesystemservice.pas
new file mode 100644
index 00000000..8e290ad1
--- /dev/null
+++ b/sys/test/ps4_libscesystemservice.pas
@@ -0,0 +1,474 @@
+unit ps4_libSceSystemService;
+
+{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
+
+interface
+
+uses
+ windows,
+ subr_dynlib;
+
+const
+ SCE_SYSTEM_SERVICE_PARAM_ID_LANG =1;
+ SCE_SYSTEM_SERVICE_PARAM_ID_DATE_FORMAT =2;
+ SCE_SYSTEM_SERVICE_PARAM_ID_TIME_FORMAT =3;
+ SCE_SYSTEM_SERVICE_PARAM_ID_TIME_ZONE =4;
+ SCE_SYSTEM_SERVICE_PARAM_ID_SUMMERTIME =5;
+ SCE_SYSTEM_SERVICE_PARAM_ID_SYSTEM_NAME =6;
+ SCE_SYSTEM_SERVICE_PARAM_ID_GAME_PARENTAL_LEVEL =7;
+ SCE_SYSTEM_SERVICE_PARAM_ID_ENTER_BUTTON_ASSIGN =1000;
+
+ SCE_SYSTEM_SERVICE_ERROR_INTERNAL =-2136932351;
+ SCE_SYSTEM_SERVICE_ERROR_UNAVAILABLE =-2136932350;
+ SCE_SYSTEM_SERVICE_ERROR_PARAMETER =-2136932349;
+ SCE_SYSTEM_SERVICE_ERROR_NO_EVENT =-2136932348;
+ SCE_SYSTEM_SERVICE_ERROR_REJECTED =-2136932347;
+ SCE_SYSTEM_SERVICE_ERROR_NEED_DISPLAY_SAFE_AREA_SETTINGS =-2136932346;
+ SCE_SYSTEM_SERVICE_ERROR_INVALID_URI_LEN =-2136932345;
+ SCE_SYSTEM_SERVICE_ERROR_INVALID_URI_SCHEME =-2136932344;
+ SCE_SYSTEM_SERVICE_ERROR_NO_APP_INFO =-2136932343;
+ SCE_SYSTEM_SERVICE_ERROR_NOT_FLAG_IN_PARAM_SFO =-2136932342;
+
+ // Language
+ SCE_SYSTEM_PARAM_LANG_JAPANESE =0; //LANG_JAPANESE
+ SCE_SYSTEM_PARAM_LANG_ENGLISH_US =1; //else
+ SCE_SYSTEM_PARAM_LANG_FRENCH =2; //LANG_FRENCH else
+ SCE_SYSTEM_PARAM_LANG_SPANISH =3; //LANG_SPANISH SUBLANG_SPANISH SUBLANG_SPANISH_MEXICAN SUBLANG_SPANISH_MODERN
+ SCE_SYSTEM_PARAM_LANG_GERMAN =4; //LANG_GERMAN
+ SCE_SYSTEM_PARAM_LANG_ITALIAN =5; //LANG_ITALIAN
+ SCE_SYSTEM_PARAM_LANG_DUTCH =6; //LANG_DUTCH
+ SCE_SYSTEM_PARAM_LANG_PORTUGUESE_PT =7; //LANG_PORTUGUESE SUBLANG_PORTUGUESE
+ SCE_SYSTEM_PARAM_LANG_RUSSIAN =8; //LANG_RUSSIAN
+ SCE_SYSTEM_PARAM_LANG_KOREAN =9; //LANG_KOREAN
+ SCE_SYSTEM_PARAM_LANG_CHINESE_T =10; //LANG_CHINESE else
+ SCE_SYSTEM_PARAM_LANG_CHINESE_S =11; //LANG_CHINESE SUBLANG_CHINESE_SIMPLIFIED
+ SCE_SYSTEM_PARAM_LANG_FINNISH =12; //LANG_FINNISH
+ SCE_SYSTEM_PARAM_LANG_SWEDISH =13; //LANG_SWEDISH
+ SCE_SYSTEM_PARAM_LANG_DANISH =14; //LANG_DANISH
+ SCE_SYSTEM_PARAM_LANG_NORWEGIAN =15; //LANG_NORWEGIAN
+ SCE_SYSTEM_PARAM_LANG_POLISH =16; //LANG_POLISH
+ SCE_SYSTEM_PARAM_LANG_PORTUGUESE_BR =17; //LANG_PORTUGUESE SUBLANG_PORTUGUESE_BRAZILIAN
+ SCE_SYSTEM_PARAM_LANG_ENGLISH_GB =18; //LANG_ENGLISH SUBLANG_ENGLISH_UK
+ SCE_SYSTEM_PARAM_LANG_TURKISH =19; //LANG_TURKISH
+ SCE_SYSTEM_PARAM_LANG_SPANISH_LA =20; //LANG_SPANISH else
+ SCE_SYSTEM_PARAM_LANG_ARABIC =21; //LANG_ARABIC
+ SCE_SYSTEM_PARAM_LANG_FRENCH_CA =22; //LANG_FRENCH SUBLANG_FRENCH_CANADIAN
+ SCE_SYSTEM_PARAM_LANG_CZECH =23; //LANG_CZECH
+ SCE_SYSTEM_PARAM_LANG_HUNGARIAN =24; //LANG_HUNGARIAN
+ SCE_SYSTEM_PARAM_LANG_GREEK =25; //LANG_GREEK
+ SCE_SYSTEM_PARAM_LANG_ROMANIAN =26; //LANG_ROMANIAN
+ SCE_SYSTEM_PARAM_LANG_THAI =27; //LANG_THAI
+ SCE_SYSTEM_PARAM_LANG_VIETNAMESE =28; //LANG_VIETNAMESE
+ SCE_SYSTEM_PARAM_LANG_INDONESIAN =29; //LANG_INDONESIAN
+
+ // Date
+ SCE_SYSTEM_PARAM_DATE_FORMAT_YYYYMMDD=0;
+ SCE_SYSTEM_PARAM_DATE_FORMAT_DDMMYYYY=1;
+ SCE_SYSTEM_PARAM_DATE_FORMAT_MMDDYYYY=2;
+
+ // Time
+ SCE_SYSTEM_PARAM_TIME_FORMAT_12HOUR=0;
+ SCE_SYSTEM_PARAM_TIME_FORMAT_24HOUR=1;
+
+ //
+ SCE_SYSTEM_SERVICE_MAX_SYSTEM_NAME_LENGTH=65;
+
+ //
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_OFF =0;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL01=1;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL02=2;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL03=3;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL04=4;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL05=5;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL06=6;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL07=7;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL08=8;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL09=9;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL10=10;
+ SCE_SYSTEM_PARAM_GAME_PARENTAL_LEVEL11=11;
+
+ //
+ SCE_SYSTEM_PARAM_ENTER_BUTTON_ASSIGN_CIRCLE=0;
+ SCE_SYSTEM_PARAM_ENTER_BUTTON_ASSIGN_CROSS =1;
+
+ //SceSystemServiceEventType
+ SCE_SYSTEM_SERVICE_EVENT_INVALID = -1;
+ SCE_SYSTEM_SERVICE_EVENT_ON_RESUME = $10000000;
+ SCE_SYSTEM_SERVICE_EVENT_GAME_LIVE_STREAMING_STATUS_UPDATE = $10000001;
+ SCE_SYSTEM_SERVICE_EVENT_SESSION_INVITATION = $10000002;
+ SCE_SYSTEM_SERVICE_EVENT_ENTITLEMENT_UPDATE = $10000003;
+ SCE_SYSTEM_SERVICE_EVENT_GAME_CUSTOM_DATA = $10000004; // deprecated
+ SCE_SYSTEM_SERVICE_EVENT_DISPLAY_SAFE_AREA_UPDATE = $10000005; // deprecated
+ SCE_SYSTEM_SERVICE_EVENT_URL_OPEN = $10000006;
+ SCE_SYSTEM_SERVICE_EVENT_LAUNCH_APP = $10000007;
+ SCE_SYSTEM_SERVICE_EVENT_APP_LAUNCH_LINK = $10000008;
+ SCE_SYSTEM_SERVICE_EVENT_ADDCONTENT_INSTALL = $10000009;
+ SCE_SYSTEM_SERVICE_EVENT_RESET_VR_POSITION = $1000000a;
+ SCE_SYSTEM_SERVICE_EVENT_JOIN_EVENT = $1000000b;
+ SCE_SYSTEM_SERVICE_EVENT_PLAYGO_LOCUS_UPDATE = $1000000c;
+ SCE_SYSTEM_SERVICE_EVENT_PLAY_TOGETHER_HOST = $1000000d;
+ SCE_SYSTEM_SERVICE_EVENT_SERVICE_ENTITLEMENT_UPDATE = $1000000e;
+ SCE_SYSTEM_SERVICE_EVENT_EYE_TO_EYE_DISTANCE_UPDATE = $1000000f;
+ SCE_SYSTEM_SERVICE_EVENT_JOIN_MATCH_EVENT = $10000010;
+ SCE_SYSTEM_SERVICE_EVENT_PLAY_TOGETHER_HOST_A = $10000011; // deprecated
+ SCE_SYSTEM_SERVICE_EVENT_WEBBROWSER_CLOSED = $10000012;
+ SCE_SYSTEM_SERVICE_EVENT_CONTROLLER_SETTINGS_CLOSED = $10000013;
+ SCE_SYSTEM_SERVICE_EVENT_JOIN_TEAM_ON_TEAM_MATCH_EVENT = $10000014;
+ SCE_SYSTEM_SERVICE_EVENT_JOIN_FFA_MATCH_EVENT = $10000015;
+ SCE_SYSTEM_SERVICE_EVENT_JOIN_FFA_TEAM_MATCH_EVENT = $10000016;
+ SCE_SYSTEM_SERVICE_EVENT_GAME_INTENT = $10000017;
+ SCE_SYSTEM_SERVICE_EVENT_OPEN_SHARE_MENU = $30000000;
+ SCE_SYSTEM_SERVICE_EVENT_UNIFIED_ENTITLEMENT_UPDATE = $10000018;
+
+function ps4_sceSystemServiceParamGetInt(paramId:Integer;value:Pinteger):Integer;
+
+implementation
+
+uses
+ errno,
+ time,
+ md_time,
+ trap,
+ kern_dlsym;
+
+type
+ pSceSystemServiceDisplaySafeAreaInfo=^SceSystemServiceDisplaySafeAreaInfo;
+ SceSystemServiceDisplaySafeAreaInfo=packed record
+ ratio:Single; //Ratio of the safe area (0.9 or more, 1.0 or less)
+ reserved:array[0..127] of Byte;
+ end;
+
+ PSceSystemServiceStatus=^SceSystemServiceStatus;
+ SceSystemServiceStatus=packed record
+ eventNum:Integer;
+ isSystemUiOverlaid,
+ isInBackgroundExecution,
+ isCpuMode7CpuNormal,
+ isGameLiveStreamingOnAir,
+ isOutOfVrPlayArea:Boolean;
+ reserved:array[0..124] of Byte;
+ end;
+
+ pSceSystemServiceHdrToneMapLuminance=^SceSystemServiceHdrToneMapLuminance;
+ SceSystemServiceHdrToneMapLuminance=packed record
+ maxFullFrameToneMapLuminance:Single;
+ maxToneMapLuminance :Single;
+ minToneMapLuminance :Single;
+ end;
+
+ pSceSystemServiceEventType=^SceSystemServiceEventType;
+ SceSystemServiceEventType=packed record
+ eventType:Integer; //SceSystemServiceEventType
+ data:packed record
+ Case Byte of
+ 0:(param:array[0..8191] of Char);
+ 1:(urlOpen:packed record
+ source:array[0..1023] of Char;
+ url :array[0..4095] of Char;
+ end);
+ 2:(launchApp:packed record
+ size:DWORD;
+ arg :array[0..8187] of Byte;
+ end);
+ 3:(appLaunchLink:packed record
+ size:DWORD;
+ arg :array[0..2019] of Byte;
+ end);
+ 4:(joinEvent:packed record
+ userId :Integer;
+ eventId :array[0..36] of Char;
+ bootArgument:array[0..7168] of Char;
+ end);
+ 5:(serviceEntitlementUpdate:packed record
+ userId :Integer;
+ npServiceLabel:DWORD;
+ reserved :array[0..8183] of Byte;
+ end);
+ 6:(unifiedEntitlementUpdate:packed record
+ userId :Integer;
+ npServiceLabel:DWORD;
+ reserved :array[0..8183] of Byte;
+ end);
+ 7:(reserved:array[0..8191] of Byte);
+ end;
+ end;
+
+function ps4_sceSystemServiceParamGetInt(paramId:Integer;value:Pinteger):Integer;
+var
+ info:DWORD;
+ Format:array[0..0] of AnsiChar;
+ z:timezone;
+begin
+ Result:=0;
+
+ if (value=nil) then Exit(SCE_SYSTEM_SERVICE_ERROR_PARAMETER);
+ value^:=0;
+
+ Case paramId of
+ SCE_SYSTEM_SERVICE_PARAM_ID_LANG:
+ begin
+ sig_lock;
+ info:=GetThreadLocale;
+ sig_unlock;
+ info:=info and $FFFF;
+
+ Case (info and $3FF) of //LANG_*
+ LANG_JAPANESE :value^:=SCE_SYSTEM_PARAM_LANG_JAPANESE;
+
+ LANG_ENGLISH :
+ Case (info shr 10) of //SUBLANG_*
+ SUBLANG_ENGLISH_UK:value^:=SCE_SYSTEM_PARAM_LANG_ENGLISH_GB;
+ else value^:=SCE_SYSTEM_PARAM_LANG_ENGLISH_US;
+ end;
+
+ LANG_FRENCH :
+ Case (info shr 10) of //SUBLANG_*
+ SUBLANG_FRENCH_CANADIAN:value^:=SCE_SYSTEM_PARAM_LANG_FRENCH_CA;
+ else value^:=SCE_SYSTEM_PARAM_LANG_FRENCH;
+ end;
+
+ LANG_SPANISH :
+ Case (info shr 10) of //SUBLANG_*
+ SUBLANG_SPANISH,
+ SUBLANG_SPANISH_MEXICAN,
+ SUBLANG_SPANISH_MODERN:value^:=SCE_SYSTEM_PARAM_LANG_SPANISH;
+ else
+ value^:=SCE_SYSTEM_PARAM_LANG_SPANISH_LA;
+ end;
+
+ LANG_GERMAN :value^:=SCE_SYSTEM_PARAM_LANG_GERMAN;
+ LANG_ITALIAN :value^:=SCE_SYSTEM_PARAM_LANG_ITALIAN;
+ LANG_DUTCH :value^:=SCE_SYSTEM_PARAM_LANG_DUTCH;
+
+ LANG_PORTUGUESE:
+ Case (info shr 10) of //SUBLANG_*
+ SUBLANG_PORTUGUESE:value^:=SCE_SYSTEM_PARAM_LANG_PORTUGUESE_PT;
+ else value^:=SCE_SYSTEM_PARAM_LANG_PORTUGUESE_BR;
+ end;
+
+ LANG_RUSSIAN :value^:=SCE_SYSTEM_PARAM_LANG_RUSSIAN;
+ LANG_KOREAN :value^:=SCE_SYSTEM_PARAM_LANG_KOREAN;
+
+ LANG_CHINESE :
+ Case (info shr 10) of //SUBLANG_*
+ SUBLANG_CHINESE_SIMPLIFIED:value^:=SCE_SYSTEM_PARAM_LANG_CHINESE_S;
+ else value^:=SCE_SYSTEM_PARAM_LANG_CHINESE_T;
+ end;
+
+ LANG_FINNISH :value^:=SCE_SYSTEM_PARAM_LANG_FINNISH;
+ LANG_SWEDISH :value^:=SCE_SYSTEM_PARAM_LANG_SWEDISH;
+ LANG_DANISH :value^:=SCE_SYSTEM_PARAM_LANG_DANISH;
+ LANG_NORWEGIAN :value^:=SCE_SYSTEM_PARAM_LANG_NORWEGIAN;
+ LANG_POLISH :value^:=SCE_SYSTEM_PARAM_LANG_POLISH;
+ LANG_TURKISH :value^:=SCE_SYSTEM_PARAM_LANG_TURKISH;
+ LANG_ARABIC :value^:=SCE_SYSTEM_PARAM_LANG_ARABIC;
+ LANG_CZECH :value^:=SCE_SYSTEM_PARAM_LANG_CZECH;
+ LANG_HUNGARIAN :value^:=SCE_SYSTEM_PARAM_LANG_HUNGARIAN;
+ LANG_GREEK :value^:=SCE_SYSTEM_PARAM_LANG_GREEK;
+ LANG_ROMANIAN :value^:=SCE_SYSTEM_PARAM_LANG_ROMANIAN;
+ LANG_THAI :value^:=SCE_SYSTEM_PARAM_LANG_THAI;
+ LANG_VIETNAMESE:value^:=SCE_SYSTEM_PARAM_LANG_VIETNAMESE;
+ LANG_INDONESIAN:value^:=SCE_SYSTEM_PARAM_LANG_INDONESIAN;
+
+ else
+ value^:=SCE_SYSTEM_PARAM_LANG_ENGLISH_US;
+ end;
+
+ end;
+
+ SCE_SYSTEM_SERVICE_PARAM_ID_DATE_FORMAT:
+ begin
+ Format[0]:=#0;
+ sig_lock;
+ GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_ILDATE,@Format,1);
+ sig_unlock;
+
+ Case Format[0] of
+ '0':value^:=SCE_SYSTEM_PARAM_DATE_FORMAT_MMDDYYYY;
+ '1':value^:=SCE_SYSTEM_PARAM_DATE_FORMAT_DDMMYYYY;
+ '2':value^:=SCE_SYSTEM_PARAM_DATE_FORMAT_YYYYMMDD;
+ end;
+ end;
+
+ SCE_SYSTEM_SERVICE_PARAM_ID_TIME_FORMAT:
+ begin
+ Format[0]:=#0;
+ sig_lock;
+ GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_ILDATE,@Format,1);
+ sig_unlock;
+
+ Case Format[0] of
+ '0':value^:=SCE_SYSTEM_PARAM_TIME_FORMAT_12HOUR;
+ '1':value^:=SCE_SYSTEM_PARAM_TIME_FORMAT_24HOUR;
+ end;
+ end;
+
+ SCE_SYSTEM_SERVICE_PARAM_ID_TIME_ZONE:
+ begin
+ gettimezone(@z);
+ value^:=z.tz_minuteswest;
+ end;
+
+ SCE_SYSTEM_SERVICE_PARAM_ID_SUMMERTIME:
+ begin
+ gettimezone(@z);
+ value^:=z.tz_dsttime;
+ end;
+
+ SCE_SYSTEM_SERVICE_PARAM_ID_SYSTEM_NAME:;
+ SCE_SYSTEM_SERVICE_PARAM_ID_GAME_PARENTAL_LEVEL:value^:=SCE_SYSTEM_PARAM_GAME_PARENTAL_OFF;
+ SCE_SYSTEM_SERVICE_PARAM_ID_ENTER_BUTTON_ASSIGN:value^:=SCE_SYSTEM_PARAM_ENTER_BUTTON_ASSIGN_CROSS;
+
+ else
+ Exit(SCE_SYSTEM_SERVICE_ERROR_PARAMETER);
+ end;
+end;
+
+const
+ CUH='CUH-0000'#0;
+
+function ps4_sceSystemServiceParamGetString(paramId:Integer;buf:Pchar;bufSize:size_t):Integer;
+begin
+ if (buf=nil) then Exit(SCE_SYSTEM_SERVICE_ERROR_PARAMETER);
+
+ Case paramId of
+ SCE_SYSTEM_SERVICE_PARAM_ID_SYSTEM_NAME:
+ begin
+ if (bufSizenil) then
+ begin
+ ptr($80000052);
+ end;
+
+ Writeln('init');
+end;
+
+//
+
+function Load_libSceSystemService(name:pchar):p_lib_info;
+var
+ lib:TLIBRARY;
+begin
+ Result:=obj_new_int('libSceSystemService');
+
+ Result^.init_proc_addr:=@init;
+
+ lib:=Result^.add_lib('libSceSystemService');
+ lib.set_proc($7D9A38F2E9FB2CAE,@ps4_sceSystemServiceParamGetInt);
+ lib.set_proc($4AC0BF9BF4BD2530,@ps4_sceSystemServiceParamGetString);
+ lib.set_proc($568E55F0A0300A69,@ps4_sceSystemServiceHideSplashScreen);
+ lib.set_proc($C75501F5BC0348EC,@ps4_sceSystemServiceDisableMusicPlayer);
+ lib.set_proc($F643C2CFB3ABFB56,@ps4_sceSystemServiceReenableMusicPlayer);
+ lib.set_proc($467DF63B93C3966A,@ps4_sceSystemServiceEnableSuspendConfirmationDialog);
+ lib.set_proc($3D0F928D7020DC43,@ps4_sceSystemServiceDisableSuspendConfirmationDialog);
+ lib.set_proc($D67DFBAB506F7396,@ps4_sceSystemServiceGetDisplaySafeAreaInfo);
+ lib.set_proc($98FA4FC6FE4266DE,@ps4_sceSystemServiceGetHdrToneMapLuminance);
+ lib.set_proc($ACFA3AB55F03F5B3,@ps4_sceSystemServiceGetStatus);
+ lib.set_proc($EB9E8B3104AB83A5,@ps4_sceSystemServiceReceiveEvent);
+
+ lib:=Result^.add_lib('libSceSystemServiceSuspend');
+ lib.set_proc($6B92A38EAE8781C5,@ps4_sceSystemServiceEnableSuspendNotification);
+ lib.set_proc($322D2AC026FEAEFA,@ps4_sceSystemServiceDisableSuspendNotification);
+end;
+
+var
+ stub:t_int_file;
+
+initialization
+ reg_int_file(stub,'libSceSystemService.prx',@Load_libSceSystemService);
+
+end.
+