diff --git a/SMBLibrary/Enums/NTStatus.cs b/SMBLibrary/Enums/NTStatus.cs index 447bc94..9c956b5 100644 --- a/SMBLibrary/Enums/NTStatus.cs +++ b/SMBLibrary/Enums/NTStatus.cs @@ -31,11 +31,12 @@ namespace SMBLibrary STATUS_CANNOT_DELETE = 0xC0000121, STATUS_USER_SESSION_DELETED = 0xC0000203, STATUS_INSUFF_SERVER_RESOURCES = 0xC0000205, - - STATUS_INVALID_SMB = 0x00010002, // CIFS/SMB1: A corrupt or invalid SMB request was received - STATUS_SMB_BAD_COMMAND = 0x00160002, // CIFS/SMB1: An unknown SMB command code was received by the server - STATUS_SMB_BAD_FID = 0x00060001, // CIFS/SMB1 - STATUS_SMB_BAD_TID = 0x00050002, // CIFS/SMB1 - STATUS_OS2_NO_MORE_SIDS = 0x00710001, // CIFS/SMB1 + + STATUS_INVALID_SMB = 0x00010002, // SMB1/CIFS: A corrupt or invalid SMB request was received + STATUS_SMB_BAD_COMMAND = 0x00160002, // SMB1/CIFS: An unknown SMB command code was received by the server + STATUS_SMB_BAD_FID = 0x00060001, // SMB1/CIFS + STATUS_SMB_BAD_TID = 0x00050002, // SMB1/CIFS + STATUS_OS2_NO_MORE_SIDS = 0x00710001, // SMB1/CIFS + STATUS_OS2_INVALID_LEVEL = 0x007C0001, // SMB1/CIFS } } diff --git a/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.Query.cs b/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.Query.cs index 788005a..9c8f9d0 100644 --- a/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.Query.cs +++ b/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.Query.cs @@ -14,114 +14,128 @@ namespace SMBLibrary.Server.SMB1 { public partial class SMB1FileSystemHelper { - public static QueryInformation GetFileInformation(FileSystemEntry entry, bool deletePending, QueryInformationLevel informationLevel) + public static NTStatus GetFileInformation(out QueryInformation result, FileSystemEntry entry, bool deletePending, QueryInformationLevel informationLevel) { switch (informationLevel) { case QueryInformationLevel.SMB_INFO_STANDARD: { - QueryInfoStandard result = new QueryInfoStandard(); - result.CreationDateTime = entry.CreationTime; - result.LastAccessDateTime = entry.LastAccessTime; - result.LastWriteDateTime = entry.LastWriteTime; - result.FileDataSize = (uint)Math.Min(entry.Size, UInt32.MaxValue); - result.AllocationSize = (uint)Math.Min(NTFileSystemHelper.GetAllocationSize(entry.Size), UInt32.MaxValue); - return result; + QueryInfoStandard information = new QueryInfoStandard(); + information.CreationDateTime = entry.CreationTime; + information.LastAccessDateTime = entry.LastAccessTime; + information.LastWriteDateTime = entry.LastWriteTime; + information.FileDataSize = (uint)Math.Min(entry.Size, UInt32.MaxValue); + information.AllocationSize = (uint)Math.Min(NTFileSystemHelper.GetAllocationSize(entry.Size), UInt32.MaxValue); + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_INFO_QUERY_EA_SIZE: { - QueryEASize result = new QueryEASize(); - result.CreationDateTime = entry.CreationTime; - result.LastAccessDateTime = entry.LastAccessTime; - result.LastWriteDateTime = entry.LastWriteTime; - result.FileDataSize = (uint)Math.Min(entry.Size, UInt32.MaxValue); - result.AllocationSize = (uint)Math.Min(NTFileSystemHelper.GetAllocationSize(entry.Size), UInt32.MaxValue); - result.Attributes = GetFileAttributes(entry); - result.EASize = 0; - return result; + QueryEASize information = new QueryEASize(); + information.CreationDateTime = entry.CreationTime; + information.LastAccessDateTime = entry.LastAccessTime; + information.LastWriteDateTime = entry.LastWriteTime; + information.FileDataSize = (uint)Math.Min(entry.Size, UInt32.MaxValue); + information.AllocationSize = (uint)Math.Min(NTFileSystemHelper.GetAllocationSize(entry.Size), UInt32.MaxValue); + information.Attributes = GetFileAttributes(entry); + information.EASize = 0; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST: { - throw new NotImplementedException(); + result = null; + return NTStatus.STATUS_NOT_IMPLEMENTED; } case QueryInformationLevel.SMB_INFO_QUERY_ALL_EAS: { - throw new NotImplementedException(); + result = null; + return NTStatus.STATUS_NOT_IMPLEMENTED; } case QueryInformationLevel.SMB_INFO_IS_NAME_VALID: { - throw new NotImplementedException(); + result = null; + return NTStatus.STATUS_NOT_IMPLEMENTED; } case QueryInformationLevel.SMB_QUERY_FILE_BASIC_INFO: { - QueryFileBasicInfo result = new QueryFileBasicInfo(); - result.CreationDateTime = entry.CreationTime; - result.LastAccessDateTime = entry.LastAccessTime; - result.LastWriteDateTime = entry.LastWriteTime; - result.LastChangeTime = entry.LastWriteTime; - result.ExtFileAttributes = GetExtendedFileAttributes(entry); - return result; + QueryFileBasicInfo information = new QueryFileBasicInfo(); + information.CreationDateTime = entry.CreationTime; + information.LastAccessDateTime = entry.LastAccessTime; + information.LastWriteDateTime = entry.LastWriteTime; + information.LastChangeTime = entry.LastWriteTime; + information.ExtFileAttributes = GetExtendedFileAttributes(entry); + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_QUERY_FILE_STANDARD_INFO: { - QueryFileStandardInfo result = new QueryFileStandardInfo(); - result.AllocationSize = NTFileSystemHelper.GetAllocationSize(entry.Size); - result.EndOfFile = entry.Size; - result.DeletePending = deletePending; - result.Directory = entry.IsDirectory; - return result; + QueryFileStandardInfo information = new QueryFileStandardInfo(); + information.AllocationSize = NTFileSystemHelper.GetAllocationSize(entry.Size); + information.EndOfFile = entry.Size; + information.DeletePending = deletePending; + information.Directory = entry.IsDirectory; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_QUERY_FILE_EA_INFO: { - QueryFileExtendedAttributeInfo result = new QueryFileExtendedAttributeInfo(); - result.EASize = 0; - return result; + QueryFileExtendedAttributeInfo information = new QueryFileExtendedAttributeInfo(); + information.EASize = 0; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_QUERY_FILE_NAME_INFO: { - QueryFileNameInfo result = new QueryFileNameInfo(); - result.FileName = entry.Name; - return result; + QueryFileNameInfo information = new QueryFileNameInfo(); + information.FileName = entry.Name; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO: { - QueryFileAllInfo result = new QueryFileAllInfo(); - result.CreationDateTime = entry.CreationTime; - result.LastAccessDateTime = entry.LastAccessTime; - result.LastWriteDateTime = entry.LastWriteTime; - result.ExtFileAttributes = GetExtendedFileAttributes(entry); - result.LastChangeTime = entry.LastWriteTime; - result.AllocationSize = NTFileSystemHelper.GetAllocationSize(entry.Size); - result.EndOfFile = entry.Size; - result.DeletePending = deletePending; - result.Directory = entry.IsDirectory; - result.EASize = 0; - result.FileName = entry.Name; - return result; + QueryFileAllInfo information = new QueryFileAllInfo(); + information.CreationDateTime = entry.CreationTime; + information.LastAccessDateTime = entry.LastAccessTime; + information.LastWriteDateTime = entry.LastWriteTime; + information.ExtFileAttributes = GetExtendedFileAttributes(entry); + information.LastChangeTime = entry.LastWriteTime; + information.AllocationSize = NTFileSystemHelper.GetAllocationSize(entry.Size); + information.EndOfFile = entry.Size; + information.DeletePending = deletePending; + information.Directory = entry.IsDirectory; + information.EASize = 0; + information.FileName = entry.Name; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_QUERY_FILE_ALT_NAME_INFO: { - QueryFileAltNameInfo result = new QueryFileAltNameInfo(); - result.FileName = NTFileSystemHelper.GetShortName(entry.Name); - return result; + QueryFileAltNameInfo information = new QueryFileAltNameInfo(); + information.FileName = NTFileSystemHelper.GetShortName(entry.Name); + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_QUERY_FILE_STREAM_INFO: { - QueryFileStreamInfo result = new QueryFileStreamInfo(); - result.StreamSize = entry.Size; - result.StreamAllocationSize = NTFileSystemHelper.GetAllocationSize(entry.Size); - result.StreamName = "::$DATA"; - return result; + QueryFileStreamInfo information = new QueryFileStreamInfo(); + information.StreamSize = entry.Size; + information.StreamAllocationSize = NTFileSystemHelper.GetAllocationSize(entry.Size); + information.StreamName = "::$DATA"; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryInformationLevel.SMB_QUERY_FILE_COMPRESSION_INFO: { - QueryFileCompressionInfo result = new QueryFileCompressionInfo(); - result.CompressionFormat = CompressionFormat.COMPRESSION_FORMAT_NONE; - return result; + QueryFileCompressionInfo information = new QueryFileCompressionInfo(); + information.CompressionFormat = CompressionFormat.COMPRESSION_FORMAT_NONE; + result = information; + return NTStatus.STATUS_SUCCESS; } default: { - throw new UnsupportedInformationLevelException(); + result = null; + return NTStatus.STATUS_OS2_INVALID_LEVEL; } } } diff --git a/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.QueryFileSystem.cs b/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.QueryFileSystem.cs index 12ef9dc..483014b 100644 --- a/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.QueryFileSystem.cs +++ b/SMBLibrary/Server/SMB1/SMB1FileSystemHelper.QueryFileSystem.cs @@ -14,60 +14,67 @@ namespace SMBLibrary.Server.SMB1 { public partial class SMB1FileSystemHelper { - public static QueryFSInformation GetFileSystemInformation(QueryFSInformationLevel informationLevel, IFileSystem fileSystem) + public static NTStatus GetFileSystemInformation(out QueryFSInformation result, QueryFSInformationLevel informationLevel, IFileSystem fileSystem) { switch (informationLevel) { case QueryFSInformationLevel.SMB_INFO_ALLOCATION: { - QueryFSInfoAllocation result = new QueryFSInfoAllocation(); - result.FileSystemID = 0; - result.SectorUnit = NTFileSystemHelper.ClusterSize / NTFileSystemHelper.BytesPerSector; - result.UnitsTotal = (uint)Math.Min(fileSystem.Size / NTFileSystemHelper.ClusterSize, UInt32.MaxValue); - result.UnitsAvailable = (uint)Math.Min(fileSystem.FreeSpace / NTFileSystemHelper.ClusterSize, UInt32.MaxValue); - result.Sector = NTFileSystemHelper.BytesPerSector; - return result; + QueryFSInfoAllocation information = new QueryFSInfoAllocation(); + information.FileSystemID = 0; + information.SectorUnit = NTFileSystemHelper.ClusterSize / NTFileSystemHelper.BytesPerSector; + information.UnitsTotal = (uint)Math.Min(fileSystem.Size / NTFileSystemHelper.ClusterSize, UInt32.MaxValue); + information.UnitsAvailable = (uint)Math.Min(fileSystem.FreeSpace / NTFileSystemHelper.ClusterSize, UInt32.MaxValue); + information.Sector = NTFileSystemHelper.BytesPerSector; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryFSInformationLevel.SMB_INFO_VOLUME: { - QueryFSInfoVolume result = new QueryFSInfoVolume(); - result.VolumeLabel = String.Empty; - result.VolumeSerialNumber = 0; - return result; + QueryFSInfoVolume information = new QueryFSInfoVolume(); + information.VolumeLabel = String.Empty; + information.VolumeSerialNumber = 0; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryFSInformationLevel.SMB_QUERY_FS_VOLUME_INFO: { - QueryFSVolumeInfo result = new QueryFSVolumeInfo(); - result.VolumeCreationTime = DateTime.Now; - return result; + QueryFSVolumeInfo information = new QueryFSVolumeInfo(); + information.VolumeCreationTime = DateTime.Now; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryFSInformationLevel.SMB_QUERY_FS_SIZE_INFO: { - QueryFSSizeInfo result = new QueryFSSizeInfo(); - result.TotalAllocationUnits = (ulong)(fileSystem.Size / NTFileSystemHelper.ClusterSize); - result.TotalFreeAllocationUnits = (ulong)(fileSystem.FreeSpace / NTFileSystemHelper.ClusterSize); - result.BytesPerSector = NTFileSystemHelper.BytesPerSector; - result.SectorsPerAllocationUnit = NTFileSystemHelper.ClusterSize / NTFileSystemHelper.BytesPerSector; - return result; + QueryFSSizeInfo information = new QueryFSSizeInfo(); + information.TotalAllocationUnits = (ulong)(fileSystem.Size / NTFileSystemHelper.ClusterSize); + information.TotalFreeAllocationUnits = (ulong)(fileSystem.FreeSpace / NTFileSystemHelper.ClusterSize); + information.BytesPerSector = NTFileSystemHelper.BytesPerSector; + information.SectorsPerAllocationUnit = NTFileSystemHelper.ClusterSize / NTFileSystemHelper.BytesPerSector; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryFSInformationLevel.SMB_QUERY_FS_DEVICE_INFO: { - QueryFSDeviceInfo result = new QueryFSDeviceInfo(); - result.DeviceCharacteristics = DeviceCharacteristics.IsMounted; - result.DeviceType = DeviceType.Disk; - return result; + QueryFSDeviceInfo information = new QueryFSDeviceInfo(); + information.DeviceCharacteristics = DeviceCharacteristics.IsMounted; + information.DeviceType = DeviceType.Disk; + result = information; + return NTStatus.STATUS_SUCCESS; } case QueryFSInformationLevel.SMB_QUERY_FS_ATTRIBUTE_INFO: { - QueryFSAttibuteInfo result = new QueryFSAttibuteInfo(); - result.FileSystemAttributes = FileSystemAttributes.UnicodeOnDisk; - result.MaxFileNameLengthInBytes = 255; - result.FileSystemName = fileSystem.Name; - return result; + QueryFSAttibuteInfo information = new QueryFSAttibuteInfo(); + information.FileSystemAttributes = FileSystemAttributes.UnicodeOnDisk; + information.MaxFileNameLengthInBytes = 255; + information.FileSystemName = fileSystem.Name; + result = information; + return NTStatus.STATUS_SUCCESS; } default: { - throw new UnsupportedInformationLevelException(); + result = null; + return NTStatus.STATUS_OS2_INVALID_LEVEL; } } } diff --git a/SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs b/SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs index 59434c7..b455cc3 100644 --- a/SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs +++ b/SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs @@ -43,7 +43,16 @@ namespace SMBLibrary.Server.SMB1 int entriesToReturn = Math.Min(subcommand.SearchCount, entries.Count); List temp = entries.GetRange(0, entriesToReturn); int maxLength = (int)state.GetMaxDataCount(header.PID).Value; - FindInformationList findInformationList = SMB1FileSystemHelper.GetFindInformationList(temp, subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys, maxLength); + FindInformationList findInformationList; + try + { + findInformationList = SMB1FileSystemHelper.GetFindInformationList(temp, subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys, maxLength); + } + catch (UnsupportedInformationLevelException) + { + header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; + return null; + } int returnCount = findInformationList.Count; Transaction2FindFirst2Response response = new Transaction2FindFirst2Response(); response.SetFindInformationList(findInformationList, header.UnicodeFlag); @@ -83,7 +92,16 @@ namespace SMBLibrary.Server.SMB1 int maxLength = (int)state.GetMaxDataCount(header.PID).Value; int maxCount = Math.Min(openSearch.Entries.Count - openSearch.EnumerationLocation, subcommand.SearchCount); List temp = openSearch.Entries.GetRange(openSearch.EnumerationLocation, maxCount); - FindInformationList findInformationList = SMB1FileSystemHelper.GetFindInformationList(temp, subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys, maxLength); + FindInformationList findInformationList; + try + { + findInformationList = SMB1FileSystemHelper.GetFindInformationList(temp, subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys, maxLength); + } + catch (UnsupportedInformationLevelException) + { + header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; + return null; + } int returnCount = findInformationList.Count; Transaction2FindNext2Response response = new Transaction2FindNext2Response(); response.SetFindInformationList(findInformationList, header.UnicodeFlag); @@ -99,7 +117,13 @@ namespace SMBLibrary.Server.SMB1 internal static Transaction2QueryFSInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryFSInformationRequest subcommand, FileSystemShare share) { Transaction2QueryFSInformationResponse response = new Transaction2QueryFSInformationResponse(); - QueryFSInformation queryFSInformation = SMB1FileSystemHelper.GetFileSystemInformation(subcommand.InformationLevel, share.FileSystem); + QueryFSInformation queryFSInformation; + NTStatus queryStatus = SMB1FileSystemHelper.GetFileSystemInformation(out queryFSInformation, subcommand.InformationLevel, share.FileSystem); + if (queryStatus != NTStatus.STATUS_SUCCESS) + { + header.Status = queryStatus; + return null; + } response.SetQueryFSInformation(queryFSInformation, header.UnicodeFlag); return response; } @@ -118,9 +142,14 @@ namespace SMBLibrary.Server.SMB1 return null; } Transaction2QueryPathInformationResponse response = new Transaction2QueryPathInformationResponse(); - QueryInformation queryInformation = SMB1FileSystemHelper.GetFileInformation(entry, false, subcommand.InformationLevel); + QueryInformation queryInformation; + NTStatus queryStatus = SMB1FileSystemHelper.GetFileInformation(out queryInformation, entry, false, subcommand.InformationLevel); + if (queryStatus != NTStatus.STATUS_SUCCESS) + { + header.Status = queryStatus; + return null; + } response.SetQueryInformation(queryInformation); - return response; } @@ -142,9 +171,14 @@ namespace SMBLibrary.Server.SMB1 return null; } Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse(); - QueryInformation queryInformation = SMB1FileSystemHelper.GetFileInformation(entry, openFile.DeleteOnClose, subcommand.InformationLevel); + QueryInformation queryInformation; + NTStatus queryStatus = SMB1FileSystemHelper.GetFileInformation(out queryInformation, entry, openFile.DeleteOnClose, subcommand.InformationLevel); + if (queryStatus != NTStatus.STATUS_SUCCESS) + { + header.Status = queryStatus; + return null; + } response.SetQueryInformation(queryInformation); - return response; }