コード例 #1
0
ファイル: cellFs.cpp プロジェクト: Maheshan/rpcs3
s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_file)
{
	std::shared_ptr<vfsFileBase> packed_stream(Emu.GetVFS().OpenFile(packed_file, fom::read));
	std::shared_ptr<vfsFileBase> unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, fom::write | fom::create | fom::trunc));

	if (!packed_stream || !packed_stream->IsOpened())
	{
		cellFs.Error("File '%s' not found!", packed_file.c_str());
		return CELL_ENOENT;
	}

	if (!unpacked_stream || !unpacked_stream->IsOpened())
	{
		cellFs.Error("File '%s' couldn't be created!", unpacked_file.c_str());
		return CELL_ENOENT;
	}

	char buffer[10200];
	packed_stream->Read(buffer, 256);
	u32 format = *(be_t<u32>*)&buffer[0];
	if (format != 0x4E504400) // "NPD\x00"
	{
		cellFs.Error("Illegal format. Expected 0x4E504400, but got 0x%08x", format);
		return CELL_EFSSPECIFIC;
	}

	u32 version = *(be_t<u32>*)&buffer[0x04];
	u32 flags = *(be_t<u32>*)&buffer[0x80];
	u32 blockSize = *(be_t<u32>*)&buffer[0x84];
	u64 filesizeOutput = *(be_t<u64>*)&buffer[0x88];
	u64 filesizeInput = packed_stream->GetSize();
	u32 blockCount = (u32)((filesizeOutput + blockSize - 1) / blockSize);

	// SDATA file is compressed
	if (flags & 0x1)
	{
		cellFs.Warning("cellFsSdataOpen: Compressed SDATA files are not supported yet.");
		return CELL_EFSSPECIFIC;
	}
	// SDATA file is NOT compressed
	else
	{
		u32 t1 = (flags & 0x20) ? 0x20 : 0x10;
		u32 startOffset = (blockCount * t1) + 0x100;
		u64 filesizeTmp = (filesizeOutput + 0xF) & 0xFFFFFFF0 + startOffset;

		if (!sdata_check(version, flags, filesizeInput, filesizeTmp))
		{
			cellFs.Error("cellFsSdataOpen: Wrong header information.");
			return CELL_EFSSPECIFIC;
		}

		if (flags & 0x20)
			packed_stream->Seek(0x100);
		else
			packed_stream->Seek(startOffset);

		for (u32 i = 0; i < blockCount; i++)
		{
			if (flags & 0x20)
				packed_stream->Seek(packed_stream->Tell() + t1);

			if (!(blockCount - i - 1))
				blockSize = (u32)(filesizeOutput - i * blockSize);

			packed_stream->Read(buffer + 256, blockSize);
			unpacked_stream->Write(buffer + 256, blockSize);
		}
	}

	return CELL_OK;
}
コード例 #2
0
ファイル: cellFs.cpp プロジェクト: scu-wangsj/rpcs3
s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_file)
{
	fs::file packed_stream(vfs::get(packed_file));
	fs::file unpacked_stream(vfs::get(unpacked_file), fs::rewrite);

	if (!packed_stream)
	{
		cellFs.error("File '%s' not found!", packed_file);
		return CELL_ENOENT;
	}

	if (!unpacked_stream)
	{
		cellFs.error("File '%s' couldn't be created!", unpacked_file);
		return CELL_ENOENT;
	}

	char buffer[10200];
	packed_stream.read(buffer, 256);
	u32 format = *(be_t<u32>*)&buffer[0];
	if (format != 0x4E504400) // "NPD\x00"
	{
		cellFs.error("Illegal format. Expected 0x4E504400, but got 0x%08x", format);
		return CELL_EFSSPECIFIC;
	}

	u32 version = *(be_t<u32>*)&buffer[0x04];
	u32 flags = *(be_t<u32>*)&buffer[0x80];
	u32 blockSize = *(be_t<u32>*)&buffer[0x84];
	u64 filesizeOutput = *(be_t<u64>*)&buffer[0x88];
	u64 filesizeInput = packed_stream.size();
	u32 blockCount = (u32)((filesizeOutput + blockSize - 1) / blockSize);

	// SDATA file is compressed
	if (flags & 0x1)
	{
		cellFs.warning("cellFsSdataOpen: Compressed SDATA files are not supported yet.");
		return CELL_EFSSPECIFIC;
	}
	// SDATA file is NOT compressed
	else
	{
		u32 t1 = (flags & 0x20) ? 0x20 : 0x10;
		u32 startOffset = (blockCount * t1) + 0x100;
		u64 filesizeTmp = (filesizeOutput + 0xF) & 0xFFFFFFF0 + startOffset;

		if (!sdata_check(version, flags, filesizeInput, filesizeTmp))
		{
			cellFs.error("cellFsSdataOpen: Wrong header information.");
			return CELL_EFSSPECIFIC;
		}

		if (flags & 0x20)
		{
			packed_stream.seek(0x100);
		}
		else
		{
			packed_stream.seek(startOffset);
		}

		for (u32 i = 0; i < blockCount; i++)
		{
			if (flags & 0x20)
			{
				packed_stream.seek(t1, fs::seek_cur);
			}

			if (!(blockCount - i - 1))
			{
				blockSize = (u32)(filesizeOutput - i * blockSize);
			}

			packed_stream.read(buffer + 256, blockSize);
			unpacked_stream.write(buffer + 256, blockSize);
		}
	}

	return CELL_OK;
}