diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index dc62835d8a..e07d19fb32 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -694,8 +694,7 @@ u32 sceAtracEndEntry() { } u32 sceAtracGetBufferInfoForResetting(int atracID, int sample, u32 bufferInfoAddr) { - PSPPointer bufferInfo; - bufferInfo = bufferInfoAddr; + auto bufferInfo = PSPPointer::Create(bufferInfoAddr); Atrac *atrac = getAtrac(atracID); if (!atrac) { diff --git a/Core/HLE/sceCcc.cpp b/Core/HLE/sceCcc.cpp index a73690d7b0..c3beafc28f 100644 --- a/Core/HLE/sceCcc.cpp +++ b/Core/HLE/sceCcc.cpp @@ -289,8 +289,7 @@ int sceCccStrlenSJIS(u32 strAddr) u32 sceCccEncodeUTF8(u32 dstAddrAddr, u32 ucs) { - PSPPointer dstp; - dstp = dstAddrAddr; + auto dstp = PSPPointer::Create(dstAddrAddr); if (!dstp.IsValid() || !dstp->IsValid()) { @@ -304,8 +303,7 @@ u32 sceCccEncodeUTF8(u32 dstAddrAddr, u32 ucs) void sceCccEncodeUTF16(u32 dstAddrAddr, u32 ucs) { - PSPPointer dstp; - dstp = dstAddrAddr; + auto dstp = PSPPointer::Create(dstAddrAddr); if (!dstp.IsValid() || !dstp->IsValid()) { @@ -321,8 +319,7 @@ void sceCccEncodeUTF16(u32 dstAddrAddr, u32 ucs) u32 sceCccEncodeSJIS(u32 dstAddrAddr, u32 jis) { - PSPPointer dstp; - dstp = dstAddrAddr; + auto dstp = PSPPointer::Create(dstAddrAddr); if (!dstp.IsValid() || !dstp->IsValid()) { @@ -336,8 +333,7 @@ u32 sceCccEncodeSJIS(u32 dstAddrAddr, u32 jis) u32 sceCccDecodeUTF8(u32 dstAddrAddr) { - PSPPointer dstp; - dstp = dstAddrAddr; + auto dstp = PSPPointer::Create(dstAddrAddr); if (!dstp.IsValid() || !dstp->IsValid()) { ERROR_LOG(HLE, "sceCccDecodeUTF8(%08x): invalid pointer", dstAddrAddr); @@ -357,8 +353,7 @@ u32 sceCccDecodeUTF8(u32 dstAddrAddr) u32 sceCccDecodeUTF16(u32 dstAddrAddr) { - PSPPointer dstp; - dstp = dstAddrAddr; + auto dstp = PSPPointer::Create(dstAddrAddr); if (!dstp.IsValid() || !dstp->IsValid()) { ERROR_LOG(HLE, "sceCccDecodeUTF16(%08x): invalid pointer", dstAddrAddr); @@ -379,8 +374,7 @@ u32 sceCccDecodeUTF16(u32 dstAddrAddr) u32 sceCccDecodeSJIS(u32 dstAddrAddr) { - PSPPointer dstp; - dstp = dstAddrAddr; + auto dstp = PSPPointer::Create(dstAddrAddr); if (!dstp.IsValid() || !dstp->IsValid()) { ERROR_LOG(HLE, "sceCccDecodeSJIS(%08x): invalid pointer", dstAddrAddr); diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index ad99f5f649..cc19502d58 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -236,8 +236,7 @@ int __CtrlReadBuffer(u32 ctrlDataPtr, u32 nBufs, bool negative, bool peek) ctrlBufRead = (ctrlBuf - availBufs + NUM_CTRL_BUFFERS) % NUM_CTRL_BUFFERS; int done = 0; - PSPPointer<_ctrl_data> data; - data = ctrlDataPtr; + auto data = PSPPointer<_ctrl_data>::Create(ctrlDataPtr); for (u32 i = 0; i < availBufs; ++i) done += __CtrlReadSingleBuffer(data++, negative); diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 773b9ba78b..6398a8b580 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -333,8 +333,7 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, DEBUG_LOG(SCEGE, "sceGeListEnQueue(addr=%08x, stall=%08x, cbid=%08x, param=%08x)", listAddress, stallAddress, callbackId, optParamAddr); - PSPPointer optParam; - optParam = optParamAddr; + auto optParam = PSPPointer::Create(optParamAddr); u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, false); if ((int)listID >= 0) @@ -352,8 +351,7 @@ u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, DEBUG_LOG(SCEGE, "sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x)", listAddress, stallAddress, callbackId, optParamAddr); - PSPPointer optParam; - optParam = optParamAddr; + auto optParam = PSPPointer::Create(optParamAddr); u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, true); if ((int)listID >= 0) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 675a3204f6..fad604789f 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -51,6 +51,7 @@ extern "C" { #include "Core/HLE/sceDisplay.h" const int ERROR_ERRNO_FILE_NOT_FOUND = 0x80010002; +const int ERROR_ERRNO_IO_ERROR = 0x80010005; const int ERROR_ERRNO_FILE_ALREADY_EXISTS = 0x80010011; const int ERROR_MEMSTICK_DEVCTL_BAD_PARAMS = 0x80220081; const int ERROR_MEMSTICK_DEVCTL_TOO_MANY_CALLBACKS = 0x80220082; @@ -988,6 +989,32 @@ u32 npdrmLseek(FileNode *f, s32 where, FileMove whence) return newPos; } +s64 __IoLseekDest(FileNode *f, s64 offset, int whence, FileMove &seek) { + seek = FILEMOVE_BEGIN; + + s64 newPos = 0; + switch (whence) { + case 0: + newPos = offset; + break; + case 1: + newPos = pspFileSystem.GetSeekPos(f->handle) + offset; + seek = FILEMOVE_CURRENT; + break; + case 2: + newPos = f->info.size + offset; + seek = FILEMOVE_END; + break; + default: + return (s32)SCE_KERNEL_ERROR_INVAL; + } + + // Yes, -1 is the correct return code for this case. + if (newPos < 0) + return -1; + return newPos; +} + s64 __IoLseek(SceUID id, s64 offset, int whence) { u32 error; FileNode *f = __IoGetFd(id, error); @@ -996,31 +1023,14 @@ s64 __IoLseek(SceUID id, s64 offset, int whence) { WARN_LOG(SCEIO, "sceIoLseek*(%d, %llx, %i): async busy", id, offset, whence); return SCE_KERNEL_ERROR_ASYNC_BUSY; } - FileMove seek = FILEMOVE_BEGIN; - - s64 newPos = 0; - switch (whence) { - case 0: - newPos = offset; - break; - case 1: - newPos = pspFileSystem.GetSeekPos(f->handle) + offset; - seek = FILEMOVE_CURRENT; - break; - case 2: - newPos = f->info.size + offset; - seek = FILEMOVE_END; - break; - default: - return (s32)SCE_KERNEL_ERROR_INVAL; - } + FileMove seek; + s64 newPos = __IoLseekDest(f, offset, whence, seek); if(f->npdrm) return npdrmLseek(f, (s32)offset, seek); - // Yes, -1 is the correct return code for this case. if (newPos < 0) - return -1; + return newPos; return pspFileSystem.SeekFile(f->handle, (s32) offset, seek); } else { return (s32) error; @@ -1966,47 +1976,137 @@ int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 out return (int)f->info.size; break; + // Get ISO9660 volume descriptor (from open ISO9660 file.) + case 0x01020001: + // TODO: Should not work for umd0:/, ms0:/, etc. + // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. + if (!Memory::IsValidAddress(outdataPtr) || outlen < 0x800) { + WARN_LOG_REPORT(SCEIO, "sceIoIoctl: Invalid out pointer while reading ISO9660 volume descriptor"); + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; + } else { + INFO_LOG(SCEIO, "sceIoIoctl: reading ISO9660 volume descriptor read"); + u32 descFd = pspFileSystem.OpenFile("disc0:/sce_lbn0x10_size0x800", FILEACCESS_READ); + if (descFd == 0) { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; + } + pspFileSystem.ReadFile(descFd, Memory::GetPointer(outdataPtr), 0x800); + pspFileSystem.CloseFile(descFd); + return 0; + } + break; + + // Get ISO9660 path table (from open ISO9660 file.) + case 0x01020002: + // TODO: Should not work for umd0:/, ms0:/, etc. + // Seems like it will accept an out size > path table size, but only write path table bytes. + // If not big enough, returns SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT. + // Probably only the LE version. + { + char temp[256]; + // We want the reported message to include the cmd, so it's unique. + sprintf(temp, "sceIoIoctl(%%s, %08x, %%08x, %%x, %%08x, %%x)", cmd); + Reporting::ReportMessage(temp, f->fullpath.c_str(), indataPtr, inlen, outdataPtr, outlen); + ERROR_LOG(SCEIO, "UNIMPL 0=sceIoIoctl id: %08x, cmd %08x, indataPtr %08x, inlen %08x, outdataPtr %08x, outLen %08x", id,cmd,indataPtr,inlen,outdataPtr,outlen); + } + break; + // Get UMD sector size case 0x01020003: - INFO_LOG(SCEIO, "sceIoIoCtl: Asked for sector size of file %i", id); - if (Memory::IsValidAddress(outdataPtr) && outlen == 4) { - Memory::Write_U32(f->info.sectorSize, outdataPtr); + // TODO: Should not work for umd0:/, ms0:/, etc. + // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. + INFO_LOG(SCEIO, "sceIoIoctl: Asked for sector size of file %i", id); + if (Memory::IsValidAddress(outdataPtr) && outlen >= 4) { + // ISOs always use 2048 sized sectors. + Memory::Write_U32(2048, outdataPtr); + } else { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } break; // Get UMD file offset case 0x01020004: - { + // TODO: Should not work for umd0:/, ms0:/, etc. + // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. + INFO_LOG(SCEIO, "sceIoIoctl: Asked for file offset of file %i", id); + if (Memory::IsValidAddress(outdataPtr) && outlen >= 4) { u32 offset = (u32)pspFileSystem.GetSeekPos(f->handle); - INFO_LOG(SCEIO, "sceIoIoCtl: Asked for file offset of file %i", id); - if (Memory::IsValidAddress(outdataPtr) && outlen >= 4) { - Memory::Write_U32(offset, outdataPtr); + Memory::Write_U32(offset, outdataPtr); + } else { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; + } + break; + + case 0x01010005: + // TODO: Should not work for umd0:/, ms0:/, etc. + // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. + INFO_LOG(SCEIO, "sceIoIoctl: Seek for file %i", id); + // Even if the size is 4, it still actually reads a 16 byte struct, it seems. + if (Memory::IsValidAddress(indataPtr) && inlen >= 4) { + struct SeekInfo { + u64 offset; + u32 unk; + u32 whence; + }; + const auto seekInfo = PSPPointer::Create(indataPtr); + FileMove seek; + s64 newPos = __IoLseekDest(f, seekInfo->offset, seekInfo->whence, seek); + if (newPos < 0 || newPos > f->info.size) { + // Not allowed to seek past the end of the file with this API. + return ERROR_ERRNO_IO_ERROR; } + pspFileSystem.SeekFile(f->handle, (s32)seekInfo->offset, seek); + } else { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } break; // Get UMD file start sector. case 0x01020006: - INFO_LOG(SCEIO, "sceIoIoCtl: Asked for start sector of file %i", id); + // TODO: Should not work for umd0:/, ms0:/, etc. + // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. + INFO_LOG(SCEIO, "sceIoIoctl: Asked for start sector of file %i", id); if (Memory::IsValidAddress(outdataPtr) && outlen >= 4) { Memory::Write_U32(f->info.startSector, outdataPtr); + } else { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } break; // Get UMD file size in bytes. case 0x01020007: - INFO_LOG(SCEIO, "sceIoIoCtl: Asked for size of file %i", id); + // TODO: Should not work for umd0:/, ms0:/, etc. + // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. + INFO_LOG(SCEIO, "sceIoIoctl: Asked for size of file %i", id); if (Memory::IsValidAddress(outdataPtr) && outlen >= 8) { Memory::Write_U64(f->info.size, outdataPtr); + } else { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; + } + break; + + // Read from UMD file. + case 0x01030008: + // TODO: Should not work for umd0:/, ms0:/, etc. + // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. + INFO_LOG(SCEIO, "sceIoIoctl: Read from file %i", id); + if (Memory::IsValidAddress(indataPtr) && inlen >= 4) { + u32 size = Memory::Read_U32(indataPtr); + if (Memory::IsValidAddress(outdataPtr) && size <= outlen) { + return sceIoRead(id, outdataPtr, size); + } else { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; + } + } else { + return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } break; // Unknown command, always expects return value of 1 according to JPCSP, used by Pangya Fantasy Golf. // TODO: This is unsupported on ms0:/ (SCE_KERNEL_ERROR_UNSUP.) case 0x01f30003: - INFO_LOG(SCEIO, "sceIoIoCtl: Unknown cmd %08x always returns 1", cmd); + INFO_LOG(SCEIO, "sceIoIoctl: Unknown cmd %08x always returns 1", cmd); if(inlen != 4 || outlen != 1 || Memory::Read_U32(indataPtr) != outlen) { - INFO_LOG(SCEIO, "sceIoIoCtl id: %08x, cmd %08x, indataPtr %08x, inlen %08x, outdataPtr %08x, outlen %08x has invalid parameters", id, cmd, indataPtr, inlen, outdataPtr, outlen); + INFO_LOG(SCEIO, "sceIoIoctl id: %08x, cmd %08x, indataPtr %08x, inlen %08x, outdataPtr %08x, outlen %08x has invalid parameters", id, cmd, indataPtr, inlen, outdataPtr, outlen); return SCE_KERNEL_ERROR_INVALID_ARGUMENT; } else { @@ -2020,6 +2120,7 @@ int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 out sprintf(temp, "sceIoIoctl(%%s, %08x, %%08x, %%x, %%08x, %%x)", cmd); Reporting::ReportMessage(temp, f->fullpath.c_str(), indataPtr, inlen, outdataPtr, outlen); ERROR_LOG(SCEIO, "UNIMPL 0=sceIoIoctl id: %08x, cmd %08x, indataPtr %08x, inlen %08x, outdataPtr %08x, outLen %08x", id,cmd,indataPtr,inlen,outdataPtr,outlen); + // TODO: return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } break; } @@ -2060,8 +2161,7 @@ u32 sceIoIoctlAsync(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u u32 sceIoGetFdList(u32 outAddr, int outSize, u32 fdNumAddr) { WARN_LOG(SCEIO, "sceIoGetFdList(%08x, %i, %08x)", outAddr, outSize, fdNumAddr); - PSPPointer out; - out = outAddr; + auto out = PSPPointer::Create(outAddr); int count = 0; // Always have the first three. diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index e0efc36cef..2098084205 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1803,8 +1803,7 @@ u32 sceKernelQueryModuleInfo(u32 uid, u32 infoAddr) return -1; } - PSPPointer info; - info = infoAddr; + auto info = PSPPointer::Create(infoAddr); memcpy(info->segmentaddr, module->nm.segmentaddr, sizeof(info->segmentaddr)); memcpy(info->segmentsize, module->nm.segmentsize, sizeof(info->segmentsize)); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 03ff9621e9..8b69a58743 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1535,8 +1535,7 @@ u32 sceKernelReferThreadRunStatus(u32 threadID, u32 statusPtr) if (!Memory::IsValidAddress(statusPtr)) return -1; - PSPPointer runStatus; - runStatus = statusPtr; + auto runStatus = PSPPointer::Create(statusPtr); // TODO: Check size? runStatus->size = sizeof(SceKernelThreadRunStatus); @@ -2575,8 +2574,7 @@ int sceKernelDelayThread(u32 usec) int sceKernelDelaySysClockThreadCB(u32 sysclockAddr) { - PSPPointer sysclock; - sysclock = sysclockAddr; + auto sysclock = PSPPointer::Create(sysclockAddr); if (!sysclock.IsValid()) { ERROR_LOG(SCEKERNEL, "sceKernelDelaySysClockThreadCB(%08x) - bad pointer", sysclockAddr); return -1; @@ -2594,8 +2592,7 @@ int sceKernelDelaySysClockThreadCB(u32 sysclockAddr) int sceKernelDelaySysClockThread(u32 sysclockAddr) { - PSPPointer sysclock; - sysclock = sysclockAddr; + auto sysclock = PSPPointer::Create(sysclockAddr); if (!sysclock.IsValid()) { ERROR_LOG(SCEKERNEL, "sceKernelDelaySysClockThread(%08x) - bad pointer", sysclockAddr); return -1; diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index dd4ccad48d..e62afc50d5 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -900,8 +900,7 @@ int sceMpegQueryAtracEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) int sceMpegRingbufferAvailableSize(u32 ringbufferAddr) { - PSPPointer ringbuffer; - ringbuffer = ringbufferAddr; + auto ringbuffer = PSPPointer::Create(ringbufferAddr); if (!ringbuffer.IsValid()) { ERROR_LOG(ME, "sceMpegRingbufferAvailableSize(%08x) - bad address", ringbufferAddr); diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index d5317869c2..e0deb26515 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -395,8 +395,7 @@ static std::map psmfPlayerMap; Psmf *getPsmf(u32 psmf) { - PSPPointer psmfstruct; - psmfstruct = psmf; + auto psmfstruct = PSPPointer::Create(psmf); if (!psmfstruct.IsValid()) return 0; auto iter = psmfMap.find(psmfstruct->headerOffset); diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 6bf970ba9a..c7defa11b5 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -222,8 +222,7 @@ u32 sceUmdGetDiscInfo(u32 infoAddr) DEBUG_LOG(SCEIO, "sceUmdGetDiscInfo(%08x)", infoAddr); if (Memory::IsValidAddress(infoAddr)) { - PSPPointer info; - info = infoAddr; + auto info = PSPPointer::Create(infoAddr); if (info->size != 8) return PSP_ERROR_UMD_INVALID_PARAM; diff --git a/Core/MemMap.h b/Core/MemMap.h index 9ae6488315..60d2da3175 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -428,6 +428,12 @@ struct PSPPointer { return Memory::IsValidAddress(ptr); } + + static PSPPointer Create(u32 ptr) { + PSPPointer p; + p = ptr; + return p; + } }; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 3cfff675d4..efbcc6a202 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -182,8 +182,7 @@ int GPUCommon::GetStack(int index, u32 stackPtr) { } if (index >= 0) { - PSPPointer stack; - stack = stackPtr; + auto stack = PSPPointer::Create(stackPtr); if (stack.IsValid()) { auto entry = currentList->stack[index]; // Not really sure what most of these values are.