ObjectToken.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Speech / Src / Internal / ObjectToken / ObjectToken.cs / 1 / ObjectToken.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: 
//		Object Token
// 
// History:
//		7/1/2004	jeanfp		
//---------------------------------------------------------------------------
 
using Microsoft.Win32;
using System; 
using System.Collections.Generic; 
using System.Globalization;
using System.Diagnostics; 
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text; 
using System.Threading;
 
using RegistryEntry = System.Collections.Generic.KeyValuePair; 

namespace System.Speech.Internal.ObjectTokens 
{
    /// 
    /// Summary description for ObjectToken.
    ///  
#if VSCOMPILE
    [DebuggerDisplay ("{Name}")] 
#endif 
    internal class ObjectToken : RegistryDataKey, ISpObjectToken
#if SPEECHSERVER 
        ,ISpObjectTokenMss
#endif
    {
        //******************************************************************* 
        //
        // Constructors 
        // 
        //*******************************************************************
 
        #region Constructors

        protected ObjectToken (string keyId, RegistryKey hkey)
            : base (keyId, hkey) 
        {
        } 
 
        internal static RegistryKey CreateKey (string sCategoryId, string sTokenId, bool fCreateIfNotExist, out string id)
        { 
            id = null;
            RegistryKey hkey = null;

            if (ParseRegistryString (sCategoryId, sTokenId)) 
            {
                hkey = RegistryDataKey.CreateKey (sTokenId, fCreateIfNotExist, out id); 
            } 
            return hkey;
        } 

        internal static ObjectToken Create (string sCategoryId, string sTokenId, bool fCreateIfNotExist)
        {
            string id; 
            RegistryKey hkey = CreateKey (sTokenId, fCreateIfNotExist, out id);
            if (hkey != null) 
            { 
                return new ObjectToken (id, hkey);
            } 
            return null;
        }

        #endregion 

        //******************************************************************** 
        // 
        // Public Methods
        // 
        //*******************************************************************

        #region public Methods
 
        /// 
        /// Tests whether two AutomationIdentifier objects are equivalent 
        ///  
        public override bool Equals (object obj)
        { 
            ObjectToken token = obj as ObjectToken;
            return token != null && string.Compare (Id, token.Id, StringComparison.OrdinalIgnoreCase) == 0;
        }
 
        /// 
        /// Overrides Object.GetHashCode() 
        ///  
        public override int GetHashCode ()
        { 
            return Id.GetHashCode ();
        }

        #endregion 

        //******************************************************************** 
        // 
        // Internal Properties
        // 
        //********************************************************************

        #region Internal Properties
 
        internal RegistryDataKey Attributes
        { 
            get 
            {
                return _attributes != null ? _attributes : (_attributes = OpenKey ("Attributes")); 
            }
        }

        ///  
        /// Returns the Name for the voice
        /// Look first in the Name attribute, if not available then get the default string 
        ///  
        /// 
        internal string TokenName () 
        {
            string name = string.Empty;
            if (Attributes != null)
            { 
                Attributes.TryGetString ("Name", out name);
 
                if (string.IsNullOrEmpty (name)) 
                {
                    TryGetString (null, out name); 
                }
            }
            return name;
        } 

        ///  
        /// Returns the Culture defined in the Language field for a token 
        /// 
        ///  
        internal CultureInfo Culture
        {
            get
            { 
                CultureInfo culture = null;
                string langId; 
                if (Attributes.TryGetString ("Language", out langId)) 
                {
                    culture = SapiAttributeParser.GetCultureInfoFromLanguageString (langId); 
                }
                return culture;
            }
        } 

        ///  
        /// Returns the Culture defined in the Language field for a token 
        /// 
        ///  
        internal string Description
        {
            get
            { 
                string description = string.Empty;
                string sCultureId = string.Format (CultureInfo.InvariantCulture, "{0:x}", CultureInfo.CurrentUICulture.LCID); 
 
                if (!TryGetString (sCultureId, out description))
                { 
                    TryGetString (null, out description);
                }
                return description;
            } 
        }
 
        #endregion 

        //******************************************************************* 
        //
        // Internal Methods
        //
        //******************************************************************** 

        #region internal Methods 
 
        #region ISpObjectToken Implementation
 
        public void SetId ([MarshalAs (UnmanagedType.LPWStr)] string pszCategoryId, [MarshalAs (UnmanagedType.LPWStr)] string pszTokenId, [MarshalAs (UnmanagedType.Bool)] bool fCreateIfNotExist)
        {
            throw new NotImplementedException ();
        } 

        public void GetId ([MarshalAs (UnmanagedType.LPWStr)] out IntPtr ppszCoMemTokenId) 
        { 
            ppszCoMemTokenId = Marshal.StringToCoTaskMemUni (Id);
        } 

        public void Slot15 () { throw new NotImplementedException (); } // void GetCategory(out ISpObjectTokenCategory ppTokenCategory);
        public void Slot16 () { throw new NotImplementedException (); } // void CreateInstance(object pUnkOuter, UInt32 dwClsContext, ref Guid riid, ref IntPtr ppvObject);
        public void Slot17 () { throw new NotImplementedException (); } // void GetStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszValueName, [MarshalAs(UnmanagedType.LPWStr)] string pszFileNameSpecifier, UInt32 nFolder, [MarshalAs(UnmanagedType.LPWStr)] out string ppszFilePath); 
        public void Slot18 () { throw new NotImplementedException (); } // void RemoveStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszKeyName, int fDeleteFile);
        public void Slot19 () { throw new NotImplementedException (); } // void Remove(ref Guid pclsidCaller); 
        public void Slot20 () { throw new NotImplementedException (); } // void IsUISupported([MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject, ref Int32 pfSupported); 
        public void Slot21 () { throw new NotImplementedException (); } // void DisplayUI(UInt32 hWndParent, [MarshalAs(UnmanagedType.LPWStr)] string pszTitle, [MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject);
        public void MatchesAttributes ([MarshalAs (UnmanagedType.LPWStr)] string pszAttributes, [MarshalAs (UnmanagedType.Bool)] out bool pfMatches) { throw new NotImplementedException (); } 

        #endregion

        ///  
        /// Check if the token supports the attributes list given in. The
        /// attributes list has the same format as the required attributes given to 
        /// SpEnumTokens. 
        /// 
        ///  
        /// 
        internal bool MatchesAttributes (string [] sAttributes)
        {
            bool fMatch = true; 

            for (int iAttribute = 0; iAttribute < sAttributes.Length; iAttribute++) 
            { 
                string s = sAttributes [iAttribute];
                fMatch &= HasValue (s) || (Attributes != null && Attributes.HasValue (s)); 
                if (!fMatch)
                {
                    break;
                } 
            }
            return fMatch; 
        } 

#if false 

        /// 
        ///
        ///  
        /// 
        ///  
        ///  
        internal static ObjectTokenCategory CategoryFromId (string sCategoryId, bool fCreateIfNotExist)
        { 
            return new ObjectTokenCategory (sCategoryId, fCreateIfNotExist);
        }

        ///  
        /// Remove the specified storage file name and optionally delete the file
        ///  
        ///  
        /// 
        ///  
        internal void RemoveStorageFileName (Guid clsidCaller, string sValueName, bool fDeleteFile)
        {
            // SPDBG_FUNC("CSpObjectToken::RemoveStorageFileName");
 
            ObjectToken cpDataKey = OpenFilesKey (clsidCaller, false);
            if (fDeleteFile) 
            { 
                DeleteFileFromKey (cpDataKey, sValueName);
            } 
            cpDataKey.DeleteValue (sValueName);
        }

        ///  
        /// Get a filename which can be manipulated by this token. Storage files will
        /// be deleted on a Remove call. 
        /// clsidCaller - a key will be made in registry below the token with this name and files key beneath that. 
        /// sValueName - Value name which will be made in registry to store the file path string.
        /// sFileSpecifier - either null or a path/filename for storage file: 
        ///     - if this starts with 'X:\' or '\\' then is assumed to be a full path.
        ///     - otherwise is assumed to be relative to special folders given in the nFolder parameter.
        ///     - if ends with a '\', or is null a unique filename will be created.
        ///     - if the name contains a %d the %d is replaced by a number to give a unique filename. 
        ///     - intermediate directories are created.
        ///     - if a relative file is being used the value stored in the registry includes 
        ///         the nFolder value as %nFolder% before the rest of the path. This allows 
        ///         roaming to work properly if you pick an nFolder value representing a raoming folder
        /// nFolder - equivalent to the value given to SHGetFolderPath in the Shell API. 
        /// ppszFilePath - CoTaskMemAlloc'd returned file path.
        ///
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        internal string GetStorageFileName (Guid clsidCaller, string sValueName, string sFileSpecifier, Environment.SpecialFolder nFolder, bool fCreate) 
        {
            string ppszFilePath = null;

            // SPDBG_FUNC("CSpObjectToken::GetStorageFileName"); 

            // See if there is already a Files key in the registry for this token 
            ObjectToken cpFilesKey = OpenFilesKey (clsidCaller, (int) nFolder != 0); 

            string dstrFilePath;  // Path to the file which we return to user. 
            string dstrRegPath;   // Path to the string which will be stored in the registry.

            // See if the key we are looking for is present
            cpFilesKey.TryGetString (sValueName, out dstrRegPath); 
#if _WIN32_WCE
            if (hr == SPERR_NOT_FOUND && nFolder) 
#else 
            if (fCreate && dstrRegPath != null)
#endif //_WIN32_WCE 
            {
                // Didn't find the key and want to create

                // Calculate the new file path and key value 
                FileSpecifierToRegPath (sFileSpecifier, nFolder, out dstrFilePath, out dstrRegPath);
                // Set the key value 
                cpFilesKey.SetString (sValueName, dstrRegPath); 
            }
            else 
            {
                // Found existing entry so convert and return
                RegPathToFilePath (dstrRegPath, out dstrFilePath);
            } 
            ppszFilePath = dstrFilePath;
 
            return ppszFilePath; 
        }
 
        /// 
        /// Determine if the specific type of UI is supported or not
        /// 
        ///  
        /// 
        internal bool IsUISupported (string sTypeOfUI /*, object pvExtraData, int cbExtraData*/) 
        { 
            // SPDBG_FUNC("CSpObjectToken::IsUISupported");
 
#if false
 	if (m_cpTokenDelegate != null)
	{
		// NTRAID#SPEECH-7392-2000/08/31-robch: Maybe we should first delegate, and if that doesn't work, 
		// try this token's category ui...
 		m_cpTokenDelegate.IsUISupported( 
					pszTypeOfUI, 
 					pvExtraData,
 					cbExtraData, 
					pfSupported);
 	}
	else
	{ 
            /*Guid clsidObject = */
            GetUIObjectClsid (sTypeOfUI); 
 
		ISpTokenUI cpTokenUI = cpTokenUI.CoCreateInstance(clsidObject);
 
 		pfSupported = cpTokenUI.IsUISupported(sTypeOfUI, pvExtraData, cbExtraData, punkObject);
#endif
            //
            throw new NotImplementedException (); 
            //return pfSupported;
        } 
 
        /// 
        /// Remove either a specified caller's section of the token, or the 
        /// entire token. We remove the entire token if pclsidCaller == null.
        /// 
        /// 
        internal void Remove (Guid pclsidCaller) 
        {
            // SPDBG_FUNC("CSpObjectToken::Remove"); 
 
            // Remove all the filenames
            RemoveAllStorageFileNames (pclsidCaller); 

            // Now go ahead and delete the registry entry which is either
            // the token itself (if pclsidCaller == null) or the clsid's
            // sub key 
            if (pclsidCaller == Guid.Empty)
            { 
                RegistryDataKey.DeleteRegistryPath (Id, null); 
            }
            else 
            {
                //
                throw new NotImplementedException ();
                //					string szClsid; //[MAX_PATH]; 
                //					StringFromGUID2(pclsidCaller, szClsid, sp_countof(szClsid));
                //					RegistryDataKey.SpDeleteRegPath(_dstrTokenId, szClsid); 
            } 
        }
 
#endif
        internal T CreateObjectFromToken (string name)
        {
            T instanceValue = default (T); 
            string clsid;
 
            if (!TryGetString (name, out clsid)) 
            {
                throw new ArgumentException (SR.Get (SRID.TokenCannotCreateInstance)); 
            }

            try
            { 
                // Application Class Id
                Type type = Type.GetTypeFromCLSID (new Guid (clsid)); 
 
                // Create the object instance
                instanceValue = (T) Activator.CreateInstance (type); 

                // Initialize the instance
                ISpObjectWithToken objectWithToken = instanceValue as ISpObjectWithToken;
                if (objectWithToken != null) 
                {
                    //IntPtr ite = Marshal.GetComInterfaceForObject (this, typeof (ISpObjectToken2)); 
                    int hresult = objectWithToken.SetObjectToken ((ISpObjectToken) this); 
                    if (hresult < 0)
                    { 
                        throw new ArgumentException (SR.Get (SRID.TokenCannotCreateInstance));
                    }
                }
#if SPEECHSERVER 
                else
                { 
                    // For MSS - we should try the new MSS interface (with new GUID). 
                    ISpObjectWithTokenMss objectWithTokenMss = instanceValue as ISpObjectWithTokenMss;
                    if (objectWithTokenMss != null) 
                    {
                        objectWithTokenMss.SetObjectToken((ISpObjectTokenMss)this);
                    }
                } 
#endif
            } 
            catch (Exception e) 
            {
                //wow I am not really sure we want to do this here.... 
                if (e is MissingMethodException || e is TypeLoadException || e is FileLoadException || e is FileNotFoundException || e is MethodAccessException || e is MemberAccessException || e is TargetInvocationException || e is InvalidComObjectException || e is NotSupportedException || e is FormatException)
                {
                    throw new ArgumentException (SR.Get (SRID.TokenCannotCreateInstance));
                } 
                throw;
            } 
            return instanceValue; 
        }
 
        #endregion

        //*******************************************************************
        // 
        // Protected Methods
        // 
        //******************************************************************* 

        #region Protected Methods 

        protected override void Dispose (bool disposing)
        {
            try 
            {
                if (disposing && _attributes != null) 
                { 
                    _attributes.Dispose ();
                    _attributes = null; 
                }
            }
            finally
            { 
                base.Dispose (disposing);
            } 
        } 

        #endregion 

        //*******************************************************************
        //
        // Private Methods 
        //
        //******************************************************************** 
 
        #region private Methods
 
#if false

        /// 
        /// Given a path and file specifier, creates a new filename. 
        /// Just the filename is returned, not the path.
        ///  
        ///  
        /// 
        ///  
        private static string GenerateFileName (string sPath, string sFileSpecifier)
        {
            // Is the caller asking for a random filename element in the name
            if (sFileSpecifier == null || sFileSpecifier.Length == 0 || sFileSpecifier.IndexOf (sGenerateFileNameSpecifier) >= 0) 
            {
                // Generate a random filename using prefix and suffix 
                string dstrFilePrefix; 
                string dstrFileSuffix;
 
                if (sFileSpecifier == null || sFileSpecifier.Length == 0 ||
                    (sFileSpecifier.Length == sGenerateFileNameSpecifier.Length &&
                    sFileSpecifier == sGenerateFileNameSpecifier))
                { 
                    // No specific format given so make files of format "SP_xxxx.dat"
                    dstrFilePrefix = sDefaultFilePrefix; 
                    dstrFileSuffix = sDefaultFileSuffix; 
                }
                else 
                {
                    // Extract the prefix and suffix of the random element
                    int iPos = sFileSpecifier.IndexOf (sGenerateFileNameSpecifier);
                    dstrFilePrefix = sFileSpecifier.Substring (0, iPos); 
                    dstrFileSuffix = sFileSpecifier.Substring (iPos, sGenerateFileNameSpecifier.Length);
                } 
 
                // Create random GUID to use as part of filename
                Guid guid = Guid.NewGuid (); 

                // Convert to string
                string dstrGUID = guid.ToString ();
 
                StringBuilder dstrRandomString = new StringBuilder ();
 
                // Remove non-alpha numeric characters 
                foreach (char ch in dstrGUID)
                { 
                    if (char.IsLetterOrDigit (ch))
                    {
                        dstrRandomString.Append (ch);
                    } 
                }
 
                string sFile = dstrFilePrefix + dstrRandomString + dstrFileSuffix; 

                string dstrFileAndPath = sPath + sFile; 

                // See if file can be created
                FileStream hFile = new FileStream (dstrFileAndPath, FileMode.CreateNew, FileAccess.Write);
 
                // Successfully created empty new file, so close and return
                hFile.Close (); 
 
                return sFile;
            } 
            else
            {
                string dstrFileAndPath = sPath + sFileSpecifier;
 
                // Create file if it doesn't already exist
                FileStream hFile = new FileStream (dstrFileAndPath, FileMode.CreateNew, FileAccess.Write); 
 
                // Successfully created empty new file, so close and return
                hFile.Close (); 

                // Otherwise we just leave things as they are
                return sFileSpecifier;
            } 
        }
 
        ///  
        /// Creates all non-existent directories in sPath. Assumes all
        /// directories prior to createFrom string offset already exist. 
        /// 
        /// 
        /// 
        private static void CreatePath (string sPath, int createFrom) 
        {
            //if \\ skip \\ find next '\' 
            if (createFrom == 0 && sPath.Length >= 2 && sPath.IndexOf ("\\\\") == 0) 
            {
                while (sPath [createFrom] == '\\') 
                {
                    createFrom++;
                }
                int iPos = sPath.IndexOf ('\\', createFrom); 
                if (iPos >= 0)
                { 
                    throw new ArgumentException (SR.Get (SRID.NoBackSlash, "createFrom"), "createFrom"); 
                }
                createFrom = iPos; 
            }

            // Skip any '\' (also at start to cope with \\machine network paths
            while (sPath [createFrom] == '\\') 
            {
                createFrom++; 
            } 

            for (int iStart = createFrom; iStart < sPath.Length; iStart++) 
            {
                // Scan thought path. Each time reach a '\', copy section and try and create directory
                if (sPath [iStart] == '\\')
                { 
                    // Copy last section and trailing slash
                    string dstrIncrementalPath = sPath.Substring (0, iStart); 
 
                    if (!Directory.Exists (dstrIncrementalPath))
                    { 
                        Directory.CreateDirectory (dstrIncrementalPath);
                    }
                }
            } 

            if (!Directory.Exists (sPath)) 
            { 
                Directory.CreateDirectory (sPath);
            } 
        }


        ///  
        /// Given the file specifier string and nFolder value, convert to a reg key and file path.
        ///  
        ///  
        /// 
        ///  
        /// 
        private static void FileSpecifierToRegPath (string sFileSpecifier, Environment.SpecialFolder nFolder, out string dstrFilePath, out string dstrRegPath)
        {
            // Make sure return strings are empty 
            dstrFilePath = null;
            dstrRegPath = null; 
 
            // Is it a "X:\" path or a "\\" path
            if (sFileSpecifier != null && sFileSpecifier.Length >= 3 && (sFileSpecifier.IndexOf (":\\", 1) == 1 || sFileSpecifier.IndexOf ("\\\\") == 0)) 
            {
                // Find last '\' that separates path from base file
                int iBaseFile = sFileSpecifier.LastIndexOf ('\\');
                iBaseFile++; 

                // dstrFilePath holds the path with trailing '\' 
                dstrFilePath = sFileSpecifier.Substring (0, iBaseFile); 
                CreatePath (dstrFilePath, 0);
 
                // Calculate the new filename
                string sFile = GenerateFileName (dstrFilePath, sFileSpecifier.Substring (iBaseFile + 1));

                // Add fileName to path and copy to reg key 
                dstrFilePath = dstrFilePath + @"\" + sFile;
                dstrRegPath = dstrFilePath; 
            } 

            // It's a relative path 
            else
            {
#if _WIN32_WCE
            string szPath = "\\Windows"; 
#else
                string szPath = Environment.GetFolderPath (nFolder); 
#endif 

                int ulCreateDirsFrom = szPath.Length; 

                // dstrFilePath holds the special folder path no trailing '\'
                dstrFilePath = szPath + sFileStoragePath;
 
                // Make the %...% folder identifier
#if !_WIN32_WCE 
                string sFolder = string.Format (CultureInfo.InvariantCulture, "%{0}%", (int) nFolder); 
#else
        string sFolder = "\\Windows"; 
#endif

                // Add the %...% and path into reg data.
                dstrRegPath = sFolder + sFileStoragePath; 

                // both dstrRegPath and dstrFilePath have trailing '\' 
 
                // Now add any fileNameSpecifier directories
                int iBaseFile; 
                if (sFileSpecifier == null || sFileSpecifier.Length == 0)
                {
                    iBaseFile = 0;
                } 
                else
                { 
                    iBaseFile = sFileSpecifier.LastIndexOf ('\\'); 
                    if (iBaseFile > 0)
                    { 
                        // Specifier contains '\'
                        iBaseFile++; // part after last '\' becomes base file

                        int iStart = 0; 
                        if (sFileSpecifier [0] == '\\')
                        { 
                            iStart++; // Skip initial '\' 
                        }
 
                        // Add file specifier path to file and key
                        dstrFilePath = dstrRegPath = sFileSpecifier.Substring (iStart, iBaseFile - iStart + 1);
                    }
                } 

                // Create any new directories 
                CreatePath (dstrFilePath, ulCreateDirsFrom); 

                // Generate the actual file name 
                string sFile = GenerateFileName (dstrFilePath, sFileSpecifier.Substring (iBaseFile + 1, sFileSpecifier.Length - iBaseFile + 1));

                // Add file name to path and reg key
                dstrRegPath += sFile; 

                dstrFilePath += sFile; 
            } 
        }
 
        /// 
        /// Given a file storage value from the registry, convert to a file path.
        /// This will extract the %...% value and finds the local special folder path.
        ///  
        /// 
        ///  
        private static void RegPathToFilePath (string sRegPath, out string dstrFilePath) 
        {
            // Is this a reference to a special folder 
            if (sRegPath [0] == '%')
            {
                // Find the second % symbol
                int iPosPercent = sRegPath.LastIndexOf ('%'); 

                // Convert the string between the %s to a number 
                int nFolder = 0; 
                if (!int.TryParse (sRegPath.Substring (iPosPercent, iPosPercent - 1), out nFolder))
                { 
                    throw new ArgumentException (SR.Get (SRID.InvalidRegistryEntry, "sRegPath"), "sRegPath");
                }

                // Point to start of real path '\' 
                if (sRegPath [++iPosPercent] != '\\')
                { 
                    throw new ArgumentException (SR.Get (SRID.InvalidRegistryEntry, "sRegPath"), "sRegPath"); 
                }
 
#if _WIN32_WCE
        string szPath = @"\Windows";
#else
                string szPath = Environment.GetFolderPath ((Environment.SpecialFolder) nFolder); 
#endif
 
                // filePath now has the special folder path (with no trailing '\') 
                dstrFilePath = szPath + sRegPath.Substring (iPosPercent, sRegPath.Length - iPosPercent);
            } 
            else
            {
                // Not a special folder so just copy
                dstrFilePath = sRegPath; 
            }
        } 
 
#if false
/**************************************************************************** 
* CSpObjectToken__DisplayUI *
*---------------------------*
*   Description:
*       Display the specified type of UI 
*
*   Return: 
*   S_OK on success 
*   FAILED(hr) otherwise
******************************************************************** robch */ 
private void DisplayUI(
    HWND hwndParent,
    string sTitle,
    string sTypeOfUI, 
    object pvExtraData,
    uint cbExtraData, 
    object punkObject) 
{
    // SPDBG_FUNC("CSpObjectToken::DisplayUI"); 
    HRESULT hr;
    CLSID clsidObject;

    if (m_fKeyDeleted) 
    {
		// TODO 
 		throw new ObjectTokenException(SR.Get (SRID.TokenDeleted)); 
    }
    else if (!IsWindow(hwndParent) || 
             SP_IS_BAD_OPTIONAL_STRING_PTR(sTitle) ||
             SP_IS_BAD_STRING_PTR(sTypeOfUI) ||
             (pvExtraData != null && SPIsBadReadPtr(pvExtraData, cbExtraData)) ||
             (punkObject != null && SP_IS_BAD_INTERFACE_PTR(punkObject))) 
    {
        E_INVALIDARG; 
    } 
    else if (m_cpTokenDelegate != null)
    { 
        // NTRAID#SPEECH-7392-2000/08/31-robch: Maybe we should first delegate, and if that doesn't work,
        // try this token's category ui...
        m_cpTokenDelegate.DisplayUI(
                    hwndParent, 
                    sTitle,
                    sTypeOfUI, 
                    pvExtraData, 
                    cbExtraData,
                    punkObject); 
    }
    else
    {
        GetUIObjectClsid(sTypeOfUI, &clsidObject); 

        ISpTokenUI cpTokenUI = cpTokenUI.CoCreateInstance(clsidObject); 
 
        cpTokenUI.DisplayUI(
                            hwndParent, 
                            sTitle,
                            sTypeOfUI,
                            pvExtraData,
                            cbExtraData, 
                            this,
                            punkObject); 
    } 

    SPDBG_REPORT_ON_FAIL(hr); 
    return hr;
}
#endif
 
        /// 
        /// Open the "Files" subkey of a specified data key's caller's sub key 
        ///  
        /// 
        ///  
        /// 
        private ObjectToken OpenFilesKey (Guid clsidCaller, bool fCreateKey)
        {
            // SPDBG_FUNC("CSpObjectToken::OpenFilesKey"); 

            ObjectToken cpClsidKey; 
 
            // Convert the string clsid to a real clsid
            string dstrCLSID = clsidCaller.ToString (); 

            // Either create the data key or open it
            if (fCreateKey)
            { 
                cpClsidKey = (ObjectToken) CreateKey (dstrCLSID);
            } 
            else 
            {
                cpClsidKey = (ObjectToken) OpenKey (dstrCLSID); 
            }

            // Either crate the files data key or open it
            ObjectToken ppKey; 

            if (fCreateKey) 
            { 
                ppKey = (ObjectToken) cpClsidKey.CreateKey (SPTOKENKEY_FILES);
            } 
            else
            {
                ppKey = (ObjectToken) cpClsidKey.OpenKey (SPTOKENKEY_FILES);
            } 
            return ppKey;
        } 
 
        /// 
        /// Delete either a specific file (specified by sValueName) or all files 
        /// (when sValueName == null) from the specified data key
        /// 
        /// 
        ///  
        private void DeleteFileFromKey (ObjectToken pDataKey, string sValueName)
        { 
            // SPDBG_FUNC("CSpObjectToken::DeleteFileFromKey"); 

            // If the value name wasn't specified, we'll delete all the value's files 
            if (sValueName == null)
            {
                // Loop thru the values
                foreach (RegistryEntry regEntry in (IEnumerable) pDataKey) 
                {
                    try 
                    { 
                        // Delete the file
                        DeleteFileFromKey (pDataKey, (string) regEntry.Value); 
                    }
                    catch (IOException)
                    {
                        // ignore the File IO exception 
                    }
                } 
            } 
            else
            { 
                // Get the filename
                string sFile;
                string dstrRegPath = pDataKey.GetString (sValueName);
 
                // Convert the path stored in the registry to a real file path
                RegPathToFilePath (dstrRegPath, out sFile); 
 
                // And delete the file
                // Ignore errors from DeleteFile, we can't let this stop us 
                try
                {
                    File.Delete (sFile);
                } 
                catch (IOException)
                { 
                } 
            }
        } 

        /// 
        /// Remove all filenames for a specified caller, or for all callers
        /// if pclsidCaller is null. 
        /// 
        ///  
        private void RemoveAllStorageFileNames (Guid pclsidCaller) 
        {
            // SPDBG_FUNC("CSpObjectToken::RemoveAllStorageFileNames"); 

            // If the clsid wasn't specified, we'll delete all files from all
            // keys that are clsids
            if (pclsidCaller == Guid.Empty) 
            {
                // Loop thru all the keys 
                for (int i = 0; ; i++) 
                {
                    // Get the next sub key 
                    //TODO
                    string dstrSubKey = null; //((ObjectToken) this).EnumKeys (i);
                    if (dstrSubKey != null)
                    { 
                        break;
                    } 
 
                    // If this key looks like a clsid, and it is, recursively call
                    // this function to delete the specific clsid's files 
                    Guid clsid = new Guid (dstrSubKey);
                    RemoveAllStorageFileNames (clsid);
                }
            } 
            else
            { 
                // Open the files data key, and delete all the files 
                ObjectToken cpFilesKey = OpenFilesKey (pclsidCaller, false);
                { 
                    try
                    {
                        DeleteFileFromKey (cpFilesKey, null);
                    } 
                    catch (SystemException)
                    { 
                        // If we failed to delete this file then that should not stop us from deleting the other files. 
                    }
                } 
            }
        }

#endif 

        ///  
        /// Description: 
        ///     Parse a token id into it's parts. For example:
        /// 
        ///         sCategoryId   = HKEY...\Recognizers
        ///         sTokenId      = HKEY...\Recognizers\Tokens\MSASR English
        ///
        ///         *ppszCategoryId     = HKEY...\Recognizers 
        ///         *ppszTokenId        = HKEY...\Recognizers\Tokens\MSASR English
        ///         *ppszTokenIdForEnum = null 
        ///         *ppszTokenEnumExtra = null 
        ///
        ///     or 
        ///
        ///         sCategoryId = HKEY...\AudioIn
        ///         sTokenId =    HKEY...\AudioIn\TokenEnums\DSound
        /// 
        ///         *ppszCategoryId     = HKEY...\AudioIn
        ///         *ppszTokenId        = HKEY...\AudioIn\TokenEnums\DSound 
        ///         *ppszTokenIdForEnum = HKEY...\AudioIn\TokenEnums\DSound 
        ///         *ppszTokenEnumExtra = null
        /// 
        ///     or
        ///
        ///         sCategoryId = HKEY...\AudioIn
        ///         sTokenId =    HKEY...\AudioIn\TokenEnums\DSound\CrystalWave 
        ///
        ///         *ppszCategoryId     = HKEY...\AudioIn 
        ///         *ppszTokenId        = HKEY...\AudioIn\TokenEnums\DSound\CrystalWave 
        ///         *ppszTokenIdForEnum = HKEY...\AudioIn\TokenEnums\DSound
        ///         *ppszTokenEnumExtra = CrystalWave 
        ///
        ///     sCategoryId can be null. If it is, we'll calculate the category id
        ///     by finding the first occurrence of either "Tokens" or "TokenEnums"
        ///     The category id will immediately proceed that. 
        /// 
        ///  
        ///  
        private static bool ParseRegistryString (string sCategoryId, string sTokenId)
        { 
            // If the caller supplied a category, we already know how big it is
            int cchCategoryId = 0;
            if (!string.IsNullOrEmpty (sCategoryId))
            { 
                cchCategoryId = sCategoryId.Length;
                if (sTokenId.Length < sCategoryId.Length || string.Compare (sTokenId.Substring (0, cchCategoryId), sCategoryId, StringComparison.OrdinalIgnoreCase) != 0) 
                { 
                    // The tokenid wasn't prefaced with the category id, a must
                    return false; 
                }
            }

            string sSlashTokensSlash = "Tokens"; 

            int iFirst = cchCategoryId; 
            int cchTokenId = sTokenId.Length; 
            while (iFirst < sTokenId.Length)
            { 
                int iSecond = sTokenId.IndexOf ('\\', iFirst);
                if (iSecond < 0)
                {
                    iSecond = cchTokenId; 
                }
 
                // name between '/' '/' 
                string sEntry = sTokenId.Substring (iFirst, iSecond - iFirst);
 
                if (string.Compare (sEntry, sSlashTokensSlash, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    cchCategoryId = iFirst;
                    break; 
                }
                else if (cchCategoryId > 0) 
                { 
                    break;
                } 
                else
                {
                    iFirst = iSecond + 1;
                } 
            }
 
            if (cchCategoryId == 0) 
            {
                int iPosCategory = sTokenId.LastIndexOf ('\\'); 
                if (iPosCategory < 0)
                {
                    return false;
                } 
                else
                { 
                    cchCategoryId = iPosCategory; 
                }
            } 

            if (cchCategoryId <= 0)
            {
                return false; 
            }
            return true; 
        } 

#if VSCOMPILE && false 

        /// 
        /// Get the UI object's clsid from the registry. First check under the
        /// token's root, then under the category 
        /// 
        ///  
        ///  
        private Guid GetUIObjectClsid (string sTypeOfUI)
        { 
            // SPDBG_FUNC("CSpObjectToken::GetUIObjectClsid");

            // We'll try and retrive the CLSID as a string from the token ui registry
            // key, then from the category ui registry key. We'll convert to an actual 
            // GUID at the end of the function
            string dstrClsid = null; 
 
            //--- Try getting the clsid from token's UI key
            ObjectToken cpTokenUI = (ObjectToken) OpenKey (SPTOKENKEY_UI); 

            ObjectToken cpType = (ObjectToken) cpTokenUI.OpenKey (sTypeOfUI);
            if (cpType.TryGetString (SPTOKENVALUE_CLSID, out dstrClsid))
            { 
                //--- Try getting the clsid from the category's UI key
                if (CategoryId != null) 
                { 
                    ObjectTokenCategory cpCategory = CategoryFromId (CategoryId, false);
 
                    ObjectToken cpTokenUI2 = (ObjectToken) cpCategory.OpenKey (SPTOKENKEY_UI);
                    {
                        ObjectToken cpType2 = (ObjectToken) cpTokenUI2.OpenKey (sTypeOfUI);
                        dstrClsid = cpType2.GetString (SPTOKENVALUE_CLSID); 
                    }
                } 
            } 

            // If we were successful at getting the clsid, convert it 
            return new Guid (dstrClsid);
        }

#endif 

        #endregion 
 
        //*******************************************************************
        // 
        // Private Types
        //
        //*******************************************************************
 
        #region Private Types
 
        //--- ISpObjectWithToken ---------------------------------------------------- 
        [ComImport, Guid ("5B559F40-E952-11D2-BB91-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
        interface ISpObjectWithToken 
        {
            [PreserveSig]
            int SetObjectToken (ISpObjectToken pToken);
            [PreserveSig] 
            int GetObjectToken (IntPtr ppToken);
        }; 
 
#if SPEECHSERVER
        //--- ISpObjectWithTokenMss ---------------------------------------------------- 
        // This interface is necessary to support "pre-private-SAPI" for MSS (still used by TTS voices)
        // When querying for ISpObjectWithToken interface, ISpObjectWithTokenMss should be tried if QueryInterface for ISpObjectWithToken fails.
        [ComImport, Guid ("5C559F40-E952-11D2-BB91-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
        interface ISpObjectWithTokenMss 
        {
            [PreserveSig] 
            int SetObjectToken (ISpObjectTokenMss pToken); 
            [PreserveSig]
            int GetObjectToken (IntPtr ppToken); 
        };
#endif
        #endregion
 
        //*******************************************************************
        // 
        // Private Fields 
        //
        //******************************************************************* 

        #region private Fields

        // Specifier used to generate a random filename. 
        private const string sGenerateFileNameSpecifier = "{0}";
 
        private const string SPTOKENVALUE_CLSID = "CLSID"; 

        private RegistryDataKey _attributes; 

#if VSCOMPILE

        // Prefix used for storage files if not otherwise set 
        private const string sDefaultFilePrefix = "SP_";
 
        // Extension used for storage files if not otherwise set 
        private const string sDefaultFileSuffix = ".dat";
 
        private const string SPTOKENKEY_FILES = "Files";

        private const string SPTOKENKEY_UI = "UI";
 
        // Relative path below special folders where storage files are stored
        private const string sFileStoragePath = "\\Microsoft\\Speech\\Files\\"; 
 
#endif
        #endregion 
    }

    #region SAPI interface
 
#if SPEECHSERVER
    // This interface is necessary to support "pre-private-SAPI" for MSS (still used by TTS voices) 
    [ComImport, Guid ("15056589-E16C-11D2-BB90-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface ISpObjectTokenMss : ISpDataKey
    { 
        // ISpDataKey Methods
        [PreserveSig]
        new int SetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 cbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] Byte [] pData);
        [PreserveSig] 
        new int GetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pcbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte [] pData);
        [PreserveSig] 
        new int SetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] string pszValue); 
        [PreserveSig]
        new int GetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValue); 
        [PreserveSig]
        new int SetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 dwValue);
        [PreserveSig]
        new int GetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pdwValue); 
        [PreserveSig]
        new int OpenKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKeyName, out ISpDataKey ppSubKey); 
        [PreserveSig] 
        new int CreateKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey, out ISpDataKey ppSubKey);
        [PreserveSig] 
        new int DeleteKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey);
        [PreserveSig]
        new int DeleteValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName);
        [PreserveSig] 
        new int EnumKeys (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszSubKeyName);
        [PreserveSig] 
        new int EnumValues (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValueName); 

        // ISpObjectToken Methods 
        void SetId ([MarshalAs (UnmanagedType.LPWStr)] string pszCategoryId, [MarshalAs (UnmanagedType.LPWStr)] string pszTokenId, [MarshalAs (UnmanagedType.Bool)] bool fCreateIfNotExist);
        void GetId (out IntPtr ppszCoMemTokenId);
        void Slot15 (); // void GetCategory(out ISpObjectTokenCategory ppTokenCategory);
        void Slot16 (); // void CreateInstance(object pUnkOuter, UInt32 dwClsContext, ref Guid riid, ref IntPtr ppvObject); 
        void Slot17 (); // void GetStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszValueName, [MarshalAs(UnmanagedType.LPWStr)] string pszFileNameSpecifier, UInt32 nFolder, [MarshalAs(UnmanagedType.LPWStr)] out string ppszFilePath);
        void Slot18 (); // void RemoveStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszKeyName, int fDeleteFile); 
        void Slot19 (); // void Remove(ref Guid pclsidCaller); 
        void Slot20 (); // void IsUISupported([MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject, ref Int32 pfSupported);
        void Slot21 (); // void DisplayUI(UInt32 hWndParent, [MarshalAs(UnmanagedType.LPWStr)] string pszTitle, [MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject); 
        void MatchesAttributes ([MarshalAs (UnmanagedType.LPWStr)] string pszAttributes, [MarshalAs (UnmanagedType.Bool)] out bool pfMatches);
    }
#endif
 
    [ComImport, Guid ("14056589-E16C-11D2-BB90-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISpObjectToken : ISpDataKey 
    { 
        // ISpDataKey Methods
        [PreserveSig] 
        new int SetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 cbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] Byte [] pData);
        [PreserveSig]
        new int GetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pcbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte [] pData);
        [PreserveSig] 
        new int SetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] string pszValue);
        [PreserveSig] 
        new int GetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValue); 
        [PreserveSig]
        new int SetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 dwValue); 
        [PreserveSig]
        new int GetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pdwValue);
        [PreserveSig]
        new int OpenKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKeyName, out ISpDataKey ppSubKey); 
        [PreserveSig]
        new int CreateKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey, out ISpDataKey ppSubKey); 
        [PreserveSig] 
        new int DeleteKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey);
        [PreserveSig] 
        new int DeleteValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName);
        [PreserveSig]
        new int EnumKeys (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszSubKeyName);
        [PreserveSig] 
        new int EnumValues (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValueName);
 
        // ISpObjectToken Methods 
        void SetId ([MarshalAs (UnmanagedType.LPWStr)] string pszCategoryId, [MarshalAs (UnmanagedType.LPWStr)] string pszTokenId, [MarshalAs (UnmanagedType.Bool)] bool fCreateIfNotExist);
        void GetId (out IntPtr ppszCoMemTokenId); 
        void Slot15 (); // void GetCategory(out ISpObjectTokenCategory ppTokenCategory);
        void Slot16 (); // void CreateInstance(object pUnkOuter, UInt32 dwClsContext, ref Guid riid, ref IntPtr ppvObject);
        void Slot17 (); // void GetStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszValueName, [MarshalAs(UnmanagedType.LPWStr)] string pszFileNameSpecifier, UInt32 nFolder, [MarshalAs(UnmanagedType.LPWStr)] out string ppszFilePath);
        void Slot18 (); // void RemoveStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszKeyName, int fDeleteFile); 
        void Slot19 (); // void Remove(ref Guid pclsidCaller);
        void Slot20 (); // void IsUISupported([MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject, ref Int32 pfSupported); 
        void Slot21 (); // void DisplayUI(UInt32 hWndParent, [MarshalAs(UnmanagedType.LPWStr)] string pszTitle, [MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject); 
        void MatchesAttributes ([MarshalAs (UnmanagedType.LPWStr)] string pszAttributes, [MarshalAs (UnmanagedType.Bool)] out bool pfMatches);
    } 

    #endregion
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: 
//		Object Token
// 
// History:
//		7/1/2004	jeanfp		
//---------------------------------------------------------------------------
 
using Microsoft.Win32;
using System; 
using System.Collections.Generic; 
using System.Globalization;
using System.Diagnostics; 
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text; 
using System.Threading;
 
using RegistryEntry = System.Collections.Generic.KeyValuePair; 

namespace System.Speech.Internal.ObjectTokens 
{
    /// 
    /// Summary description for ObjectToken.
    ///  
#if VSCOMPILE
    [DebuggerDisplay ("{Name}")] 
#endif 
    internal class ObjectToken : RegistryDataKey, ISpObjectToken
#if SPEECHSERVER 
        ,ISpObjectTokenMss
#endif
    {
        //******************************************************************* 
        //
        // Constructors 
        // 
        //*******************************************************************
 
        #region Constructors

        protected ObjectToken (string keyId, RegistryKey hkey)
            : base (keyId, hkey) 
        {
        } 
 
        internal static RegistryKey CreateKey (string sCategoryId, string sTokenId, bool fCreateIfNotExist, out string id)
        { 
            id = null;
            RegistryKey hkey = null;

            if (ParseRegistryString (sCategoryId, sTokenId)) 
            {
                hkey = RegistryDataKey.CreateKey (sTokenId, fCreateIfNotExist, out id); 
            } 
            return hkey;
        } 

        internal static ObjectToken Create (string sCategoryId, string sTokenId, bool fCreateIfNotExist)
        {
            string id; 
            RegistryKey hkey = CreateKey (sTokenId, fCreateIfNotExist, out id);
            if (hkey != null) 
            { 
                return new ObjectToken (id, hkey);
            } 
            return null;
        }

        #endregion 

        //******************************************************************** 
        // 
        // Public Methods
        // 
        //*******************************************************************

        #region public Methods
 
        /// 
        /// Tests whether two AutomationIdentifier objects are equivalent 
        ///  
        public override bool Equals (object obj)
        { 
            ObjectToken token = obj as ObjectToken;
            return token != null && string.Compare (Id, token.Id, StringComparison.OrdinalIgnoreCase) == 0;
        }
 
        /// 
        /// Overrides Object.GetHashCode() 
        ///  
        public override int GetHashCode ()
        { 
            return Id.GetHashCode ();
        }

        #endregion 

        //******************************************************************** 
        // 
        // Internal Properties
        // 
        //********************************************************************

        #region Internal Properties
 
        internal RegistryDataKey Attributes
        { 
            get 
            {
                return _attributes != null ? _attributes : (_attributes = OpenKey ("Attributes")); 
            }
        }

        ///  
        /// Returns the Name for the voice
        /// Look first in the Name attribute, if not available then get the default string 
        ///  
        /// 
        internal string TokenName () 
        {
            string name = string.Empty;
            if (Attributes != null)
            { 
                Attributes.TryGetString ("Name", out name);
 
                if (string.IsNullOrEmpty (name)) 
                {
                    TryGetString (null, out name); 
                }
            }
            return name;
        } 

        ///  
        /// Returns the Culture defined in the Language field for a token 
        /// 
        ///  
        internal CultureInfo Culture
        {
            get
            { 
                CultureInfo culture = null;
                string langId; 
                if (Attributes.TryGetString ("Language", out langId)) 
                {
                    culture = SapiAttributeParser.GetCultureInfoFromLanguageString (langId); 
                }
                return culture;
            }
        } 

        ///  
        /// Returns the Culture defined in the Language field for a token 
        /// 
        ///  
        internal string Description
        {
            get
            { 
                string description = string.Empty;
                string sCultureId = string.Format (CultureInfo.InvariantCulture, "{0:x}", CultureInfo.CurrentUICulture.LCID); 
 
                if (!TryGetString (sCultureId, out description))
                { 
                    TryGetString (null, out description);
                }
                return description;
            } 
        }
 
        #endregion 

        //******************************************************************* 
        //
        // Internal Methods
        //
        //******************************************************************** 

        #region internal Methods 
 
        #region ISpObjectToken Implementation
 
        public void SetId ([MarshalAs (UnmanagedType.LPWStr)] string pszCategoryId, [MarshalAs (UnmanagedType.LPWStr)] string pszTokenId, [MarshalAs (UnmanagedType.Bool)] bool fCreateIfNotExist)
        {
            throw new NotImplementedException ();
        } 

        public void GetId ([MarshalAs (UnmanagedType.LPWStr)] out IntPtr ppszCoMemTokenId) 
        { 
            ppszCoMemTokenId = Marshal.StringToCoTaskMemUni (Id);
        } 

        public void Slot15 () { throw new NotImplementedException (); } // void GetCategory(out ISpObjectTokenCategory ppTokenCategory);
        public void Slot16 () { throw new NotImplementedException (); } // void CreateInstance(object pUnkOuter, UInt32 dwClsContext, ref Guid riid, ref IntPtr ppvObject);
        public void Slot17 () { throw new NotImplementedException (); } // void GetStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszValueName, [MarshalAs(UnmanagedType.LPWStr)] string pszFileNameSpecifier, UInt32 nFolder, [MarshalAs(UnmanagedType.LPWStr)] out string ppszFilePath); 
        public void Slot18 () { throw new NotImplementedException (); } // void RemoveStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszKeyName, int fDeleteFile);
        public void Slot19 () { throw new NotImplementedException (); } // void Remove(ref Guid pclsidCaller); 
        public void Slot20 () { throw new NotImplementedException (); } // void IsUISupported([MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject, ref Int32 pfSupported); 
        public void Slot21 () { throw new NotImplementedException (); } // void DisplayUI(UInt32 hWndParent, [MarshalAs(UnmanagedType.LPWStr)] string pszTitle, [MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject);
        public void MatchesAttributes ([MarshalAs (UnmanagedType.LPWStr)] string pszAttributes, [MarshalAs (UnmanagedType.Bool)] out bool pfMatches) { throw new NotImplementedException (); } 

        #endregion

        ///  
        /// Check if the token supports the attributes list given in. The
        /// attributes list has the same format as the required attributes given to 
        /// SpEnumTokens. 
        /// 
        ///  
        /// 
        internal bool MatchesAttributes (string [] sAttributes)
        {
            bool fMatch = true; 

            for (int iAttribute = 0; iAttribute < sAttributes.Length; iAttribute++) 
            { 
                string s = sAttributes [iAttribute];
                fMatch &= HasValue (s) || (Attributes != null && Attributes.HasValue (s)); 
                if (!fMatch)
                {
                    break;
                } 
            }
            return fMatch; 
        } 

#if false 

        /// 
        ///
        ///  
        /// 
        ///  
        ///  
        internal static ObjectTokenCategory CategoryFromId (string sCategoryId, bool fCreateIfNotExist)
        { 
            return new ObjectTokenCategory (sCategoryId, fCreateIfNotExist);
        }

        ///  
        /// Remove the specified storage file name and optionally delete the file
        ///  
        ///  
        /// 
        ///  
        internal void RemoveStorageFileName (Guid clsidCaller, string sValueName, bool fDeleteFile)
        {
            // SPDBG_FUNC("CSpObjectToken::RemoveStorageFileName");
 
            ObjectToken cpDataKey = OpenFilesKey (clsidCaller, false);
            if (fDeleteFile) 
            { 
                DeleteFileFromKey (cpDataKey, sValueName);
            } 
            cpDataKey.DeleteValue (sValueName);
        }

        ///  
        /// Get a filename which can be manipulated by this token. Storage files will
        /// be deleted on a Remove call. 
        /// clsidCaller - a key will be made in registry below the token with this name and files key beneath that. 
        /// sValueName - Value name which will be made in registry to store the file path string.
        /// sFileSpecifier - either null or a path/filename for storage file: 
        ///     - if this starts with 'X:\' or '\\' then is assumed to be a full path.
        ///     - otherwise is assumed to be relative to special folders given in the nFolder parameter.
        ///     - if ends with a '\', or is null a unique filename will be created.
        ///     - if the name contains a %d the %d is replaced by a number to give a unique filename. 
        ///     - intermediate directories are created.
        ///     - if a relative file is being used the value stored in the registry includes 
        ///         the nFolder value as %nFolder% before the rest of the path. This allows 
        ///         roaming to work properly if you pick an nFolder value representing a raoming folder
        /// nFolder - equivalent to the value given to SHGetFolderPath in the Shell API. 
        /// ppszFilePath - CoTaskMemAlloc'd returned file path.
        ///
        /// 
        ///  
        /// 
        ///  
        ///  
        /// 
        internal string GetStorageFileName (Guid clsidCaller, string sValueName, string sFileSpecifier, Environment.SpecialFolder nFolder, bool fCreate) 
        {
            string ppszFilePath = null;

            // SPDBG_FUNC("CSpObjectToken::GetStorageFileName"); 

            // See if there is already a Files key in the registry for this token 
            ObjectToken cpFilesKey = OpenFilesKey (clsidCaller, (int) nFolder != 0); 

            string dstrFilePath;  // Path to the file which we return to user. 
            string dstrRegPath;   // Path to the string which will be stored in the registry.

            // See if the key we are looking for is present
            cpFilesKey.TryGetString (sValueName, out dstrRegPath); 
#if _WIN32_WCE
            if (hr == SPERR_NOT_FOUND && nFolder) 
#else 
            if (fCreate && dstrRegPath != null)
#endif //_WIN32_WCE 
            {
                // Didn't find the key and want to create

                // Calculate the new file path and key value 
                FileSpecifierToRegPath (sFileSpecifier, nFolder, out dstrFilePath, out dstrRegPath);
                // Set the key value 
                cpFilesKey.SetString (sValueName, dstrRegPath); 
            }
            else 
            {
                // Found existing entry so convert and return
                RegPathToFilePath (dstrRegPath, out dstrFilePath);
            } 
            ppszFilePath = dstrFilePath;
 
            return ppszFilePath; 
        }
 
        /// 
        /// Determine if the specific type of UI is supported or not
        /// 
        ///  
        /// 
        internal bool IsUISupported (string sTypeOfUI /*, object pvExtraData, int cbExtraData*/) 
        { 
            // SPDBG_FUNC("CSpObjectToken::IsUISupported");
 
#if false
 	if (m_cpTokenDelegate != null)
	{
		// NTRAID#SPEECH-7392-2000/08/31-robch: Maybe we should first delegate, and if that doesn't work, 
		// try this token's category ui...
 		m_cpTokenDelegate.IsUISupported( 
					pszTypeOfUI, 
 					pvExtraData,
 					cbExtraData, 
					pfSupported);
 	}
	else
	{ 
            /*Guid clsidObject = */
            GetUIObjectClsid (sTypeOfUI); 
 
		ISpTokenUI cpTokenUI = cpTokenUI.CoCreateInstance(clsidObject);
 
 		pfSupported = cpTokenUI.IsUISupported(sTypeOfUI, pvExtraData, cbExtraData, punkObject);
#endif
            //
            throw new NotImplementedException (); 
            //return pfSupported;
        } 
 
        /// 
        /// Remove either a specified caller's section of the token, or the 
        /// entire token. We remove the entire token if pclsidCaller == null.
        /// 
        /// 
        internal void Remove (Guid pclsidCaller) 
        {
            // SPDBG_FUNC("CSpObjectToken::Remove"); 
 
            // Remove all the filenames
            RemoveAllStorageFileNames (pclsidCaller); 

            // Now go ahead and delete the registry entry which is either
            // the token itself (if pclsidCaller == null) or the clsid's
            // sub key 
            if (pclsidCaller == Guid.Empty)
            { 
                RegistryDataKey.DeleteRegistryPath (Id, null); 
            }
            else 
            {
                //
                throw new NotImplementedException ();
                //					string szClsid; //[MAX_PATH]; 
                //					StringFromGUID2(pclsidCaller, szClsid, sp_countof(szClsid));
                //					RegistryDataKey.SpDeleteRegPath(_dstrTokenId, szClsid); 
            } 
        }
 
#endif
        internal T CreateObjectFromToken (string name)
        {
            T instanceValue = default (T); 
            string clsid;
 
            if (!TryGetString (name, out clsid)) 
            {
                throw new ArgumentException (SR.Get (SRID.TokenCannotCreateInstance)); 
            }

            try
            { 
                // Application Class Id
                Type type = Type.GetTypeFromCLSID (new Guid (clsid)); 
 
                // Create the object instance
                instanceValue = (T) Activator.CreateInstance (type); 

                // Initialize the instance
                ISpObjectWithToken objectWithToken = instanceValue as ISpObjectWithToken;
                if (objectWithToken != null) 
                {
                    //IntPtr ite = Marshal.GetComInterfaceForObject (this, typeof (ISpObjectToken2)); 
                    int hresult = objectWithToken.SetObjectToken ((ISpObjectToken) this); 
                    if (hresult < 0)
                    { 
                        throw new ArgumentException (SR.Get (SRID.TokenCannotCreateInstance));
                    }
                }
#if SPEECHSERVER 
                else
                { 
                    // For MSS - we should try the new MSS interface (with new GUID). 
                    ISpObjectWithTokenMss objectWithTokenMss = instanceValue as ISpObjectWithTokenMss;
                    if (objectWithTokenMss != null) 
                    {
                        objectWithTokenMss.SetObjectToken((ISpObjectTokenMss)this);
                    }
                } 
#endif
            } 
            catch (Exception e) 
            {
                //wow I am not really sure we want to do this here.... 
                if (e is MissingMethodException || e is TypeLoadException || e is FileLoadException || e is FileNotFoundException || e is MethodAccessException || e is MemberAccessException || e is TargetInvocationException || e is InvalidComObjectException || e is NotSupportedException || e is FormatException)
                {
                    throw new ArgumentException (SR.Get (SRID.TokenCannotCreateInstance));
                } 
                throw;
            } 
            return instanceValue; 
        }
 
        #endregion

        //*******************************************************************
        // 
        // Protected Methods
        // 
        //******************************************************************* 

        #region Protected Methods 

        protected override void Dispose (bool disposing)
        {
            try 
            {
                if (disposing && _attributes != null) 
                { 
                    _attributes.Dispose ();
                    _attributes = null; 
                }
            }
            finally
            { 
                base.Dispose (disposing);
            } 
        } 

        #endregion 

        //*******************************************************************
        //
        // Private Methods 
        //
        //******************************************************************** 
 
        #region private Methods
 
#if false

        /// 
        /// Given a path and file specifier, creates a new filename. 
        /// Just the filename is returned, not the path.
        ///  
        ///  
        /// 
        ///  
        private static string GenerateFileName (string sPath, string sFileSpecifier)
        {
            // Is the caller asking for a random filename element in the name
            if (sFileSpecifier == null || sFileSpecifier.Length == 0 || sFileSpecifier.IndexOf (sGenerateFileNameSpecifier) >= 0) 
            {
                // Generate a random filename using prefix and suffix 
                string dstrFilePrefix; 
                string dstrFileSuffix;
 
                if (sFileSpecifier == null || sFileSpecifier.Length == 0 ||
                    (sFileSpecifier.Length == sGenerateFileNameSpecifier.Length &&
                    sFileSpecifier == sGenerateFileNameSpecifier))
                { 
                    // No specific format given so make files of format "SP_xxxx.dat"
                    dstrFilePrefix = sDefaultFilePrefix; 
                    dstrFileSuffix = sDefaultFileSuffix; 
                }
                else 
                {
                    // Extract the prefix and suffix of the random element
                    int iPos = sFileSpecifier.IndexOf (sGenerateFileNameSpecifier);
                    dstrFilePrefix = sFileSpecifier.Substring (0, iPos); 
                    dstrFileSuffix = sFileSpecifier.Substring (iPos, sGenerateFileNameSpecifier.Length);
                } 
 
                // Create random GUID to use as part of filename
                Guid guid = Guid.NewGuid (); 

                // Convert to string
                string dstrGUID = guid.ToString ();
 
                StringBuilder dstrRandomString = new StringBuilder ();
 
                // Remove non-alpha numeric characters 
                foreach (char ch in dstrGUID)
                { 
                    if (char.IsLetterOrDigit (ch))
                    {
                        dstrRandomString.Append (ch);
                    } 
                }
 
                string sFile = dstrFilePrefix + dstrRandomString + dstrFileSuffix; 

                string dstrFileAndPath = sPath + sFile; 

                // See if file can be created
                FileStream hFile = new FileStream (dstrFileAndPath, FileMode.CreateNew, FileAccess.Write);
 
                // Successfully created empty new file, so close and return
                hFile.Close (); 
 
                return sFile;
            } 
            else
            {
                string dstrFileAndPath = sPath + sFileSpecifier;
 
                // Create file if it doesn't already exist
                FileStream hFile = new FileStream (dstrFileAndPath, FileMode.CreateNew, FileAccess.Write); 
 
                // Successfully created empty new file, so close and return
                hFile.Close (); 

                // Otherwise we just leave things as they are
                return sFileSpecifier;
            } 
        }
 
        ///  
        /// Creates all non-existent directories in sPath. Assumes all
        /// directories prior to createFrom string offset already exist. 
        /// 
        /// 
        /// 
        private static void CreatePath (string sPath, int createFrom) 
        {
            //if \\ skip \\ find next '\' 
            if (createFrom == 0 && sPath.Length >= 2 && sPath.IndexOf ("\\\\") == 0) 
            {
                while (sPath [createFrom] == '\\') 
                {
                    createFrom++;
                }
                int iPos = sPath.IndexOf ('\\', createFrom); 
                if (iPos >= 0)
                { 
                    throw new ArgumentException (SR.Get (SRID.NoBackSlash, "createFrom"), "createFrom"); 
                }
                createFrom = iPos; 
            }

            // Skip any '\' (also at start to cope with \\machine network paths
            while (sPath [createFrom] == '\\') 
            {
                createFrom++; 
            } 

            for (int iStart = createFrom; iStart < sPath.Length; iStart++) 
            {
                // Scan thought path. Each time reach a '\', copy section and try and create directory
                if (sPath [iStart] == '\\')
                { 
                    // Copy last section and trailing slash
                    string dstrIncrementalPath = sPath.Substring (0, iStart); 
 
                    if (!Directory.Exists (dstrIncrementalPath))
                    { 
                        Directory.CreateDirectory (dstrIncrementalPath);
                    }
                }
            } 

            if (!Directory.Exists (sPath)) 
            { 
                Directory.CreateDirectory (sPath);
            } 
        }


        ///  
        /// Given the file specifier string and nFolder value, convert to a reg key and file path.
        ///  
        ///  
        /// 
        ///  
        /// 
        private static void FileSpecifierToRegPath (string sFileSpecifier, Environment.SpecialFolder nFolder, out string dstrFilePath, out string dstrRegPath)
        {
            // Make sure return strings are empty 
            dstrFilePath = null;
            dstrRegPath = null; 
 
            // Is it a "X:\" path or a "\\" path
            if (sFileSpecifier != null && sFileSpecifier.Length >= 3 && (sFileSpecifier.IndexOf (":\\", 1) == 1 || sFileSpecifier.IndexOf ("\\\\") == 0)) 
            {
                // Find last '\' that separates path from base file
                int iBaseFile = sFileSpecifier.LastIndexOf ('\\');
                iBaseFile++; 

                // dstrFilePath holds the path with trailing '\' 
                dstrFilePath = sFileSpecifier.Substring (0, iBaseFile); 
                CreatePath (dstrFilePath, 0);
 
                // Calculate the new filename
                string sFile = GenerateFileName (dstrFilePath, sFileSpecifier.Substring (iBaseFile + 1));

                // Add fileName to path and copy to reg key 
                dstrFilePath = dstrFilePath + @"\" + sFile;
                dstrRegPath = dstrFilePath; 
            } 

            // It's a relative path 
            else
            {
#if _WIN32_WCE
            string szPath = "\\Windows"; 
#else
                string szPath = Environment.GetFolderPath (nFolder); 
#endif 

                int ulCreateDirsFrom = szPath.Length; 

                // dstrFilePath holds the special folder path no trailing '\'
                dstrFilePath = szPath + sFileStoragePath;
 
                // Make the %...% folder identifier
#if !_WIN32_WCE 
                string sFolder = string.Format (CultureInfo.InvariantCulture, "%{0}%", (int) nFolder); 
#else
        string sFolder = "\\Windows"; 
#endif

                // Add the %...% and path into reg data.
                dstrRegPath = sFolder + sFileStoragePath; 

                // both dstrRegPath and dstrFilePath have trailing '\' 
 
                // Now add any fileNameSpecifier directories
                int iBaseFile; 
                if (sFileSpecifier == null || sFileSpecifier.Length == 0)
                {
                    iBaseFile = 0;
                } 
                else
                { 
                    iBaseFile = sFileSpecifier.LastIndexOf ('\\'); 
                    if (iBaseFile > 0)
                    { 
                        // Specifier contains '\'
                        iBaseFile++; // part after last '\' becomes base file

                        int iStart = 0; 
                        if (sFileSpecifier [0] == '\\')
                        { 
                            iStart++; // Skip initial '\' 
                        }
 
                        // Add file specifier path to file and key
                        dstrFilePath = dstrRegPath = sFileSpecifier.Substring (iStart, iBaseFile - iStart + 1);
                    }
                } 

                // Create any new directories 
                CreatePath (dstrFilePath, ulCreateDirsFrom); 

                // Generate the actual file name 
                string sFile = GenerateFileName (dstrFilePath, sFileSpecifier.Substring (iBaseFile + 1, sFileSpecifier.Length - iBaseFile + 1));

                // Add file name to path and reg key
                dstrRegPath += sFile; 

                dstrFilePath += sFile; 
            } 
        }
 
        /// 
        /// Given a file storage value from the registry, convert to a file path.
        /// This will extract the %...% value and finds the local special folder path.
        ///  
        /// 
        ///  
        private static void RegPathToFilePath (string sRegPath, out string dstrFilePath) 
        {
            // Is this a reference to a special folder 
            if (sRegPath [0] == '%')
            {
                // Find the second % symbol
                int iPosPercent = sRegPath.LastIndexOf ('%'); 

                // Convert the string between the %s to a number 
                int nFolder = 0; 
                if (!int.TryParse (sRegPath.Substring (iPosPercent, iPosPercent - 1), out nFolder))
                { 
                    throw new ArgumentException (SR.Get (SRID.InvalidRegistryEntry, "sRegPath"), "sRegPath");
                }

                // Point to start of real path '\' 
                if (sRegPath [++iPosPercent] != '\\')
                { 
                    throw new ArgumentException (SR.Get (SRID.InvalidRegistryEntry, "sRegPath"), "sRegPath"); 
                }
 
#if _WIN32_WCE
        string szPath = @"\Windows";
#else
                string szPath = Environment.GetFolderPath ((Environment.SpecialFolder) nFolder); 
#endif
 
                // filePath now has the special folder path (with no trailing '\') 
                dstrFilePath = szPath + sRegPath.Substring (iPosPercent, sRegPath.Length - iPosPercent);
            } 
            else
            {
                // Not a special folder so just copy
                dstrFilePath = sRegPath; 
            }
        } 
 
#if false
/**************************************************************************** 
* CSpObjectToken__DisplayUI *
*---------------------------*
*   Description:
*       Display the specified type of UI 
*
*   Return: 
*   S_OK on success 
*   FAILED(hr) otherwise
******************************************************************** robch */ 
private void DisplayUI(
    HWND hwndParent,
    string sTitle,
    string sTypeOfUI, 
    object pvExtraData,
    uint cbExtraData, 
    object punkObject) 
{
    // SPDBG_FUNC("CSpObjectToken::DisplayUI"); 
    HRESULT hr;
    CLSID clsidObject;

    if (m_fKeyDeleted) 
    {
		// TODO 
 		throw new ObjectTokenException(SR.Get (SRID.TokenDeleted)); 
    }
    else if (!IsWindow(hwndParent) || 
             SP_IS_BAD_OPTIONAL_STRING_PTR(sTitle) ||
             SP_IS_BAD_STRING_PTR(sTypeOfUI) ||
             (pvExtraData != null && SPIsBadReadPtr(pvExtraData, cbExtraData)) ||
             (punkObject != null && SP_IS_BAD_INTERFACE_PTR(punkObject))) 
    {
        E_INVALIDARG; 
    } 
    else if (m_cpTokenDelegate != null)
    { 
        // NTRAID#SPEECH-7392-2000/08/31-robch: Maybe we should first delegate, and if that doesn't work,
        // try this token's category ui...
        m_cpTokenDelegate.DisplayUI(
                    hwndParent, 
                    sTitle,
                    sTypeOfUI, 
                    pvExtraData, 
                    cbExtraData,
                    punkObject); 
    }
    else
    {
        GetUIObjectClsid(sTypeOfUI, &clsidObject); 

        ISpTokenUI cpTokenUI = cpTokenUI.CoCreateInstance(clsidObject); 
 
        cpTokenUI.DisplayUI(
                            hwndParent, 
                            sTitle,
                            sTypeOfUI,
                            pvExtraData,
                            cbExtraData, 
                            this,
                            punkObject); 
    } 

    SPDBG_REPORT_ON_FAIL(hr); 
    return hr;
}
#endif
 
        /// 
        /// Open the "Files" subkey of a specified data key's caller's sub key 
        ///  
        /// 
        ///  
        /// 
        private ObjectToken OpenFilesKey (Guid clsidCaller, bool fCreateKey)
        {
            // SPDBG_FUNC("CSpObjectToken::OpenFilesKey"); 

            ObjectToken cpClsidKey; 
 
            // Convert the string clsid to a real clsid
            string dstrCLSID = clsidCaller.ToString (); 

            // Either create the data key or open it
            if (fCreateKey)
            { 
                cpClsidKey = (ObjectToken) CreateKey (dstrCLSID);
            } 
            else 
            {
                cpClsidKey = (ObjectToken) OpenKey (dstrCLSID); 
            }

            // Either crate the files data key or open it
            ObjectToken ppKey; 

            if (fCreateKey) 
            { 
                ppKey = (ObjectToken) cpClsidKey.CreateKey (SPTOKENKEY_FILES);
            } 
            else
            {
                ppKey = (ObjectToken) cpClsidKey.OpenKey (SPTOKENKEY_FILES);
            } 
            return ppKey;
        } 
 
        /// 
        /// Delete either a specific file (specified by sValueName) or all files 
        /// (when sValueName == null) from the specified data key
        /// 
        /// 
        ///  
        private void DeleteFileFromKey (ObjectToken pDataKey, string sValueName)
        { 
            // SPDBG_FUNC("CSpObjectToken::DeleteFileFromKey"); 

            // If the value name wasn't specified, we'll delete all the value's files 
            if (sValueName == null)
            {
                // Loop thru the values
                foreach (RegistryEntry regEntry in (IEnumerable) pDataKey) 
                {
                    try 
                    { 
                        // Delete the file
                        DeleteFileFromKey (pDataKey, (string) regEntry.Value); 
                    }
                    catch (IOException)
                    {
                        // ignore the File IO exception 
                    }
                } 
            } 
            else
            { 
                // Get the filename
                string sFile;
                string dstrRegPath = pDataKey.GetString (sValueName);
 
                // Convert the path stored in the registry to a real file path
                RegPathToFilePath (dstrRegPath, out sFile); 
 
                // And delete the file
                // Ignore errors from DeleteFile, we can't let this stop us 
                try
                {
                    File.Delete (sFile);
                } 
                catch (IOException)
                { 
                } 
            }
        } 

        /// 
        /// Remove all filenames for a specified caller, or for all callers
        /// if pclsidCaller is null. 
        /// 
        ///  
        private void RemoveAllStorageFileNames (Guid pclsidCaller) 
        {
            // SPDBG_FUNC("CSpObjectToken::RemoveAllStorageFileNames"); 

            // If the clsid wasn't specified, we'll delete all files from all
            // keys that are clsids
            if (pclsidCaller == Guid.Empty) 
            {
                // Loop thru all the keys 
                for (int i = 0; ; i++) 
                {
                    // Get the next sub key 
                    //TODO
                    string dstrSubKey = null; //((ObjectToken) this).EnumKeys (i);
                    if (dstrSubKey != null)
                    { 
                        break;
                    } 
 
                    // If this key looks like a clsid, and it is, recursively call
                    // this function to delete the specific clsid's files 
                    Guid clsid = new Guid (dstrSubKey);
                    RemoveAllStorageFileNames (clsid);
                }
            } 
            else
            { 
                // Open the files data key, and delete all the files 
                ObjectToken cpFilesKey = OpenFilesKey (pclsidCaller, false);
                { 
                    try
                    {
                        DeleteFileFromKey (cpFilesKey, null);
                    } 
                    catch (SystemException)
                    { 
                        // If we failed to delete this file then that should not stop us from deleting the other files. 
                    }
                } 
            }
        }

#endif 

        ///  
        /// Description: 
        ///     Parse a token id into it's parts. For example:
        /// 
        ///         sCategoryId   = HKEY...\Recognizers
        ///         sTokenId      = HKEY...\Recognizers\Tokens\MSASR English
        ///
        ///         *ppszCategoryId     = HKEY...\Recognizers 
        ///         *ppszTokenId        = HKEY...\Recognizers\Tokens\MSASR English
        ///         *ppszTokenIdForEnum = null 
        ///         *ppszTokenEnumExtra = null 
        ///
        ///     or 
        ///
        ///         sCategoryId = HKEY...\AudioIn
        ///         sTokenId =    HKEY...\AudioIn\TokenEnums\DSound
        /// 
        ///         *ppszCategoryId     = HKEY...\AudioIn
        ///         *ppszTokenId        = HKEY...\AudioIn\TokenEnums\DSound 
        ///         *ppszTokenIdForEnum = HKEY...\AudioIn\TokenEnums\DSound 
        ///         *ppszTokenEnumExtra = null
        /// 
        ///     or
        ///
        ///         sCategoryId = HKEY...\AudioIn
        ///         sTokenId =    HKEY...\AudioIn\TokenEnums\DSound\CrystalWave 
        ///
        ///         *ppszCategoryId     = HKEY...\AudioIn 
        ///         *ppszTokenId        = HKEY...\AudioIn\TokenEnums\DSound\CrystalWave 
        ///         *ppszTokenIdForEnum = HKEY...\AudioIn\TokenEnums\DSound
        ///         *ppszTokenEnumExtra = CrystalWave 
        ///
        ///     sCategoryId can be null. If it is, we'll calculate the category id
        ///     by finding the first occurrence of either "Tokens" or "TokenEnums"
        ///     The category id will immediately proceed that. 
        /// 
        ///  
        ///  
        private static bool ParseRegistryString (string sCategoryId, string sTokenId)
        { 
            // If the caller supplied a category, we already know how big it is
            int cchCategoryId = 0;
            if (!string.IsNullOrEmpty (sCategoryId))
            { 
                cchCategoryId = sCategoryId.Length;
                if (sTokenId.Length < sCategoryId.Length || string.Compare (sTokenId.Substring (0, cchCategoryId), sCategoryId, StringComparison.OrdinalIgnoreCase) != 0) 
                { 
                    // The tokenid wasn't prefaced with the category id, a must
                    return false; 
                }
            }

            string sSlashTokensSlash = "Tokens"; 

            int iFirst = cchCategoryId; 
            int cchTokenId = sTokenId.Length; 
            while (iFirst < sTokenId.Length)
            { 
                int iSecond = sTokenId.IndexOf ('\\', iFirst);
                if (iSecond < 0)
                {
                    iSecond = cchTokenId; 
                }
 
                // name between '/' '/' 
                string sEntry = sTokenId.Substring (iFirst, iSecond - iFirst);
 
                if (string.Compare (sEntry, sSlashTokensSlash, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    cchCategoryId = iFirst;
                    break; 
                }
                else if (cchCategoryId > 0) 
                { 
                    break;
                } 
                else
                {
                    iFirst = iSecond + 1;
                } 
            }
 
            if (cchCategoryId == 0) 
            {
                int iPosCategory = sTokenId.LastIndexOf ('\\'); 
                if (iPosCategory < 0)
                {
                    return false;
                } 
                else
                { 
                    cchCategoryId = iPosCategory; 
                }
            } 

            if (cchCategoryId <= 0)
            {
                return false; 
            }
            return true; 
        } 

#if VSCOMPILE && false 

        /// 
        /// Get the UI object's clsid from the registry. First check under the
        /// token's root, then under the category 
        /// 
        ///  
        ///  
        private Guid GetUIObjectClsid (string sTypeOfUI)
        { 
            // SPDBG_FUNC("CSpObjectToken::GetUIObjectClsid");

            // We'll try and retrive the CLSID as a string from the token ui registry
            // key, then from the category ui registry key. We'll convert to an actual 
            // GUID at the end of the function
            string dstrClsid = null; 
 
            //--- Try getting the clsid from token's UI key
            ObjectToken cpTokenUI = (ObjectToken) OpenKey (SPTOKENKEY_UI); 

            ObjectToken cpType = (ObjectToken) cpTokenUI.OpenKey (sTypeOfUI);
            if (cpType.TryGetString (SPTOKENVALUE_CLSID, out dstrClsid))
            { 
                //--- Try getting the clsid from the category's UI key
                if (CategoryId != null) 
                { 
                    ObjectTokenCategory cpCategory = CategoryFromId (CategoryId, false);
 
                    ObjectToken cpTokenUI2 = (ObjectToken) cpCategory.OpenKey (SPTOKENKEY_UI);
                    {
                        ObjectToken cpType2 = (ObjectToken) cpTokenUI2.OpenKey (sTypeOfUI);
                        dstrClsid = cpType2.GetString (SPTOKENVALUE_CLSID); 
                    }
                } 
            } 

            // If we were successful at getting the clsid, convert it 
            return new Guid (dstrClsid);
        }

#endif 

        #endregion 
 
        //*******************************************************************
        // 
        // Private Types
        //
        //*******************************************************************
 
        #region Private Types
 
        //--- ISpObjectWithToken ---------------------------------------------------- 
        [ComImport, Guid ("5B559F40-E952-11D2-BB91-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
        interface ISpObjectWithToken 
        {
            [PreserveSig]
            int SetObjectToken (ISpObjectToken pToken);
            [PreserveSig] 
            int GetObjectToken (IntPtr ppToken);
        }; 
 
#if SPEECHSERVER
        //--- ISpObjectWithTokenMss ---------------------------------------------------- 
        // This interface is necessary to support "pre-private-SAPI" for MSS (still used by TTS voices)
        // When querying for ISpObjectWithToken interface, ISpObjectWithTokenMss should be tried if QueryInterface for ISpObjectWithToken fails.
        [ComImport, Guid ("5C559F40-E952-11D2-BB91-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
        interface ISpObjectWithTokenMss 
        {
            [PreserveSig] 
            int SetObjectToken (ISpObjectTokenMss pToken); 
            [PreserveSig]
            int GetObjectToken (IntPtr ppToken); 
        };
#endif
        #endregion
 
        //*******************************************************************
        // 
        // Private Fields 
        //
        //******************************************************************* 

        #region private Fields

        // Specifier used to generate a random filename. 
        private const string sGenerateFileNameSpecifier = "{0}";
 
        private const string SPTOKENVALUE_CLSID = "CLSID"; 

        private RegistryDataKey _attributes; 

#if VSCOMPILE

        // Prefix used for storage files if not otherwise set 
        private const string sDefaultFilePrefix = "SP_";
 
        // Extension used for storage files if not otherwise set 
        private const string sDefaultFileSuffix = ".dat";
 
        private const string SPTOKENKEY_FILES = "Files";

        private const string SPTOKENKEY_UI = "UI";
 
        // Relative path below special folders where storage files are stored
        private const string sFileStoragePath = "\\Microsoft\\Speech\\Files\\"; 
 
#endif
        #endregion 
    }

    #region SAPI interface
 
#if SPEECHSERVER
    // This interface is necessary to support "pre-private-SAPI" for MSS (still used by TTS voices) 
    [ComImport, Guid ("15056589-E16C-11D2-BB90-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface ISpObjectTokenMss : ISpDataKey
    { 
        // ISpDataKey Methods
        [PreserveSig]
        new int SetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 cbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] Byte [] pData);
        [PreserveSig] 
        new int GetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pcbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte [] pData);
        [PreserveSig] 
        new int SetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] string pszValue); 
        [PreserveSig]
        new int GetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValue); 
        [PreserveSig]
        new int SetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 dwValue);
        [PreserveSig]
        new int GetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pdwValue); 
        [PreserveSig]
        new int OpenKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKeyName, out ISpDataKey ppSubKey); 
        [PreserveSig] 
        new int CreateKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey, out ISpDataKey ppSubKey);
        [PreserveSig] 
        new int DeleteKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey);
        [PreserveSig]
        new int DeleteValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName);
        [PreserveSig] 
        new int EnumKeys (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszSubKeyName);
        [PreserveSig] 
        new int EnumValues (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValueName); 

        // ISpObjectToken Methods 
        void SetId ([MarshalAs (UnmanagedType.LPWStr)] string pszCategoryId, [MarshalAs (UnmanagedType.LPWStr)] string pszTokenId, [MarshalAs (UnmanagedType.Bool)] bool fCreateIfNotExist);
        void GetId (out IntPtr ppszCoMemTokenId);
        void Slot15 (); // void GetCategory(out ISpObjectTokenCategory ppTokenCategory);
        void Slot16 (); // void CreateInstance(object pUnkOuter, UInt32 dwClsContext, ref Guid riid, ref IntPtr ppvObject); 
        void Slot17 (); // void GetStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszValueName, [MarshalAs(UnmanagedType.LPWStr)] string pszFileNameSpecifier, UInt32 nFolder, [MarshalAs(UnmanagedType.LPWStr)] out string ppszFilePath);
        void Slot18 (); // void RemoveStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszKeyName, int fDeleteFile); 
        void Slot19 (); // void Remove(ref Guid pclsidCaller); 
        void Slot20 (); // void IsUISupported([MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject, ref Int32 pfSupported);
        void Slot21 (); // void DisplayUI(UInt32 hWndParent, [MarshalAs(UnmanagedType.LPWStr)] string pszTitle, [MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject); 
        void MatchesAttributes ([MarshalAs (UnmanagedType.LPWStr)] string pszAttributes, [MarshalAs (UnmanagedType.Bool)] out bool pfMatches);
    }
#endif
 
    [ComImport, Guid ("14056589-E16C-11D2-BB90-00C04F8EE6C0"), InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISpObjectToken : ISpDataKey 
    { 
        // ISpDataKey Methods
        [PreserveSig] 
        new int SetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 cbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] Byte [] pData);
        [PreserveSig]
        new int GetData ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pcbData, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte [] pData);
        [PreserveSig] 
        new int SetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] string pszValue);
        [PreserveSig] 
        new int GetStringValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValue); 
        [PreserveSig]
        new int SetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, UInt32 dwValue); 
        [PreserveSig]
        new int GetDWORD ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName, ref UInt32 pdwValue);
        [PreserveSig]
        new int OpenKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKeyName, out ISpDataKey ppSubKey); 
        [PreserveSig]
        new int CreateKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey, out ISpDataKey ppSubKey); 
        [PreserveSig] 
        new int DeleteKey ([MarshalAs (UnmanagedType.LPWStr)] string pszSubKey);
        [PreserveSig] 
        new int DeleteValue ([MarshalAs (UnmanagedType.LPWStr)] string pszValueName);
        [PreserveSig]
        new int EnumKeys (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszSubKeyName);
        [PreserveSig] 
        new int EnumValues (UInt32 Index, [MarshalAs (UnmanagedType.LPWStr)] out string ppszValueName);
 
        // ISpObjectToken Methods 
        void SetId ([MarshalAs (UnmanagedType.LPWStr)] string pszCategoryId, [MarshalAs (UnmanagedType.LPWStr)] string pszTokenId, [MarshalAs (UnmanagedType.Bool)] bool fCreateIfNotExist);
        void GetId (out IntPtr ppszCoMemTokenId); 
        void Slot15 (); // void GetCategory(out ISpObjectTokenCategory ppTokenCategory);
        void Slot16 (); // void CreateInstance(object pUnkOuter, UInt32 dwClsContext, ref Guid riid, ref IntPtr ppvObject);
        void Slot17 (); // void GetStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszValueName, [MarshalAs(UnmanagedType.LPWStr)] string pszFileNameSpecifier, UInt32 nFolder, [MarshalAs(UnmanagedType.LPWStr)] out string ppszFilePath);
        void Slot18 (); // void RemoveStorageFileName(ref Guid clsidCaller, [MarshalAs(UnmanagedType.LPWStr)] string pszKeyName, int fDeleteFile); 
        void Slot19 (); // void Remove(ref Guid pclsidCaller);
        void Slot20 (); // void IsUISupported([MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject, ref Int32 pfSupported); 
        void Slot21 (); // void DisplayUI(UInt32 hWndParent, [MarshalAs(UnmanagedType.LPWStr)] string pszTitle, [MarshalAs(UnmanagedType.LPWStr)] string pszTypeOfUI, IntPtr pvExtraData, UInt32 cbExtraData, object punkObject); 
        void MatchesAttributes ([MarshalAs (UnmanagedType.LPWStr)] string pszAttributes, [MarshalAs (UnmanagedType.Bool)] out bool pfMatches);
    } 

    #endregion
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK