#if (!DEBUG)
#define useIsolatedStorage
#endif
//The XML configuration file may be written to isolated storage or to normal file storage.
//Normal file storage is useful for debugging as it is easy to view or modify the XML source.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
namespace FileFind
{
/// <summary>
/// ConfigInfo holds configuration data as well as data that is commonly shared between
/// program modules and forms.
/// Product/version information is maintained in AssemblyInfo.cs
/// Configuration information is stored when the application exits and retrieved at the next start up.
/// Saving of a filter list triggers an immediate save of the configuration information.
/// If useIsolatedStorage is #defined, application setting are saved in isolated storage specific to
/// the program and user. Otherwise, the information is stored in the program execution directory
/// where it is simple to view or modify the XML source for testing.
///
/// ConfigInfo is also used to pass data from various forms and dialogs back to the caller.
/// </summary>
[IsolatedStorageFilePermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
class ConfigInfo
{
#region Local constants and variables
private object syncobj = new object(); //local lock object
/// <summary>
/// Product/version identification constants
/// </summary>
private const string PRODUCTDATE = "2010";
//private static string PRODUCTVERSION =
// System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
// PRODUCTVERSION replaced with Application.Application.ProductVersion
/// <summary>
/// Maintenance
/// Version 1.0.0.0 Initial coding
/// 2.0.0.0 Code restructured and optimized based on hard won knowledge
/// 2.1.0.0 Added ResolvePartitions logic to Form1.cs to eliminate
/// seek contention on partitioned physical drives.
/// 2.1.0.3 Added reparse point processing (do not recurse into it)
/// 2.1.0.4 Added time filters
/// 2.1.0.5 Added hidden folder/file menu option
/// 2.1.0.6 Switched from foreach (FileSystemInfo to FileSystemEnumerator in DiskScan
/// to significantly speed up access to network drives
/// 2.1.0.7 Added Menu->Options->Scanning via enumerator to ease testing and
/// allow for Windows 7 bug. Windows 7 failed when using enumerator.
/// 2.1.0.8 Added NumericScaling class
/// 2.1.0.9 Final clean up before publication to www.codeproject.com
/// 2.1.0.10 Changed .cvs to .csv file extention
/// Added code to correctly handle embedded commas, new line characters and double quotes for save to .CSV files
/// Modified exit from Excludes to refresh selected drive information
/// Modified .CSV save routine to properly handle reservered characters (comma and double quotes) and changed
/// the seperation character to a tab.
/// 2.1.0.11 Modified menu titles and rearranged menu items. Changed opening instructions.
/// Added status area at bottom of form to report disks being searched and thread terminations.
/// Modified SelectAllDisks logic to handle a system with no drives.
/// 2.1.0.12
/// Added "Waiting on logical/physical drive resolution" message to Form1.cs
/// Grid view of "Folders only" no longer has file name or size columns
/// 2.1.0.13
/// Added busy cursor during logical/physical disk resolution, Sort and Grid view swap.
/// Totally revamped BeginUpdate/EndUpdate logic for filesFoundBox displays resulting in
/// better response and faster searches when a large number of hits are found.
/// 2.1.0.14
/// Moved logical to physical disk resolution to LogicalPhysicalDiskResolution class
/// Corrected Form1.excludesButton_Click to resolve with currently selected disk drives.
/// Add disk info display to single/double click of Disk column in grid view.
/// Now launches Drive for double click.
/// 2.1.0.15
/// Improved user identity checking in About.
/// Corrected an error in Directory delete.
/// 2.1.0.16
/// Bypassed logical/physical disk resolution if only 1 disk is being searched.
/// Redrive SelectAllDisks after excludesButton_Click was selected
/// Disable Delete button if no entries in grid view
/// Used OnIdle event to enable the Start button only if a mask is present
/// 2.1.0.17
/// Prepare for publication in CodeProject
/// 2.1.0.18
/// Correct an object disposed when terminating the application in Form1.TerminateAllThreads by
/// adding "catch (ObjectDisposedException)" to error handling in DiskScan routine. Also added
/// "Application.DoEvents()" to Form1.TerminateAllThreads
/// Added a check for disk resolution completion before calling a modal form
/// Added Type.GetType("System.DateTime") to dates in the grid view
/// Added the ability to select which columns to display in the grid view
/// Changed the Disk column to a fixed width and added a Volume Id column
/// Allowed Parameters to be passed to the program's invocation
/// 2.1.0.19
/// Changed updates to toolStripStatusLabel1 to call the UpdateStatus routine due to problems when
/// UltraMon switched monitor screens during disk resolution.
/// Added code to start new forms with a location close to the original form as this looked much
/// better on multiple monitors.
/// Grid view now honors a Delete key as well as the delete button.
/// 3.0.0.0
/// Changed from IgnoreFolders to Exclude/Include rule processing
/// Save/restore grid view column visibility
/// Upgraded LogicalPhysicalDiskResolution class to support synchronous and asynchronous methods.
/// The upgrade required changing the Invoke to BeginInvoke in UpdateStatus
/// Corrected selection problems when using the track bars for date selection
/// </summary>
private const string CONFIGFILENAME = "FileFind.xml"; //name of the configuration file
private static bool alreadyInitialized = false; //determines if the following static fields are already loaded
private static bool dirty = false; //determines if ConfigInfo should be saved at exit
private static bool removedSavedOptions = false; //Isolated storage is not to be written at termination
//variables to be saved for the next execution of this program
private static bool startWithGrid = false; //start in List or Grid view
private static Font usingFont = null; //display panels using this font
private static bool showUnauthorizedFolders; //if True, security exceptions are displayed
private static bool showReparsePoints; //if True, reparse points are displayed
private static bool showHiddenFoldersFiles; //if True, search and show hidden folders and files
private static bool scanningViaEnumerator; //if True, search files and folders using enumerators
private static bool autoScrolling; //if true, auto scroll list view
private static bool returnDriveLetters; //used in SelectDiskPath
private static Dictionary<string, GridInfoCollection> gridInfos = null;
private static FilterListCollection filterLists = null; //filter lists from prior FileFind execution
private static FilterList activeFilterList = null; //currently active filter list
#endregion Local constants and variables
#region Properties
public static string ProductDate
{ get { return PRODUCTDATE; } }
/// <summary>
/// Determines if the initial display should begin with a list or grid view
/// List view is the inital default
/// The current view is saved when the application exits and the
/// application will be restarted with the same view.
/// </summary>
public bool StartWithGrid
{
get { return startWithGrid; }
set
{
if(value != startWithGrid)
{ startWithGrid = value; dirty = true; }
}
}
/// <summary>
/// Determines if a display of failed folder accesses should be created or not
/// </summary>
public bool ShowUnauthorizedFolders
{
get { return showUnauthorizedFolders; }
set { showUnauthorizedFolders = value; }
}
/// <summary>
/// Determines if a display of reparse points should be created or not
/// </summary>
public bool ShowReparsePoints
{
get { return showReparsePoints; }
set { showReparsePoints = value; }
}
/// <summary>
/// Determines if hidden folders or files should be shown and searched
/// </summary>
public bool ShowHiddenFoldersFiles
{
get { return showHiddenFoldersFiles; }
set { showHiddenFoldersFiles = value; dirty = true; }
}
/// <summary>
/// Determines if DiskScan should use enumerator scanning or FileSystemInfo calls
/// </summary>
public bool ScanningViaEnumerator
{
get { return scanningViaEnumerator; }
set { scanningViaEnumerator = value; dirty = true; }
}
/// <summary>
/// Turns list view automatic scrolling on or off
/// Retrieves the current setting
/// </summary>
public bool AutoScrolling
{
get { return autoScrolling; }
set { autoScrolling = value; dirty = true; }
}
/// <summary>
/// Returns true if drive letters are to be returned from the Disk/Path selection form
/// Returns false if volume labels are being returned
/// </summary>
public bool ReturnDriveLetters
{
get { return returnDriveLetters; }
set { returnDriveLetters = value; dirty = true; }
}
/* obsolete starting in release 3.0.0.0
public ArrayList IgnoreFolders
{ //a set of folder nodes, drives or specific drive folder combinations to be excluded
//populated by the IgnoreFolders class
get { lock (syncobj) { return ignoreFolders; } }
set { lock (syncobj) { ignoreFolders = value; dirty = true; } }
}
* */
/// <summary>
/// font to use for forms and displays
/// selected via menu option
/// </summary>
public Font UseFont
{
get { lock (syncobj) { return usingFont; } }
set { lock (syncobj) { usingFont = value; dirty = true; } }
}
/// <summary>
/// Returns a reasonable list of folders that typically do not contain user files
/// and rarely need searching.
/// </summary>
public ArrayList DefaultFolders
{ //generate a default exclusion list
get
{
ArrayList defaultFolders = new ArrayList();
defaultFolders.Add("System Volume Information");
defaultFolders.Add("$Recycle.Bin");
defaultFolders.Add("RECYCLER"); //NTFS
defaultFolders.Add("RECYCLED"); //FAT
defaultFolders.Add("Program Files"); //found on 32 and 64 bit systems
defaultFolders.Add("Program Files (x86)"); //found on 64 bit systems
//Windows 7
defaultFolders.Add("WindowsImageBackup");
defaultFolders.Add("PerfLogs");
return defaultFolders;
}
}
#endregion Properties
#region GridColumnsInformation
/// <summary>
/// Returns a clone of the requested grid view information
/// or null if the grid view does not exist
/// </summary>
public GridInfoCollection GetGridView(string viewName)
{
GridInfoCollection gridInfo = null;
if (gridInfos.TryGetValue(viewName, out gridInfo))
return (GridInfoCollection)gridInfo.Clone();
return null;
}
/// <summary>
/// Adds or replaces a named grid view to the ConfigInfo
/// </summary>
/// <param name="gridInfo"></param>
public void StoreGridView(GridInfoCollection gridInfo)
{
dirty = true;
gridInfo.SortByDisplayOrder(); //sort is not required, it just makes it easier to read
if (gridInfos.ContainsKey(gridInfo.ViewName))
gridInfos[gridInfo.ViewName] = gridInfo; //The key was found; change its value.
else
gridInfos.Add(gridInfo.ViewName, gridInfo); //Grid view does not exit, add it.
}
/// <summary>
/// Remove a grid view
/// </summary>
/// <param name="viewName"></param>
public void RemoveGridView(string viewName)
{ gridInfos.Remove(viewName); dirty = true; }
public void RemoveGridView(GridInfoCollection gridInfo)
{ gridInfos.Remove(gridInfo.ViewName); dirty = true; }
/// <summary>
/// Remove all grid views
/// </summary>
public void ClearGridViews()
{ gridInfos.Clear(); }
#endregion GridColumnsInformation
#region Filter lists
/// <summary>
/// Returns or Sets the complete collection or filter lists
/// </summary>
public FilterListCollection MasterFilterListCollection
{
get { return filterLists; }
set { filterLists = value; }
}
/// <summary>
/// Returns or sets the active filter list
/// </summary>
public FilterList ActiveFilterList
{
get { return activeFilterList; }
set
{
activeFilterList = value;
if (null != activeFilterList)
{
try { filterLists.SetInUse(activeFilterList); }
catch { }
dirty = true;
}
}
}
/// <summary>
/// Returns the filter rules currently being used
/// </summary>
public static FilterRules GetFilterRules
{
get
{
if (null == activeFilterList) //if no filter rules exist, build an include all rule
return FilterRules.IncludeAllFilterRule;
//convert the active filter list into filter rules
FilterList activeClone = FilterList.ValidateFilterList(activeFilterList);
FilterRules filterRules = new FilterRules();
filterRules.PrepareRules(activeClone, true);
return filterRules;
}
}
#endregion Filter lists
#region Public functions
/// <summary>
/// Class constructor
/// On first use, initializes all the static fields to default values then loads
/// stored values from a prior execution.
/// </summary>
public ConfigInfo()
{
if (!alreadyInitialized)
{ //initialize all configuration data when first called
//perform the initializations outside the try statement as the try may fail
lock (syncobj)
{ //set default values
string myTrue = true.ToString();
alreadyInitialized = true;
filterLists = new FilterListCollection();
gridInfos = new Dictionary<string, GridInfoCollection>();
scanningViaEnumerator =
showHiddenFoldersFiles =
showUnauthorizedFolders =
showReparsePoints =
startWithGrid = false;
returnDriveLetters =
autoScrolling = true;
string mutexName = GetMutexName();
Mutex mutex = new Mutex(false, mutexName);
try
{
mutex.WaitOne(); //gain exclusive control
//read settings from the XML file saved after prior execution of this program
#if useIsolatedStorage
using (Stream isolatedStorageStream = new IsolatedStorageFileStream(CONFIGFILENAME,
FileMode.Open, IsolatedStorageFile.GetUserStoreForAssembly()))
#else
using (Stream isolatedStorageStream = new FileStream(CONFIGFILENAME, FileMode.Open))
#endif
{
XmlDocument xmldoc = new XmlDocument();
using (StreamReader ifs = new StreamReader(isolatedStorageStream))
{ xmldoc.Load(ifs); }
XmlNode listOrGrid = xmldoc.SelectSingleNode("FileFind/StartView");
if ((null != listOrGrid) && ("Grid" == listOrGrid.InnerText))
startWithGrid = true;
XmlNode showHidden = xmldoc.SelectSingleNode("FileFind/Hidden");
if ((null != showHidden) && (myTrue == showHidden.InnerText))
showHiddenFoldersFiles = true;
XmlNode scanning = xmldoc.SelectSingleNode("FileFind/ScanningViaEnumerator");
if ((null != scanning) && (myTrue == scanning.InnerText))
scanningViaEnumerator = true;
else
scanningViaEnumerator = false;
XmlNode autoScroll = xmldoc.SelectSingleNode("FileFind/AutoScroll");
if ((null != autoScroll) && (myTrue == autoScroll.InnerText))
autoScrolling = true;
else
autoScrolling = false;
XmlNode driveLetters = xmldoc.SelectSingleNode("FileFind/DriveLetters");
if ((null != driveLetters) && (myTrue == driveLetters.InnerText))
returnDriveLetters = true;
else
returnDriveLetters = false;
XmlNode filters = xmldoc.SelectSingleNode("FileFind/FilterListCollection");
if (null != filters)
{
try
{ //load the Xml to the filterLists collection
foreach (XmlNode xNode in filters)
{
FilterList filterList = new FilterList();
filterList.Name = xNode.NamespaceURI;
filterList.AllowDuplicates = (xNode.Attributes["AllowDuplicates"].Value.ToString() == myTrue);
filterList.CurrentlyInUse = (xNode.Attributes["CurrentlyInUse"].Value.ToString() == myTrue);
foreach (XmlNode yNode in xNode)
filterList.Add(new Filter(yNode.Attributes["Function"].Value.ToString(),
yNode.Attributes["Type"].Value.ToString(),
yNode.NamespaceURI));
filterLists.Add(filterList);
}
filterLists.IsDirty = false; //initial collection load completed
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString(),
Application.ProductName + " FilterListCollection",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
activeFilterList = filterLists.GetInUse;
}
else
{
XmlNode ignore = xmldoc.SelectSingleNode("FileFind/IgnoreFolders");
ArrayList ignoreFolders = new ArrayList(); //contains file and folder names to exclude when searching
//used to maintain backward compatibility for FileFind XML saved option files prior to release 3.0.0.0
if (null != ignore)
foreach (XmlNode xNode in ignore)
ignoreFolders.Add(xNode.InnerText);
else
ignoreFolders = DefaultFolders;
//convert ignorefolders to a FilterList
FilterList ignoreList = new FilterList();
ignoreList.Name = "Prior Excludes";
foreach (string exclude in ignoreFolders)
{
string str = exclude.Replace('/', '\\');
if ((str.Length > 3)
&& ((':' == str[1]) && ('\\' == str[2]) && (Char.IsLetter(str[0]))))
ignoreList.Add(new Filter(FilterList.FilterExclude, FilterList.FilterPath, str));
else if ((3 == str.Length)
&& ((':' == str[1]) && ('\\' == str[2]) && (Char.IsLetter(str[0]))))
ignoreList.Add(new Filter(FilterList.FilterExclude, FilterList.FilterDrive, str));
else
ignoreList.Add(new Filter(FilterList.FilterExclude, FilterList.FilterFolder, str));
}
filterLists.Add(ignoreList);
ActiveFilterList = ignoreList;
}
XmlNode gridViews = xmldoc.SelectSingleNode("FileFind/GridViews");
if (null != filters)
{
try
{ //load the Xml to the GridInfoCollection collection
foreach (XmlNode xNode in gridViews)
{
GridInfoCollection gridInfo = new GridInfoCollection();
gridInfo.ViewName = xNode.NamespaceURI;
foreach (XmlNode yNode in xNode)
{
string colName = yNode.Attributes["ColName"].Value.ToString();
bool menuVisible = (myTrue == yNode.Attributes["Visible"].Value.ToString());
string displayOrder = yNode.Attributes["DisplayOrder"].Value.ToString(CultureInfo.InvariantCulture);
int menuDisplayOrder = System.Convert.ToInt32(displayOrder, CultureInfo.InvariantCulture);
string width = yNode.Attributes["Width"].Value.ToString(CultureInfo.InvariantCulture);
int menuWidth = System.Convert.ToInt32(width, CultureInfo.InvariantCulture);
gridInfo.Add(new ColumnInfo(colName, menuVisible, menuDisplayOrder, menuWidth));
}
gridInfos.Add(gridInfo.ViewName, gridInfo);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString(),
Application.ProductName + " FilterListCollection",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
try
{
XmlNode useFont = xmldoc.SelectSingleNode("FileFind/UseFont");
if (null != usingFont)
{
XmlNode root;
root = xmldoc.SelectSingleNode("FileFind/UseFont/Name");
string fontName = root.InnerText;
root = xmldoc.SelectSingleNode("FileFind/UseFont/Size");
string swFont = root.InnerText;
float currentSize = System.Convert.ToSingle(swFont, CultureInfo.InvariantCulture);
FontStyle swStyle = new FontStyle();
root = xmldoc.SelectSingleNode("FileFind/UseFont/Bold");
if (myTrue == root.InnerText)
swStyle |= FontStyle.Bold;
root = xmldoc.SelectSingleNode("FileFind/UseFont/Italic");
if (myTrue == root.InnerText)
swStyle |= FontStyle.Italic;
root = xmldoc.SelectSingleNode("FileFind/UseFont/Strikeout");
if (myTrue == root.InnerText)
swStyle |= FontStyle.Strikeout;
root = xmldoc.SelectSingleNode("FileFind/UseFont/Underline");
if (myTrue == root.InnerText)
swStyle |= FontStyle.Underline;
usingFont = new Font(fontName, currentSize, swStyle);
}
}
catch (Exception xe)
{
MessageBox.Show(xe.InnerException.ToString(),
Application.ProductName + " UseFont",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
} //ends read settings from the XML file saved
catch (SecurityException se)
{
MessageBox.Show(se.Message,
Application.ProductName + " Config loading",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
catch { }
finally { mutex.ReleaseMutex(); }
ActiveFilterList = filterLists.GetInUse;
} //ends lock (syncobj)
} //ends if (!alreadyInitialized)
} //ends public ConfigInfo()
/// <summary>
/// Saves configuration values for the next execution of the application
/// </summary>
public void SaveConfig()
{ //XML Create (creates an XML file via native calls)
if((dirty) && (!removedSavedOptions))
lock (syncobj)
{
string mutexName = GetMutexName();
Mutex mutex = new Mutex(false, mutexName);
try
{
mutex.WaitOne(); //gain exclusive control
#if useIsolatedStorage
using (Stream isolatedStorageStream =
new IsolatedStorageFileStream(CONFIGFILENAME, FileMode.Create, IsolatedStorageFile.GetUserStoreForAssembly()))
#else
using (Stream isolatedStorageStream = new FileStream(CONFIGFILENAME, FileMode.Create))
#endif
using(XmlTextWriter appconfig = new XmlTextWriter(isolatedStorageStream, Encoding.UTF8))
{
appconfig.Formatting = Formatting.Indented;
appconfig.WriteStartDocument();
DateTime newDate = DateTime.Now;
appconfig.WriteComment("Created " + newDate.ToString(CultureInfo.InvariantCulture));
appconfig.WriteStartElement("FileFind");
appconfig.WriteCData(@"<>\&");
if (startWithGrid)
appconfig.WriteElementString("StartView", "Grid");
else
appconfig.WriteElementString("StartView", "List");
appconfig.WriteElementString("Hidden", showHiddenFoldersFiles.ToString());
appconfig.WriteElementString("ScanningViaEnumerator", scanningViaEnumerator.ToString());
appconfig.WriteElementString("AutoScroll", autoScrolling.ToString());
appconfig.WriteElementString("DriveLetters", returnDriveLetters.ToString());
if (filterLists != null && filterLists.Count > 0)
filterLists.Export(appconfig); //store all filter lists
if (0 != gridInfos.Count)
{
appconfig.WriteStartElement("GridViews");
foreach (KeyValuePair<string, GridInfoCollection> kvp in gridInfos)
{ //record each FilterList
GridInfoCollection gridInfo = kvp.Value;
appconfig.WriteStartElement("GridView", gridInfo.ViewName);
foreach (ColumnInfo columnInfo in gridInfo)
{
appconfig.WriteStartElement("GridColumn");
appconfig.WriteAttributeString("ColName", columnInfo.ColumnName);
appconfig.WriteAttributeString("Visible", columnInfo.Visible.ToString());
appconfig.WriteAttributeString("DisplayOrder", columnInfo.DisplayOrder.ToString(CultureInfo.InvariantCulture));
appconfig.WriteAttributeString("Width", columnInfo.Width.ToString(CultureInfo.InvariantCulture));
appconfig.WriteEndElement(); //ends ColumnInfo
}
appconfig.WriteEndElement(); //ends GridView
}
appconfig.WriteEndElement(); //ends gridInfos
}
if (null != usingFont)
{
appconfig.WriteStartElement("UseFont");
appconfig.WriteElementString("Name", usingFont.Name.ToString());
appconfig.WriteElementString("Style", usingFont.Style.ToString());
appconfig.WriteElementString("Size", usingFont.Size.ToString(CultureInfo.InvariantCulture));
appconfig.WriteElementString("Bold", usingFont.Bold.ToString());
appconfig.WriteElementString("Italic", usingFont.Italic.ToString());
appconfig.WriteElementString("Strikeout", usingFont.Strikeout.ToString());
appconfig.WriteElementString("Underline", usingFont.Underline.ToString());
appconfig.WriteEndElement(); //ends UseFont
}
appconfig.WriteEndDocument();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n" + ex.InnerException,
Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
finally { mutex.ReleaseMutex(); }
} //ends lock (syncobj)
} //ends public void SaveConfig()
/// <summary>
/// Show all ready disks as selected except explicitly excluded disks (via Disk selection form).
/// Returns an ArrayList of selected disks and a count of selected disks.
/// If the count is -1 then all ready disks have been selected.
/// </summary>
/// <param name="diskCount">returns number of drives selected</param>
/// <returns>names of selected drives</returns>
public ArrayList SelectAllDisks(out int diskCount)
{
ArrayList selected = new ArrayList();
diskCount = 0;
DriveInfo[] allDrives = null;
try { allDrives = DriveInfo.GetDrives(); }
catch (Exception ex)
{
MessageBox.Show(ex.Message,
Application.ProductName + " ConfigInfo.SelectAllDisks",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
allDrives = null;
}
FilterRules localFilterRules = GetFilterRules;
if (allDrives != null)
{
int readyDrives = 0;
foreach (DriveInfo drive in allDrives)
{ //show only available drives
if (drive.IsReady)
{
++readyDrives;
if (localFilterRules.SearchAnyPath(drive.Name))
selected.Add(drive.Name);
}
}
diskCount = selected.Count;
if (diskCount == readyDrives)
diskCount = -1; //all drives selected
}
return selected;
} //ends public ArrayList SelectAllDisks(...
public ArrayList FilterSelectedDisks(ArrayList currentlySelected)
{ //show all disks as selected except explicitly excluded disks
//returns an ArrayList of selected disks and a count of selected disks
//if the count is -1 then all disks have been selected
FilterRules localFilterRules = GetFilterRules;
ArrayList selected = new ArrayList();
foreach (string selectedDrive in currentlySelected)
{//show drives available
DriveInfo drive = new DriveInfo(selectedDrive);
if ((drive.IsReady)
&& (localFilterRules.SearchThisPath(new DirectoryInfo(drive.Name))))
selected.Add(drive.Name);
}
return selected;
} //ends public ArrayList FilterSelectedDisks(...
public void RemoveIsolatedStorage()
{
removedSavedOptions = true;
try
{
#if useIsolatedStorage
IsolatedStorageFile isoFile = IsolatedStorageFile.GetStore(IsolatedStorageScope.User |
IsolatedStorageScope.Assembly,
typeof(System.Security.Policy.Url),
typeof(System.Security.Policy.Url));
String[] fileNames = isoFile.GetFileNames(CONFIGFILENAME);
foreach (string fileName in fileNames)
{
// Delete the files.
isoFile.DeleteFile(fileName);
}
#else
File.Delete(CONFIGFILENAME);
#endif
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,
Application.ProductName + " Isolated storage / file delete",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
} //ends public RemoveIsolatedStorage()
#endregion Public functions
#region Private functions
private string GetMutexName()
{ return Path.GetPathRoot(Environment.CurrentDirectory).Replace("\\", "_").Replace("/", "_") + "FileFindMutex"; }
#endregion Private functions
}
}