// Decompiled with JetBrains decompiler // Type: ZuneUI.BurnableCD // Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 // MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 // Assembly location: C:\Program Files\Zune\ZuneShell.dll using Microsoft.Iris; using Microsoft.Zune.Service; using MicrosoftZuneLibrary; using System; using System.Collections; using System.Collections.Generic; namespace ZuneUI { public class BurnableCD : ModelItem { private CDAccess _cdAccess; private ZuneLibraryCDDevice _device; private bool _isBurning; private bool _hasDeviceStartedBurn; private bool _isErasing; private bool _burnCanceling; private List _items; private int _playlistId; private string _burnTitle; private bool _downloadsComplete; private HRESULT _burnError; private ProgressNotification _burnNotification; private int _sessionTotalTime; private int _sessionTimeRemaining; private int _sessionPercentComplete; private int _sessionCurrentTrackNumber; private bool _sessionFinalizing; private Timer _progressTimer; private int _simulatedTickInterval; private string _burnProgressMessage; private static string s_burnStartedMessage = Shell.LoadString(StringId.IDS_BURN_STARTED_NOTIFICATION); private static string s_burnPreparingMessage = Shell.LoadString(StringId.IDS_BURN_PREPARING); private static string s_burnProgressMessage = Shell.LoadString(StringId.IDS_BURN_PROGRESS_NOTIFICATION); private static string s_burnProgressDataMessage = Shell.LoadString(StringId.IDS_BURN_PROGRESS_NOTIFICATION_DATA); private static string s_burnFinalizingMessage = Shell.LoadString(StringId.IDS_BURN_FINALIZING); private static string s_burnSucceededMessage = Shell.LoadString(StringId.IDS_BURN_SUCCEEDED_NOTIFICATION); private static string s_burnFailedMessage = Shell.LoadString(StringId.IDS_BURN_FAILED_NOTIFICATION); private static string s_burnCanceledMessage = Shell.LoadString(StringId.IDS_BURN_CANCELED_NOTIFICATION); private static string s_burnCancelingMessage = Shell.LoadString(StringId.IDS_BURN_CANCELING_NOTIFICATION); private static string s_eraseStartedMessage = Shell.LoadString(StringId.IDS_ERASE_STARTED_NOTIFICATION); private static string s_eraseFinishedMessage = Shell.LoadString(StringId.IDS_ERASE_COMPLETED_NOTIFICATION); internal BurnableCD(CDAccess cdAccess, ZuneLibraryCDDevice device) { this._cdAccess = cdAccess; this._device = device; } protected override void OnDispose(bool fDisposing) { base.OnDispose(fDisposing); if (!fDisposing) return; this._device = null; this._cdAccess = null; } internal bool IsWriteable => this._device.IsWriteable; public bool CanBurnAudio => !this._device.IsDVD; public ZuneLibraryCDDevice Device => this._device; public char DriveLetter => this._device.DrivePath; public TimeSpan TimeAvailable => TimeSpan.FromSeconds(_device.TimeAvailable); public long SpaceAvailable => this._device.SpaceAvailable; public bool IsBurning => this._isBurning; public bool IsErasing => this._isErasing; public bool IsBurnCanceling => this._burnCanceling; public void PrepareForBurn(string burnTitle, int playlistId, IList burnListItems) { this._isBurning = true; this._burnError = new HRESULT(); this._items = new List(burnListItems.Count); this._playlistId = playlistId; this._burnTitle = burnTitle; this._downloadsComplete = false; this._burnProgressMessage = this._cdAccess.IsAudioBurn ? s_burnProgressMessage : s_burnProgressDataMessage; for (int index = 0; index < burnListItems.Count; ++index) { DataProviderObject burnListItem = (DataProviderObject)burnListItems[index]; int property1 = (int)burnListItem.GetProperty("LibraryId"); Guid property2 = (Guid)burnListItem.GetProperty("ZuneMediaId"); this._items.Add(new BurnSessionItem(this, index, property1, property2)); } this.BeginSession(); this.UpdateMessage(); } public void ClearBurnItems() => this._items = null; public void StartBurn() { if (!this._isBurning) return; this.WaitForDownloads(); } private void WaitForDownloads() { bool flag = false; if (this._cdAccess.IsAudioBurn) { foreach (BurnSessionItem burnSessionItem in this._items) { bool fPending = false; if (Download.Instance.IsDownloading(burnSessionItem.ZuneMediaId, EContentType.MusicTrack, out fPending)) { burnSessionItem.Downloading = true; flag = true; } } } if (!flag) { this.StartBurnForReal(); } else { Download.Instance.DownloadEvent += new DownloadEventHandler(this.OnDownloadEvent); Download.Instance.DownloadProgressEvent += new DownloadEventProgressHandler(this.OnDownloadProgress); this._downloadsComplete = false; } } private void OnDownloadEvent(Guid zuneMediaId, HRESULT hr) { if (this._downloadsComplete || hr == HRESULT._E_PENDING || hr == HRESULT._E_ALREADY_EXISTS) return; bool flag = true; int hrError = 0; foreach (BurnSessionItem burnSessionItem in this._items) { if (burnSessionItem.ZuneMediaId == zuneMediaId) { burnSessionItem.Downloading = false; burnSessionItem.ErrorCode = hr.Int; } else if (burnSessionItem.Downloading) flag = false; if (hrError == 0 && burnSessionItem.ErrorCode != 0) hrError = burnSessionItem.ErrorCode; } if (!flag) return; this._downloadsComplete = true; if (hrError != 0) { this.OnSessionError(hrError); this.NotifyBurnStopped(); } else this.StartBurnForReal(); } private void OnDownloadProgress(Guid zuneMediaId, float percent) { foreach (BurnSessionItem burnSessionItem in this._items) { if (burnSessionItem.ZuneMediaId == zuneMediaId) { burnSessionItem.DownloadProgress = (int)percent; break; } } } private void StartBurnForReal() { this._sessionCurrentTrackNumber = 0; HRESULT hr = this._device.SetBurnPlaylist(this._playlistId); if (hr.IsSuccess) { if (!string.IsNullOrEmpty(this._burnTitle)) hr = this._device.SetVolumeLabelW(this._burnTitle); if (hr.IsSuccess) hr = this._device.StartBurn(); } if (hr.IsError) { Application.DeferredInvoke(delegate { this.OnSessionError(hr.Int); this.NotifyBurnStopped(); }, null); } else { this._hasDeviceStartedBurn = true; this.UpdateMessage(); } } internal void CancelBurn() { if (!this._isBurning || this._burnCanceling) return; this._burnCanceling = true; if (this._hasDeviceStartedBurn) this._device.StopBurn(); if (this._progressTimer != null) this._progressTimer.Stop(); this.UpdateMessage(); if (!this._hasDeviceStartedBurn) this.NotifyBurnStopped(); this._hasDeviceStartedBurn = false; } private void BeginSession() { this._device.ItemProgressHandler += new OnItemProgressHandler(this.OnItemProgress); this._device.ItemErrorHandler += new OnItemErrorHandler(this.OnItemError); this._device.SessionProgressHandler += new OnSessionProgressHandler(this.OnSessionProgress); this._device.BurnStateChangeHandler += new OnBurnStateChangeHandler(this.OnBurnStateChanged); } private void NotifyBurnStopped() { this.EndSession(); if (this._burnCanceling && this._items != null) { foreach (BurnSessionItem burnSessionItem in this._items) burnSessionItem.BurnCanceled = true; this._items = null; } this._isBurning = false; this._burnCanceling = false; this._sessionFinalizing = false; this._playlistId = PlaylistManager.InvalidPlaylistId; this._burnTitle = null; this._cdAccess.IsBurning = false; } private void EndSession() { this._device.ItemProgressHandler -= new OnItemProgressHandler(this.OnItemProgress); this._device.ItemErrorHandler -= new OnItemErrorHandler(this.OnItemError); this._device.SessionProgressHandler -= new OnSessionProgressHandler(this.OnSessionProgress); this._device.BurnStateChangeHandler -= new OnBurnStateChangeHandler(this.OnBurnStateChanged); Download.Instance.DownloadEvent -= new DownloadEventHandler(this.OnDownloadEvent); Download.Instance.DownloadProgressEvent -= new DownloadEventProgressHandler(this.OnDownloadProgress); this._downloadsComplete = false; this._sessionTotalTime = 0; this._sessionTimeRemaining = 0; this._sessionPercentComplete = 0; if (this._progressTimer != null) { this._progressTimer.Dispose(); this._progressTimer = null; } this.ShowCompletedMessage(); } public void Erase() { if (this._isErasing) return; this._isErasing = true; this._cdAccess.ActiveDriveLetter = this.DriveLetter; this._cdAccess.IsErasing = true; this.BeginSession(); if (!this._device.EraseDisc().IsError) return; this.CompleteErase(); } private void CompleteErase() { this.EndSession(); this._isErasing = false; this._cdAccess.IsErasing = false; } public BurnSessionItem GetBurnItemByPlaylistContentId(int playlistContentId) { if (this._items != null) { foreach (BurnSessionItem burnSessionItem in this._items) { if (burnSessionItem.PlaylistContentId == playlistContentId) return burnSessionItem; } } return null; } private void OnItemProgress(int index, EBurnProgressStatus eStatus, int nPercent) => Application.DeferredInvoke(delegate { bool flag = false; if (0 <= index && index < this._items.Count) { if (eStatus == EBurnProgressStatus.ebpsComplete || eStatus == EBurnProgressStatus.ebpsFinalizing) this._items[index].BurnComplete = true; else if (eStatus == EBurnProgressStatus.ebpsWritingImageToCD || eStatus == EBurnProgressStatus.ebpsTAOConvertingAndWriting) { this._items[index].BurnProgress = nPercent; int num = index + 1; if (this._sessionCurrentTrackNumber != num) { this._sessionCurrentTrackNumber = num; flag = true; } } } if (eStatus == EBurnProgressStatus.ebpsFinalizing) { this._sessionFinalizing = true; flag = true; } if (!flag) return; this.UpdateMessage(); }, null); private void OnItemError(int index, int hrError) => Application.DeferredInvoke(delegate { if (index == -1) { this.OnSessionError(hrError); } else { if (0 > index || index >= this._items.Count) return; this._items[index].ErrorCode = hrError; } }, null); private void OnSessionError(int hrError) { this._burnError = new HRESULT(hrError); bool flag = false; foreach (BurnSessionItem burnSessionItem in this._items) { if (burnSessionItem.ErrorCode != 0) { flag = true; break; } } foreach (BurnSessionItem burnSessionItem in this._items) { if (!flag) burnSessionItem.ErrorCode = hrError; else if (burnSessionItem.ErrorCode == 0) burnSessionItem.BurnCanceled = true; } Shell.ShowErrorDialog(hrError, StringId.IDS_BURN_FAILED); } private void OnSessionProgress(int lSessionTimeRemaining, int lSessionTotalTime) => Application.DeferredInvoke(delegate { this._sessionTotalTime = lSessionTotalTime * 1000; this._sessionTimeRemaining = lSessionTimeRemaining * 1000; this.UpdateMessage(); int num = 100 - this._sessionPercentComplete; if (num <= 0) return; this._simulatedTickInterval = this._sessionTimeRemaining / num; if (this._simulatedTickInterval <= 0) return; if (this._progressTimer == null) { this._progressTimer = new Timer(); this._progressTimer.Enabled = true; this._progressTimer.Tick += new EventHandler(this.OnSimulatedSessionProgress); } this._progressTimer.Interval = this._simulatedTickInterval; }, null); private void OnSimulatedSessionProgress(object sender, EventArgs args) { this._sessionTimeRemaining = Math.Max(this._sessionTimeRemaining - this._simulatedTickInterval, 0); this.UpdateMessage(); } private void OnBurnStateChanged(EBurnState eBurnState) => Application.DeferredInvoke(delegate { if (eBurnState != EBurnState.ebsStopped) return; if (this._isBurning) { this.NotifyBurnStopped(); } else { if (!this._isErasing) return; this.CompleteErase(); } }, null); private ProgressNotification Notification { get => this._burnNotification; set { this._burnNotification = value; this._cdAccess.BurnNotification = this._burnNotification; } } private void UpdateMessage() { string message = this._isBurning ? s_burnStartedMessage : s_eraseStartedMessage; if (this._burnNotification == null) { this.Notification = new ProgressNotification(message, NotificationTask.Burn, NotificationState.Normal, 0); } else { this._burnNotification.Type = NotificationState.Normal; this._burnNotification.Message = message; } int num = 0; if (this._sessionTotalTime > 0) num = (this._sessionTotalTime - this._sessionTimeRemaining) * 100 / this._sessionTotalTime; if (this._sessionPercentComplete < num) this._sessionPercentComplete = num; this._burnNotification.Percentage = this._sessionPercentComplete; if (!this._isBurning) return; if (this._burnCanceling) this._burnNotification.SubMessage = s_burnCancelingMessage; else if (this._sessionFinalizing) this._burnNotification.SubMessage = s_burnFinalizingMessage; else if (this._sessionCurrentTrackNumber == 0) this._burnNotification.SubMessage = s_burnPreparingMessage; else this._burnNotification.SubMessage = string.Format(this._burnProgressMessage, _sessionCurrentTrackNumber, _items.Count); } private void ShowCompletedMessage() { if (this._burnNotification != null && this._burnNotification.Type != NotificationState.Completed) { this._burnNotification.Type = NotificationState.Completed; if (this._isBurning) { if (this._burnCanceling) this._burnNotification.Message = s_burnCanceledMessage; else if (this._burnError.IsSuccess) { this._burnNotification.Message = s_burnSucceededMessage; this._burnNotification.Percentage = 100; } else this._burnNotification.Message = s_burnFailedMessage; } else this._burnNotification.Message = s_eraseFinishedMessage; this._burnNotification.SubMessage = null; this.Notification = null; } SoundHelper.Play(SoundId.BurnComplete); } } }