示例#1
0
        internal static TransactionTransactNamedPipeResponse GetSubcommandResponse(SMBHeader header, TransactionTransactNamedPipeRequest subcommand, NamedPipeShare share, StateObject state)
        {
            string openedFilePath = state.GetOpenedFilePath(subcommand.FID);

            if (openedFilePath == null)
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            TransactionTransactNamedPipeResponse response = new TransactionTransactNamedPipeResponse();
            RemoteService service = share.GetService(openedFilePath);

            if (service != null)
            {
                RPCPDU rpcRequest = RPCPDU.GetPDU(subcommand.WriteData);
                RPCPDU rpcReply   = RemoteServiceHelper.GetRPCReply(rpcRequest, service);
                response.ReadData = rpcReply.GetBytes();
                return(response);
            }

            // This code should not execute unless the request sequence is invalid
            header.Status = NTStatus.STATUS_INVALID_SMB;
            return(null);
        }
示例#2
0
        public override void Write(byte[] buffer, int offset, int count)
        {
            int lengthOfPDUs = 0;

            do
            {
                RPCPDU rpcRequest = RPCPDU.GetPDU(buffer, offset);
                lengthOfPDUs += rpcRequest.FragmentLength;
                RPCPDU rpcReply  = RemoteServiceHelper.GetRPCReply(rpcRequest, m_service);
                byte[] replyData = rpcReply.GetBytes();
                Append(replyData);
            }while (lengthOfPDUs < count);
        }
示例#3
0
        public static uint PerformWrite(SMBHeader header, object share, ushort FID, ulong offset, byte[] data, StateObject state)
        {
            OpenedFileObject openedFile = state.GetOpenedFileObject(FID);

            if (openedFile == null)
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(0);
            }
            string openedFilePath = openedFile.Path;

            if (share is NamedPipeShare)
            {
                RemoteService service = ((NamedPipeShare)share).GetService(openedFilePath);
                if (service != null)
                {
                    RPCPDU rpcRequest = RPCPDU.GetPDU(data);
                    RPCPDU rpcReply   = RemoteServiceHelper.GetRPCReply(rpcRequest, service);
                    byte[] replyData  = rpcReply.GetBytes();
                    state.StoreNamedPipeReply(FID, replyData);
                    return((uint)data.Length);
                }

                // This code should not execute unless the SMB request (sequence) is invalid
                header.Status = NTStatus.STATUS_INVALID_SMB;
                return(0);
            }
            else // FileSystemShare
            {
                FileSystemShare fileSystemShare = (FileSystemShare)share;
                IFileSystem     fileSystem      = fileSystemShare.FileSystem;

                if (openedFile.IsSequentialAccess && openedFile.Cache.Length > 0)
                {
                    openedFile.Cache = new byte[0]; // Empty cache
                }

                try
                {
                    Stream stream = fileSystem.OpenFile(openedFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    stream.Seek((long)offset, SeekOrigin.Begin);
                    stream.Write(data, 0, data.Length);
                    stream.Close();
                    return((uint)data.Length);
                }
                catch (IOException ex)
                {
                    ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
                    if (errorCode == (ushort)Win32Error.ERROR_DISK_FULL)
                    {
                        header.Status = NTStatus.STATUS_DISK_FULL;
                        return(0);
                    }
                    else if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
                    {
                        // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid
                        header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                        return(0);
                    }
                    else
                    {
                        header.Status = NTStatus.STATUS_DATA_ERROR;
                        return(0);
                    }
                }
                catch (ArgumentOutOfRangeException)
                {
                    header.Status = NTStatus.STATUS_DATA_ERROR;
                    return(0);
                }
                catch (UnauthorizedAccessException)
                {
                    // The user may have tried to write to a readonly file
                    header.Status = NTStatus.STATUS_ACCESS_DENIED;
                    return(0);
                }
            }
        }