예제 #1
0
inline
bool list_files(FileInfoContainer &p_infos,
                const char *p_path) {
        dir_t _dir = NULL;
        RETRY_DO {
                RETRY_LOG("gfs::list_files failed");
                _dir = file_system()->opendir(p_path);
        } RETRY_ON((_dir == NULL) && is_directory(p_path));

        if (_dir == NULL)
                return false;

        // 注意,如果有. ..的话,要过滤掉
        Directory::iterator _iter;
        file_info _info;
        while(!_dir->done())
        {
                _iter = _dir->next();
                _info.m_name = _iter->name();
                _info.m_is_dir = _iter->is_dir();
                p_infos.push_back(_info);
        }

        file_system()->closedir(_dir);
        return true;
}
예제 #2
0
std::map<IVolume::ELanguage, std::string> CVolumeWiiCrypted::GetNames(bool prefer_long) const
{
	std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this));
	std::vector<u8> opening_bnr(NAMES_TOTAL_BYTES);
	opening_bnr.resize(file_system->ReadFile("opening.bnr", opening_bnr.data(), opening_bnr.size(), 0x5C));
	return ReadWiiNames(opening_bnr);
}
예제 #3
0
inline
bool mkdir(const char *p_path) {
        int32_t ret = 0;
        RETRY_DO {
                RETRY_LOG("gfs::mkdir failed");
                ret = file_system()->mkdir(p_path);
        } RETRY_ON((ret < 0) && (! exists(p_path)));
        return ret == 0;
}
예제 #4
0
inline
bool remove(const char *p_path) {
        int32_t ret = 0;
        RETRY_DO {
                RETRY_LOG("gfs::remove failed");
                ret = file_system()->unlink(p_path);
        } RETRY_ON(ret < 0);
        return ret == 0;
}
예제 #5
0
inline
bool exists(const char *p_path) {
        int32_t ret = 0;
        RETRY_DO {
                RETRY_LOG("gfs::exists failed");
                ret = file_system()->exists(p_path);
        } RETRY_ON ((ret != 0) && (ret != 1));
        // TODO: 可能这里无限重试更好?
        return ret == 1;
}
예제 #6
0
inline
bool stat(file_status &p_status,
          const char *p_path) {
        uint32_t ret = 0;
        RETRY_DO {
                RETRY_LOG("gfs::stat failed");
                ret = file_system()->stat(p_path, &p_status, true/*get_exact_len*/);
        } RETRY_ON((ret < 0) &&
                   (get_errno() != ERR_NODE_NOEXIST));
        return ret == 0;
}
예제 #7
0
inline
bool rename(const char *p_old_path,
            const char *p_new_path) {
        int32_t ret = 0;
        RETRY_DO {
                RETRY_LOG("gfs::rename failed");
                ret = file_system()->rename(p_old_path,
                                            p_new_path);
        } RETRY_ON(ret < 0);
        return ret == 0;
}
예제 #8
0
inline
file_t open(const char *p_path,
            mode_t p_mode = MT_O_RDONLY) {
        file_t fd = BAD_FILE;
        RETRY_DO {
                RETRY_LOG("gfs::open failed");
                fd = file_system()->open(p_path,
                                         static_cast<int32_t>(p_mode));
        } RETRY_ON ((fd == BAD_FILE)
                    && (ERR_EXIST != get_errno())); // 文件已存在错误则不重试
        return fd;
}
예제 #9
0
inline
file_t create(const char *p_path) {
        file_t fd = BAD_FILE;
        RETRY_DO {
                RETRY_LOG("gfs::create failed");
                if(fd != BAD_FILE)
                {
                        close(fd);
                }
                fd = file_system()->creat(p_path);
        } RETRY_ON ((fd == BAD_FILE) &&
                    (! exists(p_path)));
        // 创建成功后,验证文件是否存在;因为发生过创建
        // 成功后,文件不存在的现象。
        return fd;
}
예제 #10
0
inline
file_t create(const char *p_path,
              std::size_t replica_number) {
        file_t fd = BAD_FILE;
        RETRY_DO {
                RETRY_LOG("gfs::create failed");
                if(fd != BAD_FILE)
                {
                        close(fd);
                }
                fd = file_system()->creat(p_path,
                                          static_cast<int32_t>(replica_number));
        } RETRY_ON ((fd == BAD_FILE) &&
                    (! exists(p_path)));
        // 创建成功后,验证文件是否存在;因为发生过创建
        // 成功后,文件不存在的现象。
        return fd;
}
예제 #11
0
bool CVolumeGC::LoadBannerFile() const
{
	// The methods GetNames, GetDescriptions, GetCompany and GetBanner
	// all need to access the opening.bnr file. These four methods are
	// typically called after each other, so we store the file in RAM
	// to avoid reading it from the disc several times. However,
	// if none of these methods are called, the file is never loaded.

	if (m_banner_file_type != BANNER_NOT_LOADED)
		return m_banner_file_type != BANNER_INVALID;

	std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this));
	size_t file_size = (size_t)file_system->GetFileSize("opening.bnr");
	if (file_size == BNR1_SIZE || file_size == BNR2_SIZE)
	{
		m_banner_file.resize(file_size);
		file_system->ReadFile("opening.bnr", m_banner_file.data(), m_banner_file.size());

		u32 bannerSignature = *(u32*)m_banner_file.data();
		switch (bannerSignature)
		{
		case 0x31524e42:	// "BNR1"
			m_banner_file_type = BANNER_BNR1;
			break;
		case 0x32524e42:	// "BNR2"
			m_banner_file_type = BANNER_BNR2;
			break;
		default:
			m_banner_file_type = BANNER_INVALID;
			WARN_LOG(DISCIO, "Invalid opening.bnr type");
			break;
		}
	}
	else
	{
		m_banner_file_type = BANNER_INVALID;
		WARN_LOG(DISCIO, "Invalid opening.bnr size: %0lx", (unsigned long)file_size);
	}

	return m_banner_file_type != BANNER_INVALID;
}
예제 #12
0
void CVolumeGC::LoadBannerFile() const
{
	// If opening.bnr has been loaded already, return immediately
	if (m_banner_loaded)
		return;

	m_banner_loaded = true;

	GCBanner banner_file;
	std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this));
	size_t file_size = (size_t)file_system->GetFileSize("opening.bnr");

	constexpr int BNR1_MAGIC = 0x31524e42;
	constexpr int BNR2_MAGIC = 0x32524e42;
	if (file_size != BNR1_SIZE && file_size != BNR2_SIZE)
	{
		WARN_LOG(DISCIO, "Invalid opening.bnr. Size: %0zx", file_size);
		return;
	}

	file_system->ReadFile("opening.bnr", reinterpret_cast<u8*>(&banner_file), file_size);

	bool is_bnr1;
	if (banner_file.id == BNR1_MAGIC && file_size == BNR1_SIZE)
	{
		is_bnr1 = true;
	}
	else if (banner_file.id == BNR2_MAGIC && file_size == BNR2_SIZE)
	{
		is_bnr1 = false;
	}
	else
	{
		WARN_LOG(DISCIO, "Invalid opening.bnr. Type: %0x Size: %0zx", banner_file.id, file_size);
		return;
	}

	ExtractBannerInformation(banner_file, is_bnr1);
}
예제 #13
0
Retcode
dos_partition(Environ *e, Filesys_action what, Instance *disk,
		Byte *path, uLong loc, uLong start_unused, uByte *buf, uInt size,
		uByte *retbuf, uLong *val)
{
	int i, j;
	Retcode ret = NO_ERROR;
	int partition = -1;
	struct bootsector50 *bs = (struct bootsector50*)buf;
	struct dos_partition part[NDOSPART];
	static int indent = 0;

	DPRINTF(("\ndos_partition: enter\n"));

	if (size < DOS_BLOCK_SIZE)
		return E_BLOCKSIZE;

	/* first see if this is a DOS boot-block */
	ret = filesys_read_bytes(e, disk, loc, size, buf);

	if (ret != NO_ERROR)
		return ret;

	DPRINTF(("dos-partition: boot_sect_sig0/1=%#x.%#x jump=%#x"
			" boot_signature=%#x drive_number=%#x\n",
			bs->boot_sect_sig[0], bs->boot_sect_sig[1],
			bs->jump[0], bs->boot_signature, bs->drive_number));

	if (bs->boot_sect_sig[0] != BOOTSIG0 ||
		bs->boot_sect_sig[1] != BOOTSIG1 ||
		((bs->jump[0] == 0xE9 || bs->jump[0] == 0xEB) &&
			bs->boot_signature != 0x29 &&
			bs->boot_signature != 0x13 &&
			bs->boot_signature != 0x7C &&
			bs->boot_signature != 0xBC))
		return E_NO_FILESYS;

	/* copy the partition info */
	memcpy((void*)part, buf + DOSPARTOFF, sizeof part);

	/* see if we have any partitions - may not be a partition table */
	for (i = 0; i < 4; i++)
	{
		if (part[i].typ != DP_UNUSED)
			break;
	}

	if (i >= 4)
		return E_NO_FILESYS;

	if (*path >= '0' && *path <= '3')
	{
		partition = *path - '0';
		path = strchr(path, ',');

		if (path == NULL)
			path = "";
		else
			path++;
	}
	else if (*path)
	{
		cprintf(e, "dos-partition: unknown partition %s\n", path);
		return E_ABORT;
	}

	if (what == FS_PROBE)
		strcat((char*)retbuf, ",dos-partition");

	for (i = 0; i < 4; i++)
	{
		struct dos_partition *p = &part[i];
		uInt start, size;

		/* handle alignment and endian problems */
		start = p->start[0] |
				(p->start[1] << BYTE_SIZE) |
				(p->start[2] << BYTE_SIZE * 2) |
				(p->start[3] << BYTE_SIZE * 3);
		size = p->size[0] |
				(p->size[1] << BYTE_SIZE) |
				(p->size[2] << BYTE_SIZE * 2) |
				(p->size[3] << BYTE_SIZE * 3);
		DPRINTF(("dos_partition: partition=%d size=%#x start=%#x typ=%#x\n"
				"\tflag=%#x shd=%#x ssect=%#x scyl=%#x ehd=%#x"
				" esect=%#x ecyl=%#x\n",
				i, size, start, p->typ, p->flag, p->shd, p->ssect, p->scyl,
				p->ehd, p->esect, p->ecyl));

		/* find matching fstype */
		if (what == FS_LIST && partition < 0)
		{
			DPtype *fs;

			for (fs = g_dplist; fs->name; fs++)
				if (fs->type == p->typ)
					break;

			for (j = 0; j < indent; j++)
				cprintf(e, " ");

			cprintf(e, "DOS partition %d: %s (%#x)\n", i,
					fs->name ? fs->name : "<unknown>", p->typ);
		}

		/* make sure we have something in this partition */
		if (size == 0 || p->typ == DP_UNUSED)
		{
			if (i == partition && what != FS_PROBE)
				return E_NO_FILESYS;

			continue;
		}

		if (p->typ == DP_EXTENDED)
		{
			indent += 4;
			ret = dos_partition(e, what, disk, path,
					loc + start * DOS_BLOCK_SIZE, start,
					buf, DOS_BLOCK_SIZE, retbuf, val);
			indent -= 4;

			if (ret != NO_ERROR && ret != E_NO_FILESYS && ret != R_END)
				return ret;

			continue;
		}

		/* handle filesystems inside our partitions */
		switch (what)
		{
		case FS_PROBE:
			ret = file_system(e, what, disk, path,
					loc + start * DOS_BLOCK_SIZE, start,
					buf, DOS_BLOCK_SIZE, retbuf, val);

			if (ret != NO_ERROR && ret != E_NO_FILESYS)
				return ret;

			break;

		case FS_LIST:
			if (i == partition)
			{
				ret = file_system(e, what, disk, path,
						loc + start * DOS_BLOCK_SIZE, start,
						buf, DOS_BLOCK_SIZE, retbuf, val);

				return (ret == E_NO_FILESYS) ?  E_UNSUPPORTED_FILESYS : ret;
			}

			break;

		case FS_LOAD:
			if (i == partition)
			{
				if (*path)
				{
					ret = file_system(e, what, disk, path,
							loc + start * DOS_BLOCK_SIZE, start,
							buf, DOS_BLOCK_SIZE, retbuf, val);

					return (ret == E_NO_FILESYS) ?  E_UNSUPPORTED_FILESYS : ret;
				}

				/* no path specified - try to load this partition's bootblock */
				return filesys_read_bytes(e, disk, loc + start * DOS_BLOCK_SIZE,
						*val = DOS_BLOCK_SIZE, retbuf);
			}
			else if (i < 0)
				/* no partition specified - try to load MBR */
				return filesys_read_bytes(e, disk, loc * DOS_BLOCK_SIZE,
						*val = DOS_BLOCK_SIZE, retbuf);

			break;
		}
	}

	/* no other partitions or filesystems should be on this volume */
	DPRINTF(("dos_partition: return R_END\n"));
	return R_END;
}
예제 #14
0
inline
bool close(file_t p_file) {
        return file_system()->close(p_file) == 0;
}