Beispiel #1
0
static BOOL SoftwarePicker_InternalAddFile(HWND hwndPicker, LPCSTR pszFilename,
	BOOL bForce)
{
	LPCSTR s;
	BOOL rc = TRUE;
	zip_error ziperr;
	zip_file *pZip;
	const zip_file_header *pZipEnt;

	s = strrchr(pszFilename, '.');
	if (s && !mame_stricmp(s, ".zip"))
	{
		ziperr = zip_file_open(pszFilename, &pZip);
		if (ziperr  == ZIPERR_NONE)
		{
			pZipEnt = zip_file_first_file(pZip);
			while(rc && pZipEnt)
			{
				rc = SoftwarePicker_AddZipEntFile(hwndPicker, pszFilename,
					bForce, pZip, pZipEnt);
				pZipEnt = zip_file_next_file(pZip);
			}
			zip_file_close(pZip);
		}
	}
	else
	{
		rc = SoftwarePicker_AddFileEntry(hwndPicker, pszFilename, 0, 0, bForce);
	}
	return rc;
}
static const zip_file_header *zip_file_seek_file(zip_file *zip, const char *filename)
{
	const zip_file_header *header;
	char *new_filename;
	int i;

	// we need to change filename; allocate a copy
	new_filename = (char*)malloc(strlen(filename) + 1);
	if (!new_filename)
		return NULL;

	// change all backslashes to forward slashes
	for (i = 0; filename[i]; i++)
		new_filename[i] = (filename[i] != '\\') ? filename[i] : '/';
	new_filename[i] = '\0';

	// find the entry
	header = zip_file_first_file(zip);
	while(header && mame_stricmp(header->filename, new_filename))
	{
		header = zip_file_next_file(zip);
	}

	free(new_filename);
	return header;
}
Beispiel #3
0
static imgtool_stream *stream_open_zip(const char *zipname, const char *subname, int read_or_write)
{
	imgtool_stream *imgfile = NULL;
//  zip_error ziperr;
	zip_file *z = NULL;
	const zip_file_header *zipent;
	FILE *f;

	if (read_or_write)
		goto error;

	/* check to see if the file exists */
	f = fopen(zipname, "r");
	if (!f)
		goto error;
	fclose(f);

	imgfile = (imgtool_stream *)malloc(sizeof(imgtool_stream));
	if (!imgfile)
		goto error;

	memset(imgfile, 0, sizeof(*imgfile));
	imgfile->imgtype = IMG_MEM;
	imgfile->write_protect = 1;
	imgfile->position = 0;

//  ziperr =
	zip_file_open(zipname, &z);
	if (!z)
		goto error;

	zipent = zip_file_first_file(z);
	while(zipent && subname && strcmp(subname, zipent->filename))
		zipent = zip_file_next_file(z);
	if (!zipent)
		goto error;

	imgfile->filesize = zipent->uncompressed_length;
	imgfile->u.buffer = (UINT8*)malloc(zipent->uncompressed_length);
	if (!imgfile->u.buffer)
		goto error;

	if (zip_file_decompress(z, imgfile->u.buffer, zipent->uncompressed_length))
		goto error;

	zip_file_close(z);
	return imgfile;

error:
	if (z)
		zip_file_close(z);
	if (imgfile)
	{
		if (imgfile->u.buffer)
			free(imgfile->u.buffer);
		free(imgfile);
	}
	return NULL;
}
Beispiel #4
0
static void romident(const char *filename, romident_status *status)
{
	osd_directory *directory;

	/* reset the status */
	memset(status, 0, sizeof(*status));

	/* first try to open as a directory */
	directory = osd_opendir(filename);
	if (directory != NULL)
	{
		const osd_directory_entry *entry;

		/* iterate over all files in the directory */
		while ((entry = osd_readdir(directory)) != NULL)
			if (entry->type == ENTTYPE_FILE)
			{
				astring *curfile = astring_assemble_3(astring_alloc(), filename, PATH_SEPARATOR, entry->name);
				identify_file(astring_c(curfile), status);
				astring_free(curfile);
			}
		osd_closedir(directory);
	}

	/* if that failed, and the filename ends with .zip, identify as a ZIP file */
	else if (core_filename_ends_with(filename, ".zip"))
	{
		/* first attempt to examine it as a valid ZIP file */
		zip_file *zip = NULL;
		zip_error ziperr = zip_file_open(filename, &zip);
		if (ziperr == ZIPERR_NONE && zip != NULL)
		{
			const zip_file_header *entry;

			/* loop over entries in the ZIP, skipping empty files and directories */
			for (entry = zip_file_first_file(zip); entry; entry = zip_file_next_file(zip))
				if (entry->uncompressed_length != 0)
				{
					UINT8 *data = (UINT8 *)malloc(entry->uncompressed_length);
					if (data != NULL)
					{
						/* decompress data into RAM and identify it */
						ziperr = zip_file_decompress(zip, data, entry->uncompressed_length);
						if (ziperr == ZIPERR_NONE)
							identify_data(entry->filename, data, entry->uncompressed_length, status);
						free(data);
					}
				}

			/* close up */
			zip_file_close(zip);
		}
	}

	/* otherwise, identify as a raw file */
	else
		identify_file(filename, status);
}
static const zip_file_header *find_file(zip_file *zip, const char *filename)
{
	const zip_file_header *header;
	for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
	{
		if (!core_stricmp(header->filename, filename))
			return header;
	}
	return NULL;
}
Beispiel #6
0
static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const char *subpath, osd_dir_entry_type *type)
{
	int i, j;
	char c1, c2, last_char;
	const zip_file_header *header;

	for (header = zip_file_first_file(zipfile); header != NULL; header = zip_file_next_file(zipfile))
	{
		/* special case */
		if (subpath == NULL)
		{
			if (type != NULL)
				*type = ENTTYPE_FILE;
			return header;
		}

		i = 0;
		j = 0;
		last_char = '/';
				while(((c1 = next_path_char(header->filename, &i)) == (c2 = next_path_char(subpath, &j))) &&
						( c1 != '\0' && c2 != '\0' ))
						last_char = c2;


		if (c2 == '\0')
		{
			if (c1 == '\0')
			{
				if (type != NULL)
					*type = ENTTYPE_FILE;
				return header;
			}
			else if ((last_char == '/') || (c1 == '/'))
			{
				if (type != NULL)
					*type = ENTTYPE_DIR;
				return header;
			}
		}
	}

	if (type != NULL)
		*type = ENTTYPE_NONE;
	return NULL;
}
static const zip_file_header *find_file_crc(zip_file *zip, const char *filename, UINT32 crc)
{
	const zip_file_header *header;
	for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
	{
		// if the CRC and name both match, we're good
		// if the CRC matches and the name doesn't, we're still good
		if ((!core_stricmp(header->filename, filename)) && (header->crc == crc))
		{
			return header;
		}
		else if (header->crc == crc)
		{
			return header;
		}
	}
	return NULL;
}
Beispiel #8
0
static imgtool_stream *stream_open_zip(const char *zipname, const char *subname, int read_or_write)
{
	if (read_or_write)
		return nullptr;

	/* check to see if the file exists */
	FILE *f = fopen(zipname, "r");
	if (!f)
		return nullptr;
	fclose(f);

	imgtool_stream::ptr imgfile(new imgtool_stream(true));

	imgfile->imgtype = IMG_MEM;

	zip_file *z = nullptr;
	const zip_file_header *zipent = nullptr;
	zip_file_open(zipname, &z);
	if (!z)
		goto error;

	zipent = zip_file_first_file(z);
	while (zipent && subname && strcmp(subname, zipent->filename))
		zipent = zip_file_next_file(z);
	if (!zipent)
		goto error;

	imgfile->filesize = zipent->uncompressed_length;
	imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(zipent->uncompressed_length));
	if (!imgfile->buffer)
		goto error;

	if (zip_file_decompress(z, imgfile->buffer, zipent->uncompressed_length))
		goto error;

	zip_file_close(z);
	return imgfile.release();

error:
	if (z)
		zip_file_close(z);
	return nullptr;
}
Beispiel #9
0
file_error emu_file::attempt_zipped()
{
    astring filename;

    // loop over directory parts up to the start of filename
    while (1)
    {
        // find the final path separator
        int dirsep = m_fullpath.rchr(0, PATH_SEPARATOR[0]);
        if (dirsep == -1)
            return FILERR_NOT_FOUND;

        // insert the part from the right of the separator into the head of the filename
        if (filename.len() > 0)
            filename.ins(0, "/");
        filename.inssubstr(0, m_fullpath, dirsep + 1, -1);

        // remove this part of the filename and append a .zip extension
        m_fullpath.substr(0, dirsep).cat(".zip");

        // attempt to open the ZIP file
        zip_file *zip;
        zip_error ziperr = zip_file_open(m_fullpath, &zip);

        // chop the .zip back off the filename before continuing
        m_fullpath.substr(0, dirsep);

        // if we failed to open this file, continue scanning
        if (ziperr != ZIPERR_NONE)
            continue;

        // see if we can find a file with the right name and (if available) crc
        const zip_file_header *header;
        for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
            if (zip_filename_match(*header, filename) && (!(m_openflags & OPEN_FLAG_HAS_CRC) || header->crc == m_crc))
                break;

        // if that failed, look for a file with the right crc, but the wrong filename
        if (header == NULL && (m_openflags & OPEN_FLAG_HAS_CRC))
            for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
                if (header->crc == m_crc && !zip_header_is_path(*header))
                    break;

        // if that failed, look for a file with the right name; reporting a bad checksum
        // is more helpful and less confusing than reporting "rom not found"
        if (header == NULL)
            for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
                if (zip_filename_match(*header, filename))
                    break;

        // if we got it, read the data
        if (header != NULL)
        {
            m_zipfile = zip;
            m_ziplength = header->uncompressed_length;

            // build a hash with just the CRC
            m_hashes.reset();
            m_hashes.add_crc(header->crc);
            return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? FILERR_NONE : load_zipped_file();
        }

        // close up the ZIP file and try the next level
        zip_file_close(zip);
    }
}
Beispiel #10
0
const osd_directory_entry *zippath_readdir(zippath_directory *directory)
{
	const osd_directory_entry *result = NULL;
	const zip_file_header *header;
	const char *relpath;
	const char *separator;
	const char *s;
	zippath_returned_directory *rdent;

	if (!directory->returned_parent)
	{
		/* first thing's first - return parent directory */
		directory->returned_parent = true;
		memset(&directory->returned_entry, 0, sizeof(directory->returned_entry));
		directory->returned_entry.name = "..";
		directory->returned_entry.type = ENTTYPE_DIR;
		result = &directory->returned_entry;
	}
	else if (directory->directory != NULL)
	{
		/* a normal directory read */
		do
		{
			result = osd_readdir(directory->directory);
		}
		while((result != NULL) && (!strcmp(result->name, ".") || !strcmp(result->name, "..")));

		/* special case - is this entry a ZIP file?  if so we need to return it as a "directory" */
		if ((result != NULL) && is_zip_file(result->name))
		{
			/* copy; but change the entry type */
			directory->returned_entry = *result;
			directory->returned_entry.type = ENTTYPE_DIR;
			result = &directory->returned_entry;
		}
	}
	else if (directory->zipfile != NULL)
	{
		do
		{
			/* a zip file read */
			do
			{
				if (!directory->called_zip_first)
					header = zip_file_first_file(directory->zipfile);
				else
					header = zip_file_next_file(directory->zipfile);
				directory->called_zip_first = true;
				relpath = NULL;
			}
			while((header != NULL) && ((relpath = get_relative_path(directory, header)) == NULL));

			if (relpath != NULL)
			{
				/* we've found a ZIP entry; but this may be an entry deep within the target directory */
				for (s = relpath; *s && !is_zip_file_separator(*s); s++)
					;
				separator = *s ? s : NULL;

				if (separator != NULL)
				{
					/* a nested entry; loop through returned_dirlist to see if we've returned the parent directory */
					for (rdent = directory->returned_dirlist; rdent != NULL; rdent = rdent->next)
					{
						if (!core_strnicmp(rdent->name.c_str(), relpath, separator - relpath))
							break;
					}

					if (rdent == NULL)
					{
						/* we've found a new directory; add this to returned_dirlist */
						rdent = new zippath_returned_directory;
						rdent->next = directory->returned_dirlist;
						rdent->name.assign(relpath, separator - relpath);
						directory->returned_dirlist = rdent;

						/* ...and return it */
						memset(&directory->returned_entry, 0, sizeof(directory->returned_entry));
						directory->returned_entry.name = rdent->name.c_str();
						directory->returned_entry.type = ENTTYPE_DIR;
						result = &directory->returned_entry;
					}
				}
				else
				{
					/* a real file */
					memset(&directory->returned_entry, 0, sizeof(directory->returned_entry));
					directory->returned_entry.name = relpath;
					directory->returned_entry.type = ENTTYPE_FILE;
					directory->returned_entry.size = header->uncompressed_length;
					result = &directory->returned_entry;
				}
			}
		}
		while((relpath != NULL) && (result == NULL));
	}
	return result;
}
Beispiel #11
0
file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, std::string &revised_path)
{
	file_error filerr = FILERR_NOT_FOUND;
	zip_error ziperr;
	zip_file *zip = NULL;
	const zip_file_header *header;
	osd_dir_entry_type entry_type;
	char *alloc_fullpath = NULL;
	int len;

	/* first, set up the two types of paths */
	std::string mainpath(filename);
	std::string subpath;
	file = NULL;

	/* loop through */
	while((file == NULL) && (mainpath.length() > 0)
		&& ((openflags == OPEN_FLAG_READ) || (subpath.length() == 0)))
	{
		/* is the mainpath a ZIP path? */
		if (is_zip_file(mainpath.c_str()))
		{
			/* this file might be a zip file - lets take a look */
			ziperr = zip_file_open(mainpath.c_str(), &zip);
			if (ziperr == ZIPERR_NONE)
			{
				/* it is a zip file - error if we're not opening for reading */
				if (openflags != OPEN_FLAG_READ)
				{
					filerr = FILERR_ACCESS_DENIED;
					goto done;
				}

				if (subpath.length() > 0)
					header = zippath_find_sub_path(zip, subpath.c_str(), &entry_type);
				else
					header = zip_file_first_file(zip);

				if (header == NULL)
				{
					filerr = FILERR_NOT_FOUND;
					goto done;
				}

				/* attempt to read the file */
				filerr = create_core_file_from_zip(zip, header, file);
				if (filerr != FILERR_NONE)
					goto done;

				/* update subpath, if appropriate */
				if (subpath.length() == 0)
					subpath.assign(header->filename);

				/* we're done */
				goto done;
			}
		}
		else if (is_7z_file(mainpath.c_str()))
		{
			filerr = FILERR_INVALID_DATA;
			goto done;
		}

		if (subpath.length() == 0)
			filerr = core_fopen(filename, openflags, &file);
		else
			filerr = FILERR_NOT_FOUND;

		/* if we errored, then go up a directory */
		if (filerr != FILERR_NONE)
		{
			/* go up a directory */
			std::string temp;
			zippath_parent(temp, mainpath.c_str());

			/* append to the sub path */
			if (subpath.length() > 0)
			{
				std::string temp2;
				mainpath = mainpath.substr(temp.length());
				temp2.assign(mainpath).append(PATH_SEPARATOR).append(subpath);
				subpath.assign(temp2);
			}
			else 
			{
				mainpath = mainpath.substr(temp.length());
				subpath.assign(mainpath);
			}
			/* get the new main path, truncating path separators */
			len = temp.length();
			while (len > 0 && is_zip_file_separator(temp[len - 1]))
				len--;
			temp = temp.substr(0, len);
			mainpath.assign(temp);
		}
	}

done:
	/* store the revised path */
	revised_path.clear();
	if (filerr == FILERR_NONE)
	{
		/* cannonicalize mainpath */
		filerr = osd_get_full_path(&alloc_fullpath, mainpath.c_str());
		if (filerr == FILERR_NONE)
		{
			if (subpath.length() > 0)
				revised_path.assign(alloc_fullpath).append(PATH_SEPARATOR).append(subpath);
			else
				revised_path.assign(alloc_fullpath);
		}
	}

	if (zip != NULL)
		zip_file_close(zip);
	if (alloc_fullpath != NULL)
		osd_free(alloc_fullpath);
	return filerr;
}
Beispiel #12
0
static image_error_t load_zip_path(mess_image *image, const char *path)
{
	image_error_t err = IMAGE_ERROR_FILENOTFOUND;
	zip_file *zip = NULL;
	zip_error ziperr;
	const zip_file_header *header;
	const char *zip_extension = ".zip";
	char *path_copy;
	const char *zip_entry;
	void *ptr;
	int pos;

	/* create our own copy of the path */
	path_copy = mame_strdup(path);
	if (!path_copy)
	{
		err = IMAGE_ERROR_OUTOFMEMORY;
		goto done;
	}

	/* loop through the path and try opening zip files */
	ziperr = ZIPERR_FILE_ERROR;
	zip_entry = NULL;
	pos = strlen(path_copy);
	while(pos > strlen(zip_extension))
	{
		/* is this a potential zip path? */
		if ((path_copy[pos] == '\0') || !strncmp(&path_copy[pos], PATH_SEPARATOR, strlen(PATH_SEPARATOR)))
		{
			/* parse out the zip path */
			if (path_copy[pos] == '\0')
			{
				/* no zip path */
				zip_entry = NULL;
			}
			else
			{
				/* we are at a zip path */
				path_copy[pos] = '\0';
				zip_entry = &path_copy[pos + strlen(PATH_SEPARATOR)];
			}

			/* try to open the zip file */
			ziperr = zip_file_open(path_copy, &zip);
			if (ziperr != ZIPERR_FILE_ERROR)
				break;

			/* restore the path if we changed */
			if (zip_entry)
				path_copy[pos] = PATH_SEPARATOR[0];
		}
		pos--;
	}

	/* did we succeed in opening up a zip file? */
	if (ziperr == ZIPERR_NONE)
	{
		/* iterate through the zip file */
		header = zip_file_first_file(zip);

		/* if we specified a zip partial path, find it */
		if (zip_entry)
		{
			while(header)
			{
				if (!mame_stricmp(header->filename, zip_entry))
					break;
				header = zip_file_next_file(zip);
			}
		}

		/* were we successful? */
		if (header)
		{
			/* if no zip path was specified, we have to change the name */
			if (!zip_entry)
			{
				/* use the first entry; tough part is we have to change the name */
				err = set_image_filename(image, image->name, header->filename);
				if (err)
					goto done;
			}

			/* allocate space for this zip file */
			ptr = image_malloc(image, header->uncompressed_length);
			if (!ptr)
			{
				err = IMAGE_ERROR_OUTOFMEMORY;
				goto done;
			}

			ziperr = zip_file_decompress(zip, ptr, header->uncompressed_length);
			if (ziperr == ZIPERR_NONE)
			{
				/* success! */
				err = IMAGE_ERROR_SUCCESS;
				image->ptr = ptr;
				image->length = header->uncompressed_length;
			}
		}
	}

done:
	if (path_copy)
		free(path_copy);
	if (zip)
		zip_file_close(zip);
	return err;
}