From 63088515b49e118ffad192b73163ea1dbff27899 Mon Sep 17 00:00:00 2001 From: Raul Tambre Date: Wed, 13 Aug 2014 21:01:09 +0300 Subject: [PATCH 1/2] Actually fix sys_rwlock_create --- rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp | 45 +++++++++++---------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index 6e6d631618..74987422fd 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -10,38 +10,29 @@ s32 sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t attr { sys_rwlock.Warning("sys_rwlock_create(rw_lock_id_addr=0x%x, attr_addr=0x%x)", rw_lock_id.GetAddr(), attr.GetAddr()); - if (attr) + if (!attr) + return CELL_EFAULT; + + switch (attr->attr_protocol.ToBE()) { - switch (attr->attr_protocol.ToBE()) - { - case se(attr->attr_protocol, SYS_SYNC_PRIORITY): sys_rwlock.Todo("SYS_SYNC_PRIORITY"); break; - case se(attr->attr_protocol, SYS_SYNC_RETRY): sys_rwlock.Error("SYS_SYNC_RETRY"); return CELL_EINVAL; - case se(attr->attr_protocol, SYS_SYNC_PRIORITY_INHERIT): sys_rwlock.Todo("SYS_SYNC_PRIORITY_INHERIT"); break; - case se(attr->attr_protocol, SYS_SYNC_FIFO): break; - default: return CELL_EINVAL; - } - - if (attr->attr_pshared.ToBE() != se32(0x200)) - { - sys_rwlock.Error("Invalid attr_pshared(0x%x)", (u32)attr->attr_pshared); - return CELL_EINVAL; - } - - rw_lock_id = sys_rwlock.GetNewId(new RWLock((u32)attr->attr_protocol, attr->name_u64)); - - sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id = %d", - std::string(attr->name, 8).c_str(), (u32)attr->attr_protocol, rw_lock_id.GetValue()); + case se(attr->attr_protocol, SYS_SYNC_PRIORITY): sys_rwlock.Todo("SYS_SYNC_PRIORITY"); break; + case se(attr->attr_protocol, SYS_SYNC_RETRY): sys_rwlock.Error("SYS_SYNC_RETRY"); return CELL_EINVAL; + case se(attr->attr_protocol, SYS_SYNC_PRIORITY_INHERIT): sys_rwlock.Todo("SYS_SYNC_PRIORITY_INHERIT"); break; + case se(attr->attr_protocol, SYS_SYNC_FIFO): break; + default: return CELL_EINVAL; } - else + + if (attr->attr_pshared.ToBE() != se32(0x200)) { - sys_rwlock.Todo("SYS_SYNC_PRIORITY"); - - rw_lock_id = sys_rwlock.GetNewId(new RWLock((u32)SYS_SYNC_PRIORITY, (u64)"default")); - - sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id = %d", - std::string("default", 8).c_str(), (u32)SYS_SYNC_PRIORITY, rw_lock_id.GetValue()); + sys_rwlock.Error("Invalid attr_pshared(0x%x)", (u32)attr->attr_pshared); + return CELL_EINVAL; } + rw_lock_id = sys_rwlock.GetNewId(new RWLock((u32)attr->attr_protocol, attr->name_u64)); + + sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id = %d", + std::string(attr->name, 8).c_str(), (u32)attr->attr_protocol, rw_lock_id.GetValue()); + return CELL_OK; } From 91b4596c0bccefabdd9ad3d8f9317a05bfa1bdde Mon Sep 17 00:00:00 2001 From: Raul Tambre Date: Wed, 13 Aug 2014 22:29:38 +0300 Subject: [PATCH 2/2] Implement sceNpDrmIsAvailable2 --- rpcs3/Emu/SysCalls/Modules/sceNp.cpp | 66 +++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp index 7ae3e88654..f8588f7c6d 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -97,7 +97,71 @@ int sceNpDrmIsAvailable(u32 k_licensee_addr, u32 drm_path_addr) int sceNpDrmIsAvailable2(u32 k_licensee_addr, u32 drm_path_addr) { - UNIMPLEMENTED_FUNC(sceNp); + sceNp->Warning("sceNpDrmIsAvailable2(k_licensee_addr=0x%x, drm_path_addr=0x%x)", k_licensee_addr, drm_path_addr); + + std::string drm_path = Memory.ReadString(drm_path_addr); + if (!Emu.GetVFS().ExistsFile(drm_path)) + { + sceNp->Warning("sceNpDrmIsAvailable2(): '%s' not found", drm_path.c_str()); + return CELL_ENOENT; + } + + std::string k_licensee_str = "0"; + u8 k_licensee[0x10]; + + if (k_licensee_addr) + { + for (int i = 0; i < 0x10; i++) + { + k_licensee[i] = Memory.Read8(k_licensee_addr + i); + k_licensee_str += fmt::Format("%02x", k_licensee[i]); + } + } + + sceNp->Warning("sceNpDrmIsAvailable2: Found DRM license file at %s", drm_path.c_str()); + sceNp->Warning("sceNpDrmIsAvailable2: Using k_licensee 0x%s", k_licensee_str.c_str()); + + // Set the necessary file paths. + std::string drm_file_name = fmt::AfterLast(drm_path, '/'); + + // TODO: Make more explicit what this actually does (currently it copies "XXXXXXXX" from drm_path (== "/dev_hdd0/game/XXXXXXXXX/*" assumed) + std::string titleID = drm_path.substr(15, 9); + + // TODO: These shouldn't use current dir + std::string enc_drm_path = drm_path; + std::string dec_drm_path = "/dev_hdd1/" + titleID + "/" + drm_file_name; + std::string rap_path = "/dev_usb000/"; + + // Search dev_usb000 for a compatible RAP file. + vfsDir *raps_dir = new vfsDir(rap_path); + if (!raps_dir->IsOpened()) + sceNp->Warning("sceNpDrmIsAvailable2: Can't find RAP file for DRM!"); + else + { + const std::vector &entries = raps_dir->GetEntries(); + for (auto &entry : entries) + { + if (entry.name.find(titleID) != std::string::npos) + { + rap_path += entry.name; + break; + } + } + } + + // Create a new directory under dev_hdd1/titleID to hold the decrypted data. + // TODO: These shouldn't use current dir + std::string tmp_dir = "./dev_hdd1/" + titleID; + if (!rExists(tmp_dir)) + rMkdir("./dev_hdd1/" + titleID); + + // Decrypt this EDAT using the supplied k_licensee and matching RAP file. + std::string enc_drm_path_local, dec_drm_path_local, rap_path_local; + Emu.GetVFS().GetDevice(enc_drm_path, enc_drm_path_local); + Emu.GetVFS().GetDevice(dec_drm_path, dec_drm_path_local); + Emu.GetVFS().GetDevice(rap_path, rap_path_local); + + DecryptEDAT(enc_drm_path_local, dec_drm_path_local, 8, rap_path_local, k_licensee, false); return CELL_OK; }