IsolatedStorageFileStream.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / IO / IsolatedStorage / IsolatedStorageFileStream.cs / 2 / IsolatedStorageFileStream.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
 * 
 * Class:  IsolatedStorageFileStream 
 *
 * 
 * Purpose: Provides access to files using the same interface as FileStream
 *
 * Date:  Feb 18, 2000
 * 
 ===========================================================*/
namespace System.IO.IsolatedStorage { 
    using System; 
    using System.IO;
    using Microsoft.Win32; 
    using Microsoft.Win32.SafeHandles;
    using System.Security;
    using System.Security.Permissions;
    using System.Threading; 
    using System.Runtime.InteropServices;
    using System.Runtime.Versioning; 
 
[System.Runtime.InteropServices.ComVisible(true)]
    public class IsolatedStorageFileStream : FileStream 
    {
        private const int    s_BlockSize = 1024;    // Should be a power of 2!
                                                    // see usage before
                                                    // changing this constant 
#if !FEATURE_PAL
        private const String s_BackSlash = "\\"; 
#else 
        // s_BackSlash is initialized in the contructor with Path.DirectorySeparatorChar
        private readonly String s_BackSlash; 
#endif // !FEATURE_PAL

        private FileStream m_fs;
        private IsolatedStorageFile m_isf; 
        private String m_GivenPath;
        private String m_FullPath; 
        private bool   m_OwnedStore; 

        private IsolatedStorageFileStream() {} 

        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)]
        public IsolatedStorageFileStream(String path, FileMode mode) 
            : this(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.None, null) {
        } 
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        public IsolatedStorageFileStream(String path, FileMode mode,
                IsolatedStorageFile isf)
            : this(path, mode, FileAccess.ReadWrite, FileShare.None, isf) {
        } 

        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)] 
        public IsolatedStorageFileStream(String path, FileMode mode,
                FileAccess access) 
            : this(path, mode, access, access == FileAccess.Read?
                FileShare.Read: FileShare.None, DefaultBufferSize, null) {
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)] 
        public IsolatedStorageFileStream(String path, FileMode mode, 
                FileAccess access, IsolatedStorageFile isf)
            : this(path, mode, access, access == FileAccess.Read? 
                FileShare.Read: FileShare.None, DefaultBufferSize, isf) {
        }

        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)]
        public IsolatedStorageFileStream(String path, FileMode mode, 
                FileAccess access, FileShare share) 
            : this(path, mode, access, share, DefaultBufferSize, null) {
        } 

        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public IsolatedStorageFileStream(String path, FileMode mode, 
                FileAccess access, FileShare share, IsolatedStorageFile isf)
            : this(path, mode, access, share, DefaultBufferSize, isf) { 
        } 

        [ResourceExposure(ResourceScope.AppDomain | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly, ResourceScope.AppDomain | ResourceScope.Assembly)]
        public IsolatedStorageFileStream(String path, FileMode mode,
                FileAccess access, FileShare share, int bufferSize)
            : this(path, mode, access, share, bufferSize, null) { 
        }
 
        // If the isolated storage file is null, then we default to using a file 
        // that is scoped by user, appdomain, and assembly.
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)] 
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public IsolatedStorageFileStream(String path, FileMode mode,
            FileAccess access, FileShare share, int bufferSize,
            IsolatedStorageFile isf) 
        {
            if (path == null) 
                throw new ArgumentNullException("path"); 

#if FEATURE_PAL 
            if (s_BackSlash == null)
                s_BackSlash = new String(System.IO.Path.DirectorySeparatorChar,1);
#endif // FEATURE_PAL
 
            if ((path.Length == 0) || path.Equals(s_BackSlash))
                throw new ArgumentException( 
                    Environment.GetResourceString( 
                        "IsolatedStorage_Path"));
 
            ulong oldFileSize=0, newFileSize;
            bool fNewFile = false, fLock=false;
            FileInfo fOld;
 
            if (isf == null)
            { 
                m_OwnedStore = true; 
                isf = IsolatedStorageFile.GetUserStoreForDomain();
            } 

            m_isf = isf;

            FileIOPermission fiop = 
                new FileIOPermission(FileIOPermissionAccess.AllAccess,
                    m_isf.RootDirectory); 
 
            fiop.Assert();
            fiop.PermitOnly(); 

            m_GivenPath = path;
            m_FullPath  = m_isf.GetFullPath(m_GivenPath);
 
            try { // for finally Unlocking locked store
 
                // Cache the old file size if the file size could change 
                // Also find if we are going to create a new file.
 
                switch (mode) {
                case FileMode.CreateNew:        // Assume new file
                    fNewFile = true;
                    break; 

                case FileMode.Create:           // Check for New file & Unreserve 
                case FileMode.OpenOrCreate:     // Check for new file 
                case FileMode.Truncate:         // Unreserve old file size
                case FileMode.Append:           // Check for new file 

                    m_isf.Lock();               // oldFileSize needs to be
                                                // protected
                    fLock = true;               // Lock succeded 

                    try { 
                        fOld = new FileInfo(m_FullPath); 
                        oldFileSize = IsolatedStorageFile.RoundToBlockSize((ulong)fOld.Length);
                    } catch (FileNotFoundException) { 
                            fNewFile = true;
                    } catch {
                    }
 
                    break;
 
                case FileMode.Open:             // Open existing, else exception 
                    break;
 
                default:
                    throw new ArgumentException(
                        Environment.GetResourceString(
                            "IsolatedStorage_FileOpenMode")); 
                }
 
                if (fNewFile) 
                    m_isf.ReserveOneBlock();
 
                try {
                    m_fs = new
                        FileStream(m_FullPath, mode, access, share, bufferSize,
                            FileOptions.None, m_GivenPath, true); 
                } catch {
 
                    if (fNewFile) 
                        m_isf.UnreserveOneBlock();
 
                    throw;
                }

                // make adjustment to the Reserve / Unreserve state 

                if ((fNewFile == false) && 
                    ((mode == FileMode.Truncate) || (mode == FileMode.Create))) 
                {
                    newFileSize = IsolatedStorageFile.RoundToBlockSize((ulong)m_fs.Length); 

                    if (oldFileSize > newFileSize)
                        m_isf.Unreserve(oldFileSize - newFileSize);
                    else if (newFileSize > oldFileSize)     // Can this happen ? 
                        m_isf.Reserve(newFileSize - oldFileSize);
                } 
 
            } finally {
                if (fLock) 
                    m_isf.Unlock();
            }
            CodeAccessPermission.RevertAll();
 
        }
 
#if false 
    	public IsolatedStorageFileStream(IntPtr handle, FileAccess access)
            : this(handle, access, true, false, DefaultBufferSize) { 
        }

        public IsolatedStorageFileStream(IntPtr handle, FileAccess access,
            bool ownsHandle) 
            : this(handle, access, ownsHandle, false, DefaultBufferSize) {
        } 
 
        public IsolatedStorageFileStream(IntPtr handle, FileAccess access,
            bool ownsHandle, bool isAsync) 
            : this(handle, access, ownsHandle, isAsync, DefaultBufferSize) {
        }

        [SecurityPermissionAttribute(SecurityAction.Demand, 
         Flags=SecurityPermissionFlag.UnmanagedCode)]
        public IsolatedStorageFileStream(IntPtr handle, FileAccess access, 
            bool ownsHandle, bool isAsync, int bufferSize) { 
            NotPermittedError();
        } 
#endif

        public override bool CanRead {
            get { return m_fs.CanRead; } 
        }
 
        public override bool CanWrite { 
            get { return m_fs.CanWrite; }
        } 

        public override bool CanSeek {
            get { return m_fs.CanSeek; }
        } 

        public override bool IsAsync { 
            get { return m_fs.IsAsync; } 
        }
 
        public override long Length {
            get { return m_fs.Length; }
        }
 
        public override long Position {
 
            get { return m_fs.Position; } 

            set 
            {
                if (value < 0)
                {
                    throw new ArgumentOutOfRangeException("value", 
                        Environment.GetResourceString(
                            "ArgumentOutOfRange_NeedNonNegNum")); 
                } 

                Seek(value, SeekOrigin.Begin); 
            }
        }

#if false 
        unsafe private static void AsyncFSCallback(uint errorCode,
                uint numBytes, NativeOverlapped* pOverlapped) { 
            NotPermittedError(); 
        }
#endif 

        protected override void Dispose(bool disposing)
        {
            if (disposing) { 
                if (m_fs != null)
                    m_fs.Close(); 
                if (m_OwnedStore && m_isf != null) 
                    m_isf.Close();
            } 
            base.Dispose(disposing);
        }

        public override void Flush() { 
            m_fs.Flush();
        } 
 
        [Obsolete("This property has been deprecated.  Please use IsolatedStorageFileStream's SafeFileHandle property instead.  http://go.microsoft.com/fwlink/?linkid=14202")]
        public override IntPtr Handle { 
            [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
            [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
            get {
                NotPermittedError(); 
                return Win32Native.INVALID_HANDLE_VALUE;
            } 
        } 

        public override SafeFileHandle SafeFileHandle { 
            [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
            [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
            get {
                NotPermittedError(); 
                return null;
            } 
        } 

        public override void SetLength(long value) 
        {
            if (value < 0)
                throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
 
            m_isf.Lock(); // oldLen needs to be protected
 
            try { 
                ulong oldLen = (ulong)m_fs.Length;
                ulong newLen = (ulong)value; 

                // Reserve before the operation.
                m_isf.Reserve(oldLen, newLen);
 
                try {
 
                    ZeroInit(oldLen, newLen); 

                    m_fs.SetLength(value); 

                } catch {

                    // Undo the reserve 
                    m_isf.UndoReserveOperation(oldLen, newLen);
 
                    throw; 
                }
 
                // Unreserve if this operation reduced the file size.
                if (oldLen > newLen)
                {
                    // params oldlen, newlength reversed on purpose. 
                    m_isf.UndoReserveOperation(newLen, oldLen);
                } 
 
            } finally {
                m_isf.Unlock(); 
            }
        }

        // 0 out the allocated disk so that 
        // untrusted apps won't be able to read garbage, which
        // is a security  hole, if allowed. 
        // This may not be necessary in some file systems ? 
        private void ZeroInit(ulong oldLen, ulong newLen)
        { 
            if (oldLen >= newLen)
                return;

            ulong    rem  = newLen - oldLen; 
            byte[] buffer = new byte[s_BlockSize];  // buffer is zero inited
                                                    // here by the runtime 
                                                    // memory allocator. 

            // back up the current position. 
            long pos      = m_fs.Position;

            m_fs.Seek((long)oldLen, SeekOrigin.Begin);
 
            // If we have a small number of bytes to write, do that and
            // we are done. 
            if (rem <= (ulong)s_BlockSize) 
            {
                m_fs.Write(buffer, 0, (int)rem); 
                m_fs.Position = pos;
                return;
            }
 
            // Block write is better than writing a byte in a loop
            // or all bytes. The number of bytes to write could 
            // be very large. 

            // Align to block size 
            // allign = s_BlockSize - (int)(oldLen % s_BlockSize);
            // Converting % to & operation since s_BlockSize is a power of 2

            int allign = s_BlockSize - (int)(oldLen & ((ulong)s_BlockSize - 1)); 

            /* 
                this will never happen since we already handled this case 
                leaving this code here for documentation
            if ((ulong)allign > rem) 
                allign = (int)rem;
            */

            m_fs.Write(buffer, 0, allign); 
            rem -= (ulong)allign;
 
            int nBlocks = (int)(rem / s_BlockSize); 

            // Write out one block at a time. 
            for (int i=0; i

                        

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