internal static Transaction2FindNext2Response GetSubcommandResponse(SMBHeader header, Transaction2FindNext2Request subcommand, FileSystemShare share, StateObject state)
        {
            Transaction2FindNext2Response response = new Transaction2FindNext2Response();

            if (!state.OpenSearches.ContainsKey(subcommand.SID))
            {
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            bool returnResumeKeys          = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0;
            List <FileSystemEntry> entries = state.OpenSearches[subcommand.SID];

            for (int index = 0; index < entries.Count; index++)
            {
                FindInformationEntry infoEntry = InfoHelper.FromFileSystemEntry(entries[index], subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys);
                response.FindInfoList.Add(infoEntry);
                if (response.FindInfoList.GetLength(header.UnicodeFlag) > state.GetMaxDataCount(header.PID))
                {
                    response.FindInfoList.RemoveAt(response.FindInfoList.Count - 1);
                    break;
                }
            }
            int returnCount = response.FindInfoList.Count;

            entries.RemoveRange(0, returnCount);
            state.OpenSearches[subcommand.SID] = entries;
            response.SearchCount = (ushort)returnCount;
            response.EndOfSearch = (returnCount == entries.Count) && (entries.Count <= subcommand.SearchCount);
            return(response);
        }
예제 #2
0
        internal static Transaction2FindNext2Response GetSubcommandResponse(SMB1Header header, uint maxDataCount, Transaction2FindNext2Request subcommand, ISMBShare share, SMB1ConnectionState state)
        {
            SMB1Session session    = state.GetSession(header.UID);
            OpenSearch  openSearch = session.GetOpenSearch(subcommand.SID);

            if (openSearch == null)
            {
                state.LogToServer(Severity.Verbose, "FindNext2 failed. Invalid SID.");
                header.Status = NTStatus.STATUS_INVALID_HANDLE;
                return(null);
            }

            bool returnResumeKeys = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0;
            int  maxLength        = (int)maxDataCount;
            int  maxCount         = Math.Min(openSearch.Entries.Count - openSearch.EnumerationLocation, subcommand.SearchCount);
            List <QueryDirectoryFileInformation> segment = openSearch.Entries.GetRange(openSearch.EnumerationLocation, maxCount);
            FindInformationList findInformationList;

            try
            {
                findInformationList = FindInformationHelper.ToFindInformationList(segment, header.UnicodeFlag, maxLength);
            }
            catch (UnsupportedInformationLevelException)
            {
                state.LogToServer(Severity.Verbose, "FindNext2: Unsupported information level: {0}.", subcommand.InformationLevel);
                header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL;
                return(null);
            }
            int returnCount = findInformationList.Count;
            Transaction2FindNext2Response response = new Transaction2FindNext2Response();

            response.SetFindInformationList(findInformationList, header.UnicodeFlag);
            openSearch.EnumerationLocation += returnCount;
            response.EndOfSearch            = (openSearch.EnumerationLocation == openSearch.Entries.Count);
            if (response.EndOfSearch)
            {
                session.RemoveOpenSearch(subcommand.SID);
            }
            return(response);
        }
예제 #3
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);
        }
예제 #4
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();
        }