2022-05-31 07:20:10 +00:00
|
|
|
unit sys_kernel;
|
|
|
|
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
Uses
|
|
|
|
Windows;
|
|
|
|
|
|
|
|
{$I sce_errno.inc}
|
|
|
|
{$I errno.inc}
|
|
|
|
|
2022-09-30 21:25:10 +00:00
|
|
|
var
|
|
|
|
SDK_VERSION:DWORD=0;
|
|
|
|
|
2022-05-31 07:20:10 +00:00
|
|
|
type
|
|
|
|
SceKernelModule=Integer;
|
|
|
|
|
|
|
|
PSceKernelLoadModuleOpt=^SceKernelLoadModuleOpt;
|
|
|
|
SceKernelLoadModuleOpt=packed record
|
|
|
|
size:size_t;
|
|
|
|
end;
|
|
|
|
|
|
|
|
atexit_func=function(param:Pointer):Integer;SysV_ABI_CDecl;
|
2022-09-12 14:13:01 +00:00
|
|
|
TKernelAtexitFuncCount=function(handle:Integer):Integer;SysV_ABI_CDecl;
|
|
|
|
TKernelAtexitReportFunc=procedure(handle:Integer);
|
2022-05-31 07:20:10 +00:00
|
|
|
|
|
|
|
function px2sce(e:Integer):Integer;
|
|
|
|
function sce2px(e:Integer):Integer;
|
|
|
|
|
|
|
|
function _set_errno(r:Integer):Integer;
|
2022-09-13 13:31:03 +00:00
|
|
|
function _set_sce_errno(r:Integer):Integer;
|
2022-05-31 07:20:10 +00:00
|
|
|
function _error:Pointer;
|
|
|
|
|
|
|
|
function SwFreeMem(p:pointer):ptruint;
|
|
|
|
function SwAllocMem(Size:ptruint):pointer;
|
|
|
|
|
|
|
|
Procedure SwYieldExecution; inline;
|
|
|
|
function SwDelayExecution(Alertable:Boolean;DelayInterval:PQWORD):DWORD;
|
|
|
|
|
|
|
|
function SwWaitForSingleObject(
|
|
|
|
ObjectHandle:THandle;
|
|
|
|
TimeOut:PQWORD;
|
|
|
|
Alertable:LONGBOOL):DWORD;
|
|
|
|
|
2022-06-26 20:50:32 +00:00
|
|
|
function SwWaitFor(Handle:THandle;pTimeout:PQWORD):Integer; //pTimeout in ns
|
2022-05-31 07:20:10 +00:00
|
|
|
|
|
|
|
Function safe_move(const src;var dst;count:QWORD):QWORD;
|
|
|
|
procedure safe_move_ptr(const src;var dst);
|
|
|
|
function safe_test(var src:DWORD;value:DWORD):Boolean;
|
|
|
|
function safe_str(P:PChar):shortstring;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
|
|
|
ntapi,
|
|
|
|
sys_pthread,
|
|
|
|
sys_signal,
|
|
|
|
sys_time;
|
|
|
|
|
|
|
|
function px2sce(e:Integer):Integer;
|
|
|
|
begin
|
|
|
|
if (e=0) then
|
|
|
|
Result:=0
|
|
|
|
else
|
|
|
|
Result:=e-$7ffe0000;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function sce2px(e:Integer):Integer;
|
|
|
|
begin
|
|
|
|
if (e=0) then
|
|
|
|
Result:=0
|
|
|
|
else
|
|
|
|
Result:=e+$7ffe0000;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function _set_errno(r:Integer):Integer;
|
|
|
|
var
|
|
|
|
t:pthread;
|
|
|
|
begin
|
2022-09-13 13:59:10 +00:00
|
|
|
Result:=0;
|
|
|
|
|
|
|
|
t:=tcb_thread;
|
|
|
|
if (t<>nil) then t^.errno:=r;
|
|
|
|
|
|
|
|
if (r<>0) then
|
2022-05-31 07:20:10 +00:00
|
|
|
begin
|
2022-09-13 13:59:10 +00:00
|
|
|
Result:=-1;
|
2022-05-31 07:20:10 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-09-13 13:31:03 +00:00
|
|
|
function _set_sce_errno(r:Integer):Integer;
|
|
|
|
var
|
|
|
|
t:pthread;
|
|
|
|
begin
|
2022-09-13 13:59:10 +00:00
|
|
|
t:=tcb_thread;
|
|
|
|
if (t<>nil) then t^.errno:=sce2px(r);
|
|
|
|
|
2022-09-13 13:31:03 +00:00
|
|
|
Result:=r;
|
|
|
|
end;
|
|
|
|
|
2022-05-31 07:20:10 +00:00
|
|
|
function _error:Pointer;
|
|
|
|
var
|
|
|
|
t:pthread;
|
|
|
|
begin
|
|
|
|
Result:=nil;
|
|
|
|
t:=tcb_thread;
|
|
|
|
if (t<>nil) then Result:=@t^.errno;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function SwFreeMem(p:pointer):ptruint;
|
|
|
|
begin
|
|
|
|
_sig_lock;
|
|
|
|
Result:=FreeMem(p);
|
|
|
|
_sig_unlock;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function SwAllocMem(Size:ptruint):pointer;
|
|
|
|
begin
|
|
|
|
_sig_lock;
|
|
|
|
Result:=AllocMem(Size);
|
|
|
|
_sig_unlock;
|
|
|
|
end;
|
|
|
|
|
|
|
|
Procedure SwYieldExecution; inline;
|
|
|
|
begin
|
|
|
|
_sig_lock;
|
|
|
|
NtYieldExecution;
|
|
|
|
_sig_unlock;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function SwDelayExecution(Alertable:Boolean;DelayInterval:PQWORD):DWORD;
|
|
|
|
begin
|
2022-07-14 20:16:23 +00:00
|
|
|
_sig_lock(ord(Alertable));
|
2022-05-31 07:20:10 +00:00
|
|
|
Result:=NtDelayExecution(Alertable,Pointer(DelayInterval));
|
|
|
|
_sig_unlock;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
function SwWaitForSingleObject(
|
|
|
|
ObjectHandle:THandle;
|
|
|
|
TimeOut:PQWORD;
|
|
|
|
Alertable:LONGBOOL):DWORD;
|
|
|
|
begin
|
2022-07-14 20:16:23 +00:00
|
|
|
_sig_lock(ord(Alertable));
|
2022-05-31 07:20:10 +00:00
|
|
|
Result:=NtWaitForSingleObject(ObjectHandle,Alertable,Pointer(TimeOut));
|
|
|
|
_sig_unlock;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function SwWaitFor(Handle:THandle;pTimeout:PQWORD):Integer;
|
|
|
|
var
|
|
|
|
timeout:Int64;
|
|
|
|
passed :Int64;
|
|
|
|
START:QWORD;
|
|
|
|
QTIME:QWORD;
|
|
|
|
res:DWORD;
|
|
|
|
begin
|
|
|
|
Result:=0;
|
|
|
|
|
|
|
|
if (pTimeout<>nil) then
|
|
|
|
begin
|
|
|
|
timeout:=(pTimeout^ div 100);
|
|
|
|
SwSaveTime(START);
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
timeout:=NT_INFINITE;
|
|
|
|
end;
|
|
|
|
|
|
|
|
repeat
|
|
|
|
|
|
|
|
if (pTimeout<>nil) then
|
|
|
|
begin
|
|
|
|
if (timeout=0) then
|
|
|
|
begin
|
2022-06-07 13:24:08 +00:00
|
|
|
pTimeout^:=0;
|
2022-05-31 07:20:10 +00:00
|
|
|
Result:=ETIMEDOUT;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
|
|
|
|
SwSaveTime(QTIME);
|
|
|
|
|
|
|
|
timeout:=-timeout;
|
2022-07-14 20:16:23 +00:00
|
|
|
_sig_lock(SL_ALERTABLE);
|
2022-05-31 07:20:10 +00:00
|
|
|
res:=NtWaitForSingleObject(Handle,True,@timeout);
|
|
|
|
_sig_unlock;
|
|
|
|
timeout:=-timeout;
|
|
|
|
|
|
|
|
passed:=SwTimePassedUnits(QTIME);
|
|
|
|
|
|
|
|
if (passed>=timeout) then
|
|
|
|
begin
|
|
|
|
timeout:=0;
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
timeout:=timeout-passed;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end else
|
|
|
|
begin
|
2022-07-14 20:16:23 +00:00
|
|
|
_sig_lock(SL_ALERTABLE);
|
2022-05-31 07:20:10 +00:00
|
|
|
res:=NtWaitForSingleObject(Handle,True,@timeout);
|
|
|
|
_sig_unlock;
|
|
|
|
end;
|
|
|
|
|
|
|
|
case res of
|
|
|
|
STATUS_ALERTED,
|
|
|
|
STATUS_USER_APC:
|
|
|
|
begin
|
|
|
|
//continue
|
|
|
|
end;
|
|
|
|
STATUS_TIMEOUT:
|
|
|
|
begin
|
2022-06-07 13:24:08 +00:00
|
|
|
if (pTimeout<>nil) then
|
|
|
|
begin
|
2022-06-07 20:12:11 +00:00
|
|
|
pTimeout^:=0;
|
2022-06-07 13:24:08 +00:00
|
|
|
end;
|
2022-05-31 07:20:10 +00:00
|
|
|
Result:=ETIMEDOUT;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
STATUS_ABANDONED:
|
|
|
|
begin
|
2022-06-07 20:12:11 +00:00
|
|
|
if (pTimeout<>nil) then
|
|
|
|
begin
|
|
|
|
pTimeout^:=timeout*100;
|
|
|
|
end;
|
2022-05-31 07:20:10 +00:00
|
|
|
Result:=EPERM;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
STATUS_SUCCESS:
|
|
|
|
begin
|
2022-06-07 20:12:11 +00:00
|
|
|
if (pTimeout<>nil) then
|
|
|
|
begin
|
|
|
|
pTimeout^:=timeout*100;
|
|
|
|
end;
|
2022-05-31 07:20:10 +00:00
|
|
|
Result:=0;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
else
|
|
|
|
begin
|
2022-06-07 20:12:11 +00:00
|
|
|
if (pTimeout<>nil) then
|
|
|
|
begin
|
|
|
|
pTimeout^:=timeout*100;
|
|
|
|
end;
|
2022-05-31 07:20:10 +00:00
|
|
|
Result:=EINVAL;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
until false;
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
Function safe_move(const src;var dst;count:QWORD):QWORD;
|
|
|
|
begin
|
|
|
|
_sig_lock;
|
|
|
|
if not ReadProcessMemory(GetCurrentProcess,@src,@dst,count,Result) then Result:=0;
|
|
|
|
_sig_unlock;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure safe_move_ptr(const src;var dst);
|
|
|
|
begin
|
|
|
|
if safe_move(src,dst,SizeOf(Pointer))<>SizeOf(Pointer) then Pointer(dst):=nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function safe_test(var src:DWORD;value:DWORD):Boolean;
|
|
|
|
var
|
|
|
|
t:DWORD;
|
|
|
|
begin
|
|
|
|
Result:=False;
|
|
|
|
t:=0;
|
|
|
|
if (safe_move(src,t,SizeOf(DWORD))=SizeOf(DWORD)) then
|
|
|
|
begin
|
|
|
|
Result:=(t=value);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function safe_str(P:PChar):shortstring;
|
|
|
|
var
|
|
|
|
ch:Char;
|
|
|
|
begin
|
|
|
|
Result:='';
|
|
|
|
repeat
|
|
|
|
ch:=#0;
|
|
|
|
safe_move(P^,ch,SizeOf(Char));
|
|
|
|
if (ch=#0) then Exit;
|
|
|
|
Result:=Result+ch;
|
|
|
|
if (Result[0]=#255) then Exit;
|
|
|
|
Inc(P);
|
|
|
|
until false;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|
|
|