コード例 #1
0
        private void OpenSqlFileStream
        (
            string path,
            byte[] transactionContext,
            System.IO.FileAccess access,
            System.IO.FileOptions options,
            Int64 allocationSize
        )
        {
            //-----------------------------------------------------------------
            // precondition validation

            // these should be checked by any caller of this method

            // ensure we have validated and normalized the path before
            Debug.Assert(path != null);
            Debug.Assert(transactionContext != null);

            if (access != FileAccess.Read && access != FileAccess.Write && access != FileAccess.ReadWrite)
            {
                throw ADP.ArgumentOutOfRange("access");
            }

            // FileOptions is a set of flags, so AND the given value against the set of values we do not support
            if ((options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.SequentialScan)) != 0)
            {
                throw ADP.ArgumentOutOfRange("options");
            }

            //-----------------------------------------------------------------

            // normalize the provided path
            //   * compress path to remove any occurences of '.' or '..'
            //   * trim whitespace from the beginning and end of the path
            //   * ensure that the path starts with '\\'
            //   * ensure that the path does not start with '\\.\'
            //   * ensure that the path is not longer than Int16.MaxValue
            path = GetFullPathInternal(path);

            // ensure the running code has permission to read/write the file
            DemandAccessPermission(path, access);

            FileFullEaInformation    eaBuffer   = null;
            SecurityQualityOfService qos        = null;
            UnicodeString            objectName = null;

            Microsoft.Win32.SafeHandles.SafeFileHandle hFile = null;

            int nDesiredAccess = UnsafeNativeMethods.FILE_READ_ATTRIBUTES | UnsafeNativeMethods.SYNCHRONIZE;

            UInt32 dwCreateOptions     = 0;
            UInt32 dwCreateDisposition = 0;

            System.IO.FileShare shareAccess = System.IO.FileShare.None;

            switch (access)
            {
            case System.IO.FileAccess.Read:
                nDesiredAccess     |= UnsafeNativeMethods.FILE_READ_DATA;
                shareAccess         = System.IO.FileShare.Delete | System.IO.FileShare.ReadWrite;
                dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OPEN;
                break;

            case System.IO.FileAccess.Write:
                nDesiredAccess     |= UnsafeNativeMethods.FILE_WRITE_DATA;
                shareAccess         = System.IO.FileShare.Delete | System.IO.FileShare.Read;
                dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE;
                break;

            case System.IO.FileAccess.ReadWrite:
            default:
                // we validate the value of 'access' parameter in the beginning of this method
                Debug.Assert(access == System.IO.FileAccess.ReadWrite);

                nDesiredAccess     |= UnsafeNativeMethods.FILE_READ_DATA | UnsafeNativeMethods.FILE_WRITE_DATA;
                shareAccess         = System.IO.FileShare.Delete | System.IO.FileShare.Read;
                dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE;
                break;
            }

            if ((options & System.IO.FileOptions.WriteThrough) != 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_WRITE_THROUGH;
            }

            if ((options & System.IO.FileOptions.Asynchronous) == 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_SYNCHRONOUS_IO_NONALERT;
            }

            if ((options & System.IO.FileOptions.SequentialScan) != 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_SEQUENTIAL_ONLY;
            }

            if ((options & System.IO.FileOptions.RandomAccess) != 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_RANDOM_ACCESS;
            }

            try
            {
                eaBuffer = new FileFullEaInformation(transactionContext);

                qos = new SecurityQualityOfService(UnsafeNativeMethods.SecurityImpersonationLevel.SecurityAnonymous,
                                                   false, false);

                // NOTE: the Name property is intended to reveal the publicly available moniker for the
                //   FILESTREAM attributed column data. We will not surface the internal processing that
                //   takes place to create the mappedPath.
                string mappedPath = InitializeNtPath(path);
                objectName = new UnicodeString(mappedPath);

                UnsafeNativeMethods.OBJECT_ATTRIBUTES oa;
                oa.length                   = Marshal.SizeOf(typeof(UnsafeNativeMethods.OBJECT_ATTRIBUTES));
                oa.rootDirectory            = IntPtr.Zero;
                oa.attributes               = (int)UnsafeNativeMethods.Attributes.CaseInsensitive;
                oa.securityDescriptor       = IntPtr.Zero;
                oa.securityQualityOfService = qos;
                oa.objectName               = objectName;

                UnsafeNativeMethods.IO_STATUS_BLOCK ioStatusBlock;

                uint oldMode;
                uint retval = 0;

                UnsafeNativeMethods.SetErrorModeWrapper(UnsafeNativeMethods.SEM_FAILCRITICALERRORS, out oldMode);
                try
                {
                    Bid.Trace("<sc.SqlFileStream.OpenSqlFileStream|ADV> %d#, desiredAccess=0x%08x, allocationSize=%I64d, fileAttributes=0x%08x, shareAccess=0x%08x, dwCreateDisposition=0x%08x, createOptions=0x%08x\n",
                              ObjectID, (int)nDesiredAccess, allocationSize, 0, (int)shareAccess, dwCreateDisposition, dwCreateOptions);

                    retval = UnsafeNativeMethods.NtCreateFile(out hFile, nDesiredAccess,
                                                              ref oa, out ioStatusBlock, ref allocationSize,
                                                              0, shareAccess, dwCreateDisposition, dwCreateOptions,
                                                              eaBuffer, (uint)eaBuffer.Length);
                }
                finally
                {
                    UnsafeNativeMethods.SetErrorModeWrapper(oldMode, out oldMode);
                }

                switch (retval)
                {
                case 0:
                    break;

                case UnsafeNativeMethods.STATUS_SHARING_VIOLATION:
                    throw ADP.InvalidOperation(Res.GetString(Res.SqlFileStream_FileAlreadyInTransaction));

                case UnsafeNativeMethods.STATUS_INVALID_PARAMETER:
                    throw ADP.Argument(Res.GetString(Res.SqlFileStream_InvalidParameter));

                case UnsafeNativeMethods.STATUS_OBJECT_NAME_NOT_FOUND:
                {
                    System.IO.DirectoryNotFoundException e = new System.IO.DirectoryNotFoundException();
                    ADP.TraceExceptionAsReturnValue(e);
                    throw e;
                }

                default:
                {
                    uint error = UnsafeNativeMethods.RtlNtStatusToDosError(retval);
                    if (error == UnsafeNativeMethods.ERROR_MR_MID_NOT_FOUND)
                    {
                        // status code could not be mapped to a Win32 error code
                        error = retval;
                    }

                    System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(unchecked ((int)error));
                    ADP.TraceExceptionAsReturnValue(e);
                    throw e;
                }
                }

                if (hFile.IsInvalid)
                {
                    System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(UnsafeNativeMethods.ERROR_INVALID_HANDLE);
                    ADP.TraceExceptionAsReturnValue(e);
                    throw e;
                }

                UnsafeNativeMethods.FileType fileType = UnsafeNativeMethods.GetFileType(hFile);
                if (fileType != UnsafeNativeMethods.FileType.Disk)
                {
                    hFile.Dispose();
                    throw ADP.Argument(Res.GetString(Res.SqlFileStream_PathNotValidDiskResource));
                }

                // if the user is opening the SQL FileStream in read/write mode, we assume that they want to scan
                //   through current data and then append new data to the end, so we need to tell SQL Server to preserve
                //   the existing file contents.
                if (access == System.IO.FileAccess.ReadWrite)
                {
                    uint ioControlCode = UnsafeNativeMethods.CTL_CODE(UnsafeNativeMethods.FILE_DEVICE_FILE_SYSTEM,
                                                                      IoControlCodeFunctionCode, (byte)UnsafeNativeMethods.Method.METHOD_BUFFERED,
                                                                      (byte)UnsafeNativeMethods.Access.FILE_ANY_ACCESS);
                    uint cbBytesReturned = 0;

                    if (!UnsafeNativeMethods.DeviceIoControl(hFile, ioControlCode, IntPtr.Zero, 0, IntPtr.Zero, 0, out cbBytesReturned, IntPtr.Zero))
                    {
                        System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
                        ADP.TraceExceptionAsReturnValue(e);
                        throw e;
                    }
                }

                // now that we've successfully opened a handle on the path and verified that it is a file,
                //   use the SafeFileHandle to initialize our internal System.IO.FileStream instance
                // NOTE: need to assert UnmanagedCode permissions for this constructor. This is relatively benign
                //   in that we've done much the same validation as in the FileStream(string path, ...) ctor case
                //   most notably, validating that the handle type corresponds to an on-disk file.
                bool bRevertAssert = false;
                try
                {
                    SecurityPermission sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
                    sp.Assert();
                    bRevertAssert = true;

                    System.Diagnostics.Debug.Assert(m_fs == null);
                    m_fs = new System.IO.FileStream(hFile, access, DefaultBufferSize, ((options & System.IO.FileOptions.Asynchronous) != 0));
                }
                finally
                {
                    if (bRevertAssert)
                    {
                        SecurityPermission.RevertAssert();
                    }
                }
            }
            catch
            {
                if (hFile != null && !hFile.IsInvalid)
                {
                    hFile.Dispose();
                }

                throw;
            }
            finally
            {
                if (eaBuffer != null)
                {
                    eaBuffer.Dispose();
                    eaBuffer = null;
                }

                if (qos != null)
                {
                    qos.Dispose();
                    qos = null;
                }

                if (objectName != null)
                {
                    objectName.Dispose();
                    objectName = null;
                }
            }
        }
コード例 #2
0
        private void OpenSqlFileStream
            (
                string path, 
                byte[] transactionContext,
                System.IO.FileAccess access, 
                System.IO.FileOptions options,
                Int64 allocationSize
            )
        {
            //-----------------------------------------------------------------
            // precondition validation

            // these should be checked by any caller of this method

            // ensure we have validated and normalized the path before
            Debug.Assert ( path != null );
            Debug.Assert (transactionContext != null);

            if (access != FileAccess.Read && access != FileAccess.Write && access != FileAccess.ReadWrite)
                throw ADP.ArgumentOutOfRange ("access");

            // FileOptions is a set of flags, so AND the given value against the set of values we do not support
            if ( ( options & ~( FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.SequentialScan ) ) != 0 )
                throw ADP.ArgumentOutOfRange ( "options" );

            //-----------------------------------------------------------------

            // normalize the provided path
            //   * compress path to remove any occurences of '.' or '..'
            //   * trim whitespace from the beginning and end of the path
            //   * ensure that the path starts with '\\'
            //   * ensure that the path does not start with '\\.\'
            //   * ensure that the path is not longer than Int16.MaxValue
            path = GetFullPathInternal ( path );

            // ensure the running code has permission to read/write the file
            DemandAccessPermission(path, access);

            FileFullEaInformation eaBuffer = null;
            SecurityQualityOfService qos = null;
            UnicodeString objectName = null;

            Microsoft.Win32.SafeHandles.SafeFileHandle hFile = null;

            int nDesiredAccess = UnsafeNativeMethods.FILE_READ_ATTRIBUTES | UnsafeNativeMethods.SYNCHRONIZE;

            UInt32 dwCreateOptions = 0;
            UInt32 dwCreateDisposition = 0;

            System.IO.FileShare shareAccess = System.IO.FileShare.None;

            switch (access)
            {
                case System.IO.FileAccess.Read:
                    nDesiredAccess |= UnsafeNativeMethods.FILE_READ_DATA;
                    shareAccess = System.IO.FileShare.Delete | System.IO.FileShare.ReadWrite;
                    dwCreateDisposition = (uint) UnsafeNativeMethods.CreationDisposition.FILE_OPEN;
                    break;

                case System.IO.FileAccess.Write:
                    nDesiredAccess |= UnsafeNativeMethods.FILE_WRITE_DATA;
                    shareAccess = System.IO.FileShare.Delete | System.IO.FileShare.Read;
                    dwCreateDisposition = (uint) UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE;
                    break;

                case System.IO.FileAccess.ReadWrite:
                default:
                    // we validate the value of 'access' parameter in the beginning of this method
                    Debug.Assert(access == System.IO.FileAccess.ReadWrite);

                    nDesiredAccess |= UnsafeNativeMethods.FILE_READ_DATA | UnsafeNativeMethods.FILE_WRITE_DATA;
                    shareAccess = System.IO.FileShare.Delete | System.IO.FileShare.Read;
                    dwCreateDisposition = (uint) UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE;
                    break;
            }

            if ((options & System.IO.FileOptions.WriteThrough) != 0)
            {
                dwCreateOptions |= (uint) UnsafeNativeMethods.CreateOption.FILE_WRITE_THROUGH;
            }

            if ((options & System.IO.FileOptions.Asynchronous) == 0)
            {
                dwCreateOptions |= (uint) UnsafeNativeMethods.CreateOption.FILE_SYNCHRONOUS_IO_NONALERT;
            }

            if ((options & System.IO.FileOptions.SequentialScan) != 0)
            {
                dwCreateOptions |= (uint) UnsafeNativeMethods.CreateOption.FILE_SEQUENTIAL_ONLY;
            }

            if ( (options & System.IO.FileOptions.RandomAccess) != 0)
            {
                dwCreateOptions |= (uint) UnsafeNativeMethods.CreateOption.FILE_RANDOM_ACCESS;
            }

            try
            {
                eaBuffer = new FileFullEaInformation(transactionContext);

                qos = new SecurityQualityOfService(UnsafeNativeMethods.SecurityImpersonationLevel.SecurityAnonymous, 
                    false, false);

                // NOTE: the Name property is intended to reveal the publicly available moniker for the
                //   FILESTREAM attributed column data. We will not surface the internal processing that
                //   takes place to create the mappedPath.
                string mappedPath = InitializeNtPath(path);
                objectName = new UnicodeString(mappedPath);

                UnsafeNativeMethods.OBJECT_ATTRIBUTES oa;
                    oa.length = Marshal.SizeOf(typeof(UnsafeNativeMethods.OBJECT_ATTRIBUTES));
                oa.rootDirectory = IntPtr.Zero;
                oa.attributes = (int)UnsafeNativeMethods.Attributes.CaseInsensitive;
                oa.securityDescriptor = IntPtr.Zero;
                oa.securityQualityOfService = qos;
                oa.objectName = objectName;

                UnsafeNativeMethods.IO_STATUS_BLOCK ioStatusBlock;

                uint oldMode;
                uint retval = 0;
                
                UnsafeNativeMethods.SetErrorModeWrapper ( UnsafeNativeMethods.SEM_FAILCRITICALERRORS, out oldMode );
                try
                {
                    Bid.Trace("<sc.SqlFileStream.OpenSqlFileStream|ADV> %d#, desiredAccess=0x%08x, allocationSize=%I64d, fileAttributes=0x%08x, shareAccess=0x%08x, dwCreateDisposition=0x%08x, createOptions=0x%08x\n",
                        ObjectID, (int) nDesiredAccess, allocationSize, 0, (int) shareAccess, dwCreateDisposition, dwCreateOptions );
                    
                    retval = UnsafeNativeMethods.NtCreateFile(out hFile, nDesiredAccess, 
                        ref oa, out ioStatusBlock, ref allocationSize, 
                        0, shareAccess, dwCreateDisposition, dwCreateOptions, 
                        eaBuffer, (uint) eaBuffer.Length);
                }
                finally
                {
                    UnsafeNativeMethods.SetErrorModeWrapper( oldMode, out oldMode );
                }

                switch ( retval )
                {
                    case 0:
                        break;

                    case UnsafeNativeMethods.STATUS_SHARING_VIOLATION:
                        throw ADP.InvalidOperation ( Res.GetString ( Res.SqlFileStream_FileAlreadyInTransaction ) );

                    case UnsafeNativeMethods.STATUS_INVALID_PARAMETER:
                        throw ADP.Argument ( Res.GetString ( Res.SqlFileStream_InvalidParameter ) );

                    case UnsafeNativeMethods.STATUS_OBJECT_NAME_NOT_FOUND:
                        {
                            System.IO.DirectoryNotFoundException e = new System.IO.DirectoryNotFoundException();
                            ADP.TraceExceptionAsReturnValue ( e );
                            throw e;
                        }
                    default:
                        {
                            uint error = UnsafeNativeMethods.RtlNtStatusToDosError ( retval );
                            if ( error == UnsafeNativeMethods.ERROR_MR_MID_NOT_FOUND )
                            {
                                // status code could not be mapped to a Win32 error code 
                                error = retval;
                            }
                            
                            System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception ( unchecked ( (int) error ) );
                            ADP.TraceExceptionAsReturnValue ( e );
                            throw e;
                        }
                }

                if ( hFile.IsInvalid )
                {
                    System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception ( UnsafeNativeMethods.ERROR_INVALID_HANDLE );
                    ADP.TraceExceptionAsReturnValue ( e );
                    throw e;
                }

                UnsafeNativeMethods.FileType fileType = UnsafeNativeMethods.GetFileType(hFile);
                if (fileType != UnsafeNativeMethods.FileType.Disk) 
                {
                    hFile.Dispose();
                    throw ADP.Argument ( Res.GetString ( Res.SqlFileStream_PathNotValidDiskResource ) );
                }

                // if the user is opening the SQL FileStream in read/write mode, we assume that they want to scan
                //   through current data and then append new data to the end, so we need to tell SQL Server to preserve
                //   the existing file contents.
                if ( access == System.IO.FileAccess.ReadWrite )
                {
                    uint ioControlCode = UnsafeNativeMethods.CTL_CODE ( UnsafeNativeMethods.FILE_DEVICE_FILE_SYSTEM, 
                        IoControlCodeFunctionCode, (byte) UnsafeNativeMethods.Method.METHOD_BUFFERED, 
                        (byte) UnsafeNativeMethods.Access.FILE_ANY_ACCESS);
                    uint cbBytesReturned = 0;
                    
                    if ( !UnsafeNativeMethods.DeviceIoControl ( hFile, ioControlCode, IntPtr.Zero, 0, IntPtr.Zero, 0, out cbBytesReturned, IntPtr.Zero ) )
                    {
                        System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception ( Marshal.GetLastWin32Error() );
                        ADP.TraceExceptionAsReturnValue ( e );
                        throw e;
                    }
                }
                
                // now that we've successfully opened a handle on the path and verified that it is a file,
                //   use the SafeFileHandle to initialize our internal System.IO.FileStream instance
                // NOTE: need to assert UnmanagedCode permissions for this constructor. This is relatively benign
                //   in that we've done much the same validation as in the FileStream(string path, ...) ctor case
                //   most notably, validating that the handle type corresponds to an on-disk file.
                bool bRevertAssert = false;
                try
                {
                    SecurityPermission sp = new SecurityPermission ( SecurityPermissionFlag.UnmanagedCode );
                    sp.Assert();
                    bRevertAssert = true;
                    
                    System.Diagnostics.Debug.Assert ( m_fs == null );
#if MOBILE
                    m_fs = new System.IO.FileStream ( hFile.DangerousGetHandle (), access, ( ( options & System.IO.FileOptions.Asynchronous ) != 0 ), DefaultBufferSize );
#else
                    m_fs = new System.IO.FileStream ( hFile, access, DefaultBufferSize, ( ( options & System.IO.FileOptions.Asynchronous ) != 0 ) );
#endif
                }
                finally
                {
                    if ( bRevertAssert )
                        SecurityPermission.RevertAssert();
                }
                
            }
            catch
            {
                if ( hFile != null && !hFile.IsInvalid )
                    hFile.Dispose();

                throw;
            }
            finally
            {
                if (eaBuffer != null)
                {
                    eaBuffer.Dispose();
                    eaBuffer = null;
                }

                if (qos != null)
                {
                    qos.Dispose();
                    qos = null;
                }

                if (objectName != null)
                {
                    objectName.Dispose();
                    objectName = null;
                }
            }
        }
コード例 #3
0
        private void OpenSqlFileStream(string path, byte[] transactionContext, FileAccess access, FileOptions options, long allocationSize)
        {
            if (((access != FileAccess.Read) && (access != FileAccess.Write)) && (access != FileAccess.ReadWrite))
            {
                throw ADP.ArgumentOutOfRange("access");
            }
            if ((options & ~(FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.SequentialScan | FileOptions.WriteThrough)) != FileOptions.None)
            {
                throw ADP.ArgumentOutOfRange("options");
            }
            path = GetFullPathInternal(path);
            DemandAccessPermission(path, access);
            FileFullEaInformation eaBuffer = null;
            SecurityQualityOfService service = null;
            UnicodeString str = null;
            SafeFileHandle fileHandle = null;
            int num2 = 0x100080;
            uint num = 0;
            uint num4 = 0;
            FileShare none = FileShare.None;
            switch (access)
            {
                case FileAccess.Read:
                    num2 |= 1;
                    none = FileShare.Delete | FileShare.ReadWrite;
                    num4 = 1;
                    break;

                case FileAccess.Write:
                    num2 |= 2;
                    none = FileShare.Delete | FileShare.Read;
                    num4 = 4;
                    break;

                default:
                    num2 |= 3;
                    none = FileShare.Delete | FileShare.Read;
                    num4 = 4;
                    break;
            }
            if ((options & (FileOptions.None | FileOptions.WriteThrough)) != FileOptions.None)
            {
                num |= 2;
            }
            if ((options & FileOptions.Asynchronous) == FileOptions.None)
            {
                num |= 0x20;
            }
            if ((options & FileOptions.SequentialScan) != FileOptions.None)
            {
                num |= 4;
            }
            if ((options & FileOptions.RandomAccess) != FileOptions.None)
            {
                num |= 0x800;
            }
            try
            {
                System.Data.SqlTypes.UnsafeNativeMethods.OBJECT_ATTRIBUTES object_attributes;
                eaBuffer = new FileFullEaInformation(transactionContext);
                service = new SecurityQualityOfService(System.Data.SqlTypes.UnsafeNativeMethods.SecurityImpersonationLevel.SecurityAnonymous, false, false);
                str = new UnicodeString(InitializeNtPath(path));
                object_attributes.length = Marshal.SizeOf(typeof(System.Data.SqlTypes.UnsafeNativeMethods.OBJECT_ATTRIBUTES));
                object_attributes.rootDirectory = IntPtr.Zero;
                object_attributes.attributes = 0x40;
                object_attributes.securityDescriptor = IntPtr.Zero;
                object_attributes.securityQualityOfService = service;
                object_attributes.objectName = str;
                uint mode = System.Data.SqlTypes.UnsafeNativeMethods.SetErrorMode(1);
                uint status = 0;
                try
                {
                    System.Data.SqlTypes.UnsafeNativeMethods.IO_STATUS_BLOCK io_status_block;
                    Bid.Trace("<sc.SqlFileStream.OpenSqlFileStream|ADV> %d#, desiredAccess=0x%08x, allocationSize=%I64d, fileAttributes=0x%08x, shareAccess=0x%08x, dwCreateDisposition=0x%08x, createOptions=0x%08x\n", this.ObjectID, num2, allocationSize, 0, (int) none, num4, num);
                    status = System.Data.SqlTypes.UnsafeNativeMethods.NtCreateFile(out fileHandle, num2, ref object_attributes, out io_status_block, ref allocationSize, 0, none, num4, num, eaBuffer, (uint) eaBuffer.Length);
                }
                finally
                {
                    System.Data.SqlTypes.UnsafeNativeMethods.SetErrorMode(mode);
                }
                switch (status)
                {
                    case 0:
                        break;

                    case 0xc000000d:
                        throw ADP.Argument(Res.GetString("SqlFileStream_InvalidParameter"));

                    case 0xc0000034:
                    {
                        DirectoryNotFoundException e = new DirectoryNotFoundException();
                        ADP.TraceExceptionAsReturnValue(e);
                        throw e;
                    }
                    case 0xc0000043:
                        throw ADP.InvalidOperation(Res.GetString("SqlFileStream_FileAlreadyInTransaction"));

                    default:
                    {
                        uint num6 = System.Data.SqlTypes.UnsafeNativeMethods.RtlNtStatusToDosError(status);
                        if (num6 == 0x13d)
                        {
                            num6 = status;
                        }
                        Win32Exception exception3 = new Win32Exception((int) num6);
                        ADP.TraceExceptionAsReturnValue(exception3);
                        throw exception3;
                    }
                }
                if (fileHandle.IsInvalid)
                {
                    Win32Exception exception2 = new Win32Exception(6);
                    ADP.TraceExceptionAsReturnValue(exception2);
                    throw exception2;
                }
                if (System.Data.SqlTypes.UnsafeNativeMethods.GetFileType(fileHandle) != System.Data.SqlTypes.UnsafeNativeMethods.FileType.Disk)
                {
                    fileHandle.Dispose();
                    throw ADP.Argument(Res.GetString("SqlFileStream_PathNotValidDiskResource"));
                }
                if (access == FileAccess.ReadWrite)
                {
                    uint ioControlCode = System.Data.SqlTypes.UnsafeNativeMethods.CTL_CODE(9, 0x958, 0, 0);
                    uint cbBytesReturned = 0;
                    if (!System.Data.SqlTypes.UnsafeNativeMethods.DeviceIoControl(fileHandle, ioControlCode, IntPtr.Zero, 0, IntPtr.Zero, 0, out cbBytesReturned, IntPtr.Zero))
                    {
                        Win32Exception exception = new Win32Exception(Marshal.GetLastWin32Error());
                        ADP.TraceExceptionAsReturnValue(exception);
                        throw exception;
                    }
                }
                bool flag = false;
                try
                {
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
                    flag = true;
                    this.m_fs = new FileStream(fileHandle, access, 1, (options & FileOptions.Asynchronous) != FileOptions.None);
                }
                finally
                {
                    if (flag)
                    {
                        CodeAccessPermission.RevertAssert();
                    }
                }
            }
            catch
            {
                if ((fileHandle != null) && !fileHandle.IsInvalid)
                {
                    fileHandle.Dispose();
                }
                throw;
            }
            finally
            {
                if (eaBuffer != null)
                {
                    eaBuffer.Dispose();
                    eaBuffer = null;
                }
                if (service != null)
                {
                    service.Dispose();
                    service = null;
                }
                if (str != null)
                {
                    str.Dispose();
                    str = null;
                }
            }
        }
コード例 #4
0
        private void OpenSqlFileStream(string path, byte[] transactionContext, FileAccess access, FileOptions options, long allocationSize)
        {
            if (((access != FileAccess.Read) && (access != FileAccess.Write)) && (access != FileAccess.ReadWrite))
            {
                throw ADP.ArgumentOutOfRange("access");
            }
            if ((options & ~(FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.SequentialScan | FileOptions.WriteThrough)) != FileOptions.None)
            {
                throw ADP.ArgumentOutOfRange("options");
            }
            path = GetFullPathInternal(path);
            DemandAccessPermission(path, access);
            FileFullEaInformation    eaBuffer   = null;
            SecurityQualityOfService service    = null;
            UnicodeString            str        = null;
            SafeFileHandle           fileHandle = null;
            int       num2 = 0x100080;
            uint      num  = 0;
            uint      num4 = 0;
            FileShare none = FileShare.None;

            switch (access)
            {
            case FileAccess.Read:
                num2 |= 1;
                none  = FileShare.Delete | FileShare.ReadWrite;
                num4  = 1;
                break;

            case FileAccess.Write:
                num2 |= 2;
                none  = FileShare.Delete | FileShare.Read;
                num4  = 4;
                break;

            default:
                num2 |= 3;
                none  = FileShare.Delete | FileShare.Read;
                num4  = 4;
                break;
            }
            if ((options & (FileOptions.None | FileOptions.WriteThrough)) != FileOptions.None)
            {
                num |= 2;
            }
            if ((options & FileOptions.Asynchronous) == FileOptions.None)
            {
                num |= 0x20;
            }
            if ((options & FileOptions.SequentialScan) != FileOptions.None)
            {
                num |= 4;
            }
            if ((options & FileOptions.RandomAccess) != FileOptions.None)
            {
                num |= 0x800;
            }
            try
            {
                System.Data.SqlTypes.UnsafeNativeMethods.OBJECT_ATTRIBUTES object_attributes;
                eaBuffer = new FileFullEaInformation(transactionContext);
                service  = new SecurityQualityOfService(System.Data.SqlTypes.UnsafeNativeMethods.SecurityImpersonationLevel.SecurityAnonymous, false, false);
                str      = new UnicodeString(InitializeNtPath(path));
                object_attributes.length                   = Marshal.SizeOf(typeof(System.Data.SqlTypes.UnsafeNativeMethods.OBJECT_ATTRIBUTES));
                object_attributes.rootDirectory            = IntPtr.Zero;
                object_attributes.attributes               = 0x40;
                object_attributes.securityDescriptor       = IntPtr.Zero;
                object_attributes.securityQualityOfService = service;
                object_attributes.objectName               = str;
                uint mode   = System.Data.SqlTypes.UnsafeNativeMethods.SetErrorMode(1);
                uint status = 0;
                try
                {
                    System.Data.SqlTypes.UnsafeNativeMethods.IO_STATUS_BLOCK io_status_block;
                    Bid.Trace("<sc.SqlFileStream.OpenSqlFileStream|ADV> %d#, desiredAccess=0x%08x, allocationSize=%I64d, fileAttributes=0x%08x, shareAccess=0x%08x, dwCreateDisposition=0x%08x, createOptions=0x%08x\n", this.ObjectID, num2, allocationSize, 0, (int)none, num4, num);
                    status = System.Data.SqlTypes.UnsafeNativeMethods.NtCreateFile(out fileHandle, num2, ref object_attributes, out io_status_block, ref allocationSize, 0, none, num4, num, eaBuffer, (uint)eaBuffer.Length);
                }
                finally
                {
                    System.Data.SqlTypes.UnsafeNativeMethods.SetErrorMode(mode);
                }
                switch (status)
                {
                case 0:
                    break;

                case 0xc000000d:
                    throw ADP.Argument(Res.GetString("SqlFileStream_InvalidParameter"));

                case 0xc0000034:
                {
                    DirectoryNotFoundException e = new DirectoryNotFoundException();
                    ADP.TraceExceptionAsReturnValue(e);
                    throw e;
                }

                case 0xc0000043:
                    throw ADP.InvalidOperation(Res.GetString("SqlFileStream_FileAlreadyInTransaction"));

                default:
                {
                    uint num6 = System.Data.SqlTypes.UnsafeNativeMethods.RtlNtStatusToDosError(status);
                    if (num6 == 0x13d)
                    {
                        num6 = status;
                    }
                    Win32Exception exception3 = new Win32Exception((int)num6);
                    ADP.TraceExceptionAsReturnValue(exception3);
                    throw exception3;
                }
                }
                if (fileHandle.IsInvalid)
                {
                    Win32Exception exception2 = new Win32Exception(6);
                    ADP.TraceExceptionAsReturnValue(exception2);
                    throw exception2;
                }
                if (System.Data.SqlTypes.UnsafeNativeMethods.GetFileType(fileHandle) != System.Data.SqlTypes.UnsafeNativeMethods.FileType.Disk)
                {
                    fileHandle.Dispose();
                    throw ADP.Argument(Res.GetString("SqlFileStream_PathNotValidDiskResource"));
                }
                if (access == FileAccess.ReadWrite)
                {
                    uint ioControlCode   = System.Data.SqlTypes.UnsafeNativeMethods.CTL_CODE(9, 0x958, 0, 0);
                    uint cbBytesReturned = 0;
                    if (!System.Data.SqlTypes.UnsafeNativeMethods.DeviceIoControl(fileHandle, ioControlCode, IntPtr.Zero, 0, IntPtr.Zero, 0, out cbBytesReturned, IntPtr.Zero))
                    {
                        Win32Exception exception = new Win32Exception(Marshal.GetLastWin32Error());
                        ADP.TraceExceptionAsReturnValue(exception);
                        throw exception;
                    }
                }
                bool flag = false;
                try
                {
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
                    flag      = true;
                    this.m_fs = new FileStream(fileHandle, access, 1, (options & FileOptions.Asynchronous) != FileOptions.None);
                }
                finally
                {
                    if (flag)
                    {
                        CodeAccessPermission.RevertAssert();
                    }
                }
            }
            catch
            {
                if ((fileHandle != null) && !fileHandle.IsInvalid)
                {
                    fileHandle.Dispose();
                }
                throw;
            }
            finally
            {
                if (eaBuffer != null)
                {
                    eaBuffer.Dispose();
                    eaBuffer = null;
                }
                if (service != null)
                {
                    service.Dispose();
                    service = null;
                }
                if (str != null)
                {
                    str.Dispose();
                    str = null;
                }
            }
        }