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;
}
Example #2
0
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;
}