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; }
file_error emu_file::load_zipped_file() { assert(m_file == NULL); assert(m_zipdata.count() == 0); assert(m_zipfile != NULL); // allocate some memory m_zipdata.resize(m_ziplength); // read the data into our buffer and return zip_error ziperr = zip_file_decompress(m_zipfile, m_zipdata, m_zipdata.count()); if (ziperr != ZIPERR_NONE) { m_zipdata.reset(); return FILERR_FAILURE; } // convert to RAM file file_error filerr = core_fopen_ram(m_zipdata, m_zipdata.count(), m_openflags, &m_file); if (filerr != FILERR_NONE) { m_zipdata.reset(); return FILERR_FAILURE; } // close out the ZIP file zip_file_close(m_zipfile); m_zipfile = NULL; return FILERR_NONE; }
void emu_file::close() { // close files and free memory if (m__7zfile != NULL) _7z_file_close(m__7zfile); m__7zfile = NULL; if (m_zipfile != NULL) zip_file_close(m_zipfile); m_zipfile = NULL; if (m_file != NULL) core_fclose(m_file); m_file = NULL; m__7zdata.reset(); m_zipdata.reset(); if (m_remove_on_close) osd_rmfile(m_fullpath); m_remove_on_close = false; // reset our hashes and path as well m_hashes.reset(); m_fullpath.reset(); }
file_error emu_file::load_zipped_file() { assert(m_file == NULL); assert(m_zipdata == NULL); assert(m_zipfile != NULL); // allocate some memory m_zipdata = global_alloc_array(UINT8, m_ziplength); // read the data into our buffer and return zip_error ziperr = zip_file_decompress(m_zipfile, m_zipdata, m_ziplength); if (ziperr != ZIPERR_NONE) { global_free(m_zipdata); m_zipdata = NULL; return FILERR_FAILURE; } // convert to RAM file file_error filerr = core_fopen_ram(m_zipdata, m_ziplength, m_openflags, &m_file); if (filerr != FILERR_NONE) { global_free(m_zipdata); m_zipdata = NULL; return FILERR_FAILURE; } // close out the ZIP file zip_file_close(m_zipfile); m_zipfile = NULL; return FILERR_NONE; }
file_error emu_file::load_zipped_file() { assert(m_file == nullptr); assert(m_zipdata.empty()); assert(m_zipfile != nullptr); // allocate some memory m_zipdata.resize(m_ziplength); // read the data into our buffer and return zip_error ziperr = zip_file_decompress(m_zipfile, &m_zipdata[0], m_zipdata.size()); if (ziperr != ZIPERR_NONE) { m_zipdata.clear(); return FILERR_FAILURE; } // convert to RAM file file_error filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file); if (filerr != FILERR_NONE) { m_zipdata.clear(); return FILERR_FAILURE; } // close out the ZIP file zip_file_close(m_zipfile); m_zipfile = nullptr; return FILERR_NONE; }
void emu_file::close() { // close files and free memory if (m__7zfile != nullptr) _7z_file_close(m__7zfile); m__7zfile = nullptr; if (m_zipfile != nullptr) zip_file_close(m_zipfile); m_zipfile = nullptr; if (m_file != nullptr) core_fclose(m_file); m_file = nullptr; m__7zdata.clear(); m_zipdata.clear(); if (m_remove_on_close) osd_rmfile(m_fullpath.c_str()); m_remove_on_close = false; // reset our hashes and path as well m_hashes.reset(); m_fullpath.clear(); }
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 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 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; }
void zippath_closedir(zippath_directory *directory) { if (directory->directory != NULL) osd_closedir(directory->directory); if (directory->zipfile != NULL) zip_file_close(directory->zipfile); while (directory->returned_dirlist != NULL) { zippath_returned_directory *dirlist = directory->returned_dirlist; directory->returned_dirlist = directory->returned_dirlist->next; delete dirlist; } delete directory; }
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); } }
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; }