mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
99393e0e19
commit
683f552d55
|
@ -8,189 +8,12 @@ uses
|
|||
windows,
|
||||
sys_types,
|
||||
sys_path,
|
||||
sys_fd,
|
||||
sys_file,
|
||||
sys_dev,
|
||||
Classes,
|
||||
SysUtils;
|
||||
|
||||
const
|
||||
NAME_MAX =255; // max bytes in a file name
|
||||
PATH_MAX =1024; // max bytes in pathname
|
||||
IOV_MAX =1024; // max elements in i/o vector
|
||||
MAXNAMLEN =255;
|
||||
|
||||
O_RDONLY =$0000; // open for reading only
|
||||
O_WRONLY =$0001; // open for writing only
|
||||
O_RDWR =$0002; // open for reading and writing
|
||||
O_ACCMODE =$0003; // mask for above modes
|
||||
|
||||
O_NONBLOCK =$0004; // no delay
|
||||
O_APPEND =$0008; // set append mode
|
||||
O_SYNC =$0080; // POSIX synonym for O_FSYNC
|
||||
O_CREAT =$0200; // create if nonexistent
|
||||
O_TRUNC =$0400; // truncate to zero length
|
||||
O_EXCL =$0800; // error if already exists
|
||||
O_DSYNC =$1000; // synchronous data writes(omit inode writes)
|
||||
|
||||
O_DIRECT =$00010000;
|
||||
O_FSYNC =$0080; // synchronous writes
|
||||
|
||||
O_DIRECTORY =$00020000; // Fail if not directory
|
||||
O_EXEC =$00040000; // Open for execute only
|
||||
|
||||
S_IRWXU =&0000700; // RWX mask for owner
|
||||
S_IRUSR =&0000400; // R for owner
|
||||
S_IWUSR =&0000200; // W for owner
|
||||
S_IXUSR =&0000100; // X for owner
|
||||
|
||||
S_IRWXG =&0000070; // RWX mask for group
|
||||
S_IRGRP =&0000040; // R for group
|
||||
S_IWGRP =&0000020; // W for group
|
||||
S_IXGRP =&0000010; // X for group
|
||||
|
||||
S_IRWXO =&0000007; // RWX mask for other
|
||||
S_IROTH =&0000004; // R for other
|
||||
S_IWOTH =&0000002; // W for other
|
||||
S_IXOTH =&0000001; // X for other
|
||||
|
||||
S_IFMT =&0170000; // type of file mask
|
||||
S_IFIFO =&0010000; // named pipe (fifo)
|
||||
S_IFCHR =&0020000; // character special
|
||||
S_IFDIR =&0040000; // directory
|
||||
S_IFBLK =&0060000; // block special
|
||||
S_IFREG =&0100000; // regular
|
||||
S_IFLNK =&0120000; // symbolic link
|
||||
S_IFSOCK =&0140000; // socket
|
||||
S_ISVTX =&0001000; // save swapped text even after use
|
||||
|
||||
F_GETFL =3; // get file status flags
|
||||
F_SETFL =4; // set file status flags
|
||||
|
||||
SEEK_SET =0; // set file offset to offset
|
||||
SEEK_CUR =1; // set file offset to current plus offset
|
||||
SEEK_END =2; // set file offset to EOF plus offset
|
||||
|
||||
MAP_SHARED =$0001; // share changes
|
||||
MAP_PRIVATE =$0002; // changes are private
|
||||
|
||||
MAP_FILE =$0000; // map from file (default)
|
||||
MAP_ANON =$1000; // allocated from memory, swap space
|
||||
MAP_SYSTEM =$2000;
|
||||
|
||||
MAP_NOCORE =$00020000; // dont include these pages in a coredump
|
||||
MAP_NOSYNC =$0800; // page to but do not sync underlying file
|
||||
MAP_PREFAULT_READ =$00040000; // prefault mapping for reading
|
||||
|
||||
DT_UNKNOWN =0;
|
||||
DT_DIR =4;
|
||||
DT_REG =8;
|
||||
|
||||
SCE_KERNEL_NAME_MAX =NAME_MAX;
|
||||
SCE_KERNEL_PATH_MAX =PATH_MAX;
|
||||
SCE_KERNEL_IOV_MAX =IOV_MAX;
|
||||
SCE_KERNEL_MAXNAMLEN =MAXNAMLEN;
|
||||
|
||||
SCE_KERNEL_O_RDONLY =O_RDONLY;
|
||||
SCE_KERNEL_O_WRONLY =O_WRONLY;
|
||||
SCE_KERNEL_O_RDWR =O_RDWR ;
|
||||
SCE_KERNEL_O_NONBLOCK =O_NONBLOCK;
|
||||
SCE_KERNEL_O_APPEND =O_APPEND;
|
||||
SCE_KERNEL_O_CREAT =O_CREAT;
|
||||
SCE_KERNEL_O_TRUNC =O_TRUNC;
|
||||
SCE_KERNEL_O_EXCL =O_EXCL;
|
||||
SCE_KERNEL_O_DIRECT =O_DIRECT;
|
||||
SCE_KERNEL_O_FSYNC =O_FSYNC;
|
||||
SCE_KERNEL_O_SYNC =O_SYNC;
|
||||
SCE_KERNEL_O_DSYNC =O_DSYNC;
|
||||
SCE_KERNEL_O_DIRECTORY =O_DIRECTORY;
|
||||
|
||||
SCE_KERNEL_S_IFMT =S_IFMT;
|
||||
SCE_KERNEL_S_IFDIR =S_IFDIR;
|
||||
SCE_KERNEL_S_IFREG =S_IFREG;
|
||||
|
||||
SCE_KERNEL_S_IRUSR =(S_IRUSR or S_IRGRP or S_IROTH or S_IXUSR or S_IXGRP or S_IXOTH);
|
||||
SCE_KERNEL_S_IWUSR =(S_IWUSR or S_IWGRP or S_IWOTH or S_IXUSR or S_IXGRP or S_IXOTH);
|
||||
SCE_KERNEL_S_IXUSR =(S_IXUSR or S_IXGRP or S_IXOTH);
|
||||
SCE_KERNEL_S_IRWXU =(SCE_KERNEL_S_IRUSR or SCE_KERNEL_S_IWUSR);
|
||||
|
||||
SCE_KERNEL_S_IRWU =(SCE_KERNEL_S_IRUSR or SCE_KERNEL_S_IWUSR);
|
||||
// 00777, R/W
|
||||
SCE_KERNEL_S_IRU =(SCE_KERNEL_S_IRUSR);
|
||||
// 00555, R
|
||||
|
||||
SCE_KERNEL_S_INONE =&0000000;
|
||||
|
||||
//SCE_KERNEL_S_ISDIR(m) =S_ISDIR(m);
|
||||
//SCE_KERNEL_S_ISREG(m) =S_ISREG(m);
|
||||
|
||||
// for sceKernelFcntl()
|
||||
SCE_KERNEL_F_GETFL =F_GETFL;
|
||||
SCE_KERNEL_F_SETFL =F_SETFL;
|
||||
|
||||
// for sceKernelLseek()
|
||||
SCE_KERNEL_SEEK_SET =SEEK_SET;
|
||||
SCE_KERNEL_SEEK_CUR =SEEK_CUR;
|
||||
SCE_KERNEL_SEEK_END =SEEK_END;
|
||||
|
||||
// for sceKernelMmap()
|
||||
SCE_KERNEL_MAP_NOCORE =MAP_NOCORE;
|
||||
SCE_KERNEL_MAP_NOSYNC =MAP_NOSYNC;
|
||||
SCE_KERNEL_MAP_PREFAULT_READ=MAP_PREFAULT_READ;
|
||||
SCE_KERNEL_MAP_PRIVATE =MAP_PRIVATE;
|
||||
SCE_KERNEL_MAP_SHARED =MAP_SHARED;
|
||||
|
||||
// for SceKernelDirent
|
||||
SCE_KERNEL_DT_UNKNOWN =DT_UNKNOWN;
|
||||
SCE_KERNEL_DT_DIR =DT_DIR;
|
||||
SCE_KERNEL_DT_REG =DT_REG;
|
||||
|
||||
// for sceKernelSetCompress
|
||||
SCE_KERNEL_COMPRESS_FILE_MAGIC =($43534650);
|
||||
SCE_KERNEL_SET_COMPRESS_FILE =(1);
|
||||
SCE_KERNEL_SET_REGULAR_FILE =(0);
|
||||
|
||||
// for sceKernelLwfsSetAttribute
|
||||
SCE_KERNEL_LWFS_DISABLE =(0);
|
||||
SCE_KERNEL_LWFS_ENABLE =(1);
|
||||
|
||||
type
|
||||
p_iovec=^iovec;
|
||||
iovec=packed record
|
||||
iov_base:Pointer; //Base address.
|
||||
iov_len :Int64; //Length.
|
||||
end;
|
||||
|
||||
PSceKernelStat=^SceKernelStat;
|
||||
SceKernelStat=packed object
|
||||
type
|
||||
__dev_t =DWORD;
|
||||
ino_t =DWORD;
|
||||
mode_t =Word;
|
||||
nlink_t =Word;
|
||||
uid_t =DWORD;
|
||||
gid_t =DWORD;
|
||||
off_t =Int64;
|
||||
blkcnt_t =Int64;
|
||||
blksize_t=DWORD;
|
||||
fflags_t =DWORD;
|
||||
var
|
||||
st_dev :__dev_t ; // inode's device
|
||||
st_ino :ino_t ; // inode's number
|
||||
st_mode :mode_t ; // inode protection mode S_IFMT.....
|
||||
st_nlink :nlink_t ; // number of hard links
|
||||
st_uid :uid_t ; // user ID of the file's owner S_IRWXU....
|
||||
st_gid :gid_t ; // group ID of the file's group S_IRWXG....
|
||||
st_rdev :__dev_t ; // device type
|
||||
st_atim :timespec ; // time of last access
|
||||
st_mtim :timespec ; // time of last data modification
|
||||
st_ctim :timespec ; // time of last file status change
|
||||
st_size :off_t ; // file size, in bytes
|
||||
st_blocks :blkcnt_t ; // blocks allocated for file
|
||||
st_blksize :blksize_t ; // optimal blocksize for I/O
|
||||
st_flags :fflags_t ; // user defined flags for file
|
||||
st_gen :DWORD ; // file generation number
|
||||
st_lspare :DWORD ;
|
||||
st_birthtim:timespec ; // time of file creation
|
||||
end;
|
||||
|
||||
function ps4_open(path:PChar;flags,mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelOpen(path:PChar;flags,mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
unit sys_dev;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows,
|
||||
Classes,
|
||||
SysUtils,
|
||||
RWLock,
|
||||
sys_kernel,
|
||||
sys_time,
|
||||
sys_fd;
|
||||
|
||||
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
TDevFile=class(TCustomFile)
|
||||
Constructor Create;
|
||||
function lseek (offset:Int64;whence:Integer):Int64; override;
|
||||
function fstat (stat:PSceKernelStat):Integer; override;
|
||||
end;
|
||||
|
||||
TDevRandom=class(TDevFile)
|
||||
function read (data:Pointer;size:Int64):Int64; override;
|
||||
function pread (data:Pointer;size,offset:Int64):Int64; override;
|
||||
function readv (vector:p_iovec;count:Integer):Int64; override;
|
||||
function write (data:Pointer;size:Int64):Int64; override;
|
||||
function pwrite(data:Pointer;size,offset:Int64):Int64; override;
|
||||
end;
|
||||
|
||||
TDevStd=class(TDevFile)
|
||||
Text:PText;
|
||||
cache:TMemoryStream;
|
||||
Constructor Create(t:PText);
|
||||
Destructor Destroy; override;
|
||||
function read (data:Pointer;size:Int64):Int64; override;
|
||||
function pread (data:Pointer;size,offset:Int64):Int64; override;
|
||||
function readv (vector:p_iovec;count:Integer):Int64; override;
|
||||
function write (data:Pointer;size:Int64):Int64; override;
|
||||
function pwrite(data:Pointer;size,offset:Int64):Int64; override;
|
||||
end;
|
||||
|
||||
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer;
|
||||
var
|
||||
f:TCustomFile;
|
||||
begin
|
||||
|
||||
Case path of
|
||||
'stdin' :f:=TDevStd.Create(@Input);
|
||||
'stdout':f:=TDevStd.Create(@StdOut);
|
||||
'stderr':f:=TDevStd.Create(@StdErr);
|
||||
|
||||
'random',
|
||||
'urandom':
|
||||
begin
|
||||
f:=TDevRandom.Create;
|
||||
end;
|
||||
else
|
||||
Exit(-ENOENT);
|
||||
end;
|
||||
|
||||
Result:=_sys_open_fd(f);
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
f.Release;
|
||||
end else
|
||||
begin
|
||||
f.Destroy;
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
Constructor TDevFile.Create;
|
||||
begin
|
||||
Handle:=INVALID_HANDLE_VALUE;
|
||||
end;
|
||||
|
||||
function TDevFile.lseek (offset:Int64;whence:Integer):Int64;
|
||||
begin
|
||||
Result:=-ESPIPE;
|
||||
end;
|
||||
|
||||
function TDevFile.fstat (stat:PSceKernelStat):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
stat^:=Default(SceKernelStat);
|
||||
stat^.st_dev :=fd;
|
||||
stat^.st_rdev :=fd;
|
||||
stat^.st_mode :=S_IFCHR;
|
||||
stat^.st_nlink:=1;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
const
|
||||
BCRYPT_USE_SYSTEM_PREFERRED_RNG=2;
|
||||
|
||||
function BCryptGenRandom(hAlgorithm:Pointer;
|
||||
pbBuffer:PByte;
|
||||
cbBuffer:DWORD;
|
||||
dwFlags:DWORD):DWORD; stdcall; external 'Bcrypt';
|
||||
|
||||
function TDevRandom.read (data:Pointer;size:Int64):Int64;
|
||||
begin
|
||||
Assert(size<High(DWORD));
|
||||
|
||||
BCryptGenRandom(nil,data,size,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
Result:=size;
|
||||
end;
|
||||
|
||||
function TDevRandom.pread (data:Pointer;size,offset:Int64):Int64;
|
||||
begin
|
||||
Assert(size<High(DWORD));
|
||||
|
||||
BCryptGenRandom(nil,data,size,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
Result:=size;
|
||||
end;
|
||||
|
||||
function TDevRandom.readv (vector:p_iovec;count:Integer):Int64;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
For i:=0 to count-1 do
|
||||
begin
|
||||
Assert(vector[i].iov_len<High(DWORD));
|
||||
|
||||
BCryptGenRandom(nil,vector[i].iov_base,vector[i].iov_len,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
Result:=Result+vector[i].iov_len;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDevRandom.write (data:Pointer;size:Int64):Int64;
|
||||
begin
|
||||
Result:=size;
|
||||
end;
|
||||
|
||||
function TDevRandom.pwrite(data:Pointer;size,offset:Int64):Int64;
|
||||
begin
|
||||
Result:=size;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
Constructor TDevStd.Create(t:PText);
|
||||
type
|
||||
PTextRec=^TextRec;
|
||||
begin
|
||||
Handle:=PTextRec(t)^.Handle;
|
||||
Text:=t;
|
||||
cache:=TMemoryStream.Create
|
||||
end;
|
||||
|
||||
Destructor TDevStd.Destroy;
|
||||
begin
|
||||
FreeAndNil(cache);
|
||||
end;
|
||||
|
||||
function TDevStd.read (data:Pointer;size:Int64):Int64;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
function TDevStd.pread (data:Pointer;size,offset:Int64):Int64;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
function TDevStd.readv (vector:p_iovec;count:Integer):Int64;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
function TDevStd.write (data:Pointer;size:Int64):Int64;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
function TDevStd.pwrite(data:Pointer;size,offset:Int64):Int64;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
unit sys_fd;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
windows,
|
||||
Classes,
|
||||
SysUtils,
|
||||
ps4_handles,
|
||||
sys_types,
|
||||
sys_kernel;
|
||||
|
||||
const
|
||||
NAME_MAX =255; // max bytes in a file name
|
||||
PATH_MAX =1024; // max bytes in pathname
|
||||
IOV_MAX =1024; // max elements in i/o vector
|
||||
MAXNAMLEN =255;
|
||||
|
||||
O_RDONLY =$0000; // open for reading only
|
||||
O_WRONLY =$0001; // open for writing only
|
||||
O_RDWR =$0002; // open for reading and writing
|
||||
O_ACCMODE =$0003; // mask for above modes
|
||||
|
||||
O_NONBLOCK =$0004; // no delay
|
||||
O_APPEND =$0008; // set append mode
|
||||
O_SYNC =$0080; // POSIX synonym for O_FSYNC
|
||||
O_CREAT =$0200; // create if nonexistent
|
||||
O_TRUNC =$0400; // truncate to zero length
|
||||
O_EXCL =$0800; // error if already exists
|
||||
O_DSYNC =$1000; // synchronous data writes(omit inode writes)
|
||||
|
||||
O_DIRECT =$00010000;
|
||||
O_FSYNC =$0080; // synchronous writes
|
||||
|
||||
O_DIRECTORY =$00020000; // Fail if not directory
|
||||
O_EXEC =$00040000; // Open for execute only
|
||||
|
||||
S_IRWXU =&0000700; // RWX mask for owner
|
||||
S_IRUSR =&0000400; // R for owner
|
||||
S_IWUSR =&0000200; // W for owner
|
||||
S_IXUSR =&0000100; // X for owner
|
||||
|
||||
S_IRWXG =&0000070; // RWX mask for group
|
||||
S_IRGRP =&0000040; // R for group
|
||||
S_IWGRP =&0000020; // W for group
|
||||
S_IXGRP =&0000010; // X for group
|
||||
|
||||
S_IRWXO =&0000007; // RWX mask for other
|
||||
S_IROTH =&0000004; // R for other
|
||||
S_IWOTH =&0000002; // W for other
|
||||
S_IXOTH =&0000001; // X for other
|
||||
|
||||
S_IFMT =&0170000; // type of file mask
|
||||
S_IFIFO =&0010000; // named pipe (fifo)
|
||||
S_IFCHR =&0020000; // character special
|
||||
S_IFDIR =&0040000; // directory
|
||||
S_IFBLK =&0060000; // block special
|
||||
S_IFREG =&0100000; // regular
|
||||
S_IFLNK =&0120000; // symbolic link
|
||||
S_IFSOCK =&0140000; // socket
|
||||
S_ISVTX =&0001000; // save swapped text even after use
|
||||
|
||||
F_GETFL =3; // get file status flags
|
||||
F_SETFL =4; // set file status flags
|
||||
|
||||
SEEK_SET =0; // set file offset to offset
|
||||
SEEK_CUR =1; // set file offset to current plus offset
|
||||
SEEK_END =2; // set file offset to EOF plus offset
|
||||
|
||||
MAP_SHARED =$0001; // share changes
|
||||
MAP_PRIVATE =$0002; // changes are private
|
||||
|
||||
MAP_FILE =$0000; // map from file (default)
|
||||
MAP_ANON =$1000; // allocated from memory, swap space
|
||||
MAP_SYSTEM =$2000;
|
||||
|
||||
MAP_NOCORE =$00020000; // dont include these pages in a coredump
|
||||
MAP_NOSYNC =$0800; // page to but do not sync underlying file
|
||||
MAP_PREFAULT_READ =$00040000; // prefault mapping for reading
|
||||
|
||||
DT_UNKNOWN =0;
|
||||
DT_DIR =4;
|
||||
DT_REG =8;
|
||||
|
||||
SCE_KERNEL_NAME_MAX =NAME_MAX;
|
||||
SCE_KERNEL_PATH_MAX =PATH_MAX;
|
||||
SCE_KERNEL_IOV_MAX =IOV_MAX;
|
||||
SCE_KERNEL_MAXNAMLEN =MAXNAMLEN;
|
||||
|
||||
SCE_KERNEL_O_RDONLY =O_RDONLY;
|
||||
SCE_KERNEL_O_WRONLY =O_WRONLY;
|
||||
SCE_KERNEL_O_RDWR =O_RDWR ;
|
||||
SCE_KERNEL_O_NONBLOCK =O_NONBLOCK;
|
||||
SCE_KERNEL_O_APPEND =O_APPEND;
|
||||
SCE_KERNEL_O_CREAT =O_CREAT;
|
||||
SCE_KERNEL_O_TRUNC =O_TRUNC;
|
||||
SCE_KERNEL_O_EXCL =O_EXCL;
|
||||
SCE_KERNEL_O_DIRECT =O_DIRECT;
|
||||
SCE_KERNEL_O_FSYNC =O_FSYNC;
|
||||
SCE_KERNEL_O_SYNC =O_SYNC;
|
||||
SCE_KERNEL_O_DSYNC =O_DSYNC;
|
||||
SCE_KERNEL_O_DIRECTORY =O_DIRECTORY;
|
||||
|
||||
SCE_KERNEL_S_IFMT =S_IFMT;
|
||||
SCE_KERNEL_S_IFDIR =S_IFDIR;
|
||||
SCE_KERNEL_S_IFREG =S_IFREG;
|
||||
|
||||
SCE_KERNEL_S_IRUSR =(S_IRUSR or S_IRGRP or S_IROTH or S_IXUSR or S_IXGRP or S_IXOTH);
|
||||
SCE_KERNEL_S_IWUSR =(S_IWUSR or S_IWGRP or S_IWOTH or S_IXUSR or S_IXGRP or S_IXOTH);
|
||||
SCE_KERNEL_S_IXUSR =(S_IXUSR or S_IXGRP or S_IXOTH);
|
||||
SCE_KERNEL_S_IRWXU =(SCE_KERNEL_S_IRUSR or SCE_KERNEL_S_IWUSR);
|
||||
|
||||
SCE_KERNEL_S_IRWU =(SCE_KERNEL_S_IRUSR or SCE_KERNEL_S_IWUSR);
|
||||
// 00777, R/W
|
||||
SCE_KERNEL_S_IRU =(SCE_KERNEL_S_IRUSR);
|
||||
// 00555, R
|
||||
|
||||
SCE_KERNEL_S_INONE =&0000000;
|
||||
|
||||
//SCE_KERNEL_S_ISDIR(m) =S_ISDIR(m);
|
||||
//SCE_KERNEL_S_ISREG(m) =S_ISREG(m);
|
||||
|
||||
// for sceKernelFcntl()
|
||||
SCE_KERNEL_F_GETFL =F_GETFL;
|
||||
SCE_KERNEL_F_SETFL =F_SETFL;
|
||||
|
||||
// for sceKernelLseek()
|
||||
SCE_KERNEL_SEEK_SET =SEEK_SET;
|
||||
SCE_KERNEL_SEEK_CUR =SEEK_CUR;
|
||||
SCE_KERNEL_SEEK_END =SEEK_END;
|
||||
|
||||
// for sceKernelMmap()
|
||||
SCE_KERNEL_MAP_NOCORE =MAP_NOCORE;
|
||||
SCE_KERNEL_MAP_NOSYNC =MAP_NOSYNC;
|
||||
SCE_KERNEL_MAP_PREFAULT_READ=MAP_PREFAULT_READ;
|
||||
SCE_KERNEL_MAP_PRIVATE =MAP_PRIVATE;
|
||||
SCE_KERNEL_MAP_SHARED =MAP_SHARED;
|
||||
|
||||
// for SceKernelDirent
|
||||
SCE_KERNEL_DT_UNKNOWN =DT_UNKNOWN;
|
||||
SCE_KERNEL_DT_DIR =DT_DIR;
|
||||
SCE_KERNEL_DT_REG =DT_REG;
|
||||
|
||||
// for sceKernelSetCompress
|
||||
SCE_KERNEL_COMPRESS_FILE_MAGIC =($43534650);
|
||||
SCE_KERNEL_SET_COMPRESS_FILE =(1);
|
||||
SCE_KERNEL_SET_REGULAR_FILE =(0);
|
||||
|
||||
// for sceKernelLwfsSetAttribute
|
||||
SCE_KERNEL_LWFS_DISABLE =(0);
|
||||
SCE_KERNEL_LWFS_ENABLE =(1);
|
||||
|
||||
type
|
||||
p_iovec=^iovec;
|
||||
iovec=packed record
|
||||
iov_base:Pointer; //Base address.
|
||||
iov_len :Int64; //Length.
|
||||
end;
|
||||
|
||||
PSceKernelStat=^SceKernelStat;
|
||||
SceKernelStat=packed object
|
||||
type
|
||||
__dev_t =DWORD;
|
||||
ino_t =DWORD;
|
||||
mode_t =Word;
|
||||
nlink_t =Word;
|
||||
uid_t =DWORD;
|
||||
gid_t =DWORD;
|
||||
off_t =Int64;
|
||||
blkcnt_t =Int64;
|
||||
blksize_t=DWORD;
|
||||
fflags_t =DWORD;
|
||||
var
|
||||
st_dev :__dev_t ; // inode's device
|
||||
st_ino :ino_t ; // inode's number
|
||||
st_mode :mode_t ; // inode protection mode S_IFMT.....
|
||||
st_nlink :nlink_t ; // number of hard links
|
||||
st_uid :uid_t ; // user ID of the file's owner S_IRWXU....
|
||||
st_gid :gid_t ; // group ID of the file's group S_IRWXG....
|
||||
st_rdev :__dev_t ; // device type
|
||||
st_atim :timespec ; // time of last access
|
||||
st_mtim :timespec ; // time of last data modification
|
||||
st_ctim :timespec ; // time of last file status change
|
||||
st_size :off_t ; // file size, in bytes
|
||||
st_blocks :blkcnt_t ; // blocks allocated for file
|
||||
st_blksize :blksize_t ; // optimal blocksize for I/O
|
||||
st_flags :fflags_t ; // user defined flags for file
|
||||
st_gen :DWORD ; // file generation number
|
||||
st_lspare :DWORD ;
|
||||
st_birthtim:timespec ; // time of file creation
|
||||
end;
|
||||
|
||||
TCustomFile=class(TClassHandle)
|
||||
var
|
||||
fd:Integer;
|
||||
Handle:THandle;
|
||||
function lseek (offset:Int64;whence:Integer):Int64; virtual;
|
||||
function read (data:Pointer;size:Int64):Int64; virtual;
|
||||
function pread (data:Pointer;size,offset:Int64):Int64; virtual;
|
||||
function readv (vector:p_iovec;count:Integer):Int64; virtual;
|
||||
function write (data:Pointer;size:Int64):Int64; virtual;
|
||||
function pwrite(data:Pointer;size,offset:Int64):Int64; virtual;
|
||||
function fstat (stat:PSceKernelStat):Integer; virtual;
|
||||
end;
|
||||
|
||||
function _sys_get_osfhandle(fd:Integer):THandle;
|
||||
function _sys_open_fd(f:TCustomFile):Integer;
|
||||
function _sys_close(fd:Integer):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
FileHandles:TIntegerHandles;
|
||||
|
||||
//
|
||||
|
||||
function TCustomFile.lseek (offset:Int64;whence:Integer):Int64;
|
||||
begin
|
||||
Result:=-ENOTSUP;
|
||||
end;
|
||||
|
||||
function TCustomFile.read (data:Pointer;size:Int64):Int64;
|
||||
begin
|
||||
Result:=-ENOTSUP;
|
||||
end;
|
||||
|
||||
function TCustomFile.pread (data:Pointer;size,offset:Int64):Int64;
|
||||
begin
|
||||
Result:=-ENOTSUP;
|
||||
end;
|
||||
|
||||
function TCustomFile.readv (vector:p_iovec;count:Integer):Int64;
|
||||
begin
|
||||
Result:=-ENOTSUP;
|
||||
end;
|
||||
|
||||
function TCustomFile.write (data:Pointer;size:Int64):Int64;
|
||||
begin
|
||||
Result:=-ENOTSUP;
|
||||
end;
|
||||
|
||||
function TCustomFile.pwrite(data:Pointer;size,offset:Int64):Int64;
|
||||
begin
|
||||
Result:=-ENOTSUP;
|
||||
end;
|
||||
|
||||
function TCustomFile.fstat (stat:PSceKernelStat):Integer;
|
||||
begin
|
||||
Result:=-ENOTSUP;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function _sys_get_osfhandle(fd:Integer):THandle;
|
||||
var
|
||||
f:TCustomFile;
|
||||
begin
|
||||
Result:=INVALID_HANDLE_VALUE;
|
||||
f:=TCustomFile(FileHandles.Acqure(fd));
|
||||
if (f<>nil) then
|
||||
begin
|
||||
Result:=f.Handle;
|
||||
f.Release;
|
||||
end;
|
||||
end;
|
||||
|
||||
function _sys_open_fd(f:TCustomFile):Integer;
|
||||
begin
|
||||
if (f=nil) then Exit(-EINVAL);
|
||||
if FileHandles.New(f,Result) then
|
||||
begin
|
||||
f.fd:=Result;
|
||||
end else
|
||||
begin
|
||||
Result:=-EMFILE;
|
||||
end;
|
||||
end;
|
||||
|
||||
function _sys_close(fd:Integer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
if (fd<0) then Exit(EINVAL);
|
||||
if not FileHandles.Delete(fd) then Exit(EBADF);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
initialization
|
||||
FileHandles:=TIntegerHandles.Create;
|
||||
FileHandles.min_key:=0;
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,408 @@
|
|||
unit sys_file;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows,
|
||||
Classes,
|
||||
SysUtils,
|
||||
RWLock,
|
||||
sys_kernel,
|
||||
sys_time,
|
||||
sys_fd;
|
||||
|
||||
function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
TFile=class(TCustomFile)
|
||||
var
|
||||
lock:TRWLock;
|
||||
Constructor Create;
|
||||
Destructor Destroy; override;
|
||||
function lseek (offset:Int64;whence:Integer):Int64; override;
|
||||
function read (data:Pointer;size:Int64):Int64; override;
|
||||
function pread (data:Pointer;size,offset:Int64):Int64; override;
|
||||
function readv (vector:p_iovec;count:Integer):Int64; override;
|
||||
function write (data:Pointer;size:Int64):Int64; override;
|
||||
function pwrite(data:Pointer;size,offset:Int64):Int64; override;
|
||||
function fstat (stat:PSceKernelStat):Integer; override;
|
||||
end;
|
||||
|
||||
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;
|
||||
|
||||
function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer;
|
||||
var
|
||||
f:TFile;
|
||||
h:THandle;
|
||||
|
||||
err:DWORD;
|
||||
dwDesiredAccess:DWORD;
|
||||
dwCreationDisposition:DWORD;
|
||||
|
||||
wp:WideString;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
wp:=UTF8Decode(path);
|
||||
|
||||
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;
|
||||
|
||||
f:=TFile.Create;
|
||||
f.Handle:=h;
|
||||
|
||||
Result:=_sys_open_fd(f);
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
f.Release;
|
||||
end else
|
||||
begin
|
||||
f.Destroy;
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
Constructor TFile.Create;
|
||||
begin
|
||||
rwlock_init(lock);
|
||||
end;
|
||||
|
||||
Destructor TFile.Destroy;
|
||||
begin
|
||||
rwlock_destroy(lock);
|
||||
CloseHandle(Handle);
|
||||
end;
|
||||
|
||||
function SetFilePointerEx(hFile:HANDLE;
|
||||
liDistanceToMove:LARGE_INTEGER;
|
||||
lpNewFilePointer:PLARGE_INTEGER;
|
||||
dwMoveMethod:DWORD):BOOL; external 'kernel32';
|
||||
|
||||
function TFile.lseek (offset:Int64;whence:Integer):Int64;
|
||||
var
|
||||
err:DWORD;
|
||||
R:BOOL;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
rwlock_wrlock(lock);
|
||||
R:=SetFilePointerEx(Handle,LARGE_INTEGER(offset),@Result,whence);
|
||||
rwlock_unlock(lock);
|
||||
|
||||
if not R then
|
||||
begin
|
||||
err:=GetLastError;
|
||||
Case err of
|
||||
ERROR_HANDLE_EOF :Exit(-EOVERFLOW);
|
||||
ERROR_INVALID_PARAMETER:Exit(-EINVAL);
|
||||
else
|
||||
Exit(-EOVERFLOW);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFile.read (data:Pointer;size:Int64):Int64;
|
||||
var
|
||||
N:DWORD;
|
||||
R:BOOL;
|
||||
begin
|
||||
Assert(size<High(DWORD));
|
||||
|
||||
N:=0;
|
||||
rwlock_wrlock(lock);
|
||||
R:=ReadFile(Handle,data^,size,N,nil);
|
||||
rwlock_unlock(lock);
|
||||
|
||||
if R then
|
||||
begin
|
||||
Result:=N;
|
||||
end else
|
||||
begin
|
||||
Result:=-EIO;
|
||||
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 TFile.pread (data:Pointer;size,offset:Int64):Int64;
|
||||
var
|
||||
N:DWORD;
|
||||
O:TOVERLAPPED;
|
||||
p:Int64;
|
||||
R:BOOL;
|
||||
begin
|
||||
Assert(size<High(DWORD));
|
||||
|
||||
O:=Default(TOVERLAPPED);
|
||||
PInt64(@O.Offset)^:=offset;
|
||||
N:=0;
|
||||
rwlock_wrlock(lock);
|
||||
//NOTE: pread and pwrite don't change the file position, but ReadFile/WriteFile do, damn it.
|
||||
p:=_get_pos(Handle);
|
||||
R:=ReadFile(Handle,data^,size,N,@O);
|
||||
_set_pos(Handle,p);
|
||||
rwlock_unlock(lock);
|
||||
|
||||
if R then
|
||||
begin
|
||||
Result:=N;
|
||||
end else
|
||||
begin
|
||||
Result:=-EIO;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFile.readv (vector:p_iovec;count:Integer):Int64;
|
||||
var
|
||||
N:DWORD;
|
||||
R:BOOL;
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
For i:=0 to count-1 do
|
||||
begin
|
||||
Assert(vector[i].iov_len<High(DWORD));
|
||||
|
||||
N:=0;
|
||||
rwlock_wrlock(lock);
|
||||
R:=ReadFile(Handle,vector[i].iov_base^,vector[i].iov_len,N,nil);
|
||||
rwlock_unlock(lock);
|
||||
|
||||
if R then
|
||||
begin
|
||||
Result:=Result+N;
|
||||
if (N<vector[i].iov_len) then Exit;
|
||||
end else
|
||||
begin
|
||||
Exit(-EIO);
|
||||
Break;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TFile.write (data:Pointer;size:Int64):Int64;
|
||||
var
|
||||
N:DWORD;
|
||||
R:BOOL;
|
||||
begin
|
||||
Assert(size<High(DWORD));
|
||||
|
||||
N:=0;
|
||||
rwlock_wrlock(lock);
|
||||
R:=WriteFile(Handle,data^,size,N,nil);
|
||||
rwlock_unlock(lock);
|
||||
|
||||
if R then
|
||||
begin
|
||||
Result:=N;
|
||||
end else
|
||||
begin
|
||||
Result:=-EIO;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFile.pwrite(data:Pointer;size,offset:Int64):Int64;
|
||||
var
|
||||
N:DWORD;
|
||||
O:TOVERLAPPED;
|
||||
p:Int64;
|
||||
R:BOOL;
|
||||
begin
|
||||
Assert(size<High(DWORD));
|
||||
|
||||
O:=Default(TOVERLAPPED);
|
||||
PInt64(@O.Offset)^:=offset;
|
||||
N:=0;
|
||||
rwlock_wrlock(lock);
|
||||
//NOTE: pread and pwrite don't change the file position, but ReadFile/WriteFile do, damn it.
|
||||
p:=_get_pos(Handle);
|
||||
R:=WriteFile(Handle,data^,size,N,@O);
|
||||
_set_pos(Handle,p);
|
||||
rwlock_unlock(lock);
|
||||
|
||||
if R then
|
||||
begin
|
||||
Result:=N;
|
||||
end else
|
||||
begin
|
||||
Result:=-EIO;
|
||||
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 TFile.fstat (stat:PSceKernelStat):Integer;
|
||||
var
|
||||
hfi:TByHandleFileInformation;
|
||||
err:DWORD;
|
||||
begin
|
||||
stat^:=Default(SceKernelStat);
|
||||
|
||||
Case SwGetFileType(Handle) 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(Handle,@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.
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue