This commit is contained in:
red-prig 2022-11-13 00:59:35 +03:00
parent 4fbb608639
commit 40b2c39b5c
13 changed files with 235 additions and 494 deletions

View File

@ -6,7 +6,6 @@ interface
uses uses
windows, windows,
sys_types,
sys_path, sys_path,
sys_fd, sys_fd,
sys_file, sys_file,
@ -42,6 +41,11 @@ function ps4_sceKernelPwrite(fd:Integer;buf:Pointer;nbytes,offset:Int64):Int64;
function ps4_fstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; function ps4_fstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
function ps4_sceKernelFstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; function ps4_sceKernelFstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
function ps4_getdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl;
function ps4_getdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl;
function ps4_sceKernelGetdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl;
function ps4_sceKernelGetdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl;
function ps4_stat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; function ps4_stat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
function ps4_sceKernelStat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; function ps4_sceKernelStat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
@ -54,78 +58,20 @@ implementation
uses uses
sys_kernel, sys_kernel,
sys_signal, sys_signal;
sys_time;
Function get_DesiredAccess(flags:Integer):DWORD;
begin
Result:=0;
if (flags and SCE_KERNEL_O_RDWR)<>0 then
begin
Result:=GENERIC_READ or GENERIC_WRITE;
end else
if (flags and SCE_KERNEL_O_WRONLY)<>0 then
begin
Result:=GENERIC_WRITE;
end else
begin
Result:=GENERIC_READ;
end;
if (flags and SCE_KERNEL_O_APPEND)<>0 then
begin
Result:=Result or FILE_APPEND_DATA;
end;
end;
Function get_CreationDisposition(flags:Integer):DWORD;
const
CREAT_EXCL=SCE_KERNEL_O_CREAT or SCE_KERNEL_O_EXCL;
begin
Result:=0;
if (flags and CREAT_EXCL)=CREAT_EXCL then
begin
Result:=CREATE_NEW;
end else
if (flags and SCE_KERNEL_O_CREAT)<>0 then
begin
Result:=CREATE_ALWAYS;
end else
if (flags and SCE_KERNEL_O_TRUNC)<>0 then
begin
Result:=TRUNCATE_EXISTING;
end else
begin
Result:=OPEN_EXISTING;
end;
end;
var
dev_random_nm:array[0..1] of PChar=('/dev/random','/dev/urandom');
dev_random_fd:Integer=-1;
function _sys_open(path:PChar;flags,mode:Integer):Integer; function _sys_open(path:PChar;flags,mode:Integer):Integer;
const const
WR_RDWR=O_WRONLY or O_RDWR; WR_RDWR=O_WRONLY or O_RDWR;
O_OFS=O_RDONLY or O_WRONLY or O_RDWR or O_APPEND;
var var
h:THandle;
err:DWORD;
dwDesiredAccess:DWORD;
dwCreationDisposition:DWORD;
rp:RawByteString; rp:RawByteString;
wp:WideString;
begin begin
Result:=0; Result:=0;
if (path=nil) then Exit(-EINVAL); if (path=nil) then Exit(-EINVAL);
Writeln('open:',path,' ',flags,' (',OctStr(mode,3),')'); Writeln('open:',path,' ',flags,' (',OctStr(mode,3),')');
Assert((flags and O_DIRECTORY)=0,'folder open TODO');
if ((flags and WR_RDWR)=WR_RDWR) then if ((flags and WR_RDWR)=WR_RDWR) then
begin begin
Exit(-EINVAL); Exit(-EINVAL);
@ -136,82 +82,33 @@ begin
Exit(-ENOENT); Exit(-ENOENT);
end; end;
if (CompareChar0(path^,dev_random_nm[0]^,Length(dev_random_nm[0]))=0) or
(CompareChar0(path^,dev_random_nm[1]^,Length(dev_random_nm[1]))=0) then
begin
if (dev_random_fd<>-1) then
begin
Exit(dev_random_fd);
end else
begin
h:=_get_osfhandle(0);
Result:=_open_osfhandle(h,flags and O_OFS);
if (Result<0) then
begin
Exit(-EMFILE);
end else
begin
dev_random_fd:=Result;
Exit;
end;
end;
end;
rp:=''; rp:='';
Result:=parse_filename(path,rp); Result:=parse_filename(path,rp);
Case Result of Case Result of
PT_ROOT:Exit(-EACCES); //TODO PT_ROOT:Exit(-EACCES); //TODO
PT_FILE:; PT_FILE:
PT_DEV :Exit(-EACCES); //TODO begin
if DirectoryExists(rp) then
begin
Result:=_sys_dir_open(rp,flags,mode);
end else
begin
if (flags and O_DIRECTORY)<>0 then
begin
Exit(-ENOTDIR);
end;
Result:=_sys_file_open(rp,flags,mode);
end;
end;
PT_DEV:
begin
Result:=_sys_dev_open(rp,flags,mode);
end;
else else
Exit(-EACCES); Exit(-EACCES);
end; end;
wp:=UTF8Decode(rp);
dwDesiredAccess:=get_DesiredAccess(flags);
dwCreationDisposition:=get_CreationDisposition(flags);
h:=CreateFileW(
PWideChar(wp),
dwDesiredAccess,
FILE_SHARE_READ,
nil,
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
0
);
if (h=INVALID_HANDLE_VALUE) then
begin
err:=GetLastError;
//Writeln('GetLastError:',err{,' ',ps4_pthread_self^.sig._lock});
Case err of
ERROR_INVALID_DRIVE,
ERROR_PATH_NOT_FOUND,
ERROR_FILE_NOT_FOUND :Exit(-ENOENT);
ERROR_ACCESS_DENIED :Exit(-EACCES);
ERROR_BUFFER_OVERFLOW :Exit(-ENAMETOOLONG);
ERROR_NOT_ENOUGH_MEMORY:Exit(-ENOMEM);
ERROR_ALREADY_EXISTS :Exit(-EEXIST);
ERROR_FILE_EXISTS :Exit(-EEXIST);
ERROR_DISK_FULL :Exit(-ENOSPC);
else
Exit(-EIO);
end;
end;
Result:=_open_osfhandle(h,flags and O_OFS);
if (Result<0) then
begin
CloseHandle(h);
Exit(-EMFILE);
end;
end; end;
function ps4_open(path:PChar;flags,mode:Integer):Integer; SysV_ABI_CDecl; function ps4_open(path:PChar;flags,mode:Integer):Integer; SysV_ABI_CDecl;
@ -246,21 +143,6 @@ begin
end; end;
end; end;
function _sys_close(fd:Integer):Integer;
begin
if (dev_random_fd<>-1) and (dev_random_fd=fd) then
begin
Exit(0);
end;
Result:=_close(fd);
if (Result<>0) then
begin
Result:=EBADF;
end;
end;
function ps4_close(fd:Integer):Integer; SysV_ABI_CDecl; function ps4_close(fd:Integer):Integer; SysV_ABI_CDecl;
begin begin
_sig_lock; _sig_lock;
@ -278,47 +160,27 @@ begin
Result:=px2sce(Result); Result:=px2sce(Result);
end; end;
function SetFilePointerEx(hFile:HANDLE;
liDistanceToMove:LARGE_INTEGER;
lpNewFilePointer:PLARGE_INTEGER;
dwMoveMethod:DWORD):BOOL; external 'kernel32';
function _sys_lseek(fd:Integer;offset:Int64;whence:Integer):Int64; function _sys_lseek(fd:Integer;offset:Int64;whence:Integer):Int64;
var var
h:THandle; f:TCustomFile;
err:DWORD;
begin begin
Result:=0; Result:=0;
if (fd<0) then Exit(-EINVAL); if (fd<0) then Exit(-EINVAL);
if (dev_random_fd=fd) then Exit(-ESPIPE);
h:=_get_osfhandle(fd);
if (h=INVALID_HANDLE_VALUE) then
begin
Exit(-EBADF);
end;
case whence of case whence of
SEEK_SET, SEEK_SET,
SEEK_CUR, SEEK_CUR,
SEEK_END: SEEK_END:;
begin
if not SetFilePointerEx(h,LARGE_INTEGER(offset),@Result,whence) then
begin
err:=GetLastError;
Case err of
ERROR_HANDLE_EOF :Exit(-EOVERFLOW);
ERROR_INVALID_PARAMETER:Exit(-EINVAL);
else
Exit(-EOVERFLOW);
end;
end;
end;
else else
Exit(-EINVAL); Exit(-EINVAL);
end; end;
f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
Result:=f.lseek(offset,whence);
f.Release;
end; end;
function ps4_lseek(fd:Integer;offset:Int64;whence:Integer):Int64; SysV_ABI_CDecl; function ps4_lseek(fd:Integer;offset:Int64;whence:Integer):Int64; SysV_ABI_CDecl;
@ -353,46 +215,20 @@ begin
end; end;
end; end;
const
BCRYPT_USE_SYSTEM_PREFERRED_RNG=2;
function BCryptGenRandom(hAlgorithm:Pointer;
pbBuffer:PByte;
cbBuffer:DWORD;
dwFlags:DWORD):DWORD; stdcall; external 'Bcrypt';
function _sys_read(fd:Integer;data:Pointer;size:Int64):Int64; function _sys_read(fd:Integer;data:Pointer;size:Int64):Int64;
var var
h:THandle; f:TCustomFile;
N:DWORD;
begin begin
if (data=nil) then Exit(-EFAULT); if (data=nil) then Exit(-EFAULT);
if (fd<0) then Exit(-EINVAL); if (fd<0) then Exit(-EINVAL);
if (size<=0) then Exit(-EINVAL); if (size<=0) then Exit(-EINVAL);
Assert(size<High(DWORD)); f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
if (dev_random_fd=fd) then Result:=f.read(data,size);
begin
BCryptGenRandom(nil,data,size,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
Exit(size);
end;
h:=_get_osfhandle(fd); f.Release;
if (h=INVALID_HANDLE_VALUE) then
begin
Exit(-EBADF);
end;
N:=0;
if ReadFile(h,data^,size,N,nil) then
begin
Result:=N;
end else
begin
Result:=-EIO;
end;
end; end;
function ps4_read(fd:Integer;data:Pointer;size:Int64):Int64; SysV_ABI_CDecl; function ps4_read(fd:Integer;data:Pointer;size:Int64):Int64; SysV_ABI_CDecl;
@ -427,65 +263,21 @@ begin
end; end;
end; end;
function _get_pos(h:THandle):Int64;
const
zero:LARGE_INTEGER=(QuadPart:0);
begin
Result:=-1;
if not SetFilePointerEx(h,zero,@Result,FILE_CURRENT) then
begin
Result:=-1;
end;
end;
procedure _set_pos(h:THandle;p:Int64);
begin
SetFilePointerEx(h,LARGE_INTEGER(p),nil,FILE_BEGIN);
end;
function _sys_pread(fd:Integer;data:Pointer;size,offset:Int64):Int64; function _sys_pread(fd:Integer;data:Pointer;size,offset:Int64):Int64;
var var
h:THandle; f:TCustomFile;
N:DWORD;
O:TOVERLAPPED;
p:Int64;
begin begin
if (data=nil) then Exit(-EFAULT);
if (fd<0) then Exit(-EINVAL); if (fd<0) then Exit(-EINVAL);
if (data=nil) then Exit(-EFAULT);
if (size<=0) then Exit(-EINVAL); if (size<=0) then Exit(-EINVAL);
if (offset<0) then Exit(-EINVAL); if (offset<0) then Exit(-EINVAL);
Assert(size<High(DWORD)); f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
if (dev_random_fd=fd) then Result:=f.pread(data,size,offset);
begin
BCryptGenRandom(nil,data,size,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
Exit(size);
end;
h:=_get_osfhandle(fd); f.Release;
if (h=INVALID_HANDLE_VALUE) then
begin
Exit(-EBADF);
end;
O:=Default(TOVERLAPPED);
PInt64(@O.Offset)^:=offset;
//NOTE: pread and pwrite don't change the file position, but ReadFile/WriteFile do, damn it.
p:=_get_pos(h);
N:=0;
if ReadFile(h,data^,size,N,@O) then
begin
Result:=N;
end else
begin
Result:=-EIO;
end;
_set_pos(h,p);
end; end;
function ps4_pread(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl; function ps4_pread(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl;
@ -522,8 +314,7 @@ end;
function _sys_readv(fd:Integer;vector:p_iovec;count:Integer):Int64; function _sys_readv(fd:Integer;vector:p_iovec;count:Integer):Int64;
var var
h:THandle; f:TCustomFile;
N:DWORD;
i:Integer; i:Integer;
begin begin
if (vector=nil) then Exit(-EFAULT); if (vector=nil) then Exit(-EFAULT);
@ -536,42 +327,12 @@ begin
if (vector[i].iov_len<=0) then Exit(-EINVAL); if (vector[i].iov_len<=0) then Exit(-EINVAL);
end; end;
if (dev_random_fd=fd) then f:=_sys_acqure_fd(fd);
begin if (f=nil) then Exit(-EBADF);
Result:=0; Result:=f.readv(vector,count);
For i:=0 to count-1 do
begin
BCryptGenRandom(nil,vector[i].iov_base,vector[i].iov_len,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
Result:=Result+vector[i].iov_len;
end;
Exit;
end;
h:=_get_osfhandle(fd);
if (h=INVALID_HANDLE_VALUE) then
begin
Exit(-EBADF);
end;
Result:=0;
For i:=0 to count-1 do
begin
N:=0;
if ReadFile(h,vector[i].iov_base^,vector[i].iov_len,N,nil) then
begin
Result:=Result+N;
if (N<vector[i].iov_len) then Exit;
end else
begin
Exit(-EIO);
Break;
end;
end;
f.Release;
end; end;
function ps4_readv(fd:Integer;vector:p_iovec;count:Integer):Int64; SysV_ABI_CDecl; function ps4_readv(fd:Integer;vector:p_iovec;count:Integer):Int64; SysV_ABI_CDecl;
@ -608,32 +369,18 @@ end;
function _sys_write(fd:Integer;data:Pointer;size:Int64):Int64; function _sys_write(fd:Integer;data:Pointer;size:Int64):Int64;
var var
h:THandle; f:TCustomFile;
N:DWORD;
begin begin
if (data=nil) then Exit(-EFAULT); if (data=nil) then Exit(-EFAULT);
if (fd<0) then Exit(-EINVAL); if (fd<0) then Exit(-EINVAL);
if (size<=0) then Exit(-EINVAL); if (size<=0) then Exit(-EINVAL);
Assert(size<High(DWORD)); f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
if (dev_random_fd=fd) then Exit(-EPIPE); Result:=f.write(data,size);
h:=_get_osfhandle(fd); f.Release;
if (h=INVALID_HANDLE_VALUE) then
begin
Exit(-EBADF);
end;
N:=0;
if WriteFile(h,data^,size,N,nil) then
begin
Result:=N;
end else
begin
Result:=-EIO;
end;
end; end;
function ps4_write(fd:Integer;data:Pointer;size:Int64):Int64; SysV_ABI_CDecl; function ps4_write(fd:Integer;data:Pointer;size:Int64):Int64; SysV_ABI_CDecl;
@ -670,43 +417,19 @@ end;
function _sys_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; function _sys_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64;
var var
h:THandle; f:TCustomFile;
N:DWORD;
O:TOVERLAPPED;
p:Int64;
begin begin
if (data=nil) then Exit(-EFAULT);
if (fd<0) then Exit(-EINVAL); if (fd<0) then Exit(-EINVAL);
if (data=nil) then Exit(-EFAULT);
if (size<=0) then Exit(-EINVAL); if (size<=0) then Exit(-EINVAL);
if (offset<0) then Exit(-EINVAL); if (offset<0) then Exit(-EINVAL);
Assert(size<High(DWORD)); f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
if (dev_random_fd=fd) then Exit(-EPIPE); Result:=f.pwrite(data,size,offset);
h:=_get_osfhandle(fd); f.Release;
if (h=INVALID_HANDLE_VALUE) then
begin
Exit(-EBADF);
end;
O:=Default(TOVERLAPPED);
PInt64(@O.Offset)^:=offset;
//NOTE: pread and pwrite don't change the file position, but ReadFile/WriteFile do, damn it.
p:=_get_pos(h);
N:=0;
if WriteFile(h,data^,size,N,@O) then
begin
Result:=N;
end else
begin
Result:=-EIO;
end;
_set_pos(h,p);
end; end;
function ps4_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl; function ps4_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl;
@ -741,92 +464,19 @@ begin
end; end;
end; end;
function file_attr_to_st_mode(attr:DWORD):Word;
begin
Result:=S_IRUSR;
if ((attr and FILE_ATTRIBUTE_DIRECTORY)<>0) then
Result:=Result or S_IFDIR
else
Result:=Result or S_IFREG;
if ((attr and FILE_ATTRIBUTE_READONLY)=0) then
Result:=Result or S_IWUSR;
end;
function _sys_fstat(fd:Integer;stat:PSceKernelStat):Integer; function _sys_fstat(fd:Integer;stat:PSceKernelStat):Integer;
var var
h:THandle; f:TCustomFile;
hfi:TByHandleFileInformation;
err:DWORD;
begin begin
if (fd<0) then Exit(EINVAL);
if (stat=nil) then Exit(EINVAL); if (stat=nil) then Exit(EINVAL);
stat^:=Default(SceKernelStat); f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
h:=_get_osfhandle(fd); Result:=f.fstat(stat);
if (h=INVALID_HANDLE_VALUE) then f.Release;
begin
Exit(EBADF);
end;
Case SwGetFileType(h) of
FILE_TYPE_PIPE:
begin
stat^.st_dev :=fd;
stat^.st_rdev :=fd;
stat^.st_mode :=S_IFIFO;
stat^.st_nlink:=1;
end;
FILE_TYPE_CHAR:
begin
stat^.st_dev :=fd;
stat^.st_rdev :=fd;
stat^.st_mode :=S_IFCHR;
stat^.st_nlink:=1;
end;
FILE_TYPE_DISK:
begin
err:=SwGetFileInformationByHandle(h,@hfi);
if (err<>0) then
begin
Case err of
ERROR_ACCESS_DENIED,
ERROR_SHARING_VIOLATION,
ERROR_LOCK_VIOLATION,
ERROR_SHARING_BUFFER_EXCEEDED:
Exit(EACCES);
ERROR_BUFFER_OVERFLOW:
Exit(ENAMETOOLONG);
ERROR_NOT_ENOUGH_MEMORY:
Exit(ENOMEM);
else
Exit(ENOENT);
end;
end;
stat^.st_mode :=file_attr_to_st_mode(hfi.dwFileAttributes);
stat^.st_size :=hfi.nFileSizeLow or (QWORD(hfi.nFileSizeHigh) shl 32);
stat^.st_nlink :=Word(hfi.nNumberOfLinks);
stat^.st_gen :=hfi.nFileIndexLow;
stat^.st_atim :=filetime_to_timespec(hfi.ftLastAccessTime);
stat^.st_mtim :=filetime_to_timespec(hfi.ftLastWriteTime);
stat^.st_ctim :=stat^.st_mtim;
stat^.st_birthtim:=filetime_to_timespec(hfi.ftCreationTime);
stat^.st_blocks :=((stat^.st_size+511) div 512);
stat^.st_blksize :=512;
end;
else
Exit(EBADF);
end;
Result:=0;
end; end;
function ps4_fstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; function ps4_fstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
@ -846,11 +496,75 @@ begin
Result:=px2sce(Result); Result:=px2sce(Result);
end; end;
function _sys_getdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64;
var
f:TCustomFile;
begin
if (fd<0) then Exit(-EINVAL);
if (buf=nil) then Exit(-EFAULT);
if (nbytes<=0) then Exit(-EINVAL);
f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
Result:=f.getdirentries(buf,nbytes,basep);
f.Release;
end;
function ps4_getdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl;
begin
_sig_lock;
Result:=_sys_getdirentries(fd,buf,nbytes,basep);
_sig_unlock;
if (Result<0) then
begin
Result:=_set_errno(-Result);
end else
begin
_set_errno(0);
end;
end;
function ps4_getdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl;
begin
_sig_lock;
Result:=_sys_getdirentries(fd,buf,nbytes,nil);
_sig_unlock;
if (Result<0) then
begin
Result:=_set_errno(-Result);
end else
begin
_set_errno(0);
end;
end;
function ps4_sceKernelGetdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl;
begin
_sig_lock;
Result:=_sys_getdirentries(fd,buf,nbytes,basep);
_sig_unlock;
_set_errno(Result);
Result:=px2sce(Result);
end;
function ps4_sceKernelGetdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl;
begin
_sig_lock;
Result:=_sys_getdirentries(fd,buf,nbytes,nil);
_sig_unlock;
_set_errno(Result);
Result:=px2sce(Result);
end;
function _sys_stat(path:PChar;stat:PSceKernelStat):Integer; function _sys_stat(path:PChar;stat:PSceKernelStat):Integer;
var var
rp:RawByteString; rp:RawByteString;
hfi:WIN32_FILE_ATTRIBUTE_DATA;
err:DWORD;
begin begin
if (path=nil) or (stat=nil) then Exit(EINVAL); if (path=nil) or (stat=nil) then Exit(EINVAL);
@ -859,60 +573,28 @@ begin
Exit(ENOENT); Exit(ENOENT);
end; end;
stat^:=Default(SceKernelStat);
rp:=''; rp:='';
Result:=parse_filename(path,rp); Result:=parse_filename(path,rp);
Case Result of Case Result of
PT_ROOT:Exit(-EACCES); //TODO PT_ROOT:Exit(-EACCES); //TODO
PT_FILE:; PT_FILE:
PT_DEV :
begin begin
stat^.st_dev :=1; if DirectoryExists(rp) then
stat^.st_rdev :=1; begin
stat^.st_mode :=S_IFCHR; Result:=_sys_dir_stat(rp,stat);
stat^.st_nlink:=1; end else
Exit(0); begin
end Result:=_sys_file_stat(rp,stat);
end;
end;
PT_DEV:
begin
Result:=_sys_dev_stat(rp,stat);
end;
else else
Exit(-EACCES); Exit(-EACCES);
end; end;
hfi:=Default(WIN32_FILE_ATTRIBUTE_DATA);
err:=SwGetFileAttributes(rp,@hfi);
if (err<>0) then
begin
Case err of
ERROR_ACCESS_DENIED,
ERROR_SHARING_VIOLATION,
ERROR_LOCK_VIOLATION,
ERROR_SHARING_BUFFER_EXCEEDED:
Exit(SCE_KERNEL_ERROR_EACCES);
ERROR_BUFFER_OVERFLOW:
Exit(ENAMETOOLONG);
ERROR_NOT_ENOUGH_MEMORY:
Exit(ENOMEM);
else
Exit(ENOENT);
end;
end;
stat^.st_mode :=file_attr_to_st_mode(hfi.dwFileAttributes);
stat^.st_size :=hfi.nFileSizeLow or (QWORD(hfi.nFileSizeHigh) shl 32);
stat^.st_atim :=filetime_to_timespec(hfi.ftLastAccessTime);
stat^.st_mtim :=filetime_to_timespec(hfi.ftLastWriteTime);
stat^.st_ctim :=stat^.st_mtim;
stat^.st_birthtim:=filetime_to_timespec(hfi.ftCreationTime);
stat^.st_blocks :=((stat^.st_size+511) div 512);
stat^.st_blksize :=512;
Result:=0;
end; end;
function ps4_stat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; function ps4_stat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;

View File

@ -40,7 +40,8 @@ uses
sys_path, sys_path,
sys_kernel, sys_kernel,
sys_pthread, sys_pthread,
sys_signal; sys_signal,
sys_dev;
type type
pSceKernelUuid=^SceKernelUuid; pSceKernelUuid=^SceKernelUuid;
@ -868,6 +869,13 @@ begin
lib^.set_proc($E1F539CAF3A4546E,@ps4_sceSysmoduleGetModuleInfoForUnwind); lib^.set_proc($E1F539CAF3A4546E,@ps4_sceSysmoduleGetModuleInfoForUnwind);
end; end;
procedure _kernel_init;
begin
_mem_init;
_sys_dev_init;
ps4_sceKernelGetCompiledSdkVersion(@SDK_VERSION);
end;
function Load_libkernel(Const name:RawByteString):TElf_node; function Load_libkernel(Const name:RawByteString):TElf_node;
var var
lib,px:PLIBRARY; lib,px:PLIBRARY;
@ -1255,6 +1263,9 @@ begin
lib^.set_proc($9CA5A2FCDD87055E,@ps4_sceKernelPwrite); lib^.set_proc($9CA5A2FCDD87055E,@ps4_sceKernelPwrite);
lib^.set_proc($901C023EC617FE6E,@ps4_sceKernelFstat); lib^.set_proc($901C023EC617FE6E,@ps4_sceKernelFstat);
lib^.set_proc($B5A4568532454E01,@ps4_sceKernelGetdirentries);
lib^.set_proc($8F6008A92A893F4C,@ps4_sceKernelGetdents);
lib^.set_proc($C2E0ABA081A3B768,@ps4_open); //open lib^.set_proc($C2E0ABA081A3B768,@ps4_open); //open
lib^.set_proc($E9CDEB09513F7D35,@ps4_open); //_open lib^.set_proc($E9CDEB09513F7D35,@ps4_open); //_open
@ -1278,6 +1289,9 @@ begin
lib^.set_proc($9AA40C875CCF3D3F,@ps4_fstat); lib^.set_proc($9AA40C875CCF3D3F,@ps4_fstat);
lib^.set_proc($7F4F4ABC83F2FD06,@ps4_getdirentries);
lib^.set_proc($D86EA2EA13085146,@ps4_getdents);
lib^.set_proc($13A6A8DF8C0FC3E5,@ps4_stat); lib^.set_proc($13A6A8DF8C0FC3E5,@ps4_stat);
lib^.set_proc($795F70003DAB8880,@ps4_sceKernelStat); lib^.set_proc($795F70003DAB8880,@ps4_sceKernelStat);
@ -1301,8 +1315,7 @@ begin
lib^.set_proc($8A5D379E5B8A7CC9,@ps4_sceKernelRaiseException); lib^.set_proc($8A5D379E5B8A7CC9,@ps4_sceKernelRaiseException);
// //
ps4_sceKernelGetCompiledSdkVersion(@SDK_VERSION); _kernel_init;
_mem_init;
end; end;
initialization initialization

View File

@ -1342,7 +1342,7 @@ initialization
ps4_app.files.Init; ps4_app.files.Init;
ps4_app.mods.Init; ps4_app.mods.Init;
ps4_app.libs.Init; ps4_app.libs.Init;
ps4_app.elfs:=TIntegerHandles.Create; ps4_app.elfs:=TIntegerHandles.Create(1);
end. end.

View File

@ -88,6 +88,7 @@ function _VirtualQuery (addr:Pointer;paddr:PPointer;psize:Pptruint;pprots,pfla
implementation implementation
uses uses
sys_fd,
sys_kernel; sys_kernel;
const const
@ -236,7 +237,7 @@ begin
Result:=0; Result:=0;
if (Addr=nil) then Exit(-1); if (Addr=nil) then Exit(-1);
h:=_get_osfhandle(fd); h:=_sys_get_osfhandle(fd);
if (h=INVALID_HANDLE_VALUE) then if (h=INVALID_HANDLE_VALUE) then
begin begin
Exit(GetLastError); Exit(GetLastError);

View File

@ -32,7 +32,6 @@ type
TIntegerHandles=class TIntegerHandles=class
private private
Const Const
def_min_key=1;
def_max_key=$7FFFFFFF; def_max_key=$7FFFFFFF;
var var
FStub:TSTUB_HAMT32; FStub:TSTUB_HAMT32;
@ -41,7 +40,7 @@ type
FLock:TRWLock; FLock:TRWLock;
public public
min_key,max_key:Integer; min_key,max_key:Integer;
constructor Create; constructor Create(min:Integer);
destructor Destroy; override; destructor Destroy; override;
function New(H:TClassHandle;var OutKey:Integer):Boolean; function New(H:TClassHandle;var OutKey:Integer):Boolean;
function Acqure(const Key:Integer):TClassHandle; function Acqure(const Key:Integer):TClassHandle;
@ -85,11 +84,11 @@ begin
rwlock_unlock(FLock); rwlock_unlock(FLock);
end; end;
constructor TIntegerHandles.Create; constructor TIntegerHandles.Create(min:Integer);
begin begin
min_key:=def_min_key; min_key:=min;
max_key:=def_max_key; max_key:=def_max_key;
FPos:=def_min_key; FPos:=min;
FHAMT:=@FStub; FHAMT:=@FStub;
rwlock_init(FLock); rwlock_init(FLock);
end; end;

View File

@ -487,7 +487,7 @@ begin
end; end;
initialization initialization
FAjmMap:=TIntegerHandles.Create; FAjmMap:=TIntegerHandles.Create(1);
ps4_app.RegistredPreLoad('libSceAjm.prx',@Load_libSceAjm); ps4_app.RegistredPreLoad('libSceAjm.prx',@Load_libSceAjm);
end. end.

View File

@ -132,7 +132,7 @@ begin
_sig_unlock; _sig_unlock;
if (Result<>0) then Exit(SCE_AUDIO_OUT_ERROR_TRANS_EVENT); if (Result<>0) then Exit(SCE_AUDIO_OUT_ERROR_TRANS_EVENT);
_sig_lock; _sig_lock;
HAudioOuts:=TIntegerHandles.Create; HAudioOuts:=TIntegerHandles.Create(1);
_sig_unlock; _sig_unlock;
fetch_add(_lazy_wait,1); fetch_add(_lazy_wait,1);
end else end else

View File

@ -1856,7 +1856,7 @@ end;
initialization initialization
FQueueVideoOut.Create; FQueueVideoOut.Create;
FVideoOutMap:=TIntegerHandles.Create; FVideoOutMap:=TIntegerHandles.Create(1);
ps4_app.RegistredPreLoad('libSceVideoOut.prx',@Load_libSceVideoOut); ps4_app.RegistredPreLoad('libSceVideoOut.prx',@Load_libSceVideoOut);
end. end.

View File

@ -12,7 +12,9 @@ uses
sys_kernel, sys_kernel,
sys_fd; sys_fd;
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer; procedure _sys_dev_init;
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer;
function _sys_dev_stat(Const path:RawByteString;stat:PSceKernelStat):Integer;
implementation implementation
@ -45,6 +47,13 @@ type
function pwrite(data:Pointer;size,offset:Int64):Int64; override; function pwrite(data:Pointer;size,offset:Int64):Int64; override;
end; end;
procedure _sys_dev_init;
begin
_sys_dev_open('stdin' ,O_RDONLY,0); //0
_sys_dev_open('stdout',O_WRONLY,0); //1
_sys_dev_open('stderr',O_WRONLY,0); //2
end;
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer; function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer;
var var
f:TCustomFile; f:TCustomFile;
@ -68,15 +77,25 @@ begin
if (Result<0) then if (Result<0) then
begin begin
f.Release; f.Destroy;
end else end else
begin begin
f.Destroy; f.Release;
end; end;
end; end;
// //
function _sys_dev_stat(Const path:RawByteString;stat:PSceKernelStat):Integer;
begin
Result:=0;
stat^:=Default(SceKernelStat);
stat^.st_mode :=S_IFCHR;
stat^.st_nlink:=1;
end;
//
Constructor TDevFile.Create; Constructor TDevFile.Create;
begin begin
Handle:=INVALID_HANDLE_VALUE; Handle:=INVALID_HANDLE_VALUE;

View File

@ -131,6 +131,7 @@ begin
ERROR_BUFFER_OVERFLOW :Exit(-ENAMETOOLONG); ERROR_BUFFER_OVERFLOW :Exit(-ENAMETOOLONG);
ERROR_NOT_ENOUGH_MEMORY:Exit(-ENOMEM); ERROR_NOT_ENOUGH_MEMORY:Exit(-ENOMEM);
ERROR_DISK_FULL :Exit(-ENOSPC); ERROR_DISK_FULL :Exit(-ENOSPC);
ERROR_NO_MORE_FILES,
ERROR_FILE_NOT_FOUND :; ERROR_FILE_NOT_FOUND :;
else else
Exit(-EIO); Exit(-EIO);
@ -140,7 +141,7 @@ begin
f:=TDirFile.Create; f:=TDirFile.Create;
f.path:=path; f.path:=path;
if (err<>ERROR_FILE_NOT_FOUND) then if (h<>INVALID_HANDLE_VALUE) then
begin begin
tmp:=Default(dirent); tmp:=Default(dirent);
move_dirent(0,@data,@tmp); move_dirent(0,@data,@tmp);
@ -161,6 +162,7 @@ begin
begin begin
err:=GetLastError; err:=GetLastError;
Case err of Case err of
ERROR_NO_MORE_FILES,
ERROR_FILE_NOT_FOUND: ERROR_FILE_NOT_FOUND:
begin begin
Break; Break;
@ -174,16 +176,17 @@ begin
end; end;
end; end;
until false; until false;
Windows.FindClose(h);
end; end;
Result:=_sys_open_fd(f); Result:=_sys_open_fd(f);
if (Result<0) then if (Result<0) then
begin begin
f.Release; f.Destroy;
end else end else
begin begin
f.Destroy; f.Release;
end; end;
end; end;

View File

@ -208,6 +208,7 @@ type
function _sys_get_osfhandle(fd:Integer):THandle; function _sys_get_osfhandle(fd:Integer):THandle;
function _sys_open_fd(f:TCustomFile):Integer; function _sys_open_fd(f:TCustomFile):Integer;
function _sys_acqure_fd(fd:Integer):TCustomFile;
function _sys_close(fd:Integer):Integer; function _sys_close(fd:Integer):Integer;
implementation implementation
@ -284,6 +285,11 @@ begin
end; end;
end; end;
function _sys_acqure_fd(fd:Integer):TCustomFile;
begin
Result:=TCustomFile(FileHandles.Acqure(fd));
end;
function _sys_close(fd:Integer):Integer; function _sys_close(fd:Integer):Integer;
begin begin
Result:=0; Result:=0;
@ -294,8 +300,7 @@ end;
// //
initialization initialization
FileHandles:=TIntegerHandles.Create; FileHandles:=TIntegerHandles.Create(0);
FileHandles.min_key:=0;
end. end.

View File

@ -14,6 +14,7 @@ uses
sys_fd; sys_fd;
function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer; function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer;
function _sys_file_stat(Const path:RawByteString;stat:PSceKernelStat):Integer;
implementation implementation
@ -75,9 +76,8 @@ begin
end; end;
end; end;
function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer; function __sys_file_open(const path:RawByteString;flags,mode:Integer;var f:TFile):Integer;
var var
f:TFile;
h:THandle; h:THandle;
err:DWORD; err:DWORD;
@ -124,20 +124,44 @@ begin
f:=TFile.Create; f:=TFile.Create;
f.Handle:=h; f.Handle:=h;
end;
function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer;
var
f:TFile;
begin
f:=nil;
Result:=__sys_file_open(path,flags,mode,f);
if (Result<>0) then Exit;
Result:=_sys_open_fd(f); Result:=_sys_open_fd(f);
if (Result<0) then if (Result<0) then
begin begin
f.Release; f.Destroy;
end else end else
begin begin
f.Destroy; f.Release;
end; end;
end; end;
// //
function _sys_file_stat(Const path:RawByteString;stat:PSceKernelStat):Integer;
var
f:TFile;
begin
f:=nil;
Result:=__sys_file_open(path,O_RDONLY,0,f);
if (Result<>0) then Exit(-Result);
Result:=f.fstat(stat);
f.Destroy;
end;
//
Constructor TFile.Create; Constructor TFile.Create;
begin begin
rwlock_init(lock); rwlock_init(lock);

View File

@ -56,11 +56,6 @@ procedure safe_move_ptr(const src;var dst);
function safe_test(var src:DWORD;value:DWORD):Boolean; function safe_test(var src:DWORD;value:DWORD):Boolean;
function safe_str(P:PChar):shortstring; function safe_str(P:PChar):shortstring;
function _open_osfhandle(h:THandle;flags:Integer):Integer; cdecl; external 'msvcrt';
function _get_osfhandle(fd:Integer):THandle; cdecl; external 'msvcrt';
function _close(fd:Integer):Integer; cdecl; external 'msvcrt';
function MapViewOfFileEx(hFileMappingObject:HANDLE; function MapViewOfFileEx(hFileMappingObject:HANDLE;
dwDesiredAccess:DWORD; dwDesiredAccess:DWORD;
dwFileOffsetHigh:DWORD; dwFileOffsetHigh:DWORD;