internal static Transaction2QueryPathInformationResponse GetSubcommandResponse(SMBHeader header, Transaction2QueryPathInformationRequest subcommand, FileSystemShare share)
        {
            IFileSystem     fileSystem = share.FileSystem;
            string          path       = subcommand.FileName;
            FileSystemEntry entry      = fileSystem.GetEntry(path);

            if (entry == null)
            {
                // Windows Server 2003 will return STATUS_OBJECT_NAME_NOT_FOUND
                // Returning STATUS_NO_SUCH_FILE caused an issue when executing ImageX.exe from WinPE 3.0 (32-bit)
                header.Status = NTStatus.STATUS_OBJECT_NAME_NOT_FOUND;
                return(null);
            }
            Transaction2QueryPathInformationResponse response = new Transaction2QueryPathInformationResponse();

            response.QueryInfo = InfoHelper.FromFileSystemEntry(entry, subcommand.InformationLevel);

            return(response);
        }
Пример #2
0
        internal static SMBCommand GetQueryInformationResponse(SMBHeader header, QueryInformationRequest request, FileSystemShare share)
        {
            IFileSystem     fileSystem = share.FileSystem;
            FileSystemEntry entry      = fileSystem.GetEntry(request.FileName);

            if (entry == null)
            {
                header.Status = NTStatus.STATUS_OBJECT_PATH_INVALID;
                return(new ErrorResponse(CommandName.SMB_COM_QUERY_INFORMATION));
            }

            QueryInformationResponse response = new QueryInformationResponse();

            response.FileAttributes = InfoHelper.GetFileAttributes(entry);
            response.LastWriteTime  = entry.LastWriteTime;
            response.FileSize       = (uint)Math.Min(UInt32.MaxValue, entry.Size);

            return(response);
        }
        internal static Transaction2QueryFileInformationResponse GetSubcommandResponse(SMBHeader header, Transaction2QueryFileInformationRequest subcommand, FileSystemShare share, StateObject state)
        {
            IFileSystem fileSystem     = share.FileSystem;
            string      openedFilePath = state.GetOpenedFilePath(subcommand.FID);

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

            FileSystemEntry entry = fileSystem.GetEntry(openedFilePath);

            if (entry == null)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                return(null);
            }
            Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse();

            response.QueryInfo = InfoHelper.FromFileSystemEntry(entry, subcommand.InformationLevel);

            return(response);
        }
Пример #4
0
        private static NTCreateAndXResponse CreateResponseFromFileSystemEntry(FileSystemEntry entry, ushort fileID)
        {
            NTCreateAndXResponse response = new NTCreateAndXResponse();

            if (entry.IsDirectory)
            {
                response.ExtFileAttributes = ExtendedFileAttributes.Directory;
                response.Directory         = true;
            }
            else
            {
                response.ExtFileAttributes = ExtendedFileAttributes.Normal;
            }
            response.FID = fileID;
            response.CreateDisposition = CreateDisposition.FILE_OPEN;
            response.AllocationSize    = InfoHelper.GetAllocationSize(entry.Size);
            response.EndOfFile         = entry.Size;
            response.CreateTime        = entry.CreationTime;
            response.LastAccessTime    = entry.LastAccessTime;
            response.LastWriteTime     = entry.LastWriteTime;
            response.LastChangeTime    = entry.LastWriteTime;
            response.ResourceType      = ResourceType.FileTypeDisk;
            return(response);
        }
        internal static Transaction2FindFirst2Response GetSubcommandResponse(SMBHeader header, Transaction2FindFirst2Request subcommand, FileSystemShare share, StateObject state)
        {
            IFileSystem fileSystem = share.FileSystem;
            Transaction2FindFirst2Response response = new Transaction2FindFirst2Response();
            string path = subcommand.FileName;
            // '\Directory' - Get the directory info
            // '\Directory\*' - List the directory files
            // '\Directory\s*' - List the directory files starting with s (cmd.exe will use this syntax when entering 's' and hitting tab for autocomplete)
            // '\Directory\<.inf' (Update driver will use this syntax)
            // '\Directory\exefile"*' (cmd.exe will use this syntax when entering an exe without its extension, explorer will use this opening a directory from the run menu)
            bool   isDirectoryEnumeration = false;
            string searchPattern          = String.Empty;

            if (path.Contains("*") || path.Contains("<"))
            {
                isDirectoryEnumeration = true;
                int separatorIndex = path.LastIndexOf('\\');
                searchPattern = path.Substring(separatorIndex + 1);
                path          = path.Substring(0, separatorIndex + 1);
            }
            bool exactNameWithoutExtension = searchPattern.Contains("\"");

            FileSystemEntry entry = fileSystem.GetEntry(path);

            if (entry == null)
            {
                header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                return(null);
            }

            List <FileSystemEntry> entries;

            if (isDirectoryEnumeration)
            {
                try
                {
                    entries = fileSystem.ListEntriesInDirectory(path);
                }
                catch (UnauthorizedAccessException)
                {
                    header.Status = NTStatus.STATUS_ACCESS_DENIED;
                    return(null);
                }

                if (searchPattern != String.Empty)
                {
                    entries = GetFiltered(entries, searchPattern);
                }

                if (!exactNameWithoutExtension)
                {
                    if (IncludeParentDirectoryInResults)
                    {
                        entries.Insert(0, fileSystem.GetEntry(FileSystem.GetParentDirectory(path)));
                        entries[0].Name = "..";
                    }
                    if (IncludeCurrentDirectoryInResults)
                    {
                        entries.Insert(0, fileSystem.GetEntry(path));
                        entries[0].Name = ".";
                    }
                }

                // If no matching entries are found, the server SHOULD fail the request with STATUS_NO_SUCH_FILE.
                if (entries.Count == 0)
                {
                    header.Status = NTStatus.STATUS_NO_SUCH_FILE;
                    return(null);
                }
            }
            else
            {
                entries = new List <FileSystemEntry>();
                entries.Add(entry);
            }

            bool returnResumeKeys = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0;
            int  entriesToReturn  = Math.Min(subcommand.SearchCount, entries.Count);

            // We ignore SearchAttributes
            for (int index = 0; index < entriesToReturn; 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;

            response.EndOfSearch = (returnCount == entries.Count) && (entries.Count <= subcommand.SearchCount);
            response.SID         = state.AllocateSearchHandle();
            entries.RemoveRange(0, returnCount);
            state.OpenSearches.Add(response.SID, entries);
            return(response);
        }