IsolatedStorageFile.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / BCL / System / IO / IsolatedStorage / IsolatedStorageFile.cs / 1 / IsolatedStorageFile.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
 * 
 * Class:  IsolatedStorageFile 
 *
 * 
 * Purpose: Provides access to Application files and folders
 *
 * Date:  Feb 18, 2000
 * 
 ===========================================================*/
namespace System.IO.IsolatedStorage { 
    using System; 
    using System.Text;
    using System.IO; 
    using Microsoft.Win32;
    using Microsoft.Win32.SafeHandles;
    using System.Collections;
    using System.Security; 
    using System.Threading;
    using System.Security.Policy; 
    using System.Security.Permissions; 
    using System.Security.Cryptography;
    using System.Runtime.InteropServices; 
    using System.Runtime.CompilerServices;
    using System.Runtime.Versioning;
    using System.Globalization;
 
[System.Runtime.InteropServices.ComVisible(true)]
    public sealed class IsolatedStorageFile : IsolatedStorage, IDisposable 
    { 
        private  const int    s_BlockSize = 1024;
        private  const int    s_DirSize   = s_BlockSize; 
        private  const String s_name      = "file.store";
        internal const String s_Files     = "Files";
        internal const String s_AssemFiles= "AssemFiles";
        internal const String s_AppFiles= "AppFiles"; 
        internal const String s_IDFile    = "identity.dat";
        internal const String s_InfoFile  = "info.dat"; 
        internal const String s_AppInfoFile  = "appinfo.dat"; 

        private static String s_RootDirUser; 
        private static String s_RootDirMachine;
        private static String s_RootDirRoaming;
        private static String s_appDataDir;
 
        private static FileIOPermission              s_PermUser;
        private static FileIOPermission              s_PermMachine; 
        private static FileIOPermission              s_PermRoaming; 
        private static IsolatedStorageFilePermission s_PermAdminUser;
 
        private FileIOPermission m_fiop;
        private String           m_RootDir;
        private String           m_InfoFile;
        private String           m_SyncObjectName; 
        private IntPtr           m_handle;
        private bool             m_closed; 
        private bool             m_bDisposed = false; 

#if _DEBUG 
        private static bool s_fDebug;
#endif

        internal IsolatedStorageFile() {} 

        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetUserStoreForDomain()
        { 
            return GetStore(
                IsolatedStorageScope.Assembly|
                IsolatedStorageScope.Domain|
                IsolatedStorageScope.User, 
                null, null);
        } 
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetUserStoreForAssembly()
        {
            return GetStore(
                IsolatedStorageScope.Assembly| 
                IsolatedStorageScope.User,
                null, null); 
        } 

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetUserStoreForApplication()
        {
            return GetStore( 
                IsolatedStorageScope.Application|
                IsolatedStorageScope.User, 
                null); 
        }
 
        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetMachineStoreForDomain()
        { 
            return GetStore(
                IsolatedStorageScope.Assembly| 
                IsolatedStorageScope.Domain| 
                IsolatedStorageScope.Machine,
                null, null); 
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetMachineStoreForAssembly()
        { 
            return GetStore( 
                IsolatedStorageScope.Assembly|
                IsolatedStorageScope.Machine, 
                null, null);
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetMachineStoreForApplication() 
        { 
            return GetStore(
                IsolatedStorageScope.Application| 
                IsolatedStorageScope.Machine,
                null);
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, 
            Type domainEvidenceType, Type assemblyEvidenceType)
        { 
            if (domainEvidenceType != null)
                DemandAdminPermission();

            IsolatedStorageFile sf = new IsolatedStorageFile(); 
            sf.InitStore(scope, domainEvidenceType, assemblyEvidenceType);
            sf.Init(scope); 
            return sf; 
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope,
            Object domainIdentity, Object assemblyIdentity) 
        {
            // Verify input params. 
            if (IsDomain(scope) && (domainIdentity == null)) 
                throw new ArgumentNullException("domainIdentity");
 
            if (assemblyIdentity == null)
                throw new ArgumentNullException("assemblyIdentity");

            DemandAdminPermission(); 

            IsolatedStorageFile sf = new IsolatedStorageFile(); 
            sf.InitStore(scope, domainIdentity, assemblyIdentity, null); 
            sf.Init(scope);
 
            return sf;
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, 
            Evidence domainEvidence, Type  domainEvidenceType, 
            Evidence assemblyEvidence, Type assemblyEvidenceType)
        { 
            // Verify input params.
            if (IsDomain(scope) && (domainEvidence == null))
                throw new ArgumentNullException("domainEvidence");
 
            if (assemblyEvidence == null)
                throw new ArgumentNullException("assemblyEvidence"); 
 
            DemandAdminPermission();
 
            IsolatedStorageFile sf = new IsolatedStorageFile();
            sf.InitStore(scope, domainEvidence, domainEvidenceType,
                assemblyEvidence, assemblyEvidenceType, null, null);
            sf.Init(scope); 

            return sf; 
        } 

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope,
                                                                    Type applicationEvidenceType)
        { 
            if (applicationEvidenceType != null)
                DemandAdminPermission(); 
 
            IsolatedStorageFile sf = new IsolatedStorageFile();
            sf.InitStore(scope, applicationEvidenceType); 
            sf.Init(scope);
            return sf;
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, 
                                                                    Object applicationIdentity)
        { 
            if (applicationIdentity == null)
                throw new ArgumentNullException("applicationIdentity");

            DemandAdminPermission(); 

            IsolatedStorageFile sf = new IsolatedStorageFile(); 
            sf.InitStore(scope, null, null, applicationIdentity); 
            sf.Init(scope);
 
            return sf;
        }

        [CLSCompliant(false)] 
        public override ulong CurrentSize
        { 
            get { 
                if (IsRoaming())
                    throw new InvalidOperationException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_CurrentSizeUndefined"));

                lock (this) 
                {
                    if (m_bDisposed) 
                        throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen")); 

                    if (m_closed) 
                        throw new InvalidOperationException(
                            Environment.GetResourceString(
                                "IsolatedStorage_StoreNotOpen"));
 
                    if (m_handle == Win32Native.NULL)
                        m_handle = nOpen(m_InfoFile, GetSyncObjectName()); 
 
                    return nGetUsage(m_handle);
                } 
            }
        }

        [CLSCompliant(false)] 
        public override ulong MaximumSize
        { 
            get 
            {
                if (IsRoaming()) 
                    return Int64.MaxValue;

                return base.MaximumSize;
            } 
        }
 
        internal unsafe void Reserve(ulong lReserve) 
        {
            if (IsRoaming())  // No Quota enforcement for roaming 
                return;

            ulong quota = this.MaximumSize;
            ulong reserve = lReserve; 

            lock (this) 
            { 
                if (m_bDisposed)
                    throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen")); 

                if (m_closed)
                    throw new InvalidOperationException(
                        Environment.GetResourceString( 
                            "IsolatedStorage_StoreNotOpen"));
 
                if (m_handle == Win32Native.NULL) 
                    m_handle = nOpen(m_InfoFile, GetSyncObjectName());
 
                nReserve(m_handle, "a, &reserve, false);
            }
        }
 
        internal unsafe void Unreserve(ulong lFree)
        { 
            if (IsRoaming())  // No Quota enforcement for roaming 
                return;
 
            ulong quota = this.MaximumSize;
            ulong free = lFree;

            lock (this) 
            {
                if (m_bDisposed) 
                    throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen")); 

                if (m_closed) 
                    throw new InvalidOperationException(
                        Environment.GetResourceString(
                            "IsolatedStorage_StoreNotOpen"));
 
                if (m_handle == Win32Native.NULL)
                    m_handle = nOpen(m_InfoFile, GetSyncObjectName()); 
 
                nReserve(m_handle, "a, &free, true);
            } 
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public void DeleteFile(String file)
        { 
            if (file == null) 
                throw new ArgumentNullException("file");
 
            m_fiop.Assert();
            m_fiop.PermitOnly();

            FileInfo f = new FileInfo(GetFullPath(file)); 
            long oldLen = 0;
 
            Lock(); // protect oldLen 

            try { 
                try {
                    oldLen = f.Length;
                    f.Delete();
                } catch { 
                    throw new IsolatedStorageException(
                        Environment.GetResourceString( 
                            "IsolatedStorage_DeleteFile")); 
                }
                Unreserve(RoundToBlockSize((ulong)oldLen)); 
            } finally {
                Unlock();
            }
            CodeAccessPermission.RevertAll(); 

        } 
 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public void CreateDirectory(String dir)
        {
            if (dir == null)
                throw new ArgumentNullException("dir"); 

            String isPath = GetFullPath(dir); // Prepend IS root 
 
            String fullPath = Path.GetFullPathInternal(isPath);
 
            String [] dirList = DirectoriesToCreate(fullPath);

            if (dirList == null || dirList.Length == 0)
            { 
                if (Directory.Exists(isPath))
                    return; 
                else 
                    throw new IsolatedStorageException(
                        Environment.GetResourceString( 
                            "IsolatedStorage_CreateDirectory"));
            }
            Reserve(s_DirSize*((ulong)dirList.Length));
            m_fiop.Assert(); 
            m_fiop.PermitOnly();
            try { 
                Directory.CreateDirectory(dirList[dirList.Length-1]); 
            } catch {
                Unreserve(s_DirSize*((ulong)dirList.Length)); 
                // force delete any new directories we created
                Directory.Delete(dirList[0],true);
                throw new IsolatedStorageException(
                    Environment.GetResourceString( 
                        "IsolatedStorage_CreateDirectory"));
            } 
            CodeAccessPermission.RevertAll(); 

        } 

        // Given a path to a dir to create, will return the list of directories to create and the last one in the array is the actual dir to create.
        // for example if dir is a\\b\\c and none of them exist, the list returned will be a, a\\b, a\\b\\c.
        private String[] DirectoriesToCreate(String fullPath) 
        {
 
            ArrayList list = new ArrayList(); 
            int length = fullPath.Length;
 
            // We need to trim the trailing slash or the code will try to create 2 directories of the same name.
            if (length >= 2 && fullPath[length - 1] == SeparatorExternal)
                length--;
            int i = Path.GetRootLength(fullPath); 

            // Attempt to figure out which directories don't exist 
            while (i < length) { 
                i++;
                while (i < length && fullPath[i] != SeparatorExternal) 
                    i++;
                String currDir = fullPath.Substring(0, i);

                if (!Directory.InternalExists(currDir)) 
                { // Create only the ones missing
                    list.Add(currDir); 
                } 
            }
 
            if (list.Count != 0)
            {
                return (String[])list.ToArray(typeof(String));
            } 
            return null;
        } 
 
        public void DeleteDirectory(String dir)
        { 
            if (dir == null)
                throw new ArgumentNullException("dir");

            m_fiop.Assert(); 
            m_fiop.PermitOnly();
 
            Lock(); // Delete *.*, will beat quota enforcement without this lock 

            try { 
                try {
                    new DirectoryInfo(GetFullPath(dir)).Delete(false);
                } catch {
                    throw new IsolatedStorageException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_DeleteDirectory")); 
                } 
                Unreserve(s_DirSize);
            } finally { 
                Unlock();
            }
            CodeAccessPermission.RevertAll();
        } 

        /* 
         * foo\abc*.txt will give all abc*.txt files in foo directory 
         */
        public String[] GetFileNames(String searchPattern) 
        {
            if (searchPattern == null)
                throw new ArgumentNullException("searchPattern");
 
            m_fiop.Assert();
            m_fiop.PermitOnly(); 
            String[] retVal = GetFileDirectoryNames(GetFullPath(searchPattern), searchPattern, true); 
            CodeAccessPermission.RevertAll();
            return retVal; 

        }

        /* 
         * foo\data* will give all directory names in foo directory that
         * starts with data 
         */ 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage.
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public String[] GetDirectoryNames(String searchPattern)
        {
            if (searchPattern == null)
                throw new ArgumentNullException("searchPattern"); 

            m_fiop.Assert(); 
            m_fiop.PermitOnly(); 
            String[] retVal = GetFileDirectoryNames(GetFullPath(searchPattern), searchPattern, false);
            CodeAccessPermission.RevertAll(); 
            return retVal;
        }

        // Remove this individual store 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage.
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public override void Remove() 
        {
            // No security check required here since we have already done 
            // that during creation

            String rootDir, domainRoot = null;
 
            // First remove the logical root directory of this store, this
            // will not delete the quota file. Removes all the files and dirs 
            // that applications see. 

            RemoveLogicalDir(); 

            Close();

            // Now try to remove other files folders that become unnecessary 
            // if the application directory is deleted.
 
            StringBuilder sb = new StringBuilder(); 

            sb.Append(GetRootDir(this.Scope)); 

            if (IsApp())
            {
                sb.Append(this.AppName); 
                sb.Append(this.SeparatorExternal);
            } 
            else 
            {
                if (IsDomain()) 
                {
                    sb.Append(this.DomainName);
                    sb.Append(this.SeparatorExternal);
                    domainRoot = sb.ToString(); 
                }
 
                sb.Append(this.AssemName); 
                sb.Append(this.SeparatorExternal);
            } 
            rootDir = sb.ToString();

            new FileIOPermission(
                FileIOPermissionAccess.AllAccess, rootDir).Assert(); 

            if (ContainsUnknownFiles(rootDir)) 
                return; 

            try { 

                Directory.Delete(rootDir, true);
#if _DEBUG
            } catch (Exception e) { 

                if (s_fDebug) 
                { 
                    Console.WriteLine(e);
                    Console.WriteLine("Delete failed on rootdir"); 
                }
#else
            } catch {
#endif 
                return; // OK to ignore this exception.
            } 
 
            // If this was a domain store, and if this happens to be
            // the only store around, then delete the root store for this 
            // domain

            if (IsDomain())
            { 
                CodeAccessPermission.RevertAssert();
 
                new FileIOPermission( 
                    FileIOPermissionAccess.AllAccess, domainRoot).Assert();
 
                if (!ContainsUnknownFiles(domainRoot))
                {

                    try { 

                        Directory.Delete(domainRoot, true); 
#if _DEBUG 
                    } catch (Exception e) {
 
                        if (s_fDebug)
                        {
                            Console.WriteLine(e);
                            Console.WriteLine("Delete failed on basedir"); 
                        }
#else 
                    } catch { 
#endif
                        return; // OK to ignore this exception. 
                    }
                }
            }
        } 

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        private void RemoveLogicalDir()
        { 
            m_fiop.Assert();

            ulong oldLen;
 
            Lock(); // A ---- here with delete dir/delete file can get around
                    // quota enforcement. 
 
            try {
                oldLen = IsRoaming() ? 0 : CurrentSize; 

                try {

                    Directory.Delete(RootDirectory, true); 
#if _DEBUG
                } catch (Exception e) { 
 
                    if (s_fDebug)
                    { 
                        Console.WriteLine(e);
                        Console.WriteLine("Delete failed on LogicalRooDir");
                    }
#else 
                    } catch {
#endif 
                    throw new IsolatedStorageException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_DeleteDirectories")); 
                }

                Unreserve(oldLen);
            } finally { 
                Unlock();
            } 
        } 

        private bool ContainsUnknownFiles(String rootDir) 
        {
            String[] dirs, files;

            // Delete everything in the root directory of this store 
            // if there are no Domain Stores / other files
            // Make sure that there are no other subdirs present here other 
            // than the ones used by IsolatedStorageFile (Cookies in future 
            // releases ?)
 
            try {
                files = GetFileDirectoryNames(rootDir + "*", "*", true);
                dirs = GetFileDirectoryNames(rootDir + "*", "*", false);
            } catch { 
                throw new IsolatedStorageException(
                    Environment.GetResourceString( 
                        "IsolatedStorage_DeleteDirectories")); 
            }
 
            // First see if there are any unkonwn Folders
            if ((dirs != null) && (dirs.Length > 0))
            {
                if (dirs.Length > 1) 
                {
                    // More than one directory present 
                    return true; 
                }
 
                if (IsApp())
                {
                    if (NotAppFilesDir(dirs[0]))
                        return true; 
                }
                else if (IsDomain()) 
                { 
                    if (NotFilesDir(dirs[0]))
                        return true; 
                }
                else
                {
                    if (NotAssemFilesDir(dirs[0])) 
                        return true;
                } 
            } 

            // Now look at the files 

            if ((files == null) || (files.Length == 0))
                return false;
 
            if (IsRoaming())
            { 
                if ((files.Length > 1) || NotIDFile(files[0])) 
                {
                    // There is one or more files unknown to this version 
                    // of IsoStoreFile

                    return true;
                } 

                return false; 
            } 

            if ((files.Length > 2) || 
                (NotIDFile(files[0]) && NotInfoFile(files[0])) ||
                ((files.Length == 2) &&
                NotIDFile(files[1]) && NotInfoFile(files[1])))
            { 
                // There is one or more files unknown to this version
                // of IsoStoreFile 
 
                return true;
            } 

            return false;
        }
 
        public void Close()
        { 
            if (IsRoaming()) 
                return;
 
            lock (this) {

                if (!m_closed) {
                    m_closed = true; 

                    IntPtr handle = m_handle; 
 
                    m_handle = Win32Native.NULL;
                    nClose(handle); 

                    GC.nativeSuppressFinalize(this);
                }
 
            }
        } 
 
        public void Dispose()
        { 
            Close();
            m_bDisposed = true;
        }
 
        ~IsolatedStorageFile()
        { 
            Dispose(); 
        }
 
        // Macros, expect JIT to expand this
        private static bool NotIDFile(String file)
        {
            return (String.Compare( 
                file, IsolatedStorageFile.s_IDFile, StringComparison.Ordinal) != 0);
        } 
 
        private static bool NotInfoFile(String file)
        { 
            return (
                String.Compare(file, IsolatedStorageFile.s_InfoFile, StringComparison.Ordinal) != 0 &&
                String.Compare(file, IsolatedStorageFile.s_AppInfoFile, StringComparison.Ordinal) != 0);
        } 

        private static bool NotFilesDir(String dir) 
        { 
            return (String.Compare(
                dir, IsolatedStorageFile.s_Files, StringComparison.Ordinal) != 0); 
        }

        internal static bool NotAssemFilesDir(String dir)
        { 
            return (String.Compare(
                dir, IsolatedStorageFile.s_AssemFiles, StringComparison.Ordinal) != 0); 
        } 

        internal static bool NotAppFilesDir(String dir) 
        {
            return (String.Compare(
                dir, IsolatedStorageFile.s_AppFiles, StringComparison.Ordinal) != 0);
        } 

        // Remove store for all identities 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        public static void Remove(IsolatedStorageScope scope) 
        {
            VerifyGlobalScope(scope);
            DemandAdminPermission();
 
            String rootDir = GetRootDir(scope);
 
            new FileIOPermission( 
                FileIOPermissionAccess.Write, rootDir).Assert();
 
            try {
                Directory.Delete(rootDir, true);    // Remove all sub dirs and files
                Directory.CreateDirectory(rootDir); // Recreate the root dir
            } catch { 
                throw new IsolatedStorageException(
                    Environment.GetResourceString( 
                        "IsolatedStorage_DeleteDirectories")); 
            }
        } 

        public static IEnumerator GetEnumerator(IsolatedStorageScope scope)
        {
            VerifyGlobalScope(scope); 
            DemandAdminPermission();
 
            return new IsolatedStorageFileEnumerator(scope); 
        }
 
        // Internal & private methods

        internal String RootDirectory
        { 
            get { return m_RootDir; }
        } 
 
        // RootDirectory has been scoped already.
        internal String GetFullPath(String path) 
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(this.RootDirectory); 

            if (path[0] == SeparatorExternal) 
                sb.Append(path.Substring(1)); 
            else
                sb.Append(path); 

            return sb.ToString();
        }
 
#if !FEATURE_PAL
        [SecurityPermissionAttribute(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)] 
        private static String GetDataDirectoryFromActivationContext() 
        {
            if (s_appDataDir == null) 
            {
                ActivationContext activationContext = AppDomain.CurrentDomain.ActivationContext;
                if (activationContext == null)
                    throw new IsolatedStorageException( 
                            Environment.GetResourceString(
                                "IsolatedStorage_ApplicationMissingIdentity")); 
                String dataDir = activationContext.DataDirectory; 
                if (dataDir != null)
                { 
                    //Append a '\' at the end if it already does not end with one
                    if (dataDir[dataDir.Length-1] != '\\')
                        dataDir = dataDir + "\\";
                } 
                s_appDataDir = dataDir;
            } 
            return s_appDataDir; 
        }
#endif 

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine | ResourceScope.Assembly)]
        internal void Init(IsolatedStorageScope scope) 
        {
            GetGlobalFileIOPerm(scope).Assert(); 
 
            StringBuilder sb = new StringBuilder();
 
            // Create the root directory if it is not already there


            if (IsApp(scope)) 
            {
#if FEATURE_PAL 
                throw new IsolatedStorageException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_ApplicationMissingIdentity")); 
#endif // !FEATURE_PAL

                sb.Append(GetRootDir(scope));
                if (s_appDataDir == null) 
                {
                    // We're not using the App Data directory...so we need to append AppName 
                    sb.Append(this.AppName); 
                    sb.Append(this.SeparatorExternal);
                } 

                try {

                    Directory.CreateDirectory(sb.ToString()); 

                    // No exception implies this directory was created now 
 

                } catch { 
                    // Ok to ignore IO exception

                }
                // Create the Identity blob file in the root 
                // directory. OK if there are more than one created
                // last one wins 
 
                CreateIDFile(sb.ToString(), scope);
 
                // For App Stores, accounting is done in the app root
                this.m_InfoFile = sb.ToString() + s_AppInfoFile;

                sb.Append(s_AppFiles); 

            } 
            else 
            {
                sb.Append(GetRootDir(scope)); 
                if (IsDomain(scope))
                {
                    sb.Append(this.DomainName);
                    sb.Append(this.SeparatorExternal); 

                    try { 
 
                        Directory.CreateDirectory(sb.ToString());
 
                        // No exception implies this directory was created now

                        // Create the Identity blob file in the root
                        // directory. OK if there are more than one created 
                        // last one wins
 
                        CreateIDFile(sb.ToString(), scope); 

                    } catch { 

                        // Ok to ignore IO exception

    #if false 
            // Leaving this commented for now for performance
 
                        // It is possible that a previous create directory 
                        // succeeded, but the Identity blob file was not
                        // created. Create it now. 

                        CreateIDFileIfNecessary(sb.ToString(), scope);
    #endif
                    } 

                    // For Domain Stores, accounting is done in the domain root 
                    this.m_InfoFile = sb.ToString() + s_InfoFile; 
                }
 
                sb.Append(this.AssemName);
                sb.Append(this.SeparatorExternal);

                try { 

                    Directory.CreateDirectory(sb.ToString()); 
 
                    // No exception implies this directory was created now
 
                    // Create the Identity blob file in the root
                    // directory. OK if there are more than one created
                    // last one wins
 
                    CreateIDFile(sb.ToString(), scope);
 
                } catch { 
                    // Ok to ignore IO exception
 
    #if false
            // Leaving this commented for now for performance

                    // It is possible that a previous create directory 
                    // succeeded, but the Identity blob file was not
                    // created. Create it now. 
 
                    CreateIDFileIfNecessary(sb.ToString(), scope);
    #endif 
                }

                if (IsDomain(scope))
                { 
                    sb.Append(s_Files);
                } 
                else 
                {
                    // For Assem Stores, accounting is done in the assem root 
                    this.m_InfoFile = sb.ToString() + s_InfoFile;

                    sb.Append(s_AssemFiles);
                } 
            }
            sb.Append(this.SeparatorExternal); 
 
            String rootDir = sb.ToString();
 
            try {
                Directory.CreateDirectory(rootDir);
            } catch {
                // Ok to ignore IO exception 
            }
 
            this.m_RootDir = rootDir; 

            // Use the "new" RootDirectory to create the permission. 
            // This instance of permission is not the same as the
            // one we just asserted. It uses this.base.RootDirectory.

            m_fiop = new FileIOPermission( 
                FileIOPermissionAccess.AllAccess, rootDir);
        } 
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        internal bool InitExistingStore(IsolatedStorageScope scope)
        {
            FileIOPermission fp;
            StringBuilder sb = new StringBuilder(); 

            sb.Append(GetRootDir(scope)); 
 
            if (IsApp(scope))
            { 
                sb.Append(this.AppName);
                sb.Append(this.SeparatorExternal);
                // For App Stores, accounting is done in the app root
                this.m_InfoFile = sb.ToString() + s_AppInfoFile; 

                sb.Append(s_AppFiles); 
            } 
            else
            { 
                if (IsDomain(scope))
                {
                    sb.Append(this.DomainName);
                    sb.Append(this.SeparatorExternal); 

                    // For Domain Stores, accounting is done in the domain root 
                    this.m_InfoFile = sb.ToString() + s_InfoFile; 
                }
 
                sb.Append(this.AssemName);
                sb.Append(this.SeparatorExternal);

                if (IsDomain(scope)) 
                {
                    sb.Append(s_Files); 
                } 
                else
                { 
                    // For Assem Stores, accounting is done in the assem root
                    this.m_InfoFile = sb.ToString() + s_InfoFile;

                    sb.Append(s_AssemFiles); 
                }
            } 
            sb.Append(this.SeparatorExternal); 

            fp = new FileIOPermission( 
                FileIOPermissionAccess.AllAccess, sb.ToString());

            fp.Assert();
 
            if (!Directory.Exists(sb.ToString()))
                return false; 
 
            this.m_RootDir = sb.ToString();
            this.m_fiop = fp; 

            return true;
        }
 
        protected override IsolatedStoragePermission GetPermission(
                PermissionSet ps) 
        { 
            if (ps == null)
                return null; 
            else if (ps.IsUnrestricted())
                return new IsolatedStorageFilePermission(
                        PermissionState.Unrestricted);
 
            return (IsolatedStoragePermission) ps.
                    GetPermission(typeof(IsolatedStorageFilePermission)); 
        } 

        internal void UndoReserveOperation(ulong oldLen, ulong newLen) 
        {
            oldLen = RoundToBlockSize(oldLen);
            if (newLen > oldLen)
                Unreserve(RoundToBlockSize(newLen - oldLen)); 
        }
 
        internal void Reserve(ulong oldLen, ulong newLen) 
        {
            oldLen = RoundToBlockSize(oldLen); 
            if (newLen > oldLen)
                Reserve(RoundToBlockSize(newLen - oldLen));
        }
 
        internal void ReserveOneBlock()
        { 
            Reserve(s_BlockSize); 
        }
 
        internal void UnreserveOneBlock()
        {
            Unreserve(s_BlockSize);
        } 

        internal static ulong RoundToBlockSize(ulong num) 
        { 
            if (num < s_BlockSize)
                return s_BlockSize; 

            ulong rem = (num % s_BlockSize);

            if (rem != 0) 
                num += (s_BlockSize - rem);
 
            return num; 
        }
 
        // Helper static methods
        internal static String GetRootDir(IsolatedStorageScope scope)
        {
            if (IsRoaming(scope)) 
            {
                if (s_RootDirRoaming == null) 
                    s_RootDirRoaming = nGetRootDir(scope); 

                return s_RootDirRoaming; 
            }

            if (IsMachine(scope))
            { 
                if (s_RootDirMachine == null)
                    InitGlobalsMachine(scope); 
 
                return s_RootDirMachine;
            } 

            // This is then the non-roaming user store.
            if (s_RootDirUser == null)
                InitGlobalsNonRoamingUser(scope); 

            return s_RootDirUser; 
        } 

        private static void InitGlobalsMachine(IsolatedStorageScope scope) 
        {
            String rootDir = nGetRootDir(scope);
            new FileIOPermission(FileIOPermissionAccess.AllAccess, rootDir).Assert();
            String rndName = GetMachineRandomDirectory(rootDir); 
            if (rndName == null) {  // Create a random directory
                Mutex m = CreateMutexNotOwned(rootDir); 
                if (!m.WaitOne()) 
                    throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
                try {   // finally... 
                    rndName = GetMachineRandomDirectory(rootDir);  // try again with lock
                    if (rndName == null) {
                        string relRandomDirectory1 = Path.GetRandomFileName();
                        string relRandomDirectory2 = Path.GetRandomFileName(); 
                        try {
                            nCreateDirectoryWithDacl(rootDir + relRandomDirectory1); 
                            // Now create the root directory with the correct DACL 
                            nCreateDirectoryWithDacl(rootDir + relRandomDirectory1 + "\\" + relRandomDirectory2);
                        } catch { 
                            // We don't want to leak any information here
                            // Throw a store initialization exception instead
                            throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
                        } 
                        rndName = relRandomDirectory1 + "\\" + relRandomDirectory2;
                    } 
                } finally { 
                    m.ReleaseMutex();
                } 
            }
            s_RootDirMachine = rootDir + rndName + "\\";
        }
 
        private static void InitGlobalsNonRoamingUser(IsolatedStorageScope scope)
        { 
            String rootDir = null; 
#if !FEATURE_PAL
            if (scope == c_AppUser) 
            {
                rootDir = GetDataDirectoryFromActivationContext();
                if (rootDir != null)
                { 
                    s_RootDirUser = rootDir;
                    return; 
                } 
            }
#endif 
            // Non App Data directory case or non-App case:
            rootDir = nGetRootDir(scope);
            new FileIOPermission(FileIOPermissionAccess.AllAccess, rootDir).Assert();
            bool bMigrateNeeded = false; 
            string sOldStoreLocation = null;
            String rndName = GetRandomDirectory(rootDir, out bMigrateNeeded, out sOldStoreLocation); 
            if (rndName == null) {  // Create a random directory 
                Mutex m = CreateMutexNotOwned(rootDir);
                if (!m.WaitOne()) 
                    throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
                try {   // finally...
                    rndName = GetRandomDirectory(rootDir, out bMigrateNeeded, out sOldStoreLocation);  // try again with lock
                    if (rndName == null) { 
                        if (bMigrateNeeded) {
                            // We have a store directory in the old format; we need to migrate it 
                            rndName = MigrateOldIsoStoreDirectory(rootDir, sOldStoreLocation); 
                        } else {
                            rndName = CreateRandomDirectory(rootDir); 
                        }
                    }
                } finally {
                    m.ReleaseMutex(); 
                }
            } 
            s_RootDirUser = rootDir + rndName + "\\"; 
        }
 
        // Migrates the old store location to a new one and returns the new location without the path separator
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine | ResourceScope.Assembly)]
        internal static string MigrateOldIsoStoreDirectory(string rootDir, string oldRandomDirectory) { 
            // First create the new random directory
            string relRandomDirectory1 = Path.GetRandomFileName(); 
            string relRandomDirectory2 = Path.GetRandomFileName(); 
            string firstRandomDirectory  = rootDir + relRandomDirectory1;
            string newRandomDirectory = firstRandomDirectory + "\\" + relRandomDirectory2; 
            // Move the old directory to the new location, throw an exception and revert
            // the transaction if the operation is not successful
            try {
                // Create the first level of the new random directory 
                Directory.CreateDirectory(firstRandomDirectory);
                // Move the old directory under the newly created random directory 
                Directory.Move(rootDir + oldRandomDirectory, newRandomDirectory); 
            } catch {
                // We don't want to leak any information here. 
                // Throw a store initialization exception instead
                throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
            }
            return (relRandomDirectory1 + "\\" + relRandomDirectory2); 
        }
 
        // creates and returns the relative path to the random directory string without the path separator 
        [ResourceExposure(ResourceScope.Assembly | ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Assembly | ResourceScope.Machine)] 
        internal static string CreateRandomDirectory(String rootDir) {
            string rndName = Path.GetRandomFileName() + "\\" + Path.GetRandomFileName();
            try {
                Directory.CreateDirectory(rootDir + rndName); 
            } catch {
                // We don't want to leak any information here 
                // Throw a store initialization exception instead 
                throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
            } 
            return rndName;
        }

        // returns the relative path to the current random directory string if one is there without the path separator 
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)] 
        internal static string GetRandomDirectory(String rootDir, out bool bMigrateNeeded, out string sOldStoreLocation) 
        {
            // Initialize Out Parameters 
            bMigrateNeeded = false; sOldStoreLocation = null;
            String[] nodes1 = GetFileDirectoryNames(rootDir + "*", "*", false);
            // First see if there is a new store
            for (int i=0; i 0) {
                        int n = fs.Read(b, offset, length);
                        if (n == 0)
                            __Error.EndOfFile(); 
                        offset += n;
                        length -= n; 
                    } 
                }
                s = new MemoryStream(b); 
            } catch {
                return false;
            }
 
            return true;
        } 
    } 

    internal sealed class TwoPaths 
    {
        public String Path1;
        public String Path2;
 
    }
 
    // Given a directory, enumerates all subdirs of upto depth 2 
    internal sealed class TwoLevelFileEnumerator : IEnumerator
    { 
        private String   m_Root;
        private TwoPaths m_Current;
        private bool     m_fReset;
 
        private String[] m_RootDir;
        private int      m_nRootDir; 
 
        private String[] m_SubDir;
        private int      m_nSubDir; 


        public TwoLevelFileEnumerator(String root)
        { 
            m_Root = root;
            Reset(); 
        } 

        public bool MoveNext() 
        {
            lock (this)
            {
                // Sepecial case the Reset State 
                if (m_fReset)
                { 
                    m_fReset = false; 
                    return AdvanceRootDir();
                } 

                // Don't move anything if RootDir is empty
                if (m_RootDir.Length == 0)
                    return false; 

 
                // Get Next SubDir 

                ++m_nSubDir; 

                if (m_nSubDir >= m_SubDir.Length)
                {
                    m_nSubDir = m_SubDir.Length;    // to avoid wrap aournd. 
                    return AdvanceRootDir();
                } 
 
                UpdateCurrent();
            } 

            return true;
        }
 

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        private bool AdvanceRootDir()
        { 
            ++m_nRootDir;

            if (m_nRootDir >= m_RootDir.Length)
            { 
                m_nRootDir = m_RootDir.Length;  // to prevent wrap around
                return false;                   // We are at the very end. 
            } 

            m_SubDir = Directory.GetDirectories(m_RootDir[m_nRootDir]); 

            if (m_SubDir.Length == 0)
                return AdvanceRootDir();        // recurse here.
 
            m_nSubDir  = 0;
 
            // Set m_Current 
            UpdateCurrent();
 
            return true;
        }

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        private void UpdateCurrent() 
        { 
            m_Current.Path1 = Path.GetFileName(m_RootDir[m_nRootDir]);
            m_Current.Path2 = Path.GetFileName(m_SubDir[m_nSubDir]); 
        }

        public Object Current
        { 
            get {
 
                if (m_fReset) 
                {
                    throw new InvalidOperationException( 
                        Environment.GetResourceString(
                            "InvalidOperation_EnumNotStarted"));
                }
                else if (m_nRootDir >= m_RootDir.Length) 
                {
                    throw new InvalidOperationException( 
                        Environment.GetResourceString( 
                            "InvalidOperation_EnumEnded"));
                } 

                return (Object) m_Current;
            }
        } 

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public void Reset()
        { 
            m_RootDir  = null;
            m_nRootDir = -1;

            m_SubDir   = null; 
            m_nSubDir  = -1;
 
            m_Current  = new TwoPaths(); 
            m_fReset   = true;
 
            m_RootDir  = Directory.GetDirectories(m_Root);
        }
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
 * 
 * Class:  IsolatedStorageFile 
 *
 * 
 * Purpose: Provides access to Application files and folders
 *
 * Date:  Feb 18, 2000
 * 
 ===========================================================*/
namespace System.IO.IsolatedStorage { 
    using System; 
    using System.Text;
    using System.IO; 
    using Microsoft.Win32;
    using Microsoft.Win32.SafeHandles;
    using System.Collections;
    using System.Security; 
    using System.Threading;
    using System.Security.Policy; 
    using System.Security.Permissions; 
    using System.Security.Cryptography;
    using System.Runtime.InteropServices; 
    using System.Runtime.CompilerServices;
    using System.Runtime.Versioning;
    using System.Globalization;
 
[System.Runtime.InteropServices.ComVisible(true)]
    public sealed class IsolatedStorageFile : IsolatedStorage, IDisposable 
    { 
        private  const int    s_BlockSize = 1024;
        private  const int    s_DirSize   = s_BlockSize; 
        private  const String s_name      = "file.store";
        internal const String s_Files     = "Files";
        internal const String s_AssemFiles= "AssemFiles";
        internal const String s_AppFiles= "AppFiles"; 
        internal const String s_IDFile    = "identity.dat";
        internal const String s_InfoFile  = "info.dat"; 
        internal const String s_AppInfoFile  = "appinfo.dat"; 

        private static String s_RootDirUser; 
        private static String s_RootDirMachine;
        private static String s_RootDirRoaming;
        private static String s_appDataDir;
 
        private static FileIOPermission              s_PermUser;
        private static FileIOPermission              s_PermMachine; 
        private static FileIOPermission              s_PermRoaming; 
        private static IsolatedStorageFilePermission s_PermAdminUser;
 
        private FileIOPermission m_fiop;
        private String           m_RootDir;
        private String           m_InfoFile;
        private String           m_SyncObjectName; 
        private IntPtr           m_handle;
        private bool             m_closed; 
        private bool             m_bDisposed = false; 

#if _DEBUG 
        private static bool s_fDebug;
#endif

        internal IsolatedStorageFile() {} 

        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetUserStoreForDomain()
        { 
            return GetStore(
                IsolatedStorageScope.Assembly|
                IsolatedStorageScope.Domain|
                IsolatedStorageScope.User, 
                null, null);
        } 
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetUserStoreForAssembly()
        {
            return GetStore(
                IsolatedStorageScope.Assembly| 
                IsolatedStorageScope.User,
                null, null); 
        } 

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetUserStoreForApplication()
        {
            return GetStore( 
                IsolatedStorageScope.Application|
                IsolatedStorageScope.User, 
                null); 
        }
 
        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetMachineStoreForDomain()
        { 
            return GetStore(
                IsolatedStorageScope.Assembly| 
                IsolatedStorageScope.Domain| 
                IsolatedStorageScope.Machine,
                null, null); 
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetMachineStoreForAssembly()
        { 
            return GetStore( 
                IsolatedStorageScope.Assembly|
                IsolatedStorageScope.Machine, 
                null, null);
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetMachineStoreForApplication() 
        { 
            return GetStore(
                IsolatedStorageScope.Application| 
                IsolatedStorageScope.Machine,
                null);
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, 
            Type domainEvidenceType, Type assemblyEvidenceType)
        { 
            if (domainEvidenceType != null)
                DemandAdminPermission();

            IsolatedStorageFile sf = new IsolatedStorageFile(); 
            sf.InitStore(scope, domainEvidenceType, assemblyEvidenceType);
            sf.Init(scope); 
            return sf; 
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope,
            Object domainIdentity, Object assemblyIdentity) 
        {
            // Verify input params. 
            if (IsDomain(scope) && (domainIdentity == null)) 
                throw new ArgumentNullException("domainIdentity");
 
            if (assemblyIdentity == null)
                throw new ArgumentNullException("assemblyIdentity");

            DemandAdminPermission(); 

            IsolatedStorageFile sf = new IsolatedStorageFile(); 
            sf.InitStore(scope, domainIdentity, assemblyIdentity, null); 
            sf.Init(scope);
 
            return sf;
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, 
            Evidence domainEvidence, Type  domainEvidenceType, 
            Evidence assemblyEvidence, Type assemblyEvidenceType)
        { 
            // Verify input params.
            if (IsDomain(scope) && (domainEvidence == null))
                throw new ArgumentNullException("domainEvidence");
 
            if (assemblyEvidence == null)
                throw new ArgumentNullException("assemblyEvidence"); 
 
            DemandAdminPermission();
 
            IsolatedStorageFile sf = new IsolatedStorageFile();
            sf.InitStore(scope, domainEvidence, domainEvidenceType,
                assemblyEvidence, assemblyEvidenceType, null, null);
            sf.Init(scope); 

            return sf; 
        } 

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope,
                                                                    Type applicationEvidenceType)
        { 
            if (applicationEvidenceType != null)
                DemandAdminPermission(); 
 
            IsolatedStorageFile sf = new IsolatedStorageFile();
            sf.InitStore(scope, applicationEvidenceType); 
            sf.Init(scope);
            return sf;
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, 
                                                                    Object applicationIdentity)
        { 
            if (applicationIdentity == null)
                throw new ArgumentNullException("applicationIdentity");

            DemandAdminPermission(); 

            IsolatedStorageFile sf = new IsolatedStorageFile(); 
            sf.InitStore(scope, null, null, applicationIdentity); 
            sf.Init(scope);
 
            return sf;
        }

        [CLSCompliant(false)] 
        public override ulong CurrentSize
        { 
            get { 
                if (IsRoaming())
                    throw new InvalidOperationException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_CurrentSizeUndefined"));

                lock (this) 
                {
                    if (m_bDisposed) 
                        throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen")); 

                    if (m_closed) 
                        throw new InvalidOperationException(
                            Environment.GetResourceString(
                                "IsolatedStorage_StoreNotOpen"));
 
                    if (m_handle == Win32Native.NULL)
                        m_handle = nOpen(m_InfoFile, GetSyncObjectName()); 
 
                    return nGetUsage(m_handle);
                } 
            }
        }

        [CLSCompliant(false)] 
        public override ulong MaximumSize
        { 
            get 
            {
                if (IsRoaming()) 
                    return Int64.MaxValue;

                return base.MaximumSize;
            } 
        }
 
        internal unsafe void Reserve(ulong lReserve) 
        {
            if (IsRoaming())  // No Quota enforcement for roaming 
                return;

            ulong quota = this.MaximumSize;
            ulong reserve = lReserve; 

            lock (this) 
            { 
                if (m_bDisposed)
                    throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen")); 

                if (m_closed)
                    throw new InvalidOperationException(
                        Environment.GetResourceString( 
                            "IsolatedStorage_StoreNotOpen"));
 
                if (m_handle == Win32Native.NULL) 
                    m_handle = nOpen(m_InfoFile, GetSyncObjectName());
 
                nReserve(m_handle, "a, &reserve, false);
            }
        }
 
        internal unsafe void Unreserve(ulong lFree)
        { 
            if (IsRoaming())  // No Quota enforcement for roaming 
                return;
 
            ulong quota = this.MaximumSize;
            ulong free = lFree;

            lock (this) 
            {
                if (m_bDisposed) 
                    throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen")); 

                if (m_closed) 
                    throw new InvalidOperationException(
                        Environment.GetResourceString(
                            "IsolatedStorage_StoreNotOpen"));
 
                if (m_handle == Win32Native.NULL)
                    m_handle = nOpen(m_InfoFile, GetSyncObjectName()); 
 
                nReserve(m_handle, "a, &free, true);
            } 
        }

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public void DeleteFile(String file)
        { 
            if (file == null) 
                throw new ArgumentNullException("file");
 
            m_fiop.Assert();
            m_fiop.PermitOnly();

            FileInfo f = new FileInfo(GetFullPath(file)); 
            long oldLen = 0;
 
            Lock(); // protect oldLen 

            try { 
                try {
                    oldLen = f.Length;
                    f.Delete();
                } catch { 
                    throw new IsolatedStorageException(
                        Environment.GetResourceString( 
                            "IsolatedStorage_DeleteFile")); 
                }
                Unreserve(RoundToBlockSize((ulong)oldLen)); 
            } finally {
                Unlock();
            }
            CodeAccessPermission.RevertAll(); 

        } 
 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public void CreateDirectory(String dir)
        {
            if (dir == null)
                throw new ArgumentNullException("dir"); 

            String isPath = GetFullPath(dir); // Prepend IS root 
 
            String fullPath = Path.GetFullPathInternal(isPath);
 
            String [] dirList = DirectoriesToCreate(fullPath);

            if (dirList == null || dirList.Length == 0)
            { 
                if (Directory.Exists(isPath))
                    return; 
                else 
                    throw new IsolatedStorageException(
                        Environment.GetResourceString( 
                            "IsolatedStorage_CreateDirectory"));
            }
            Reserve(s_DirSize*((ulong)dirList.Length));
            m_fiop.Assert(); 
            m_fiop.PermitOnly();
            try { 
                Directory.CreateDirectory(dirList[dirList.Length-1]); 
            } catch {
                Unreserve(s_DirSize*((ulong)dirList.Length)); 
                // force delete any new directories we created
                Directory.Delete(dirList[0],true);
                throw new IsolatedStorageException(
                    Environment.GetResourceString( 
                        "IsolatedStorage_CreateDirectory"));
            } 
            CodeAccessPermission.RevertAll(); 

        } 

        // Given a path to a dir to create, will return the list of directories to create and the last one in the array is the actual dir to create.
        // for example if dir is a\\b\\c and none of them exist, the list returned will be a, a\\b, a\\b\\c.
        private String[] DirectoriesToCreate(String fullPath) 
        {
 
            ArrayList list = new ArrayList(); 
            int length = fullPath.Length;
 
            // We need to trim the trailing slash or the code will try to create 2 directories of the same name.
            if (length >= 2 && fullPath[length - 1] == SeparatorExternal)
                length--;
            int i = Path.GetRootLength(fullPath); 

            // Attempt to figure out which directories don't exist 
            while (i < length) { 
                i++;
                while (i < length && fullPath[i] != SeparatorExternal) 
                    i++;
                String currDir = fullPath.Substring(0, i);

                if (!Directory.InternalExists(currDir)) 
                { // Create only the ones missing
                    list.Add(currDir); 
                } 
            }
 
            if (list.Count != 0)
            {
                return (String[])list.ToArray(typeof(String));
            } 
            return null;
        } 
 
        public void DeleteDirectory(String dir)
        { 
            if (dir == null)
                throw new ArgumentNullException("dir");

            m_fiop.Assert(); 
            m_fiop.PermitOnly();
 
            Lock(); // Delete *.*, will beat quota enforcement without this lock 

            try { 
                try {
                    new DirectoryInfo(GetFullPath(dir)).Delete(false);
                } catch {
                    throw new IsolatedStorageException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_DeleteDirectory")); 
                } 
                Unreserve(s_DirSize);
            } finally { 
                Unlock();
            }
            CodeAccessPermission.RevertAll();
        } 

        /* 
         * foo\abc*.txt will give all abc*.txt files in foo directory 
         */
        public String[] GetFileNames(String searchPattern) 
        {
            if (searchPattern == null)
                throw new ArgumentNullException("searchPattern");
 
            m_fiop.Assert();
            m_fiop.PermitOnly(); 
            String[] retVal = GetFileDirectoryNames(GetFullPath(searchPattern), searchPattern, true); 
            CodeAccessPermission.RevertAll();
            return retVal; 

        }

        /* 
         * foo\data* will give all directory names in foo directory that
         * starts with data 
         */ 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage.
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public String[] GetDirectoryNames(String searchPattern)
        {
            if (searchPattern == null)
                throw new ArgumentNullException("searchPattern"); 

            m_fiop.Assert(); 
            m_fiop.PermitOnly(); 
            String[] retVal = GetFileDirectoryNames(GetFullPath(searchPattern), searchPattern, false);
            CodeAccessPermission.RevertAll(); 
            return retVal;
        }

        // Remove this individual store 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage.
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public override void Remove() 
        {
            // No security check required here since we have already done 
            // that during creation

            String rootDir, domainRoot = null;
 
            // First remove the logical root directory of this store, this
            // will not delete the quota file. Removes all the files and dirs 
            // that applications see. 

            RemoveLogicalDir(); 

            Close();

            // Now try to remove other files folders that become unnecessary 
            // if the application directory is deleted.
 
            StringBuilder sb = new StringBuilder(); 

            sb.Append(GetRootDir(this.Scope)); 

            if (IsApp())
            {
                sb.Append(this.AppName); 
                sb.Append(this.SeparatorExternal);
            } 
            else 
            {
                if (IsDomain()) 
                {
                    sb.Append(this.DomainName);
                    sb.Append(this.SeparatorExternal);
                    domainRoot = sb.ToString(); 
                }
 
                sb.Append(this.AssemName); 
                sb.Append(this.SeparatorExternal);
            } 
            rootDir = sb.ToString();

            new FileIOPermission(
                FileIOPermissionAccess.AllAccess, rootDir).Assert(); 

            if (ContainsUnknownFiles(rootDir)) 
                return; 

            try { 

                Directory.Delete(rootDir, true);
#if _DEBUG
            } catch (Exception e) { 

                if (s_fDebug) 
                { 
                    Console.WriteLine(e);
                    Console.WriteLine("Delete failed on rootdir"); 
                }
#else
            } catch {
#endif 
                return; // OK to ignore this exception.
            } 
 
            // If this was a domain store, and if this happens to be
            // the only store around, then delete the root store for this 
            // domain

            if (IsDomain())
            { 
                CodeAccessPermission.RevertAssert();
 
                new FileIOPermission( 
                    FileIOPermissionAccess.AllAccess, domainRoot).Assert();
 
                if (!ContainsUnknownFiles(domainRoot))
                {

                    try { 

                        Directory.Delete(domainRoot, true); 
#if _DEBUG 
                    } catch (Exception e) {
 
                        if (s_fDebug)
                        {
                            Console.WriteLine(e);
                            Console.WriteLine("Delete failed on basedir"); 
                        }
#else 
                    } catch { 
#endif
                        return; // OK to ignore this exception. 
                    }
                }
            }
        } 

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        private void RemoveLogicalDir()
        { 
            m_fiop.Assert();

            ulong oldLen;
 
            Lock(); // A ---- here with delete dir/delete file can get around
                    // quota enforcement. 
 
            try {
                oldLen = IsRoaming() ? 0 : CurrentSize; 

                try {

                    Directory.Delete(RootDirectory, true); 
#if _DEBUG
                } catch (Exception e) { 
 
                    if (s_fDebug)
                    { 
                        Console.WriteLine(e);
                        Console.WriteLine("Delete failed on LogicalRooDir");
                    }
#else 
                    } catch {
#endif 
                    throw new IsolatedStorageException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_DeleteDirectories")); 
                }

                Unreserve(oldLen);
            } finally { 
                Unlock();
            } 
        } 

        private bool ContainsUnknownFiles(String rootDir) 
        {
            String[] dirs, files;

            // Delete everything in the root directory of this store 
            // if there are no Domain Stores / other files
            // Make sure that there are no other subdirs present here other 
            // than the ones used by IsolatedStorageFile (Cookies in future 
            // releases ?)
 
            try {
                files = GetFileDirectoryNames(rootDir + "*", "*", true);
                dirs = GetFileDirectoryNames(rootDir + "*", "*", false);
            } catch { 
                throw new IsolatedStorageException(
                    Environment.GetResourceString( 
                        "IsolatedStorage_DeleteDirectories")); 
            }
 
            // First see if there are any unkonwn Folders
            if ((dirs != null) && (dirs.Length > 0))
            {
                if (dirs.Length > 1) 
                {
                    // More than one directory present 
                    return true; 
                }
 
                if (IsApp())
                {
                    if (NotAppFilesDir(dirs[0]))
                        return true; 
                }
                else if (IsDomain()) 
                { 
                    if (NotFilesDir(dirs[0]))
                        return true; 
                }
                else
                {
                    if (NotAssemFilesDir(dirs[0])) 
                        return true;
                } 
            } 

            // Now look at the files 

            if ((files == null) || (files.Length == 0))
                return false;
 
            if (IsRoaming())
            { 
                if ((files.Length > 1) || NotIDFile(files[0])) 
                {
                    // There is one or more files unknown to this version 
                    // of IsoStoreFile

                    return true;
                } 

                return false; 
            } 

            if ((files.Length > 2) || 
                (NotIDFile(files[0]) && NotInfoFile(files[0])) ||
                ((files.Length == 2) &&
                NotIDFile(files[1]) && NotInfoFile(files[1])))
            { 
                // There is one or more files unknown to this version
                // of IsoStoreFile 
 
                return true;
            } 

            return false;
        }
 
        public void Close()
        { 
            if (IsRoaming()) 
                return;
 
            lock (this) {

                if (!m_closed) {
                    m_closed = true; 

                    IntPtr handle = m_handle; 
 
                    m_handle = Win32Native.NULL;
                    nClose(handle); 

                    GC.nativeSuppressFinalize(this);
                }
 
            }
        } 
 
        public void Dispose()
        { 
            Close();
            m_bDisposed = true;
        }
 
        ~IsolatedStorageFile()
        { 
            Dispose(); 
        }
 
        // Macros, expect JIT to expand this
        private static bool NotIDFile(String file)
        {
            return (String.Compare( 
                file, IsolatedStorageFile.s_IDFile, StringComparison.Ordinal) != 0);
        } 
 
        private static bool NotInfoFile(String file)
        { 
            return (
                String.Compare(file, IsolatedStorageFile.s_InfoFile, StringComparison.Ordinal) != 0 &&
                String.Compare(file, IsolatedStorageFile.s_AppInfoFile, StringComparison.Ordinal) != 0);
        } 

        private static bool NotFilesDir(String dir) 
        { 
            return (String.Compare(
                dir, IsolatedStorageFile.s_Files, StringComparison.Ordinal) != 0); 
        }

        internal static bool NotAssemFilesDir(String dir)
        { 
            return (String.Compare(
                dir, IsolatedStorageFile.s_AssemFiles, StringComparison.Ordinal) != 0); 
        } 

        internal static bool NotAppFilesDir(String dir) 
        {
            return (String.Compare(
                dir, IsolatedStorageFile.s_AppFiles, StringComparison.Ordinal) != 0);
        } 

        // Remove store for all identities 
        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        public static void Remove(IsolatedStorageScope scope) 
        {
            VerifyGlobalScope(scope);
            DemandAdminPermission();
 
            String rootDir = GetRootDir(scope);
 
            new FileIOPermission( 
                FileIOPermissionAccess.Write, rootDir).Assert();
 
            try {
                Directory.Delete(rootDir, true);    // Remove all sub dirs and files
                Directory.CreateDirectory(rootDir); // Recreate the root dir
            } catch { 
                throw new IsolatedStorageException(
                    Environment.GetResourceString( 
                        "IsolatedStorage_DeleteDirectories")); 
            }
        } 

        public static IEnumerator GetEnumerator(IsolatedStorageScope scope)
        {
            VerifyGlobalScope(scope); 
            DemandAdminPermission();
 
            return new IsolatedStorageFileEnumerator(scope); 
        }
 
        // Internal & private methods

        internal String RootDirectory
        { 
            get { return m_RootDir; }
        } 
 
        // RootDirectory has been scoped already.
        internal String GetFullPath(String path) 
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(this.RootDirectory); 

            if (path[0] == SeparatorExternal) 
                sb.Append(path.Substring(1)); 
            else
                sb.Append(path); 

            return sb.ToString();
        }
 
#if !FEATURE_PAL
        [SecurityPermissionAttribute(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)] 
        private static String GetDataDirectoryFromActivationContext() 
        {
            if (s_appDataDir == null) 
            {
                ActivationContext activationContext = AppDomain.CurrentDomain.ActivationContext;
                if (activationContext == null)
                    throw new IsolatedStorageException( 
                            Environment.GetResourceString(
                                "IsolatedStorage_ApplicationMissingIdentity")); 
                String dataDir = activationContext.DataDirectory; 
                if (dataDir != null)
                { 
                    //Append a '\' at the end if it already does not end with one
                    if (dataDir[dataDir.Length-1] != '\\')
                        dataDir = dataDir + "\\";
                } 
                s_appDataDir = dataDir;
            } 
            return s_appDataDir; 
        }
#endif 

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine | ResourceScope.Assembly)]
        internal void Init(IsolatedStorageScope scope) 
        {
            GetGlobalFileIOPerm(scope).Assert(); 
 
            StringBuilder sb = new StringBuilder();
 
            // Create the root directory if it is not already there


            if (IsApp(scope)) 
            {
#if FEATURE_PAL 
                throw new IsolatedStorageException( 
                        Environment.GetResourceString(
                            "IsolatedStorage_ApplicationMissingIdentity")); 
#endif // !FEATURE_PAL

                sb.Append(GetRootDir(scope));
                if (s_appDataDir == null) 
                {
                    // We're not using the App Data directory...so we need to append AppName 
                    sb.Append(this.AppName); 
                    sb.Append(this.SeparatorExternal);
                } 

                try {

                    Directory.CreateDirectory(sb.ToString()); 

                    // No exception implies this directory was created now 
 

                } catch { 
                    // Ok to ignore IO exception

                }
                // Create the Identity blob file in the root 
                // directory. OK if there are more than one created
                // last one wins 
 
                CreateIDFile(sb.ToString(), scope);
 
                // For App Stores, accounting is done in the app root
                this.m_InfoFile = sb.ToString() + s_AppInfoFile;

                sb.Append(s_AppFiles); 

            } 
            else 
            {
                sb.Append(GetRootDir(scope)); 
                if (IsDomain(scope))
                {
                    sb.Append(this.DomainName);
                    sb.Append(this.SeparatorExternal); 

                    try { 
 
                        Directory.CreateDirectory(sb.ToString());
 
                        // No exception implies this directory was created now

                        // Create the Identity blob file in the root
                        // directory. OK if there are more than one created 
                        // last one wins
 
                        CreateIDFile(sb.ToString(), scope); 

                    } catch { 

                        // Ok to ignore IO exception

    #if false 
            // Leaving this commented for now for performance
 
                        // It is possible that a previous create directory 
                        // succeeded, but the Identity blob file was not
                        // created. Create it now. 

                        CreateIDFileIfNecessary(sb.ToString(), scope);
    #endif
                    } 

                    // For Domain Stores, accounting is done in the domain root 
                    this.m_InfoFile = sb.ToString() + s_InfoFile; 
                }
 
                sb.Append(this.AssemName);
                sb.Append(this.SeparatorExternal);

                try { 

                    Directory.CreateDirectory(sb.ToString()); 
 
                    // No exception implies this directory was created now
 
                    // Create the Identity blob file in the root
                    // directory. OK if there are more than one created
                    // last one wins
 
                    CreateIDFile(sb.ToString(), scope);
 
                } catch { 
                    // Ok to ignore IO exception
 
    #if false
            // Leaving this commented for now for performance

                    // It is possible that a previous create directory 
                    // succeeded, but the Identity blob file was not
                    // created. Create it now. 
 
                    CreateIDFileIfNecessary(sb.ToString(), scope);
    #endif 
                }

                if (IsDomain(scope))
                { 
                    sb.Append(s_Files);
                } 
                else 
                {
                    // For Assem Stores, accounting is done in the assem root 
                    this.m_InfoFile = sb.ToString() + s_InfoFile;

                    sb.Append(s_AssemFiles);
                } 
            }
            sb.Append(this.SeparatorExternal); 
 
            String rootDir = sb.ToString();
 
            try {
                Directory.CreateDirectory(rootDir);
            } catch {
                // Ok to ignore IO exception 
            }
 
            this.m_RootDir = rootDir; 

            // Use the "new" RootDirectory to create the permission. 
            // This instance of permission is not the same as the
            // one we just asserted. It uses this.base.RootDirectory.

            m_fiop = new FileIOPermission( 
                FileIOPermissionAccess.AllAccess, rootDir);
        } 
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        internal bool InitExistingStore(IsolatedStorageScope scope)
        {
            FileIOPermission fp;
            StringBuilder sb = new StringBuilder(); 

            sb.Append(GetRootDir(scope)); 
 
            if (IsApp(scope))
            { 
                sb.Append(this.AppName);
                sb.Append(this.SeparatorExternal);
                // For App Stores, accounting is done in the app root
                this.m_InfoFile = sb.ToString() + s_AppInfoFile; 

                sb.Append(s_AppFiles); 
            } 
            else
            { 
                if (IsDomain(scope))
                {
                    sb.Append(this.DomainName);
                    sb.Append(this.SeparatorExternal); 

                    // For Domain Stores, accounting is done in the domain root 
                    this.m_InfoFile = sb.ToString() + s_InfoFile; 
                }
 
                sb.Append(this.AssemName);
                sb.Append(this.SeparatorExternal);

                if (IsDomain(scope)) 
                {
                    sb.Append(s_Files); 
                } 
                else
                { 
                    // For Assem Stores, accounting is done in the assem root
                    this.m_InfoFile = sb.ToString() + s_InfoFile;

                    sb.Append(s_AssemFiles); 
                }
            } 
            sb.Append(this.SeparatorExternal); 

            fp = new FileIOPermission( 
                FileIOPermissionAccess.AllAccess, sb.ToString());

            fp.Assert();
 
            if (!Directory.Exists(sb.ToString()))
                return false; 
 
            this.m_RootDir = sb.ToString();
            this.m_fiop = fp; 

            return true;
        }
 
        protected override IsolatedStoragePermission GetPermission(
                PermissionSet ps) 
        { 
            if (ps == null)
                return null; 
            else if (ps.IsUnrestricted())
                return new IsolatedStorageFilePermission(
                        PermissionState.Unrestricted);
 
            return (IsolatedStoragePermission) ps.
                    GetPermission(typeof(IsolatedStorageFilePermission)); 
        } 

        internal void UndoReserveOperation(ulong oldLen, ulong newLen) 
        {
            oldLen = RoundToBlockSize(oldLen);
            if (newLen > oldLen)
                Unreserve(RoundToBlockSize(newLen - oldLen)); 
        }
 
        internal void Reserve(ulong oldLen, ulong newLen) 
        {
            oldLen = RoundToBlockSize(oldLen); 
            if (newLen > oldLen)
                Reserve(RoundToBlockSize(newLen - oldLen));
        }
 
        internal void ReserveOneBlock()
        { 
            Reserve(s_BlockSize); 
        }
 
        internal void UnreserveOneBlock()
        {
            Unreserve(s_BlockSize);
        } 

        internal static ulong RoundToBlockSize(ulong num) 
        { 
            if (num < s_BlockSize)
                return s_BlockSize; 

            ulong rem = (num % s_BlockSize);

            if (rem != 0) 
                num += (s_BlockSize - rem);
 
            return num; 
        }
 
        // Helper static methods
        internal static String GetRootDir(IsolatedStorageScope scope)
        {
            if (IsRoaming(scope)) 
            {
                if (s_RootDirRoaming == null) 
                    s_RootDirRoaming = nGetRootDir(scope); 

                return s_RootDirRoaming; 
            }

            if (IsMachine(scope))
            { 
                if (s_RootDirMachine == null)
                    InitGlobalsMachine(scope); 
 
                return s_RootDirMachine;
            } 

            // This is then the non-roaming user store.
            if (s_RootDirUser == null)
                InitGlobalsNonRoamingUser(scope); 

            return s_RootDirUser; 
        } 

        private static void InitGlobalsMachine(IsolatedStorageScope scope) 
        {
            String rootDir = nGetRootDir(scope);
            new FileIOPermission(FileIOPermissionAccess.AllAccess, rootDir).Assert();
            String rndName = GetMachineRandomDirectory(rootDir); 
            if (rndName == null) {  // Create a random directory
                Mutex m = CreateMutexNotOwned(rootDir); 
                if (!m.WaitOne()) 
                    throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
                try {   // finally... 
                    rndName = GetMachineRandomDirectory(rootDir);  // try again with lock
                    if (rndName == null) {
                        string relRandomDirectory1 = Path.GetRandomFileName();
                        string relRandomDirectory2 = Path.GetRandomFileName(); 
                        try {
                            nCreateDirectoryWithDacl(rootDir + relRandomDirectory1); 
                            // Now create the root directory with the correct DACL 
                            nCreateDirectoryWithDacl(rootDir + relRandomDirectory1 + "\\" + relRandomDirectory2);
                        } catch { 
                            // We don't want to leak any information here
                            // Throw a store initialization exception instead
                            throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
                        } 
                        rndName = relRandomDirectory1 + "\\" + relRandomDirectory2;
                    } 
                } finally { 
                    m.ReleaseMutex();
                } 
            }
            s_RootDirMachine = rootDir + rndName + "\\";
        }
 
        private static void InitGlobalsNonRoamingUser(IsolatedStorageScope scope)
        { 
            String rootDir = null; 
#if !FEATURE_PAL
            if (scope == c_AppUser) 
            {
                rootDir = GetDataDirectoryFromActivationContext();
                if (rootDir != null)
                { 
                    s_RootDirUser = rootDir;
                    return; 
                } 
            }
#endif 
            // Non App Data directory case or non-App case:
            rootDir = nGetRootDir(scope);
            new FileIOPermission(FileIOPermissionAccess.AllAccess, rootDir).Assert();
            bool bMigrateNeeded = false; 
            string sOldStoreLocation = null;
            String rndName = GetRandomDirectory(rootDir, out bMigrateNeeded, out sOldStoreLocation); 
            if (rndName == null) {  // Create a random directory 
                Mutex m = CreateMutexNotOwned(rootDir);
                if (!m.WaitOne()) 
                    throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
                try {   // finally...
                    rndName = GetRandomDirectory(rootDir, out bMigrateNeeded, out sOldStoreLocation);  // try again with lock
                    if (rndName == null) { 
                        if (bMigrateNeeded) {
                            // We have a store directory in the old format; we need to migrate it 
                            rndName = MigrateOldIsoStoreDirectory(rootDir, sOldStoreLocation); 
                        } else {
                            rndName = CreateRandomDirectory(rootDir); 
                        }
                    }
                } finally {
                    m.ReleaseMutex(); 
                }
            } 
            s_RootDirUser = rootDir + rndName + "\\"; 
        }
 
        // Migrates the old store location to a new one and returns the new location without the path separator
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine | ResourceScope.Assembly)]
        internal static string MigrateOldIsoStoreDirectory(string rootDir, string oldRandomDirectory) { 
            // First create the new random directory
            string relRandomDirectory1 = Path.GetRandomFileName(); 
            string relRandomDirectory2 = Path.GetRandomFileName(); 
            string firstRandomDirectory  = rootDir + relRandomDirectory1;
            string newRandomDirectory = firstRandomDirectory + "\\" + relRandomDirectory2; 
            // Move the old directory to the new location, throw an exception and revert
            // the transaction if the operation is not successful
            try {
                // Create the first level of the new random directory 
                Directory.CreateDirectory(firstRandomDirectory);
                // Move the old directory under the newly created random directory 
                Directory.Move(rootDir + oldRandomDirectory, newRandomDirectory); 
            } catch {
                // We don't want to leak any information here. 
                // Throw a store initialization exception instead
                throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
            }
            return (relRandomDirectory1 + "\\" + relRandomDirectory2); 
        }
 
        // creates and returns the relative path to the random directory string without the path separator 
        [ResourceExposure(ResourceScope.Assembly | ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Assembly | ResourceScope.Machine)] 
        internal static string CreateRandomDirectory(String rootDir) {
            string rndName = Path.GetRandomFileName() + "\\" + Path.GetRandomFileName();
            try {
                Directory.CreateDirectory(rootDir + rndName); 
            } catch {
                // We don't want to leak any information here 
                // Throw a store initialization exception instead 
                throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Init"));
            } 
            return rndName;
        }

        // returns the relative path to the current random directory string if one is there without the path separator 
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)] 
        internal static string GetRandomDirectory(String rootDir, out bool bMigrateNeeded, out string sOldStoreLocation) 
        {
            // Initialize Out Parameters 
            bMigrateNeeded = false; sOldStoreLocation = null;
            String[] nodes1 = GetFileDirectoryNames(rootDir + "*", "*", false);
            // First see if there is a new store
            for (int i=0; i 0) {
                        int n = fs.Read(b, offset, length);
                        if (n == 0)
                            __Error.EndOfFile(); 
                        offset += n;
                        length -= n; 
                    } 
                }
                s = new MemoryStream(b); 
            } catch {
                return false;
            }
 
            return true;
        } 
    } 

    internal sealed class TwoPaths 
    {
        public String Path1;
        public String Path2;
 
    }
 
    // Given a directory, enumerates all subdirs of upto depth 2 
    internal sealed class TwoLevelFileEnumerator : IEnumerator
    { 
        private String   m_Root;
        private TwoPaths m_Current;
        private bool     m_fReset;
 
        private String[] m_RootDir;
        private int      m_nRootDir; 
 
        private String[] m_SubDir;
        private int      m_nSubDir; 


        public TwoLevelFileEnumerator(String root)
        { 
            m_Root = root;
            Reset(); 
        } 

        public bool MoveNext() 
        {
            lock (this)
            {
                // Sepecial case the Reset State 
                if (m_fReset)
                { 
                    m_fReset = false; 
                    return AdvanceRootDir();
                } 

                // Don't move anything if RootDir is empty
                if (m_RootDir.Length == 0)
                    return false; 

 
                // Get Next SubDir 

                ++m_nSubDir; 

                if (m_nSubDir >= m_SubDir.Length)
                {
                    m_nSubDir = m_SubDir.Length;    // to avoid wrap aournd. 
                    return AdvanceRootDir();
                } 
 
                UpdateCurrent();
            } 

            return true;
        }
 

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        private bool AdvanceRootDir()
        { 
            ++m_nRootDir;

            if (m_nRootDir >= m_RootDir.Length)
            { 
                m_nRootDir = m_RootDir.Length;  // to prevent wrap around
                return false;                   // We are at the very end. 
            } 

            m_SubDir = Directory.GetDirectories(m_RootDir[m_nRootDir]); 

            if (m_SubDir.Length == 0)
                return AdvanceRootDir();        // recurse here.
 
            m_nSubDir  = 0;
 
            // Set m_Current 
            UpdateCurrent();
 
            return true;
        }

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        private void UpdateCurrent() 
        { 
            m_Current.Path1 = Path.GetFileName(m_RootDir[m_nRootDir]);
            m_Current.Path2 = Path.GetFileName(m_SubDir[m_nSubDir]); 
        }

        public Object Current
        { 
            get {
 
                if (m_fReset) 
                {
                    throw new InvalidOperationException( 
                        Environment.GetResourceString(
                            "InvalidOperation_EnumNotStarted"));
                }
                else if (m_nRootDir >= m_RootDir.Length) 
                {
                    throw new InvalidOperationException( 
                        Environment.GetResourceString( 
                            "InvalidOperation_EnumEnded"));
                } 

                return (Object) m_Current;
            }
        } 

        [ResourceExposure(ResourceScope.None)]  // Scoping should be done when opening isolated storage. 
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        public void Reset()
        { 
            m_RootDir  = null;
            m_nRootDir = -1;

            m_SubDir   = null; 
            m_nSubDir  = -1;
 
            m_Current  = new TwoPaths(); 
            m_fReset   = true;
 
            m_RootDir  = Directory.GetDirectories(m_Root);
        }
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

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