mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-11-27 00:20:36 +00:00
+
This commit is contained in:
parent
4fbb608639
commit
40b2c39b5c
@ -6,7 +6,6 @@ interface
|
||||
|
||||
uses
|
||||
windows,
|
||||
sys_types,
|
||||
sys_path,
|
||||
sys_fd,
|
||||
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_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_sceKernelStat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
|
||||
|
||||
@ -54,78 +58,20 @@ implementation
|
||||
|
||||
uses
|
||||
sys_kernel,
|
||||
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;
|
||||
sys_signal;
|
||||
|
||||
function _sys_open(path:PChar;flags,mode:Integer):Integer;
|
||||
const
|
||||
WR_RDWR=O_WRONLY or O_RDWR;
|
||||
O_OFS=O_RDONLY or O_WRONLY or O_RDWR or O_APPEND;
|
||||
|
||||
var
|
||||
h:THandle;
|
||||
|
||||
err:DWORD;
|
||||
dwDesiredAccess:DWORD;
|
||||
dwCreationDisposition:DWORD;
|
||||
|
||||
rp:RawByteString;
|
||||
wp:WideString;
|
||||
begin
|
||||
Result:=0;
|
||||
if (path=nil) then Exit(-EINVAL);
|
||||
|
||||
Writeln('open:',path,' ',flags,' (',OctStr(mode,3),')');
|
||||
|
||||
Assert((flags and O_DIRECTORY)=0,'folder open TODO');
|
||||
|
||||
if ((flags and WR_RDWR)=WR_RDWR) then
|
||||
begin
|
||||
Exit(-EINVAL);
|
||||
@ -136,82 +82,33 @@ begin
|
||||
Exit(-ENOENT);
|
||||
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:='';
|
||||
Result:=parse_filename(path,rp);
|
||||
|
||||
Case Result of
|
||||
PT_ROOT:Exit(-EACCES); //TODO
|
||||
PT_FILE:;
|
||||
PT_DEV :Exit(-EACCES); //TODO
|
||||
PT_FILE:
|
||||
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
|
||||
Exit(-EACCES);
|
||||
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;
|
||||
|
||||
function ps4_open(path:PChar;flags,mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
@ -246,21 +143,6 @@ begin
|
||||
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;
|
||||
begin
|
||||
_sig_lock;
|
||||
@ -278,47 +160,27 @@ begin
|
||||
Result:=px2sce(Result);
|
||||
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;
|
||||
var
|
||||
h:THandle;
|
||||
err:DWORD;
|
||||
f:TCustomFile;
|
||||
begin
|
||||
Result:=0;
|
||||
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
|
||||
SEEK_SET,
|
||||
SEEK_CUR,
|
||||
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;
|
||||
SEEK_END:;
|
||||
else
|
||||
Exit(-EINVAL);
|
||||
Exit(-EINVAL);
|
||||
end;
|
||||
|
||||
f:=_sys_acqure_fd(fd);
|
||||
if (f=nil) then Exit(-EBADF);
|
||||
|
||||
Result:=f.lseek(offset,whence);
|
||||
|
||||
f.Release;
|
||||
end;
|
||||
|
||||
function ps4_lseek(fd:Integer;offset:Int64;whence:Integer):Int64; SysV_ABI_CDecl;
|
||||
@ -353,46 +215,20 @@ begin
|
||||
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;
|
||||
var
|
||||
h:THandle;
|
||||
N:DWORD;
|
||||
f:TCustomFile;
|
||||
begin
|
||||
if (data=nil) then Exit(-EFAULT);
|
||||
if (fd<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
|
||||
begin
|
||||
BCryptGenRandom(nil,data,size,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
Exit(size);
|
||||
end;
|
||||
Result:=f.read(data,size);
|
||||
|
||||
h:=_get_osfhandle(fd);
|
||||
|
||||
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;
|
||||
f.Release;
|
||||
end;
|
||||
|
||||
function ps4_read(fd:Integer;data:Pointer;size:Int64):Int64; SysV_ABI_CDecl;
|
||||
@ -427,65 +263,21 @@ begin
|
||||
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;
|
||||
var
|
||||
h:THandle;
|
||||
N:DWORD;
|
||||
O:TOVERLAPPED;
|
||||
p:Int64;
|
||||
f:TCustomFile;
|
||||
begin
|
||||
if (data=nil) then Exit(-EFAULT);
|
||||
if (fd<0) then Exit(-EINVAL);
|
||||
if (data=nil) then Exit(-EFAULT);
|
||||
if (size<=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
|
||||
begin
|
||||
BCryptGenRandom(nil,data,size,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
Exit(size);
|
||||
end;
|
||||
Result:=f.pread(data,size,offset);
|
||||
|
||||
h:=_get_osfhandle(fd);
|
||||
|
||||
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);
|
||||
f.Release;
|
||||
end;
|
||||
|
||||
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;
|
||||
var
|
||||
h:THandle;
|
||||
N:DWORD;
|
||||
f:TCustomFile;
|
||||
i:Integer;
|
||||
begin
|
||||
if (vector=nil) then Exit(-EFAULT);
|
||||
@ -536,42 +327,12 @@ begin
|
||||
if (vector[i].iov_len<=0) then Exit(-EINVAL);
|
||||
end;
|
||||
|
||||
if (dev_random_fd=fd) then
|
||||
begin
|
||||
f:=_sys_acqure_fd(fd);
|
||||
if (f=nil) then Exit(-EBADF);
|
||||
|
||||
Result:=0;
|
||||
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;
|
||||
Result:=f.readv(vector,count);
|
||||
|
||||
f.Release;
|
||||
end;
|
||||
|
||||
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;
|
||||
var
|
||||
h:THandle;
|
||||
N:DWORD;
|
||||
f:TCustomFile;
|
||||
begin
|
||||
if (data=nil) then Exit(-EFAULT);
|
||||
if (fd<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);
|
||||
|
||||
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;
|
||||
f.Release;
|
||||
end;
|
||||
|
||||
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;
|
||||
var
|
||||
h:THandle;
|
||||
N:DWORD;
|
||||
O:TOVERLAPPED;
|
||||
p:Int64;
|
||||
f:TCustomFile;
|
||||
begin
|
||||
if (data=nil) then Exit(-EFAULT);
|
||||
if (fd<0) then Exit(-EINVAL);
|
||||
if (data=nil) then Exit(-EFAULT);
|
||||
if (size<=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);
|
||||
|
||||
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);
|
||||
f.Release;
|
||||
end;
|
||||
|
||||
function ps4_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl;
|
||||
@ -741,92 +464,19 @@ begin
|
||||
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;
|
||||
var
|
||||
h:THandle;
|
||||
hfi:TByHandleFileInformation;
|
||||
err:DWORD;
|
||||
f:TCustomFile;
|
||||
begin
|
||||
if (fd<0) 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
|
||||
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;
|
||||
f.Release;
|
||||
end;
|
||||
|
||||
function ps4_fstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
|
||||
@ -846,11 +496,75 @@ begin
|
||||
Result:=px2sce(Result);
|
||||
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;
|
||||
var
|
||||
rp:RawByteString;
|
||||
hfi:WIN32_FILE_ATTRIBUTE_DATA;
|
||||
err:DWORD;
|
||||
begin
|
||||
if (path=nil) or (stat=nil) then Exit(EINVAL);
|
||||
|
||||
@ -859,60 +573,28 @@ begin
|
||||
Exit(ENOENT);
|
||||
end;
|
||||
|
||||
stat^:=Default(SceKernelStat);
|
||||
|
||||
rp:='';
|
||||
Result:=parse_filename(path,rp);
|
||||
|
||||
Case Result of
|
||||
PT_ROOT:Exit(-EACCES); //TODO
|
||||
PT_FILE:;
|
||||
PT_DEV :
|
||||
PT_FILE:
|
||||
begin
|
||||
stat^.st_dev :=1;
|
||||
stat^.st_rdev :=1;
|
||||
stat^.st_mode :=S_IFCHR;
|
||||
stat^.st_nlink:=1;
|
||||
Exit(0);
|
||||
end
|
||||
if DirectoryExists(rp) then
|
||||
begin
|
||||
Result:=_sys_dir_stat(rp,stat);
|
||||
end else
|
||||
begin
|
||||
Result:=_sys_file_stat(rp,stat);
|
||||
end;
|
||||
end;
|
||||
PT_DEV:
|
||||
begin
|
||||
Result:=_sys_dev_stat(rp,stat);
|
||||
end;
|
||||
else
|
||||
Exit(-EACCES);
|
||||
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;
|
||||
|
||||
function ps4_stat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
|
||||
|
@ -40,7 +40,8 @@ uses
|
||||
sys_path,
|
||||
sys_kernel,
|
||||
sys_pthread,
|
||||
sys_signal;
|
||||
sys_signal,
|
||||
sys_dev;
|
||||
|
||||
type
|
||||
pSceKernelUuid=^SceKernelUuid;
|
||||
@ -868,6 +869,13 @@ begin
|
||||
lib^.set_proc($E1F539CAF3A4546E,@ps4_sceSysmoduleGetModuleInfoForUnwind);
|
||||
end;
|
||||
|
||||
procedure _kernel_init;
|
||||
begin
|
||||
_mem_init;
|
||||
_sys_dev_init;
|
||||
ps4_sceKernelGetCompiledSdkVersion(@SDK_VERSION);
|
||||
end;
|
||||
|
||||
function Load_libkernel(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
lib,px:PLIBRARY;
|
||||
@ -1255,6 +1263,9 @@ begin
|
||||
lib^.set_proc($9CA5A2FCDD87055E,@ps4_sceKernelPwrite);
|
||||
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($E9CDEB09513F7D35,@ps4_open); //_open
|
||||
|
||||
@ -1278,6 +1289,9 @@ begin
|
||||
|
||||
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($795F70003DAB8880,@ps4_sceKernelStat);
|
||||
|
||||
@ -1301,8 +1315,7 @@ begin
|
||||
lib^.set_proc($8A5D379E5B8A7CC9,@ps4_sceKernelRaiseException);
|
||||
|
||||
//
|
||||
ps4_sceKernelGetCompiledSdkVersion(@SDK_VERSION);
|
||||
_mem_init;
|
||||
_kernel_init;
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
@ -1342,7 +1342,7 @@ initialization
|
||||
ps4_app.files.Init;
|
||||
ps4_app.mods.Init;
|
||||
ps4_app.libs.Init;
|
||||
ps4_app.elfs:=TIntegerHandles.Create;
|
||||
ps4_app.elfs:=TIntegerHandles.Create(1);
|
||||
|
||||
end.
|
||||
|
||||
|
@ -88,6 +88,7 @@ function _VirtualQuery (addr:Pointer;paddr:PPointer;psize:Pptruint;pprots,pfla
|
||||
implementation
|
||||
|
||||
uses
|
||||
sys_fd,
|
||||
sys_kernel;
|
||||
|
||||
const
|
||||
@ -236,7 +237,7 @@ begin
|
||||
Result:=0;
|
||||
if (Addr=nil) then Exit(-1);
|
||||
|
||||
h:=_get_osfhandle(fd);
|
||||
h:=_sys_get_osfhandle(fd);
|
||||
if (h=INVALID_HANDLE_VALUE) then
|
||||
begin
|
||||
Exit(GetLastError);
|
||||
|
@ -32,7 +32,6 @@ type
|
||||
TIntegerHandles=class
|
||||
private
|
||||
Const
|
||||
def_min_key=1;
|
||||
def_max_key=$7FFFFFFF;
|
||||
var
|
||||
FStub:TSTUB_HAMT32;
|
||||
@ -41,7 +40,7 @@ type
|
||||
FLock:TRWLock;
|
||||
public
|
||||
min_key,max_key:Integer;
|
||||
constructor Create;
|
||||
constructor Create(min:Integer);
|
||||
destructor Destroy; override;
|
||||
function New(H:TClassHandle;var OutKey:Integer):Boolean;
|
||||
function Acqure(const Key:Integer):TClassHandle;
|
||||
@ -85,11 +84,11 @@ begin
|
||||
rwlock_unlock(FLock);
|
||||
end;
|
||||
|
||||
constructor TIntegerHandles.Create;
|
||||
constructor TIntegerHandles.Create(min:Integer);
|
||||
begin
|
||||
min_key:=def_min_key;
|
||||
min_key:=min;
|
||||
max_key:=def_max_key;
|
||||
FPos:=def_min_key;
|
||||
FPos:=min;
|
||||
FHAMT:=@FStub;
|
||||
rwlock_init(FLock);
|
||||
end;
|
||||
|
@ -487,7 +487,7 @@ begin
|
||||
end;
|
||||
|
||||
initialization
|
||||
FAjmMap:=TIntegerHandles.Create;
|
||||
FAjmMap:=TIntegerHandles.Create(1);
|
||||
ps4_app.RegistredPreLoad('libSceAjm.prx',@Load_libSceAjm);
|
||||
|
||||
end.
|
||||
|
@ -132,7 +132,7 @@ begin
|
||||
_sig_unlock;
|
||||
if (Result<>0) then Exit(SCE_AUDIO_OUT_ERROR_TRANS_EVENT);
|
||||
_sig_lock;
|
||||
HAudioOuts:=TIntegerHandles.Create;
|
||||
HAudioOuts:=TIntegerHandles.Create(1);
|
||||
_sig_unlock;
|
||||
fetch_add(_lazy_wait,1);
|
||||
end else
|
||||
|
@ -1856,7 +1856,7 @@ end;
|
||||
|
||||
initialization
|
||||
FQueueVideoOut.Create;
|
||||
FVideoOutMap:=TIntegerHandles.Create;
|
||||
FVideoOutMap:=TIntegerHandles.Create(1);
|
||||
ps4_app.RegistredPreLoad('libSceVideoOut.prx',@Load_libSceVideoOut);
|
||||
|
||||
end.
|
||||
|
@ -12,7 +12,9 @@ uses
|
||||
sys_kernel,
|
||||
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
|
||||
|
||||
@ -45,6 +47,13 @@ type
|
||||
function pwrite(data:Pointer;size,offset:Int64):Int64; override;
|
||||
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;
|
||||
var
|
||||
f:TCustomFile;
|
||||
@ -68,15 +77,25 @@ begin
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
f.Release;
|
||||
f.Destroy;
|
||||
end else
|
||||
begin
|
||||
f.Destroy;
|
||||
f.Release;
|
||||
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;
|
||||
begin
|
||||
Handle:=INVALID_HANDLE_VALUE;
|
||||
|
@ -131,6 +131,7 @@ begin
|
||||
ERROR_BUFFER_OVERFLOW :Exit(-ENAMETOOLONG);
|
||||
ERROR_NOT_ENOUGH_MEMORY:Exit(-ENOMEM);
|
||||
ERROR_DISK_FULL :Exit(-ENOSPC);
|
||||
ERROR_NO_MORE_FILES,
|
||||
ERROR_FILE_NOT_FOUND :;
|
||||
else
|
||||
Exit(-EIO);
|
||||
@ -140,7 +141,7 @@ begin
|
||||
f:=TDirFile.Create;
|
||||
f.path:=path;
|
||||
|
||||
if (err<>ERROR_FILE_NOT_FOUND) then
|
||||
if (h<>INVALID_HANDLE_VALUE) then
|
||||
begin
|
||||
tmp:=Default(dirent);
|
||||
move_dirent(0,@data,@tmp);
|
||||
@ -161,6 +162,7 @@ begin
|
||||
begin
|
||||
err:=GetLastError;
|
||||
Case err of
|
||||
ERROR_NO_MORE_FILES,
|
||||
ERROR_FILE_NOT_FOUND:
|
||||
begin
|
||||
Break;
|
||||
@ -174,16 +176,17 @@ begin
|
||||
end;
|
||||
end;
|
||||
until false;
|
||||
Windows.FindClose(h);
|
||||
end;
|
||||
|
||||
Result:=_sys_open_fd(f);
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
f.Release;
|
||||
f.Destroy;
|
||||
end else
|
||||
begin
|
||||
f.Destroy;
|
||||
f.Release;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -208,6 +208,7 @@ type
|
||||
|
||||
function _sys_get_osfhandle(fd:Integer):THandle;
|
||||
function _sys_open_fd(f:TCustomFile):Integer;
|
||||
function _sys_acqure_fd(fd:Integer):TCustomFile;
|
||||
function _sys_close(fd:Integer):Integer;
|
||||
|
||||
implementation
|
||||
@ -284,6 +285,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function _sys_acqure_fd(fd:Integer):TCustomFile;
|
||||
begin
|
||||
Result:=TCustomFile(FileHandles.Acqure(fd));
|
||||
end;
|
||||
|
||||
function _sys_close(fd:Integer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
@ -294,8 +300,7 @@ end;
|
||||
//
|
||||
|
||||
initialization
|
||||
FileHandles:=TIntegerHandles.Create;
|
||||
FileHandles.min_key:=0;
|
||||
FileHandles:=TIntegerHandles.Create(0);
|
||||
|
||||
end.
|
||||
|
||||
|
@ -14,6 +14,7 @@ uses
|
||||
sys_fd;
|
||||
|
||||
function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer;
|
||||
function _sys_file_stat(Const path:RawByteString;stat:PSceKernelStat):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
@ -75,9 +76,8 @@ begin
|
||||
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
|
||||
f:TFile;
|
||||
h:THandle;
|
||||
|
||||
err:DWORD;
|
||||
@ -124,20 +124,44 @@ begin
|
||||
|
||||
f:=TFile.Create;
|
||||
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);
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
f.Release;
|
||||
f.Destroy;
|
||||
end else
|
||||
begin
|
||||
f.Destroy;
|
||||
f.Release;
|
||||
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;
|
||||
begin
|
||||
rwlock_init(lock);
|
||||
|
@ -56,11 +56,6 @@ procedure safe_move_ptr(const src;var dst);
|
||||
function safe_test(var src:DWORD;value:DWORD):Boolean;
|
||||
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;
|
||||
dwDesiredAccess:DWORD;
|
||||
dwFileOffsetHigh:DWORD;
|
||||
|
Loading…
Reference in New Issue
Block a user