예제 #1
0
uint32 CCdvdman::CdSearchFile(uint32 fileInfoPtr, uint32 namePtr)
{
	struct FILEINFO
	{
		uint32		sector;
		uint32		size;
		char		name[16];
		uint8		date[8];
	};

	const char* name = NULL;
	FILEINFO* fileInfo = NULL;

	if(namePtr != 0)
	{
		name = reinterpret_cast<const char*>(m_ram + namePtr);
	}
	if(fileInfoPtr != 0)
	{
		fileInfo = reinterpret_cast<FILEINFO*>(m_ram + fileInfoPtr);
	}

#ifdef _DEBUG
	CLog::GetInstance().Print(LOG_NAME, FUNCTION_CDSEARCHFILE "(fileInfo = 0x%0.8X, name = '%s');\r\n",
		fileInfoPtr, name);
#endif

	uint32 result = 0;

	if(m_image != NULL && name != NULL && fileInfo != NULL)
	{
		std::string fixedPath(name);

		//Fix all slashes
		std::string::size_type slashPos = fixedPath.find('\\');
		while(slashPos != std::string::npos)
		{
			fixedPath[slashPos] = '/';
			slashPos = fixedPath.find('\\', slashPos + 1);
		}

		ISO9660::CDirectoryRecord record;
		if(m_image->GetFileRecord(&record, fixedPath.c_str()))
		{
			fileInfo->sector	= record.GetPosition();
			fileInfo->size		= record.GetDataLength();
			strncpy(fileInfo->name, record.GetName(), 16);
			fileInfo->name[15] = 0;
			memset(fileInfo->date, 0, 8);

			result = 1;
		}
	}

	return result;
}
예제 #2
0
void CCdvdfsv::SearchFile(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
	uint32 layer = 0;
	uint32 pathOffset = 0x24;
	if(argsSize == 0x128)
	{
		pathOffset = 0x24;
	}
	else if(argsSize == 0x124)
	{
		pathOffset = 0x20;
	}
	else if(argsSize == 0x12C)
	{
		//Used by:
		//- Xenosaga (dual layer)
		pathOffset = 0x24;
		layer = args[0x128 / 4];
	}
	else
	{
		CLog::GetInstance().Warn(LOG_NAME, "Warning: Using unknown structure size (%d bytes);\r\n", argsSize);
	}

	assert(retSize == 4);

	if(!m_opticalMedia)
	{
		ret[0] = 0;
		return;
	}

	//0x12C structure
	//00 - Block Num
	//04 - Size
	//08
	//0C
	//10
	//14
	//18
	//1C
	//20 - Unknown
	//24 - Path

	const char* path = reinterpret_cast<const char*>(args) + pathOffset;
	CLog::GetInstance().Print(LOG_NAME, "SearchFile(layer = %d, path = '%s');\r\n", layer, path);

	//Fix all slashes
	std::string fixedPath(path);
	{
		auto slashPos = fixedPath.find('\\');
		while(slashPos != std::string::npos)
		{
			fixedPath[slashPos] = '/';
			slashPos = fixedPath.find('\\', slashPos + 1);
		}
	}

	//Hack to remove any superfluous version extensions (ie.: ;1) that might be present in the path
	//Don't know if this is valid behavior but shouldn't hurt compatibility. This was done for Sengoku Musou 2.
	while(1)
	{
		auto semColCount = std::count(fixedPath.begin(), fixedPath.end(), ';');
		if(semColCount <= 1) break;
		auto semColPos = fixedPath.rfind(';');
		assert(semColPos != std::string::npos);
		fixedPath = std::string(fixedPath.begin(), fixedPath.begin() + semColPos);
	}

	ISO9660::CDirectoryRecord record;
	auto fileSystem = (layer == 0) ? m_opticalMedia->GetFileSystem() : m_opticalMedia->GetFileSystemL1();
	if(!fileSystem->GetFileRecord(&record, fixedPath.c_str()))
	{
		ret[0] = 0;
		return;
	}

	args[0x00] = record.GetPosition();
	args[0x01] = record.GetDataLength();
	if(layer != 0)
	{
		args[0x00] += m_opticalMedia->GetDvdSecondLayerStart();
	}

	ret[0] = 1;
}