mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Fix "double delay" error in sceNpDrmEdataSetupKey
This commit is contained in:
parent
0a069f39c9
commit
c5e0dafa44
5 changed files with 31 additions and 19 deletions
|
@ -575,7 +575,7 @@ size_t MetaFileSystem::SeekFile(u32 handle, s32 position, FileMove type)
|
|||
std::lock_guard<std::recursive_mutex> guard(lock);
|
||||
IFileSystem *sys = GetHandleOwner(handle);
|
||||
if (sys)
|
||||
return sys->SeekFile(handle,position,type);
|
||||
return sys->SeekFile(handle, position, type);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -130,13 +130,11 @@ u64 hleDelayResult(u64 result, const char *reason, int usec);
|
|||
void hleEatCycles(int cycles);
|
||||
void hleEatMicro(int usec);
|
||||
|
||||
inline int hleDelayResult(int result, const char *reason, int usec)
|
||||
{
|
||||
inline int hleDelayResult(int result, const char *reason, int usec) {
|
||||
return hleDelayResult((u32) result, reason, usec);
|
||||
}
|
||||
|
||||
inline s64 hleDelayResult(s64 result, const char *reason, int usec)
|
||||
{
|
||||
inline s64 hleDelayResult(s64 result, const char *reason, int usec) {
|
||||
return hleDelayResult((u64) result, reason, usec);
|
||||
}
|
||||
|
||||
|
|
|
@ -2533,7 +2533,7 @@ static u32 sceIoDclose(int id) {
|
|||
return kernelObjects.Destroy<DirListing>(id);
|
||||
}
|
||||
|
||||
static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) {
|
||||
int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) {
|
||||
u32 error;
|
||||
FileNode *f = __IoGetFd(id, error);
|
||||
if (error) {
|
||||
|
@ -2546,7 +2546,7 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr,
|
|||
}
|
||||
|
||||
// TODO: Move this into each command, probably?
|
||||
usec = 100;
|
||||
usec += 100;
|
||||
|
||||
//KD Hearts:
|
||||
//56:46:434 HLE\sceIo.cpp:886 E[HLE]: UNIMPL 0=sceIoIoctrl id: 0000011f, cmd 04100001, indataPtr 08b313d8, inlen 00000010, outdataPtr 00000000, outLen 0
|
||||
|
@ -2574,25 +2574,28 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr,
|
|||
pspFileSystem.SeekFile(f->handle, (s32)f->pgd_offset, FILEMOVE_BEGIN);
|
||||
pspFileSystem.ReadFile(f->handle, pgd_header, 0x90);
|
||||
f->pgdInfo = pgd_open(pgd_header, 2, key_ptr);
|
||||
if(f->pgdInfo==NULL){
|
||||
ERROR_LOG(SCEIO, "Not a valid PGD file. Open as normal file.");
|
||||
if (!f->pgdInfo) {
|
||||
ERROR_LOG(SCEIO, "Not a valid PGD file. Examining.");
|
||||
f->npdrm = false;
|
||||
pspFileSystem.SeekFile(f->handle, (s32)0, FILEMOVE_BEGIN);
|
||||
if(memcmp(pgd_header, pgd_magic, 4)==0){
|
||||
if (memcmp(pgd_header, pgd_magic, 4) == 0) {
|
||||
ERROR_LOG(SCEIO, "File is PGD file, but there's likely a key mismatch. Returning error.");
|
||||
// File is PGD file, but key mismatch
|
||||
return ERROR_PGD_INVALID_HEADER;
|
||||
}else{
|
||||
} else {
|
||||
WARN_LOG(SCEIO, "File is not encrypted, proceeding.");
|
||||
// File is decrypted.
|
||||
return 0;
|
||||
}
|
||||
}else{
|
||||
// Everthing OK.
|
||||
} else {
|
||||
// Everything OK.
|
||||
f->npdrm = true;
|
||||
f->pgdInfo->data_offset += f->pgd_offset;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Set PGD offset. Called from sceNpDrmEdataSetupKey
|
||||
case 0x04100002:
|
||||
f->pgd_offset = indataPtr;
|
||||
|
@ -2739,7 +2742,7 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr,
|
|||
// Even if the size is 4, it still actually reads a 16 byte struct, it seems.
|
||||
|
||||
//if (GetIOTimingMethod() == IOTIMING_REALISTIC) // Need a check for io timing method?
|
||||
usec = 15000;// Fantasy Golf Pangya Portable(KS) needs a delay over 15000us.
|
||||
usec += 15000;// Fantasy Golf Pangya Portable(KS) needs a delay over 15000us.
|
||||
|
||||
if (Memory::IsValidAddress(indataPtr) && inlen >= 4) {
|
||||
struct SeekInfo {
|
||||
|
@ -2928,7 +2931,7 @@ static int IoAsyncFinish(int id) {
|
|||
break;
|
||||
|
||||
case IoAsyncOp::IOCTL:
|
||||
us = 100;
|
||||
us = 0; // __IoIoctl will add 100.
|
||||
f->asyncResult = __IoIoctl(id, params.ioctl.cmd, params.ioctl.inAddr, params.ioctl.inSize, params.ioctl.outAddr, params.ioctl.outSize, us);
|
||||
DEBUG_LOG(SCEIO, "ASYNC sceIoIoctlAsync(%08x, %08x, %08x, %08x, %08x, %08x)", id, params.ioctl.cmd, params.ioctl.inAddr, params.ioctl.inSize, params.ioctl.outAddr, params.ioctl.outSize);
|
||||
break;
|
||||
|
|
|
@ -29,6 +29,11 @@ struct tm;
|
|||
|
||||
u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen);
|
||||
|
||||
// Called by sceIoIoctl, which normally applies the delay this function writes to usec.
|
||||
// If you need to call sceIoIoctl from a HLE function implementation more than once, use
|
||||
// __IoIoctl directly to avoid double-delays.
|
||||
int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec);
|
||||
|
||||
u32 __IoGetFileHandleFromId(u32 id, u32 &outError);
|
||||
void __IoCopyDate(ScePspDateTime& date_out, const tm& date_in);
|
||||
|
||||
|
|
|
@ -25,10 +25,16 @@ static int sceNpDrmRenameCheck(const char *filename)
|
|||
static int sceNpDrmEdataSetupKey(u32 edataFd)
|
||||
{
|
||||
INFO_LOG(HLE, "call sceNpDrmEdataSetupKey %x", edataFd);
|
||||
/* set PGD offset */
|
||||
sceIoIoctl(edataFd, 0x04100002, 0x90, 0, 0, 0);
|
||||
/* call PGD open */
|
||||
return sceIoIoctl(edataFd, 0x04100001, 0, 0, 0, 0);
|
||||
int usec = 0;
|
||||
// set PGD offset
|
||||
int retval = __IoIoctl(edataFd, 0x04100002, 0x90, 0, 0, 0, usec);
|
||||
if (retval != 0) {
|
||||
return hleDelayResult(retval, "io ctrl command", usec);
|
||||
}
|
||||
// call PGD open
|
||||
// Note that usec accumulates.
|
||||
retval = __IoIoctl(edataFd, 0x04100001, 0, 0, 0, 0, usec);
|
||||
return hleDelayResult(retval, "io ctrl command", usec);
|
||||
}
|
||||
|
||||
static int sceNpDrmEdataGetDataSize(u32 edataFd)
|
||||
|
|
Loading…
Add table
Reference in a new issue