diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index a5562976a..5054b9330 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -220,14 +220,16 @@ int PSPOskDialog::Init(u32 oskPtr) inputChars = L""; - u16 *src = (u16 *) Memory::GetPointer(oskData.intextPtr); - int c; - while (c = *src++) - { - inputChars += c; - if(c == 0x00) + if (oskData.intextPtr) { + u16 *src = (u16 *) Memory::GetPointer(oskData.intextPtr); + int c; + while (c = *src++) { - break; + inputChars += c; + if(c == 0x00) + { + break; + } } } diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index ac7bb2f2b..e0d31e2f2 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -199,3 +199,21 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) } return true; } + + +NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(std::string _filename) + : filename_(_filename), pbpReader_(_filename.c_str()) { + std::string paramSfo; + pbpReader_.GetSubFileAsString(PBP_PARAM_SFO, ¶mSfo); +} + +NPDRMDemoBlockDevice::~NPDRMDemoBlockDevice() { + +} + +bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) { + // TODO: Fill in decryption code here. Use pbpReader to read the file - might need to + // extend its functionality to do it efficiently. + + return false; +} diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index e9c95939d..aa9cc47c0 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -23,9 +23,11 @@ // The ISOFileSystemReader reads from a BlockDevice, so it automatically works // with CISO images. -#include "../../Globals.h" #include +#include "../../Globals.h" +#include "Core/ELF/PBPReader.h" + class BlockDevice { public: @@ -69,4 +71,24 @@ private: }; +// For encrypted ISOs in PBP files. + +class NPDRMDemoBlockDevice : public BlockDevice +{ +public: + NPDRMDemoBlockDevice(std::string _filename); + ~NPDRMDemoBlockDevice(); + + bool ReadBlock(int blockNumber, u8 *outPtr); + u32 GetNumBlocks() {return (u32)numBlocks_;} + +private: + std::string filename_; + PBPReader pbpReader_; + FILE *file_; + size_t size_; + size_t numBlocks_; +}; + + BlockDevice *constructBlockDevice(const char *filename); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index a070df0e0..59daa30d4 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -683,6 +683,11 @@ bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std:: __KernelInit(); PSPFileInfo info = pspFileSystem.GetFileInfo(filename); + if (!info.exists) { + ERROR_LOG(LOADER, "Failed to load executable %s - file doesn't exist", filename); + *error_string = "Could not find executable"; + return false; + } u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ); @@ -694,6 +699,8 @@ bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std:: if (!module) { ERROR_LOG(LOADER, "Failed to load module %s", filename); + *error_string = "Failed to load executable module"; + delete [] temp; return false; } diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 813a6795e..4ccf47a6f 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -126,25 +126,47 @@ bool Load_PSP_ISO(const char *filename, std::string *error_string) bool Load_PSP_ELF_PBP(const char *filename, std::string *error_string) { - // This is really just for headless, might need tweaking later. - if (!PSP_CoreParameter().mountIso.empty()) - { - ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(PSP_CoreParameter().mountIso.c_str())); + // Figure out if this is a "DEMO" PBP. In that case we want to mount it + // on UMD0:. + PBPReader reader(filename); - pspFileSystem.Mount("umd1:", umd2); - pspFileSystem.Mount("disc0:", umd2); - pspFileSystem.Mount("umd:", umd2); - } + // Hacky check, should find something better + if (reader.GetSubFileSize(PBP_UNKNOWN_PSAR) > 0x100000) { + // Yay, got a demo. + ISOFileSystem *umd0 = new ISOFileSystem(&pspFileSystem, new NPDRMDemoBlockDevice(filename)); + + pspFileSystem.Mount("umd1:", umd0); + pspFileSystem.Mount("disc0:", umd0); + pspFileSystem.Mount("umd:", umd0); + pspFileSystem.Mount("umd0:", umd0); - std::string full_path = filename; - std::string path, file, extension; - SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); + std::string bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.BIN"; + INFO_LOG(LOADER,"Loading %s from demo iso...", bootpath.c_str()); + return __KernelLoadExec(bootpath.c_str(), 0, error_string); + } else { + // Classic homebrew PBP. + + // This is really just for headless, might need tweaking later. + if (!PSP_CoreParameter().mountIso.empty()) + { + ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(PSP_CoreParameter().mountIso.c_str())); + + pspFileSystem.Mount("umd1:", umd2); + pspFileSystem.Mount("disc0:", umd2); + pspFileSystem.Mount("umd:", umd2); + } + + std::string full_path = filename; + std::string path, file, extension; + SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension); #ifdef _WIN32 - path = ReplaceAll(path, "/", "\\"); + path = ReplaceAll(path, "/", "\\"); #endif - DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path); - pspFileSystem.Mount("umd0:", fs); - std::string finalName = "umd0:/" + file + extension; - return __KernelLoadExec(finalName.c_str(), 0, error_string); + DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path); + pspFileSystem.Mount("umd0:", fs); + + std::string finalName = "umd0:/" + file + extension; + return __KernelLoadExec(finalName.c_str(), 0, error_string); + } }