SMB1: Transaction2 subcommands: Added support for pass-through Information Levels

This commit is contained in:
Tal Aloni 2017-09-30 22:12:14 +03:00
parent 42f00b4740
commit 966085c841
11 changed files with 332 additions and 68 deletions

View file

@ -211,7 +211,7 @@ namespace SMBLibrary.Client
int maxOutputLength = 4096; int maxOutputLength = 4096;
Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest(); Transaction2QueryFileInformationRequest subcommand = new Transaction2QueryFileInformationRequest();
subcommand.FID = (ushort)handle; subcommand.FID = (ushort)handle;
subcommand.InformationLevel = informationLevel; subcommand.QueryInformationLevel = informationLevel;
Transaction2Request request = new Transaction2Request(); Transaction2Request request = new Transaction2Request();
request.Setup = subcommand.GetSetup(); request.Setup = subcommand.GetSetup();
@ -282,7 +282,7 @@ namespace SMBLibrary.Client
result = null; result = null;
int maxOutputLength = 4096; int maxOutputLength = 4096;
Transaction2QueryFSInformationRequest subcommand = new Transaction2QueryFSInformationRequest(); Transaction2QueryFSInformationRequest subcommand = new Transaction2QueryFSInformationRequest();
subcommand.InformationLevel = informationLevel; subcommand.QueryFSInformationLevel = informationLevel;
Transaction2Request request = new Transaction2Request(); Transaction2Request request = new Transaction2Request();
request.Setup = subcommand.GetSetup(); request.Setup = subcommand.GetSetup();

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -6,7 +6,6 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Utilities; using Utilities;
namespace SMBLibrary.SMB1 namespace SMBLibrary.SMB1
@ -16,9 +15,10 @@ namespace SMBLibrary.SMB1
/// </summary> /// </summary>
public class Transaction2QueryFSInformationRequest : Transaction2Subcommand public class Transaction2QueryFSInformationRequest : Transaction2Subcommand
{ {
private const ushort SMB_INFO_PASSTHROUGH = 0x03E8;
public const int ParametersLength = 2; public const int ParametersLength = 2;
// Parameters:
public QueryFSInformationLevel InformationLevel; public ushort InformationLevel;
public Transaction2QueryFSInformationRequest() : base() public Transaction2QueryFSInformationRequest() : base()
{ {
@ -27,7 +27,7 @@ namespace SMBLibrary.SMB1
public Transaction2QueryFSInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2QueryFSInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
InformationLevel = (QueryFSInformationLevel)LittleEndianConverter.ToUInt16(parameters, 0); InformationLevel = LittleEndianConverter.ToUInt16(parameters, 0);
} }
public override byte[] GetSetup() public override byte[] GetSetup()
@ -38,10 +38,42 @@ namespace SMBLibrary.SMB1
public override byte[] GetParameters(bool isUnicode) public override byte[] GetParameters(bool isUnicode)
{ {
byte[] parameters = new byte[ParametersLength]; byte[] parameters = new byte[ParametersLength];
LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)InformationLevel); LittleEndianWriter.WriteUInt16(parameters, 0, InformationLevel);
return parameters; return parameters;
} }
public bool IsPassthroughInformationLevel
{
get
{
return (InformationLevel >= SMB_INFO_PASSTHROUGH);
}
}
public QueryFSInformationLevel QueryFSInformationLevel
{
get
{
return (QueryFSInformationLevel)InformationLevel;
}
set
{
InformationLevel = (ushort)value;
}
}
public FileSystemInformationClass FileSystemInformationClass
{
get
{
return (FileSystemInformationClass)(InformationLevel - SMB_INFO_PASSTHROUGH);
}
set
{
InformationLevel = (ushort)((ushort)value + SMB_INFO_PASSTHROUGH);
}
}
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName
{ {
get get

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -6,7 +6,6 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Utilities; using Utilities;
namespace SMBLibrary.SMB1 namespace SMBLibrary.SMB1
@ -18,7 +17,7 @@ namespace SMBLibrary.SMB1
{ {
public const int ParametersLength = 0; public const int ParametersLength = 0;
// Data: // Data:
private byte[] QueryFSInformationBytes; public byte[] InformationBytes;
public Transaction2QueryFSInformationResponse() : base() public Transaction2QueryFSInformationResponse() : base()
{ {
@ -26,22 +25,38 @@ namespace SMBLibrary.SMB1
public Transaction2QueryFSInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2QueryFSInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
QueryFSInformationBytes = data; InformationBytes = data;
} }
public override byte[] GetData(bool isUnicode) public override byte[] GetData(bool isUnicode)
{ {
return QueryFSInformationBytes; return InformationBytes;
} }
public QueryFSInformation GetQueryFSInformation(QueryFSInformationLevel informationLevel, bool isUnicode) public QueryFSInformation GetQueryFSInformation(QueryFSInformationLevel informationLevel, bool isUnicode)
{ {
return QueryFSInformation.GetQueryFSInformation(QueryFSInformationBytes, informationLevel, isUnicode); return QueryFSInformation.GetQueryFSInformation(InformationBytes, informationLevel, isUnicode);
} }
public void SetQueryFSInformation(QueryFSInformation queryFSInformation, bool isUnicode) public void SetQueryFSInformation(QueryFSInformation queryFSInformation, bool isUnicode)
{ {
QueryFSInformationBytes = queryFSInformation.GetBytes(isUnicode); InformationBytes = queryFSInformation.GetBytes(isUnicode);
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public FileSystemInformation GetFileSystemInformation(FileSystemInformationClass informationClass)
{
return FileSystemInformation.GetFileSystemInformation(InformationBytes, 0, informationClass);
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public void SetFileSystemInformation(FileSystemInformation information)
{
InformationBytes = information.GetBytes();
} }
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName

View file

@ -15,10 +15,11 @@ namespace SMBLibrary.SMB1
/// </summary> /// </summary>
public class Transaction2QueryFileInformationRequest : Transaction2Subcommand public class Transaction2QueryFileInformationRequest : Transaction2Subcommand
{ {
private const ushort SMB_INFO_PASSTHROUGH = 0x03E8;
public const int ParametersLength = 4; public const int ParametersLength = 4;
// Parameters: // Parameters:
public ushort FID; public ushort FID;
public QueryInformationLevel InformationLevel; public ushort InformationLevel;
// Data: // Data:
public FullExtendedAttributeList GetExtendedAttributeList; // Used with QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST public FullExtendedAttributeList GetExtendedAttributeList; // Used with QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST
@ -30,9 +31,9 @@ namespace SMBLibrary.SMB1
public Transaction2QueryFileInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2QueryFileInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
FID = LittleEndianConverter.ToUInt16(parameters, 0); FID = LittleEndianConverter.ToUInt16(parameters, 0);
InformationLevel = (QueryInformationLevel)LittleEndianConverter.ToUInt16(parameters, 2); InformationLevel = LittleEndianConverter.ToUInt16(parameters, 2);
if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST) if (!IsPassthroughInformationLevel && QueryInformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
{ {
GetExtendedAttributeList = new FullExtendedAttributeList(data, 0); GetExtendedAttributeList = new FullExtendedAttributeList(data, 0);
} }
@ -47,13 +48,13 @@ namespace SMBLibrary.SMB1
{ {
byte[] parameters = new byte[ParametersLength]; byte[] parameters = new byte[ParametersLength];
LittleEndianWriter.WriteUInt16(parameters, 0, FID); LittleEndianWriter.WriteUInt16(parameters, 0, FID);
LittleEndianWriter.WriteUInt16(parameters, 2, (ushort)InformationLevel); LittleEndianWriter.WriteUInt16(parameters, 2, InformationLevel);
return parameters; return parameters;
} }
public override byte[] GetData(bool isUnicode) public override byte[] GetData(bool isUnicode)
{ {
if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST) if (!IsPassthroughInformationLevel && QueryInformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
{ {
return GetExtendedAttributeList.GetBytes(); return GetExtendedAttributeList.GetBytes();
} }
@ -63,6 +64,38 @@ namespace SMBLibrary.SMB1
} }
} }
public bool IsPassthroughInformationLevel
{
get
{
return (InformationLevel >= SMB_INFO_PASSTHROUGH);
}
}
public QueryInformationLevel QueryInformationLevel
{
get
{
return (QueryInformationLevel)InformationLevel;
}
set
{
InformationLevel = (ushort)value;
}
}
public FileInformationClass FileInformationClass
{
get
{
return (FileInformationClass)(InformationLevel - SMB_INFO_PASSTHROUGH);
}
set
{
InformationLevel = (ushort)((ushort)value + SMB_INFO_PASSTHROUGH);
}
}
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName
{ {
get get

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -6,7 +6,6 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Utilities; using Utilities;
namespace SMBLibrary.SMB1 namespace SMBLibrary.SMB1
@ -20,7 +19,7 @@ namespace SMBLibrary.SMB1
// Parameters: // Parameters:
public ushort EaErrorOffset; // Meaningful only when request's InformationLevel is SMB_INFO_QUERY_EAS_FROM_LIST public ushort EaErrorOffset; // Meaningful only when request's InformationLevel is SMB_INFO_QUERY_EAS_FROM_LIST
// Data: // Data:
private byte[] QueryInformationBytes = new byte[0]; public byte[] InformationBytes = new byte[0];
public Transaction2QueryFileInformationResponse() : base() public Transaction2QueryFileInformationResponse() : base()
{ {
@ -29,7 +28,7 @@ namespace SMBLibrary.SMB1
public Transaction2QueryFileInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2QueryFileInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
QueryInformationBytes = data; InformationBytes = data;
} }
public override byte[] GetParameters(bool isUnicode) public override byte[] GetParameters(bool isUnicode)
@ -39,17 +38,33 @@ namespace SMBLibrary.SMB1
public override byte[] GetData(bool isUnicode) public override byte[] GetData(bool isUnicode)
{ {
return QueryInformationBytes; return InformationBytes;
} }
public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel) public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel)
{ {
return QueryInformation.GetQueryInformation(QueryInformationBytes, queryInformationLevel); return QueryInformation.GetQueryInformation(InformationBytes, queryInformationLevel);
} }
public void SetQueryInformation(QueryInformation queryInformation) public void SetQueryInformation(QueryInformation queryInformation)
{ {
QueryInformationBytes = queryInformation.GetBytes(); InformationBytes = queryInformation.GetBytes();
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public FileInformation GetFileInformation(FileInformationClass informationClass)
{
return FileInformation.GetFileInformation(InformationBytes, 0, informationClass);
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public void SetFileInformation(FileInformation information)
{
InformationBytes = information.GetBytes();
} }
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName

View file

@ -15,8 +15,10 @@ namespace SMBLibrary.SMB1
/// </summary> /// </summary>
public class Transaction2QueryPathInformationRequest : Transaction2Subcommand public class Transaction2QueryPathInformationRequest : Transaction2Subcommand
{ {
private const ushort SMB_INFO_PASSTHROUGH = 0x03E8;
public const int ParametersFixedLength = 6;
// Parameters: // Parameters:
public QueryInformationLevel InformationLevel; public ushort InformationLevel;
public uint Reserved; public uint Reserved;
public string FileName; // SMB_STRING public string FileName; // SMB_STRING
// Data: // Data:
@ -29,11 +31,11 @@ namespace SMBLibrary.SMB1
public Transaction2QueryPathInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2QueryPathInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
InformationLevel = (QueryInformationLevel)LittleEndianConverter.ToUInt16(parameters, 0); InformationLevel = LittleEndianConverter.ToUInt16(parameters, 0);
Reserved = LittleEndianConverter.ToUInt32(parameters, 4); Reserved = LittleEndianConverter.ToUInt32(parameters, 4);
FileName = SMB1Helper.ReadSMBString(parameters, 6, isUnicode); FileName = SMB1Helper.ReadSMBString(parameters, 6, isUnicode);
if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST) if (!IsPassthroughInformationLevel && QueryInformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
{ {
GetExtendedAttributeList = new FullExtendedAttributeList(data, 0); GetExtendedAttributeList = new FullExtendedAttributeList(data, 0);
} }
@ -46,7 +48,7 @@ namespace SMBLibrary.SMB1
public override byte[] GetParameters(bool isUnicode) public override byte[] GetParameters(bool isUnicode)
{ {
int length = 6; int length = ParametersFixedLength;
if (isUnicode) if (isUnicode)
{ {
length += FileName.Length * 2 + 2; length += FileName.Length * 2 + 2;
@ -56,7 +58,7 @@ namespace SMBLibrary.SMB1
length += FileName.Length + 1; length += FileName.Length + 1;
} }
byte[] parameters = new byte[length]; byte[] parameters = new byte[length];
LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)InformationLevel); LittleEndianWriter.WriteUInt16(parameters, 0, InformationLevel);
LittleEndianWriter.WriteUInt32(parameters, 2, Reserved); LittleEndianWriter.WriteUInt32(parameters, 2, Reserved);
SMB1Helper.WriteSMBString(parameters, 6, isUnicode, FileName); SMB1Helper.WriteSMBString(parameters, 6, isUnicode, FileName);
return parameters; return parameters;
@ -64,7 +66,7 @@ namespace SMBLibrary.SMB1
public override byte[] GetData(bool isUnicode) public override byte[] GetData(bool isUnicode)
{ {
if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST) if (!IsPassthroughInformationLevel && QueryInformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
{ {
return GetExtendedAttributeList.GetBytes(); return GetExtendedAttributeList.GetBytes();
} }
@ -74,6 +76,38 @@ namespace SMBLibrary.SMB1
} }
} }
public bool IsPassthroughInformationLevel
{
get
{
return (InformationLevel >= SMB_INFO_PASSTHROUGH);
}
}
public QueryInformationLevel QueryInformationLevel
{
get
{
return (QueryInformationLevel)InformationLevel;
}
set
{
InformationLevel = (ushort)value;
}
}
public FileInformationClass FileInformationClass
{
get
{
return (FileInformationClass)(InformationLevel - SMB_INFO_PASSTHROUGH);
}
set
{
InformationLevel = (ushort)((ushort)value + SMB_INFO_PASSTHROUGH);
}
}
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName
{ {
get get

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -6,7 +6,6 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Utilities; using Utilities;
namespace SMBLibrary.SMB1 namespace SMBLibrary.SMB1
@ -19,17 +18,16 @@ namespace SMBLibrary.SMB1
// Parameters: // Parameters:
public ushort EaErrorOffset; // Meaningful only when request's InformationLevel is SMB_INFO_QUERY_EAS_FROM_LIST public ushort EaErrorOffset; // Meaningful only when request's InformationLevel is SMB_INFO_QUERY_EAS_FROM_LIST
// Data: // Data:
private byte[] QueryInformationBytes; public byte[] InformationBytes;
public Transaction2QueryPathInformationResponse() : base() public Transaction2QueryPathInformationResponse() : base()
{ {
} }
public Transaction2QueryPathInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2QueryPathInformationResponse(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0); EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
QueryInformationBytes = data; InformationBytes = data;
} }
public override byte[] GetParameters(bool isUnicode) public override byte[] GetParameters(bool isUnicode)
@ -39,17 +37,33 @@ namespace SMBLibrary.SMB1
public override byte[] GetData(bool isUnicode) public override byte[] GetData(bool isUnicode)
{ {
return QueryInformationBytes; return InformationBytes;
} }
public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel) public QueryInformation GetQueryInformation(QueryInformationLevel queryInformationLevel)
{ {
return QueryInformation.GetQueryInformation(QueryInformationBytes, queryInformationLevel); return QueryInformation.GetQueryInformation(InformationBytes, queryInformationLevel);
} }
public void SetQueryInformation(QueryInformation queryInformation) public void SetQueryInformation(QueryInformation queryInformation)
{ {
QueryInformationBytes = queryInformation.GetBytes(); InformationBytes = queryInformation.GetBytes();
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public FileInformation GetFileInformation(FileInformationClass informationClass)
{
return FileInformation.GetFileInformation(InformationBytes, 0, informationClass);
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public void SetFileInformation(FileInformation information)
{
InformationBytes = information.GetBytes();
} }
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName

View file

@ -15,6 +15,7 @@ namespace SMBLibrary.SMB1
/// </summary> /// </summary>
public class Transaction2SetFSInformationRequest : Transaction2Subcommand public class Transaction2SetFSInformationRequest : Transaction2Subcommand
{ {
private const ushort SMB_INFO_PASSTHROUGH = 0x03E8;
public const int ParametersLength = 4; public const int ParametersLength = 4;
// Parameters: // Parameters:
public ushort FID; public ushort FID;
@ -52,6 +53,35 @@ namespace SMBLibrary.SMB1
return InformationBytes; return InformationBytes;
} }
public bool IsPassthroughInformationLevel
{
get
{
return (InformationLevel >= SMB_INFO_PASSTHROUGH);
}
}
public FileSystemInformationClass FileSystemInformationClass
{
get
{
return (FileSystemInformationClass)(InformationLevel - SMB_INFO_PASSTHROUGH);
}
set
{
InformationLevel = (ushort)((ushort)value + SMB_INFO_PASSTHROUGH);
}
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public void SetFileSystemInformation(FileSystemInformation information)
{
FileSystemInformationClass = information.FileSystemInformationClass;
InformationBytes = information.GetBytes();
}
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName
{ {
get get

View file

@ -6,7 +6,6 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Utilities; using Utilities;
namespace SMBLibrary.SMB1 namespace SMBLibrary.SMB1
@ -16,10 +15,11 @@ namespace SMBLibrary.SMB1
/// </summary> /// </summary>
public class Transaction2SetFileInformationRequest : Transaction2Subcommand public class Transaction2SetFileInformationRequest : Transaction2Subcommand
{ {
private const ushort SMB_INFO_PASSTHROUGH = 0x03E8;
public const int ParametersLength = 6; public const int ParametersLength = 6;
// Parameters: // Parameters:
public ushort FID; public ushort FID;
public SetInformationLevel InformationLevel; public ushort InformationLevel;
public ushort Reserved; public ushort Reserved;
// Data: // Data:
public byte[] InformationBytes; public byte[] InformationBytes;
@ -31,7 +31,7 @@ namespace SMBLibrary.SMB1
public Transaction2SetFileInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2SetFileInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
FID = LittleEndianConverter.ToUInt16(parameters, 0); FID = LittleEndianConverter.ToUInt16(parameters, 0);
InformationLevel = (SetInformationLevel)LittleEndianConverter.ToUInt16(parameters, 2); InformationLevel = LittleEndianConverter.ToUInt16(parameters, 2);
Reserved = LittleEndianConverter.ToUInt16(parameters, 4); Reserved = LittleEndianConverter.ToUInt16(parameters, 4);
InformationBytes = data; InformationBytes = data;
@ -46,7 +46,7 @@ namespace SMBLibrary.SMB1
{ {
byte[] parameters = new byte[ParametersLength]; byte[] parameters = new byte[ParametersLength];
LittleEndianWriter.WriteUInt16(parameters, 0, FID); LittleEndianWriter.WriteUInt16(parameters, 0, FID);
LittleEndianWriter.WriteUInt16(parameters, 2, (ushort)InformationLevel); LittleEndianWriter.WriteUInt16(parameters, 2, InformationLevel);
LittleEndianWriter.WriteUInt16(parameters, 4, Reserved); LittleEndianWriter.WriteUInt16(parameters, 4, Reserved);
return parameters; return parameters;
} }
@ -56,9 +56,50 @@ namespace SMBLibrary.SMB1
return InformationBytes; return InformationBytes;
} }
public bool IsPassthroughInformationLevel
{
get
{
return (InformationLevel >= SMB_INFO_PASSTHROUGH);
}
}
public SetInformationLevel SetInformationLevel
{
get
{
return (SetInformationLevel)InformationLevel;
}
set
{
InformationLevel = (ushort)value;
}
}
public FileInformationClass FileInformationClass
{
get
{
return (FileInformationClass)(InformationLevel - SMB_INFO_PASSTHROUGH);
}
set
{
InformationLevel = (ushort)((ushort)value + SMB_INFO_PASSTHROUGH);
}
}
public void SetInformation(SetInformation information) public void SetInformation(SetInformation information)
{ {
InformationLevel = information.InformationLevel; SetInformationLevel = information.InformationLevel;
InformationBytes = information.GetBytes();
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public void SetInformation(FileInformation information)
{
FileInformationClass = information.FileInformationClass;
InformationBytes = information.GetBytes(); InformationBytes = information.GetBytes();
} }

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -6,7 +6,6 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Utilities; using Utilities;
namespace SMBLibrary.SMB1 namespace SMBLibrary.SMB1
@ -16,22 +15,26 @@ namespace SMBLibrary.SMB1
/// </summary> /// </summary>
public class Transaction2SetPathInformationRequest : Transaction2Subcommand public class Transaction2SetPathInformationRequest : Transaction2Subcommand
{ {
private const ushort SMB_INFO_PASSTHROUGH = 0x03E8;
public const int ParametersFixedLength = 6; public const int ParametersFixedLength = 6;
// Parameters: // Parameters:
public SetInformationLevel InformationLevel; public ushort InformationLevel;
public uint Reserved; public uint Reserved;
public string FileName; // SMB_STRING public string FileName; // SMB_STRING
// Data: // Data:
public SetInformation SetInfo; public byte[] InformationBytes;
public Transaction2SetPathInformationRequest() : base() public Transaction2SetPathInformationRequest() : base()
{} {
}
public Transaction2SetPathInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base() public Transaction2SetPathInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
{ {
InformationLevel = (SetInformationLevel)LittleEndianConverter.ToUInt16(parameters, 0); InformationLevel = LittleEndianConverter.ToUInt16(parameters, 0);
Reserved = LittleEndianConverter.ToUInt32(parameters, 2); Reserved = LittleEndianConverter.ToUInt32(parameters, 2);
FileName = SMB1Helper.ReadSMBString(parameters, 6, isUnicode); FileName = SMB1Helper.ReadSMBString(parameters, 6, isUnicode);
InformationBytes = data;
} }
public override byte[] GetSetup() public override byte[] GetSetup()
@ -52,7 +55,7 @@ namespace SMBLibrary.SMB1
} }
byte[] parameters = new byte[length]; byte[] parameters = new byte[length];
LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)InformationLevel); LittleEndianWriter.WriteUInt16(parameters, 0, InformationLevel);
LittleEndianWriter.WriteUInt32(parameters, 2, Reserved); LittleEndianWriter.WriteUInt32(parameters, 2, Reserved);
SMB1Helper.WriteSMBString(parameters, 6, isUnicode, FileName); SMB1Helper.WriteSMBString(parameters, 6, isUnicode, FileName);
return parameters; return parameters;
@ -60,7 +63,54 @@ namespace SMBLibrary.SMB1
public override byte[] GetData(bool isUnicode) public override byte[] GetData(bool isUnicode)
{ {
return SetInfo.GetBytes(); return InformationBytes;
}
public bool IsPassthroughInformationLevel
{
get
{
return (InformationLevel >= SMB_INFO_PASSTHROUGH);
}
}
public SetInformationLevel SetInformationLevel
{
get
{
return (SetInformationLevel)InformationLevel;
}
set
{
InformationLevel = (ushort)value;
}
}
public FileInformationClass FileInformationClass
{
get
{
return (FileInformationClass)(InformationLevel - SMB_INFO_PASSTHROUGH);
}
set
{
InformationLevel = (ushort)((ushort)value + SMB_INFO_PASSTHROUGH);
}
}
public void SetInformation(SetInformation information)
{
SetInformationLevel = information.InformationLevel;
InformationBytes = information.GetBytes();
}
/// <remarks>
/// Support for pass-through Information Levels must be enabled.
/// </remarks>
public void SetInformation(FileInformation information)
{
FileInformationClass = information.FileInformationClass;
InformationBytes = information.GetBytes();
} }
public override Transaction2SubcommandName SubcommandName public override Transaction2SubcommandName SubcommandName

View file

@ -146,14 +146,14 @@ namespace SMBLibrary.Server.SMB1
Transaction2QueryFSInformationResponse response = new Transaction2QueryFSInformationResponse(); Transaction2QueryFSInformationResponse response = new Transaction2QueryFSInformationResponse();
QueryFSInformation queryFSInformation; QueryFSInformation queryFSInformation;
NTStatus queryStatus = SMB1FileStoreHelper.GetFileSystemInformation(out queryFSInformation, share.FileStore, subcommand.InformationLevel); NTStatus queryStatus = SMB1FileStoreHelper.GetFileSystemInformation(out queryFSInformation, share.FileStore, subcommand.QueryFSInformationLevel);
if (queryStatus != NTStatus.STATUS_SUCCESS) if (queryStatus != NTStatus.STATUS_SUCCESS)
{ {
state.LogToServer(Severity.Verbose, "GetFileSystemInformation on '{0}' failed. Information level: {1}, NTStatus: {2}", share.Name, subcommand.InformationLevel, queryStatus); state.LogToServer(Severity.Verbose, "GetFileSystemInformation on '{0}' failed. Information level: {1}, NTStatus: {2}", share.Name, subcommand.QueryFSInformationLevel, queryStatus);
header.Status = queryStatus; header.Status = queryStatus;
return null; return null;
} }
state.LogToServer(Severity.Information, "GetFileSystemInformation on '{0}' succeeded. Information level: {1}", share.Name, subcommand.InformationLevel); state.LogToServer(Severity.Information, "GetFileSystemInformation on '{0}' succeeded. Information level: {1}", share.Name, subcommand.QueryFSInformationLevel);
response.SetQueryFSInformation(queryFSInformation, header.UnicodeFlag); response.SetQueryFSInformation(queryFSInformation, header.UnicodeFlag);
return response; return response;
} }
@ -179,14 +179,14 @@ namespace SMBLibrary.Server.SMB1
Transaction2QueryPathInformationResponse response = new Transaction2QueryPathInformationResponse(); Transaction2QueryPathInformationResponse response = new Transaction2QueryPathInformationResponse();
QueryInformation queryInformation; QueryInformation queryInformation;
NTStatus queryStatus = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, path, subcommand.InformationLevel, session.SecurityContext); NTStatus queryStatus = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, path, subcommand.QueryInformationLevel, session.SecurityContext);
if (queryStatus != NTStatus.STATUS_SUCCESS) if (queryStatus != NTStatus.STATUS_SUCCESS)
{ {
state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}", share.Name, path, subcommand.InformationLevel, queryStatus); state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}", share.Name, path, subcommand.QueryInformationLevel, queryStatus);
header.Status = queryStatus; header.Status = queryStatus;
return null; return null;
} }
state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}", share.Name, path, subcommand.InformationLevel); state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}", share.Name, path, subcommand.QueryInformationLevel);
response.SetQueryInformation(queryInformation); response.SetQueryInformation(queryInformation);
return response; return response;
} }
@ -214,14 +214,14 @@ namespace SMBLibrary.Server.SMB1
Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse(); Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse();
QueryInformation queryInformation; QueryInformation queryInformation;
NTStatus queryStatus = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, openFile.Handle, subcommand.InformationLevel); NTStatus queryStatus = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, openFile.Handle, subcommand.QueryInformationLevel);
if (queryStatus != NTStatus.STATUS_SUCCESS) if (queryStatus != NTStatus.STATUS_SUCCESS)
{ {
state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.InformationLevel, queryStatus, subcommand.FID); state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.QueryInformationLevel, queryStatus, subcommand.FID);
header.Status = queryStatus; header.Status = queryStatus;
return null; return null;
} }
state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.InformationLevel, subcommand.FID); state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.QueryInformationLevel, subcommand.FID);
response.SetQueryInformation(queryInformation); response.SetQueryInformation(queryInformation);
return response; return response;
} }
@ -250,17 +250,17 @@ namespace SMBLibrary.Server.SMB1
SetInformation information; SetInformation information;
try try
{ {
information = SetInformation.GetSetInformation(subcommand.InformationBytes, subcommand.InformationLevel); information = SetInformation.GetSetInformation(subcommand.InformationBytes, subcommand.SetInformationLevel);
} }
catch(UnsupportedInformationLevelException) catch(UnsupportedInformationLevelException)
{ {
state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_OS2_INVALID_LEVEL.", share.Name, openFile.Path, subcommand.InformationLevel); state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_OS2_INVALID_LEVEL.", share.Name, openFile.Path, subcommand.SetInformationLevel);
header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL;
return null; return null;
} }
catch(Exception) catch(Exception)
{ {
state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, openFile.Path, subcommand.InformationLevel); state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, openFile.Path, subcommand.SetInformationLevel);
header.Status = NTStatus.STATUS_INVALID_PARAMETER; header.Status = NTStatus.STATUS_INVALID_PARAMETER;
return null; return null;
} }
@ -268,11 +268,11 @@ namespace SMBLibrary.Server.SMB1
NTStatus status = SMB1FileStoreHelper.SetFileInformation(share.FileStore, openFile.Handle, information); NTStatus status = SMB1FileStoreHelper.SetFileInformation(share.FileStore, openFile.Handle, information);
if (status != NTStatus.STATUS_SUCCESS) if (status != NTStatus.STATUS_SUCCESS)
{ {
state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.InformationLevel, status, subcommand.FID); state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.SetInformationLevel, status, subcommand.FID);
header.Status = status; header.Status = status;
return null; return null;
} }
state.LogToServer(Severity.Information, "SetFileInformation on '{0}{1}' succeeded. Information level: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.InformationLevel, subcommand.FID); state.LogToServer(Severity.Information, "SetFileInformation on '{0}{1}' succeeded. Information level: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.SetInformationLevel, subcommand.FID);
Transaction2SetFileInformationResponse response = new Transaction2SetFileInformationResponse(); Transaction2SetFileInformationResponse response = new Transaction2SetFileInformationResponse();
return response; return response;
} }