Inheritance: ICloneable
 private bool TryStopTask(ScheduledTask task)
 {
     if(task.Status == TaskStatus.Waiting) {
         // stop the timer
         task.Stop();
         return true;
     }
     else if(task.Status == TaskStatus.Stopped) {
         return true;
     }
     else {
         return false;
     }
 }
        public void TaskStopped(ScheduledTask task, int remaining)
        {
            if(_settings == null) {
                throw new Exception("Settings not set");
            }

            if(remaining == 0 && powerManager.Running) {
                powerManager.Stop();
            }
        }
 private void TaskStatusChanged(ScheduledTask task, TaskStatus status)
 {
     if(OnTaskStatusChanged != null) {
         OnTaskStatusChanged(task.TaskId, status);
     }
 }
        private void Export()
        {
            FileStore.FileStore store = new FileStore.FileStore();
            FileStore.StoreFile file = null;
            FileStore.StoreMode storeMode = FileStore.StoreMode.Normal;

            if(EncryptCheckbox.Checked) {
                SHA256Managed passwordHash = new SHA256Managed();
                store.Encrypt = true;
                store.EncryptionKey = passwordHash.ComputeHash(Encoding.ASCII.GetBytes(PasswordTextbox.Text));
                storeMode = FileStore.StoreMode.Encrypted;
            }

            // general settings
            if(GeneralCheckbox.Checked) {
                file = store.CreateFile("options.dat");
                store.WriteFile(file, SDOptionsFile.SerializeOptions(_options), storeMode);
            }

            // default plugin settings
            if(PluginCheckbox.Checked) {
                file = store.CreateFile("pluginSettings.dat");
                if(store.WriteFile(file, SecureDeleteLocations.GetPluginDefaultSettingsFilePath(), storeMode) == false) {
                    actionErrors.Add("Failed to export default plugin settings");
                }
            }

            // add methods
            if(MethodsCheckbox.Checked) {
                store.CreateFolder("methods");
                Dictionary<int, string> methodList = new Dictionary<int, string>();

                // add methods
                foreach(ListViewItem item in MethodList.Items) {
                    if(item.Checked) {
                        int id = (int)item.Tag;
                        string methodFile = Path.Combine(SecureDeleteLocations.GetMethodsFolder(),
                                                         id.ToString() + WipeMethodManager.MethodFileExtension);

                        file = store.CreateFile("methods\\" + Path.GetFileName(methodFile));
                        if(store.WriteFile(file, methodFile, storeMode) == false) {
                            actionErrors.Add("Failed to export wipe method " + item.Text);
                        }

                        // add to methd list
                        methodList.Add(id, item.Text);
                    }
                }

                // store the method list
                file = store.CreateFile("methods\\list.dat");
                store.WriteFile(file, SerializeMethodList(methodList), storeMode);
            }

            // scheduled tasks
            if(TasksCheckbox.Checked) {
                store.CreateFolder("tasks");

                // add task list
                file = store.CreateFile("tasks\\list.dat");
                store.WriteFile(file, SerializeTaskList(_options.SessionNames), storeMode);

                foreach(ListViewItem item in TaskList.Items) {
                    if(item.Checked) {
                        Guid taskId = (Guid)item.Tag;
                        string taskFile = SecureDeleteLocations.GetTaskFile(taskId);
                        string sessionFile = SecureDeleteLocations.GetSessionFile(taskId);

                        file = store.CreateFile("tasks\\" + Path.GetFileName(taskFile));
                        ScheduledTask task = new ScheduledTask();
                        TaskManager.LoadTask(taskFile, out task);
                        store.WriteFile(file, TaskManager.SerializeTask(task), storeMode);

                        file = store.CreateFile("tasks\\" + Path.GetFileName(sessionFile));
                        WipeSession session = new WipeSession();
                        SessionLoader.LoadSession(sessionFile, out session);
                        store.WriteFile(file, SessionSaver.SerializeSession(session), storeMode);
                    }
                }
            }

            // save
            if(store.Save(ExportPath.Text) == false) {
                actionErrors.Add("Failed to export to file " + ExportPath.Text);
            }
        }
        private void HandleNewTask()
        {
            if(_task == null) {
                return;
            }

            // modify a copy
            _task = (ScheduledTask)_task.Clone();
            NameTextbox.Text = _task.Name;

            if(_task.Schedule == null) {
                _task.Schedule = new OneTimeSchedule();
            }

            if(_task.Description != null) {
                DescriptionTextbox.Text = _task.Description;
            }

            SetDefaultSchedule(_task.Schedule);
            EnabledCheckbox.Checked = _task.Enabled;
            SaveReportsCheckbox.Checked = _task.SaveReport;
        }
        private ListViewItem GetItemByTask(ScheduledTask task)
        {
            foreach(ListViewItem item in TaskList.Items) {
                if(((ScheduledTask)(item.Tag)).TaskId == task.TaskId) {
                    return item;
                }
            }

            return null;
        }
        private void HandleTaskStarted(ScheduledTask task)
        {
            if(task == activeTask.Tag) {
                StartButton.Enabled = false;
                StopButton.Enabled = true;
                HideDetailsPanel();
                HistoryTool.Visible = false;
                WipeItems.Visible = false;
            }

            _actionManager.StateChanged();
        }
 private void ControllerTaskStopped(ScheduledTask task, int remaining)
 {
     foreach(ITaskController controller in _taskControllers) {
         controller.TaskStopped(task, remaining);
     }
 }
 private void DetachTaskEvents(ScheduledTask task)
 {
     task.OnTaskStarted -= TaskStarted;
     task.OnTaskStatusChanged -= TaskStatusChanged;
     task.OnTaskCompleted -= TaskCompleted;
 }
        /// <summary>
        /// 
        /// </summary>
        /// <remarks>Used on the client side only.</remarks>
        /// <returns></returns>
        public bool AddTask(ScheduledTask task, bool start)
        {
            if(task == null) {
                throw new ArgumentNullException("task");
            }

            // check if already in list
            foreach(ScheduledTask t in _taskList) {
                if(task.TaskId == t.TaskId) {
                    return false;
                }
            }

            // save
            if(SaveTask(SecureDeleteLocations.CombinePath(SecureDeleteLocations.GetScheduledTasksDirectory(),
                                                          task.TaskId.ToString() + TaskFileExtension), task) == false) {
                return false;
            }

            // add to the list
            _taskList.Add(task);
            HandleNewTask(task, start);
            return true;
        }
 public void StartTaskSchedule(ScheduledTask task)
 {
     PrepareForStart(task);
     task.StartSchedule();
 }
        public static byte[] SerializeTask(ScheduledTask task)
        {
            BinaryFormatter serializer = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();

            try {
                // serialize in memory
                serializer.Serialize(stream, task);
                return stream.ToArray();
            }
            catch(Exception e) {
                Debug.ReportError("Error while serializing task. Exception: {0}", e.Message);
                return null;
            }
            finally {
                if(stream != null) {
                    stream.Close();
                }
            }
        }
        public static bool SaveTask(string path, ScheduledTask task)
        {
            // check the parameters
            if(task == null || path == null) {
                throw new ArgumentNullException("task | path");
            }

            try {
                // create the store
                FileStore.FileStore store = new FileStore.FileStore();
                store.Encrypt = true;
                store.UseDPAPI = true;

                // add the file
                FileStore.StoreFile file = store.CreateFile("task.dat");
                byte[] data = SerializeTask(task);

                if(data == null) {
                    return false;
                }

                // write the file contents
                store.WriteFile(file, data, FileStore.StoreMode.Encrypted);
                return store.Save(path);
            }
            catch(Exception e) {
                Debug.ReportError("Error while saving task. Exception: {0}", e.Message);
                return false;
            }
        }
        public static bool LoadTask(string path, out ScheduledTask task)
        {
            // check the parameters
            if(path == null) {
                throw new ArgumentNullException("path");
            }

            task = null;

            try {
                // create the store
                FileStore.FileStore store = new FileStore.FileStore();
                store.Encrypt = true;
                store.UseDPAPI = true;

                // load store
                if(store.Load(path) == false) {
                    Debug.ReportError("Error while loading store from path {0}", path);
                    return false;
                }

                // deserialize
                task = DeserializeTask(store.ReadFile("task.dat"));
                return true;
            }
            catch(Exception e) {
                Debug.ReportError("Error while loading task. Exception: {0}", e.Message);
                return false;
            }
        }
        private void AddTask()
        {
            WipeSession session = new WipeSession();
            session.GenerateGuid();
            ScheduledTask task = new ScheduledTask();
            task.TaskId = session.SessionId;
            task.Schedule = new OneTimeSchedule();
            task.Name = "Untitled task";
            task.Enabled = true;

            // show the dialog
            ScheduleOptions options = new ScheduleOptions();
            options.Options = _options;
            options.EditMode = false;
            options.Task = task;

            if(options.ShowDialog() == DialogResult.OK) {
                task = options.Task;
                manager.LoadOptions();
                manager.AddTask(task, true);

                SessionSaver.SaveSession(session, SecureDeleteLocations.GetSessionFile(task.TaskId));
                ListViewItem item = CreateTaskItem(task);
                UpdateTaskItem(item);

                // add to the <guid,taskName> mapping
                _options.SessionNames.Add(task.TaskId, task.Name);
                SDOptionsFile.TrySaveOptions(_options);
                TaskList.Items[TaskList.Items.Count - 1].Selected = true;
            }

            _actionManager.StateChanged();
        }
 /// <summary>
 /// Stop a task, event if it's in wiping mode
 /// </summary>
 private bool ForceStopTask(ScheduledTask task)
 {
     return task.Stop();
 }
 private ListViewItem CreateTaskItem(ScheduledTask task)
 {
     ListViewItem item = new ListViewItem();
     item.SubItems.AddRange(new string[] { "", "" });
     item.Tag = task;
     TaskList.Items.Add(item);
     return item;
 }
        private void HandleNewTask(ScheduledTask task, bool start)
        {
            task.Options = _options;

            if(start) {
                StartTaskSchedule(task);
            }
        }
        private void HandleItemSelection(ScheduledTask scheduledTask)
        {
            TaskStatus status = scheduledTask.Status;

            if(status != TaskStatus.Wiping && status != TaskStatus.InitializingWiping &&
               status != TaskStatus.Stopping) {
                StartButton.Enabled = true;
                StopButton.Enabled = false;
            }
            else {
                StartButton.Enabled = false;
                StopButton.Enabled = true;
            }
        }
 private void PrepareForStart(ScheduledTask task)
 {
     LoadOptions();
     task.Options = _options;
     task.HistoryManager = _taskHistory;
     task.TaskControllers = _taskControllers;
     AttachTaskEvents(task);
 }
        private void HandleTaskStopped(ScheduledTask task)
        {
            if(activeTask != null && task == activeTask.Tag) {
                if(HistorySelector.Selected) {
                    // reload history info
                    HistoryTool.Task = task;
                    StartButton.Enabled = true;
                    StopButton.Enabled = false;
                    ShowDetailsPanel();

                    if(WipeSelector.Selected) {
                        WipeSelector.Selected = true;
                    }
                    else {
                        HistorySelector.Selected = true;
                    }
                }
            }

            _actionManager.StateChanged();
        }
        private void TaskCompleted(ScheduledTask task)
        {
            lock(queueLock) {
                // remove from the queue
                if(taskQueue.Contains(task)) {
                    taskQueue.Remove(task);
                }

                ControllerTaskStopped(task, taskQueue.Count);
            }
        }
        public object Clone()
        {
            ScheduledTask temp = new ScheduledTask();
            temp._taskId = _taskId;

            if(_schedule != null) {
                temp._schedule = (ISchedule)_schedule.Clone();
            }
            if(_name != null) {
                temp._name = (string)_name.Clone();
            }
            if(_description != null) {
                temp._description = (string)_description.Clone();
            }

            temp._saveReport = _saveReport;

            foreach(IAction action in _beforeWipeActions) {
                temp._beforeWipeActions.Add((IAction)action.Clone());
            }

            foreach(IAction action in _afterWipeActions) {
                temp._afterWipeActions.Add((IAction)action.Clone());
            }

            temp._useCustomOptions = _useCustomOptions;

            if(_customOptions != null) {
                temp._customOptions = (WipeOptions)_customOptions.Clone();
            }

            temp._enabled = _enabled;
            return temp;
        }
        private void TaskStarted(ScheduledTask task)
        {
            // add it to the queue
            lock(queueLock) {
                taskQueue.Add(task);
            }

            // wait for previous tasks to finnish
            if(_options.QueueTasks) {
                int position;
                lock(queueLock) {
                    position = taskQueue.IndexOf(task);
                }

                while(position > 0) {
                    task.Status = TaskStatus.Queued;

                    // get first task
                    ScheduledTask first;
                    lock(queueLock) {
                        first = taskQueue[0];
                    }

                    first.WaitForFinnish();

                    // update position
                    lock(queueLock) {
                        position = taskQueue.IndexOf(task);
                    }
                }
            }

            // start
            if(task.Status != TaskStatus.Stopped && TaskCanStart()) {
                task.StartWipe();
            }
        }
        private void ScheduleOptions_Load(object sender, EventArgs e)
        {
            SecureDeleteWinForms.Properties.Settings.Default.PositionManager.LoadPosition(this);

            if(_editMode) {
                SaveButton.Text = "Save";
            }
            else {
                SaveButton.Text = "Add Task";
            }

            if(_task == null) _task = new ScheduledTask();
            GeneralSelector.Selected = true;
        }
        public void TaskStarted(ScheduledTask task)
        {
            if(_settings == null) {
                throw new Exception("Settings not set");
            }

            if(_settings.StopIfLowBatteryPower || _settings.StopIfPowerSaverScheme) {
                if(powerManager.Running == false) {
                    powerManager.Start();
                }
            }
            else {
                if(powerManager.Running) {
                    powerManager.Stop();
                }
            }
        }