예제 #1
0
        /// <summary>
        /// Unpack a PBP file, avoiding to consume too much memory
        /// (i.e. not reading each section completely in memory).
        /// </summary>
        /// <param name="vFile">        the PBP file </param>
        /// <exception cref="IOException"> </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static void unpackPBP(pspsharp.HLE.VFS.IVirtualFile vFile) throws java.io.IOException
        public static void unpackPBP(IVirtualFile vFile)
        {
            vFile.ioLseek(0L);
            PBP pbp = new PBP();

            pbp.size_pbp = (int)vFile.Length();
            pbp.p_magic  = read32(vFile);
            if (!pbp.Valid)
            {
                return;
            }
            pbp.p_version = read32(vFile);
            pbp.p_offsets = new int[] { read32(vFile), read32(vFile), read32(vFile), read32(vFile), read32(vFile), read32(vFile), read32(vFile), read32(vFile), pbp.size_pbp };

            File dir = new File(PBP_UNPACK_PATH_PREFIX);

            deleteDir(dir);             //delete all files and directory
            dir.mkdir();

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'sealed override':
//ORIGINAL LINE: sealed override byte[] buffer = new byte[10 * 1024];
            sbyte[] buffer = new sbyte[10 * 1024];
            for (int index = 0; index < TOTAL_FILES; index++)
            {
                int size = pbp.getSize(index);
                if (size > 0)
                {
                    long offset = pbp.getOffset(index) & 0xFFFFFFFFL;
                    if (vFile.ioLseek(offset) == offset)
                    {
                        System.IO.Stream os = new System.IO.FileStream(PBP_UNPACK_PATH_PREFIX + pbp.getName(index), System.IO.FileMode.Create, System.IO.FileAccess.Write);
                        while (size > 0)
                        {
                            int Length     = System.Math.Min(size, buffer.Length);
                            int readLength = vFile.ioRead(buffer, 0, Length);
                            if (readLength > 0)
                            {
                                os.Write(buffer, 0, readLength);
                                size -= readLength;
                            }
                            if (readLength != Length)
                            {
                                break;
                            }
                        }
                        os.Close();
                    }
                }
            }
        }
예제 #2
0
        protected internal override bool isHeaderValid(IVirtualFile pgdFile)
        {
            sbyte[] header   = new sbyte[edatHeaderSize];
            long    position = pgdFile.Position;
            int     Length   = pgdFile.ioRead(header, 0, edatHeaderSize);

            pgdFile.ioLseek(position);

            if (Length != edatHeaderSize)
            {
                return(false);
            }

            if (header[0] != 0 || header[1] != (sbyte)'P' || header[2] != (sbyte)'S' || header[3] != (sbyte)'P' || header[4] != (sbyte)'E' || header[5] != (sbyte)'D' || header[6] != (sbyte)'A' || header[7] != (sbyte)'T')
            {
                // No "EDAT" found in the header,
                Console.WriteLine("PSPEDAT header not found!");
                return(false);
            }

            return(base.isHeaderValid(pgdFile));
        }
예제 #3
0
 public virtual int ioRead(IVirtualFile file, TPointer outputPointer, int outputLength)
 {
     return(file.ioRead(outputPointer, outputLength));
 }
예제 #4
0
 public virtual int ioRead(TPointer outputPointer, int outputLength)
 {
     return(vFile.ioRead(outputPointer, outputLength));
 }
예제 #5
0
        public virtual int sceKernelLoadModuleToBlock(PspString path, int blockId, TPointer32 separatedBlockId, int unknown2, TPointer optionAddr)
        {
            SceKernelLMOption lmOption = null;

            if (optionAddr.NotNull)
            {
                lmOption = new SceKernelLMOption();
                lmOption.read(optionAddr);
                if (log.InfoEnabled)
                {
                    Console.WriteLine(string.Format("sceKernelLoadModuleToBlock options: {0}", lmOption));
                }
            }

            SysMemInfo sysMemInfo = Modules.SysMemUserForUserModule.getSysMemInfo(blockId);

            if (sysMemInfo == null)
            {
                return(-1);
            }

            //if (log.DebugEnabled)
            {
                Console.WriteLine(string.Format("sceKernelLoadModuleToBlock sysMemInfo={0}", sysMemInfo));
            }

            modulesWithMemoryAllocated.Add(path.String);

            // If we cannot load the module file, return the same blockId
            separatedBlockId.setValue(blockId);

            StringBuilder      localFileName = new StringBuilder();
            IVirtualFileSystem vfs           = Modules.IoFileMgrForUserModule.getVirtualFileSystem(path.String, localFileName);

            if (vfs != null)
            {
                IVirtualFile vFile = vfs.ioOpen(localFileName.ToString(), IoFileMgrForUser.PSP_O_RDONLY, 0);
                if (vFile != null)
                {
                    sbyte[]    bytes        = new sbyte[(int)vFile.Length()];
                    int        Length       = vFile.ioRead(bytes, 0, bytes.Length);
                    ByteBuffer moduleBuffer = ByteBuffer.wrap(bytes, 0, Length);

                    SceModule module = Modules.ModuleMgrForUserModule.getModuleInfo(path.String, moduleBuffer, sysMemInfo.partitionid, sysMemInfo.partitionid);
                    if (module != null)
                    {
                        int size = Modules.ModuleMgrForUserModule.getModuleRequiredMemorySize(module);

                        //if (log.DebugEnabled)
                        {
                            Console.WriteLine(string.Format("sceKernelLoadModuleToBlock module requiring 0x{0:X} bytes", size));
                        }

                        // Aligned on 256 bytes boundary
                        size = Utilities.alignUp(size, 0xFF);
                        SysMemInfo separatedSysMemInfo = Modules.SysMemUserForUserModule.separateMemoryBlock(sysMemInfo, size);
                        // This is the new blockId after calling sceKernelSeparateMemoryBlock
                        separatedBlockId.setValue(separatedSysMemInfo.uid);

                        //if (log.DebugEnabled)
                        {
                            Console.WriteLine(string.Format("sceKernelLoadModuleToBlock separatedSysMemInfo={0}", separatedSysMemInfo));
                        }
                    }
                }
            }

            LoadModuleContext loadModuleContext = new LoadModuleContext();

            loadModuleContext.fileName       = path.String;
            loadModuleContext.lmOption       = lmOption;
            loadModuleContext.needModuleInfo = true;
            loadModuleContext.allocMem       = false;
            loadModuleContext.baseAddr       = sysMemInfo.addr;
            loadModuleContext.basePartition  = sysMemInfo.partitionid;

            return(Modules.ModuleMgrForUserModule.hleKernelLoadModule(loadModuleContext));
        }
예제 #6
0
        public XmbIsoVirtualFile(string umdFilename) : base(null)
        {
            this.umdFilename = umdFilename;
            umdName          = System.IO.Path.GetFileName(umdFilename);

            File cacheDirectory   = new File(CacheDirectory);
            bool createCacheFiles = !cacheDirectory.Directory;

            if (createCacheFiles)
            {
                cacheDirectory.mkdirs();
            }

            try
            {
                UmdIsoReader       iso = new UmdIsoReader(umdFilename);
                IVirtualFileSystem vfs = new UmdIsoVirtualFileSystem(iso);
                sections           = new PbpSection[umdFilenames.Length + 1];
                sections[0]        = new PbpSection();
                sections[0].index  = 0;
                sections[0].offset = 0;
                sections[0].size   = 0x28;
                sections[0].availableInContents = true;
                int       offset = 0x28;
                SceIoStat stat   = new SceIoStat();
                for (int i = 0; i < umdFilenames.Length; i++)
                {
                    PbpSection section = new PbpSection();
                    section.index       = i + 1;
                    section.offset      = offset;
                    section.umdFilename = umdFilenames[i];
                    if (vfs.ioGetstat(section.umdFilename, stat) >= 0)
                    {
                        section.size = (int)stat.size;
                        if (log.TraceEnabled)
                        {
                            log.trace(string.Format("{0}: mapping {1} at offset 0x{2:X}, size 0x{3:X}", umdFilename, umdFilenames[i], section.offset, section.size));
                        }
                    }

                    string cacheFileName = getCacheFileName(section);
                    File   cacheFile     = new File(cacheFileName);

                    // Create only cache files for PARAM.SFO and ICON0.PNG
                    if (createCacheFiles && i < 2)
                    {
                        IVirtualFile vFile = vfs.ioOpen(section.umdFilename, IoFileMgrForUser.PSP_O_RDONLY, 0);
                        if (vFile != null)
                        {
                            section.size = (int)vFile.Length();
                            sbyte[] buffer = new sbyte[section.size];
                            int     Length = vFile.ioRead(buffer, 0, buffer.Length);
                            vFile.ioClose();

                            System.IO.Stream os = new System.IO.FileStream(cacheFile, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                            os.Write(buffer, 0, Length);
                            os.Close();
                        }
                    }

                    if (cacheFile.canRead())
                    {
                        section.cacheFile = cacheFile;
                    }

                    sections[section.index] = section;
                    offset += section.size;
                }
                totalLength = offset;

                contents = new sbyte[offset];
                ByteBuffer buffer = ByteBuffer.wrap(contents).order(ByteOrder.LITTLE_ENDIAN);
                buffer.putInt(PBP.PBP_MAGIC);
                buffer.putInt(0x10000);                 // version
                for (int i = 1; i < sections.Length; i++)
                {
                    buffer.putInt(sections[i].offset);
                }
                int endSectionOffset = sections[sections.Length - 1].offset + sections[sections.Length - 1].size;
                for (int i = sections.Length; i <= 8; i++)
                {
                    buffer.putInt(endSectionOffset);
                }

                if (log.TraceEnabled)
                {
                    log.trace(string.Format("{0}: PBP header :{1}", umdFilename, Utilities.getMemoryDump(contents, sections[0].offset, sections[0].size)));
                }
                vfs.ioExit();
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine("XmbIsoVirtualFile", e);
            }
            catch (IOException e)
            {
                Console.WriteLine("XmbIsoVirtualFile", e);
            }
        }
예제 #7
0
        protected internal virtual void readSection(PbpSection section)
        {
            if (section.size > 0)
            {
                try
                {
                    if (section.cacheFile != null)
                    {
                        //if (log.DebugEnabled)
                        {
                            Console.WriteLine(string.Format("XmbIsoVirtualFile.readSection from Cache {0}", section.cacheFile));
                        }

                        System.IO.Stream @is = new System.IO.FileStream(section.cacheFile, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                        @is.Read(contents, section.offset, section.size);
                        @is.Close();
                    }
                    else
                    {
                        //if (log.DebugEnabled)
                        {
                            Console.WriteLine(string.Format("XmbIsoVirtualFile.readSection from UMD {0}", section.umdFilename));
                        }

                        UmdIsoReader       iso   = new UmdIsoReader(umdFilename);
                        IVirtualFileSystem vfs   = new UmdIsoVirtualFileSystem(iso);
                        IVirtualFile       vFile = vfs.ioOpen(section.umdFilename, IoFileMgrForUser.PSP_O_RDONLY, 0);
                        if (vFile != null)
                        {
                            vFile.ioRead(contents, section.offset, section.size);
                            vFile.ioClose();
                        }
                        vfs.ioExit();
                    }
                }
                catch (IOException e)
                {
                    Console.WriteLine("readSection", e);
                }

                // PARAM.SFO?
                if (section.index == 1)
                {
                    // Patch the CATEGORY in the PARAM.SFO:
                    // the VSH is checking that the CATEGORY value is starting
                    // with 'M' (meaning MemoryStick) and not 'U' (UMD).
                    // Change the first letter 'U' into 'M'.
                    int offset           = section.offset;
                    int keyTableOffset   = readUnaligned32(contents, offset + 8) + offset;
                    int valueTableOffset = readUnaligned32(contents, offset + 12) + offset;
                    int numberKeys       = readUnaligned32(contents, offset + 16);
                    for (int i = 0; i < numberKeys; i++)
                    {
                        int    keyOffset = readUnaligned16(contents, offset + 20 + i * 16);
                        string key       = Utilities.readStringZ(contents, keyTableOffset + keyOffset);
                        if ("CATEGORY".Equals(key))
                        {
                            int  valueOffset    = readUnaligned32(contents, offset + 20 + i * 16 + 12);
                            char valueFirstChar = (char)contents[valueTableOffset + valueOffset];

                            // Change the first letter 'U' into 'M'.
                            if (valueFirstChar == 'U')
                            {
                                contents[valueTableOffset + valueOffset] = (sbyte)'M';
                            }
                            break;
                        }
                    }
                }
            }

            section.availableInContents = true;
        }
예제 #8
0
        public virtual bool loadAndRun()
        {
            if (!enableReboot)
            {
                return(false);
            }

            Memory mem = Memory.Instance;

            StringBuilder      localFileName = new StringBuilder();
            IVirtualFileSystem vfs           = Modules.IoFileMgrForUserModule.getVirtualFileSystem(rebootFileName, localFileName);

            if (vfs == null)
            {
                return(false);
            }

            IVirtualFile vFile = vfs.ioOpen(localFileName.ToString(), IoFileMgrForUser.PSP_O_RDONLY, 0);

            if (vFile == null)
            {
                return(false);
            }

            int rebootFileLength = (int)vFile.Length();

            if (rebootFileLength <= 0)
            {
                return(false);
            }

            SceModule rebootModule = new SceModule(true);

            rebootModule.modname     = Name;
            rebootModule.pspfilename = rebootFileName;
            rebootModule.baseAddress = rebootBaseAddress;
            rebootModule.text_addr   = rebootBaseAddress;
            rebootModule.text_size   = rebootFileLength;
            rebootModule.data_size   = 0;
            rebootModule.bss_size    = 0x26B80;

            const bool fromSyscall = false;

            Emulator.Instance.initNewPsp(fromSyscall);
            Emulator.Instance.ModuleLoaded = true;
            HLEModuleManager.Instance.startModules(fromSyscall);
            Modules.ThreadManForUserModule.Initialise(rebootModule, rebootModule.baseAddress, 0, rebootModule.pspfilename, -1, 0, fromSyscall);

            int        rebootMemSize = rebootModule.text_size + rebootModule.data_size + rebootModule.bss_size;
            SysMemInfo rebootMemInfo = Modules.SysMemUserForUserModule.malloc(VSHELL_PARTITION_ID, "reboot", PSP_SMEM_Addr, rebootMemSize, rebootModule.text_addr);

            if (rebootMemInfo == null)
            {
                return(false);
            }

            TPointer rebootBinAddr = new TPointer(mem, rebootBaseAddress);
            int      readLength    = vFile.ioRead(rebootBinAddr, rebootFileLength);

            vFile.ioClose();
            if (readLength != rebootFileLength)
            {
                return(false);
            }

            markMMIO();

            addFunctionNames(rebootModule);

            SysMemInfo          rebootParamInfo         = Modules.SysMemUserForUserModule.malloc(VSHELL_PARTITION_ID, "reboot-parameters", PSP_SMEM_Addr, 0x10000, rebootParamAddress);
            TPointer            sceLoadCoreBootInfoAddr = new TPointer(mem, rebootParamInfo.addr);
            SceLoadCoreBootInfo sceLoadCoreBootInfo     = new SceLoadCoreBootInfo();

            sceLoadCoreBootInfoAddr.clear(0x1000 + 0x1C000 + 0x380);

            TPointer startAddr = new TPointer(sceLoadCoreBootInfoAddr, 0x1000);

            TPointer sceKernelLoadExecVSHParamAddr = new TPointer(startAddr, 0x1C000);
            TPointer loadModeStringAddr            = new TPointer(sceKernelLoadExecVSHParamAddr, 48);

            loadModeStringAddr.StringZ = "vsh";
            SceKernelLoadExecVSHParam sceKernelLoadExecVSHParam = new SceKernelLoadExecVSHParam();

            sceKernelLoadExecVSHParamAddr.setValue32(48);
            sceKernelLoadExecVSHParam.flags   = 0x10000;
            sceKernelLoadExecVSHParam.keyAddr = loadModeStringAddr;
            sceKernelLoadExecVSHParam.write(sceKernelLoadExecVSHParamAddr);

            sceLoadCoreBootInfo.memBase      = MemoryMap.START_KERNEL;
            sceLoadCoreBootInfo.memSize      = MemoryMap.SIZE_RAM;
            sceLoadCoreBootInfo.startAddr    = startAddr;
            sceLoadCoreBootInfo.endAddr      = new TPointer(sceKernelLoadExecVSHParamAddr, 0x380);
            sceLoadCoreBootInfo.modProtId    = -1;
            sceLoadCoreBootInfo.modArgProtId = -1;
            sceLoadCoreBootInfo.model        = Model.Model;
            sceLoadCoreBootInfo.dipswLo      = Modules.KDebugForKernelModule.sceKernelDipswLow32();
            sceLoadCoreBootInfo.dipswHi      = Modules.KDebugForKernelModule.sceKernelDipswHigh32();
            sceLoadCoreBootInfo.unknown72    = MemoryMap.END_USERSPACE | unchecked ((int)0x80000000);         // Must be larger than 0x89000000 + size of pspbtcnf.bin file
            sceLoadCoreBootInfo.cpTime       = Modules.KDebugForKernelModule.sceKernelDipswCpTime();
            sceLoadCoreBootInfo.write(sceLoadCoreBootInfoAddr);

            SceKernelThreadInfo rootThread = Modules.ThreadManForUserModule.getRootThread(null);

            if (rootThread != null)
            {
                rootThread.cpuContext._a0 = sceLoadCoreBootInfoAddr.Address;
                rootThread.cpuContext._a1 = sceKernelLoadExecVSHParamAddr.Address;
                rootThread.cpuContext._a2 = SCE_INIT_APITYPE_KERNEL_REBOOT;
                rootThread.cpuContext._a3 = Modules.SysMemForKernelModule.sceKernelGetInitialRandomValue();
            }

            // This will set the Log4j MDC values for the root thread
            Emulator.Scheduler.addAction(new SetLog4jMDC());

            //if (log.DebugEnabled)
            {
                Console.WriteLine(string.Format("sceReboot arg0={0}, arg1={1}", sceLoadCoreBootInfoAddr, sceKernelLoadExecVSHParamAddr));
            }

            return(true);
        }