예제 #1
0
        public NTStatus GetFileSystemInformation(out QueryFSInformation result, QueryFSInformationLevel informationLevel)
        {
            result = null;
            int maxOutputLength = 4096;
            Transaction2QueryFSInformationRequest subcommand = new Transaction2QueryFSInformationRequest();

            subcommand.QueryFSInformationLevel = informationLevel;

            Transaction2Request request = new Transaction2Request();

            request.Setup               = subcommand.GetSetup();
            request.TransParameters     = subcommand.GetParameters(m_client.Unicode);
            request.TransData           = subcommand.GetData(m_client.Unicode);
            request.TotalDataCount      = (ushort)request.TransData.Length;
            request.TotalParameterCount = (ushort)request.TransParameters.Length;
            request.MaxParameterCount   = Transaction2QueryFSInformationResponse.ParametersLength;
            request.MaxDataCount        = (ushort)maxOutputLength;

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

            if (reply != null)
            {
                if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is Transaction2Response)
                {
                    Transaction2Response response = (Transaction2Response)reply.Commands[0];
                    Transaction2QueryFSInformationResponse subcommandResponse = new Transaction2QueryFSInformationResponse(response.TransParameters, response.TransData, reply.Header.UnicodeFlag);
                    result = subcommandResponse.GetQueryFSInformation(informationLevel, reply.Header.UnicodeFlag);
                }
                return(reply.Header.Status);
            }
            return(NTStatus.STATUS_INVALID_SMB);
        }
예제 #2
0
        public void GetFileSystemInformation(out QueryFSInformation result, QueryFSInformationLevel informationLevel)
        {
            int maxOutputLength = 4096;
            Transaction2QueryFSInformationRequest subcommand = new Transaction2QueryFSInformationRequest
            {
                QueryFSInformationLevel = informationLevel
            };

            Transaction2Request request = new Transaction2Request
            {
                Setup           = subcommand.GetSetup(),
                TransParameters = subcommand.GetParameters(m_client.Unicode),
                TransData       = subcommand.GetData(m_client.Unicode)
            };

            request.TotalDataCount      = (ushort)request.TransData.Length;
            request.TotalParameterCount = (ushort)request.TransParameters.Length;
            request.MaxParameterCount   = Transaction2QueryFSInformationResponse.ParametersLength;
            request.MaxDataCount        = (ushort)maxOutputLength;

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

            if (reply.Header.Status != NTStatus.STATUS_SUCCESS || !(reply.Commands[0] is Transaction2Response))
            {
                throw new NtStatusException(reply.Header.Status);
            }

            Transaction2Response response = (Transaction2Response)reply.Commands[0];
            Transaction2QueryFSInformationResponse subcommandResponse = new Transaction2QueryFSInformationResponse(response.TransData);

            result = subcommandResponse.GetQueryFSInformation(informationLevel);
        }
예제 #3
0
        internal static void PrepareResponse(TransactionResponse response, byte[] responseSetup, byte[] responseParameters, byte[] responseData, int maxBufferSize, List <SMBCommand> sendQueue)
        {
            int responseSize = TransactionResponse.CalculateMessageSize(responseSetup.Length, responseParameters.Length, responseData.Length);

            if (responseSize <= maxBufferSize)
            {
                response.Setup = responseSetup;
                response.TotalParameterCount = (ushort)responseParameters.Length;
                response.TotalDataCount      = (ushort)responseData.Length;
                response.TransParameters     = responseParameters;
                response.TransData           = responseData;
            }
            else
            {
                int    currentDataLength = maxBufferSize - (responseSize - responseData.Length);
                byte[] buffer            = new byte[currentDataLength];
                Array.Copy(responseData, 0, buffer, 0, currentDataLength);
                response.Setup = responseSetup;
                response.TotalParameterCount = (ushort)responseParameters.Length;
                response.TotalDataCount      = (ushort)responseData.Length;
                response.TransParameters     = responseParameters;
                response.TransData           = buffer;

                int dataBytesLeftToSend = responseData.Length - currentDataLength;
                while (dataBytesLeftToSend > 0)
                {
                    TransactionResponse additionalResponse;
                    if (response is Transaction2Response)
                    {
                        additionalResponse = new Transaction2Response();
                    }
                    else
                    {
                        additionalResponse = new TransactionResponse();
                    }
                    currentDataLength = dataBytesLeftToSend;
                    responseSize      = TransactionResponse.CalculateMessageSize(0, 0, dataBytesLeftToSend);
                    if (responseSize > maxBufferSize)
                    {
                        currentDataLength = maxBufferSize - (responseSize - dataBytesLeftToSend);
                    }
                    buffer = new byte[currentDataLength];
                    int dataBytesSent = responseData.Length - dataBytesLeftToSend;
                    Array.Copy(responseData, dataBytesSent, buffer, 0, currentDataLength);
                    additionalResponse.TotalParameterCount   = (ushort)responseParameters.Length;
                    additionalResponse.TotalDataCount        = (ushort)responseData.Length;
                    additionalResponse.TransData             = buffer;
                    additionalResponse.ParameterDisplacement = (ushort)response.TransParameters.Length;
                    additionalResponse.DataDisplacement      = (ushort)dataBytesSent;
                    sendQueue.Add(additionalResponse);

                    dataBytesLeftToSend -= currentDataLength;
                }
            }
        }
예제 #4
0
        public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
        {
            result = null;
            if (m_client.InfoLevelPassthrough)
            {
                int maxOutputLength = 4096;
                Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest();
                subcommand.FID = (ushort)handle;
                subcommand.FileInformationClass = informationClass;

                Transaction2Request request = new Transaction2Request();
                request.Setup               = subcommand.GetSetup();
                request.TransParameters     = subcommand.GetParameters(m_client.Unicode);
                request.TransData           = subcommand.GetData(m_client.Unicode);
                request.TotalDataCount      = (ushort)request.TransData.Length;
                request.TotalParameterCount = (ushort)request.TransParameters.Length;
                request.MaxParameterCount   = Transaction2QueryFileInformationResponse.ParametersLength;
                request.MaxDataCount        = (ushort)maxOutputLength;

                TrySendMessage(request);
                SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2);
                if (reply != null)
                {
                    if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is Transaction2Response)
                    {
                        Transaction2Response response = (Transaction2Response)reply.Commands[0];
                        Transaction2QueryFileInformationResponse subcommandResponse = new Transaction2QueryFileInformationResponse(response.TransParameters, response.TransData, reply.Header.UnicodeFlag);
                        if (informationClass == FileInformationClass.FileAllInformation)
                        {
                            // Windows implementations return SMB_QUERY_FILE_ALL_INFO when a client specifies native NT passthrough level "FileAllInformation".
                            QueryInformation queryFileAllInfo = subcommandResponse.GetQueryInformation(QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO);
                            result = QueryInformationHelper.ToFileInformation(queryFileAllInfo);
                        }
                        else
                        {
                            result = subcommandResponse.GetFileInformation(informationClass);
                        }
                    }
                    return(reply.Header.Status);
                }
                return(NTStatus.STATUS_INVALID_SMB);
            }
            else
            {
                QueryInformationLevel informationLevel = QueryInformationHelper.ToFileInformationLevel(informationClass);
                QueryInformation      queryInformation;
                NTStatus status = GetFileInformation(out queryInformation, handle, informationLevel);
                if (status == NTStatus.STATUS_SUCCESS)
                {
                    result = QueryInformationHelper.ToFileInformation(queryInformation);
                }
                return(status);
            }
        }
예제 #5
0
        public void GetFileInformation(out QueryInformation result, NtHandle handle, QueryInformationLevel informationLevel)
        {
            int maxOutputLength = 4096;
            Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest
            {
                FID = ((Smb1Handle)handle).FID,
                QueryInformationLevel = informationLevel
            };

            Transaction2Request request = new Transaction2Request
            {
                Setup           = subcommand.GetSetup(),
                TransParameters = subcommand.GetParameters(m_client.Unicode),
                TransData       = subcommand.GetData(m_client.Unicode)
            };

            request.TotalDataCount      = (ushort)request.TransData.Length;
            request.TotalParameterCount = (ushort)request.TransParameters.Length;
            request.MaxParameterCount   = Transaction2QueryFileInformationResponse.ParametersLength;
            request.MaxDataCount        = (ushort)maxOutputLength;

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

            reply.IsSuccessElseThrow();
            if (!(reply.Commands[0] is Transaction2Response))
            {
                throw new NtStatusException(reply.Header.Status);
            }

            Transaction2Response response = (Transaction2Response)reply.Commands[0];
            Transaction2QueryFileInformationResponse subcommandResponse = new Transaction2QueryFileInformationResponse(response.TransParameters, response.TransData);

            result = subcommandResponse.GetQueryInformation(informationLevel);
            reply.IsSuccessElseThrow();
        }
예제 #6
0
        internal static SMBCommand GetCompleteTransaction2Response(SMBHeader header, byte[] requestSetup, byte[] requestParameters, byte[] requestData, object share, StateObject state, List <SMBCommand> sendQueue)
        {
            Transaction2Subcommand subcommand         = Transaction2Subcommand.GetSubcommandRequest(requestSetup, requestParameters, requestData, header.UnicodeFlag);
            Transaction2Subcommand subcommandResponse = null;

            if (!(share is FileSystemShare))
            {
                header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                return(new ErrorResponse(CommandName.SMB_COM_TRANSACTION2));
            }

            FileSystemShare fileSystemShare = (FileSystemShare)share;

            if (subcommand is Transaction2FindFirst2Request)
            {
                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2FindFirst2Request)subcommand, fileSystemShare, state);
            }
            else if (subcommand is Transaction2FindNext2Request)
            {
                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2FindNext2Request)subcommand, fileSystemShare, state);
            }
            else if (subcommand is Transaction2QueryFSInformationRequest)
            {
                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2QueryFSInformationRequest)subcommand, fileSystemShare);
            }
            else if (subcommand is Transaction2QueryPathInformationRequest)
            {
                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2QueryPathInformationRequest)subcommand, fileSystemShare);
            }
            else if (subcommand is Transaction2SetPathInformationRequest)
            {
                header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            }
            else if (subcommand is Transaction2QueryFileInformationRequest)
            {
                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2QueryFileInformationRequest)subcommand, fileSystemShare, state);
            }
            else if (subcommand is Transaction2SetFileInformationRequest)
            {
                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2SetFileInformationRequest)subcommand, fileSystemShare, state);
            }
            else if (subcommand is Transaction2CreateDirectoryRequest)
            {
                header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
            }
            else if (subcommand is Transaction2GetDfsReferralRequest)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_DEVICE;
            }
            else
            {
                header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
            }

            if (header.Status != NTStatus.STATUS_SUCCESS)
            {
                return(new ErrorResponse(CommandName.SMB_COM_TRANSACTION2));
            }

            byte[] responseSetup          = subcommandResponse.GetSetup();
            byte[] responseParameters     = subcommandResponse.GetParameters(header.UnicodeFlag);
            byte[] responseData           = subcommandResponse.GetData(header.UnicodeFlag);
            Transaction2Response response = new Transaction2Response();

            PrepareResponse(response, responseSetup, responseParameters, responseData, state.MaxBufferSize, sendQueue);
            return(response);
        }
예제 #7
0
        public NTStatus QueryDirectory(out List <FindInformation> result, string fileName, FindInformationLevel informationLevel)
        {
            result = null;
            int maxOutputLength = 4096;
            Transaction2FindFirst2Request subcommand = new Transaction2FindFirst2Request();

            subcommand.SearchAttributes = SMBFileAttributes.Hidden | SMBFileAttributes.System | SMBFileAttributes.Directory;
            subcommand.SearchCount      = UInt16.MaxValue;
            subcommand.Flags            = FindFlags.SMB_FIND_CLOSE_AT_EOS;
            subcommand.InformationLevel = informationLevel;
            subcommand.FileName         = fileName;

            Transaction2Request request = new Transaction2Request();

            request.Setup               = subcommand.GetSetup();
            request.TransParameters     = subcommand.GetParameters(m_client.Unicode);
            request.TransData           = subcommand.GetData(m_client.Unicode);
            request.TotalDataCount      = (ushort)request.TransData.Length;
            request.TotalParameterCount = (ushort)request.TransParameters.Length;
            request.MaxParameterCount   = Transaction2FindFirst2Response.ParametersLength;
            request.MaxDataCount        = (ushort)maxOutputLength;

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

            if (reply != null)
            {
                if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is Transaction2Response)
                {
                    result = new List <FindInformation>();
                    Transaction2Response           response            = (Transaction2Response)reply.Commands[0];
                    Transaction2FindFirst2Response subcommandResponse  = new Transaction2FindFirst2Response(response.TransParameters, response.TransData, reply.Header.UnicodeFlag);
                    FindInformationList            findInformationList = subcommandResponse.GetFindInformationList(subcommand.InformationLevel, reply.Header.UnicodeFlag);
                    result.AddRange(findInformationList);
                    bool endOfSearch = subcommandResponse.EndOfSearch;
                    while (!endOfSearch)
                    {
                        Transaction2FindNext2Request nextSubcommand = new Transaction2FindNext2Request();
                        nextSubcommand.SID              = subcommandResponse.SID;
                        nextSubcommand.SearchCount      = UInt16.MaxValue;
                        nextSubcommand.Flags            = FindFlags.SMB_FIND_CLOSE_AT_EOS | FindFlags.SMB_FIND_CONTINUE_FROM_LAST;
                        nextSubcommand.InformationLevel = informationLevel;
                        nextSubcommand.FileName         = fileName;

                        request                     = new Transaction2Request();
                        request.Setup               = nextSubcommand.GetSetup();
                        request.TransParameters     = nextSubcommand.GetParameters(m_client.Unicode);
                        request.TransData           = nextSubcommand.GetData(m_client.Unicode);
                        request.TotalDataCount      = (ushort)request.TransData.Length;
                        request.TotalParameterCount = (ushort)request.TransParameters.Length;
                        request.MaxParameterCount   = Transaction2FindNext2Response.ParametersLength;
                        request.MaxDataCount        = (ushort)maxOutputLength;

                        TrySendMessage(request);
                        reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2);
                        if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is Transaction2Response)
                        {
                            response = (Transaction2Response)reply.Commands[0];
                            Transaction2FindNext2Response nextSubcommandResponse = new Transaction2FindNext2Response(response.TransParameters, response.TransData, reply.Header.UnicodeFlag);
                            findInformationList = nextSubcommandResponse.GetFindInformationList(subcommand.InformationLevel, reply.Header.UnicodeFlag);
                            result.AddRange(findInformationList);
                            endOfSearch = nextSubcommandResponse.EndOfSearch;
                        }
                        else
                        {
                            endOfSearch = true;
                        }
                    }
                }
                return(reply.Header.Status);
            }
            return(NTStatus.STATUS_INVALID_SMB);
        }
예제 #8
0
        public void QueryDirectory(out List <FindInformation>?result, string fileName, FindInformationLevel informationLevel)
        {
            result = null;
            int maxOutputLength = 4096;
            Transaction2FindFirst2Request subCommand = new Transaction2FindFirst2Request
            {
                SearchAttributes = SMBFileAttributes.Hidden | SMBFileAttributes.System | SMBFileAttributes.Directory,
                SearchCount      = ushort.MaxValue,
                Flags            = FindFlags.SMB_FIND_CLOSE_AT_EOS,
                InformationLevel = informationLevel,
                FileName         = fileName
            };

            Transaction2Request request = new Transaction2Request
            {
                Setup           = subCommand.GetSetup(),
                TransParameters = subCommand.GetParameters(m_client.Unicode),
                TransData       = subCommand.GetData(m_client.Unicode)
            };

            request.TotalDataCount      = (ushort)request.TransData.Length;
            request.TotalParameterCount = (ushort)request.TransParameters.Length;
            request.MaxParameterCount   = Transaction2FindFirst2Response.ParametersLength;
            request.MaxDataCount        = (ushort)maxOutputLength;

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

            reply.IsSuccessElseThrow();
            if (!(reply.Commands[0] is Transaction2Response))
            {
                throw new NtStatusException(reply.Header.Status);
            }

            result = new List <FindInformation>();
            Transaction2Response           response            = (Transaction2Response)reply.Commands[0];
            Transaction2FindFirst2Response subcommandResponse  = new Transaction2FindFirst2Response(response.TransParameters, response.TransData);
            FindInformationList            findInformationList = subcommandResponse.GetFindInformationList(subCommand.InformationLevel, reply.Header.UnicodeFlag);

            result.AddRange(findInformationList);
            bool endOfSearch = subcommandResponse.EndOfSearch;

            while (!endOfSearch)
            {
                Transaction2FindNext2Request nextSubCommand = new Transaction2FindNext2Request
                {
                    SID              = subcommandResponse.SID,
                    SearchCount      = ushort.MaxValue,
                    Flags            = FindFlags.SMB_FIND_CLOSE_AT_EOS | FindFlags.SMB_FIND_CONTINUE_FROM_LAST,
                    InformationLevel = informationLevel,
                    FileName         = fileName
                };

                request = new Transaction2Request
                {
                    Setup           = nextSubCommand.GetSetup(),
                    TransParameters = nextSubCommand.GetParameters(m_client.Unicode),
                    TransData       = nextSubCommand.GetData(m_client.Unicode)
                };
                request.TotalDataCount      = (ushort)request.TransData.Length;
                request.TotalParameterCount = (ushort)request.TransParameters.Length;
                request.MaxParameterCount   = Transaction2FindNext2Response.ParametersLength;
                request.MaxDataCount        = (ushort)maxOutputLength;

                TrySendMessage(request);
                reply = m_client.WaitForMessage(CommandName.SMB_COM_TRANSACTION2);
                if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is Transaction2Response transaction2Response)
                {
                    Transaction2FindNext2Response nextSubCommandResponse = new Transaction2FindNext2Response(transaction2Response.TransParameters, transaction2Response.TransData);
                    findInformationList = nextSubCommandResponse.GetFindInformationList(subCommand.InformationLevel, reply.Header.UnicodeFlag);
                    result.AddRange(findInformationList);
                    endOfSearch = nextSubCommandResponse.EndOfSearch;
                }
                else
                {
                    endOfSearch = true;
                }
            }
            reply.IsSuccessElseThrow();
        }