diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryResponse.cs index 64b9663..9393acb 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryResponse.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryResponse.cs @@ -24,7 +24,7 @@ namespace SMBLibrary.SMB1 } - public Transaction2CreateDirectoryResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base() + public Transaction2CreateDirectoryResponse(byte[] parameters, byte[] data, bool isUnicode) : base() { EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); } diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Request.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Request.cs index ac7c968..51de456 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Request.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Request.cs @@ -24,7 +24,7 @@ namespace SMBLibrary.SMB1 public SearchStorageType SearchStorageType; public string FileName; // SMB_STRING // Data: - FullExtendedAttributeList GetExtendedAttributeList; // Used with FindInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST + public FullExtendedAttributeList GetExtendedAttributeList; // Used with FindInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST public Transaction2FindFirst2Request() : base() { diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Response.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Response.cs index beb315b..8d475ac 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Response.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Response.cs @@ -19,19 +19,18 @@ namespace SMBLibrary.SMB1 public const int ParametersLength = 10; // Parameters: public ushort SID; // Search handle - public ushort SearchCount; + private ushort SearchCount; public bool EndOfSearch; public ushort EaErrorOffset; public ushort LastNameOffset; // Data: - public FindInformationList FindInfoList; + private byte[] FindInformationListBytes = new byte[0]; public Transaction2FindFirst2Response() : base() { - FindInfoList = new FindInformationList(); } - public Transaction2FindFirst2Response(byte[] parameters, byte[] data, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys) : base() + public Transaction2FindFirst2Response(byte[] parameters, byte[] data, bool isUnicode) : base() { SID = LittleEndianConverter.ToUInt16(parameters, 0); SearchCount = LittleEndianConverter.ToUInt16(parameters, 2); @@ -39,13 +38,11 @@ namespace SMBLibrary.SMB1 EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 6); LastNameOffset = LittleEndianConverter.ToUInt16(parameters, 8); - FindInfoList = new FindInformationList(data, informationLevel, isUnicode, returnResumeKeys); + FindInformationListBytes = data; } public override byte[] GetParameters(bool isUnicode) { - SearchCount = (ushort)FindInfoList.Count; - byte[] parameters = new byte[ParametersLength]; LittleEndianWriter.WriteUInt16(parameters, 0, SID); LittleEndianWriter.WriteUInt16(parameters, 2, SearchCount); @@ -57,7 +54,18 @@ namespace SMBLibrary.SMB1 public override byte[] GetData(bool isUnicode) { - return FindInfoList.GetBytes(isUnicode); + return FindInformationListBytes; + } + + public FindInformationList GetFindInformationList(FindInformationLevel findInformationLevel, bool isUnicode, bool returnResumeKeys) + { + return new FindInformationList(FindInformationListBytes, findInformationLevel, isUnicode, returnResumeKeys); + } + + public void SetFindInformationList(FindInformationList findInformationList, bool isUnicode) + { + SearchCount = (ushort)findInformationList.Count; + FindInformationListBytes = findInformationList.GetBytes(isUnicode); } public override Transaction2SubcommandName SubcommandName diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Response.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Response.cs index 944f2cc..fb97740 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Response.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Response.cs @@ -18,26 +18,25 @@ namespace SMBLibrary.SMB1 { public const int ParametersLength = 8; // Parameters: - public ushort SearchCount; + private ushort SearchCount; public bool EndOfSearch; public ushort EaErrorOffset; public ushort LastNameOffset; // Data: - public FindInformationList FindInfoList; + private byte[] FindInformationListBytes = new byte[0]; public Transaction2FindNext2Response() : base() { - FindInfoList = new FindInformationList(); } - public Transaction2FindNext2Response(byte[] parameters, byte[] data, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys) : base() + public Transaction2FindNext2Response(byte[] parameters, byte[] data, bool isUnicode) : base() { SearchCount = LittleEndianConverter.ToUInt16(parameters, 0); EndOfSearch = LittleEndianConverter.ToUInt16(parameters, 2) != 0; EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 4); LastNameOffset = LittleEndianConverter.ToUInt16(parameters, 6); - FindInfoList = new FindInformationList(data, informationLevel, isUnicode, returnResumeKeys); + FindInformationListBytes = data; } public override byte[] GetParameters(bool isUnicode) @@ -52,7 +51,18 @@ namespace SMBLibrary.SMB1 public override byte[] GetData(bool isUnicode) { - return FindInfoList.GetBytes(isUnicode); + return FindInformationListBytes; + } + + public FindInformationList GetFindInformationList(FindInformationLevel findInformationLevel, bool isUnicode, bool returnResumeKeys) + { + return new FindInformationList(FindInformationListBytes, findInformationLevel, isUnicode, returnResumeKeys); + } + + public void SetFindInformationList(FindInformationList findInformationList, bool isUnicode) + { + SearchCount = (ushort)findInformationList.Count; + FindInformationListBytes = findInformationList.GetBytes(isUnicode); } public override Transaction2SubcommandName SubcommandName diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationResponse.cs index 0d328fa..669af44 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationResponse.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationResponse.cs @@ -17,21 +17,31 @@ namespace SMBLibrary.SMB1 public class Transaction2QueryFSInformationResponse : Transaction2Subcommand { // Data: - public QueryFSInformation QueryFSInfo; + private byte[] QueryFSInformationBytes; public Transaction2QueryFSInformationResponse() : base() { } - public Transaction2QueryFSInformationResponse(byte[] parameters, byte[] data, QueryFSInformationLevel informationLevel, bool isUnicode) : base() + public Transaction2QueryFSInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() { - QueryFSInfo = QueryFSInformation.GetQueryFSInformation(data, informationLevel, isUnicode); + QueryFSInformationBytes = data; } public override byte[] GetData(bool isUnicode) { - return QueryFSInfo.GetBytes(isUnicode); + return QueryFSInformationBytes; + } + + public QueryFSInformation GetQueryFSInformation(QueryFSInformationLevel informationLevel, bool isUnicode) + { + return QueryFSInformation.GetQueryFSInformation(QueryFSInformationBytes, informationLevel, isUnicode); + } + + public void SetQueryFSInformation(QueryFSInformation queryFSInformation, bool isUnicode) + { + QueryFSInformationBytes = queryFSInformation.GetBytes(isUnicode); } public override Transaction2SubcommandName SubcommandName diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationResponse.cs index de4c8e2..255bc2f 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationResponse.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationResponse.cs @@ -17,46 +17,39 @@ namespace SMBLibrary.SMB1 public class Transaction2QueryFileInformationResponse : Transaction2Subcommand { // Parameters: - public ushort EaErrorOffset; + public ushort EaErrorOffset; // Meaningful only when request's InformationLevel is SMB_INFO_QUERY_EAS_FROM_LIST // Data: - public QueryInformation QueryInfo; + private byte[] QueryInformationBytes = new byte[0]; public Transaction2QueryFileInformationResponse() : base() { } - public Transaction2QueryFileInformationResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base() + public Transaction2QueryFileInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() { - if ((ushort)informationLevel > 0x0100) - { - EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); - } - QueryInfo = QueryInformation.GetQueryInformation(data, informationLevel); + EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); + QueryInformationBytes = data; } public override byte[] GetParameters(bool isUnicode) { - if ((ushort)QueryInfo.InformationLevel > 0x0100) - { - byte[] parameters = new byte[2]; - LittleEndianWriter.WriteUInt16(parameters, 0, EaErrorOffset); - return parameters; - } - return new byte[0]; + return LittleEndianConverter.GetBytes(EaErrorOffset); } public override byte[] GetData(bool isUnicode) { - if (QueryInfo == null) - { - // SMB_INFO_IS_NAME_VALID - return new byte[0]; - } - else - { - return QueryInfo.GetBytes(); - } + return QueryInformationBytes; + } + + public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel) + { + return QueryInformation.GetQueryInformation(QueryInformationBytes, queryInformationLevel); + } + + public void SetQueryInformation(QueryInformation queryInformation) + { + QueryInformationBytes = queryInformation.GetBytes(); } public override Transaction2SubcommandName SubcommandName diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationResponse.cs index cdda7cc..bd217c7 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationResponse.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationResponse.cs @@ -17,46 +17,39 @@ namespace SMBLibrary.SMB1 public class Transaction2QueryPathInformationResponse : Transaction2Subcommand { // Parameters: - public ushort EaErrorOffset; + public ushort EaErrorOffset; // Meaningful only when request's InformationLevel is SMB_INFO_QUERY_EAS_FROM_LIST // Data: - public QueryInformation QueryInfo; + private byte[] QueryInformationBytes; public Transaction2QueryPathInformationResponse() : base() { } - public Transaction2QueryPathInformationResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base() + public Transaction2QueryPathInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() { - if ((ushort)informationLevel > 0x0100) - { - EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); - } - QueryInfo = QueryInformation.GetQueryInformation(data, informationLevel); + EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); + QueryInformationBytes = data; } public override byte[] GetParameters(bool isUnicode) { - if ((ushort)QueryInfo.InformationLevel > 0x0100) - { - byte[] parameters = new byte[2]; - LittleEndianWriter.WriteUInt16(parameters, 0, EaErrorOffset); - return parameters; - } - return new byte[0]; + return LittleEndianConverter.GetBytes(EaErrorOffset); } public override byte[] GetData(bool isUnicode) { - if (QueryInfo == null) - { - // SMB_INFO_IS_NAME_VALID - return new byte[0]; - } - else - { - return QueryInfo.GetBytes(); - } + return QueryInformationBytes; + } + + public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel) + { + return QueryInformation.GetQueryInformation(QueryInformationBytes, queryInformationLevel); + } + + public void SetQueryInformation(QueryInformation queryInformation) + { + QueryInformationBytes = queryInformation.GetBytes(); } public override Transaction2SubcommandName SubcommandName diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationResponse.cs index 312bfc4..69db39b 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationResponse.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationResponse.cs @@ -17,14 +17,14 @@ namespace SMBLibrary.SMB1 public class Transaction2SetFileInformationResponse : Transaction2Subcommand { // Parameters: - public ushort EaErrorOffset; + public ushort EaErrorOffset; // Meaningful only when the request's InformationLevel is set to SMB_INFO_SET_EAS public Transaction2SetFileInformationResponse() : base() { } - public Transaction2SetFileInformationResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base() + public Transaction2SetFileInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() { EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); } diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationResponse.cs index 3ea5e46..f502aeb 100644 --- a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationResponse.cs +++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationResponse.cs @@ -17,14 +17,14 @@ namespace SMBLibrary.SMB1 public class Transaction2SetPathInformationResponse : Transaction2Subcommand { // Parameters: - public ushort EaErrorOffset; + public ushort EaErrorOffset; // Meaningful only when the request's InformationLevel is set to SMB_INFO_SET_EAS public Transaction2SetPathInformationResponse() : base() { } - public Transaction2SetPathInformationResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base() + public Transaction2SetPathInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() { EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); } diff --git a/SMBLibrary/Server/ResponseHelpers/Transaction2SubcommandHelper.cs b/SMBLibrary/Server/ResponseHelpers/Transaction2SubcommandHelper.cs index 4ae28cb..4a11b07 100644 --- a/SMBLibrary/Server/ResponseHelpers/Transaction2SubcommandHelper.cs +++ b/SMBLibrary/Server/ResponseHelpers/Transaction2SubcommandHelper.cs @@ -101,18 +101,20 @@ namespace SMBLibrary.Server bool returnResumeKeys = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0; int entriesToReturn = Math.Min(subcommand.SearchCount, entries.Count); // We ignore SearchAttributes - Transaction2FindFirst2Response response = new Transaction2FindFirst2Response(); + FindInformationList findInformationList = new FindInformationList(); for (int index = 0; index < entriesToReturn; index++) { FindInformation infoEntry = InfoHelper.FromFileSystemEntry(entries[index], subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys); - response.FindInfoList.Add(infoEntry); - if (response.FindInfoList.GetLength(header.UnicodeFlag) > state.GetMaxDataCount(header.PID)) + findInformationList.Add(infoEntry); + if (findInformationList.GetLength(header.UnicodeFlag) > state.GetMaxDataCount(header.PID)) { - response.FindInfoList.RemoveAt(response.FindInfoList.Count - 1); + findInformationList.RemoveAt(findInformationList.Count - 1); break; } } - int returnCount = response.FindInfoList.Count; + int returnCount = findInformationList.Count; + Transaction2FindFirst2Response response = new Transaction2FindFirst2Response(); + response.SetFindInformationList(findInformationList, header.UnicodeFlag); response.EndOfSearch = (returnCount == entries.Count) && (entries.Count <= subcommand.SearchCount); bool closeAtEndOfSearch = (subcommand.Flags & FindFlags.SMB_FIND_CLOSE_AT_EOS) > 0; bool closeAfterRequest = (subcommand.Flags & FindFlags.SMB_FIND_CLOSE_AFTER_REQUEST) > 0; @@ -193,7 +195,6 @@ namespace SMBLibrary.Server 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; @@ -202,20 +203,22 @@ namespace SMBLibrary.Server bool returnResumeKeys = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0; List entries = state.OpenSearches[subcommand.SID]; + FindInformationList findInformationList = new FindInformationList(); for (int index = 0; index < entries.Count; index++) { FindInformation infoEntry = InfoHelper.FromFileSystemEntry(entries[index], subcommand.InformationLevel, header.UnicodeFlag, returnResumeKeys); - response.FindInfoList.Add(infoEntry); - if (response.FindInfoList.GetLength(header.UnicodeFlag) > state.GetMaxDataCount(header.PID)) + findInformationList.Add(infoEntry); + if (findInformationList.GetLength(header.UnicodeFlag) > state.GetMaxDataCount(header.PID)) { - response.FindInfoList.RemoveAt(response.FindInfoList.Count - 1); + findInformationList.RemoveAt(findInformationList.Count - 1); break; } } - int returnCount = response.FindInfoList.Count; + int returnCount = findInformationList.Count; + Transaction2FindNext2Response response = new Transaction2FindNext2Response(); + response.SetFindInformationList(findInformationList, header.UnicodeFlag); entries.RemoveRange(0, returnCount); state.OpenSearches[subcommand.SID] = entries; - response.SearchCount = (ushort)returnCount; response.EndOfSearch = (returnCount == entries.Count) && (entries.Count <= subcommand.SearchCount); if (response.EndOfSearch) { @@ -227,7 +230,8 @@ namespace SMBLibrary.Server internal static Transaction2QueryFSInformationResponse GetSubcommandResponse(SMBHeader header, Transaction2QueryFSInformationRequest subcommand, FileSystemShare share) { Transaction2QueryFSInformationResponse response = new Transaction2QueryFSInformationResponse(); - response.QueryFSInfo = InfoHelper.GetFSInformation(subcommand.InformationLevel, share.FileSystem); + QueryFSInformation queryFSInformation = InfoHelper.GetFSInformation(subcommand.InformationLevel, share.FileSystem); + response.SetQueryFSInformation(queryFSInformation, header.UnicodeFlag); return response; } @@ -245,7 +249,8 @@ namespace SMBLibrary.Server return null; } Transaction2QueryPathInformationResponse response = new Transaction2QueryPathInformationResponse(); - response.QueryInfo = InfoHelper.FromFileSystemEntry(entry, subcommand.InformationLevel); + QueryInformation queryInformation = InfoHelper.FromFileSystemEntry(entry, subcommand.InformationLevel); + response.SetQueryInformation(queryInformation); return response; } @@ -267,7 +272,8 @@ namespace SMBLibrary.Server return null; } Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse(); - response.QueryInfo = InfoHelper.FromFileSystemEntry(entry, subcommand.InformationLevel); + QueryInformation queryInformation = InfoHelper.FromFileSystemEntry(entry, subcommand.InformationLevel); + response.SetQueryInformation(queryInformation); return response; }