mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-04-30 02:37:49 +02:00
Improved Transaction2Subcommands implementation
This commit is contained in:
parent
2f4a6e1538
commit
8864c4f335
10 changed files with 106 additions and 86 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
if ((ushort)informationLevel > 0x0100)
|
||||
public Transaction2QueryFileInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base()
|
||||
{
|
||||
EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
|
||||
}
|
||||
QueryInfo = QueryInformation.GetQueryInformation(data, informationLevel);
|
||||
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];
|
||||
return QueryInformationBytes;
|
||||
}
|
||||
else
|
||||
|
||||
public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel)
|
||||
{
|
||||
return QueryInfo.GetBytes();
|
||||
return QueryInformation.GetQueryInformation(QueryInformationBytes, queryInformationLevel);
|
||||
}
|
||||
|
||||
public void SetQueryInformation(QueryInformation queryInformation)
|
||||
{
|
||||
QueryInformationBytes = queryInformation.GetBytes();
|
||||
}
|
||||
|
||||
public override Transaction2SubcommandName SubcommandName
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
if ((ushort)informationLevel > 0x0100)
|
||||
public Transaction2QueryPathInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base()
|
||||
{
|
||||
EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
|
||||
}
|
||||
QueryInfo = QueryInformation.GetQueryInformation(data, informationLevel);
|
||||
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];
|
||||
return QueryInformationBytes;
|
||||
}
|
||||
else
|
||||
|
||||
public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel)
|
||||
{
|
||||
return QueryInfo.GetBytes();
|
||||
return QueryInformation.GetQueryInformation(QueryInformationBytes, queryInformationLevel);
|
||||
}
|
||||
|
||||
public void SetQueryInformation(QueryInformation queryInformation)
|
||||
{
|
||||
QueryInformationBytes = queryInformation.GetBytes();
|
||||
}
|
||||
|
||||
public override Transaction2SubcommandName SubcommandName
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<FileSystemEntry> 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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue