From 40b2c39b5c5cee8a550f167c0a1fc6b9b33e56d8 Mon Sep 17 00:00:00 2001 From: red-prig Date: Sun, 13 Nov 2022 00:59:35 +0300 Subject: [PATCH] + --- kernel/ps4_kernel_file.pas | 610 ++++++++----------------------- kernel/ps4_libkernel.pas | 19 +- ps4_program.pas | 2 +- rtl/mmap.pas | 3 +- rtl/ps4_handles.pas | 9 +- src/ajm/ps4_libsceajm.pas | 2 +- src/audio/ps4_libsceaudioout.pas | 2 +- src/ps4_libscevideoout.pas | 2 +- sys/sys_dev.pas | 25 +- sys/sys_dir.pas | 9 +- sys/sys_fd.pas | 9 +- sys/sys_file.pas | 32 +- sys/sys_kernel.pas | 5 - 13 files changed, 235 insertions(+), 494 deletions(-) diff --git a/kernel/ps4_kernel_file.pas b/kernel/ps4_kernel_file.pas index db979fa..e493dd6 100644 --- a/kernel/ps4_kernel_file.pas +++ b/kernel/ps4_kernel_file.pas @@ -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(size0) 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; diff --git a/kernel/ps4_libkernel.pas b/kernel/ps4_libkernel.pas index fb34119..85bedbe 100644 --- a/kernel/ps4_libkernel.pas +++ b/kernel/ps4_libkernel.pas @@ -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 diff --git a/ps4_program.pas b/ps4_program.pas index dcd456e..9063a55 100644 --- a/ps4_program.pas +++ b/ps4_program.pas @@ -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. diff --git a/rtl/mmap.pas b/rtl/mmap.pas index 1aa1f20..80fd24e 100644 --- a/rtl/mmap.pas +++ b/rtl/mmap.pas @@ -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); diff --git a/rtl/ps4_handles.pas b/rtl/ps4_handles.pas index 768a296..6840818 100644 --- a/rtl/ps4_handles.pas +++ b/rtl/ps4_handles.pas @@ -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; diff --git a/src/ajm/ps4_libsceajm.pas b/src/ajm/ps4_libsceajm.pas index df25bef..f963e42 100644 --- a/src/ajm/ps4_libsceajm.pas +++ b/src/ajm/ps4_libsceajm.pas @@ -487,7 +487,7 @@ begin end; initialization - FAjmMap:=TIntegerHandles.Create; + FAjmMap:=TIntegerHandles.Create(1); ps4_app.RegistredPreLoad('libSceAjm.prx',@Load_libSceAjm); end. diff --git a/src/audio/ps4_libsceaudioout.pas b/src/audio/ps4_libsceaudioout.pas index af8abf0..52dfd99 100644 --- a/src/audio/ps4_libsceaudioout.pas +++ b/src/audio/ps4_libsceaudioout.pas @@ -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 diff --git a/src/ps4_libscevideoout.pas b/src/ps4_libscevideoout.pas index f3d0d4b..da119a6 100644 --- a/src/ps4_libscevideoout.pas +++ b/src/ps4_libscevideoout.pas @@ -1856,7 +1856,7 @@ end; initialization FQueueVideoOut.Create; - FVideoOutMap:=TIntegerHandles.Create; + FVideoOutMap:=TIntegerHandles.Create(1); ps4_app.RegistredPreLoad('libSceVideoOut.prx',@Load_libSceVideoOut); end. diff --git a/sys/sys_dev.pas b/sys/sys_dev.pas index 6db8753..a147097 100644 --- a/sys/sys_dev.pas +++ b/sys/sys_dev.pas @@ -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; diff --git a/sys/sys_dir.pas b/sys/sys_dir.pas index b9e1aa1..f5917c2 100644 --- a/sys/sys_dir.pas +++ b/sys/sys_dir.pas @@ -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; diff --git a/sys/sys_fd.pas b/sys/sys_fd.pas index a84c59a..c83c2ef 100644 --- a/sys/sys_fd.pas +++ b/sys/sys_fd.pas @@ -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. diff --git a/sys/sys_file.pas b/sys/sys_file.pas index d3aaba5..8206e08 100644 --- a/sys/sys_file.pas +++ b/sys/sys_file.pas @@ -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); diff --git a/sys/sys_kernel.pas b/sys/sys_kernel.pas index 1522592..d720b9c 100644 --- a/sys/sys_kernel.pas +++ b/sys/sys_kernel.pas @@ -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;