예제 #1
0
void cfg_layout_t::get_data_raw(stream_writer * out, abort_callback & p_abort)
{
	out->write_lendian_t(t_uint32(stream_version_current), p_abort);
	out->write_lendian_t(m_active, p_abort);
	unsigned n, count = m_presets.get_count();
	out->write_lendian_t(count, p_abort);
	for (n = 0; n < count; n++)
	{
		if (n != m_active || !g_layout_window.get_wnd())
			m_presets[n].write(out, p_abort);
		else
		{
			uie::splitter_item_ptr item;
			g_layout_window.get_child(item);
			out->write_lendian_t(item->get_panel_guid(), p_abort);
			stream_writer_memblock conf;
			item->get_panel_config(&conf);
			out->write_string(m_presets[n].m_name.get_ptr(), p_abort);
			out->write_lendian_t(conf.m_data.get_size(), p_abort);
			out->write(conf.m_data.get_ptr(), conf.m_data.get_size(), p_abort);
		}
	}

}
예제 #2
0
LRESULT threaded_process_v2_t::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
	switch (msg)
	{
		case WM_TIMER:
			if (wp == 1)
			{
				ShowWindow(wnd, SW_SHOWNORMAL);
				KillTimer(wnd, 1);
				return 0;
			}
			else if (wp == 667)
			{
				KillTimer(wnd, 667);
				m_timer_active = false;
				RedrawWindow(wnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
				return 0;
			}
			break;
		case WM_NCCREATE:
			modeless_dialog_manager::g_add(wnd);
			break;
		case WM_SYSCOLORCHANGE:
		case WM_THEMECHANGED:
			refresh_title_font();
			resize();
			break;
		case WM_CREATE:
		{
			if (m_flags & flag_show_button)
			{
				m_textfont = uCreateIconFont();
				m_textfont_height = uGetFontHeight(m_titlefont);
			}
			if (m_flags & flag_show_text)
				refresh_title_font();

			uSetWindowText(wnd, m_title);
			//t_size y_progress = 11;
			//if (m_flags & flag_show_text)
			//	y_progress+=5+uGetFontHeight(m_titlefont);
			//RECT rc;
			//GetClientRect(wnd, &rc);
			//m_wnd_caption = CreateWindowEx(0, WC_STATIC, L"STATIC", WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, wnd, (HMENU)1001, core_api::get_my_instance(), NULL);
			m_wnd_progress = CreateWindowEx(0, PROGRESS_CLASS, L"PROGRESS", WS_SYSMENU | WS_CHILD | WS_VISIBLE | ((m_flags & flag_progress_marquee) ? 0x08 : 0) | PBS_SMOOTH | WS_GROUP, 0, 0, 0, 0, wnd, (HMENU)1002, core_api::get_my_instance(), NULL);
			if (0 == (m_flags & flag_progress_marquee))
				SendMessage(m_wnd_progress, PBM_SETRANGE32, 0, progress_width/*m_range*/);
			else
				SendMessage(m_wnd_progress, WM_USER + 10, TRUE, 20);
			if (m_flags & flag_show_button)
			{
				m_wnd_button = CreateWindowEx(0, WC_BUTTON, L"Stop", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON | WS_GROUP, 0, 0, 0, 0, wnd, (HMENU)IDCANCEL, core_api::get_my_instance(), NULL);
				SendMessage(m_wnd_button, WM_SETFONT, (WPARAM)m_textfont.get(), MAKELPARAM(1, 0));
				//SetFocus(m_wnd_button);
			}
			else
			{
				HMENU menu = GetSystemMenu(wnd, FALSE);
				EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
			}
			resize();
			if (m_flags & flag_no_delay)
			{
				ShowWindow(wnd, SW_SHOWNORMAL);
			}
			else
			{
				SetTimer(wnd, 1, 300, NULL);
			}
			on_init();
		}
		return 0;
		case WM_SHOWWINDOW:
			if (wp == TRUE && lp == 0 && m_wnd_button)
				SetFocus(m_wnd_button);
			break;
		case WM_MOVING:
		{
			LPRECT lprc = (LPRECT)lp;
			lprc->right = lprc->left + m_window_cx;
			lprc->bottom = lprc->top + m_window_cy;
		}
		return TRUE;
		case DM_GETDEFID:
			if (m_flags & flag_show_button)
				return IDCANCEL | (DC_HASDEFID << 16);
			return 0;
		case WM_DESTROY:
			on_destroy_thread();
			m_textfont.release();
			m_titlefont.release();
			return 0;
		case WM_NCDESTROY:
			modeless_dialog_manager::g_remove(wnd);
			break;
		case WM_CLOSE:
			m_abort.abort();
			return 0;
		case WM_SETFOCUS:
			break;
		case WM_COMMAND:
			switch (wp)
			{
				case IDCANCEL:
					if (m_wnd_button)
						EnableWindow(m_wnd_button, FALSE);
					m_abort.abort();
					return 0;
			}
			break;
		case WM_PAINT:
		{
			pfc::string8 p_text;
			pfc::array_t<detail_entry> p_detail_entries;
			{
				insync(m_sync);
				p_text = m_text;
				p_detail_entries = m_detail_entries;
			}
			PAINTSTRUCT ps;
			HDC dc = BeginPaint(wnd, &ps);
			if (dc)
			{
				RECT rc_client, rc_button;
				GetClientRect(wnd, &rc_client);
				RECT rc_fill = rc_client;
				if (m_wnd_button)
				{
					GetWindowRect(m_wnd_button, &rc_button);
					rc_fill.bottom -= RECT_CY(rc_button) + 9;
					rc_fill.bottom -= 11;
				}

				FillRect(dc, &rc_fill, GetSysColorBrush(COLOR_WINDOW));

				if (m_wnd_button)
				{
					rc_fill.top = rc_fill.bottom;
					rc_fill.bottom += 1;
					FillRect(dc, &rc_fill, GetSysColorBrush(COLOR_3DLIGHT));
				}

				rc_fill.top = rc_fill.bottom;
				rc_fill.bottom = rc_client.bottom;
				if (rc_fill.top < rc_fill.bottom)
					FillRect(dc, &rc_fill, GetSysColorBrush(COLOR_3DFACE));

				if (m_flags & flag_show_text)
				{
					SetTextAlign(dc, TA_LEFT);
					SetBkMode(dc, TRANSPARENT);
					//SetTextColor(dc, m_titlecolour);
					RECT rc;
					GetClientRect(wnd, &rc);
					RECT rc2 = { 11 * 2, 11, RECT_CX(rc) - 11 * 2, m_titlefont_height + 11 };
					//FillRect(dc, &rc2, GetSysColorBrush(COLOR_BTNFACE));
					HFONT fnt_old = SelectFont(dc, m_titlefont);
					ui_helpers::text_out_colours_ellipsis(dc, p_text, p_text.get_length(), 0, 11, &rc2, false, false, m_titlecolour, ui_helpers::ALIGN_LEFT);
					//uExtTextOut(dc, 11*2, 11, ETO_CLIPPED, &rc2, m_text, m_text.get_length(), NULL);
					t_size detail_entry_count = 0;
					if (detail_entry_count = p_detail_entries.get_count())
					{
						RECT rc3 = rc2;
						rc3.top = rc2.bottom + 7;
						rc3.bottom = rc3.top + m_textfont_height;
						//SetTextColor(dc, GetSysColor(COLOR_BTNTEXT));
						SelectFont(dc, m_textfont);
						unsigned max_x = 0;
						for (t_size i = 0; i<detail_entry_count; i++)
						{
							unsigned last_x = 0;
							ui_helpers::text_out_colours_ellipsis(dc, p_detail_entries[i].m_label, p_detail_entries[i].m_label.get_length(), 0, rc3.top,
								&rc3, false, false, GetSysColor(COLOR_WINDOWTEXT), ui_helpers::ALIGN_LEFT, NULL, true, &last_x);
							max_x = max(last_x, max_x);
							rc3.top = rc3.bottom;
							rc3.bottom = rc3.top + m_textfont_height;
							//uExtTextOut(dc, 11*2, rc3.top, ETO_CLIPPED, &rc3, m_detail_entries[i].m_label, m_detail_entries[i].m_label.get_length(), NULL);
						}
						rc3.top = rc2.bottom + 7;
						rc3.bottom = rc3.top + m_textfont_height;
						rc3.left = max_x + 5;
						for (t_size i = 0; i<detail_entry_count; i++)
						{
							ui_helpers::text_out_colours_ellipsis(dc, p_detail_entries[i].m_value, p_detail_entries[i].m_value.get_length(), 0, rc3.top,
								&rc3, false, true, GetSysColor(COLOR_WINDOWTEXT), ui_helpers::ALIGN_LEFT);
							rc3.top = rc3.bottom;
							rc3.bottom = rc3.top + m_textfont_height;
						}
					}
					SelectFont(dc, fnt_old);
				}
				EndPaint(wnd, &ps);
			}
		}
		return 0;
		case MSG_REDRAW:
			resize();
			if (!m_timer_active)
			{
				LARGE_INTEGER current = { 0 }, freq = { 0 };
				QueryPerformanceCounter(&current);
				QueryPerformanceFrequency(&freq);
				t_uint64 tenth = 5;
				if (m_time_last_redraw.QuadPart)
				{
					tenth = (current.QuadPart - m_time_last_redraw.QuadPart) / (freq.QuadPart / 100);
				}
				if (tenth < 10)
				{
					SetTimer(get_wnd(), 667, 100 - t_uint32(tenth) * 10, NULL);
					m_timer_active = true;
				}
				else RedrawWindow(wnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
			}
			return 0;
		case MSG_UPDATE_PROGRESS:
			if (abs((int)(wp - SendMessage(m_wnd_progress, PBM_GETPOS, 0, 0))) > 0)
				SendMessage(m_wnd_progress, PBM_SETPOS, wp, 0);
			return 0;
		case MSG_END:
			destroy();
			on_exit();
			return 0;
	}
	return DefWindowProc(wnd, msg, wp, lp);
}
예제 #3
0
파일: spc.cpp 프로젝트: xomniversex/foo_gep
	write_xid6( service_ptr_t<file> & p_file, const file_info & p_info, abort_callback & p_abort )
		: m_file( p_file ), m_abort( p_abort )
	{
		pfc::stringcvt::string_ansi_from_utf8 converter;
		t_filesize offset_tag_start;
		const char * value;
		t_uint32 int32 = 0;

		p_file->seek_ex( 0, file::seek_from_eof, p_abort );

		p_file->write_object( xid6_signature, 4, p_abort );
		p_file->write_object_t( int32, p_abort );

		offset_tag_start = p_file->get_position( p_abort );

		value = p_info.meta_get( "title", 0 );
		if ( value )
		{
			converter.convert( value );
			if ( strlen( converter ) > 32 ) write_string( XID_SONG, converter );
		}

		value = p_info.meta_get( "album", 0 );
		if ( value )
		{
			converter.convert( value );
			if ( strlen( converter ) > 32 ) write_string( XID_GAME, converter );
		}

		value = p_info.meta_get( "artist", 0 );
		if ( value )
		{
			converter.convert( value );
			if ( strlen( converter ) > 32 ) write_string( XID_ARTIST, converter );
		}

		value = p_info.meta_get( "dumper", 0 );
		if ( value )
		{
			converter.convert( value );
			if ( strlen( converter ) > 16 ) write_string( XID_DUMPER, converter );
		}

		value = p_info.meta_get( "comment", 0 );
		if ( value )
		{
			converter.convert( value );
			if ( strlen( converter ) > 32 ) write_string( XID_CMNTS, converter );
		}

		value = p_info.meta_get( "OST", 0 );
		if ( value )
		{
			converter.convert( value );
			write_string( XID_OST, converter );
		}

		value = p_info.meta_get( "discnumber", 0 );
		if ( value )
		{
			char * end;
			unsigned disc = strtoul( value, &end, 10 );
			if ( !*end && disc > 0 && disc <= 9 )
				write_data( XID_DISC, disc );
		}

		value = p_info.meta_get( "tracknumber", 0 );
		if ( value )
		{
			char * end;
			unsigned track = strtoul( value, &end, 10 );
			if ( track > 0 && track < 100 )
				write_data( XID_TRACK, track * 0x100 + *end );
		}

		value = p_info.meta_get( "copyright", 0 );
		if ( value )
		{
			char * end;
			unsigned copyright_year = strtoul( value, &end, 10 );
			if ( copyright_year > 0 && copyright_year < 65536 )
				write_data( XID_COPY, copyright_year );

			while ( *end && *end == ' ' ) end++;
			if ( *end )
			{
				converter.convert( end );
				write_string( XID_PUB, converter );
			}
		}

		value = p_info.info_get( field_length );
		if ( value )
		{
			char * end;
			unsigned length = strtoul( value, &end, 10 );
			if ( !*end && length > 0 && ( length % 1000 || length > 999000 ) )
				write_int( XID_INTRO, length * 64 );
		}

		value = p_info.info_get( field_fade );
		if ( value )
		{
			char * end;
			unsigned fade = strtoul( value, &end, 10 );
			if ( !*end && fade > 99999 )
				write_int( XID_FADE, fade * 64 );
		}

		t_filesize offset = p_file->get_position( p_abort );
		offset -= offset_tag_start;
		if ( offset > ( 1 << 30 ) ) throw exception_io_data();

		if ( offset )
		{
			int32 = t_uint32( offset );
			p_file->seek( offset_tag_start - 4, p_abort );
			p_file->write_lendian_t( int32, p_abort );
		}
		else
		{
			p_file->seek( offset_tag_start - 8, p_abort );
			p_file->set_eof( p_abort );
		}
	}
예제 #4
0
void ipod_write_shadowdb_v2(ipod_device_ptr_ref_t p_ipod, const char * m_path, const ipod::tasks::load_database_t & p_library, threaded_process_v2_t & p_status,abort_callback & p_abort)
{
	pfc::string8 newpath;
	bool b_opened = false;
	//string_print_drive m_path(p_ipod->drive);

	try
	{
		pfc::string8 path = m_path, path_shuffle, path_pstate, path_stats;
		pfc::string8 backup_path;
		path << "\\iTunes\\" << "iTunesSD";
		path_shuffle << m_path << "\\iTunes\\" << "iTunesShuffle";
		path_pstate << m_path << "\\iTunes\\" << "iTunesPState";
		path_stats << m_path << "\\iTunes\\" << "iTunesStats";

		newpath << path << ".temp";

		t_size i, count_tracks = p_library.m_tracks.get_count(), count_playlists = p_library.m_playlists.get_count();

		const t_uint32 shdb_length = 0x40;
		const t_uint32 shtr_length = 372;
		const t_uint32 shth_length = (5 + count_tracks)*sizeof(t_uint32);

		iTunesSD2::writer header;

		header.write_lendian_t(iTunesSD2::shdb, p_abort);
		header.write_lendian_t(0x02000003, p_abort);
		header.write_lendian_t(shdb_length, p_abort);
		header.write_lendian_t(count_tracks, p_abort);
		header.write_lendian_t(count_playlists + 1, p_abort);
		header.write_lendian_t(t_uint32(0), p_abort);
		header.write_lendian_t(t_uint32(0), p_abort);
		header.write_lendian_t(t_uint8(0), p_abort);
		header.write_lendian_t(t_uint8(p_library.m_itunesprefs.m_voiceover_enabled ? 1 : 0), p_abort); //voiceover_enabled
		header.write_lendian_t(t_uint8(0), p_abort);
		header.write_lendian_t(t_uint8(0), p_abort);
		header.write_lendian_t(count_tracks, p_abort);
		header.write_lendian_t(shdb_length, p_abort); //shth offset
		header.write_lendian_t(shdb_length + shth_length + shtr_length*count_tracks, p_abort); //shph offset
		header.write_lendian_t(t_uint32(0), p_abort);
		header.write_lendian_t(t_uint32(0), p_abort);
		header.write_lendian_t(t_uint32(0), p_abort);
		header.write_lendian_t(t_uint32(0), p_abort);
		header.write_lendian_t(t_uint32(0), p_abort);

		{
			iTunesSD2::writer shth;
			shth.write_lendian_t(iTunesSD2::shth, p_abort);
			shth.write_lendian_t(shth_length, p_abort);
			shth.write_lendian_t(count_tracks, p_abort);
			shth.write_lendian_t(t_uint32(0), p_abort);
			shth.write_lendian_t(t_uint32(0), p_abort);
	
			for (i=0; i<count_tracks; i++)
				shth.write_lendian_t(shdb_length + shth_length + i*shtr_length, p_abort);

			header.write(shth, p_abort);
		}

		for (i=0; i<count_tracks; i++)
		{
			const pfc::rcptr_t<itunesdb::t_track> & p_track = p_library.m_tracks[i];
			iTunesSD2::writer shtr;
			shtr.write_lendian_t(iTunesSD2::shtr, p_abort);
			shtr.write_lendian_t(shtr_length, p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort); //start pos
			shtr.write_lendian_t(p_track->length, p_abort);

			int volume = 0;
			if (p_ipod->m_device_properties.m_SupportsSoundCheck)
			{
				unsigned sc = p_library.m_tracks[i]->soundcheck;
				int voli = p_library.m_tracks[i]->volume;
				double volf = (double)voli / 255.0 + 1.0;
				if (volf == 0.0)
				{
					volume = -144;
				}
				else
				{
					double scdb = sc ? 10.0*log10 (1000.0 / (double)sc) : 0; //apple limit to [-12,+12] dB .... but let's not :)
					double vol = 20.0 * log10(volf);
					volume = round_float_signed(vol + scdb);
					if (volume < -48)  volume = -144; //silencer ???
					else if (volume > 18) volume = 18;
				}
			}
			else
			{
				volume = 100 + round_float_signed(100.0 + (double)p_library.m_tracks[i]->volume/255.0);
				volume = min(volume, 200);
				volume = max(volume, 0);
			}

			shtr.write_lendian_t(t_int32(volume)/*p_track->volume*/, p_abort);

			t_uint32 type=0;
			pfc::string_extension ext(p_library.m_tracks[i]->location);
			if (!stricmp_utf8(ext, "mp3"))
				type = 0x1;
			else if (!stricmp_utf8(ext, "mp4") || !stricmp_utf8(ext, "m4a") || !stricmp_utf8(ext, "aa") || !stricmp_utf8(ext, "m4b"))
				type = 0x2;
			else if (!stricmp_utf8(ext, "wav"))
				type = 0x4;

			shtr.write_lendian_t(type, p_abort);

			pfc::string8 path = p_library.m_tracks[i]->location;

			path.truncate (256);
			path.replace_byte(':','/');

			t_size length_path = path.length();

			shtr.write(path.get_ptr(), length_path, p_abort);

			t_size padding = 256 - length_path;
			for (;padding;padding--)
				shtr.write_lendian_t(t_uint8(0), p_abort);

			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint8(!p_track->skip_on_shuffle), p_abort);
			shtr.write_lendian_t(t_uint8(p_track->remember_playback_position), p_abort);
			shtr.write_lendian_t(t_uint8(p_track->gapless_album), p_abort);
			shtr.write_lendian_t(t_uint8(0), p_abort);
			shtr.write_lendian_t(p_track->encoder_delay, p_abort);
			shtr.write_lendian_t(p_track->encoder_padding, p_abort);
			shtr.write_lendian_t(p_track->samplecount, p_abort);
			shtr.write_lendian_t(t_uint64(p_track->resync_frame_offset), p_abort);
			shtr.write_lendian_t(p_track->album_id, p_abort);
			shtr.write_lendian_t(t_uint16(p_track->tracknumber), p_abort);
			shtr.write_lendian_t(t_uint16(p_track->discnumber), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(p_track->pid, p_abort);
			shtr.write_lendian_t(p_track->artist_id, p_abort);

			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);
			shtr.write_lendian_t(t_uint32(0), p_abort);

			header.write(shtr, p_abort);
		}

		{
			const t_uint32 shph_length = (5+1+count_playlists)*sizeof(t_uint32);
			t_uint32 shpl_rolling_start = header.get_size()+shph_length;

			iTunesSD2::writer shph;
			shph.write_lendian_t(iTunesSD2::shph, p_abort);
			shph.write_lendian_t(shph_length, p_abort);
			shph.write_lendian_t(count_playlists+1, p_abort);
			shph.write_lendian_t(t_uint16(0xffff), p_abort); //wtf
			shph.write_lendian_t(t_uint16(0xffff), p_abort); //wtf
			shph.write_lendian_t(t_uint16(0xffff), p_abort); //wtf
			shph.write_lendian_t(t_uint16(0), p_abort); //wtf

			t_uint32 j;

			pfc::array_staticsize_t<iTunesSD2::writer> shpl_array(count_playlists + 1);

			{
				const t_uint32 shpl_size = (11 + count_tracks)*sizeof(t_uint32);

				iTunesSD2::writer & shpl = shpl_array[0];
				shpl.write_lendian_t(iTunesSD2::shpl, p_abort);
				shpl.write_lendian_t(shpl_size, p_abort);
				shpl.write_lendian_t(count_tracks, p_abort);
				shpl.write_lendian_t(count_tracks, p_abort);
				shpl.write_lendian_t(t_uint64(0), p_abort);
				shpl.write_lendian_t(t_uint32(1), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				for (j=0; j<count_tracks; j++)
					shpl.write_lendian_t(t_uint32(j), p_abort);
			}

			mmh::permutation_t permuation_track_id(count_tracks);
			mmh::g_sort_get_permutation_qsort_v2(p_library.m_tracks.get_ptr(), permuation_track_id, ipod::tasks::load_database_t::g_compare_track_id, false, false);

			for (i=0; i<count_playlists; i++)
			{
				const pfc::rcptr_t<itunesdb::t_playlist> & p_playlist = p_library.m_playlists[i];
				t_size count_entries = p_playlist->items.get_count();

				pfc::array_t<t_uint32> indices;
				indices.set_size(count_entries);

				t_size k=0;
				for (j=0; j<count_entries; j++)
					if (!p_playlist->items[j].is_podcast_group)
					{
						t_size index;
						if (p_library.m_tracks.bsearch_permutation_t(ipod::tasks::load_database_t::g_compare_track_id_with_id, p_playlist->items[j].track_id, permuation_track_id, index))
							indices[k++] = index;
					}

				indices.set_size(k);

				const t_uint32 shpl_size = (11 + k)*sizeof(t_uint32);
				iTunesSD2::writer & shpl = shpl_array[1+i];
				shpl.write_lendian_t(iTunesSD2::shpl, p_abort);
				shpl.write_lendian_t(shpl_size, p_abort);
				shpl.write_lendian_t(k, p_abort);
				shpl.write_lendian_t(k, p_abort);
				shpl.write_lendian_t(p_library.m_playlists[i]->id, p_abort);
				shpl.write_lendian_t(t_uint32(2), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				shpl.write_lendian_t(t_uint32(0), p_abort);
				for (j=0; j<k; j++)
					shpl.write_lendian_t(indices[j], p_abort);
			}

			for (i=0; i<count_playlists+1; i++)
			{
				shph.write_lendian_t(shpl_rolling_start, p_abort);
				shpl_rolling_start += shpl_array[i].get_size();
			}
			for (i=0; i<count_playlists+1; i++)
				shph.write(shpl_array[i], p_abort);
			header.write(shph, p_abort);
		}

		service_ptr_t<file> p_file;
		filesystem::g_open_write_new(p_file, newpath, p_abort);
		b_opened=true;

		p_file->write(header.get_ptr(), header.get_size(), p_abort);


		p_file.release();
		b_opened=false;

		abort_callback_dummy p_dummy_abort;

		backup_path << path.get_ptr() << ".backup";
		if (filesystem::g_exists(backup_path, p_dummy_abort))
			filesystem::g_remove(backup_path, p_dummy_abort);

		if (filesystem::g_exists(path, p_dummy_abort))
			filesystem::g_move(path, backup_path, p_dummy_abort);
		filesystem::g_move(newpath, path, p_dummy_abort);

		if (filesystem::g_exists(path_shuffle, p_dummy_abort))
			filesystem::g_remove(path_shuffle, p_dummy_abort);

		if (filesystem::g_exists(path_pstate, p_dummy_abort))
			filesystem::g_remove(path_pstate, p_dummy_abort);

		if (filesystem::g_exists(path_stats, p_dummy_abort))
			filesystem::g_remove(path_stats, p_dummy_abort);
	}
	catch (const exception_aborted &) 
	{
		try
		{
			abort_callback_impl p_dummy_abort;
			if (b_opened)
				filesystem::g_remove(newpath, p_dummy_abort);
		}
		catch (const pfc::exception &) {}
		throw;
	}
	catch (const pfc::exception & ex)
	{
		try
		{
			abort_callback_impl p_dummy_abort;
			if (b_opened)
				filesystem::g_remove(newpath, p_dummy_abort);
		}
		catch (const pfc::exception &) {}
		throw pfc::exception
		//console::print
			(pfc::string_formatter() << "Error writing iTunesSD file : " << ex.what());
	}
}