static FILE* blargg_fopen( const char path [], const char mode [] ) { FILE* file = NULL; wchar_t* wmode = NULL; wchar_t* wpath = NULL; wpath = blargg_to_wide( path ); if ( wpath ) { wmode = blargg_to_wide( mode ); if ( wmode ) file = _wfopen( wpath, wmode ); } // Save and restore errno in case free() clears it int saved_errno = errno; free( wmode ); free( wpath ); errno = saved_errno; return file; }
blargg_err_t Zip_Extractor::update_info( bool advance_first ) { while ( 1 ) { entry_t& e = (entry_t&) catalog [catalog_pos]; if ( memcmp( e.type, "\0K\1\2P", 5 ) && memcmp( e.type, "PK\1\2", 4 ) ) { check( !memcmp( e.type, "\0K\5\6P", 5 ) ); break; } unsigned len = get_le16( e.filename_len ); int next_offset = catalog_pos + entry_size + len + get_le16( e.extra_len ) + get_le16( e.comment_len ); if ( (unsigned) next_offset > catalog.size() - end_entry_size ) return blargg_err_file_corrupt; if ( catalog [next_offset] == 'P' ) reorder_entry_header( next_offset ); if ( !advance_first ) { char unterminate = e.filename[len]; e.filename [len] = 0; // terminate name std::string fname = e.filename; if ( is_normal_file( e, len ) ) { e.filename[len] = unterminate; name.resize(fname.size()+1); if(len != 0) { memcpy(name.begin(),fname.c_str(),len); name[name.size()-1] = 0; } set_name( name.begin() ); set_info( get_le32( e.size ), get_le32( e.date ), get_le32( e.crc ) ); unsigned extra_len = get_le32(e.extra_len); //walk over extra fields unsigned i = len; while(i < extra_len + len) { unsigned id = get_le16(e.filename + i); i += 2; unsigned exlen = get_le16(e.filename + i); i += 2; int exfield = i; i += exlen; if(id == 0x7075) //INFO-ZIP unicode path extra field (contains version, checksum, and utf-8 filename) { unsigned version = (unsigned char)*(e.filename + exfield); if(version == 1) { exfield += 1; //skip version exfield += 4; //skip crc //the remainder is a utf-8 filename int fnamelen = exlen-5; char* tempbuf = (char*)malloc(fnamelen + 1); memcpy(tempbuf,e.filename + exfield, fnamelen); tempbuf[fnamelen] = 0; wchar_t* wfname_buf = blargg_to_wide(tempbuf); std::wstring wfname = wfname_buf; free(tempbuf); free(wfname_buf); size_t wfname_len = wfname.size(); this->wname.resize(wfname_len+1); if(wfname_len != 0) { memcpy(this->wname.begin(),wfname.c_str(),wfname_len*sizeof(wchar_t)); wname[wname.size()-1] = 0; } set_name( name.begin(), wname.begin() ); } } } break; } } catalog_pos = next_offset; advance_first = false; } return blargg_ok; }