예제 #1
0
// This is used by several of the FileIO and /dev/fs functions
std::string HLE_IPC_BuildFilename(std::string path_wii, int _size)
{
	std::string path_full = File::GetUserPath(D_WIIROOT_IDX);

	// Replaces chars that FAT32 can't support with strings defined in /sys/replace
	for (auto i = replacements.begin(); i != replacements.end(); ++i)
	{
		for (size_t j = 0; (j = path_wii.find(i->first, j)) != path_wii.npos; ++j)
			path_wii.replace(j, 1, i->second);
	}

	path_full += path_wii;

	return path_full;
}
// This is used by several of the FileIO and /dev/fs functions
std::string HLE_IPC_BuildFilename(std::string path_wii, int _size)
{
	std::string path_full = File::GetUserPath(D_WIIROOT_IDX);

	if ((path_wii.length() > 0) && (path_wii[1] == '0'))
		path_full += std::string("/title"); // this looks and feel like a hack...

	// Replaces chars that FAT32 can't support with strings defined in /sys/replace
	for (auto i = replacements.begin(); i != replacements.end(); ++i)
	{
		for (size_t j = 0; (j = path_wii.find(i->first, j)) != path_wii.npos; ++j)
			path_wii.replace(j, 1, i->second);
	}

	path_full += path_wii;

	return path_full;
}
예제 #3
0
void CWiiSaveCrypted::ExportWiiSaveFiles()
{
	if (!b_valid) return;

	u8 *__ENCdata,
		*__data;

	for(u32 i = 0; i < _numberOfFiles; i++)
	{
		FileHDR tmpFileHDR;
		std::string __name, __ext;
		memset(&tmpFileHDR, 0, FILE_HDR_SZ);

		_fileSize = File::GetSize(FilesList[i]);
		_roundedfileSize = ROUND_UP(_fileSize, BLOCK_SZ);

		tmpFileHDR.magic = Common::swap32(FILE_HDR_MAGIC);
		tmpFileHDR.size = Common::swap32(_fileSize);
		tmpFileHDR.Permissions = 0x35;
		tmpFileHDR.type = File::IsDirectory(FilesList[i]) ? 2 : 1;

		SplitPath(FilesList[i], NULL, &__name, &__ext);
		__name += __ext;

		
		for (Common::replace_v::const_iterator iter = replacements.begin(); iter != replacements.end(); ++iter)
		{
			for (size_t j = 0; (j = __name.find(iter->second, j)) != __name.npos; ++j)
			{
				__name.replace(j, iter->second.length(), 1, iter->first);
			}
		}
		
		if (__name.length() > 0x44)
		{
			PanicAlertT("%s is too long for the filename, max chars is 45", __name.c_str());
			b_valid = false;
			return;
		}
		strncpy((char *)tmpFileHDR.name, __name.c_str(), __name.length());
		
		{
		File::IOFile fpData_bin(pathData_bin, "ab");
		fpData_bin.WriteBytes(&tmpFileHDR, FILE_HDR_SZ);
		}

		if (tmpFileHDR.type == 1)
		{
			if (_fileSize == 0)
			{
				PanicAlertT("%s is a 0 byte file", FilesList[i].c_str());
				b_valid = false;
				return;
			}
			File::IOFile fpRawSaveFile(FilesList[i], "rb");
			if (!fpRawSaveFile)
			{
				PanicAlertT("%s failed to open", FilesList[i].c_str());
				b_valid = false;
			}
			__data = new u8[_roundedfileSize];
			__ENCdata = new u8[_roundedfileSize];
			memset(__data, 0, _roundedfileSize);
			if (!fpRawSaveFile.ReadBytes(__data, _fileSize))
			{
				PanicAlertT("Failed to read data from file: %s", FilesList[i].c_str());
				b_valid = false;
			}

			AES_cbc_encrypt((const u8*)__data, __ENCdata, _roundedfileSize, &m_AES_KEY, tmpFileHDR.IV, AES_ENCRYPT);
			
			File::IOFile fpData_bin(pathData_bin, "ab");
			fpData_bin.WriteBytes(__ENCdata, _roundedfileSize);

			delete [] __data;
			delete [] __ENCdata;

		}
	}
}
예제 #4
0
void CWiiSaveCrypted::ImportWiiSaveFiles()
{
	if (!b_valid) return;

	File::IOFile fpData_bin(pathData_bin, "rb");
	if (!fpData_bin)
	{
		PanicAlertT("Cannot open %s", pathData_bin);
		b_valid = false;
		return;
	}

	fpData_bin.Seek(HEADER_SZ + BK_SZ, SEEK_SET);


	FileHDR _tmpFileHDR;

	for(u32 i = 0; i < _numberOfFiles; i++)
	{
		memset(&_tmpFileHDR, 0, FILE_HDR_SZ);
		memset(IV, 0, 0x10);
		_fileSize = 0;
		
		if (!fpData_bin.ReadBytes(&_tmpFileHDR, FILE_HDR_SZ))
		{
			PanicAlertT("Failed to write header for file %d", i);
			b_valid = false;
		}
		
		if (Common::swap32(_tmpFileHDR.magic) != FILE_HDR_MAGIC)
		{
			PanicAlertT("Bad File Header");
			break;
		}
		else
		{
			std::string fileName ((char*)_tmpFileHDR.name);
			for (Common::replace_v::const_iterator iter = replacements.begin(); iter != replacements.end(); ++iter)
			{
				for (size_t j = 0; (j = fileName.find(iter->first, j)) != fileName.npos; ++j)
					fileName.replace(j, 1, iter->second);
			}

			std::string fullFilePath = WiiTitlePath + fileName;
			File::CreateFullPath(fullFilePath);
			if (_tmpFileHDR.type == 1)
			{
				_fileSize = Common::swap32(_tmpFileHDR.size);
				u32 RoundedFileSize = ROUND_UP(_fileSize, BLOCK_SZ);
				_encryptedData = new u8[RoundedFileSize];
				_data = new u8[RoundedFileSize];
				if (!fpData_bin.ReadBytes(_encryptedData, RoundedFileSize))
				{
					PanicAlertT("Failed to read data from file %d", i);
					b_valid = false;
					break;
				}
				
				
				memcpy(IV, _tmpFileHDR.IV, 0x10);
				AES_cbc_encrypt((const unsigned char *)_encryptedData, _data, RoundedFileSize, &m_AES_KEY, IV, AES_DECRYPT);
				delete []_encryptedData;
	
				if (!File::Exists(fullFilePath) || AskYesNoT("%s already exists, overwrite?", fullFilePath.c_str()))
				{
					INFO_LOG(CONSOLE, "Creating file %s", fullFilePath.c_str());
	
					File::IOFile fpRawSaveFile(fullFilePath, "wb");
					fpRawSaveFile.WriteBytes(_data, _fileSize);
				}
				delete []_data;
			}
		}	
	}
}
bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) 
{
	u32 ReturnValue = FS_RESULT_OK;
	SIOCtlVBuffer CommandBuffer(_CommandAddress);
	
	// Prepare the out buffer(s) with zeros as a safety precaution
	// to avoid returning bad values
	for(u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; i++)
	{
		Memory::Memset(CommandBuffer.PayloadBuffer[i].m_Address, 0,
			CommandBuffer.PayloadBuffer[i].m_Size);
	}

	switch(CommandBuffer.Parameter)
	{
	case IOCTLV_READ_DIR:
		{
			// the wii uses this function to define the type (dir or file)
			std::string DirName(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(
				CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size));

			INFO_LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", DirName.c_str());

			if (!File::Exists(DirName))
			{
				WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", DirName.c_str());
				ReturnValue = FS_FILE_NOT_EXIST;
				break;
			}
			else if (!File::IsDirectory(DirName))
			{
				// It's not a directory, so error.
				// Games don't usually seem to care WHICH error they get, as long as it's <
				// Well the system menu CARES!
				WARN_LOG(WII_IPC_FILEIO, "\tNot a directory - return FS_RESULT_FATAL");
				ReturnValue = FS_RESULT_FATAL;
				break;
			}

			// make a file search
			CFileSearch::XStringVector Directories;
			Directories.push_back(DirName);

			CFileSearch::XStringVector Extensions;
			Extensions.push_back("*.*");

			CFileSearch FileSearch(Extensions, Directories);

			// it is one
			if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1))
			{
				size_t numFile = FileSearch.GetFileNames().size();
				INFO_LOG(WII_IPC_FILEIO, "\t%lu Files found", (unsigned long)numFile);

				Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address);
			}
			else
			{
				u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address);

				memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size);

				size_t numFiles = 0;
				char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address));

				for (size_t i=0; i<FileSearch.GetFileNames().size(); i++)
				{
					if (i >= MaxEntries)
						break;

					std::string name, ext;
					SplitPath(FileSearch.GetFileNames()[i], NULL, &name, &ext);
					std::string FileName = name + ext;

					// Decode entities of invalid file system characters so that
					// games (such as HP:HBP) will be able to find what they expect.
					for (Common::replace_v::const_iterator it = replacements.begin(); it != replacements.end(); ++it)
					{
						for (size_t j = 0; (j = FileName.find(it->second, j)) != FileName.npos; ++j)
							FileName.replace(j, it->second.length(), 1, it->first);
					}

					strcpy(pFilename, FileName.c_str());
					pFilename += FileName.length();
					*pFilename++ = 0x00;  // termination
					numFiles++;

					INFO_LOG(WII_IPC_FILEIO, "\tFound: %s", FileName.c_str());
				}

				Memory::Write_U32((u32)numFiles, CommandBuffer.PayloadBuffer[1].m_Address);
			}

			ReturnValue = FS_RESULT_OK;
		}
		break;

	case IOCTLV_GETUSAGE:
		{
			_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2);
			_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4);
			_dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4);

			// this command sucks because it asks of the number of used 
			// fsBlocks and inodes
			// It should be correct, but don't count on it...
			const char *relativepath = (const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address);
			std::string path(HLE_IPC_BuildFilename(relativepath, CommandBuffer.InBuffer[0].m_Size));
			u32 fsBlocks = 0;
			u32 iNodes = 0;

			INFO_LOG(WII_IPC_FILEIO, "IOCTL_GETUSAGE %s", path.c_str());
			if (File::IsDirectory(path))
			{
				// LPFaint99: After I found that setting the number of inodes to the number of children + 1 for the directory itself
				// I decided to compare with sneek which has the following 2 special cases which are
				// Copyright (C) 2009-2011  crediar http://code.google.com/p/sneek/
				if ((memcmp(relativepath, "/title/00010001", 16 ) == 0 ) ||
					(memcmp(relativepath, "/title/00010005", 16) == 0 ))
				{
					fsBlocks = 23; // size is size/0x4000
					iNodes = 42; // empty folders return a FileCount of 1
				}
				else
				{
					File::FSTEntry parentDir;
					// add one for the folder itself, allows some games to create their save files
					// R8XE52 (Jurassic: The Hunted), STEETR (Tetris Party Deluxe) now create their saves with this change
					iNodes = 1 + File::ScanDirectoryTree(path, parentDir);

					u64 totalSize = ComputeTotalFileSize(parentDir); // "Real" size, to be converted to nand blocks

					fsBlocks = (u32)(totalSize / (16 * 1024));  // one bock is 16kb
				}
				ReturnValue = FS_RESULT_OK;

				INFO_LOG(WII_IPC_FILEIO, "FS: fsBlock: %i, iNodes: %i", fsBlocks, iNodes);
			}
			else
			{
				fsBlocks = 0;
				iNodes = 0;
				ReturnValue = FS_RESULT_OK;
				WARN_LOG(WII_IPC_FILEIO, "FS: fsBlock failed, cannot find directoy: %s", path.c_str());
			}

			Memory::Write_U32(fsBlocks, CommandBuffer.PayloadBuffer[0].m_Address);
			Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address);
		}
		break;


	default:
		PanicAlert("CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter);
		break;
	}

	Memory::Write_U32(ReturnValue, _CommandAddress+4);

	return true; 
}