コード例 #1
0
        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
        {
            handle     = null;
            fileStatus = FileStatus.FILE_DOES_NOT_EXIST;
            CreateRequest request = new CreateRequest();

            request.Name               = path;
            request.DesiredAccess      = desiredAccess;
            request.FileAttributes     = fileAttributes;
            request.ShareAccess        = shareAccess;
            request.CreateDisposition  = createDisposition;
            request.CreateOptions      = createOptions;
            request.ImpersonationLevel = ImpersonationLevel.Impersonation;
            TrySendCommand(request);

            SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Create);

            if (response != null)
            {
                if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is CreateResponse)
                {
                    CreateResponse createResponse = ((CreateResponse)response);
                    handle     = createResponse.FileId;
                    fileStatus = ToFileStatus(createResponse.CreateAction);
                }
                return(response.Header.Status);
            }

            return(NTStatus.STATUS_INVALID_SMB);
        }
コード例 #2
0
        public void CreateRequest(
            int messageId,
            int sessionId,
            int treeId,
            int desiredAccess,
            CreateDisposition createDisposition,
            [Domain("ImpersonationLevel")] int impersonationLevel,
            string fileName,
            ShareType shareType,
            bool isSigned,
            bool isOpenByFileId,
            bool isDirectoryFile,
            bool isMaximumAllowedSet)
        {
            #region Create Packet

            SmbNtCreateAndxRequestPacket smbPacket = new SmbNtCreateAndxRequestPacket();
            ushort uid = (ushort)this.uId[(uint)sessionId];
            ushort tid = (ushort)this.tId[(uint)treeId];
            string shareName = string.Empty;
            CreateFlags createFlags;
            bool isCreateDirectory = false;

            if (fileName != Site.Properties["SutShareExistFile"].ToString())
            {
                if (createDisposition == CreateDisposition.FileOpenIf)
                {
                    this.createActionInternal = this.createActionInternal.Add(CreateAction.FileCreated);
                    this.createActionInternal = this.createActionInternal.Add(CreateAction.FileDoesNotExist);
                }
            }

            if (shareType == ShareType.NamedPipe)
            {
                if (SmbAdapter.isMessageModePipe)
                {
                    shareName = Site.Properties["SutShareMessagePipe"];
                }
                else
                {
                    shareName = Site.Properties["SutShareStreamPipe"];
                }

                isCreateDirectory = false;
            }
            else
            {
                if (fileName == Site.Properties["SutShareTest1"])
                {
                    shareName = Site.Properties["SutShareTest1"];
                    isCreateDirectory = false;
                }
                else if (fileName == Site.Properties["SutShareTest2"])
                {
                    shareName = Site.Properties["SutShareTest2"];
                    isCreateDirectory = false;
                }
                else if (fileName == Site.Properties["SutShareExistFile"])
                {
                    shareName = Site.Properties["SutShareExistFile"];
                    isCreateDirectory = false;
                }
                else if (fileName.Contains("."))
                {
                    shareName = fileName;
                    isCreateDirectory = false;
                }
                else
                {
                    shareName = fileName;
                    isCreateDirectory = true;
                }
            }

            this.openedFileName = shareName;

            if (isCreateDirectory)
            {
                createFlags = CreateFlags.NT_CREATE_OPEN_TARGET_DIR | CreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE;
            }
            else
            {
                createFlags = CreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE;
            }

            NamespaceCifs.NtTransactShareAccess shareAccess =
                (NamespaceCifs.NtTransactShareAccess)ushort.Parse(Site.Properties["SmbTransportShareAccess"]);

            NamespaceCifs.SMB_EXT_FILE_ATTR extFileAttributes = NamespaceCifs.SMB_EXT_FILE_ATTR.NONE;

            NamespaceCifs.NtTransactCreateDisposition ntCreateDisposition =
                (NamespaceCifs.NtTransactCreateDisposition)createDisposition;

            NtTransactCreateOptions createOption = NtTransactCreateOptions.FILE_DIRECTORY_FILE;
            if (isOpenByFileId && isDirectoryFile)
            {
                createOption =
                    NtTransactCreateOptions.FILE_OPEN_BY_FILE_ID | NtTransactCreateOptions.FILE_DIRECTORY_FILE;
            }

            if (isOpenByFileId && !isDirectoryFile)
            {
                createOption =
                    NtTransactCreateOptions.FILE_NON_DIRECTORY_FILE | NtTransactCreateOptions.FILE_OPEN_BY_FILE_ID;
            }

            if (!isOpenByFileId && isDirectoryFile)
            {
                createOption = NtTransactCreateOptions.FILE_DIRECTORY_FILE;
            }

            if (!isOpenByFileId && !isDirectoryFile)
            {
                createOption = NtTransactCreateOptions.FILE_NON_DIRECTORY_FILE;
            }

            NamespaceCifs.NtTransactDesiredAccess nTDesiredAccess =
                (NamespaceCifs.NtTransactDesiredAccess)desiredAccess;

            if (nTDesiredAccess == (
                NamespaceCifs.NtTransactDesiredAccess.FILE_READ_DATA
                | NamespaceCifs.NtTransactDesiredAccess.FILE_WRITE_DATA))
            {
                nTDesiredAccess = NamespaceCifs.NtTransactDesiredAccess.GENERIC_ALL;
            }

            if (isCreateDirectory)
            {
                nTDesiredAccess = Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Cifs.NtTransactDesiredAccess.FILE_READ_DATA |
                    Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Cifs.NtTransactDesiredAccess.FILE_READ_ATTRIBUTES |
                    Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Cifs.NtTransactDesiredAccess.SYNCHRONIZE;
                shareAccess = NamespaceCifs.NtTransactShareAccess.FILE_SHARE_READ | NamespaceCifs.NtTransactShareAccess.FILE_SHARE_WRITE;
            }

            smbPacket = this.smbClientStack.CreateCreateRequest(
                tid,
                shareName,
                nTDesiredAccess,
                extFileAttributes,
                shareAccess,
                ntCreateDisposition,
                createOption,
                (NamespaceCifs.NtTransactImpersonationLevel)impersonationLevel,
                createFlags);

            if (isSigned)
            {
                NamespaceCifs.CifsClientPerConnection connection =
                    this.smbClientStack.Context.GetConnection(ConnectionId);

                NamespaceCifs.CifsClientPerSession session =
                    this.smbClientStack.Context.GetSession(ConnectionId, uid);

                smbPacket.Sign(connection.ClientNextSendSequenceNumber, session.SessionKey);
            }

            #endregion

            #region Send and Receive ExpectPacket

            this.smbClientStack.SendPacket(smbPacket);
            StackPacket response = this.smbClientStack.ExpectPacket(this.timeout);

            NamespaceCifs.SmbPacket smbPacketResponse = (NamespaceCifs.SmbPacket)response;

            this.QueryUidTable(smbPacketResponse);
            this.QueryTidTable(smbPacketResponse);

            VerifyTransport(smbPacketResponse);
            VerifyCommonMessageSyntax(smbPacketResponse);

            if (response.GetType() == typeof(SmbErrorResponsePacket))
            {
                SmbErrorResponsePacket smbErrorResponsePacket = response as SmbErrorResponsePacket;
                NamespaceCifs.SmbHeader smbErrorHeader = smbErrorResponsePacket.SmbHeader;
                this.ErrorResponse(smbErrorHeader.Mid + this.addMidMark, (MessageStatus)smbErrorHeader.Status);
            }
            else
            {
                SmbNtCreateAndxResponsePacket smbNtCreateAndXPacket = response as SmbNtCreateAndxResponsePacket;
                NamespaceCifs.SmbHeader ntCreateAndXResponseHeader = smbNtCreateAndXPacket.SmbHeader;

                SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters ntCreateAndXResponsePayload =
                    smbNtCreateAndXPacket.SmbParameters;

                this.smbFileId = ntCreateAndXResponsePayload.FID;

                int fidValue = (int)uint.MinValue;
                if (!this.fId.ContainsValue(ntCreateAndXResponsePayload.FID))
                {
                    int count = this.fId.Count;
                    this.fId.Add((uint)(count), ntCreateAndXResponsePayload.FID);
                    fidValue = count;
                }
                else
                {
                    foreach (uint key in this.fId.Keys)
                    {
                        if (this.fId[key] == ntCreateAndXResponsePayload.FID)
                        {
                            fidValue = (int)key;
                            break;
                        }
                    }
                }

                uint creatAction = ntCreateAndXResponsePayload.CreationAction;
                Microsoft.Modeling.Set<CreateAction> actionSet = new Microsoft.Modeling.Set<CreateAction>();
                if (creatAction == CreateActionSuperseded)
                {
                    actionSet = actionSet.Add(CreateAction.FileSuperseded);
                }

                if ((creatAction & CreateActionExists) == CreateActionExists)
                {
                    actionSet = actionSet.Add(CreateAction.FileExists);
                }

                if ((creatAction & CreateActionOpened) == CreateActionOpened)
                {
                    actionSet = actionSet.Add(CreateAction.FileOpened);
                    if (!actionSet.Contains(CreateAction.FileExists))
                    {
                        actionSet = actionSet.Add(CreateAction.FileExists);
                    }
                }

                if ((creatAction & CreateActionNotExists) == CreateActionNotExists)
                {
                    actionSet = actionSet.Add(CreateAction.FileDoesNotExist);
                }

                if ((creatAction & CreateActionCreated) == CreateActionCreated)
                {
                    actionSet = actionSet.Add(CreateAction.FileCreated);
                    if (!actionSet.Contains(CreateAction.FileDoesNotExist))
                    {
                        actionSet = actionSet.Add(CreateAction.FileDoesNotExist);
                    }
                }

                if ((creatAction & CreateActionOverwritten) == CreateActionOverwritten)
                {
                    actionSet = actionSet.Add(CreateAction.FileOverwritten);
                }

                bool isIdZero = false;
                bool isNoSubStreams = false;
                if (ntCreateAndXResponsePayload.ResourceType == NamespaceCifs.FileTypeValue.FileTypeDisk)
                {
                    if (SmbAdapter.FsType == FileSystemType.Ntfs.ToString())
                    {
                        isNoSubStreams = false;
                    }
                    else
                    {
                        isNoSubStreams = true;
                    }
                }

                if (SmbAdapter.ServiceShareType == ShareType.NamedPipe)
                {
                    isNoSubStreams = true;
                }

                bool isVolumnGuidZero = false;
                if (!this.checkWindowsImplementation)
                {
                    Site.Log.Add(
                        LogEntryKind.Comment,
                        @"isFileIdZero: {0};
                        isVolumnGUIDZero: {1}",
                        isIdZero,
                        isVolumnGuidZero);
                    isIdZero = true;
                    isVolumnGuidZero = true;
                }

                bool isNotionSupportedForCreate = Boolean.Parse(Site.Properties["IsNotionSupportedForCreate"]);
                bool isSerWantCliLeverageNewCap = Boolean.Parse(Site.Properties["IsSerWantCliLeverageNewCap"]);

                VerifyMessageSyntaxSmbComNtCreateAndXResponse(
                    smbNtCreateAndXPacket,
                    isSerWantCliLeverageNewCap);

                VerifyMessageSyntaxSmbComNtCreateAndXResponseForNotNotionSupported(
                    smbNtCreateAndXPacket,
                    isNotionSupportedForCreate);

                VerifyMessageSyntaxFileIdGeneration(smbNtCreateAndXPacket.SmbParameters.FileId);
                VerifyMessageSyntaxVolumeGUIDGeneration(smbNtCreateAndXPacket.SmbParameters.VolumeGUID);

                if (0x00000003 >= (uint)impersonationLevel)
                {
                    VerifyMessageSyntaxNtTransactCreateRequest(impersonationLevel);
                }

                VerifyMessageSyntaxAccessMasks(smbNtCreateAndXPacket, isDirectoryFile);

                uint computedMaximalAccessRights = (uint)Int32.Parse(Site.Properties["ComputedMaximalAccessRights"]);
                uint computedGuestMaximalAccessRights =
                    (uint)Int32.Parse(Site.Properties["ComputedGuestMaximalAccessRights"]);

                VerifyReceiveSmbComNtCreateAndXRequest(
                    (uint)smbPacket.SmbHeader.Flags,
                    smbNtCreateAndXPacket,
                    computedMaximalAccessRights,
                    computedGuestMaximalAccessRights,
                    impersonationLevel == (int)NamespaceCifs.NtTransactImpersonationLevel.SEC_ANONYMOUS ? true : false);

                //Workaround temp code (Invalid impersonation level)
                if ((string.Equals(Site.Properties["SutPlatformOS"], "Win2K8") && impersonationLevel == 4) &&
                    !bool.Parse(Site.Properties["IsTDI33006Fixed"]))
                {
                    this.ErrorResponse(ntCreateAndXResponseHeader.Mid + this.addMidMark, MessageStatus.BadImpersonationLevel);
                }
                else
                {
                    if (this.createActionInternal.Count == uint.MinValue)
                    {
                        this.CreateResponse(
                            ntCreateAndXResponseHeader.Mid + this.addMidMark,
                            this.QueryUidTable(smbPacketResponse),
                            this.QueryTidTable(smbPacketResponse),
                            fidValue,
                            smbPacketResponse.IsSignRequired,
                            actionSet,
                            isIdZero,
                            isVolumnGuidZero,
                            (ntCreateAndXResponsePayload.Directory == uint.MinValue),
                            true,
                            isNoSubStreams,
                            (MessageStatus)ntCreateAndXResponseHeader.Status);
                    }
                    else
                    {
                        this.CreateResponse(
                            ntCreateAndXResponseHeader.Mid + this.addMidMark,
                            this.QueryUidTable(smbPacketResponse),
                            this.QueryTidTable(smbPacketResponse),
                            fidValue,
                            (smbPacketResponse).IsSignRequired,
                            this.createActionInternal,
                            isIdZero,
                            isVolumnGuidZero,
                            (ntCreateAndXResponsePayload.Directory == 0),
                            true,
                            isNoSubStreams,
                            (MessageStatus)ntCreateAndXResponseHeader.Status);
                    }
                }
                this.createActionInternal = new Microsoft.Modeling.Set<CreateAction>();
            }

            #endregion
        }
コード例 #3
0
        public void Delete(string path, bool recursive, ISMBCredential credential)
        {
            if (!path.IsSharePath())
            {
                base.Delete(path, recursive);
                return;
            }

            if (recursive)
            {
                if (!path.TryResolveHostnameFromPath(out var ipAddress))
                {
                    throw new SMBException($"Failed to Delete {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\""));
                }

                if (credential == null)
                {
                    credential = _credentialProvider.GetSMBCredential(path);
                }

                if (credential == null)
                {
                    throw new SMBException($"Failed to Delete {path}", new InvalidCredentialException("Unable to find credential in SMBCredentialProvider for path: {path}"));
                }

                ISMBFileStore fileStore = null;
                object        handle    = null;

                try
                {
                    var shareName    = path.ShareName();
                    var relativePath = path.RelativeSharePath();

                    _logger?.LogTrace($"Trying to Delete {{RelativePath: {relativePath}}} for {{ShareName: {shareName}}}");

                    using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize))
                    {
                        fileStore = connection.SMBClient.TreeConnect(shareName, out var status);

                        status.HandleStatus();

                        AccessMask        accessMask    = AccessMask.SYNCHRONIZE | AccessMask.GENERIC_READ;
                        ShareAccess       shareAccess   = ShareAccess.Delete;
                        CreateDisposition disposition   = CreateDisposition.FILE_OPEN;
                        CreateOptions     createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DIRECTORY_FILE;

                        var stopwatch = new Stopwatch();

                        stopwatch.Start();
                        do
                        {
                            if (status == NTStatus.STATUS_PENDING)
                            {
                                _logger.LogTrace($"STATUS_PENDING while trying to delete directory {path}. {stopwatch.Elapsed.TotalSeconds}/{_smbFileSystemSettings.ClientSessionTimeout} seconds elapsed.");
                            }

                            status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, accessMask, 0, shareAccess,
                                                          disposition, createOptions, null);
                        } while (status == NTStatus.STATUS_PENDING && stopwatch.Elapsed.TotalSeconds <= _smbFileSystemSettings.ClientSessionTimeout);

                        stopwatch.Stop();

                        status.HandleStatus();

                        fileStore.QueryDirectory(out List <QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, "*", FileInformationClass.FileDirectoryInformation);

                        foreach (var file in queryDirectoryFileInformation)
                        {
                            if (file.FileInformationClass == FileInformationClass.FileDirectoryInformation)
                            {
                                FileDirectoryInformation fileDirectoryInformation = (FileDirectoryInformation)file;
                                if (fileDirectoryInformation.FileName == "." ||
                                    fileDirectoryInformation.FileName == ".." ||
                                    fileDirectoryInformation.FileName == ".DS_Store")
                                {
                                    continue;
                                }
                                else if (fileDirectoryInformation.FileAttributes.HasFlag(SMBLibrary.FileAttributes.Directory))
                                {
                                    Delete(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName), recursive, credential);
                                }

                                _fileSystem.File.Delete(_fileSystem.Path.Combine(path, fileDirectoryInformation.FileName));
                            }
                        }

                        FileStoreUtilities.CloseFile(fileStore, ref handle);

                        Delete(path, credential);
                    }
                }
                catch (Exception ex)
                {
                    throw new SMBException($"Failed to Delete {path}", ex);
                }
                finally
                {
                    FileStoreUtilities.CloseFile(fileStore, ref handle);
                }
            }
            else
            {
                Delete(path);
            }
        }
コード例 #4
0
        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
        {
            handle     = null;
            fileStatus = FileStatus.FILE_DOES_NOT_EXIST;
            FileAccess createAccess         = NTFileStoreHelper.ToCreateFileAccess(desiredAccess, createDisposition);
            bool       requestedWriteAccess = (createAccess & FileAccess.Write) > 0;

            bool forceDirectory = (createOptions & CreateOptions.FILE_DIRECTORY_FILE) > 0;
            bool forceFile      = (createOptions & CreateOptions.FILE_NON_DIRECTORY_FILE) > 0;

            if (forceDirectory & (createDisposition != CreateDisposition.FILE_CREATE &&
                                  createDisposition != CreateDisposition.FILE_OPEN &&
                                  createDisposition != CreateDisposition.FILE_OPEN_IF &&
                                  createDisposition != CreateDisposition.FILE_SUPERSEDE))
            {
                return(NTStatus.STATUS_INVALID_PARAMETER);
            }

            // Windows will try to access named streams (alternate data streams) regardless of the FILE_NAMED_STREAMS flag, we need to prevent this behaviour.
            if (!m_fileSystem.SupportsNamedStreams && path.Contains(":"))
            {
                // Windows Server 2003 will return STATUS_OBJECT_NAME_NOT_FOUND
                return(NTStatus.STATUS_NO_SUCH_FILE);
            }

            FileSystemEntry entry = null;

            try
            {
                entry = m_fileSystem.GetEntry(path);
            }
            catch (FileNotFoundException)
            {
            }
            catch (DirectoryNotFoundException)
            {
            }
            catch (Exception ex)
            {
                if (ex is IOException || ex is UnauthorizedAccessException)
                {
                    NTStatus status = ToNTStatus(ex);
                    Log(Severity.Verbose, "CreateFile: Error retrieving '{0}'. {1}.", path, status);
                    return(status);
                }
                else
                {
                    throw;
                }
            }

            if (createDisposition == CreateDisposition.FILE_OPEN)
            {
                if (entry == null)
                {
                    return(NTStatus.STATUS_NO_SUCH_FILE);
                }

                fileStatus = FileStatus.FILE_EXISTS;
                if (entry.IsDirectory && forceFile)
                {
                    return(NTStatus.STATUS_FILE_IS_A_DIRECTORY);
                }

                if (!entry.IsDirectory && forceDirectory)
                {
                    return(NTStatus.STATUS_OBJECT_PATH_INVALID);
                }
            }
            else if (createDisposition == CreateDisposition.FILE_CREATE)
            {
                if (entry != null)
                {
                    // File already exists, fail the request
                    Log(Severity.Verbose, "CreateFile: File '{0}' already exists.", path);
                    fileStatus = FileStatus.FILE_EXISTS;
                    return(NTStatus.STATUS_OBJECT_NAME_COLLISION);
                }

                if (!requestedWriteAccess)
                {
                    return(NTStatus.STATUS_ACCESS_DENIED);
                }

                try
                {
                    if (forceDirectory)
                    {
                        Log(Severity.Information, "CreateFile: Creating directory '{0}'", path);
                        entry = m_fileSystem.CreateDirectory(path);
                    }
                    else
                    {
                        Log(Severity.Information, "CreateFile: Creating file '{0}'", path);
                        entry = m_fileSystem.CreateFile(path);
                    }
                }
                catch (Exception ex)
                {
                    if (ex is IOException || ex is UnauthorizedAccessException)
                    {
                        NTStatus status = ToNTStatus(ex);
                        Log(Severity.Verbose, "CreateFile: Error creating '{0}'. {1}.", path, status);
                        return(status);
                    }
                    else
                    {
                        throw;
                    }
                }
                fileStatus = FileStatus.FILE_CREATED;
            }
            else if (createDisposition == CreateDisposition.FILE_OPEN_IF ||
                     createDisposition == CreateDisposition.FILE_OVERWRITE ||
                     createDisposition == CreateDisposition.FILE_OVERWRITE_IF ||
                     createDisposition == CreateDisposition.FILE_SUPERSEDE)
            {
                if (entry == null)
                {
                    if (createDisposition == CreateDisposition.FILE_OVERWRITE)
                    {
                        return(NTStatus.STATUS_OBJECT_PATH_NOT_FOUND);
                    }

                    if (!requestedWriteAccess)
                    {
                        return(NTStatus.STATUS_ACCESS_DENIED);
                    }

                    try
                    {
                        if (forceDirectory)
                        {
                            Log(Severity.Information, "CreateFile: Creating directory '{0}'", path);
                            entry = m_fileSystem.CreateDirectory(path);
                        }
                        else
                        {
                            Log(Severity.Information, "CreateFile: Creating file '{0}'", path);
                            entry = m_fileSystem.CreateFile(path);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex is IOException || ex is UnauthorizedAccessException)
                        {
                            NTStatus status = ToNTStatus(ex);
                            Log(Severity.Verbose, "CreateFile: Error creating '{0}'. {1}.", path, status);
                            return(status);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    fileStatus = FileStatus.FILE_CREATED;
                }
                else
                {
                    fileStatus = FileStatus.FILE_EXISTS;
                    if (createDisposition == CreateDisposition.FILE_OPEN_IF)
                    {
                        if (entry.IsDirectory && forceFile)
                        {
                            return(NTStatus.STATUS_FILE_IS_A_DIRECTORY);
                        }

                        if (!entry.IsDirectory && forceDirectory)
                        {
                            return(NTStatus.STATUS_OBJECT_PATH_INVALID);
                        }
                    }
                    else
                    {
                        if (!requestedWriteAccess)
                        {
                            return(NTStatus.STATUS_ACCESS_DENIED);
                        }

                        if (createDisposition == CreateDisposition.FILE_OVERWRITE ||
                            createDisposition == CreateDisposition.FILE_OVERWRITE_IF)
                        {
                            // Truncate the file
                            try
                            {
                                Stream temp = m_fileSystem.OpenFile(path, FileMode.Truncate, FileAccess.ReadWrite, FileShare.ReadWrite, FileOptions.None);
                                temp.Close();
                            }
                            catch (Exception ex)
                            {
                                if (ex is IOException || ex is UnauthorizedAccessException)
                                {
                                    NTStatus status = ToNTStatus(ex);
                                    Log(Severity.Verbose, "CreateFile: Error truncating '{0}'. {1}.", path, status);
                                    return(status);
                                }
                                else
                                {
                                    throw;
                                }
                            }
                            fileStatus = FileStatus.FILE_OVERWRITTEN;
                        }
                        else if (createDisposition == CreateDisposition.FILE_SUPERSEDE)
                        {
                            // Delete the old file
                            try
                            {
                                m_fileSystem.Delete(path);
                            }
                            catch (Exception ex)
                            {
                                if (ex is IOException || ex is UnauthorizedAccessException)
                                {
                                    NTStatus status = ToNTStatus(ex);
                                    Log(Severity.Verbose, "CreateFile: Error deleting '{0}'. {1}.", path, status);
                                    return(status);
                                }
                                else
                                {
                                    throw;
                                }
                            }

                            try
                            {
                                if (forceDirectory)
                                {
                                    Log(Severity.Information, "CreateFile: Creating directory '{0}'", path);
                                    entry = m_fileSystem.CreateDirectory(path);
                                }
                                else
                                {
                                    Log(Severity.Information, "CreateFile: Creating file '{0}'", path);
                                    entry = m_fileSystem.CreateFile(path);
                                }
                            }
                            catch (Exception ex)
                            {
                                if (ex is IOException || ex is UnauthorizedAccessException)
                                {
                                    NTStatus status = ToNTStatus(ex);
                                    Log(Severity.Verbose, "CreateFile: Error creating '{0}'. {1}.", path, status);
                                    return(status);
                                }
                                else
                                {
                                    throw;
                                }
                            }
                            fileStatus = FileStatus.FILE_SUPERSEDED;
                        }
                    }
                }
            }
            else
            {
                return(NTStatus.STATUS_INVALID_PARAMETER);
            }

            FileAccess fileAccess = NTFileStoreHelper.ToFileAccess(desiredAccess);
            Stream     stream;

            if (fileAccess == (FileAccess)0 || entry.IsDirectory)
            {
                stream = null;
            }
            else
            {
                // Note that SetFileInformationByHandle/FILE_DISPOSITION_INFO has no effect if the handle was opened with FILE_DELETE_ON_CLOSE.
                NTStatus openStatus = OpenFileStream(out stream, path, fileAccess, shareAccess, createOptions);
                if (openStatus != NTStatus.STATUS_SUCCESS)
                {
                    return(openStatus);
                }
            }

            bool deleteOnClose = (createOptions & CreateOptions.FILE_DELETE_ON_CLOSE) > 0;

            handle = new FileHandle(path, entry.IsDirectory, stream, deleteOnClose);
            if (fileStatus != FileStatus.FILE_CREATED &&
                fileStatus != FileStatus.FILE_OVERWRITTEN &&
                fileStatus != FileStatus.FILE_SUPERSEDED)
            {
                fileStatus = FileStatus.FILE_OPENED;
            }
            return(NTStatus.STATUS_SUCCESS);
        }
コード例 #5
0
        private NTStatus CreateFile(out IntPtr handle, out FileStatus fileStatus, string nativePath, AccessMask desiredAccess, long allocationSize, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions)
        {
            UNICODE_STRING    objectName       = new UNICODE_STRING(nativePath);
            OBJECT_ATTRIBUTES objectAttributes = InitializeObjectAttributes(objectName);
            IO_STATUS_BLOCK   ioStatusBlock;
            NTStatus          status = NtCreateFile(out handle, (uint)desiredAccess, ref objectAttributes, out ioStatusBlock, ref allocationSize, fileAttributes, shareAccess, createDisposition, createOptions, IntPtr.Zero, 0);

            fileStatus = (FileStatus)ioStatusBlock.Information;
            return(status);
        }
コード例 #6
0
        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
        {
            handle     = null;
            fileStatus = FileStatus.FILE_DOES_NOT_EXIST;
            NTCreateAndXRequest request = new NTCreateAndXRequest();

            request.FileName           = path;
            request.DesiredAccess      = desiredAccess;
            request.ExtFileAttributes  = ToExtendedFileAttributes(fileAttributes);
            request.ShareAccess        = shareAccess;
            request.CreateDisposition  = createDisposition;
            request.CreateOptions      = createOptions;
            request.ImpersonationLevel = ImpersonationLevel.Impersonation;

            TrySendMessage(request);
            SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_NT_CREATE_ANDX);

            if (reply != null)
            {
                if (reply.Commands[0] is NTCreateAndXResponse)
                {
                    NTCreateAndXResponse response = reply.Commands[0] as NTCreateAndXResponse;
                    handle     = response.FID;
                    fileStatus = ToFileStatus(response.CreateDisposition);
                    return(reply.Header.Status);
                }
                else if (reply.Commands[0] is ErrorResponse)
                {
                    return(reply.Header.Status);
                }
            }
            return(NTStatus.STATUS_INVALID_SMB);
        }
コード例 #7
0
        public object OpenFile(
            string filename,
            bool isDirectory,
            FileMode fileMode     = FileMode.Open,
            FileAccess fileAccess = FileAccess.Read,
            FileShare fileShare   = FileShare.None,
            bool forDeletion      = false)
        {
            AccessMask accessMask = 0;

            if (fileAccess == FileAccess.Read)
            {
                accessMask |= AccessMask.GENERIC_READ;
            }
            if (fileAccess == FileAccess.Write)
            {
                accessMask |= AccessMask.GENERIC_WRITE;
            }
            if (fileAccess == FileAccess.ReadWrite)
            {
                accessMask |= AccessMask.GENERIC_WRITE | AccessMask.GENERIC_READ;
            }

            if (forDeletion)
            {
                accessMask |= AccessMask.DELETE;
            }

            ShareAccess shareAccess = ShareAccess.None;

            if (fileShare == FileShare.Read)
            {
                shareAccess |= ShareAccess.Read;
            }
            if (fileShare == FileShare.Delete)
            {
                shareAccess |= ShareAccess.Delete;
            }
            if (fileShare == FileShare.Write)
            {
                shareAccess |= ShareAccess.Write;
            }
            if (fileShare == FileShare.ReadWrite)
            {
                shareAccess |= ShareAccess.Write | ShareAccess.Read;
            }

            CreateDisposition createDisposition = CreateDisposition.FILE_SUPERSEDE;

            if (fileMode == FileMode.CreateNew)
            {
                createDisposition = CreateDisposition.FILE_CREATE;
            }
            if (fileMode == FileMode.Create)
            {
                createDisposition = CreateDisposition.FILE_SUPERSEDE;
            }
            if (fileMode == FileMode.Open)
            {
                createDisposition = CreateDisposition.FILE_OPEN;
            }
            if (fileMode == FileMode.OpenOrCreate)
            {
                createDisposition = CreateDisposition.FILE_OPEN_IF;
            }
            if (fileMode == FileMode.Truncate)
            {
                createDisposition = CreateDisposition.FILE_OVERWRITE_IF;
            }
            if (fileMode == FileMode.Append)
            {
                createDisposition = CreateDisposition.FILE_OPEN;
            }

            CreateOptions createOptions = 0;

            if (isDirectory)
            {
                createOptions |= CreateOptions.FILE_DIRECTORY_FILE;
            }
            else
            {
                createOptions |= CreateOptions.FILE_NON_DIRECTORY_FILE;
            }


            object     fileHandle;
            FileStatus fileStatus;

            ThrowOnError(FileStore.CreateFile(
                             out fileHandle,
                             out fileStatus,
                             filename,
                             accessMask,
                             SMBLibrary.FileAttributes.Normal,
                             shareAccess,
                             createDisposition,
                             createOptions,
                             null));

            return(fileHandle);
        }
コード例 #8
0
 /// <summary>
 /// SMB_COM_NT_CREATE_ANDX request.
 /// </summary>
 /// <param name="messageId">This is used to associate a response with a request.</param>
 /// <param name="sessionId">
 /// Set this value to 0 to request a new session setup, or set this value to a previously established session
 /// identifier to request the re-authentication of an existing session.
 /// </param>
 /// <param name="name">This is used to represent the name of the resource.</param>
 /// <param name="shareType">The type of resource the client intends to access.</param>
 /// <param name="treeId">This is used to indicate the share that the client is accessing.</param>
 /// <param name="desiredAccess">Access wanted. This value must be specified in the ACCESS_MASK format.</param>
 /// <param name="createDisposition">The action to take if a file does or does not exist.</param>
 /// <param name="impersonationLevel">
 /// This field specifies the information given to the SUT about the client and how the SUT MUST represent,
 /// or impersonate the client.
 /// </param>        
 /// <param name="isSigned">It indicates whether the SUT has message signing enabled or required.</param>
 /// <param name="isOpenByFileId">
 /// It indicates whether FILE_OPEN_BY_FILE_ID is set in CreateOptions field.
 /// </param>
 /// <param name="isDirectoryFile">
 /// It indicates whether the FILE_DIRECTORY_FILE and FILE_NON_DIRECTORY_FILE are set. 
 /// If true,FILE_DIRECTORY_FILE is set; else FILE_NON_DIRECTORY_FILE is set.
 /// </param>
 public CreateRequest(
     int messageId,
     int sessionId,
     int treeId,
     int desiredAccess,
     CreateDisposition createDisposition,
     int impersonationLevel,
     string name,
     ShareType shareType,
     bool isSigned,
     bool isOpenByFileId,
     bool isDirectoryFile)
     : base(messageId, Command.NtCreateRequest)
 {
     this.sessionId = sessionId;
     this.treeId = treeId;
     this.desiredAccess = desiredAccess;
     this.createDisposition = createDisposition;
     this.impersonationLevel = impersonationLevel;
     this.name = name;
     this.shareType = shareType;
     this.isSigned = isSigned;
     this.isOpenByFileId = isOpenByFileId;
     this.isDirectoryFile = isDirectoryFile;
 }
コード例 #9
0
 internal static MessageStatus WorkaroundOpenExistingFile(ShareAccess shareAccess, FileAccess desiredAccess,
     bool streamFound, bool isSymbolicLink, FileType openFileType, FileNameStatus fileNameStatus,
     CreateOptions existingOpenModeCreateOption, ShareAccess existOpenShareModeShareAccess,
     FileAccess existOpenDesiredAccess, CreateOptions createOption, CreateDisposition createDisposition,
     StreamTypeNameToOPen streamTypeNameToOPen, FileAttribute fileAttribute,
     FileAttribute desiredFileAttribute, MessageStatus returnedStatus, ITestSite site)
 {
     if (shareAccess == ShareAccess.FILE_SHARE_READ && desiredAccess == FileAccess.FILE_ADD_SUBDIRECTORY
         && !streamFound && !isSymbolicLink && openFileType == FileType.DataFile && fileNameStatus == FileNameStatus.Normal
         && existingOpenModeCreateOption == CreateOptions.NON_DIRECTORY_FILE && existOpenShareModeShareAccess == ShareAccess.FILE_SHARE_READ
         && existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY && createOption == CreateOptions.NO_INTERMEDIATE_BUFFERING
         && createDisposition == CreateDisposition.OPEN_IF && streamTypeNameToOPen == StreamTypeNameToOPen.NULL
         && fileAttribute == FileAttribute.NORMAL && desiredFileAttribute == FileAttribute.NORMAL)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(376, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == (CreateOptions.SYNCHRONOUS_IO_NONALERT | CreateOptions.SYNCHRONOUS_IO_ALERT))
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(373, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == CreateOptions.SYNCHRONOUS_IO_ALERT
        && desiredAccess == FileAccess.FILE_READ_DATA)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(369, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == CreateOptions.SYNCHRONOUS_IO_NONALERT
         && desiredAccess == FileAccess.FILE_READ_DATA)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(2373, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == CreateOptions.DELETE_ON_CLOSE &&
         (desiredAccess == FileAccess.ACCESS_SYSTEM_SECURITY))
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(371, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == (CreateOptions.COMPLETE_IF_OPLOCKED | CreateOptions.RESERVE_OPFILTER))
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(375, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (streamFound && !isSymbolicLink && openFileType == FileType.DataFile &&
         existingOpenModeCreateOption == CreateOptions.DIRECTORY_FILE &&
         existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY &&
         createOption == CreateOptions.DIRECTORY_FILE)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(375, MessageStatus.ACCESS_VIOLATION, returnedStatus, site);
     }
     else if (!streamFound && !isSymbolicLink && openFileType == FileType.DataFile &&
         existingOpenModeCreateOption == CreateOptions.NON_DIRECTORY_FILE &&
         existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY &&
         createOption == CreateOptions.NON_DIRECTORY_FILE &&
         fileAttribute == FileAttribute.READONLY)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(375, MessageStatus.ACCESS_DENIED, returnedStatus, site);
     }
     return returnedStatus;
 }
コード例 #10
0
        public static MessageStatus OpenExistingFile(
            ShareAccess shareAccess,
            FileAccess desiredAccess,
            StreamFoundType streamFoundType,
            SymbolicLinkType symbolicLinkType,
            FileType openFileType,
            FileNameStatus fileNameStatus,
            CreateOptions existingOpenModeCreateOption,
            ShareAccess existOpenShareModeShareAccess,
            FileAccess existOpenDesiredAccess,
            CreateOptions createOption,
            CreateDisposition createDisposition,
            StreamTypeNameToOPen streamTypeNameToOPen,
            FileAttribute fileAttribute,
            FileAttribute desiredFileAttribute
            )
        {
            MessageStatus statusShareAccess = MessageStatus.SUCCESS;
            MessageStatus statusExistAccess = MessageStatus.SUCCESS;

            //call 3.1.5.1 openInitial
            MessageStatus statusInitial = OpenFileinitial(
            desiredAccess,
            shareAccess,
            createOption,
            createDisposition,
            desiredFileAttribute,
            streamFoundType,
            symbolicLinkType,
            streamTypeNameToOPen,
            openFileType,
            fileNameStatus);

            if (statusInitial != MessageStatus.SUCCESS)
            {
                return statusInitial;
            }

            #region FileTypeToOpen

            //If FileTypeToOpen is DirectoryFile
            if (gfileTypeToOpen == FileType.DirectoryFile)
            {
                //If CreateDisposition is FILE_OPEN
                if (createDisposition == CreateDisposition.OPEN)
                {
                    //call 3.1.5.1.2.1
                    statusExistAccess = CheckExistingFileAccess(
                    openFileType,
                    fileAttribute,
                    desiredAccess,
                    createOption,
                    existingOpenModeCreateOption,
                    streamTypeNameToOPen,
                    shareAccess,
                    existOpenShareModeShareAccess);

                    if (statusExistAccess != MessageStatus.SUCCESS)
                    {
                        Helper.CaptureRequirement(635, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                            If FileTypeToOpen is DirectoryFile:If CreateDisposition is FILE_OPEN then:]
                            If this[Perform access checks as described in section 3.1.5.1.2.1.] fails, the request MUST be failed with the same status.");
                        return statusExistAccess;
                    }

                    //call 3.1.5.1.2.2
                    statusShareAccess = CheckShareAccess(
                    streamFoundType,
                    existOpenShareModeShareAccess,
                    desiredAccess,
                    existOpenDesiredAccess,
                    shareAccess);

                    if (statusShareAccess != MessageStatus.SUCCESS)
                    {
                        Helper.CaptureRequirement(636, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                            If OpenFileType is DirectoryFile:If CreateDisposition is FILE_OPEN_IF then:]
                            If this[Perform access checks as described in section 3.1.5.1.2.1.] fails, the request MUST be failed with the same status.");
                        return statusShareAccess;
                    }

                    gCreateAction = CreateAction.OPENED;
                }
                //If CreateDisposition is FILE_OPEN_IF then
                else if (createDisposition == CreateDisposition.OPEN_IF)
                {
                    //call 3.1.5.1.2.1
                    statusExistAccess = CheckExistingFileAccess(
                    openFileType,
                    fileAttribute,
                    desiredAccess,
                    createOption,
                    existingOpenModeCreateOption,
                    streamTypeNameToOPen,
                    shareAccess,
                    existOpenShareModeShareAccess);

                    if (statusExistAccess != MessageStatus.SUCCESS)
                    {
                        Helper.CaptureRequirement(640, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                            If FileTypeToOpen is DirectoryFile:If CreateDisposition is FILE_OPEN_IF then:]
                            If this[Perform sharing access checks as described in section 3.1.5.1.2.2.] fails, the request MUST be failed with the same status.");
                        return statusExistAccess;
                    }

                    //call 3.1.5.1.2.2
                    statusShareAccess = CheckShareAccess(
                    streamFoundType,
                    existOpenShareModeShareAccess,
                    desiredAccess,
                    existOpenDesiredAccess,
                    shareAccess);

                    if (statusShareAccess != MessageStatus.SUCCESS)
                    {
                        Helper.CaptureRequirement(639, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                            If FileTypeToOpen is DirectoryFile:If CreateDisposition is FILE_OPEN then:]
                            If this [Perform sharing access checks as described in section 3.1.5.1.2.2.]fails, the request MUST be failed with the same status.");
                        return statusShareAccess;
                    }

                    gCreateAction = CreateAction.OPENED;
                }
                else
                {
                    //Existing directories cannot be overwritten/superseded
                    //If File == File.Volume.RootDirectory
                    if (isFileEqualRootDirectory)
                    {
                        Helper.CaptureRequirement(578, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                            If FileTypeToOpen is DirectoryFile:]
                            Else If File == File.Volume.RootDirectory then the operation MUST be failed with STATUS_ACCESS_DENIED.");
                        return MessageStatus.ACCESS_DENIED;
                    }
                    else
                    {
                        Helper.CaptureRequirement(579, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                            If FileTypeToOpen is DirectoryFile:]
                            else[If File != File.Volume.RootDirectory ] the operation MUST be failed with STATUS_OBJECT_NAME_COLLISION.");
                        return MessageStatus.OBJECT_NAME_COLLISION;
                    }
                }
            }
            //Else if FileTypeToOpen is DataFile
            else if (gfileTypeToOpen == FileType.DataFile)
            {
                #region If Stream was found

                if (streamFoundType == StreamFoundType.StreamIsFound)
                {
                    //If CreateDisposition is FILE_CREATE
                    if (createDisposition == CreateDisposition.CREATE)
                    {
                        Helper.CaptureRequirement(584, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                            Else if FileTypeToOpen is DataFile,If Stream was found,]If CreateDisposition is FILE_CREATE,
                            then the operation MUST be failed with STATUS_OBJECT_NAME_COLLISION.");
                        return MessageStatus.OBJECT_NAME_COLLISION;
                    }

                    //If CreateDisposition is FILE_OPEN_IF
                    if (createDisposition == CreateDisposition.OPEN_IF)
                    {
                        //call 3.1.5.1.2.1
                        statusExistAccess = CheckExistingFileAccess(
                        openFileType,
                        fileAttribute,
                        desiredAccess,
                        createOption,
                        existingOpenModeCreateOption,
                        streamTypeNameToOPen,
                        shareAccess,
                        existOpenShareModeShareAccess);

                        if (statusExistAccess != MessageStatus.SUCCESS)
                        {
                            return statusExistAccess;
                        }

                        //call 3.1.5.1.2.2
                        statusShareAccess = CheckShareAccess(
                        streamFoundType,
                        existOpenShareModeShareAccess,
                        desiredAccess,
                        existOpenDesiredAccess,
                        shareAccess);

                        if (statusShareAccess != MessageStatus.SUCCESS)
                        {
                            return statusShareAccess;
                        }

                        gCreateAction = CreateAction.OPENED;
                    }
                    //If CreateDisposition is FILE_OPEN
                    else if (createDisposition == CreateDisposition.OPEN)
                    {

                        //call 3.1.5.1.2.1
                        statusExistAccess = CheckExistingFileAccess(
                        openFileType,
                        fileAttribute,
                        desiredAccess,
                        createOption,
                        existingOpenModeCreateOption,
                        streamTypeNameToOPen,
                        shareAccess,
                        existOpenShareModeShareAccess);

                        if (statusExistAccess != MessageStatus.SUCCESS)
                        {
                            return statusExistAccess;
                        }

                        //call 3.1.5.1.2.2
                        statusShareAccess = CheckShareAccess(
                        streamFoundType,
                        existOpenShareModeShareAccess,
                        desiredAccess,
                        existOpenDesiredAccess,
                        shareAccess);

                        if (statusShareAccess != MessageStatus.SUCCESS)
                        {
                            return statusShareAccess;
                        }
                        gCreateAction = CreateAction.OPENED;
                    }
                    else
                    {
                        //If File.Volume.IsReadOnly is true
                        if (isFileVolumeReadOnly)
                        {
                            Helper.CaptureRequirement(596, @"[In Open of an Existing File,Pseudocode for the operation is as follows:
                                Else if FileTypeToOpen is DataFile:If Stream was found]Else (CreateDisposition is not FILE_OPEN and is not FILE_OPEN_IF)
                                If File.Volume.IsReadOnly is true, the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.");
                            return MessageStatus.MEDIA_WRITE_PROTECTED;
                        }

                        //If Stream.Name is empty
                        if (fileNameStatus == FileNameStatus.StreamNameNull)
                        {
                            //If File.FileAttributes.FILE_ATTRIBUTE_HIDDEN is true and
                            //DesiredFileAttributes.FILE_ATTRIBUTE_HIDDEN is FALSE
                            if (fileAttribute == FileAttribute.HIDDEN &&
                                desiredFileAttribute != FileAttribute.HIDDEN)
                            {
                                Helper.CaptureRequirement(487, @"[In Open of an Existing File,Pseudocode for these checks is as follows:
                                    Else if FileTypeToOpen is DataFile,If Stream was found,Else (CreateDisposition is not FILE_OPEN and is not FILE_OPEN_IF),
                                    If Stream.Name is empty:]If File.FileAttributes.FILE_ATTRIBUTE_HIDDEN is TRUE
                                    and DesiredFileAttributes.FILE_ATTRIBUTE_HIDDEN is FALSE, then the operation MUST be failed with STATUS_ACCESS_DENIED.");
                                return MessageStatus.ACCESS_DENIED;
                            }
                            //If File.FileAttributes.FILE_ATTRIBUTE_SYSTEM is true and
                            //DesiredFileAttributes.FILE_ATTRIBUTE_SYSTEM is FALSE
                            if (fileAttribute == FileAttribute.SYSTEM &&
                                desiredFileAttribute != FileAttribute.SYSTEM)
                            {
                                Helper.CaptureRequirement(488, @"[In Open of an Existing File,Pseudocode for these checks is as follows:
                                    Else if FileTypeToOpen is DataFile,If Stream was found,Else (CreateDisposition is not FILE_OPEN and is not FILE_OPEN_IF),
                                    If Stream.Name is empty:]If File.FileAttributes.FILE_ATTRIBUTE_SYSTEM is TRUE
                                    and DesiredFileAttributes.FILE_ATTRIBUTE_SYSTEM is FALSE, then the operation MUST be failed with STATUS_ACCESS_DENIED.");
                                return MessageStatus.ACCESS_DENIED;
                            }

                            //Set DesiredFileAttributes.FILE_ATTRIBUTE_ARCHIVE to true.
                            desiredFileAttribute = desiredFileAttribute | FileAttribute.ARCHIVE;

                            //Set DesiredFileAttributes.FILE_ATTRIBUTE_NORMAL to FALSE.
                            desiredFileAttribute = desiredFileAttribute & (~FileAttribute.NORMAL);

                            //Set DesiredFileAttributes.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED to FALSE
                            desiredFileAttribute = desiredFileAttribute &
                                (~FileAttribute.NOT_CONTENT_INDEXED);

                            //If File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED is true, then
                            //set DesiredFileAttributes.FILE_ATTRIBUTE_ENCRYPTED to true.
                            if ((fileAttribute & FileAttribute.ENCRYPTED) != 0)
                            {
                                desiredFileAttribute = desiredFileAttribute | FileAttribute.ENCRYPTED;
                            }

                            //If Open.HasRestoreAccess is true
                            if (isOpenHasRestoreAccess)
                            {
                                //set Open.GrantedAccess.FILE_WRITE_EA to true
                                gOpenGrantedAccess = gOpenGrantedAccess | FileAccess.FILE_WRITE_EA;

                                //set Open.GrantedAccess.FILE_WRITE_ATTRIBUTES to true
                                gOpenGrantedAccess = gOpenGrantedAccess | FileAccess.FILE_WRITE_ATTRIBUTES;
                            }
                            else
                            {
                                //set Open.RemainingDesiredAccess
                                gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess |
                                    FileAccess.FILE_WRITE_EA;

                                //store must set Open.RemainingDesiredAccess.FILE_WRITE_ATTRIBUTES to
                                //true
                                gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess |
                                    FileAccess.FILE_WRITE_ATTRIBUTES;
                            }
                        }

                        //If CreateDisposition is FILE_SUPERSEDE
                        if (createDisposition == CreateDisposition.SUPERSEDE)
                        {
                            //If Open.HasRestoreAccess is true
                            if (isOpenHasRestoreAccess)
                            {
                                //set Open.GrantedAccess.DELETE to true
                                gOpenGrantedAccess = gOpenGrantedAccess | FileAccess.DELETE;
                            }
                            else
                            {
                                //Otherwise, the object store must set Open.RemainingDesiredAccess.
                                //FILE_WRITE_DATA to true
                                gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess | FileAccess.DELETE;
                            }
                        }
                        else
                        {
                            //If Open.HasRestoreAccess is true
                            if (isOpenHasRestoreAccess)
                            {
                                //set Open.GrantedAccess.DELETE to true
                                gOpenGrantedAccess = gOpenGrantedAccess | FileAccess.FILE_WRITE_DATA;
                            }
                            else
                            {
                                //Otherwise, the object store must set Open.RemainingDesiredAccess.
                                //FILE_WRITE_DATA to true
                                gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess |
                                    FileAccess.FILE_WRITE_DATA;
                            }
                        }

                        gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess & (~gOpenGrantedAccess);

                        if (createDisposition == CreateDisposition.SUPERSEDE)
                        {
                            gCreateAction = CreateAction.SUPERSEDED;
                        }
                        else
                        {
                            gCreateAction = CreateAction.OVERWRITTEN;
                        }
                    }
                }

                #endregion

                #region Stream not found

                else
                {
                    //If CreateDisposition is FILE_OPEN or FILE_OVERWRITE
                    if (createDisposition == CreateDisposition.OPEN)
                    {
                        Helper.CaptureRequirement(610, @"[In Open of an Existing File,Pseudocode for these checks is as follows:
                            Else if FileTypeToOpen is DataFile,Else (Steam not found)]If CreateDisposition is FILE_OPEN ,
                            the operation MUST be failed with STATUS_OBJECT_NAME_NOT_FOUND.");
                        return MessageStatus.OBJECT_NAME_NOT_FOUND;
                    }

                    //If CreateDisposition is FILE_OPEN or FILE_OVERWRITE
                    if (createDisposition == CreateDisposition.OVERWRITE)
                    {
                        Helper.CaptureRequirement(2416, @"[In Open of an Existing File,Pseudocode for these checks is as follows:
                            Else if FileTypeToOpen is DataFile,Else (Steam not found)]If CreateDisposition is FILE_OVERWRITE, the operation
                            MUST be failed with STATUS_OBJECT_NAME_NOT_FOUND.");
                        return MessageStatus.OBJECT_NAME_NOT_FOUND;
                    }

                    //If Open.GrantedAccess.FILE_WRITE_DATA is not set and Open.RemainingDesiredAccess.
                    //FILE_WRITE_DATA is not set:
                    if ((gOpenGrantedAccess & FileAccess.FILE_WRITE_DATA) == 0 &&
                        (gOpenRemainingDesiredAccess & FileAccess.FILE_WRITE_DATA) == 0)
                    {
                        //If Open.HasRestoreAccess is true
                        if (isOpenHasRestoreAccess)
                        {
                            //then the object store MUST set Open.GrantedAccess.FILE_WRITE_DATA to true.
                            gOpenGrantedAccess = gOpenGrantedAccess | FileAccess.FILE_WRITE_DATA;
                        }
                        else
                        {
                            //Otherwise, the object store MUST set Open.RemainingDesiredAccess.
                            //FILE_WRITE_DATA to true.
                            gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess | FileAccess.FILE_WRITE_DATA;
                        }
                    }

                    //call 3.1.5.1.2.1
                    statusExistAccess = CheckExistingFileAccess(
                    openFileType,
                    fileAttribute,
                    desiredAccess,
                    createOption,
                    existingOpenModeCreateOption,
                    streamTypeNameToOPen,
                    shareAccess,
                    existOpenShareModeShareAccess);

                    if (statusExistAccess != MessageStatus.SUCCESS)
                    {
                        Helper.CaptureRequirement(9840, @"[In Open of an Existing File,Pseudocode for these checks is as follows:
                            Else if FileTypeToOpen is DataFile,Else (Steam not found)] If this[Perform access checks as described in section 3.1.5.1.2.1] fails,
                            the request MUST be failed with the same status.");

                        return statusExistAccess;
                    }

                    //If File.Volume.IsReadOnly is true
                    if (isFileVolumeReadOnly)
                    {
                        Helper.CaptureRequirement(614, @"[In Open of an Existing File,Pseudocode for these checks is as follows:
                            Else if FileTypeToOpen is DataFile,Else (Steam not found)]If File.Volume.IsReadOnly is TRUE,
                            the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.");
                        return MessageStatus.MEDIA_WRITE_PROTECTED;
                    }

                    //Set CreateAction to FILE_CREATED.
                    gCreateAction = CreateAction.CREATED;
                }

                #endregion

            }

            #endregion

            // If the object store implements encryption:
            if (gSecurityContext.isImplementsEncryption)
            {
                //If (CreateAction is FILE_OVERWRITTEN) and
                //(Stream.Name is empty) and (DesiredAttributes.FILE_ATTRIBUTE_ENCRYPTED is true)
                //and (File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED is FALSE) then:
                if ((gCreateAction == CreateAction.OVERWRITTEN)
                    && (fileNameStatus == FileNameStatus.StreamNameNull) &&
                    ((desiredFileAttribute & FileAttribute.ENCRYPTED) != 0)
                    && ((fileAttribute & FileAttribute.ENCRYPTED) == 0))
                {
                    //If File.OpenList is non-empty
                    //the openList must not empty
                    Helper.CaptureRequirement(623, @"[In Open of an Existing File,Pseudocode for these checks is as follows:]
                        If the object store implements encryption:If (CreateAction is FILE_OVERWRITTEN) and (Stream.Name is empty) and (DesiredAttributes.FILE_ATTRIBUTE_ENCRYPTED is TRUE) and (File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED is FALSE), then:If File.OpenList is non-empty, then the operation MUST be failed with STATUS_SHARING_VIOLATION.");
                    return MessageStatus.SHARING_VIOLATION;
                }

                //If (CreateAction is FILE_SUPERSEDED) and
                //(Stream.Name is empty) and (DesiredAttributes.FILE_ATTRIBUTE_ENCRYPTED is true)
                //and (File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED is FALSE) then:
                if ((gCreateAction == CreateAction.SUPERSEDED)
                    && (fileNameStatus == FileNameStatus.FileNameNull) &&
                    ((desiredFileAttribute & FileAttribute.ENCRYPTED) != 0)
                    && ((fileAttribute & FileAttribute.ENCRYPTED) == 0))
                {
                    //If File.OpenList is non-empty
                    //the openList must not empty
                    Helper.CaptureRequirement(2417, @"[In Open of an Existing File,Pseudocode for these checks is as follows:]
                        If the object store implements encryption:If (CreateAction is FILE_SUPERSEDED) and (Stream.Name is empty) and (DesiredAttributes.FILE_ATTRIBUTE_ENCRYPTED is TRUE) and (File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED is FALSE), then:If File.OpenList is non-empty, then the operation MUST be failed with STATUS_SHARING_VIOLATION.");
                    return MessageStatus.SHARING_VIOLATION;
                }
            }

            // If CreateAction is FILE_OVERWRITTEN
            if (gCreateAction == CreateAction.OVERWRITTEN)
            {
                if (fileNameStatus == FileNameStatus.FileNameNull)
                {
                    //Set File.FileAttributes to DesiredFileAttributes
                    fileAttribute = desiredFileAttribute;
                }
            }

            // If CreateAction is FILE_SUPERSEDED
            if (gCreateAction == CreateAction.SUPERSEDED)
            {
                if (fileNameStatus == FileNameStatus.FileNameNull)
                {
                    //Set File.FileAttributes to DesiredFileAttributes
                    fileAttribute = desiredFileAttribute;
                }
            }

            Helper.CaptureRequirement(631, @"[In Open of an Existing File,Pseudocode for these checks is as follows:]
                The object store MUST return :CreateAction set to FILE_OPENED.");
            gCreateAction = CreateAction.OPENED;

            Helper.CaptureRequirement(630, @"[In Open of an Existing File,Pseudocode for these checks is as follows:]
                The object store MUST return:Status set to STATUS_SUCCESS.");
            return MessageStatus.SUCCESS;
        }
コード例 #11
0
        public static MessageStatus OpenFileinitial(
            FileAccess desiredAccess,
            ShareAccess shareAccess,
            CreateOptions createOption,
            CreateDisposition createDisposition,
            FileAttribute fileAttribute,
            StreamFoundType streamFoundType,
            SymbolicLinkType symbolicLinkType,
            StreamTypeNameToOPen streamTypeNameToOPen,
            FileType openFileType,
            FileNameStatus fileNameStatus)
        {
            #region phase 1  Parameter Validation

            //If DesiredAccess is not a valid value as specified in MS-SMB2 section 2.2.13.1
            if (desiredAccess == FileAccess.None)
            {
                Helper.CaptureRequirement(366, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]If any of the bits in the mask 0x0CE0FE00 are set,
                    the operation MUST be failed with STATUS_ACCESS_DENIED.");
                //If DesiredAccess is zero
                Helper.CaptureRequirement(377, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]If DesiredAccess is zero, the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return MessageStatus.ACCESS_DENIED;
            }

            //If ShareAccess is not valid values for a file object as specified in MS-SMB2 section 2.2.13
            if (shareAccess == ShareAccess.NOT_VALID_VALUE)
            {
                Helper.CaptureRequirement(2370, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If ShareAccess are not valid values for a file object as specified in [MS-SMB2] section 2.2.13.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions is not valid values for a file object as specified in MS-SMB2 section 2.2.13
            if (createOption == CreateOptions.NOT_VALID_VALUE)
            {
                Helper.CaptureRequirement(2371, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions are not valid values for a file object as specified in [MS-SMB2] section 2.2.13.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateDisposition is not valid values for a file object as specified in MS-SMB2 section 2.2.13
            if (createDisposition == CreateDisposition.NOT_VALID_VALUE)
            {
                Helper.CaptureRequirement(2372, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateDisposition are not valid values for a file object as specified in [MS-SMB2] section 2.2.13.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If FileAttributes is not valid values for a file object as specified in MS-SMB2 section 2.2.13
            if (fileAttribute == FileAttribute.NOT_VALID_VALUE)
            {
                Helper.CaptureRequirement(404, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If FileAttributes are not valid values for a file object as specified in [MS-SMB2] section 2.2.13.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.FILE_DIRECTORY_FILE && CreateOptions.FILE_NON_DIRECTORY_FILE.
            //65 indicates CreateOptions.FILE_DIRECTORY_FILE && CreateOptions.FILE_NON_DIRECTORY_FILE
            if (createOption == (CreateOptions.DIRECTORY_FILE | CreateOptions.NON_DIRECTORY_FILE))
            {
                Helper.CaptureRequirement(368, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_DIRECTORY_FILE && CreateOptions.FILE_NON_DIRECTORY_FILE.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.FILE_SYNCHRONOUS_IO_ALERT && !DesiredAccess.SYNCHRONIZE.
            //updated by meying:desiredAccess == FileAccess.FILE_READ_DATA
            if (createOption == CreateOptions.SYNCHRONOUS_IO_ALERT
               && desiredAccess == FileAccess.FILE_READ_DATA)
            {
                Helper.CaptureRequirement(369, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_SYNCHRONOUS_IO_ALERT && !DesiredAccess.SYNCHRONIZE.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If Create.FILE_SYNCHRONOUS_IO_NONALERT && !DesiredAccess.SYNCHRONIZE.
            //updated by meying:desiredAccess == FileAccess.FILE_READ_DATA
            if (createOption == CreateOptions.SYNCHRONOUS_IO_NONALERT
               && desiredAccess == FileAccess.FILE_READ_DATA)
            {
                Helper.CaptureRequirement(2373, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If Create.FILE_SYNCHRONOUS_IO_NONALERT&& !DesiredAccess.SYNCHRONIZE.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.FILE_DELETE_ON_CLOSE && !DesiredAccess.DELETE.
            if (createOption == CreateOptions.DELETE_ON_CLOSE &&
                (desiredAccess == FileAccess.FILE_READ_DATA))
            {
                Helper.CaptureRequirement(371, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_DELETE_ON_CLOSE && !DesiredAccess.DELETE.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //CreateOptions.FILE_SYNCHRONOUS_IO_ALERT && Create.FILE_SYNCHRONOUS_IO_NONALERT
            //48 indicates CreateOptions.FILE_SYNCHRONOUS_IO_ALERT && Create.FILE_SYNCHRONOUS_IO_NONALERT
            if (createOption == (CreateOptions.SYNCHRONOUS_IO_NONALERT | CreateOptions.SYNCHRONOUS_IO_ALERT))
            {
                Helper.CaptureRequirement(373, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_SYNCHRONOUS_IO_ALERT && Create.FILE_SYNCHRONOUS_IO_NONALERT.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.FILE_DIRECTORY_FILE && CreateDisposition == OVERWRITE.
            if (createOption == CreateOptions.DIRECTORY_FILE &&
                createDisposition == CreateDisposition.OVERWRITE)
            {
                Helper.CaptureRequirement(2375, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_DIRECTORY_FILE && CreateDisposition == OVERWRITE.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.FILE_DIRECTORY_FILE && CreateDisposition == NONE .
            if (createOption == CreateOptions.DIRECTORY_FILE &&
                createDisposition == CreateDisposition.SUPERSEDE)
            {
                Helper.CaptureRequirement(2374, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_DIRECTORY_FILE && CreateDisposition == SUPERSEDE .");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.FILE_DIRECTORY_FILE && CreateDisposition == OVERWRITE_IF.
            if (createOption == CreateOptions.DIRECTORY_FILE &&
                createDisposition == CreateDisposition.OVERWRITE_IF)
            {
                Helper.CaptureRequirement(2376, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_DIRECTORY_FILE && CreateDisposition == OVERWRITE_IF).");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.COMPLETE_IF_OPLOCKED && CreateOptions.FILE_RESERVE_OPFILTER
            //if ((createOption & (CreateOptions.COMPLETE_IF_OPLOCKED | CreateOptions.RESERVE_OPFILTER)) != 0)
            //1048832 indicates CreateOptions.COMPLETE_IF_OPLOCKED && CreateOptions.FILE_RESERVE_OPFILTER
            if (createOption == (CreateOptions.COMPLETE_IF_OPLOCKED | CreateOptions.RESERVE_OPFILTER))
            {
                Helper.CaptureRequirement(375, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.COMPLETE_IF_OPLOCKED && CreateOptions.FILE_RESERVE_OPFILTER.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If CreateOptions.FILE_NO_INTERMEDIATE_BUFFERING && DesiredAccess.FILE_APPEND_DATA.
            if (createOption == CreateOptions.NO_INTERMEDIATE_BUFFERING &&
                desiredAccess == FileAccess.FILE_APPEND_DATA)
            {
                Helper.CaptureRequirement(376, @"[In Application Requests an Open of a File ,Phase 1 - Parameter Validation:]
                    The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:
                    If CreateOptions.FILE_NO_INTERMEDIATE_BUFFERING && DesiredAccess.FILE_APPEND_DATA.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If PathName is not valid as specified in [MS-FSCC] section 2.1.5.
            if (fileNameStatus == FileNameStatus.NotPathNameValid)
            {
                Helper.CaptureRequirement(379, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_OBJECT_NAME_INVALID under any of the following conditions:
                    If PathName is not valid as specified in [MS-FSCC] section 2.1.5.");
                return MessageStatus.OBJECT_NAME_INVALID;
            }

            //If PathName contains a trailing backslash and CreateOptions.FILE_NON_DIRECTORY_FILE is true
            if (fileNameStatus == FileNameStatus.BlacklashName &&
                createOption == CreateOptions.NON_DIRECTORY_FILE &&
                desiredAccess == FileAccess.FILE_READ_DATA)
            {
                Helper.CaptureRequirement(380, @"[In Application Requests an Open of a File ,Pseudocode for the operation is as follows:
                    Phase 1 - Parameter Validation:]The operation MUST be failed with STATUS_OBJECT_NAME_INVALID under any of the following conditions:
                    If PathName contains a trailing backslash and CreateOptions.FILE_NON_DIRECTORY_FILE is TRUE.");
                return MessageStatus.OBJECT_NAME_INVALID;
            }

            #endregion

            #region phase 2  Volume State

            //If RootOpen.Volume.IsReadOnly && (CreateDisposition == FILE_CREATE)
            //then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED
            if (isFileVolumeReadOnly && (createDisposition == CreateDisposition.CREATE))
            {
                Helper.CaptureRequirement(2377, @"[In Application Requests an Open of a File,Pseudocode for the operation is as follows: ]
                    If RootOpen.Volume.IsReadOnly && CreateDisposition == FILE_CREATE,then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.");
                return MessageStatus.MEDIA_WRITE_PROTECTED;
            }

            //If RootOpen.Volume.IsReadOnly && (CreateDisposition == FILE_SUPERSEDE)
            //then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED
            if (isFileVolumeReadOnly && (createDisposition == CreateDisposition.SUPERSEDE))
            {
                Helper.CaptureRequirement(2378, @"[In Application Requests an Open of a File,Pseudocode for the operation is as follows: ]
                    If RootOpen.Volume.IsReadOnly &&CreateDisposition == FILE_SUPERSEDE, then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.");
                return MessageStatus.MEDIA_WRITE_PROTECTED;
            }

            //If RootOpen.Volume.IsReadOnly && (CreateDisposition == OVERWRITE)
            //then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED
            if (isFileVolumeReadOnly && (createDisposition == CreateDisposition.OVERWRITE))
            {
                Helper.CaptureRequirement(2379, @"[In Application Requests an Open of a File,Pseudocode for the operation is as follows: ]
                    If RootOpen.Volume.IsReadOnly &&CreateDisposition == OVERWRITE, then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.");
                return MessageStatus.MEDIA_WRITE_PROTECTED;
            }

            //If RootOpen.Volume.IsReadOnly && (CreateDisposition == OVERWRITE_IF)
            //then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED
            if (isFileVolumeReadOnly && (createDisposition == CreateDisposition.OVERWRITE_IF))
            {
                Helper.CaptureRequirement(2380, @"[In Application Requests an Open of a File,Pseudocode for the operation is as follows: ]
                    If RootOpen.Volume.IsReadOnly &&CreateDisposition == OVERWRITE_IF, then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.");
                return MessageStatus.MEDIA_WRITE_PROTECTED;
            }

            #endregion

            #region Phase 3  Initialization of Open Object

            gOpenRemainingDesiredAccess = desiredAccess;
            gOpenSharingMode = shareAccess;
            //4158 indicates (createOption & (CreateOptions.WRITE_THROUGH |
            //CreateOptions.SEQUENTIAL_ONLY | CreateOptions.NO_INTERMEDIATE_BUFFERING |
            //CreateOptions.SYNCHRONOUS_IO_ALERT | CreateOptions.SYNCHRONOUS_IO_NONALERT |
            //CreateOptions.DELETE_ON_CLOSE));

            gOpenMode = (CreateOptions.WRITE_THROUGH |
            CreateOptions.SEQUENTIAL_ONLY | CreateOptions.NO_INTERMEDIATE_BUFFERING |
            CreateOptions.SYNCHRONOUS_IO_ALERT | CreateOptions.SYNCHRONOUS_IO_NONALERT |
            CreateOptions.DELETE_ON_CLOSE);
            if (gSecurityContext.privilegeSet == PrivilegeSet.SeBackupPrivilege)
            {
                isOpenHasBackupAccess = true;
            }

            if (gSecurityContext.privilegeSet == PrivilegeSet.SeRestorePrivilege)
            {
                isOpenHasRestoreAccess = true;
            }

            if (gSecurityContext.privilegeSet == PrivilegeSet.SeCreateSymbolicLinkPrivilege)
            {
                isOpenHasCreateSymbolicLinkAccess = true;
            }

            if (gSecurityContext.privilegeSet == PrivilegeSet.SeManageVolumePrivilege)
            {
                isOpenHasManageVolumeAccess = true;
            }

            if (gSecurityContext.isSecurityContextSIDsContainWellKnown)
            {
                isOpenIsAdministrator = true;
            }

            #endregion

            #region phase 4  Check for backup/restore intent

            //If CreateOptions.FILE_OPEN_FOR_BACKUP_INTENT is set and (CreateDisposition ==
            //FILE_OPEN || CreateDisposition == FILE_OPEN_IF || CreateDisposition ==
            //FILE_OVERWRITE_IF) and Open.HasBackupAccess is true, then the object store
            //SHOULD grant backup access as shown in the following pseudocode:
            if (createOption == CreateOptions.OPEN_FOR_BACKUP_INTENT &&
                (createDisposition == CreateDisposition.OPEN ||
                createDisposition == CreateDisposition.OPEN_IF ||
                createDisposition == CreateDisposition.OVERWRITE_IF) && isOpenHasBackupAccess)
            {
                //2164391968 indicates FileAccess.READ_CONTROL |
                //FileAccess.ACCESS_SYSTEM_SECURITY | FileAccess.GENERIC_READ |
                //FileAccess.FILE_TRAVERSE;
                FileAccess BackupAccess = FileAccess.READ_CONTROL |
                FileAccess.ACCESS_SYSTEM_SECURITY | FileAccess.GENERIC_READ |
                FileAccess.FILE_TRAVERSE;

                if (gOpenRemainingDesiredAccess == FileAccess.MAXIMUM_ALLOWED)
                {
                    gOpenGrantedAccess = gOpenGrantedAccess | BackupAccess;
                }
                else
                {
                    gOpenGrantedAccess = gOpenGrantedAccess | (gOpenRemainingDesiredAccess & BackupAccess);
                }

                gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess & (~gOpenGrantedAccess);
            }

            //If CreateOptions.FILE_OPEN_FOR_BACKUP_INTENT is set and Open.HasRestoreAccess is true,
            //then the object store SHOULD grant restore access as shown in the following pseudocode:
            if (createOption == CreateOptions.OPEN_FOR_BACKUP_INTENT && isHasRestoreAccess)
            {
                //1091309574 indicates FileAccess.WRITE_DAC | FileAccess.WRITE_OWNER |
                //FileAccess.ACCESS_SYSTEM_SECURITY | FileAccess.GENERIC_WRITE |
                //FileAccess.FILE_ADD_FILE | FileAccess.FILE_ADD_SUBDIRECTORY |
                //FileAccess.DELETE
                FileAccess RestoreAccess = FileAccess.WRITE_DAC | FileAccess.WRITE_OWNER |
                FileAccess.ACCESS_SYSTEM_SECURITY | FileAccess.GENERIC_WRITE |
                FileAccess.FILE_ADD_FILE | FileAccess.FILE_ADD_SUBDIRECTORY |
                FileAccess.DELETE;

                if (gOpenRemainingDesiredAccess == FileAccess.MAXIMUM_ALLOWED)
                {
                    gOpenGrantedAccess = gOpenGrantedAccess | RestoreAccess;
                }
                else
                {
                    gOpenGrantedAccess = gOpenGrantedAccess | (gOpenRemainingDesiredAccess & RestoreAccess);
                }

                gOpenRemainingDesiredAccess = gOpenRemainingDesiredAccess & (~gOpenGrantedAccess);
            }

            #endregion

            #region phase 5  Parse path name

            //If any StreamTypeNamei is "$INDEX_ALLOCATION" and the corresponding
            //StreamNamei has a value other than an empty string or "$I30"
            if (fileNameStatus == FileNameStatus.StreamTypeNameIsINDEX_ALLOCATION)
            {
                if (sutPlatForm != PlatformType.NoneWindows)
                {
                    Helper.CaptureRequirement(507, @"[In Application Requests an Open of a File ,Phase 5 -- Parse path name:]
                        If any StreamTypeNamei is \""$INDEX_ALLOCATION"" and the corresponding StreamNamei has a value other than an empty string
                        or \""$I30"", the operation is failed with STATUS_INVALID_PARAMETER in Windows.");
                    return MessageStatus.INVALID_PARAMETER;
                }
                else if (isR507Implemented)
                {
                    Helper.CaptureRequirement(392, @"[In Application Requests an Open of a File ,Phase 5 -- Parse path name:]
                        If any StreamTypeNamei is \""$INDEX_ALLOCATION"" and the corresponding StreamNamei has a value other than an empty string
                        or \""$I30\"", the operation SHOULD be failed with STATUS_INVALID_PARAMETER.");
                    return MessageStatus.INVALID_PARAMETER;
                }
            }

            #endregion

            #region phase 6  Location of file

            if (streamFoundType == StreamFoundType.StreamIsNotFound)
            {
                //If (CreateDisposition == FILE_OPEN )
                if (createDisposition == CreateDisposition.OPEN)
                {
                    Helper.CaptureRequirement(513, @"[In Application Requests an Open of a File , Pseudocode for the operation is as follows:
                        Phase 6 -- Location of file:] Else:[If such a link is not found:]
                        If CreateDisposition == FILE_OPEN, the operation MUST be failed with STATUS_OBJECT_NAME_NOT_FOUND.");
                    return MessageStatus.OBJECT_NAME_NOT_FOUND;
                }

                //If (CreateDisposition == FILE_OVERWRITE)
                if (createDisposition == CreateDisposition.OVERWRITE)
                {
                    Helper.CaptureRequirement(2395, @"[In Application Requests an Open of a File , Pseudocode for the operation is as follows:
                        Phase 6 -- Location of file:] Else:[If such a link is not found:]If CreateDisposition == FILE_OVERWRITE),
                        the operation MUST be failed with STATUS_OBJECT_NAME_NOT_FOUND.");
                    return MessageStatus.OBJECT_NAME_NOT_FOUND;
                }

                //If RootOpen.Volume.IsReadOnly
                if (isFileVolumeReadOnly)
                {
                    Helper.CaptureRequirement(514, @"[In Application Requests an Open of a File , Pseudocode for the operation is as follows:
                        Phase 6 -- Location of file:] Else:[If such a link is not found:]If RootOpen.Volume.IsReadOnly
                        then the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.");
                    return MessageStatus.MEDIA_WRITE_PROTECTED;
                }

                //Helper.CaptureRequirement(547, @"[In Application Requests an Open of a File , Pseudocode for the operation is as follows:Phase 6 -- Location of file:] for this search is as follows:For i = 1 to n-1:Search ParentFile.DirectoryList for a Link where Link.Name or Link.ShortName matches FileNamei,If no such link is found, the operation MUST be failed with STATUS_OBJECT_PATH_NOT_FOUND.");
                //return MessageStatus.OBJECT_PATH_NOT_FOUND;
            }

            //If Open.GrantedAccess.FILE_TRAVERSE is not set and
            //AccessCheck( SecurityContext, Link.File.SecurityDescriptor, FILE_TRAVERSE )
            //returns FALSE,
            if ((gOpenGrantedAccess & FileAccess.FILE_TRAVERSE) == 0)
            {
                if (sutPlatForm != PlatformType.NoneWindows)
                {
                    Helper.CaptureRequirement(405, @"[In Application Requests an Open of a File , Pseudocode for the operation is as follows:
                        Phase 6 -- Location of file:] Pseudocode for this search:For i = 1 to n-1:
                        If Open.GrantedAccess.FILE_TRAVERSE is not set and AccessCheck( SecurityContext, Link.File.SecurityDescriptor, FILE_TRAVERSE )
                        returns FALSE, the operation is not  failed with STATUS_ACCESS_DENIED in Windows.");
                }
                if (isR405Implemented)
                {
                    Helper.CaptureRequirement(397, @"[In Application Requests an Open of a File ,
                        Pseudocode for the operation is as follows:Phase 6 -- Location of file:]
                        Pseudocode for this search:For i = 1 to n-1:If Open.GrantedAccess.FILE_TRAVERSE is not set
                        and AccessCheck( SecurityContext, Link.File.SecurityDescriptor, FILE_TRAVERSE ) returns FALSE, the operation MAY be failed with STATUS_ACCESS_DENIED.");
                    return MessageStatus.ACCESS_DENIED;
                }
            }
            //If Link.File.IsSymbolicLink is true
            if (symbolicLinkType == SymbolicLinkType.IsSymbolicLink)
            {
                Helper.CaptureRequirement(399, @"[In Application Requests an Open of a File ,
                     Pseudocode for the operation is as follows:Phase 6 - Location of file:]
                     Pseudocode for this search:For i = 1 to n-1:If Link.File.IsSymbolicLink is TRUE,
                     the operation MUST be failed with Status set to STATUS_STOPPED_ON_SYMLINK .");
                return MessageStatus.STOPPED_ON_SYMLINK;
            }

            #endregion

            #region phase 7  Type of file to open

            //If CreateOptions.FILE_DIRECTORY_FILE is true
            if (createOption == CreateOptions.DIRECTORY_FILE)
            {
                gfileTypeToOpen = FileType.DirectoryFile;
            }
            //Else if CreateOptions.FILE_NON_DIRECTORY_FILE is true
            else if (createOption == CreateOptions.NON_DIRECTORY_FILE)
            {
                gfileTypeToOpen = FileType.DataFile;
            }
            //Else if StreamTypeNameToOpen is "$INDEX_ALLOCATION"
            else if (streamTypeNameToOPen == StreamTypeNameToOPen.INDEX_ALLOCATION)
            {
                gfileTypeToOpen = FileType.DirectoryFile;
            }
            //Else if StreamTypeNameToOpen is "$DATA"
            else if (streamTypeNameToOPen == StreamTypeNameToOPen.DATA)
            {
                gfileTypeToOpen = FileType.DataFile;
            }
            //Else if Open.File is not NULL and Open.File.FileType is DirectoryFile
            else if (fileNameStatus == FileNameStatus.OpenFileNotNull &&
                openFileType == FileType.DirectoryFile)
            {
                gfileTypeToOpen = FileType.DirectoryFile;
            }
            //Else if PathName contains a trailing backslash
            else if (fileNameStatus == FileNameStatus.PathNameTraiblack)
            {
                gfileTypeToOpen = FileType.DirectoryFile;
            }
            //else
            else
            {
                gfileTypeToOpen = FileType.DataFile;
            }

            //If FileTypeToOpen is DirectoryFile and Open.File is not NULL and
            //Open.File.FileType is not DirectoryFile:
            if (gfileTypeToOpen == FileType.DirectoryFile &&
                fileNameStatus == FileNameStatus.OpenFileNotNull &&
                openFileType == FileType.DataFile)
            {
                //If CreateDisposition == FILE_CREATE
                if (createDisposition == CreateDisposition.CREATE)
                {
                    Helper.CaptureRequirement(414, @"[In Application Requests an Open of a File , Pseudocode for the operation is as follows:
                        Phase 7 -- Type of file to open:]If FileTypeToOpen is DirectoryFile and Open.File is not NULL
                        and Open.File.FileType is not DirectoryFile:If CreateDisposition == FILE_CREATE then the operation MUST be failed with STATUS_OBJECT_NAME_COLLISION.");
                    return MessageStatus.OBJECT_NAME_COLLISION;
                }
                //else
                else
                {
                    Helper.CaptureRequirement(2396, @"[In Application Requests an Open of a File , Phase 7 -- Type of file to open:]
                        If FileTypeToOpen is DirectoryFile and Open.File is not NULL and Open.File.FileType is not DirectoryFile:
                        else[If CreateDisposition != FILE_CREATE] the operation MUST be failed with STATUS_NOT_A_DIRECTORY.");
                    return MessageStatus.NOT_A_DIRECTORY;
                }
            }

            //If FileTypeToOpen is DataFile and StreamNameToOpen is empty and Open.File
            //is not NULL and Open.File.FileType is DirectoryFile
            if (gfileTypeToOpen == FileType.DataFile &&
                streamTypeNameToOPen == StreamTypeNameToOPen.NULL &&
                fileNameStatus == FileNameStatus.OpenFileNotNull &&
                openFileType == FileType.DirectoryFile)
            {
                Helper.CaptureRequirement(415, @"[In Application Requests an Open of a File , Pseudocode for the operation is as follows:
                    Phase 7 -- Type of file to open:]If FileTypeToOpen is DataFile and StreamNameToOpen is empty and Open.File is not NULL
                    and Open.File.FileType is DirectoryFile, the operation MUST be failed with STATUS_FILE_IS_A_DIRECTORY.");
                return MessageStatus.FILE_IS_A_DIRECTORY;
            }

            #endregion

            return MessageStatus.SUCCESS;
        }
コード例 #12
0
        internal IFileInfo FromFileName(string path, ISMBCredential credential)
        {
            if (!path.IsSharePath())
            {
                return(null);
            }

            if (!path.TryResolveHostnameFromPath(out var ipAddress))
            {
                throw new SMBException($"Failed FromFileName for {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\""));
            }

            NTStatus status = NTStatus.STATUS_SUCCESS;

            if (credential == null)
            {
                credential = _credentialProvider.GetSMBCredential(path);
            }

            if (credential == null)
            {
                throw new SMBException($"Failed FromFileName for {path}", new InvalidCredentialException($"Unable to find credential for path: {path}"));
            }

            ISMBFileStore fileStore = null;
            object        handle    = null;

            try
            {
                var shareName    = path.ShareName();
                var relativePath = path.RelativeSharePath();

                _logger?.LogTrace($"Trying FromFileName {{RelativePath: {relativePath}}} for {{ShareName: {shareName}}}");

                using var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize);

                fileStore = connection.SMBClient.TreeConnect(shareName, out status);

                status.HandleStatus();

                AccessMask        accessMask    = AccessMask.SYNCHRONIZE | AccessMask.GENERIC_READ;
                ShareAccess       shareAccess   = ShareAccess.Read;
                CreateDisposition disposition   = CreateDisposition.FILE_OPEN;
                CreateOptions     createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_NON_DIRECTORY_FILE;

                status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, accessMask, 0, shareAccess,
                                              disposition, createOptions, null);

                status.HandleStatus();

                status = fileStore.GetFileInformation(out FileInformation fileBasicInfo, handle, FileInformationClass.FileBasicInformation);
                status.HandleStatus();
                status = fileStore.GetFileInformation(out FileInformation fileStandardInfo, handle, FileInformationClass.FileStandardInformation);
                status.HandleStatus();

                FileStoreUtilities.CloseFile(fileStore, ref handle);

                return(new SMBFileInfo(path, _fileSystem, (FileBasicInformation)fileBasicInfo, (FileStandardInformation)fileStandardInfo, credential));
            }
            catch (Exception ex)
            {
                throw new SMBException($"Failed FromFileName for {path}", ex);
            }
            finally
            {
                FileStoreUtilities.CloseFile(fileStore, ref handle);
            }
        }
コード例 #13
0
        internal Stream Open(string path, FileMode mode, FileAccess access, FileShare share, FileOptions fileOptions, ISMBCredential credential)
        {
            if (!path.TryResolveHostnameFromPath(out var ipAddress))
            {
                throw new ArgumentException($"Unable to resolve \"{path.Hostname()}\"");
            }

            NTStatus status = NTStatus.STATUS_SUCCESS;

            AccessMask        accessMask  = AccessMask.MAXIMUM_ALLOWED;
            ShareAccess       shareAccess = ShareAccess.None;
            CreateDisposition disposition = CreateDisposition.FILE_OPEN;
            CreateOptions     createOptions;

            switch (fileOptions)
            {
            case FileOptions.DeleteOnClose:
                createOptions = CreateOptions.FILE_DELETE_ON_CLOSE;
                break;

            case FileOptions.RandomAccess:
                createOptions = CreateOptions.FILE_RANDOM_ACCESS;
                break;

            case FileOptions.SequentialScan:
                createOptions = CreateOptions.FILE_SEQUENTIAL_ONLY;
                break;

            case FileOptions.WriteThrough:
                createOptions = CreateOptions.FILE_WRITE_THROUGH;
                break;

            case FileOptions.None:
            case FileOptions.Encrypted:         // These two are not suported unless I am missing something
            case FileOptions.Asynchronous:      //
            default:
                createOptions = CreateOptions.FILE_NON_DIRECTORY_FILE;
                break;
            }

            switch (access)
            {
            case FileAccess.Read:
                accessMask  = AccessMask.GENERIC_READ;
                shareAccess = ShareAccess.Read;
                break;

            case FileAccess.Write:
                accessMask  = AccessMask.GENERIC_WRITE;
                shareAccess = ShareAccess.Write;
                break;

            case FileAccess.ReadWrite:
                accessMask  = AccessMask.GENERIC_ALL;
                shareAccess = ShareAccess.Write;
                break;
            }

            if (credential == null)
            {
                credential = _credentialProvider.GetSMBCredential(path);
            }

            if (credential == null)
            {
                throw new Exception($"Unable to find credential for path: {path}");
            }

            var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize);

            var shareName    = path.ShareName();
            var relativePath = path.RelativeSharePath();

            ISMBFileStore fileStore = connection.SMBClient.TreeConnect(shareName, out status);

            status.HandleStatus();

            switch (mode)
            {
            case FileMode.Create:
                disposition = CreateDisposition.FILE_CREATE;
                break;

            case FileMode.CreateNew:
                disposition = CreateDisposition.FILE_OVERWRITE;
                break;

            case FileMode.Open:
                disposition = CreateDisposition.FILE_OPEN;
                break;

            case FileMode.OpenOrCreate:
                disposition = Exists(path) ? CreateDisposition.FILE_OPEN : CreateDisposition.FILE_CREATE;
                break;
            }

            int getInfoAttempts      = 0;
            int getInfoAllowedRetrys = 5;

            object          handle;
            FileInformation fileInfo;

            do
            {
                getInfoAttempts++;
                int openAttempts      = 0;
                int openAllowedRetrys = 5;

                do
                {
                    openAttempts++;

                    status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, accessMask, 0, shareAccess,
                                                  disposition, createOptions, null);
                }while (status == NTStatus.STATUS_PENDING && openAttempts < openAllowedRetrys);

                status.HandleStatus();
                status = fileStore.GetFileInformation(out fileInfo, handle, FileInformationClass.FileStandardInformation);
            }while (status == NTStatus.STATUS_NETWORK_NAME_DELETED && getInfoAttempts < getInfoAllowedRetrys);

            status.HandleStatus();

            var fileStandardInfo = (FileStandardInformation)fileInfo;

            Stream s = new SMBStream(fileStore, handle, connection, fileStandardInfo.EndOfFile);

            if (mode == FileMode.Append)
            {
                s.Seek(0, SeekOrigin.End);
            }

            return(s);
        }
コード例 #14
0
        private IDirectoryInfo CreateDirectory(string path, ISMBCredential credential)
        {
            if (!path.IsSharePath())
            {
                return(base.CreateDirectory(path));
            }

            if (!path.TryResolveHostnameFromPath(out var ipAddress))
            {
                throw new SMBException($"Failed to CreateDirectory {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\""));
            }

            if (credential == null)
            {
                credential = _credentialProvider.GetSMBCredential(path);
            }

            if (credential == null)
            {
                throw new SMBException($"Failed to CreateDirectory {path}", new InvalidCredentialException($"Unable to find credential in SMBCredentialProvider for path: {path}"));
            }

            if (Exists(path))
            {
                return(_directoryInfoFactory.FromDirectoryName(path));
            }

            ISMBFileStore fileStore = null;
            object        handle    = null;

            try
            {
                var shareName    = path.ShareName();
                var relativePath = path.RelativeSharePath();

                _logger?.LogTrace($"Trying to CreateDirectory {{RelativePath: {relativePath}}} for {{ShareName: {shareName}}}");

                using var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize);

                fileStore = connection.SMBClient.TreeConnect(shareName, out var status);

                status.HandleStatus();

                AccessMask        accessMask    = AccessMask.SYNCHRONIZE | AccessMask.MAXIMUM_ALLOWED;
                ShareAccess       shareAccess   = ShareAccess.Read | ShareAccess.Write;
                CreateDisposition disposition   = CreateDisposition.FILE_OPEN_IF;
                CreateOptions     createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DIRECTORY_FILE;

                var stopwatch = new Stopwatch();

                stopwatch.Start();
                do
                {
                    if (status == NTStatus.STATUS_PENDING)
                    {
                        _logger.LogTrace($"STATUS_PENDING while trying to create directory {path}. {stopwatch.Elapsed.TotalSeconds}/{_smbFileSystemSettings.ClientSessionTimeout} seconds elapsed.");
                    }

                    status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, accessMask, 0, shareAccess,
                                                  disposition, createOptions, null);

                    if (status == NTStatus.STATUS_OBJECT_PATH_NOT_FOUND)
                    {
                        CreateDirectory(path.GetParentPath(), credential);
                        status = fileStore.CreateFile(out handle, out fileStatus, relativePath, accessMask, 0, shareAccess,
                                                      disposition, createOptions, null);
                    }
                } while (status == NTStatus.STATUS_PENDING && stopwatch.Elapsed.TotalSeconds <= _smbFileSystemSettings.ClientSessionTimeout);

                stopwatch.Stop();

                status.HandleStatus();

                FileStoreUtilities.CloseFile(fileStore, ref handle);

                return(_directoryInfoFactory.FromDirectoryName(path, credential));
            }
            catch (Exception ex)
            {
                throw new SMBException($"Failed to CreateDirectory {path}", ex);
            }
            finally
            {
                FileStoreUtilities.CloseFile(fileStore, ref handle);
            }
        }
コード例 #15
0
        public static void CreateRequest(
            int messageId,
            int sessionId,
            int treeId,
            [Domain("DesiredAccess")] int desiredAccess,
            CreateDisposition createDisposition,
            [Domain("ImpersonationLevel")] int impersonationLevel,
            [Domain("FileDomain")] string fileName,
            ShareType shareType,
            bool isSigned,
            bool isOpenByFileId,
            bool isDirectoryFile,
            bool isMaximumAllowedSet)
        {
            smbRequest = new CreateRequest(
                messageId,
                sessionId,
                treeId,
                desiredAccess,
                createDisposition,
                impersonationLevel,
                fileName,
                shareType,
                isSigned,
                isOpenByFileId,
                isDirectoryFile);

            Checker.CheckCreateRequest(
                smbConnection,
                messageId,
                sessionId,
                treeId,
                isSigned,
                shareType,
                fileName,
                smbState,
                isOpenByFileId,
                isDirectoryFile);

            if (shareType == ShareType.NamedPipe)
            {
                Condition.IsTrue((createDisposition == CreateDisposition.FileOpen)
                                    || (createDisposition == CreateDisposition.FileCreate)
                                    || (createDisposition == CreateDisposition.FileOpenIf));
            }
            // Save the client state when setting the max allowed, to cover the requirement.
            isClientMaxAllowedSet = isMaximumAllowedSet;

            Update.UpdateCreateRequest(smbConnection, smbRequest);
        }
コード例 #16
0
        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
        {
            fileStatus = FileStatus.FILE_DOES_NOT_EXIST;
            // It is possible to have a named pipe that does not use RPC (e.g. MS-WSP),
            // However this is not currently needed by our implementation.
            RemoteService service = GetService(path);

            if (service != null)
            {
                // All instances of a named pipe share the same pipe name, but each instance has its own buffers and handles,
                // and provides a separate conduit for client/server communication.
                RPCPipeStream stream = new RPCPipeStream(service);
                handle     = new FileHandle(path, false, stream, false);
                fileStatus = FileStatus.FILE_OPENED;
                return(NTStatus.STATUS_SUCCESS);
            }
            handle = null;
            return(NTStatus.STATUS_OBJECT_PATH_NOT_FOUND);
        }
コード例 #17
0
 static extern IntPtr CreateFileCore(string lpFileName, DesiredAccess dwDesiredAccess, ShareMode dwShareMode, IntPtr lpSecurityAttributes, CreateDisposition dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
コード例 #18
0
        public static MessageStatus CreateFile(
            FileAttribute desiredFileAttribute,
            CreateOptions createOption,
            StreamTypeNameToOpen streamTypeNameToOPen,
            FileAccess desiredAccess,
            ShareAccess shareAccess,
            CreateDisposition createDisposition,
            StreamFoundType streamFoundType,
            SymbolicLinkType symbolicLinkType,
            FileType openFileType,
            FileNameStatus fileNameStatus
            )
        {
            MessageStatus status = OpenFileinitial(
                desiredAccess,
                shareAccess,
                createOption,
                createDisposition,
                desiredFileAttribute,
                streamFoundType,
                symbolicLinkType,
                streamTypeNameToOPen,
                openFileType,
                fileNameStatus);

            if (status != MessageStatus.SUCCESS)
            {
                return(status);
            }

            #region Pseudocode for the operation

            //If FileTypeToOpen is DirectoryFile and DesiredFileAttributes.FILE_ATTRIBUTE_TEMPORARY is set
            if (gfileTypeToOpen == FileType.DirectoryFile &&
                desiredFileAttribute == FileAttribute.TEMPORARY)
            {
                Helper.CaptureRequirement(418, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If FileTypeToOpen is DirectoryFile and DesiredFileAttributes.FILE_ATTRIBUTE_TEMPORARY is set, the operation MUST be failed with STATUS_INVALID_PARAMETER.");
                return(MessageStatus.INVALID_PARAMETER);
            }

            //If DesiredFileAttributes.FILE_ATTRIBUTE_READONLY and CreateOptions.FILE_DELETE_ON_CLOSE
            //are both set
            if (desiredFileAttribute == FileAttribute.READONLY &&
                createOption == CreateOptions.DELETE_ON_CLOSE)
            {
                Helper.CaptureRequirement(419, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If DesiredFileAttributes.FILE_ATTRIBUTE_READONLY and CreateOptions.FILE_DELETE_ON_CLOSE are both set, the operation MUST be failed with STATUS_CANNOT_DELETE.");
                return(MessageStatus.CANNOT_DELETE);
            }

            //If StreamTypeNameToOpen is non-empty and has a value other than "$DATA" or
            //"$INDEX_ALLOCATION", the operation MUST be failed with STATUS_ACCESS_DENIED.
            if (streamTypeNameToOPen == StreamTypeNameToOpen.Other)
            {
                Helper.CaptureRequirement(420, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If StreamTypeNameToOpen is non-empty and has a value other than \""$DATA"",the operation MUST be failed with STATUS_OBJECT_NAME_INVALID.");
                return(MessageStatus.OBJECT_NAME_INVALID);
            }

            //If Open.RemainingDesiredAccess.ACCESS_SYSTEM_SECURITY is set and
            //Open.GrantedAccess.ACCESS_SYSTEM_SECURITY is not set and
            //SecurityContext.PrivilegeSet does not contain "SeSecurityPrivilege"
            //3 indicate SeBackupPrivilege and SeRestorePrivilege
            if (gOpenRemainingDesiredAccess == FileAccess.ACCESS_SYSTEM_SECURITY &&
                gOpenGrantedAccess == FileAccess.FILE_APPEND_DATA &&
                gSecurityContext.privilegeSet == (PrivilegeSet.SeBackupPrivilege | PrivilegeSet.SeRestorePrivilege))
            {
                Helper.CaptureRequirement(422, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If Open.RemainingDesiredAccess.ACCESS_SYSTEM_SECURITY is set and Open.GrantedAccess.ACCESS_SYSTEM_SECURITY is not set and SecurityContext.PrivilegeSet does not contain \""SeSecurityPrivilege"", the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return(MessageStatus.ACCESS_DENIED);
            }

            //If FileTypeToOpen is DataFile and Open.GrantedAccess.FILE_ADD_FILE is not set
            //and AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor,
            //FILE_ADD_FILE ) returns FALSE and Open.HasRestoreAccess is FALSE

            if (gfileTypeToOpen == FileType.DataFile &&
                gOpenGrantedAccess == FileAccess.FILE_ADD_SUBDIRECTORY &&
                !isOpenHasRestoreAccess)
            {
                Helper.CaptureRequirement(423, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                    If FileTypeToOpen is DataFile and Open.GrantedAccess.FILE_ADD_FILE is not set and 
                    AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor, FILE_ADD_FILE ) 
                    returns FALSE and Open.HasRestoreAccess is FALSE, the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return(MessageStatus.ACCESS_DENIED);
            }

            //If FileTypeToOpen is DirectoryFile and Open.GrantedAccess.FILE_ADD_SUBDIRECTORY
            //is not set and AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor,
            //FILE_ADD_SUBDIRECTORY ) returns FALSE and Open.HasRestoreAccess is FALSE

            if (gfileTypeToOpen == FileType.DirectoryFile &&
                gOpenGrantedAccess == FileAccess.FILE_ADD_FILE &&
                !isOpenHasRestoreAccess)
            {
                Helper.CaptureRequirement(424, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                   If FileTypeToOpen is DirectoryFile and Open.GrantedAccess.FILE_ADD_SUBDIRECTORY is not set and 
                   AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor, FILE_ADD_SUBDIRECTORY ) 
                   returns FALSE and Open.HasRestoreAccess is FALSE, the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return(MessageStatus.ACCESS_DENIED);
            }

            if (streamTypeNameToOPen == StreamTypeNameToOpen.DATA ||
                streamTypeNameToOPen == StreamTypeNameToOpen.NULL)
            {
                gStreamType = StreamType.DataStream;
            }
            else
            {
                gStreamType = StreamType.DirectoryStream;
            }

            gFileAttribute = desiredFileAttribute;
            Helper.CaptureRequirement(475, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                The object store MUST return:CreateAction set to FILE_CREATED.");
            gCreateAction = CreateAction.CREATED;

            #endregion

            Helper.CaptureRequirement(474, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                The object store MUST return :Status set to STATUS_SUCCESS.");
            return(MessageStatus.SUCCESS);
        }
コード例 #19
0
 internal static MessageStatus WorkaroundOpenExistingFile(ShareAccess shareAccess, FileAccess desiredAccess,
                                                          bool streamFound, bool isSymbolicLink, FileType openFileType, FileNameStatus fileNameStatus,
                                                          CreateOptions existingOpenModeCreateOption, ShareAccess existOpenShareModeShareAccess,
                                                          FileAccess existOpenDesiredAccess, CreateOptions createOption, CreateDisposition createDisposition,
                                                          StreamTypeNameToOPen streamTypeNameToOPen, FileAttribute fileAttribute,
                                                          FileAttribute desiredFileAttribute, MessageStatus returnedStatus, ITestSite site)
 {
     if (shareAccess == ShareAccess.FILE_SHARE_READ && desiredAccess == FileAccess.FILE_ADD_SUBDIRECTORY &&
         !streamFound && !isSymbolicLink && openFileType == FileType.DataFile && fileNameStatus == FileNameStatus.Normal &&
         existingOpenModeCreateOption == CreateOptions.NON_DIRECTORY_FILE && existOpenShareModeShareAccess == ShareAccess.FILE_SHARE_READ &&
         existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY && createOption == CreateOptions.NO_INTERMEDIATE_BUFFERING &&
         createDisposition == CreateDisposition.OPEN_IF && streamTypeNameToOPen == StreamTypeNameToOPen.NULL &&
         fileAttribute == FileAttribute.NORMAL && desiredFileAttribute == FileAttribute.NORMAL)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(376, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == (CreateOptions.SYNCHRONOUS_IO_NONALERT | CreateOptions.SYNCHRONOUS_IO_ALERT))
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(373, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == CreateOptions.SYNCHRONOUS_IO_ALERT &&
              desiredAccess == FileAccess.FILE_READ_DATA)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(369, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == CreateOptions.SYNCHRONOUS_IO_NONALERT &&
              desiredAccess == FileAccess.FILE_READ_DATA)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(2373, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == CreateOptions.DELETE_ON_CLOSE &&
              (desiredAccess == FileAccess.ACCESS_SYSTEM_SECURITY))
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(371, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (createOption == (CreateOptions.COMPLETE_IF_OPLOCKED | CreateOptions.RESERVE_OPFILTER))
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(375, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (streamFound && !isSymbolicLink && openFileType == FileType.DataFile &&
              existingOpenModeCreateOption == CreateOptions.DIRECTORY_FILE &&
              existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY &&
              createOption == CreateOptions.DIRECTORY_FILE)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(375, MessageStatus.ACCESS_VIOLATION, returnedStatus, site);
     }
     else if (!streamFound && !isSymbolicLink && openFileType == FileType.DataFile &&
              existingOpenModeCreateOption == CreateOptions.NON_DIRECTORY_FILE &&
              existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY &&
              createOption == CreateOptions.NON_DIRECTORY_FILE &&
              fileAttribute == FileAttribute.READONLY)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(375, MessageStatus.ACCESS_DENIED, returnedStatus, site);
     }
     return(returnedStatus);
 }
コード例 #20
0
        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
        {
            IntPtr fileHandle;
            string nativePath = ToNativePath(path);

            // NtQueryDirectoryFile will return STATUS_PENDING if the directory handle was not opened with SYNCHRONIZE and FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT.
            // Our usage of NtNotifyChangeDirectoryFile assumes the directory handle is opened with SYNCHRONIZE and FILE_SYNCHRONOUS_IO_ALERT (or FILE_SYNCHRONOUS_IO_NONALERT starting from Windows Vista).
            // Note: Sometimes a directory will be opened without specifying FILE_DIRECTORY_FILE.
            desiredAccess |= AccessMask.SYNCHRONIZE;
            createOptions &= ~CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT;
            createOptions |= CreateOptions.FILE_SYNCHRONOUS_IO_ALERT;

            if ((createOptions & CreateOptions.FILE_NO_INTERMEDIATE_BUFFERING) > 0 &&
                ((FileAccessMask)desiredAccess & FileAccessMask.FILE_APPEND_DATA) > 0)
            {
                // FILE_NO_INTERMEDIATE_BUFFERING is incompatible with FILE_APPEND_DATA
                // [MS-SMB2] 3.3.5.9 suggests setting FILE_APPEND_DATA to zero in this case.
                desiredAccess = (AccessMask)((uint)desiredAccess & (uint)~FileAccessMask.FILE_APPEND_DATA);
            }

            NTStatus status = CreateFile(out fileHandle, out fileStatus, nativePath, desiredAccess, 0, fileAttributes, shareAccess, createDisposition, createOptions);

            handle = fileHandle;
            return(status);
        }
コード例 #21
0
 private static extern IntPtr OpenColorProfile(
     [MarshalAs(UnmanagedType.LPStruct)] ProfileFilename profile,
     uint desiredAccess,
     FileShare shareMode,
     CreateDisposition creationMode);
コード例 #22
0
 private static extern NTStatus NtCreateFile(out IntPtr handle, uint desiredAccess, ref OBJECT_ATTRIBUTES objectAttributes, out IO_STATUS_BLOCK ioStatusBlock, ref long allocationSize, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, IntPtr eaBuffer, uint eaLength);
コード例 #23
0
ファイル: DbgHelp.cs プロジェクト: SunburstApps/RosDbg
 public extern static IntPtr CreateFile(string FileName, DesiredAccess da, ShareMode sm, IntPtr SecurityAttributesZero, CreateDisposition cd, FlagsAndAttributes fa, IntPtr TemplateFileZero);
 internal static MessageStatus WorkaroundOpenExistingFile(ShareAccess shareAccess, FileAccess desiredAccess,
                                                          bool streamFound, bool isSymbolicLink, FileType openFileType, FileNameStatus fileNameStatus,
                                                          CreateOptions existingOpenModeCreateOption, ShareAccess existOpenShareModeShareAccess,
                                                          FileAccess existOpenDesiredAccess, CreateOptions createOption, CreateDisposition createDisposition,
                                                          StreamTypeNameToOPen streamTypeNameToOPen, FileAttribute fileAttribute,
                                                          FileAttribute desiredFileAttribute, MessageStatus returnedStatus, ITestSite site)
 {
     // SMB1 server return ACCESS_DENIED instead of INVALID_PARAMETER when "CreateOptions.DELETE_ON_CLOS && !DesiredAccess.DELETE"
     if (createOption == CreateOptions.DELETE_ON_CLOSE &&
         desiredAccess != FileAccess.DELETE)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(371, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (desiredAccess == FileAccess.None || desiredAccess == FileAccess.INVALID_ACCESS_MASK)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(377, MessageStatus.ACCESS_DENIED, returnedStatus, site);
     }
     else if (createOption == CreateOptions.NO_INTERMEDIATE_BUFFERING &&
              (desiredAccess == FileAccess.FILE_APPEND_DATA || desiredAccess == FileAccess.FILE_ADD_SUBDIRECTORY))
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(376, MessageStatus.INVALID_PARAMETER, returnedStatus, site);
     }
     else if (streamFound && !isSymbolicLink && openFileType == FileType.DataFile &&
              existingOpenModeCreateOption == CreateOptions.DIRECTORY_FILE &&
              existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY &&
              createOption == CreateOptions.DIRECTORY_FILE)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(375, MessageStatus.ACCESS_VIOLATION, returnedStatus, site);
     }
     else if (!streamFound && !isSymbolicLink && openFileType == FileType.DataFile &&
              existingOpenModeCreateOption == CreateOptions.NON_DIRECTORY_FILE &&
              existOpenDesiredAccess == FileAccess.FILE_LIST_DIRECTORY &&
              createOption == CreateOptions.NON_DIRECTORY_FILE &&
              fileAttribute == FileAttribute.READONLY)
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(375, MessageStatus.ACCESS_DENIED, returnedStatus, site);
     }
     return(returnedStatus);
 }
コード例 #25
0
        public static MessageStatus CreateFile(
            FileAttribute desiredFileAttribute,
            CreateOptions createOption,
            StreamTypeNameToOPen streamTypeNameToOPen,
            FileAccess desiredAccess,
            ShareAccess shareAccess,
            CreateDisposition createDisposition,
            StreamFoundType streamFoundType,
            SymbolicLinkType symbolicLinkType,
            FileType openFileType,
            FileNameStatus fileNameStatus
            )
        {
            MessageStatus status = OpenFileinitial(
            desiredAccess,
            shareAccess,
            createOption,
            createDisposition,
            desiredFileAttribute,
            streamFoundType,
            symbolicLinkType,
            streamTypeNameToOPen,
            openFileType,
            fileNameStatus);

            if (status != MessageStatus.SUCCESS)
            {
                return status;
            }

            #region Pseudocode for the operation

            //If FileTypeToOpen is DirectoryFile and DesiredFileAttributes.FILE_ATTRIBUTE_TEMPORARY is set
            if (gfileTypeToOpen == FileType.DirectoryFile &&
                desiredFileAttribute == FileAttribute.TEMPORARY)
            {
                Helper.CaptureRequirement(418, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If FileTypeToOpen is DirectoryFile and DesiredFileAttributes.FILE_ATTRIBUTE_TEMPORARY is set, the operation MUST be failed with STATUS_INVALID_PARAMETER.");
                return MessageStatus.INVALID_PARAMETER;
            }

            //If DesiredFileAttributes.FILE_ATTRIBUTE_READONLY and CreateOptions.FILE_DELETE_ON_CLOSE
            //are both set
            if (desiredFileAttribute == FileAttribute.READONLY &&
                createOption == CreateOptions.DELETE_ON_CLOSE)
            {
                Helper.CaptureRequirement(419, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If DesiredFileAttributes.FILE_ATTRIBUTE_READONLY and CreateOptions.FILE_DELETE_ON_CLOSE are both set, the operation MUST be failed with STATUS_CANNOT_DELETE.");
                return MessageStatus.CANNOT_DELETE;
            }

            //If StreamTypeNameToOpen is non-empty and has a value other than "$DATA" or
            //"$INDEX_ALLOCATION", the operation MUST be failed with STATUS_ACCESS_DENIED.
            if (streamTypeNameToOPen == StreamTypeNameToOPen.Other)
            {
                Helper.CaptureRequirement(420, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If StreamTypeNameToOpen is non-empty and has a value other than \""$DATA"",the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return MessageStatus.OBJECT_NAME_INVALID;
            }

            //If Open.RemainingDesiredAccess.ACCESS_SYSTEM_SECURITY is set and
            //Open.GrantedAccess.ACCESS_SYSTEM_SECURITY is not set and
            //SecurityContext.PrivilegeSet does not contain "SeSecurityPrivilege"
            //3 indicate SeBackupPrivilege and SeRestorePrivilege
            if (gOpenRemainingDesiredAccess == FileAccess.ACCESS_SYSTEM_SECURITY &&
                gOpenGrantedAccess == FileAccess.FILE_APPEND_DATA &&
                gSecurityContext.privilegeSet == (PrivilegeSet.SeBackupPrivilege | PrivilegeSet.SeRestorePrivilege))
            {
                Helper.CaptureRequirement(422, @"[In Creation of a New File,Pseudocode for the operation is as follows:]If Open.RemainingDesiredAccess.ACCESS_SYSTEM_SECURITY is set and Open.GrantedAccess.ACCESS_SYSTEM_SECURITY is not set and SecurityContext.PrivilegeSet does not contain \""SeSecurityPrivilege"", the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return MessageStatus.ACCESS_DENIED;
            }

            //If FileTypeToOpen is DataFile and Open.GrantedAccess.FILE_ADD_FILE is not set
            //and AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor,
            //FILE_ADD_FILE ) returns FALSE and Open.HasRestoreAccess is FALSE

            if (gfileTypeToOpen == FileType.DataFile &&
                gOpenGrantedAccess == FileAccess.FILE_ADD_SUBDIRECTORY &&
                !isOpenHasRestoreAccess)
            {
                Helper.CaptureRequirement(423, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                    If FileTypeToOpen is DataFile and Open.GrantedAccess.FILE_ADD_FILE is not set and
                    AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor, FILE_ADD_FILE )
                    returns FALSE and Open.HasRestoreAccess is FALSE, the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return MessageStatus.ACCESS_DENIED;
            }

            //If FileTypeToOpen is DirectoryFile and Open.GrantedAccess.FILE_ADD_SUBDIRECTORY
            //is not set and AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor,
            //FILE_ADD_SUBDIRECTORY ) returns FALSE and Open.HasRestoreAccess is FALSE

            if (gfileTypeToOpen == FileType.DirectoryFile &&
                gOpenGrantedAccess == FileAccess.FILE_ADD_FILE &&
                !isOpenHasRestoreAccess)
            {
                Helper.CaptureRequirement(424, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                   If FileTypeToOpen is DirectoryFile and Open.GrantedAccess.FILE_ADD_SUBDIRECTORY is not set and
                   AccessCheck( SecurityContext, Open.Link.ParentFile.SecurityDescriptor, FILE_ADD_SUBDIRECTORY )
                   returns FALSE and Open.HasRestoreAccess is FALSE, the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return MessageStatus.ACCESS_DENIED;
            }

            if (streamTypeNameToOPen == StreamTypeNameToOPen.DATA ||
                streamTypeNameToOPen == StreamTypeNameToOPen.NULL)
            {
                gStreamType = StreamType.DataStream;
            }
            else
            {
                gStreamType = StreamType.DirectoryStream;
            }

            gFileAttribute = desiredFileAttribute;
            Helper.CaptureRequirement(475, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                The object store MUST return:CreateAction set to FILE_CREATED.");
            gCreateAction = CreateAction.CREATED;

            #endregion

            Helper.CaptureRequirement(474, @"[In Creation of a New File,Pseudocode for the operation is as follows:]
                The object store MUST return :Status set to STATUS_SUCCESS.");
            return MessageStatus.SUCCESS;
        }
コード例 #26
0
ファイル: AssemblyCache.cs プロジェクト: lulzzz/appstract
 internal static extern void CreateAssemblyNameObject(out IAssemblyName ppAssemblyNameObj, string szAssemblyName,
                                                      CreateDisposition dwFlags, IntPtr pvReserved);
コード例 #27
0
 public static extern IntPtr CreateFile(string FileName, DesiredAccess da, ShareMode sm, IntPtr SecurityAttributesZero, CreateDisposition cd, FlagsAndAttributes fa, IntPtr TemplateFileZero);
コード例 #28
0
        internal void Delete(string path, ISMBCredential credential)
        {
            if (!path.IsSharePath())
            {
                base.Delete(path);
                return;
            }

            if (!path.TryResolveHostnameFromPath(out var ipAddress))
            {
                throw new SMBException($"Failed to Delete {path}", new ArgumentException($"Unable to resolve \"{path.Hostname()}\""));
            }

            if (!Exists(path))
            {
                return;
            }

            NTStatus status = NTStatus.STATUS_SUCCESS;

            if (credential == null)
            {
                credential = _credentialProvider.GetSMBCredential(path);
            }

            if (credential == null)
            {
                throw new SMBException($"Failed to Delete {path}", new InvalidCredentialException($"Unable to find credential in SMBCredentialProvider for path: {path}"));
            }

            if (EnumerateFileSystemEntries(path).Count() > 0)
            {
                throw new SMBException($"Failed to Delete {path}", new IOException("Cannot delete directory. Directory is not empty."));
            }

            ISMBFileStore fileStore = null;
            object        handle    = null;

            try
            {
                var shareName    = path.ShareName();
                var relativePath = path.RelativeSharePath();

                _logger?.LogTrace($"Trying to Delete {{RelativePath: {relativePath}}} for {{ShareName: {shareName}}}");

                using (var connection = SMBConnection.CreateSMBConnection(_smbClientFactory, ipAddress, transport, credential, _maxBufferSize))
                {
                    fileStore = connection.SMBClient.TreeConnect(shareName, out status);

                    status.HandleStatus();

                    AccessMask        accessMask    = AccessMask.SYNCHRONIZE | AccessMask.DELETE;
                    ShareAccess       shareAccess   = ShareAccess.Delete;
                    CreateDisposition disposition   = CreateDisposition.FILE_OPEN;
                    CreateOptions     createOptions = CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DELETE_ON_CLOSE;

                    var stopwatch = new Stopwatch();

                    stopwatch.Start();
                    do
                    {
                        if (status == NTStatus.STATUS_PENDING)
                        {
                            _logger.LogTrace($"STATUS_PENDING while trying to delete directory {path}. {stopwatch.Elapsed.TotalSeconds}/{_smbFileSystemSettings.ClientSessionTimeout} seconds elapsed.");
                        }

                        status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, accessMask, 0, shareAccess,
                                                      disposition, createOptions, null);
                    }while (status == NTStatus.STATUS_PENDING && stopwatch.Elapsed.TotalSeconds <= _smbFileSystemSettings.ClientSessionTimeout);
                    stopwatch.Stop();

                    status.HandleStatus();

                    // This is the correct delete command, but it doesn't work for some reason. You have to use FILE_DELETE_ON_CLOSE
                    // fileStore.SetFileInformation(handle, new FileDispositionInformation());

                    FileStoreUtilities.CloseFile(fileStore, ref handle);
                }
            }
            catch (Exception ex)
            {
                throw new SMBException($"Failed to Delete {path}", ex);
            }
            finally
            {
                FileStoreUtilities.CloseFile(fileStore, ref handle);
            }
        }