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 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; }
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 el_file_ptr file_open(const char* file_name, const char* extra_path) { char str[1024]; el_zip_file_entry_t key; el_file_ptr result; Sint32 i, count; if (!file_name || !*file_name) return NULL; if (extra_path) { if (do_file_exists(file_name, extra_path, sizeof(str), str) == 1) { return xz_gz_file_open(str); } } if (do_file_exists(file_name, get_path_updates(), sizeof(str), str) == 1) { return xz_gz_file_open(str); } init_key(file_name, &key, sizeof(str), str); CHECK_AND_LOCK_MUTEX(zip_mutex); count = num_zip_files - 1; CHECK_AND_UNLOCK_MUTEX(zip_mutex); for (i = count; i >= 0; i--) { CHECK_AND_LOCK_MUTEX(zip_files[i].mutex); if (locate_in_zip(&zip_files[i], &key) == 1) { result = zip_file_open(zip_files[i].file); CHECK_AND_UNLOCK_MUTEX(zip_files[i].mutex); return result; } CHECK_AND_UNLOCK_MUTEX(zip_files[i].mutex); } if (do_file_exists(file_name, datadir, sizeof(str), str) == 1) { return xz_gz_file_open(str); } LOG_ERROR("Can't open file '%s'.", file_name); return NULL; }
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; }
static file_error OpenDIBFile(const char *dir_name, const char *zip_name, const char *filename, core_file **file, void **buffer) { file_error filerr; zip_error ziperr; zip_file *zip; const zip_file_header *zip_header; astring *fname; // clear out result *file = NULL; // look for the raw file fname = astring_assemble_3(astring_alloc(), dir_name, PATH_SEPARATOR, filename); filerr = core_fopen(astring_c(fname), OPEN_FLAG_READ, file); astring_free(fname); // did the raw file not exist? if (filerr != FILERR_NONE) { // look into zip file fname = astring_assemble_4(astring_alloc(), dir_name, PATH_SEPARATOR, zip_name, ".zip"); ziperr = zip_file_open(astring_c(fname), &zip); astring_free(fname); if (ziperr == ZIPERR_NONE) { zip_header = zip_file_seek_file(zip, filename); if (zip_header != NULL) { *buffer = malloc(zip_header->uncompressed_length); ziperr = zip_file_decompress(zip, *buffer, zip_header->uncompressed_length); if (ziperr == ZIPERR_NONE) { filerr = core_fopen_ram(*buffer, zip_header->uncompressed_length, OPEN_FLAG_READ, file); } } zip_file_close(zip); } } return filerr; }
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); } }
static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file *&zipfile, std::string &newpath) { file_error err; osd_directory_entry *current_entry = NULL; osd_dir_entry_type current_entry_type; int went_up = FALSE; int i; newpath.clear(); /* be conservative */ entry_type = ENTTYPE_NONE; zipfile = NULL; std::string apath(path); std::string apath_trimmed; do { /* trim the path of trailing path separators */ i = apath.length(); while (i > 1 && is_path_separator(apath[i - 1])) i--; apath = apath.substr(0, i); apath_trimmed.assign(apath); /* stat the path */ current_entry = osd_stat(apath_trimmed.c_str()); /* did we find anything? */ if (current_entry != NULL) { /* get the entry type and free the stat entry */ current_entry_type = current_entry->type; osd_free(current_entry); current_entry = NULL; } else { /* if we have not found the file or directory, go up */ current_entry_type = ENTTYPE_NONE; went_up = TRUE; std::string parent; apath.assign(zippath_parent(parent, apath.c_str())); } } while (current_entry_type == ENTTYPE_NONE && !is_root(apath.c_str())); /* if we did not find anything, then error out */ if (current_entry_type == ENTTYPE_NONE) { err = FILERR_NOT_FOUND; goto done; } /* is this file a ZIP file? */ if ((current_entry_type == ENTTYPE_FILE) && is_zip_file(apath_trimmed.c_str()) && (zip_file_open(apath_trimmed.c_str(), &zipfile) == ZIPERR_NONE)) { i = strlen(path + apath.length()); while (i > 0 && is_zip_path_separator(path[apath.length() + i - 1])) i--; newpath.assign(path + apath.length(), i); /* this was a true ZIP path - attempt to identify the type of path */ zippath_find_sub_path(zipfile, newpath.c_str(), ¤t_entry_type); if (current_entry_type == ENTTYPE_NONE) { err = FILERR_NOT_FOUND; goto done; } } else { /* this was a normal path */ if (went_up) { err = FILERR_NOT_FOUND; goto done; } newpath.assign(path); } /* success! */ entry_type = current_entry_type; err = FILERR_NONE; done: return err; }
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; }
multicart_open_error multicart_open(emu_options &options, const char *filename, const char *gamedrv, multicart_load_flags load_flags, multicart_t **cart) { multicart_open_error err; zip_error ziperr; object_pool *pool; multicart_load_state state = {0, }; const zip_file_header *header; const char *pcb_type; char *layout_text = NULL; /* allocate an object pool */ pool = pool_alloc_lib(NULL); if (pool == NULL) { err = MCERR_OUT_OF_MEMORY; goto done; } /* allocate the multicart */ state.multicart = (multicart_t*)pool_malloc_lib(pool, sizeof(*state.multicart)); if (state.multicart == NULL) { err = MCERR_OUT_OF_MEMORY; goto done; } memset(state.multicart, 0, sizeof(*state.multicart)); /* allocate the multicart's private data */ state.multicart->data = (multicart_private*)pool_malloc_lib(pool, sizeof(*state.multicart->data)); if (state.multicart->data == NULL) { err = MCERR_OUT_OF_MEMORY; goto done; } memset(state.multicart->data, 0, sizeof(*state.multicart->data)); state.multicart->data->pool = pool; pool = NULL; /* open the ZIP file */ ziperr = zip_file_open(filename, &state.zip); if (ziperr != ZIPERR_NONE) { err = MCERR_NOT_MULTICART; goto done; } /* find the layout.xml file */ header = find_file(state.zip, "layout.xml"); if (header == NULL) { err = MCERR_MISSING_LAYOUT; goto done; } /* reserve space for the layout text */ layout_text = (char*)malloc(header->uncompressed_length + 1); if (layout_text == NULL) { err = MCERR_OUT_OF_MEMORY; goto done; } /* uncompress the layout text */ ziperr = zip_file_decompress(state.zip, layout_text, header->uncompressed_length); if (ziperr != ZIPERR_NONE) { err = MCERR_ZIP_ERROR; goto done; } layout_text[header->uncompressed_length] = '\0'; /* parse the layout text */ state.layout_xml = xml_string_read(layout_text, NULL); if (state.layout_xml == NULL) { err = MCERR_XML_ERROR; goto done; } /* locate the PCB node */ if (!find_pcb_and_resource_nodes(state.layout_xml, &state.pcb_node, &state.resources_node)) { err = MCERR_NO_PCB_OR_RESOURCES; goto done; } /* get the PCB resource_type */ pcb_type = xml_get_attribute_string(state.pcb_node, "type", ""); state.multicart->pcb_type = pool_strdup_lib(state.multicart->data->pool, pcb_type); if (state.multicart->pcb_type == NULL) { err = MCERR_OUT_OF_MEMORY; goto done; } state.multicart->gamedrv_name = pool_strdup_lib(state.multicart->data->pool, gamedrv); if (state.multicart->gamedrv_name == NULL) { err = MCERR_OUT_OF_MEMORY; goto done; } /* do we have to load resources? */ if (load_flags & MULTICART_FLAGS_LOAD_RESOURCES) { err = load_all_resources(options, &state); if (err != MCERR_NONE) goto done; err = load_all_sockets(&state); if (err != MCERR_NONE) goto done; } err = MCERR_NONE; done: if (pool != NULL) pool_free_lib(pool); if (state.zip != NULL) zip_file_close(state.zip); if (layout_text != NULL) free(layout_text); if (state.layout_xml != NULL) xml_file_free(state.layout_xml); if ((err != MCERR_NONE) && (state.multicart != NULL)) { multicart_close(options, state.multicart); state.multicart = NULL; } *cart = state.multicart; return err; }
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; }