using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
// cBookStore provides a persistant storage for the player attributes.
// This class uses the system regigistry to store the information.
// storage is placed in HKEY_CURRENT_USER under a Subkey with the exe name (abPlayer).
// the root key stores one string value with the active book name, and
// one string value that stores the last skin name.
// under the root key there are 2 subkeys:
// "BOOKS" stores the books and "BOOKSHELVES" stores book names which
// do not reside on a bookshlef and a subkey for each bookshelf under
// which string values designate the books on this bookshelf
// for each book there's a subkey with its name. under the book key
// there are 4 integer values: file index (BookMarkEntry), timeline marker
// (BookMarkLocation), Shuffle flag, and volume percentage.
// there is also a sub key 'FILES' under which all the file paths are stored.
public class cRegistryPersistancy : cBasePersistancy
{
// constants for key and value names used
private String ROOT_KEY = "";
private const String BOOKS_KEY = "Books";
private const String BOOKSHELVES_KEY = "Bookshelves";
private const String FILES = "Files";
private String ACTIVE_BOOK = "ActiveBook";
private const String SKIN = "Skin";
private String[] sBookProperty = {"BookMarkEntry",
"BookMarkLocation",
"Volume",
"Shuffle"};
// keys that stay open during the whole class life cycle
private RegistryKey RootKey = null;
private RegistryKey ActiveBook = null;
private RegistryKey BooksKey = null;
private RegistryKey BookshelvesKey = null;
public cRegistryPersistancy(String assembly)
{
ROOT_KEY = assembly;
RootKey = Registry.CurrentUser.OpenSubKey(ROOT_KEY, true);
if (RootKey == null)
RootKey = Registry.CurrentUser.CreateSubKey(ROOT_KEY);
// open 2 subkeys. if not found create them
BooksKey = RootKey.OpenSubKey(BOOKS_KEY, true);
if (BooksKey == null)
BooksKey = RootKey.CreateSubKey(BOOKS_KEY);
BookshelvesKey = RootKey.OpenSubKey(BOOKSHELVES_KEY, true);
if (BookshelvesKey == null)
BookshelvesKey = RootKey.CreateSubKey(BOOKSHELVES_KEY);
// if active book value exits - open active book key
String activeBookName = (String)RootKey.GetValue(ACTIVE_BOOK, "");
if (activeBookName.Length > 0)
{
try
{
ActiveBook = BooksKey.OpenSubKey(activeBookName, true);
if (ActiveBook == null)
throw new Exception();
}
catch{MessageBox.Show("Active Book Key Missing");}
}
}
// destructor - close any open keys
~cRegistryPersistancy()
{
try
{
if (RootKey != null)
RootKey.Close();
if (BooksKey != null)
BooksKey.Close();
if (BookshelvesKey != null)
BookshelvesKey.Close();
if (ActiveBook != null)
ActiveBook.Close();
}
catch { };
}
// get all books
public override String[] Books
{
get
{
String[] bs = BooksKey.GetSubKeyNames();
Array.Sort(bs);
return bs;
}
}
// get all books on (in) a bookshelf
// get all bookshelves
public override String[] Bookshelves
{
get
{
String[] bs = BookshelvesKey.GetSubKeyNames();
Array.Sort(bs);
return bs;
}
}
// get all books on (in) a bookshelf
public override String[] GetBookshelfBooks(String bookshelf)
{
RegistryKey rk = null;
try
{
String[] books = null;
if (bookshelf.Length == 0)
books = BookshelvesKey.GetValueNames();
else
{
rk = BookshelvesKey.OpenSubKey(bookshelf);
books = rk.GetValueNames();
}
Array.Sort(books);
return books;
}
catch
{
return new String[0];
}
finally
{
if(rk != null) rk.Close();
}
}
// get a book's bookshelf
public override String GetBooksBookshelf(String book)
{
if (book.Length <= 0)
return "";
if (((String)BookshelvesKey.GetValue(book, "not found")).Length == 0)
return "";
foreach (String bookshelf in BookshelvesKey.GetSubKeyNames())
{
RegistryKey rk = null;
try
{
rk = BookshelvesKey.OpenSubKey(bookshelf);
if (((String)rk.GetValue(book, "not found")).Length == 0)
return bookshelf;
}
catch
{
return "";
}
finally
{
if(rk != null) rk.Close();
}
}
return "";
}
// create new bookshelf
public override bool NewBookshelf(String bookshelf)
{
RegistryKey rk = BookshelvesKey.CreateSubKey(bookshelf);
rk.Close();
return true;
}
// delete a bookshelf
public override bool DeleteBookshelf(String bookshelf)
{
RegistryKey rk = null;
try
{
rk = BookshelvesKey.OpenSubKey(bookshelf);
// move all books in the bookshelf to the root node
foreach (String book in rk.GetValueNames())
BookshelvesKey.SetValue(book, "");
BookshelvesKey.DeleteSubKeyTree(bookshelf);
return true;
}
catch { MessageBox.Show("Delete Bookshelf Failed"); }
finally
{
if(rk != null) rk.Close();
}
return false;
}
// set/change a book's bookshelf
public override bool SetBooksBookshelf(String book, String newBookshelf)
{
RegistryKey rk1 = null;
RegistryKey rk2 = null;
try
{
// remove from old place
String oldBookshelf = GetBooksBookshelf(book);
if (oldBookshelf.Length == 0)
{
BookshelvesKey.DeleteValue(book);
}
else
{
rk1 = BookshelvesKey.OpenSubKey(oldBookshelf, true);
rk1.DeleteValue(book);
}
// put in new place
if (newBookshelf.Length == 0)
{
BookshelvesKey.SetValue(book, "");
}
else
{
rk2 = BookshelvesKey.OpenSubKey(newBookshelf, true);
rk2.SetValue(book, "");
}
return true;
}
catch { MessageBox.Show("Setting a Book's Bookshelf Failed"); }
finally
{
if (rk1 != null) rk1.Close();
if (rk2 != null) rk2.Close();
}
return false;
}
// get/set skin
public override String Skin
{
get
{
return (String)RootKey.GetValue(SKIN, "");
}
set
{
RootKey.SetValue(SKIN, value, RegistryValueKind.String);
}
}
// get/set active book name
public override String ActiveBookName
{
get
{
if (ActiveBook == null)
return "";
else
return ActiveBook.Name.Substring(ActiveBook.Name.LastIndexOf("\\") + 1);
}
set
{
// if we have an active book key - close
if (ActiveBook != null)
{
ActiveBook.Close();
ActiveBook = null;
}
// set new active book in registry
RootKey.SetValue(ACTIVE_BOOK, value, RegistryValueKind.String);
if (value != "")
{
// if not empty - open the active book key
try
{
ActiveBook = BooksKey.OpenSubKey(value, true);
if (ActiveBook == null)
throw new Exception();
}
catch { MessageBox.Show("Active Book Key Missing"); }
}
}
}
// create new book
public override bool NewBook(String book, String bookshelf)
{
RegistryKey rk1 = null;
RegistryKey rk2 = null;
RegistryKey srk = null;
try
{
if (bookshelf.Length == 0)
BookshelvesKey.SetValue(book, "");
else
{
rk1 = BookshelvesKey.OpenSubKey(bookshelf, true);
rk1.SetValue(book, "");
}
// create the book subkey
rk2 = BooksKey.CreateSubKey(book);
// set default values
rk2.SetValue(sBookProperty[(int)eBookProperty.BOOKMARK_LOCATION], 0, RegistryValueKind.DWord);
rk2.SetValue(sBookProperty[(int)eBookProperty.BOOKMARK_ENTRY], 0, RegistryValueKind.DWord);
rk2.SetValue(sBookProperty[(int)eBookProperty.VOLUME], 40, RegistryValueKind.DWord);
rk2.SetValue(sBookProperty[(int)eBookProperty.SHUFFLE], 0, RegistryValueKind.DWord);
// create files place holder
srk = rk2.CreateSubKey(FILES);
return true;
}
catch { MessageBox.Show("Failed to Create Key/Subkey"); }
finally
{
if (rk1 != null) rk1.Close();
if(srk != null) srk.Close();
if(rk2 != null) rk2.Close();
}
return false;
}
// set a book property
public override bool SetBookProperty(eBookProperty prop, int value, String book)
{
// if aimed at active book, but no active book - give up
if ((book == "") && (ActiveBookName == "")) return false;
RegistryKey rk = null;
try
{
if (book == "")
ActiveBook.SetValue(sBookProperty[(int)prop], value, RegistryValueKind.DWord);
else
{
rk = BooksKey.OpenSubKey(book, true);
rk.SetValue(sBookProperty[(int)prop], value, RegistryValueKind.DWord);
}
return true;
}
catch { MessageBox.Show("Book Key Missing"); }
finally
{
if(rk != null) rk.Close();
}
return false;
}
// get book poperty
public override int GetBookProperty(eBookProperty prop, String book)
{
if ((book == "") && (ActiveBookName == "")) return 0;
RegistryKey rk = null;
try
{
if (book == "")
return (int)ActiveBook.GetValue(sBookProperty[(int)prop], 0);
else
{
rk = BooksKey.OpenSubKey(book, true);
int n = (int)rk.GetValue(sBookProperty[(int)prop], 0);
return n;
}
}
catch
{
MessageBox.Show("Book Key Missing");
return 0;
}
finally
{
if(rk != null) rk.Close();
}
}
// set the book files -
// we always add the files to existing ones.
public override bool SetBookFiles(String[] newFiles, String book)
{
RegistryKey rk = null;
RegistryKey mrk = null;
try
{
if ((book == "") && (ActiveBookName == "")) return false;
// get existing files
String[] oldFiles = GetBookFiles(book);
// delete files by deleting the 'FILES' subkey, then
// recreate it
if (book == "")
{
ActiveBook.DeleteSubKeyTree(FILES);
rk = ActiveBook.CreateSubKey(FILES);
}
else
{
mrk = BooksKey.OpenSubKey(book, true);
mrk.DeleteSubKeyTree(FILES);
rk = mrk.CreateSubKey(FILES);
}
// write old & new files.
// create a string from the file index as a value name
// to preserve sort order
int len = (oldFiles.GetLength(0) + newFiles.GetLength(0)).ToString().Length;
int i = 0;
foreach (String file in oldFiles)
{
String name = i.ToString();
while (name.Length < len)
name = "0" + name;
rk.SetValue(name, file, RegistryValueKind.String);
i++;
}
foreach (String file in newFiles)
{
String name = i.ToString();
while (name.Length < len)
name = "0" + name;
rk.SetValue(name, file, RegistryValueKind.String);
i++;
}
return true;
}
catch { MessageBox.Show("Registering Playlist Failed"); }
finally
{
if (rk != null) rk.Close();
if (mrk != null) mrk.Close();
}
return false;
}
// get book file count = value count under the 'FILES' key
public override int GetBookFileCount(String book)
{
if ((book == "") && (ActiveBookName == "")) return 0;
RegistryKey rk = null;
RegistryKey mrk = null;
int count = 0;
try
{
if (book == "")
{
rk = ActiveBook.OpenSubKey(FILES, true);
}
else
{
mrk = BooksKey.OpenSubKey(book, true);
rk = mrk.OpenSubKey(FILES, true);
}
count = rk.ValueCount;
}
catch { MessageBox.Show("Key/Subkey Missing"); }
finally
{
if (rk != null) rk.Close();
if (mrk != null) mrk.Close();
}
return count;
}
// delete a file entry
public override bool DeleteBookFile(int ix, String book)
{
if ((book == "") && (ActiveBookName == "")) return false;
if((ix < 0) || (ix > (GetBookFileCount(book) - 1))) return false;
ArrayList files = new ArrayList();
files.AddRange(GetBookFiles(book));
files.RemoveAt(ix);
RegistryKey rk = null;
RegistryKey mrk = null;
try
{
if (book == "")
{
ActiveBook.DeleteSubKeyTree(FILES);
rk = ActiveBook.CreateSubKey(FILES);
}
else
{
mrk = BooksKey.OpenSubKey(book, true);
mrk.DeleteSubKeyTree(FILES);
rk = mrk.CreateSubKey(FILES);
}
SetBookFiles((String[])files.ToArray(typeof(String)), book);
return true;
}
catch { MessageBox.Show("Delete File Failed"); }
finally
{
if (rk != null) rk.Close();
if (mrk != null) mrk.Close();
}
return false;
}
// delete all book file entries
public override bool DeleteBookFiles(String book)
{
if ((book == "") && (ActiveBookName == "")) return false;
RegistryKey rk = null;
RegistryKey mrk = null;
try
{
if (book == "")
{
ActiveBook.DeleteSubKeyTree(FILES);
rk = ActiveBook.CreateSubKey(FILES);
}
else
{
mrk = BooksKey.OpenSubKey(book, true);
mrk.DeleteSubKeyTree(FILES);
rk = mrk.CreateSubKey(FILES);
}
return true;
}
catch { MessageBox.Show("Delete All Files Failed"); }
finally
{
if (rk != null) rk.Close();
if (mrk != null) mrk.Close();
}
return false;
}
// get book files - values under the 'FILES' key
public override String[] GetBookFiles(String book)
{
RegistryKey rk = null;
RegistryKey mrk = null;
try
{
String[] names, files;
if ((book == "") && (ActiveBookName == "")) return new String[0];
if (book == "")
{
rk = ActiveBook.OpenSubKey(FILES, true);
}
else
{
mrk = BooksKey.OpenSubKey(book, true);
rk = mrk.OpenSubKey(FILES, true);
}
names = rk.GetValueNames();
Array.Sort(names);
files = new String[names.GetLength(0)];
for (int i = 0; i < names.GetLength(0); i++)
files[i] = (String)rk.GetValue(names[i], "");
return files;
}
catch
{
MessageBox.Show("Key/Subkey Missing");
return new string[0];
}
finally
{
if (rk != null) rk.Close();
if (mrk != null) mrk.Close();
}
}
// rename a bookshelf
// no rename subkey so - create the new, move everything from old
// to new then remove old
public override bool RenameBookShelf(String newName, String bookshelf)
{
RegistryKey rko = null;
RegistryKey rkn = null;
try
{
rko = BookshelvesKey.OpenSubKey(bookshelf);
rkn = BookshelvesKey.CreateSubKey(newName);
foreach (String book in rko.GetValueNames())
rkn.SetValue(book, "");
BookshelvesKey.DeleteSubKeyTree(bookshelf);
return true;
}
catch { MessageBox.Show("Rename Bookshelf Failed"); }
finally
{
if (rko != null) rko.Close();
if (rkn != null) rkn.Close();
}
return false;
}
// rename book - since there is no key rename (couldn't find one) -
// we create the new book name, copy everything from old
// to new then remove the old
public override bool RenameBook(String newName, String book)
{
if (book == "") return false;
try
{
String[] files = GetBookFiles(book);
String bookshelf = GetBooksBookshelf(book);
int[] attr = new int[4];
for (int i = 0; i < attr.Length; i++)
attr[i] = GetBookProperty((eBookProperty)i, book);
DeleteBook(book);
NewBook(newName, bookshelf);
SetBookFiles(files, newName);
for (int i = 0; i < attr.Length; i++)
SetBookProperty((eBookProperty)i, attr[i], newName);
if (ActiveBookName == book)
ActiveBookName = newName;
return true;
}
catch { MessageBox.Show("Failed to Rename Book"); }
return false;
}
// delete a book.
public override bool DeleteBook(String book)
{
if (book == "") return false;
// if active book is deleted - no active book anymore
if (ActiveBookName == book)
ActiveBookName = "";
RegistryKey rk = null;
try
{
// remove from bookshelf subkey
String bookshelf = GetBooksBookshelf(book);
if (bookshelf.Length == 0)
BookshelvesKey.DeleteValue(book);
else
{
rk = BookshelvesKey.OpenSubKey(bookshelf, true);
rk.DeleteValue(book);
}
BooksKey.DeleteSubKeyTree(book);
return true;
}
catch { MessageBox.Show("Delete Key Failed"); }
finally
{
if (rk != null) rk.Close();
}
return false;
}
}