// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify)
{
  // Expand '~/' and './' to the value of the HOME env variable
  if ( p.length() >= 2 && (p[0] == '~' || p[0] == '.') && p[1] == '/')
  {
    const char *home = getenv("HOME");
#ifdef MAXPATHLEN
    if (home != NULL && strlen(home) < MAXPATHLEN)
#else // No MAXPATHLEN, as happens on Hurd
    if (home != NULL)
#endif
    {
      _path = home;
      // Skip over the tilde/dot.  We know that p contains at least
      // two chars, so this is safe:
      _path += p.c_str() + 1;
    }
  }
  else
    _path = p;

  _displayName = lastPathComponent(_path);

  if (verify)
  {
    setFlags();

    // Add a trailing slash, if necessary
    if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '/')
      _path += '/';
  }
}
Exemple #2
0
WindowsFilesystemNode::WindowsFilesystemNode(const Common::String &p, const bool currentDir) {
	if (currentDir) {
		char path[MAX_PATH];
		GetCurrentDirectory(MAX_PATH, path);
		_path = path;
	} else {
		assert(p.size() > 0);
		_path = p;
	}

	_displayName = lastPathComponent(_path, '\\');

	// Check whether it is a directory, and whether the file actually exists
	DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));

	if (fileAttribs == INVALID_FILE_ATTRIBUTES) {
		_isDirectory = false;
		_isValid = false;
	} else {
		_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
		_isValid = true;
		// Add a trailing slash, if necessary.
		if (_isDirectory && _path.lastChar() != '\\') {
			_path += '\\';
		}
	}
	_isPseudoRoot = false;
}
Exemple #3
0
static byte *readSavegameThumbnail(const Common::String &filename, uint &fileSize, bool &isPNG) {
	byte *pFileData;
	Common::SaveFileManager *sfm = g_system->getSavefileManager();
	Common::InSaveFile *file = sfm->openForLoading(lastPathComponent(filename, '/'));
	if (!file)
		error("Save file \"%s\" could not be loaded.", filename.c_str());

	// Seek to the actual PNG image
	loadString(*file);		// Marker (BS25SAVEGAME)
	Common::String storedVersionID = loadString(*file);		// Version
	if (storedVersionID != "SCUMMVM1")
		loadString(*file);

	loadString(*file);		// Description
	uint32 compressedGamedataSize = atoi(loadString(*file).c_str());
	loadString(*file);		// Uncompressed game data size
	file->skip(compressedGamedataSize);	// Skip the game data and move to the thumbnail itself
	uint32 thumbnailStart = file->pos();

	fileSize = file->size() - thumbnailStart;

	// Check if the thumbnail is in our own format, or a PNG file.
	uint32 header = file->readUint32BE();
	isPNG = (header != MKTAG('S','C','R','N'));
	file->seek(-4, SEEK_CUR);

	pFileData = new byte[fileSize];
	file->read(pFileData, fileSize);
	delete file;

	return pFileData;
}
AbstractFilesystemNode *WindowsFilesystemNode::parent() const {
	assert(_isValid || _isPseudoRoot);
	if (_isPseudoRoot)
		return 0;
	WindowsFilesystemNode *p = new WindowsFilesystemNode();
	if (_path.size() > 3) {
		const char *start = _path.c_str();
		const char *end = lastPathComponent(_path);

		p = new WindowsFilesystemNode();
		p->_path = String(start, end - start);
		p->_isValid = true;
		p->_isDirectory = true;
		p->_displayName = lastPathComponent(p->_path);
		p->_isPseudoRoot = false;
	}
	return p;
}
Exemple #5
0
AbstractFSNode *RoninCDFileNode::getParent() const {
	if (_path == "/")
		return 0;

	const char *start = _path.c_str();
	const char *end = lastPathComponent(_path, '/');

	return new RoninCDDirectoryNode(Common::String(start, end - start));
}
Exemple #6
0
AbstractFSNode *WiiFilesystemNode::getParent() const {
	if (_path.empty())
		return NULL;

	const char *start = _path.c_str();
	const char *end = lastPathComponent(_path, '/');

	return new WiiFilesystemNode(Common::String(start, end - start));
}
Exemple #7
0
AbstractFSNode *N64FilesystemNode::getParent() const {
	if (_path == ROOT_PATH)
		return 0;

	const char *start = _path.c_str();
	const char *end = lastPathComponent(_path, '/');

	return new N64FilesystemNode(Common::String(start, end - start), false);
}
AbstractFilesystemNode *GP32FilesystemNode::parent() const {
	if(_isRoot)
		return 0;

	GP32FilesystemNode *p = new GP32FilesystemNode();
	if (_path.size() > 4) {
		const char *start = _path.c_str();
		const char *end = lastPathComponent(_path);

		p->_path = String(start, end - start);
		p->_isDirectory = true;
		p->_displayName = lastPathComponent(p->_path);
		p->_isRoot = false;
		
		GPDEBUG("%s", p->_path.c_str());
	}

	return p;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFilesystemNode* POSIXFilesystemNode::getParent() const
{
  if (_path == "/")
    return 0;

  const char *start = _path.c_str();
  const char *end = lastPathComponent(_path);

  return new POSIXFilesystemNode(string(start, end - start), true);
}
Exemple #10
0
AbstractFSNode *PSPFilesystemNode::getParent() const {
	DEBUG_ENTER_FUNC();
	if (_path == ROOT_PATH)
		return 0;

	PSP_DEBUG_PRINT_FUNC("current[%s]\n", _path.c_str());

	const char *start = _path.c_str();
	const char *end = lastPathComponent(_path, '/');

	AbstractFSNode *node = new PSPFilesystemNode(Common::String(start, end - start), false);

	return node;
}
Exemple #11
0
N64FilesystemNode::N64FilesystemNode(const Common::String &p, bool verify) {
	assert(p.size() > 0);

	_path = p;
	_displayName = lastPathComponent(_path, '/');
	_isValid = true;
	_isDirectory = true;

	// Check if it's a dir
	ROMFILE *tmpfd = romfs_open(p.c_str(), "r");
	if (tmpfd) {
		_isDirectory = (tmpfd->type == 0 || tmpfd->type == 1);
		romfs_close(tmpfd);
	}
}
Exemple #12
0
WiiFilesystemNode::WiiFilesystemNode(const Common::String &p, const struct stat *st) {
	if (p.empty()) {
		initRootNode();
		return;
	}

	_path = Common::normalizePath(p, '/');

	// "sd:" is not a valid directory, but "sd:/" is
	if (_path.lastChar() == ':')
		_path += '/';

	_displayName = lastPathComponent(_path, '/');

	setFlags(st);
}
WindowsFilesystemNode::WindowsFilesystemNode(const String &p) {
	assert(p.size() > 0);

	_path = p;
	_displayName = lastPathComponent(_path);

	// Check whether it is a directory, and whether the file actually exists
	DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));

	if (fileAttribs == INVALID_FILE_ATTRIBUTES) {
		_isValid = false;
		_isDirectory = false;
	} else {
		_isValid = true;
		_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
	}
	_isPseudoRoot = false;
}
Exemple #14
0
WindowsFilesystemNode::WindowsFilesystemNode(const Common::String &p, const bool currentDir) {
	if (currentDir) {
		char path[MAX_PATH];
		GetCurrentDirectory(MAX_PATH, path);
		_path = path;
	} else {
		assert(p.size() > 0);
#ifndef _WIN32_WCE
		_path = p;
#else
		// Check whether p is a relative path
		if (p.hasPrefix("\\") || p.hasPrefix("/")) {
			_path = p;
		} else {
			// Add current directory as a prefix to the path
			// (Windows CE has no concept for relative paths)
			char path[MAX_PATH];
			GetCurrentDirectory(MAX_PATH, path);
			_path = path;
			_path += '\\';
			_path += p;
		}
#endif
	}

	_displayName = lastPathComponent(_path, '\\');

	// Check whether it is a directory, and whether the file actually exists
	DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));

	if (fileAttribs == INVALID_FILE_ATTRIBUTES) {
		_isDirectory = false;
		_isValid = false;
	} else {
		_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
		_isValid = true;
		// Add a trailing slash, if necessary.
		if (_isDirectory && _path.lastChar() != '\\') {
			_path += '\\';
		}
	}
	_isPseudoRoot = false;
}
Exemple #15
0
PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
	DEBUG_ENTER_FUNC();
	assert(p.size() > 0);

	_path = p;
	_displayName = lastPathComponent(_path, '/');
	_isValid = true;
	_isDirectory = true;

	PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());

	if (verify) {
		struct stat st;
		if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
			PSP_DEBUG_PRINT_FUNC("Suspended\n");
		_isValid = (0 == stat(_path.c_str(), &st));
		PowerMan.endCriticalSection();
		_isDirectory = S_ISDIR(st.st_mode);
	}
}
Exemple #16
0
WiiFilesystemNode::WiiFilesystemNode(const Common::String &p) {
	if (p.empty()) {
		initRootNode();
		return;
	}

	_path = Common::normalizePath(p, '/');

	WiiFilesystemFactory::instance().mountByPath(_path);

	// "sd:" is not a valid directory, but "sd:/" is
	if (_path.lastChar() == ':')
		_path += '/';

	_displayName = lastPathComponent(_path, '/');

	struct stat st;
	if(stat(_path.c_str(), &st) != -1)
		setFlags(&st);
	else
		clearFlags();
}
Exemple #17
0
int main (int argc, char **argv) {
	// start flags declarations...
	
	gDataOffset = 0; //globally declared in GCMutils.h; Must be initialized before use...
	int hexFlag = 0;
	
	//for extracting:
	char *extractFileFrom = NULL;
	char *extractFileTo = NULL;
	
	char *fsReplacePath = NULL;
	
	verboseFlag = 0;
	
	int showInfoFlag = 1;

	int extractDiskHeaderFlag = 0;
	char *extractDiskHeaderFile = GCM_DISK_HEADER_FILENAME;
	
	int extractDiskHeaderInfoFlag = 0;
	char *extractDiskHeaderInfoFile = GCM_DISK_HEADER_INFO_FILENAME;

	int extractApploaderFlag = 0;
	char *extractApploaderFile = GCM_APPLOADER_FILENAME;
	
	int extractBootDolFlag = 0;
	char *extractBootDolFile = GCM_BOOT_DOL_FILENAME;
	
	int injectDiskHeaderFlag = 0;
	char *injectDiskHeaderFile = GCM_DISK_HEADER_FILENAME;
	
	int injectDiskHeaderInfoFlag = 0;
	char *injectDiskHeaderInfoFile = GCM_DISK_HEADER_INFO_FILENAME;
	
	int injectApploaderFlag = 0;
	char *injectApploaderFile = GCM_APPLOADER_FILENAME;
	
	char *replaceFileLocalPath = NULL;
	char *replaceFileGCMPath = NULL;

	int listFilesFlag = 0;
	listInfoFlag = 0;
	listPathFlag = 0;
	// end flag declarations
	
	//start argument parsing...
	char *currentArg = NULL;

	do {
		currentArg = GET_NEXT_ARG;
		if (!currentArg) {
			//there's no args! uh oh!
			
			//printf("No arguments...\n");
			printUsage();
			exit(0);
		} else if (CHECK_ARG(ARG_VERBOSE)) {
			//turn on verbosity!
			
			verboseFlag++;
			
			verbosePrint("Verbose output ON.");
		} else if (CHECK_ARG(ARG_HELP)) {
			// print extended help
			
			printExtendedUsage();
			exit(0);
		} else if (CHECK_ARG(ARG_INFO)) {
			//they want to see info...
			
			showInfoFlag++;
			
			verbosePrint("Show info flag ON.");
		} else if (CHECK_ARG(ARG_HEX)) {
			//they want hex notation...
			
			hexFlag = 1;
			
			verbosePrint("Hex notation ON.");
			
		} else if (CHECK_ARG(ARG_OFFSET)) {
			//change the data offset
			
			gDataOffset = strtoul(GET_NEXT_ARG, NULL, 0);
			
			char verboseMsg[32] = "";
			sprintf(verboseMsg, "Data offset changed to: %d", gDataOffset);
			
			verbosePrint(verboseMsg);
		} else if (CHECK_ARG(ARG_REPLACE_FILESYSTEM)) {
			// they want to replace the filesystem
			
			fsReplacePath		= GET_NEXT_ARG;
			
			if (!fsReplacePath) {
				printf("Argument error...\n");
				printUsage();
				exit(1);
			}
		} else if (CHECK_ARG(ARG_EXTRACT)) {
			// extract files...
			// usage: -e <path> <destPath>
			
			extractFileFrom		= GET_NEXT_ARG;
			extractFileTo		= GET_NEXT_ARG;
			
			if (!extractFileFrom || !extractFileTo) {
				//argument error... something was omitted...
				printf("Argument error.\n");
				printUsage();
				exit(1);
			}
		} else if (CHECK_ARG(ARG_EXTRACT_DISK_HEADER)) {
			// extract disk header... (to a file called "boot.bin")
			
			extractDiskHeaderFlag++;
			
			if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) {
				// if they're specifying a file...
				
				SKIP_NARG(1); //skip that -f we just looked at...
				extractDiskHeaderFile = GET_NEXT_ARG;
			}
		
		} else if (CHECK_ARG(ARG_EXTRACT_DISK_HEADER_INFO)) {
			// extract disk header info... (to a file called "bi2.bin")
			
			extractDiskHeaderInfoFlag++;
			
			if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) {
				// if they're specifying a file...
				
				SKIP_NARG(1); //skip that -f we just looked at...
				extractDiskHeaderInfoFile = GET_NEXT_ARG;
			}
			
		} else if (CHECK_ARG(ARG_EXTRACT_APPLOADER)) {
			//extract apploader... (to a file called "appldr.bin")
			
			extractApploaderFlag++;
			
			if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) {
				// if they're specifying a file...
				
				SKIP_NARG(1); //skip that -f we just looked at...
				extractApploaderFile = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_EXTRACT_BOOT_DOL)) {
			//extract the boot dol...
			
			extractBootDolFlag++;
			
			if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) {
				//if they specify a file...
				
				SKIP_NARG(1); //skip that -f
				extractBootDolFile = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_INJECT_DISK_HEADER)) {
			//inject the diskheader
			
			injectDiskHeaderFlag++;
			
			if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) {
				//if they're specifying a file... (otherwise use the default);
				
				SKIP_NARG(1); //skip the -f we just looked at...
				injectDiskHeaderFile = GET_NEXT_ARG;
			}
			
		} else if (CHECK_ARG(ARG_INJECT_DISK_HEADER_INFO)) {
			//inject the diskheaderinfo...
			
			injectDiskHeaderInfoFlag++;
			
			if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) {
				// if they're specifying a file...
				
				SKIP_NARG(1);
				injectDiskHeaderInfoFile = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_INJECT_APPLOADER)) {
			//inject the apploader...
			
			injectApploaderFlag++;
			
			if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) {
				//if they're specifying a file...
				
				SKIP_NARG(1);
				injectApploaderFile = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_REPLACE_FILE)) {
			//they want to replace a file...
			
			replaceFileGCMPath = GET_NEXT_ARG;
			replaceFileLocalPath = GET_NEXT_ARG;
			
			if (!replaceFileGCMPath || !replaceFileLocalPath) {
				printf("Argument error!\n");
				printUsage();
				exit(1);
			}
			
		} else if (CHECK_ARG(ARG_LIST)) {
			// list filesystem
			
			listFilesFlag++; //turn the listFiles flag on.
			
			while(1) {
				if (PEEK_ARG && (strcmp(PEEK_ARG, OPT_FILE_INFO) == 0 || strcmp(PEEK_ARG, OPT_FILE_INFO_SYN) == 0)) {
					SKIP_NARG(1);
					listInfoFlag++;
				} else if (PEEK_ARG && (strcmp(PEEK_ARG, OPT_FULL_PATH) == 0 || strcmp(PEEK_ARG, OPT_FULL_PATH_SYN) == 0)) {
					SKIP_NARG(1);
					listPathFlag++;
				} else {
					break;
				}
			}
		} else {
			// do it to this file... this is the last argument... just ignore the rest...
			
			filepath = currentArg;
			filename = lastPathComponent(filepath);
			
			break;
		}
	} while(*argv);
	//end parsing arguments...
	
	//open the file for reading and start doing read operations!
	openFile("r");

	// print the info...
	if (showInfoFlag) {
		printGCMInfo(hexFlag);
	}
	
	// list the files, if necesary...
	if (listFilesFlag) {
		listFiles();
	}

	// extract files...
	if (extractFileFrom && extractFileTo) {
		//testing recursive extraction...
		
		GCMFileEntryStruct *e = NULL;
		
		if (strcmp(extractFileFrom, "/") == 0) {
			e = GCMGetRootFileEntry(gcmFile);
			printf("root file entry index: %d\n", e->index);
		} else {	
			e = GCMGetFileEntryAtPath(gcmFile, extractFileFrom);
		}
		
		strcpy(extractRootPath, extractFileTo);
		
		recurseFileEntry(e, extractFileEntry);
		
		free(e);
		//extractFile(extractFileFrom, extractFileTo);
	}
	
	
	//extract diskheader
	if (extractDiskHeaderFlag) {
		extractDiskHeader(extractDiskHeaderFile);
	}
	
	//extract diskheaderinfo
	if (extractDiskHeaderInfoFlag) {
		extractDiskHeaderInfo(extractDiskHeaderInfoFile);
	}
	
	//extract apploader
	if (extractApploaderFlag) {
		extractApploader(extractApploaderFile);
	}
	
	//extract main executable DOL
	if (extractBootDolFlag) {
		extractBootDol(extractBootDolFile);
	}
	
	//close the file and open it again for read/write
	closeFile();
	openFile("r+");
	
	//inject the diskheader
	if (injectDiskHeaderFlag) {
		injectDiskHeader(injectDiskHeaderFile);
	}
	
	//inject the diskheaderinfo
	if (injectDiskHeaderInfoFlag) {
		injectDiskHeaderInfo(injectDiskHeaderInfoFile);
	}
	
	//inject the apploader
	if (injectApploaderFlag) {
		injectApploader(injectApploaderFile);
	}
	
	if (replaceFileLocalPath && replaceFileGCMPath) {
		replaceFile(replaceFileGCMPath, replaceFileLocalPath);
	}

	//replace the filesystem
	if (fsReplacePath) {
		GCMReplaceFilesystem(gcmFile, fsReplacePath);
	}
	
	closeFile();
	
	return 0;
}
Exemple #18
0
	virtual Common::String getName() const { return lastPathComponent(_path, '/'); }
Exemple #19
0
int main(int argc, char **argv) {
	verboseFlag = 0;

	char *currentArg = NULL;

	do {
		currentArg = GET_NEXT_ARG;

		if (!currentArg) {
			//there's no args! uh oh!

			printUsage();
			exit(EXIT_SUCCESS); //exit success because we're just printing usage...
		} else if (CHECK_ARG(ARG_VERBOSE)) {
			//turn on verbosity!

			verboseFlag++;
	//		verbosePrint("Verbose output ON.");

		} else {
			//this is the file we want to open...

			filepath = currentArg;
			filename = lastPathComponent(filepath);

			break;
		}
	} while(*argv);
	
	printf("opening %s\n", filename);

	FILE *gcmFile;

	if (!(gcmFile = fopen(filepath, "r"))) {
		perror("error opening!\n");
		exit(EXIT_FAILURE);
	}

	u32 fstOffset = GCMGetFSTOffset(gcmFile);
	u32 fstSize = GCMGetFSTSize(gcmFile);
	u32 stringTableOffset = GCMGetStringTableOffset(gcmFile);
	GCMFileEntryStruct *root = GCMGetRootFileEntry(gcmFile);
	u32 filesize = GetFilesizeFromStream(gcmFile);

	printf("Filesize: %ld\n", filesize);
	printf("FST Offset: %ld\n", fstOffset);
	printf("FST Size: %ld\n", fstSize);
	printf("String Table: %ld\n", stringTableOffset);
	printf("entry count: %ld\n", root->length);
	
	int i = 0;
	u32 highestStringTableOffset = 0;
	u32 firstFileOffset = GetFilesizeFromStream(gcmFile);
	u32 endOfFileList = 0;
	
	for (i = 0; i < root->length; i++) {
		GCMFileEntryStruct *e = GCMGetNthFileEntry(gcmFile, i);

		GCMFetchFilenameForFileEntry(gcmFile, e);
		printf("%s\n", e->filename);
		
		if (e->filenameOffset >= highestStringTableOffset) {
			highestStringTableOffset = e->filenameOffset + strlen(e->filename) + 1; // +1 for \0
		}

		if (!(e->isDir) && e->offset < firstFileOffset) {
			firstFileOffset = e->offset;
		}

		if (!(e->isDir) && e->offset + e->length > endOfFileList) {
			endOfFileList = (e->offset + e->length);
		}
	}

	printf("\n");
	printf("HighestStringTableOffset: %ld\n", highestStringTableOffset);
	printf("firstFileOffset: %ld\n", firstFileOffset);
	printf("endOfFileList: %ld\n", endOfFileList);

	printf("\n");
	printf("Savings: %ld\n", firstFileOffset - (stringTableOffset + highestStringTableOffset));

	printf("Verifying...\n");

	fseek(gcmFile, stringTableOffset + highestStringTableOffset, SEEK_SET);

	while (!fgetc(gcmFile));

	printf("currentOffset: %ld\n", ftell(gcmFile));

	if (ftell(gcmFile) >= firstFileOffset) {
		printf("Everything seems ok... YAY!\n");
	} else {
		printf("EEK! no good! something's wrong.\n");
	}

	fclose(gcmFile);
}