public IsolatedStorageFileStream(String path, FileMode mode, 
            FileAccess access, FileShare share, int bufferSize,  
            IsolatedStorageFile isf) 
        {
            if (path == null)
                throw new ArgumentNullException("path");
            Contract.EndContractBlock();

#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"));
 
            if (isf == null)
            {
#if FEATURE_ISOSTORE_LIGHT
                throw new ArgumentNullException("isf");
#else // !FEATURE_ISOSTORE_LIGHT
                m_OwnedStore = true;
                isf = IsolatedStorageFile.GetUserStoreForDomain();
#endif // !FEATURE_ISOSTORE_LIGHT                    
            }

            if (isf.Disposed)
                throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen"));

            switch (mode) {

                case FileMode.CreateNew:        // Assume new file   
                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
                case FileMode.Open:             // Open existing, else exception
                    break;
    
                default:
                    throw new ArgumentException(Environment.GetResourceString("IsolatedStorage_FileOpenMode"));
            }

            m_isf = isf;

#if !FEATURE_CORECLR
            FileIOPermission fiop = 
                new FileIOPermission(FileIOPermissionAccess.AllAccess,
                    m_isf.RootDirectory);

            fiop.Assert();
            fiop.PermitOnly();
#endif

            m_GivenPath = path;
            m_FullPath  = m_isf.GetFullPath(m_GivenPath);

#if FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT
            ulong oldFileSize=0, newFileSize;
            bool fNewFile = false, fLock=false;

            RuntimeHelpers.PrepareConstrainedRegions();
            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
#if FEATURE_ISOSTORE_LIGHT
                        // We are going to call Reserve so we need to lock the store.
                        m_isf.Lock(ref fLock);
#endif
                        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(ref fLock);      // oldFileSize needs to be 
                                                // protected

                        try {
#if FEATURE_ISOSTORE_LIGHT
                            oldFileSize = IsolatedStorageFile.RoundToBlockSize((ulong)(FileInfo.UnsafeCreateFileInfo(m_FullPath).Length));
#else
                            oldFileSize = IsolatedStorageFile.RoundToBlockSize((ulong)LongPathFile.GetLength(m_FullPath));
#endif
                        } catch (FileNotFoundException) {
                            fNewFile = true;
                        } catch {
    
                        }
    
                        break;
    
                    case FileMode.Open:             // Open existing, else exception
                        break;
    
                }
    
                if (fNewFile)
                    m_isf.ReserveOneBlock();

#endif // FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT
    
                try {

#if FEATURE_CORECLR
                    // Since FileStream's .ctor won't do a demand, we need to do our access check here.
                    m_isf.Demand(m_FullPath);
#endif

#if FEATURE_ISOSTORE_LIGHT
                    m_fs = new
                        FileStream(m_FullPath, mode, access, share, bufferSize, 
                            FileOptions.None, m_GivenPath, true);

                } catch (Exception e) {

#else
                        m_fs = new
                        FileStream(m_FullPath, mode, access, share, bufferSize,
                            FileOptions.None, m_GivenPath, true, true);

                } catch {

#endif
#if FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT

                    if (fNewFile)
                        m_isf.UnreserveOneBlock();
#endif // FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT
#if FEATURE_ISOSTORE_LIGHT
                    // IsoStore generally does not let arbitrary exceptions flow out: a
                    // IsolatedStorageException is thrown instead (see examples in IsolatedStorageFile.cs
                    // Keeping this scoped to coreclr just because changing the exception type thrown is a
                    // breaking change and that should not be introduced into the desktop without deliberation.
                    //
                    // Note that GetIsolatedStorageException may set InnerException. To the real exception
                    // Today it always does this, for debug and chk builds, and for other builds asks the host 
                    // if it is okay to do so.
                    throw IsolatedStorageFile.GetIsolatedStorageException("IsolatedStorage_Operation_ISFS", e);
#else
                    throw;
#endif // FEATURE_ISOSTORE_LIGHT
                }

#if FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT    
                // 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();
            }
#endif // FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT

#if !FEATURE_CORECLR
            CodeAccessPermission.RevertAll();
#endif
            
        }
示例#2
0
        [System.Security.SecuritySafeCritical]  // auto-generated
        public IsolatedStorageFileStream(String path, FileMode mode,
                                         FileAccess access, FileShare share, int bufferSize,
                                         IsolatedStorageFile isf)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            Contract.EndContractBlock();

#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"));
            }

            if (isf == null)
            {
#if FEATURE_ISOSTORE_LIGHT
                throw new ArgumentNullException("isf");
#else // !FEATURE_ISOSTORE_LIGHT
                m_OwnedStore = true;
                isf          = IsolatedStorageFile.GetUserStoreForDomain();
#endif // !FEATURE_ISOSTORE_LIGHT
            }

            if (isf.Disposed)
            {
                throw new ObjectDisposedException(null, Environment.GetResourceString("IsolatedStorage_StoreNotOpen"));
            }

            switch (mode)
            {
            case FileMode.CreateNew:            // Assume new file
            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
            case FileMode.Open:                 // Open existing, else exception
                break;

            default:
                throw new ArgumentException(Environment.GetResourceString("IsolatedStorage_FileOpenMode"));
            }

            m_isf = isf;

#if !FEATURE_CORECLR
            FileIOPermission fiop =
                new FileIOPermission(FileIOPermissionAccess.AllAccess,
                                     m_isf.RootDirectory);

            fiop.Assert();
            fiop.PermitOnly();
#endif

            m_GivenPath = path;
            m_FullPath  = m_isf.GetFullPath(m_GivenPath);

#if FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT
            ulong oldFileSize = 0, newFileSize;
            bool  fNewFile = false, fLock = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            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
#if FEATURE_ISOSTORE_LIGHT
                    // We are going to call Reserve so we need to lock the store.
                    m_isf.Lock(ref fLock);
#endif
                    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(ref fLock);          // oldFileSize needs to be
                    // protected

                    try {
#if FEATURE_ISOSTORE_LIGHT
                        oldFileSize = IsolatedStorageFile.RoundToBlockSize((ulong)(FileInfo.UnsafeCreateFileInfo(m_FullPath).Length));
#else
                        oldFileSize = IsolatedStorageFile.RoundToBlockSize((ulong)LongPathFile.GetLength(m_FullPath));
#endif
                    } catch (FileNotFoundException) {
                        fNewFile = true;
                    } catch {
                    }

                    break;

                case FileMode.Open:                 // Open existing, else exception
                    break;
                }

                if (fNewFile)
                {
                    m_isf.ReserveOneBlock();
                }
#endif // FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT

            try {
#if FEATURE_CORECLR
                // Since FileStream's .ctor won't do a demand, we need to do our access check here.
                m_isf.Demand(m_FullPath);
#endif

#if FEATURE_ISOSTORE_LIGHT
                m_fs = new
                       FileStream(m_FullPath, mode, access, share, bufferSize,
                                  FileOptions.None, m_GivenPath, true);
            } catch (Exception e) {
#else
                m_fs = new
                       FileStream(m_FullPath, mode, access, share, bufferSize,
                                  FileOptions.None, m_GivenPath, true, true);
            } catch {
#endif
#if FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT
                if (fNewFile)
                {
                    m_isf.UnreserveOneBlock();
                }
#endif // FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT
#if FEATURE_ISOSTORE_LIGHT
                // IsoStore generally does not let arbitrary exceptions flow out: a
                // IsolatedStorageException is thrown instead (see examples in IsolatedStorageFile.cs
                // Keeping this scoped to coreclr just because changing the exception type thrown is a
                // breaking change and that should not be introduced into the desktop without deliberation.
                //
                // Note that GetIsolatedStorageException may set InnerException. To the real exception
                // Today it always does this, for debug and chk builds, and for other builds asks the host
                // if it is okay to do so.
                throw IsolatedStorageFile.GetIsolatedStorageException("IsolatedStorage_Operation_ISFS", e);
#else
                throw;
#endif // FEATURE_ISOSTORE_LIGHT
            }

#if FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT
            // 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();
            }
        }
#endif // FEATURE_ISOLATED_STORAGE_QUOTA_ENFORCEMENT

#if !FEATURE_CORECLR
            CodeAccessPermission.RevertAll();
#endif
        }
        [System.Security.SecurityCritical] // auto-generated
        #endif
        private static String[] GetFileDirectoryNames(String path, String msg, bool file, IsolatedStorageFile isf) {
            int hr;

            if(path == null) throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
            Contract.EndContractBlock();

            bool fEndsWithDirectory = false;
            char lastChar = path[path.Length - 1];
            if(lastChar == Path.DirectorySeparatorChar ||
                lastChar == Path.AltDirectorySeparatorChar ||
                lastChar == '.')
                fEndsWithDirectory = true;


            // Get an absolute path and do a security check
            String fullPath = Path.GetFullPathInternal(path);

            // GetFullPath() removes '\', "\." etc from path, we will restore 
            // it here. If path ends in a trailing slash (\), append a * 
            // or we'll  get a "Cannot find the file specified" exception
            if((fEndsWithDirectory) &&
                (fullPath[fullPath.Length - 1] != lastChar))
                fullPath += "\\*";

            // Check for read permission to the directory, not to the contents.
            String dir = Path.GetDirectoryName(fullPath);

            if(dir != null)
                dir += "\\";

            if(isf != null) {
                try {
                    isf.Demand(dir == null ? fullPath : dir);
                } catch (Exception e) {
                    throw GetIsolatedStorageException("IsolatedStorage_Operation", e);
                }
            }

            if(CompatibilitySwitches.IsAppEarlierThanWindowsPhoneMango)
            {
                // Pre Mango Windows Phone had very odd behavior for this function.  It would take the parent directory of the search pattern and do a *
                // in there.  That means something like GetDirectories("Dir1") would be treated as GetDirectories("*") and GetDirectories("Dir2\Dir3") would be
                // treated as GetDirectories("Dir2\*").

                // This also means that GetDirectories("") returned "IsolatedStorage" since it was looking at the directory above the root of Isolated Storage.
                fullPath = Path.Combine(Path.GetDirectoryName(fullPath), "*");                
            }

            String[] list = new String[10];
            int listSize = 0;
            Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();

            // Open a Find handle 
            SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath, data);
            if(hnd.IsInvalid) {
                // Calls to GetLastWin32Error overwrites HResult.  Store HResult.
                hr = Marshal.GetLastWin32Error();
                if(hr == Win32Native.ERROR_FILE_NOT_FOUND)
                    return new String[0];

                // Mango would throw DirectoryNotFoundException if we got ERROR_PATH_NOT_FOUND instead of IsolatedStorageException
                if(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && hr == Win32Native.ERROR_PATH_NOT_FOUND)
                    __Error.WinIOError(hr, msg);

#if FEATURE_ISOSTORE_LIGHT
                throw GetIsolatedStorageException("IsolatedStorage_Operation", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error(), new IntPtr(-1)));
#else
                __Error.WinIOError(hr, msg);
#endif
            }

            // Keep asking for more matching files, adding file names to list
            int numEntries = 0;  // Number of directory entities we see.
            do {
                bool includeThis;  // Should this file/directory be included in the output?
                if(file)
                    includeThis = (0 == (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                else {
                    includeThis = (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                    // Don't add "." nor ".."
                    if(includeThis && (data.cFileName.Equals(".") || data.cFileName.Equals("..")))
                        includeThis = false;
                }

                if(includeThis) {
                    numEntries++;
                    if(listSize == list.Length) {
                        String[] newList = new String[list.Length * 2];
                        Array.Copy(list, 0, newList, 0, listSize);
                        list = newList;
                    }
                    list[listSize++] = data.cFileName;
                }

            } while(Win32Native.FindNextFile(hnd, data));

            // Make sure we quit with a sensible error.
            hr = Marshal.GetLastWin32Error();
            hnd.Close();  // Close Find handle in all cases.
            if(hr != 0 && hr != Win32Native.ERROR_NO_MORE_FILES) __Error.WinIOError(hr, msg);

            // Check for a string such as "C:\tmp", in which case we return
            // just the directory name.  FindNextFile fails first time, and
            // data still contains a directory.
            if(!file && numEntries == 1 && (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY))) {
                String[] sa = new String[1];
                sa[0] = data.cFileName;
                return sa;
            }

            // Return list of files/directories as an array of strings
            if(listSize == list.Length)
                return list;
            String[] items = new String[listSize];
            Array.Copy(list, 0, items, 0, listSize);
            return items;
        }