示例#1
0
/**
 * Copies target path and all children to destination path.
 *
 * Returns 0 on success or a negative value indicating number of failures
 */
int copyRecursive(const char *fromPath, const char *toPath) {
    int ret = 0;
    string fromPathStr(fromPath);
    string toPathStr(toPath);

    DIR* dir = opendir(fromPath);
    if (!dir) {
        PLOG(ERROR) << "opendir " << fromPath << " failed";
        return -1;
    }
    if (fromPathStr[fromPathStr.size()-1] != '/')
        fromPathStr += '/';
    if (toPathStr[toPathStr.size()-1] != '/')
        toPathStr += '/';

    struct dirent* entry;
    while ((entry = readdir(dir))) {
        const char* name = entry->d_name;

        // ignore "." and ".."
        if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
            continue;
        }
        string oldFile = fromPathStr + name;
        string newFile = toPathStr + name;

        if (entry->d_type == DT_DIR) {
            ret += makeFolder(newFile.c_str());
            ret += copyRecursive(oldFile.c_str(), newFile.c_str());
        } else {
            ret += copyFile(oldFile.c_str(), newFile.c_str());
        }
    }
    return ret;
}
示例#2
0
FSStatus
FSMakeDirAsync(FSClient *client,
               FSCmdBlock *block,
               const char *path,
               uint32_t flags,
               FSAsyncData *asyncData)
{
   auto pathLength = strlen(path);

   if (pathLength >= FSCmdBlock::MaxPathLength) {
      return FSStatus::FatalError;
   }

   std::memcpy(block->path, path, pathLength);
   block->path[pathLength] = 0;

   internal::queueFsWork(client, block, asyncData, [=]() {
      auto fs = kernel::getFileSystem();

      if (!fs->makeFolder(coreinit::internal::translatePath(block->path))) {
         return FSStatus::FatalError;
      }

      return FSStatus::OK;
   });

   return FSStatus::OK;
}
示例#3
0
//Main program entry point
int main(int argc, char** argv)
{
    g_bProgressOverwrite = false;
    g_iNumThreads = 0;
    DWORD iTicks = GetTickCount();	//Store the starting number of milliseconds

    vfs.Prepare();

    //read in the resource names to unpack
    initResMap();
    initSoundManifest();
    parseCmdLine(argc,argv);

    if(argc < 2)
    {
        cout << "Usage: liDecompress [filename1] [filename2] ... [filenameN]" << endl;
        return 0;
    }

    for(int iArg = 1; iArg < argc; iArg++)
    {
        if(argv[iArg][0] == '-')	//Skip over commandline switches
            continue;
        cout << endl << "Unpacking resource blob file " << argv[iArg] << endl;

        FILE* f = fopen(argv[iArg], "rb");
        if(f == NULL)
        {
            cout << "Unable to open file " << argv[iArg] << endl;
            continue;
        }

        blobHeader bH;
        if(fread((void*)&bH, 1, sizeof(blobHeader), f) != sizeof(blobHeader))
        {
            cout << "Error reading number of resources in file " << argv[iArg] << endl;
            fclose(f);
            continue;
        }

        list<resourceHeader> lResourceHeaders;

        for(int i = 0; i < bH.numItems; i++)
        {
            resourceHeader rH;
            size_t sizeRead = fread((void*)&rH, 1, sizeof(resourceHeader), f);
            if(sizeRead != sizeof(resourceHeader))
            {
                cout << "Read " << sizeRead << " bytes, which differs from resource header size " << sizeof(resourceHeader) << endl;
                fclose(f);
                continue;
            }
            lResourceHeaders.push_back(rH);
        }

        //Create list file with all the files that were in this .pak
        string sPakListFilename = "";
        for(int i = strlen(argv[iArg])-1; i >= 0; i--)
        {
            if(argv[iArg][i] == '\\' ||
                    argv[iArg][i] == '/')
                break;
            sPakListFilename.insert(sPakListFilename.begin(), argv[iArg][i]);
        }
        sPakListFilename += ".filelist.txt";
        ofstream oPakList(sPakListFilename.c_str());

        //Iterate through these items, splitting them out of the file and creating new files out of each
        cout << "Extracting files..." << endl;
        for(list<resourceHeader>::iterator i = lResourceHeaders.begin(); i != lResourceHeaders.end(); i++)
        {
            ThreadConvertHelper dh;
            makeFolder(i->id);
            const wchar_t* cName = getName(i->id);
            oPakList << ws2s(cName) << endl;
            fseek(f, i->offset, SEEK_SET);
            dh.sFilename = cName;
            if(i->flags == FLAG_ZLIBCOMPRESSED)
            {
                compressedHeader cH;
                if(fread((void*)&cH, 1, sizeof(compressedHeader), f) != sizeof(compressedHeader))
                {
                    cout << "Error reading compressed header." << endl;
                    fclose(f);
                    continue;
                }

                uint32_t size = cH.compressedSizeBytes;

                uint8_t* buf = (uint8_t*)malloc(size);
                size_t sizeRead = fread((void*)buf, 1, size, f);
                if(sizeRead != size)
                {
                    cout << "Error reading compressed data. Size: " << size << " read: " << sizeRead << endl;
                    fclose(f);
                    free(buf);
                    continue;
                }
                dh.data.data = buf;
                dh.data.compressedSize = cH.compressedSizeBytes;
                dh.data.decompressedSize = cH.uncompressedSizeBytes;
                dh.bCompressed = true;
            }
            else if(i->flags == FLAG_NOCOMPRESSION)
            {
                uint8_t* buf = (uint8_t*)malloc(i->size);

                if(fread((void*)buf, 1, i->size, f) != i->size)
                {
                    cout << "Error reading non-compressed data." << endl;
                    fclose(f);
                    free(buf);
                    continue;
                }
                dh.data.data = buf;
                dh.data.compressedSize = dh.data.decompressedSize = i->size;
                dh.bCompressed = false;
            }
            else
                cout << "Invalid resource flag " << i->flags << endl;

            g_lThreadedResources.push_back(dh);

        }

        threadedDecompress();

        fclose(f);
        oPakList.close();
    }
    cout << "\rDone.                                " << endl;

    iTicks = GetTickCount() - iTicks;
    float iSeconds = (float)iTicks / 1000.0;	//Get seconds elapsed
    int iMinutes = iSeconds / 60;
    iSeconds -= iMinutes * 60;

    cout << "Time elapsed: " << iMinutes << " min, " << iSeconds << " sec" << endl;
    //system("PAUSE");

    return 0;
}
示例#4
0
bool
launchGame()
{
   if (!loadGameInfo(sGameInfo)) {
      gLog->warn("Could not load game info.");
   } else {
      gLog->info("Loaded game info: '{}' - {} v{}", sGameInfo.meta.shortnames[decaf::Language::English], sGameInfo.meta.product_code, sGameInfo.meta.title_version);
   }

   auto rpx = sGameInfo.cos.argstr;

   if (rpx.empty()) {
      rpx = sExecutableName;
   }

   if (rpx.empty()) {
      gLog->error("Could not find game executable to load.");
      return false;
   }

   // Set up the code heap to load stuff to
   initialiseCodeHeap(sGameInfo.cos.max_codesize);

   // Load the application-level kernel binding
   auto coreinitModule = loader::loadRPL("coreinit");

   if (!coreinitModule) {
      gLog->error("Could not load system coreinit library");
      return false;
   }

   // Load the application
   auto appModule = loader::loadRPL(rpx);

   if (!appModule) {
      gLog->error("Could not load {}", rpx);
      return false;
   }

   gLog->debug("Succesfully loaded {}", rpx);
   sUserModule = appModule;

   // Setup title path
   auto fileSystem = getFileSystem();

   // Temporarily set mlc to write so we can create folders
   fileSystem->setPermissions("/vol/storage_mlc01", fs::Permissions::ReadWrite, fs::PermissionFlags::Recursive);

   // Create title folder
   auto titleID = sGameInfo.app.title_id;
   auto titleLo = static_cast<uint32_t>(titleID & 0xffffffff);
   auto titleHi = static_cast<uint32_t>(titleID >> 32);
   auto titlePath = fmt::format("/vol/storage_mlc01/sys/title/{:08x}/{:08x}", titleHi, titleLo);
   auto titleFolder = fileSystem->makeFolder(titlePath);

   // Create Mii database folder
   fileSystem->makeFolder("/vol/storage_mlc01/usr/save/00050010/1004a100/user/common/db");

   // Restore mlc to Read only
   fileSystem->setPermissions("/vol/storage_mlc01", fs::Permissions::Read, fs::PermissionFlags::Recursive);

   // Set title folder to ReadWrite
   fileSystem->setPermissions(titlePath, fs::Permissions::ReadWrite, fs::PermissionFlags::Recursive);

   // Set mlc/usr to ReadWrite
   fileSystem->setPermissions("/vol/storage_mlc01/usr", fs::Permissions::ReadWrite, fs::PermissionFlags::Recursive);

   // We need to set some default stuff up...
   auto core = cpu::this_core::state();
   core->gqr[2].value = 0x40004;
   core->gqr[3].value = 0x50005;
   core->gqr[4].value = 0x60006;
   core->gqr[5].value = 0x70007;

   // Setup coreinit threads
   coreinit::internal::startAlarmCallbackThreads();
   coreinit::internal::startAppIoThreads();
   coreinit::internal::startDefaultCoreThreads();
   coreinit::internal::startDeallocatorThreads();

   // Notify frontend that game has loaded
   decaf::event::onGameLoaded(sGameInfo);

   // Start the entry thread!
   auto gameThreadEntry = coreinitModule->findFuncExport<uint32_t, uint32_t, void*>("GameThreadEntry");
   coreinit::OSRunThread(coreinit::OSGetDefaultThread(1), gameThreadEntry, 0, nullptr);

   return true;
}
示例#5
0
bool extractMap(const std::string& file)
{
	int err = 0;
	zip* zipFile = zip_open(file.c_str(), 0, &err);

	if(!zipFile)
	{
		std::cout << "[ERROR]: Failed to open archive file: " << file << ".\n";
		return false;
	}

	auto fileNumber = zip_get_num_entries(zipFile, 0);

	std::string folderName = file.substr(0, file.find_last_of('.')) + "/";	// cut off file extension, add dir char

	stripWebChars(folderName);

	if(!makeFolder(folderName))
		return false;

	for(auto i = 0u; i < fileNumber; i++)
	{
		zip_file* zipped = zip_fopen_index(zipFile, i, 0);
		struct zip_stat fileInfo;
		zip_stat_init(&fileInfo);
		zip_stat_index(zipFile, i, 0, &fileInfo);

		if(fileInfo.valid & ZIP_STAT_NAME && fileInfo.valid & ZIP_STAT_SIZE && fileInfo.valid & ZIP_STAT_COMP_SIZE)
		{
			std::string fileStr = fileInfo.name;
			if(fileStr.find('.') == std::string::npos)	// if we don't have a dot, this is a folder
			{
				continue;	// skip this folder
			}

			if(fileStr.find('/') != std::string::npos)	// if we have any dir chars in the string, strip out dirs
			{
				fileStr = fileStr.substr(fileStr.find_last_of('/') + 1);
			}

			#ifndef __linux__
				#pragma warning(push)
				#pragma warning(disable: 4244)
			#endif
			std::vector<bbyte> bytes(fileInfo.size);	// just gotta deal with this conversion
			#ifndef __linux__
				#pragma warning(pop)
			#endif

			zip_fread(zipped, bytes.data(), fileInfo.size);

			std::ofstream fout;

			fout.open(folderName + fileStr, std::ofstream::binary);

			if(fout.bad())
			{
				std::cout << "[ERROR]: Unable to extract file: " << fileInfo.name << '\n';
				return false;
			}

			fout.write(bytes.data(), bytes.size());

			fout.close();
		}
		else
		{
			std::cout << "[ERROR]: Bad file data for file in archive: " << file << '\n';
			return false;
		}

		zip_fclose(zipped);
	}

	zip_close(zipFile);

	// delete the zip file, it's no longer needed
	#ifdef __linux__
		// TBD
	#else
		DeleteFile(file.c_str());
	#endif

	return true;
}
示例#6
0
void decompressResource()
{
	for(bool bDone = false;!bDone;)	//Loop until we're done
	{
		ThreadConvertHelper dh;
		wstring sFilename;
		std::lock_guard<std::mutex> lock(g_Mutex);

		if(!g_lThreadedResources.size())	//Done
		{
			bDone = true;
		}
		else
		{
			//Grab the top item off the list
			dh = g_lThreadedResources.front();
			sFilename = getName(dh.id);	//Mutex on this too, since getName() isn't really threadsafe
			makeFolder(dh.id);	//Also create folder (not threadsafe, either)
			g_lThreadedResources.pop_front();	//Done with this element
		}
		
		//Let user know which resource we're converting now
		if(!bDone)
		{
			g_iCurResource++;
			if(!(sFilename == RESIDMAP_NAME && g_iCurResource == 1))
			{
				if(g_bProgressOverwrite)
				{
					cout << "\rDecompressing file " << g_iCurResource << " out of " << g_iNumResources;
					cout.flush();
				}
				else
					cout << "Decompressing file " << g_iCurResource << " out of " << g_iNumResources << ": " << ws2s(sFilename) << endl;
			}
		}
		
		// Release ownership of the mutex object
		if(sFilename == RESIDMAP_NAME && g_iCurResource == 1)	//Don't release residmap.dat mutex until we've read in all the filenames
		{
			g_iNumResources--;
		}

		if(bDone)
		{
			continue;	//Stop here if done
		}
			
		if(dh.bCompressed)	//Compressed
		{
			uint8_t* tempData = decompress(&dh.data);
			if(tempData == NULL)
			{
				cout << "Error decompressing file " << ws2s(sFilename) << endl;
				return;
			}
			free(dh.data.data);	//Free this compressed memory
			dh.data.data = tempData;	//Now we have the decompressed data
		}
		
		//See if this was a PNG image. Convert PNG images from the data in RAM
		if(sFilename.find(L".png") != wstring::npos ||
		   sFilename.find(L".PNG") != wstring::npos ||
		   sFilename.find(L"coloritemicon") != wstring::npos ||
		   sFilename.find(L"colorbgicon") != wstring::npos ||
		   sFilename.find(L"greybgicon") != wstring::npos)			//Also would include .png.normal files as well
		{
			convertToPNG(sFilename.c_str(), dh.data.data, dh.data.decompressedSize);	//Do the conversion to PNG
		}
		else	//For other file types, go ahead and write to the file before converting
		{
			//Write this out to the file
			FILE* fOut = fopen(ws2s(sFilename).c_str(), "wb");
			if(fOut == NULL)
			{
				cout << "Unable to open output file " << ws2s(sFilename) << endl;
				return;
			}
			fwrite(dh.data.data, 1, dh.data.decompressedSize, fOut);
			fclose(fOut);
		}
		free(dh.data.data);	//Free memory from this file
		
		/*
		//Convert wordPackDict.dat to XML
		if(sFilename.find(L"wordPackDict.dat") != wstring::npos)
		{
			wordPackToXML(sFilename.c_str());
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert sndmanifest.dat to XML
		else if(sFilename.find(L"sndmanifest.dat") != wstring::npos)
		{
			sndManifestToXML(sFilename.c_str());
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert itemmanifest.dat to XML
		else if(sFilename.find(L"itemmanifest.dat") != wstring::npos)
		{
			itemManifestToXML(sFilename.c_str());
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert letterdb.dat to XML
		else if(sFilename.find(L"letterdb.dat") != wstring::npos)
		{
			letterToXML(sFilename.c_str());
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert catalogdb.dat to XML
		else if(sFilename.find(L"catalogdb.dat") != wstring::npos)
		{
			catalogToXML(sFilename.c_str());
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert combodb.dat to XML
		else if(sFilename.find(L"combodb.dat") != wstring::npos)
		{
			comboDBToXML(sFilename.c_str());
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert residmap.dat to XML
		else if(sFilename.find(L"residmap.dat") != wstring::npos)
		{
			residMapToXML(sFilename.c_str());
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert .flac binary files to OGG
		else if(sFilename.find(L".flac") != wstring::npos ||
				sFilename.find(L".FLAC") != wstring::npos)
		{
			wstring s = sFilename;
			s += L".ogg";
			binaryToOgg(sFilename.c_str(), s.c_str());
			unlink(ws2s(sFilename).c_str());	//Delete temporary .flac file
		}
		
		//Convert vdata/fontmanifest.dat to XML
		else if(sFilename.find(L"fontmanifest.dat") != wstring::npos)
		{
			fontManifestToXML(sFilename);
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert font files to XML
		else if(sFilename.find(L".font.xml") != wstring::npos)
		{
			fontToXML(sFilename);
		}
		
		//Convert vdata/loctexmanifest.bin to XML
		else if(sFilename.find(L"loctexmanifest.bin") != wstring::npos)
		{
			LoctexManifestToXML(sFilename);
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert vdata/myPicturesImage.dat to XML
		else if(sFilename.find(L"myPicturesImage.dat") != wstring::npos)
		{
			myPicturesToXML(sFilename);
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert vdata/smokeImage.dat to XML
		else if(sFilename.find(L"smokeImage.dat") != wstring::npos)
		{
			smokeImageToXML(sFilename);
			unlink(ws2s(sFilename).c_str());
		}
		
		//Convert vdata/fluidPalettes.dat to XML
		else if(sFilename.find(L"fluidPalettes.dat") != wstring::npos)
		{
			fluidPalettesToXML(sFilename);
			unlink(ws2s(sFilename).c_str());
		}
		*/
		
		if(sFilename == RESIDMAP_NAME && g_iCurResource == 1)
		{
			g_iCurResource--;
		}
	}
	return;
}