mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-08-02 05:51:49 +02:00
Added SMB2 command structures and enums
This commit is contained in:
parent
d5b73a8f9d
commit
966096df5f
67 changed files with 3701 additions and 0 deletions
48
SMBLibrary/SMB2/Commands/CancelRequest.cs
Normal file
48
SMBLibrary/SMB2/Commands/CancelRequest.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 CANCEL Request
|
||||
/// </summary>
|
||||
public class CancelRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public CancelRequest() : base(SMB2CommandName.Cancel)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public CancelRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
60
SMBLibrary/SMB2/Commands/ChangeNotifyRequest.cs
Normal file
60
SMBLibrary/SMB2/Commands/ChangeNotifyRequest.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 CHANGE_NOTIFY Request
|
||||
/// </summary>
|
||||
public class ChangeNotifyRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 32;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ChangeNotifyFlags Flags;
|
||||
public uint OutputBufferLength;
|
||||
public FileID FileId;
|
||||
public NotifyChange CompletionFilter;
|
||||
public uint Reserved;
|
||||
|
||||
public ChangeNotifyRequest() : base(SMB2CommandName.ChangeNotify)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public ChangeNotifyRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Flags = (ChangeNotifyFlags)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
OutputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 8);
|
||||
CompletionFilter = (NotifyChange)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 24);
|
||||
Reserved = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, (ushort)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, OutputBufferLength);
|
||||
FileId.WriteBytes(buffer, offset + 8);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 24, (uint)CompletionFilter);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 28, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
SMBLibrary/SMB2/Commands/ChangeNotifyResponse.cs
Normal file
62
SMBLibrary/SMB2/Commands/ChangeNotifyResponse.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 CHANGE_NOTIFY Response
|
||||
/// </summary>
|
||||
public class ChangeNotifyResponse : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 8;
|
||||
public const int DeclaredSize = 9;
|
||||
|
||||
public ushort StructureSize;
|
||||
private ushort OutputBufferOffset;
|
||||
private uint OutputBufferLength;
|
||||
public byte[] OutputBuffer = new byte[0];
|
||||
|
||||
public ChangeNotifyResponse() : base(SMB2CommandName.ChangeNotify)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public ChangeNotifyResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
OutputBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
OutputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
OutputBuffer = ByteReader.ReadBytes(buffer, offset + OutputBufferOffset, (int)OutputBufferLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
OutputBufferOffset = 0;
|
||||
OutputBufferLength = (uint)OutputBuffer.Length;
|
||||
if (OutputBuffer.Length > 0)
|
||||
{
|
||||
OutputBufferOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, OutputBufferOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, OutputBufferLength);
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, OutputBuffer);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + OutputBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
SMBLibrary/SMB2/Commands/CloseRequest.cs
Normal file
54
SMBLibrary/SMB2/Commands/CloseRequest.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 CLOSE Request
|
||||
/// </summary>
|
||||
public class CloseRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 24;
|
||||
|
||||
public ushort StructureSize;
|
||||
public CloseFlags Flags;
|
||||
public uint Reserved;
|
||||
public FileID FileId;
|
||||
|
||||
public CloseRequest() : base(SMB2CommandName.Close)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public CloseRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Flags = (CloseFlags)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
Reserved = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 8);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, (ushort)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, Reserved);
|
||||
FileId.WriteBytes(buffer, offset + 8);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
73
SMBLibrary/SMB2/Commands/CloseResponse.cs
Normal file
73
SMBLibrary/SMB2/Commands/CloseResponse.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 CLOSE Response
|
||||
/// </summary>
|
||||
public class CloseResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 60;
|
||||
|
||||
public ushort StructureSize;
|
||||
public CloseFlags Flags;
|
||||
public uint Reserved;
|
||||
public DateTime? CreationTime;
|
||||
public DateTime? LastAccessTime;
|
||||
public DateTime? LastWriteTime;
|
||||
public DateTime? ChangeTime;
|
||||
public ulong AllocationSize;
|
||||
public ulong EndofFile;
|
||||
public FileAttributes FileAttributes;
|
||||
|
||||
public CloseResponse() : base(SMB2CommandName.Close)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public CloseResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Flags = (CloseFlags)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
Reserved = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
CreationTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 8);
|
||||
LastAccessTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 16);
|
||||
LastWriteTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 24);
|
||||
ChangeTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 32);
|
||||
AllocationSize = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 40);
|
||||
EndofFile = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 48);
|
||||
FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 56);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, (ushort)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, Reserved);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 8, CreationTime);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 16, LastAccessTime);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 24, LastWriteTime);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 32, ChangeTime);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 40, AllocationSize);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 48, EndofFile);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 56, (uint)FileAttributes);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
119
SMBLibrary/SMB2/Commands/CreateRequest.cs
Normal file
119
SMBLibrary/SMB2/Commands/CreateRequest.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 LOGOFF Request
|
||||
/// </summary>
|
||||
public class CreateRequest : SMB2Command
|
||||
{
|
||||
public const int FixedLength = 56;
|
||||
public const int DeclaredSize = 57;
|
||||
|
||||
public ushort StructureSize;
|
||||
public byte SecurityFlags; // Reserved
|
||||
public OplockLevel RequestedOplockLevel;
|
||||
public ImpersonationLevel ImpersonationLevel;
|
||||
public ulong SmbCreateFlags;
|
||||
public ulong Reserved;
|
||||
public AccessMask DesiredAccess;
|
||||
public FileAttributes FileAttributes;
|
||||
public ShareAccess ShareAccess;
|
||||
public CreateDisposition CreateDisposition;
|
||||
public CreateOptions CreateOptions;
|
||||
private ushort NameOffset;
|
||||
private ushort NameLength;
|
||||
public string Name;
|
||||
private uint CreateContextsOffsets;
|
||||
private uint CreateContextsLength;
|
||||
public List<CreateContext> CreateContexts = new List<CreateContext>();
|
||||
|
||||
public CreateRequest() : base(SMB2CommandName.Create)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public CreateRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
SecurityFlags = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
RequestedOplockLevel = (OplockLevel)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
ImpersonationLevel = (ImpersonationLevel)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
SmbCreateFlags = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 8);
|
||||
Reserved = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 16);
|
||||
DesiredAccess = new AccessMask(buffer, offset + SMB2Header.Length + 24);
|
||||
FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
|
||||
ShareAccess = (ShareAccess)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
|
||||
CreateDisposition = (CreateDisposition)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
|
||||
CreateOptions = (CreateOptions)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 40);
|
||||
NameOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 44);
|
||||
NameLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 46);
|
||||
CreateContextsOffsets = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 48);
|
||||
CreateContextsLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 52);
|
||||
Name = ByteReader.ReadUTF16String(buffer, offset + NameOffset, NameLength / 2);
|
||||
if (CreateContextsLength > 0)
|
||||
{
|
||||
CreateContexts = CreateContext.ReadCreateContextList(buffer, (int)CreateContextsOffsets);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
NameOffset = 0;
|
||||
NameLength = (ushort)(Name.Length * 2);
|
||||
if (Name.Length > 0)
|
||||
{
|
||||
NameOffset = SMB2Header.Length + FixedLength;
|
||||
}
|
||||
CreateContextsOffsets = 0;
|
||||
CreateContextsLength = 0;
|
||||
int paddedNameLength = (int)Math.Ceiling((double)(Name.Length * 2) / 8) * 8;
|
||||
if (CreateContexts.Count > 0)
|
||||
{
|
||||
CreateContextsOffsets = (uint)(SMB2Header.Length + 56 + paddedNameLength);
|
||||
CreateContextsLength = (uint)CreateContext.GetCreateContextListLength(CreateContexts);
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, SecurityFlags);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, (byte)RequestedOplockLevel);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, (uint)ImpersonationLevel);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 8, (ulong)SmbCreateFlags);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 16, (ulong)Reserved);
|
||||
DesiredAccess.WriteBytes(buffer, offset + 24);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 28, (uint)FileAttributes);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 32, (uint)ShareAccess);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 36, (uint)CreateDisposition);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 40, (uint)CreateOptions);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 44, NameOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 46, NameLength);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 48, CreateContextsOffsets);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 52, CreateContextsLength);
|
||||
ByteWriter.WriteUTF16String(buffer, offset + 56, Name);
|
||||
CreateContext.WriteCreateContextList(buffer, offset + 56 + paddedNameLength, CreateContexts);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CreateContexts.Count == 0)
|
||||
{
|
||||
return FixedLength + Name.Length * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int paddedNameLength = (int)Math.Ceiling((double)(Name.Length * 2) / 8) * 8;
|
||||
return FixedLength + paddedNameLength + CreateContext.GetCreateContextListLength(CreateContexts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
98
SMBLibrary/SMB2/Commands/CreateResponse.cs
Normal file
98
SMBLibrary/SMB2/Commands/CreateResponse.cs
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 CREATE Response
|
||||
/// </summary>
|
||||
public class CreateResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 89;
|
||||
|
||||
public ushort StructureSize;
|
||||
public OplockLevel OplockLevel;
|
||||
public CreateResponseFlags Flags;
|
||||
public CreateAction CreateAction;
|
||||
public DateTime? CreationTime;
|
||||
public DateTime? LastAccessTime;
|
||||
public DateTime? LastWriteTime;
|
||||
public DateTime? ChangeTime;
|
||||
public ulong AllocationSize;
|
||||
public ulong EndofFile;
|
||||
public FileAttributes FileAttributes;
|
||||
public uint Reserved2;
|
||||
public FileID FileId;
|
||||
private uint CreateContextsOffsets;
|
||||
private uint CreateContextsLength;
|
||||
public List<CreateContext> CreateContexts = new List<CreateContext>();
|
||||
|
||||
public CreateResponse() : base(SMB2CommandName.Create)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public CreateResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
OplockLevel = (OplockLevel)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
Flags = (CreateResponseFlags)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
CreateAction = (CreateAction)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
CreationTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 8);
|
||||
LastAccessTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 16);
|
||||
LastWriteTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 24);
|
||||
ChangeTime = FileTimeHelper.ReadNullableFileTime(buffer, offset + SMB2Header.Length + 32);
|
||||
AllocationSize = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 40);
|
||||
EndofFile = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 48);
|
||||
FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 56);
|
||||
Reserved2 = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 60);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 64);
|
||||
CreateContextsOffsets = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 80);
|
||||
CreateContextsLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 84);
|
||||
if (CreateContextsLength > 0)
|
||||
{
|
||||
CreateContexts = CreateContext.ReadCreateContextList(buffer, offset + (int)CreateContextsOffsets);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, (byte)OplockLevel);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, (byte)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, (uint)CreateAction);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 8, CreationTime);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 16, LastAccessTime);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 24, LastWriteTime);
|
||||
FileTimeHelper.WriteFileTime(buffer, offset + 32, ChangeTime);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 40, AllocationSize);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 48, EndofFile);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 56, (uint)FileAttributes);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 60, Reserved2);
|
||||
FileId.WriteBytes(buffer, offset + 64);
|
||||
CreateContextsOffsets = 0;
|
||||
CreateContextsLength = (uint)CreateContext.GetCreateContextListLength(CreateContexts);
|
||||
if (CreateContexts.Count > 0)
|
||||
{
|
||||
CreateContextsOffsets = SMB2Header.Length + 88;
|
||||
CreateContext.WriteCreateContextList(buffer, 88, CreateContexts);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return 88 + CreateContext.GetCreateContextListLength(CreateContexts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
48
SMBLibrary/SMB2/Commands/EchoRequest.cs
Normal file
48
SMBLibrary/SMB2/Commands/EchoRequest.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 ECHO Request
|
||||
/// </summary>
|
||||
public class EchoRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public EchoRequest() : base(SMB2CommandName.Echo)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public EchoRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
SMBLibrary/SMB2/Commands/EchoResponse.cs
Normal file
49
SMBLibrary/SMB2/Commands/EchoResponse.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 ECHO Response
|
||||
/// </summary>
|
||||
public class EchoResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public EchoResponse() : base(SMB2CommandName.Echo)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public EchoResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
SMBLibrary/SMB2/Commands/ErrorResponse.cs
Normal file
77
SMBLibrary/SMB2/Commands/ErrorResponse.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 ERROR Response
|
||||
/// </summary>
|
||||
public class ErrorResponse : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 8;
|
||||
public const int DeclaredSize = 9;
|
||||
|
||||
public ushort StructureSize;
|
||||
public byte ErrorContextCount;
|
||||
public byte Reserved;
|
||||
private uint ByteCount;
|
||||
public byte[] ErrorData = new byte[0];
|
||||
|
||||
public ErrorResponse(SMB2CommandName commandName) : base(commandName)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public ErrorResponse(SMB2CommandName commandName, NTStatus status) : base(commandName)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
Header.Status = status;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public ErrorResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
ErrorContextCount = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
Reserved = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
ByteCount = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
ErrorData = ByteReader.ReadBytes(buffer, offset + SMB2Header.Length + 8, (int)ByteCount);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
ByteCount = (uint)ErrorData.Length;
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, ErrorContextCount);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, ByteCount);
|
||||
if (ErrorData.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + 8, ErrorData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the ByteCount field is zero then the server MUST supply an ErrorData field that is one byte in length, and SHOULD set that byte to zero
|
||||
ByteWriter.WriteBytes(buffer, offset + 8, new byte[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
// If the ByteCount field is zero then the server MUST supply an ErrorData field that is one byte in length
|
||||
return FixedSize + Math.Max(ErrorData.Length, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
SMBLibrary/SMB2/Commands/FlushRequest.cs
Normal file
54
SMBLibrary/SMB2/Commands/FlushRequest.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 FLUSH Request
|
||||
/// </summary>
|
||||
public class FlushRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 24;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved1;
|
||||
public uint Reserved2;
|
||||
public FileID FileId;
|
||||
|
||||
public FlushRequest() : base(SMB2CommandName.Flush)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public FlushRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved1 = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
Reserved2 = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 8);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved1);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, Reserved2);
|
||||
FileId.WriteBytes(buffer, offset + 8);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
SMBLibrary/SMB2/Commands/FlushResponse.cs
Normal file
49
SMBLibrary/SMB2/Commands/FlushResponse.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 FLUSH Response
|
||||
/// </summary>
|
||||
public class FlushResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public FlushResponse() : base(SMB2CommandName.Flush)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public FlushResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
122
SMBLibrary/SMB2/Commands/IOCtlRequest.cs
Normal file
122
SMBLibrary/SMB2/Commands/IOCtlRequest.cs
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 IOCTL Request
|
||||
/// </summary>
|
||||
public class IOCtlRequest : SMB2Command
|
||||
{
|
||||
public const int FixedLength = 56;
|
||||
public const int DeclaredSize = 57;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
public uint CtlCode;
|
||||
public FileID FileId;
|
||||
private uint InputOffset;
|
||||
private uint InputCount;
|
||||
public uint MaxInputResponse;
|
||||
private uint OutputOffset;
|
||||
private uint OutputCount;
|
||||
public uint MaxOutputResponse;
|
||||
public IOCtlRequestFlags Flags;
|
||||
public uint Reserved2;
|
||||
public byte[] Input = new byte[0];
|
||||
public byte[] Output = new byte[0];
|
||||
|
||||
public IOCtlRequest() : base(SMB2CommandName.IOCtl)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public IOCtlRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
CtlCode = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 8);
|
||||
InputOffset = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 24);
|
||||
InputCount = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
|
||||
MaxInputResponse = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
|
||||
OutputOffset = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
|
||||
OutputCount = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 40);
|
||||
MaxOutputResponse = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 44);
|
||||
Flags = (IOCtlRequestFlags)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 48);
|
||||
Reserved2 = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 52);
|
||||
Input = ByteReader.ReadBytes(buffer, offset + (int)InputOffset, (int)InputCount);
|
||||
Output = ByteReader.ReadBytes(buffer, offset + (int)OutputOffset, (int)OutputCount);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
InputOffset = 0;
|
||||
InputCount = (uint)Input.Length;
|
||||
OutputOffset = 0;
|
||||
OutputCount = (uint)Output.Length;
|
||||
if (Input.Length > 0)
|
||||
{
|
||||
InputOffset = SMB2Header.Length + FixedLength;
|
||||
}
|
||||
if (Output.Length > 0)
|
||||
{
|
||||
OutputOffset = InputOffset + (uint)Input.Length;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, CtlCode);
|
||||
FileId.WriteBytes(buffer, offset + 8);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 24, InputOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 28, InputCount);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 32, MaxInputResponse);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 36, OutputOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 40, OutputCount);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 44, MaxOutputResponse);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 48, (uint)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 52, Reserved2);
|
||||
if (Input.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedLength, Input);
|
||||
}
|
||||
if (Output.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedLength + Input.Length, Output);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFSCtl
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Flags & IOCtlRequestFlags.IsFSCtl) > 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Flags |= IOCtlRequestFlags.IsFSCtl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags &= ~IOCtlRequestFlags.IsFSCtl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedLength + Input.Length + Output.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
101
SMBLibrary/SMB2/Commands/IOCtlResponse.cs
Normal file
101
SMBLibrary/SMB2/Commands/IOCtlResponse.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 IOCTL Request
|
||||
/// </summary>
|
||||
public class IOCtlResponse : SMB2Command
|
||||
{
|
||||
public const int FixedLength = 48;
|
||||
public const int DeclaredSize = 49;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
public uint CtlCode;
|
||||
public FileID FileId;
|
||||
private uint InputOffset;
|
||||
private uint InputCount;
|
||||
private uint OutputOffset;
|
||||
private uint OutputCount;
|
||||
public uint Flags;
|
||||
public uint Reserved2;
|
||||
public byte[] Input = new byte[0];
|
||||
public byte[] Output = new byte[0];
|
||||
|
||||
public IOCtlResponse() : base(SMB2CommandName.IOCtl)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public IOCtlResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
CtlCode = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 8);
|
||||
InputOffset = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 24);
|
||||
InputCount = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
|
||||
OutputOffset = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
|
||||
OutputCount = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
|
||||
Flags = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 40);
|
||||
Reserved2 = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 44);
|
||||
Input = ByteReader.ReadBytes(buffer, offset + (int)InputOffset, (int)InputCount);
|
||||
Output = ByteReader.ReadBytes(buffer, offset + (int)OutputOffset, (int)OutputCount);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
InputOffset = 0;
|
||||
InputCount = (uint)Input.Length;
|
||||
OutputOffset = 0;
|
||||
OutputCount = (uint)Output.Length;
|
||||
if (Input.Length > 0)
|
||||
{
|
||||
InputOffset = SMB2Header.Length + FixedLength;
|
||||
}
|
||||
// MS-SMB2: the output offset MUST be set to InputOffset + InputCount rounded up to a multiple of 8
|
||||
int paddedInputLength = (int)Math.Ceiling((double)Input.Length / 8) * 8;
|
||||
if (Output.Length > 0)
|
||||
{
|
||||
OutputOffset = SMB2Header.Length + FixedLength + (uint)paddedInputLength;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, CtlCode);
|
||||
FileId.WriteBytes(buffer, offset + 8);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 24, InputOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 28, InputCount);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 32, OutputOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 36, OutputCount);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 40, Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 44, Reserved2);
|
||||
if (Input.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedLength, Input);
|
||||
}
|
||||
if (Output.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedLength + paddedInputLength, Output);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
int paddedInputLength = (int)Math.Ceiling((double)Input.Length / 8) * 8;
|
||||
return FixedLength + paddedInputLength + Output.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
60
SMBLibrary/SMB2/Commands/LockRequest.cs
Normal file
60
SMBLibrary/SMB2/Commands/LockRequest.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 LOCK Request
|
||||
/// </summary>
|
||||
public class LockRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 48;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort LockCount;
|
||||
public byte LSN; // 4 bits
|
||||
public uint LockSequenceIndex; // 28 bits
|
||||
public FileID FileId;
|
||||
public List<LockElement> Locks;
|
||||
|
||||
public LockRequest() : base(SMB2CommandName.Lock)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public LockRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
LockCount = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
uint temp = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
LSN = (byte)(temp >> 28);
|
||||
LockSequenceIndex = (temp & 0x0FFFFFFF);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 8);
|
||||
Locks = LockElement.ReadLockList(buffer, offset + SMB2Header.Length + 24, (int)LockCount);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, LockCount);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, (uint)(LSN & 0x0F) << 28 | (uint)(LockSequenceIndex & 0x0FFFFFFF));
|
||||
FileId.WriteBytes(buffer, offset + 8);
|
||||
LockElement.WriteLockList(buffer, offset + 24, Locks);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return 48 + Locks.Count * LockElement.StructureLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
SMBLibrary/SMB2/Commands/LockResponse.cs
Normal file
49
SMBLibrary/SMB2/Commands/LockResponse.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 LOCK Response
|
||||
/// </summary>
|
||||
public class LockResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public LockResponse() : base(SMB2CommandName.Lock)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public LockResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
48
SMBLibrary/SMB2/Commands/LogoffRequest.cs
Normal file
48
SMBLibrary/SMB2/Commands/LogoffRequest.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 LOGOFF Request
|
||||
/// </summary>
|
||||
public class LogoffRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public LogoffRequest() : base(SMB2CommandName.Logoff)
|
||||
{
|
||||
StructureSize = 4;
|
||||
}
|
||||
|
||||
public LogoffRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
SMBLibrary/SMB2/Commands/LogoffResponse.cs
Normal file
49
SMBLibrary/SMB2/Commands/LogoffResponse.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 LOGOFF Response
|
||||
/// </summary>
|
||||
public class LogoffResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public LogoffResponse() : base(SMB2CommandName.Logoff)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = 4;
|
||||
}
|
||||
|
||||
public LogoffResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
76
SMBLibrary/SMB2/Commands/NegotiateRequest.cs
Normal file
76
SMBLibrary/SMB2/Commands/NegotiateRequest.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 NEGOTIATE Request
|
||||
/// </summary>
|
||||
public class NegotiateRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 36;
|
||||
|
||||
public ushort StructureSize;
|
||||
private ushort DialectCount;
|
||||
public SecurityMode SecurityMode;
|
||||
public ushort Reserved;
|
||||
public ServerCapabilities Capabilities;
|
||||
public Guid ClientGuid;
|
||||
public DateTime ClientStartTime;
|
||||
public List<SMB2Dialect> Dialects = new List<SMB2Dialect>();
|
||||
|
||||
public NegotiateRequest() : base(SMB2CommandName.Negotiate)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public NegotiateRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
DialectCount = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
SecurityMode = (SecurityMode)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 4);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 6);
|
||||
Capabilities = (ServerCapabilities)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 8);
|
||||
ClientGuid = LittleEndianConverter.ToGuid(buffer, offset + SMB2Header.Length + 12);
|
||||
ClientStartTime = DateTime.FromFileTimeUtc(LittleEndianConverter.ToInt64(buffer, offset + SMB2Header.Length + 28));
|
||||
|
||||
for (int index = 0; index < DialectCount; index++)
|
||||
{
|
||||
SMB2Dialect dialect = (SMB2Dialect)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 36 + index * 2);
|
||||
Dialects.Add(dialect);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, DialectCount);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 4, (ushort)SecurityMode);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 6, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 8, (uint)Capabilities);
|
||||
LittleEndianWriter.WriteGuidBytes(buffer, offset + 12, ClientGuid);
|
||||
LittleEndianWriter.WriteInt64(buffer, offset + 28, ClientStartTime.ToFileTimeUtc());
|
||||
|
||||
for (int index = 0; index < Dialects.Count; index++)
|
||||
{
|
||||
SMB2Dialect dialect = Dialects[index];
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 36 + index * 2, (ushort)dialect);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return 36 + Dialects.Count * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
114
SMBLibrary/SMB2/Commands/NegotiateResponse.cs
Normal file
114
SMBLibrary/SMB2/Commands/NegotiateResponse.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 NEGOTIATE Response
|
||||
/// </summary>
|
||||
public class NegotiateResponse : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 64;
|
||||
public const int DeclaredSize = 65;
|
||||
|
||||
public ushort StructureSize;
|
||||
public SecurityMode SecurityMode;
|
||||
public SMB2Dialect DialectRevision;
|
||||
private ushort NegotiateContextCount;
|
||||
public Guid ServerGuid;
|
||||
public ServerCapabilities Capabilities;
|
||||
public uint MaxTransactSize;
|
||||
public uint MaxReadSize;
|
||||
public uint MaxWriteSize;
|
||||
public DateTime SystemTime;
|
||||
public DateTime ServerStartTime;
|
||||
private ushort SecurityBufferOffset;
|
||||
private ushort SecurityBufferLength;
|
||||
private uint NegotiateContextOffset;
|
||||
public byte[] SecurityBuffer = new byte[0];
|
||||
public List<NegotiateContext> NegotiateContextList = new List<NegotiateContext>();
|
||||
|
||||
public NegotiateResponse() : base(SMB2CommandName.Negotiate)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public NegotiateResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
SecurityMode = (SecurityMode)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
DialectRevision = (SMB2Dialect)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 4);
|
||||
NegotiateContextCount = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 6);
|
||||
ServerGuid = LittleEndianConverter.ToGuid(buffer, offset + SMB2Header.Length + 8);
|
||||
Capabilities = (ServerCapabilities)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 24);
|
||||
MaxTransactSize = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
|
||||
MaxReadSize = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
|
||||
MaxWriteSize = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
|
||||
SystemTime = DateTime.FromFileTimeUtc(LittleEndianConverter.ToInt64(buffer, offset + SMB2Header.Length + 40));
|
||||
ServerStartTime = DateTime.FromFileTimeUtc(LittleEndianConverter.ToInt64(buffer, offset + SMB2Header.Length + 48));
|
||||
SecurityBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 56);
|
||||
SecurityBufferLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 58);
|
||||
NegotiateContextOffset = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 60);
|
||||
SecurityBuffer = ByteReader.ReadBytes(buffer, offset + SecurityBufferOffset, SecurityBufferLength);
|
||||
NegotiateContextList = NegotiateContext.ReadNegotiateContextList(buffer, (int)NegotiateContextOffset, NegotiateContextCount);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
SecurityBufferOffset = 0;
|
||||
SecurityBufferLength = (ushort)SecurityBuffer.Length;
|
||||
int paddedSecurityBufferLength = (int)Math.Ceiling((double)SecurityBufferLength / 8) * 8;
|
||||
if (SecurityBuffer.Length > 0)
|
||||
{
|
||||
SecurityBufferOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
NegotiateContextOffset = 0;
|
||||
NegotiateContextCount = (ushort)NegotiateContextList.Count;
|
||||
if (NegotiateContextList.Count > 0)
|
||||
{
|
||||
// NegotiateContextList must be 8-byte aligned
|
||||
NegotiateContextOffset = (uint)(SMB2Header.Length + FixedSize + paddedSecurityBufferLength);
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, (ushort)SecurityMode);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 4, (ushort)DialectRevision);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 6, NegotiateContextCount);
|
||||
LittleEndianWriter.WriteGuidBytes(buffer, offset + 8, ServerGuid);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 24, (uint)Capabilities);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 28, MaxTransactSize);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 32, MaxReadSize);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 36, MaxWriteSize);
|
||||
LittleEndianWriter.WriteInt64(buffer, offset + 40, SystemTime.ToFileTimeUtc());
|
||||
LittleEndianWriter.WriteInt64(buffer, offset + 48, ServerStartTime.ToFileTimeUtc());
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 56, SecurityBufferOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 58, SecurityBufferLength);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 60, NegotiateContextOffset);
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, SecurityBuffer);
|
||||
NegotiateContext.WriteNegotiateContextList(buffer, offset + FixedSize + paddedSecurityBufferLength, NegotiateContextList);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
if (NegotiateContextList.Count == 0)
|
||||
{
|
||||
return FixedSize + SecurityBuffer.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
int paddedSecurityBufferLength = (int)Math.Ceiling((double)SecurityBufferLength / 8) * 8;
|
||||
return FixedSize + paddedSecurityBufferLength + NegotiateContext.GetNegotiateContextListLength(NegotiateContextList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
133
SMBLibrary/SMB2/Commands/QueryDirectoryRequest.cs
Normal file
133
SMBLibrary/SMB2/Commands/QueryDirectoryRequest.cs
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 QUERY_DIRECTORY Request
|
||||
/// </summary>
|
||||
public class QueryDirectoryRequest : SMB2Command
|
||||
{
|
||||
public const int FixedLength = 32;
|
||||
public const int DeclaredSize = 33;
|
||||
|
||||
public ushort StructureSize;
|
||||
public FileInformationClass FileInformationClass;
|
||||
public QueryDirectoryFlags Flags;
|
||||
public uint FileIndex;
|
||||
public FileID FileId;
|
||||
private ushort FileNameOffset;
|
||||
private ushort FileNameLength;
|
||||
public uint OutputBufferLength;
|
||||
public string FileName = String.Empty;
|
||||
|
||||
public QueryDirectoryRequest() : base(SMB2CommandName.QueryDirectory)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public QueryDirectoryRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
FileInformationClass = (FileInformationClass)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
Flags = (QueryDirectoryFlags)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
FileIndex = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 8);
|
||||
FileNameOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 24);
|
||||
FileNameLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 26);
|
||||
OutputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
|
||||
FileName = ByteReader.ReadUTF16String(buffer, offset + FileNameOffset, FileNameLength / 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
FileNameOffset = 0;
|
||||
FileNameLength = (ushort)(FileName.Length * 2);
|
||||
if (FileName.Length > 0)
|
||||
{
|
||||
FileNameOffset = SMB2Header.Length + FixedLength;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, (byte)FileInformationClass);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, (byte)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, FileIndex);
|
||||
FileId.WriteBytes(buffer, offset + 8);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 24, FileNameOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 26, FileNameLength);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 28, OutputBufferLength);
|
||||
ByteWriter.WriteUTF16String(buffer, offset + 32, FileName);
|
||||
}
|
||||
|
||||
public bool Restart
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((this.Flags & QueryDirectoryFlags.SMB2_RESTART_SCANS) > 0);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Flags |= QueryDirectoryFlags.SMB2_RESTART_SCANS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags &= ~QueryDirectoryFlags.SMB2_RESTART_SCANS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ReturnSingleEntry
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((this.Flags & QueryDirectoryFlags.SMB2_RETURN_SINGLE_ENTRY) > 0);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Flags |= QueryDirectoryFlags.SMB2_RETURN_SINGLE_ENTRY;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags &= ~QueryDirectoryFlags.SMB2_RETURN_SINGLE_ENTRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Reopen
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((this.Flags & QueryDirectoryFlags.SMB2_REOPEN) > 0);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Flags |= QueryDirectoryFlags.SMB2_REOPEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags &= ~QueryDirectoryFlags.SMB2_REOPEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedLength + FileName.Length * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
79
SMBLibrary/SMB2/Commands/QueryDirectoryResponse.cs
Normal file
79
SMBLibrary/SMB2/Commands/QueryDirectoryResponse.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 QUERY_DIRECTORY Response
|
||||
/// </summary>
|
||||
public class QueryDirectoryResponse : SMB2Command
|
||||
{
|
||||
public const int FixedLength = 8;
|
||||
public const int DeclaredSize = 9;
|
||||
|
||||
public ushort StructureSize;
|
||||
private ushort OutputBufferOffset;
|
||||
private uint OutputBufferLength;
|
||||
public byte[] OutputBuffer = new byte[0];
|
||||
|
||||
public QueryDirectoryResponse() : base(SMB2CommandName.QueryDirectory)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public QueryDirectoryResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
OutputBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
OutputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
OutputBuffer = ByteReader.ReadBytes(buffer, offset + (int)OutputBufferOffset, (int)OutputBufferLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
OutputBufferOffset = 0;
|
||||
OutputBufferLength = (uint)OutputBuffer.Length;
|
||||
if (OutputBuffer.Length > 0)
|
||||
{
|
||||
OutputBufferOffset = SMB2Header.Length + FixedLength;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, OutputBufferOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, OutputBufferLength);
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedLength, OutputBuffer);
|
||||
}
|
||||
|
||||
public List<QueryDirectoryFileInformation> GetFileInformationList(FileInformationClass fileInformationClass)
|
||||
{
|
||||
if (OutputBuffer.Length > 0)
|
||||
{
|
||||
return QueryDirectoryFileInformation.ReadFileInformationList(OutputBuffer, 0, fileInformationClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<QueryDirectoryFileInformation>();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFileInformationList(List<QueryDirectoryFileInformation> fileInformationList)
|
||||
{
|
||||
OutputBuffer = QueryDirectoryFileInformation.GetBytes(fileInformationList);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedLength + OutputBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
111
SMBLibrary/SMB2/Commands/QueryInfoRequest.cs
Normal file
111
SMBLibrary/SMB2/Commands/QueryInfoRequest.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 QUERY_INFO Request
|
||||
/// </summary>
|
||||
public class QueryInfoRequest : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 40;
|
||||
public const int DeclaredSize = 41;
|
||||
|
||||
public ushort StructureSize;
|
||||
public InfoType InfoType;
|
||||
private byte FileInfoClass;
|
||||
public uint OutputBufferLength;
|
||||
private ushort InputBufferOffset;
|
||||
public ushort Reserved;
|
||||
private uint InputBufferLength;
|
||||
public uint AdditionalInformation;
|
||||
public uint Flags;
|
||||
public FileID FileId;
|
||||
public byte[] InputBuffer = new byte[0];
|
||||
|
||||
public QueryInfoRequest() : base(SMB2CommandName.QueryInfo)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public QueryInfoRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
InfoType = (InfoType)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
FileInfoClass = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
OutputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
InputBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 8);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 10);
|
||||
InputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 12);
|
||||
AdditionalInformation = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 16);
|
||||
Flags = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 20);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 24);
|
||||
InputBuffer = ByteReader.ReadBytes(buffer, offset + InputBufferOffset, (int)InputBufferLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
InputBufferOffset = 0;
|
||||
InputBufferLength = (uint)InputBuffer.Length;
|
||||
if (InputBuffer.Length > 0)
|
||||
{
|
||||
InputBufferOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, (byte)InfoType);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, FileInfoClass);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, OutputBufferLength);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 8, InputBufferOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 10, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 12, InputBufferLength);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 16, AdditionalInformation);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 20, Flags);
|
||||
FileId.WriteBytes(buffer, offset + 24);
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, InputBuffer);
|
||||
}
|
||||
|
||||
public FileInformationClass FileInformationClass
|
||||
{
|
||||
get
|
||||
{
|
||||
return (FileInformationClass)FileInfoClass;
|
||||
}
|
||||
set
|
||||
{
|
||||
FileInfoClass = (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
public FileSystemInformationClass FileSystemInformationClass
|
||||
{
|
||||
get
|
||||
{
|
||||
return (FileSystemInformationClass)FileInfoClass;
|
||||
}
|
||||
set
|
||||
{
|
||||
FileInfoClass = (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFileInformation(FileInformation fileInformation)
|
||||
{
|
||||
InputBuffer = fileInformation.GetBytes();
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + InputBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
72
SMBLibrary/SMB2/Commands/QueryInfoResponse.cs
Normal file
72
SMBLibrary/SMB2/Commands/QueryInfoResponse.cs
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 QUERY_INFO Response
|
||||
/// </summary>
|
||||
public class QueryInfoResponse : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 8;
|
||||
public const int DeclaredSize = 9;
|
||||
|
||||
public ushort StructureSize;
|
||||
private ushort OutputBufferOffset;
|
||||
private uint OutputBufferLength;
|
||||
public byte[] OutputBuffer = new byte[0];
|
||||
|
||||
public QueryInfoResponse() : base(SMB2CommandName.QueryInfo)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public QueryInfoResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
OutputBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
OutputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
OutputBuffer = ByteReader.ReadBytes(buffer, offset + OutputBufferOffset, (int)OutputBufferLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
OutputBufferOffset = 0;
|
||||
OutputBufferLength = (uint)OutputBuffer.Length;
|
||||
if (OutputBuffer.Length > 0)
|
||||
{
|
||||
OutputBufferOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, OutputBufferOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, OutputBufferLength);
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, OutputBuffer);
|
||||
}
|
||||
|
||||
public void SetFileInformation(FileInformation fileInformation)
|
||||
{
|
||||
OutputBuffer = fileInformation.GetBytes();
|
||||
}
|
||||
|
||||
public void SetFileSystemInformation(FileSystemInformation fileSystemInformation)
|
||||
{
|
||||
OutputBuffer = fileSystemInformation.GetBytes();
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + OutputBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
97
SMBLibrary/SMB2/Commands/ReadRequest.cs
Normal file
97
SMBLibrary/SMB2/Commands/ReadRequest.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 READ Request
|
||||
/// </summary>
|
||||
public class ReadRequest : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 48;
|
||||
public const int DeclaredSize = 49;
|
||||
|
||||
public ushort StructureSize;
|
||||
public byte Padding;
|
||||
public ReadFlags Flags;
|
||||
public uint ReadLength;
|
||||
public ulong Offset;
|
||||
public FileID FileId;
|
||||
public uint MinimumCount;
|
||||
public uint Channel;
|
||||
public uint RemainingBytes;
|
||||
private ushort ReadChannelInfoOffset;
|
||||
private ushort ReadChannelInfoLength;
|
||||
public byte[] ReadChannelInfo = new byte[0];
|
||||
|
||||
public ReadRequest() : base(SMB2CommandName.Read)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public ReadRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Padding = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
Flags = (ReadFlags)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
ReadLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
Offset = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 8);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 16);
|
||||
MinimumCount = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
|
||||
Channel = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
|
||||
RemainingBytes = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 40);
|
||||
ReadChannelInfoOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 44);
|
||||
ReadChannelInfoLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 46);
|
||||
if (ReadChannelInfoLength > 0)
|
||||
{
|
||||
ReadChannelInfo = ByteReader.ReadBytes(buffer, offset + ReadChannelInfoOffset, ReadChannelInfoLength);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
ReadChannelInfoOffset = 0;
|
||||
ReadChannelInfoLength = (ushort)ReadChannelInfo.Length;
|
||||
if (ReadChannelInfo.Length > 0)
|
||||
{
|
||||
ReadChannelInfoOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, Padding);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, (byte)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, ReadLength);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 8, Offset);
|
||||
FileId.WriteBytes(buffer, offset + 16);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 32, MinimumCount);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 36, Channel);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 40, RemainingBytes);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 44, ReadChannelInfoOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 46, ReadChannelInfoLength);
|
||||
if (ReadChannelInfo.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, ReadChannelInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The client MUST set one byte of [the buffer] field to 0
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, new byte[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
// The client MUST set one byte of [the buffer] field to 0
|
||||
return Math.Max(FixedSize + ReadChannelInfo.Length, DeclaredSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
SMBLibrary/SMB2/Commands/ReadResponse.cs
Normal file
77
SMBLibrary/SMB2/Commands/ReadResponse.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 READ Response
|
||||
/// </summary>
|
||||
public class ReadResponse : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 16;
|
||||
public const int DeclaredSize = 17;
|
||||
|
||||
public ushort StructureSize;
|
||||
private byte DataOffset;
|
||||
public byte Reserved;
|
||||
private uint DataLength;
|
||||
public uint DataRemaining;
|
||||
public uint Reserved2;
|
||||
public byte[] Data = new byte[0];
|
||||
|
||||
public ReadResponse() : base(SMB2CommandName.Read)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public ReadResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
DataOffset = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
Reserved = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
DataLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
DataRemaining = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 8);
|
||||
Reserved2 = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 12);
|
||||
if (DataLength > 0)
|
||||
{
|
||||
Data = ByteReader.ReadBytes(buffer, offset + DataOffset, (int)DataLength);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
DataOffset = 0;
|
||||
DataLength = (uint)Data.Length;
|
||||
if (Data.Length > 0)
|
||||
{
|
||||
DataOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, DataOffset);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, DataLength);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 8, DataRemaining);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 12, Reserved2);
|
||||
if (Data.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, Data);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + Data.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
157
SMBLibrary/SMB2/Commands/SMB2Command.cs
Normal file
157
SMBLibrary/SMB2/Commands/SMB2Command.cs
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public abstract class SMB2Command
|
||||
{
|
||||
public SMB2Header Header;
|
||||
|
||||
public SMB2Command(SMB2CommandName commandName)
|
||||
{
|
||||
Header = new SMB2Header(commandName);
|
||||
}
|
||||
|
||||
public SMB2Command(byte[] buffer, int offset)
|
||||
{
|
||||
Header = new SMB2Header(buffer, offset);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] buffer, int offset)
|
||||
{
|
||||
Header.WriteBytes(buffer, offset);
|
||||
WriteCommandBytes(buffer, offset + SMB2Header.Length);
|
||||
}
|
||||
|
||||
public abstract void WriteCommandBytes(byte[] buffer, int offset);
|
||||
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
byte[] buffer = new byte[this.Length];
|
||||
WriteBytes(buffer, 0);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public SMB2CommandName CommandName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Header.Command;
|
||||
}
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return SMB2Header.Length + CommandLength;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int CommandLength
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public static SMB2Command ReadRequest(byte[] buffer, int offset)
|
||||
{
|
||||
SMB2CommandName Command = (SMB2CommandName)LittleEndianConverter.ToUInt16(buffer, offset + 12);
|
||||
switch (Command)
|
||||
{
|
||||
case SMB2CommandName.Negotiate:
|
||||
return new NegotiateRequest(buffer, offset);
|
||||
case SMB2CommandName.SessionSetup:
|
||||
return new SessionSetupRequest(buffer, offset);
|
||||
case SMB2CommandName.Logoff:
|
||||
return new LogoffRequest(buffer, offset);
|
||||
case SMB2CommandName.TreeConnect:
|
||||
return new TreeConnectRequest(buffer, offset);
|
||||
case SMB2CommandName.TreeDisconnect:
|
||||
return new TreeDisconnectRequest(buffer, offset);
|
||||
case SMB2CommandName.Create:
|
||||
return new CreateRequest(buffer, offset);
|
||||
case SMB2CommandName.Close:
|
||||
return new CloseRequest(buffer, offset);
|
||||
case SMB2CommandName.Flush:
|
||||
return new FlushRequest(buffer, offset);
|
||||
case SMB2CommandName.Read:
|
||||
return new ReadRequest(buffer, offset);
|
||||
case SMB2CommandName.Write:
|
||||
return new WriteRequest(buffer, offset);
|
||||
case SMB2CommandName.Lock:
|
||||
return new LockRequest(buffer, offset);
|
||||
case SMB2CommandName.IOCtl:
|
||||
return new IOCtlRequest(buffer, offset);
|
||||
case SMB2CommandName.Cancel:
|
||||
return new CancelRequest(buffer, offset);
|
||||
case SMB2CommandName.Echo:
|
||||
return new EchoRequest(buffer, offset);
|
||||
case SMB2CommandName.QueryDirectory:
|
||||
return new QueryDirectoryRequest(buffer, offset);
|
||||
case SMB2CommandName.ChangeNotify:
|
||||
return new ChangeNotifyRequest(buffer, offset);
|
||||
case SMB2CommandName.QueryInfo:
|
||||
return new QueryInfoRequest(buffer, offset);
|
||||
case SMB2CommandName.SetInfo:
|
||||
return new SetInfoRequest(buffer, offset);
|
||||
default:
|
||||
throw new System.IO.InvalidDataException("Invalid SMB2 command in buffer");
|
||||
}
|
||||
}
|
||||
|
||||
public static List<SMB2Command> ReadRequestChain(byte[] buffer, int offset)
|
||||
{
|
||||
List<SMB2Command> result = new List<SMB2Command>();
|
||||
SMB2Command command;
|
||||
do
|
||||
{
|
||||
command = ReadRequest(buffer, offset);
|
||||
result.Add(command);
|
||||
offset += (int)command.Header.NextCommand;
|
||||
}
|
||||
while (command.Header.NextCommand != 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] GetCommandChainBytes(List<SMB2Command> commands)
|
||||
{
|
||||
int totalLength = 0;
|
||||
for (int index = 0; index < commands.Count; index++)
|
||||
{
|
||||
// Any subsequent SMB2 header MUST be 8-byte aligned
|
||||
int length = commands[index].Length;
|
||||
if (index < commands.Count - 1)
|
||||
{
|
||||
int paddedLength = (int)Math.Ceiling((double)length / 8) * 8;
|
||||
totalLength += paddedLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
totalLength += length;
|
||||
}
|
||||
}
|
||||
byte[] buffer = new byte[totalLength];
|
||||
int offset = 0;
|
||||
for (int index = 0; index < commands.Count; index++)
|
||||
{
|
||||
SMB2Command command = commands[index];
|
||||
int commandLength = command.Length;
|
||||
int paddedLength = (int)Math.Ceiling((double)commandLength / 8) * 8;
|
||||
if (index < commands.Count - 1)
|
||||
{
|
||||
command.Header.NextCommand = (uint)paddedLength;
|
||||
}
|
||||
command.WriteBytes(buffer, offset);
|
||||
offset += paddedLength;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
79
SMBLibrary/SMB2/Commands/SessionSetupRequest.cs
Normal file
79
SMBLibrary/SMB2/Commands/SessionSetupRequest.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 SESSION_SETUP Request
|
||||
/// </summary>
|
||||
public class SessionSetupRequest : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 24;
|
||||
public const int DeclaredSize = 25;
|
||||
|
||||
public ushort StructureSize;
|
||||
public SessionSetupFlags Flags;
|
||||
public SecurityMode SecurityMode;
|
||||
public ServerCapabilities Capabilities;
|
||||
public uint Channel;
|
||||
private ushort SecurityBufferOffset;
|
||||
private ushort SecurityBufferLength;
|
||||
public ulong PreviousSessionId;
|
||||
public byte[] SecurityBuffer = new byte[0];
|
||||
|
||||
public SessionSetupRequest() : base(SMB2CommandName.SessionSetup)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public SessionSetupRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Flags = (SessionSetupFlags)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
SecurityMode = (SecurityMode)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
Capabilities = (ServerCapabilities)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
Channel = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 8);
|
||||
SecurityBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 12);
|
||||
SecurityBufferLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 14);
|
||||
PreviousSessionId = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 16);
|
||||
if (SecurityBufferLength > 0)
|
||||
{
|
||||
SecurityBuffer = ByteReader.ReadBytes(buffer, offset + SecurityBufferOffset, SecurityBufferLength);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
SecurityBufferOffset = 0;
|
||||
SecurityBufferLength = (ushort)SecurityBuffer.Length;
|
||||
if (SecurityBuffer.Length > 0)
|
||||
{
|
||||
SecurityBufferOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, (byte)Flags);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, (byte)SecurityMode);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, (uint)Capabilities);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 8, Channel);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 12, SecurityBufferOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 14, SecurityBufferLength);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 16, PreviousSessionId);
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, SecurityBuffer);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + SecurityBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
65
SMBLibrary/SMB2/Commands/SessionSetupResponse.cs
Normal file
65
SMBLibrary/SMB2/Commands/SessionSetupResponse.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 SESSION_SETUP Response
|
||||
/// </summary>
|
||||
public class SessionSetupResponse : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 8;
|
||||
public const int DeclaredSize = 9;
|
||||
|
||||
public ushort StructureSize;
|
||||
public SessionFlags SessionFlags;
|
||||
private ushort SecurityBufferOffset;
|
||||
private ushort SecurityBufferLength;
|
||||
public byte[] SecurityBuffer = new byte[0];
|
||||
|
||||
public SessionSetupResponse() : base(SMB2CommandName.SessionSetup)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public SessionSetupResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
SessionFlags = (SessionFlags)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
SecurityBufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 4);
|
||||
SecurityBufferLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 6);
|
||||
SecurityBuffer = ByteReader.ReadBytes(buffer, offset + SecurityBufferOffset, SecurityBufferLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
SecurityBufferOffset = 0;
|
||||
SecurityBufferLength = (ushort)SecurityBuffer.Length;
|
||||
if (SecurityBuffer.Length > 0)
|
||||
{
|
||||
SecurityBufferOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, (ushort)SessionFlags);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 4, SecurityBufferOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 6, SecurityBufferLength);
|
||||
ByteWriter.WriteBytes(buffer, offset + 8, SecurityBuffer);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + SecurityBuffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
105
SMBLibrary/SMB2/Commands/SetInfoRequest.cs
Normal file
105
SMBLibrary/SMB2/Commands/SetInfoRequest.cs
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 SET_INFO Request
|
||||
/// </summary>
|
||||
public class SetInfoRequest : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 32;
|
||||
public const int DeclaredSize = 33;
|
||||
|
||||
public ushort StructureSize;
|
||||
public InfoType InfoType;
|
||||
private byte FileInfoClass;
|
||||
public uint BufferLength;
|
||||
private ushort BufferOffset;
|
||||
public ushort Reserved;
|
||||
public uint AdditionalInformation;
|
||||
public FileID FileId;
|
||||
public byte[] Buffer = new byte[0];
|
||||
|
||||
public SetInfoRequest() : base(SMB2CommandName.SetInfo)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public SetInfoRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
InfoType = (InfoType)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
FileInfoClass = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
BufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
BufferOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 8);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 10);
|
||||
AdditionalInformation = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 12);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 16);
|
||||
Buffer = ByteReader.ReadBytes(buffer, offset + BufferOffset, (int)BufferLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
BufferOffset = 0;
|
||||
BufferLength = (uint)Buffer.Length;
|
||||
if (Buffer.Length > 0)
|
||||
{
|
||||
BufferOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, (byte)InfoType);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, FileInfoClass);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, BufferLength);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 8, BufferOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 10, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 12, AdditionalInformation);
|
||||
FileId.WriteBytes(buffer, offset + 16);
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, Buffer);
|
||||
}
|
||||
|
||||
public FileInformationClass FileInformationClass
|
||||
{
|
||||
get
|
||||
{
|
||||
return (FileInformationClass)FileInfoClass;
|
||||
}
|
||||
set
|
||||
{
|
||||
FileInfoClass = (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
public FileSystemInformationClass FileSystemInformationClass
|
||||
{
|
||||
get
|
||||
{
|
||||
return (FileSystemInformationClass)FileInfoClass;
|
||||
}
|
||||
set
|
||||
{
|
||||
FileInfoClass = (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFileInformation(FileInformation fileInformation)
|
||||
{
|
||||
Buffer = fileInformation.GetBytes();
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + Buffer.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
46
SMBLibrary/SMB2/Commands/SetInfoResponse.cs
Normal file
46
SMBLibrary/SMB2/Commands/SetInfoResponse.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 SET_INFO Response
|
||||
/// </summary>
|
||||
public class SetInfoResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 2;
|
||||
|
||||
public ushort StructureSize;
|
||||
|
||||
public SetInfoResponse() : base(SMB2CommandName.SetInfo)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public SetInfoResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
SMBLibrary/SMB2/Commands/TreeConnectRequest.cs
Normal file
70
SMBLibrary/SMB2/Commands/TreeConnectRequest.cs
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 TREE_CONNECT Request
|
||||
/// </summary>
|
||||
public class TreeConnectRequest : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 8;
|
||||
public const int DeclaredSize = 9;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
private ushort PathOffset;
|
||||
private ushort PathLength;
|
||||
public string Path = String.Empty;
|
||||
|
||||
public TreeConnectRequest() : base(SMB2CommandName.TreeConnect)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public TreeConnectRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
PathOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 4);
|
||||
PathLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 6);
|
||||
if (PathLength > 0)
|
||||
{
|
||||
Path = ByteReader.ReadUTF16String(buffer, offset + PathOffset, PathLength / 2);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
PathOffset = 0;
|
||||
PathLength = (ushort)(Path.Length * 2);
|
||||
if (Path.Length > 0)
|
||||
{
|
||||
PathOffset = SMB2Header.Length + 8;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 4, PathOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 6, PathLength);
|
||||
if (Path.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteUTF16String(buffer, offset + 8, Path);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return 8 + Path.Length * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
SMBLibrary/SMB2/Commands/TreeConnectResponse.cs
Normal file
61
SMBLibrary/SMB2/Commands/TreeConnectResponse.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 TREE_CONNECT Response
|
||||
/// </summary>
|
||||
public class TreeConnectResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 16;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ShareType ShareType;
|
||||
public byte Reserved;
|
||||
public ShareFlags ShareFlags;
|
||||
public ShareCapabilities Capabilities;
|
||||
public AccessMask MaximalAccess;
|
||||
|
||||
public TreeConnectResponse() : base(SMB2CommandName.TreeConnect)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public TreeConnectResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
ShareType = (ShareType)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
|
||||
Reserved = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
|
||||
ShareFlags = (ShareFlags)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
Capabilities = (ShareCapabilities)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 8);
|
||||
MaximalAccess = new AccessMask(buffer, offset + SMB2Header.Length + 12);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
ByteWriter.WriteByte(buffer, offset + 2, (byte)ShareType);
|
||||
ByteWriter.WriteByte(buffer, offset + 3, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, (uint)ShareFlags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 8, (uint)Capabilities);
|
||||
MaximalAccess.WriteBytes(buffer, offset + 12);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
48
SMBLibrary/SMB2/Commands/TreeDisconnectRequest.cs
Normal file
48
SMBLibrary/SMB2/Commands/TreeDisconnectRequest.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 TREE_DISCONNECT Request
|
||||
/// </summary>
|
||||
public class TreeDisconnectRequest : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public TreeDisconnectRequest() : base(SMB2CommandName.TreeDisconnect)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public TreeDisconnectRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
SMBLibrary/SMB2/Commands/TreeDisconnectResponse.cs
Normal file
49
SMBLibrary/SMB2/Commands/TreeDisconnectResponse.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 TREE_DISCONNECT Response
|
||||
/// </summary>
|
||||
public class TreeDisconnectResponse : SMB2Command
|
||||
{
|
||||
public const int DeclaredSize = 4;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
|
||||
public TreeDisconnectResponse() : base(SMB2CommandName.TreeDisconnect)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public TreeDisconnectResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return DeclaredSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
99
SMBLibrary/SMB2/Commands/WriteRequest.cs
Normal file
99
SMBLibrary/SMB2/Commands/WriteRequest.cs
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 WRITE Request
|
||||
/// </summary>
|
||||
public class WriteRequest : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 48;
|
||||
public const int DeclaredSize = 49;
|
||||
|
||||
public ushort StructureSize;
|
||||
private ushort DataOffset;
|
||||
private uint DataLength;
|
||||
public ulong Offset;
|
||||
public FileID FileId;
|
||||
public uint Channel;
|
||||
public uint RemainingBytes;
|
||||
private ushort WriteChannelInfoOffset;
|
||||
private ushort WriteChannelInfoLength;
|
||||
public WriteFlags Flags;
|
||||
public byte[] Data = new byte[0];
|
||||
public byte[] WriteChannelInfo = new byte[0];
|
||||
|
||||
public WriteRequest() : base(SMB2CommandName.Write)
|
||||
{
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public WriteRequest(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
DataOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
DataLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
Offset = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 8);
|
||||
FileId = new FileID(buffer, offset + SMB2Header.Length + 16);
|
||||
Channel = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
|
||||
RemainingBytes = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
|
||||
WriteChannelInfoOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 40);
|
||||
WriteChannelInfoLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 42);
|
||||
Flags = (WriteFlags)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 44);
|
||||
Data = ByteReader.ReadBytes(buffer, offset + DataOffset, (int)DataLength);
|
||||
WriteChannelInfo = ByteReader.ReadBytes(buffer, offset + WriteChannelInfoOffset, WriteChannelInfoLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
// Note: DataLength is UInt32 while WriteChannelInfoOffset is UInt16
|
||||
// so it is best to put WriteChannelInfo before Data.
|
||||
WriteChannelInfoOffset = 0;
|
||||
WriteChannelInfoLength = (ushort)WriteChannelInfo.Length;
|
||||
if (WriteChannelInfo.Length > 0)
|
||||
{
|
||||
WriteChannelInfoOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
DataOffset = 0;
|
||||
DataLength = (uint)Data.Length;
|
||||
if (Data.Length > 0)
|
||||
{
|
||||
DataOffset = (ushort)(WriteChannelInfoOffset + WriteChannelInfo.Length);
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, DataOffset);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, DataLength);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 8, Offset);
|
||||
FileId.WriteBytes(buffer, offset + 16);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 32, Channel);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 36, RemainingBytes);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 40, WriteChannelInfoOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 42, WriteChannelInfoLength);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 44, (uint)Flags);
|
||||
if (WriteChannelInfo.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, WriteChannelInfo);
|
||||
}
|
||||
if (Data.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize + WriteChannelInfo.Length, Data);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + Data.Length + WriteChannelInfo.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
74
SMBLibrary/SMB2/Commands/WriteResponse.cs
Normal file
74
SMBLibrary/SMB2/Commands/WriteResponse.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// SMB2 WRITE Response
|
||||
/// </summary>
|
||||
public class WriteResponse : SMB2Command
|
||||
{
|
||||
public const int FixedSize = 16;
|
||||
public const int DeclaredSize = 17;
|
||||
|
||||
public ushort StructureSize;
|
||||
public ushort Reserved;
|
||||
public uint Count;
|
||||
public uint Remaining;
|
||||
private ushort WriteChannelInfoOffset;
|
||||
private ushort WriteChannelInfoLength;
|
||||
public byte[] WriteChannelInfo = new byte[0];
|
||||
|
||||
public WriteResponse() : base(SMB2CommandName.Write)
|
||||
{
|
||||
Header.IsResponse = true;
|
||||
StructureSize = DeclaredSize;
|
||||
}
|
||||
|
||||
public WriteResponse(byte[] buffer, int offset) : base(buffer, offset)
|
||||
{
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
|
||||
Count = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
|
||||
Remaining = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 8);
|
||||
WriteChannelInfoOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 12);
|
||||
WriteChannelInfoLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 14);
|
||||
WriteChannelInfo = ByteReader.ReadBytes(buffer, offset + WriteChannelInfoOffset, WriteChannelInfoLength);
|
||||
}
|
||||
|
||||
public override void WriteCommandBytes(byte[] buffer, int offset)
|
||||
{
|
||||
WriteChannelInfoOffset = 0;
|
||||
WriteChannelInfoLength = (ushort)WriteChannelInfo.Length;
|
||||
if (WriteChannelInfo.Length > 0)
|
||||
{
|
||||
WriteChannelInfoOffset = SMB2Header.Length + FixedSize;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, Count);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 8, Remaining);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 12, WriteChannelInfoOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 14, WriteChannelInfoLength);
|
||||
if (WriteChannelInfo.Length > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + FixedSize, WriteChannelInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public override int CommandLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedSize + WriteChannelInfo.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/ChangeNotify/ChangeNotifyFlags.cs
Normal file
10
SMBLibrary/SMB2/Enums/ChangeNotify/ChangeNotifyFlags.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum ChangeNotifyFlags : ushort
|
||||
{
|
||||
WatchTree = 0x0001, // SMB2_WATCH_TREE
|
||||
}
|
||||
}
|
21
SMBLibrary/SMB2/Enums/ChangeNotify/NotifyChange.cs
Normal file
21
SMBLibrary/SMB2/Enums/ChangeNotify/NotifyChange.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum NotifyChange : uint
|
||||
{
|
||||
FileName = 0x0000001, // FILE_NOTIFY_CHANGE_FILE_NAME
|
||||
DirName = 0x0000002, // FILE_NOTIFY_CHANGE_DIR_NAME
|
||||
Attributes = 0x0000004, // FILE_NOTIFY_CHANGE_ATTRIBUTES
|
||||
Size = 0x0000008, // FILE_NOTIFY_CHANGE_SIZE
|
||||
LastWrite = 0x000000010, // FILE_NOTIFY_CHANGE_LAST_WRITE
|
||||
LastAccess = 0x00000020, // FILE_NOTIFY_CHANGE_LAST_ACCESS
|
||||
Creation = 0x00000040, // FILE_NOTIFY_CHANGE_CREATION
|
||||
EA = 0x00000080, // FILE_NOTIFY_CHANGE_EA
|
||||
Security = 0x00000100, // FILE_NOTIFY_CHANGE_SECURITY
|
||||
StreamName = 0x00000200, // FILE_NOTIFY_CHANGE_STREAM_NAME
|
||||
StreamSize = 0x00000400, // FILE_NOTIFY_CHANGE_STREAM_SIZE
|
||||
StreamWrite = 0x00000800, // FILE_NOTIFY_CHANGE_STREAM_WRITE
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/Close/CloseFlags.cs
Normal file
10
SMBLibrary/SMB2/Enums/Close/CloseFlags.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum CloseFlags : byte
|
||||
{
|
||||
PostQueryAttribute = 0x0001, // SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB
|
||||
}
|
||||
}
|
11
SMBLibrary/SMB2/Enums/Create/CreateAction.cs
Normal file
11
SMBLibrary/SMB2/Enums/Create/CreateAction.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum CreateAction : uint
|
||||
{
|
||||
FILE_SUPERSEDED = 0x00000000,
|
||||
FILE_OPENED = 0x00000001,
|
||||
FILE_CREATED = 0x00000002,
|
||||
FILE_OVERWRITTEN = 0x00000003,
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/Create/CreateResponseFlags.cs
Normal file
10
SMBLibrary/SMB2/Enums/Create/CreateResponseFlags.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum CreateResponseFlags : byte
|
||||
{
|
||||
ReparsePoint = 0x01, // SMB2_CREATE_FLAG_REPARSEPOINT
|
||||
}
|
||||
}
|
14
SMBLibrary/SMB2/Enums/Create/ImpersonationLevel.cs
Normal file
14
SMBLibrary/SMB2/Enums/Create/ImpersonationLevel.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum ImpersonationLevel : uint
|
||||
{
|
||||
Anonymous = 0x00000000,
|
||||
Identification = 0x00000001,
|
||||
Impersonation = 0x00000002,
|
||||
Delegate = 0x00000003,
|
||||
}
|
||||
}
|
14
SMBLibrary/SMB2/Enums/Create/OplockLevel.cs
Normal file
14
SMBLibrary/SMB2/Enums/Create/OplockLevel.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum OplockLevel : byte
|
||||
{
|
||||
None = 0x00, // SMB2_OPLOCK_LEVEL_NONE
|
||||
Level2 = 0x01, // SMB2_OPLOCK_LEVEL_II
|
||||
Exclusive = 0x08, // SMB2_OPLOCK_LEVEL_EXCLUSIVE
|
||||
Batch = 0x09, // SMB2_OPLOCK_LEVEL_BATCH
|
||||
Lease = 0xFF, // SMB2_OPLOCK_LEVEL_LEASE
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/IOCtl/IOCtlRequestFlags.cs
Normal file
10
SMBLibrary/SMB2/Enums/IOCtl/IOCtlRequestFlags.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum IOCtlRequestFlags : uint
|
||||
{
|
||||
IsFSCtl = 0x00000001, // SMB2_0_IOCTL_IS_FSCTL
|
||||
}
|
||||
}
|
11
SMBLibrary/SMB2/Enums/InfoType.cs
Normal file
11
SMBLibrary/SMB2/Enums/InfoType.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum InfoType : byte
|
||||
{
|
||||
File = 0x01, // SMB2_0_INFO_FILE
|
||||
FileSystem = 0x02, // SMB2_0_INFO_FILESYSTEM
|
||||
Security = 0x03, // SMB2_0_INFO_SECURITY
|
||||
Quota = 0x04, // SMB2_0_INFO_QUOTA
|
||||
}
|
||||
}
|
9
SMBLibrary/SMB2/Enums/Negotiate/NegotiateContextType.cs
Normal file
9
SMBLibrary/SMB2/Enums/Negotiate/NegotiateContextType.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum NegotiateContextType : ushort
|
||||
{
|
||||
SMB2_PREAUTH_INTEGRITY_CAPABILITIES = 0x0001,
|
||||
SMB2_ENCRYPTION_CAPABILITIES = 0x0002,
|
||||
}
|
||||
}
|
21
SMBLibrary/SMB2/Enums/Negotiate/SMB2Dialect.cs
Normal file
21
SMBLibrary/SMB2/Enums/Negotiate/SMB2Dialect.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum SMB2Dialect : ushort
|
||||
{
|
||||
SMB202 = 0x0202, // SMB 2.0.2
|
||||
SMB210 = 0x0210, // SMB 2.1
|
||||
SMB300 = 0x0300, // SMB 3.0
|
||||
SMB302 = 0x0302, // SMB 3.0.2
|
||||
SMB311 = 0x0311, // SMB 3.1.1
|
||||
|
||||
/// <summary>
|
||||
/// indicates that the server implements SMB 2.1 or future dialect revisions and expects
|
||||
/// the client to send a subsequent SMB2 Negotiate request to negotiate the actual SMB 2
|
||||
/// Protocol revision to be used.
|
||||
/// The wildcard revision number is sent only in response to a multi-protocol negotiate
|
||||
/// request with the "SMB 2.???" dialect string.
|
||||
/// </summary>
|
||||
SMB2xx = 0x02FF, // SMB 2.xx
|
||||
}
|
||||
}
|
9
SMBLibrary/SMB2/Enums/Negotiate/SecurityMode.cs
Normal file
9
SMBLibrary/SMB2/Enums/Negotiate/SecurityMode.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum SecurityMode : ushort
|
||||
{
|
||||
SigningEnabled = 0x0001, // SMB2_NEGOTIATE_SIGNING_ENABLED
|
||||
SigningRequired = 0x0002, // SMB2_NEGOTIATE_SIGNING_REQUIRED
|
||||
}
|
||||
}
|
16
SMBLibrary/SMB2/Enums/Negotiate/ServerCapabilities.cs
Normal file
16
SMBLibrary/SMB2/Enums/Negotiate/ServerCapabilities.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum ServerCapabilities : uint
|
||||
{
|
||||
DFS = 0x00000001, // SMB2_GLOBAL_CAP_DFS
|
||||
Leasing = 0x00000002, // SMB2_GLOBAL_CAP_LEASING
|
||||
LargeMTU = 0x0000004, // SMB2_GLOBAL_CAP_LARGE_MTU
|
||||
MultiChannel = 0x0000008, // SMB2_GLOBAL_CAP_MULTI_CHANNEL
|
||||
PersistentHandles = 0x00000010, // SMB2_GLOBAL_CAP_PERSISTENT_HANDLES
|
||||
DirectoryLeasing = 0x00000020, // SMB2_GLOBAL_CAP_DIRECTORY_LEASING
|
||||
Encryption = 0x00000040, // SMB2_GLOBAL_CAP_ENCRYPTION (SMB 3.x)
|
||||
}
|
||||
}
|
13
SMBLibrary/SMB2/Enums/QueryDirectory/QueryDirectoryFlags.cs
Normal file
13
SMBLibrary/SMB2/Enums/QueryDirectory/QueryDirectoryFlags.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum QueryDirectoryFlags : byte
|
||||
{
|
||||
SMB2_RESTART_SCANS = 0x01,
|
||||
SMB2_RETURN_SINGLE_ENTRY = 0x02,
|
||||
SMB2_INDEX_SPECIFIED = 0x04,
|
||||
SMB2_REOPEN = 0x10,
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/Read/ReadFlags.cs
Normal file
10
SMBLibrary/SMB2/Enums/Read/ReadFlags.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum ReadFlags : byte
|
||||
{
|
||||
Unbuffered = 0x01, // SMB2_READFLAG_READ_UNBUFFERED;
|
||||
}
|
||||
}
|
26
SMBLibrary/SMB2/Enums/SMB2CommandName.cs
Normal file
26
SMBLibrary/SMB2/Enums/SMB2CommandName.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum SMB2CommandName : ushort
|
||||
{
|
||||
Negotiate = 0x0000, // SMB2 NEGOTIATE
|
||||
SessionSetup = 0x0001, // SMB2 SESSION_SETUP
|
||||
Logoff = 0x0002, // SMB2 LOGOFF
|
||||
TreeConnect = 0x0003, // SMB2 TREE_CONNECT
|
||||
TreeDisconnect = 0x0004, // SMB2 TREE_DISCONNECT
|
||||
Create = 0x0005, // SMB2 CREATE
|
||||
Close = 0x0006, // SMB2 CLOSE
|
||||
Flush = 0x0007, // SMB2 FLUSH
|
||||
Read = 0x0008, // SMB2 READ
|
||||
Write = 0x0009, // SMB2 WRITE
|
||||
Lock = 0x000A, // SMB2 LOCK
|
||||
IOCtl = 0x000B, // SMB2 IOCTL
|
||||
Cancel = 0x000C, // SMB2 CANCEL
|
||||
Echo = 0x000D, // SMB2 ECHO
|
||||
QueryDirectory = 0x000E, // SMB2 QUERY_DIRECTORY
|
||||
ChangeNotify = 0x000F, // SMB2 CHANGE_NOTIFY
|
||||
QueryInfo = 0x0010, // SMB2 QUERY_INFO
|
||||
SetInfo = 0x0011, // SMB2 SET_INFO
|
||||
OplockBreak = 0x0012, // SMB2 OPLOCK_BREAK
|
||||
}
|
||||
}
|
14
SMBLibrary/SMB2/Enums/SMB2PacketHeaderFlags.cs
Normal file
14
SMBLibrary/SMB2/Enums/SMB2PacketHeaderFlags.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum SMB2PacketHeaderFlags : uint
|
||||
{
|
||||
ServerToRedir = 0x0000001, // SMB2_FLAGS_SERVER_TO_REDIR
|
||||
AsyncCommand = 0x0000002, // SMB2_FLAGS_ASYNC_COMMAND
|
||||
RelatedOperations = 0x0000004, // SMB2_FLAGS_RELATED_OPERATIONS
|
||||
Signed = 0x0000008, // SMB2_FLAGS_SIGNED
|
||||
DfsOperations = 0x10000000, // SMB2_FLAGS_DFS_OPERATIONS
|
||||
}
|
||||
}
|
12
SMBLibrary/SMB2/Enums/SessionSetup/SessionFlags.cs
Normal file
12
SMBLibrary/SMB2/Enums/SessionSetup/SessionFlags.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum SessionFlags : ushort
|
||||
{
|
||||
IsGuest = 0x01, // SMB2_SESSION_FLAG_IS_GUEST
|
||||
IsNull = 0x02, // SMB2_SESSION_FLAG_IS_NULL
|
||||
EncryptData = 0x04, // SMB2_SESSION_FLAG_ENCRYPT_DATA (SMB 3.x)
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/SessionSetup/SessionSetupFlags.cs
Normal file
10
SMBLibrary/SMB2/Enums/SessionSetup/SessionSetupFlags.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum SessionSetupFlags : byte
|
||||
{
|
||||
Binding = 0x01, // SMB2_SESSION_FLAG_BINDING
|
||||
}
|
||||
}
|
14
SMBLibrary/SMB2/Enums/TreeConnect/ShareCapabilities.cs
Normal file
14
SMBLibrary/SMB2/Enums/TreeConnect/ShareCapabilities.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum ShareCapabilities : uint
|
||||
{
|
||||
Dfs = 0x00000008, // SMB2_SHARE_CAP_DFS
|
||||
ContinuousAvailability = 0x00000010, // SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY
|
||||
Scaleout = 0x00000020, // SMB2_SHARE_CAP_SCALEOUT
|
||||
Cluster = 0x00000040, // SMB2_SHARE_CAP_CLUSTER
|
||||
Asymmetric = 0x00000080, // SMB2_SHARE_CAP_ASYMMETRIC
|
||||
}
|
||||
}
|
23
SMBLibrary/SMB2/Enums/TreeConnect/ShareFlags.cs
Normal file
23
SMBLibrary/SMB2/Enums/TreeConnect/ShareFlags.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum ShareFlags : uint
|
||||
{
|
||||
ManualCaching = 0x00000000, // SMB2_SHAREFLAG_MANUAL_CACHING
|
||||
AutoCaching = 0x00000010, // SMB2_SHAREFLAG_AUTO_CACHING
|
||||
VdoCaching = 0x00000020, // SMB2_SHAREFLAG_VDO_CACHING
|
||||
NoCaching = 0x00000030, // SMB2_SHAREFLAG_NO_CACHING
|
||||
Dfs = 0x00000001, // SMB2_SHAREFLAG_DFS
|
||||
DfsRoot = 0x00000002, // SMB2_SHAREFLAG_DFS_ROOT
|
||||
RestrictExclusiveOpens = 0x00000100, // SMB2_SHAREFLAG_RESTRICT_EXCLUSIVE_OPENS
|
||||
ForceSharedDelete = 0x00000200, // SMB2_SHAREFLAG_FORCE_SHARED_DELETE
|
||||
AllowNamespaceCaching = 0x00000400, // SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING
|
||||
AccessBasedDirectoryEnum = 0x00000800, // SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM
|
||||
ForceLevel2Oplock = 0x00001000, // SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK
|
||||
EnableHashV1 = 0x00002000, // SMB2_SHAREFLAG_ENABLE_HASH_V1 (SMB 2.1)
|
||||
EnableHashV2 = 0x00004000, // SMB2_SHAREFLAG_ENABLE_HASH_V2 (SMB 3.x)
|
||||
EncryptData = 0x00008000, // SMB2_SHAREFLAG_ENCRYPT_DATA (SMB 3.x)
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/TreeConnect/ShareType.cs
Normal file
10
SMBLibrary/SMB2/Enums/TreeConnect/ShareType.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum ShareType : byte
|
||||
{
|
||||
Disk = 0x01, // SMB2_SHARE_TYPE_DISK
|
||||
Pipe = 0x02, // SMB2_SHARE_TYPE_PIPE
|
||||
Print = 0x03, // SMB2_SHARE_TYPE_PRINT
|
||||
}
|
||||
}
|
10
SMBLibrary/SMB2/Enums/Write/WriteFlags.cs
Normal file
10
SMBLibrary/SMB2/Enums/Write/WriteFlags.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public enum WriteFlags : uint
|
||||
{
|
||||
WriteThrough = 0x00000001, // SMB2_WRITEFLAG_WRITE_THROUGH
|
||||
Unbuffered = 0x00000002, // SMB2_WRITEFLAG_WRITE_UNBUFFERED
|
||||
}
|
||||
}
|
141
SMBLibrary/SMB2/SMB2Header.cs
Normal file
141
SMBLibrary/SMB2/SMB2Header.cs
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public class SMB2Header
|
||||
{
|
||||
public const int Length = 64;
|
||||
public static readonly byte[] ProtocolSignature = new byte[] { 0xFE, 0x53, 0x4D, 0x42 };
|
||||
|
||||
public byte[] ProtocolId; // 4 bytes, 0xFE followed by "SMB"
|
||||
public ushort StructureSize;
|
||||
public ushort CreditCharge;
|
||||
public NTStatus Status;
|
||||
public SMB2CommandName Command;
|
||||
public ushort Credits; // CreditRequest or CreditResponse (The number of credits granted to the client)
|
||||
public SMB2PacketHeaderFlags Flags;
|
||||
public uint NextCommand; // offset in bytes
|
||||
public ulong MessageID;
|
||||
public uint Reserved; // Sync
|
||||
public uint TreeID; // Sync
|
||||
public ulong AsyncID; // Async
|
||||
public ulong SessionID;
|
||||
public byte[] Signature; // 16 bytes (present if SMB2_FLAGS_SIGNED is set)
|
||||
|
||||
public SMB2Header(SMB2CommandName commandName)
|
||||
{
|
||||
ProtocolId = ProtocolSignature;
|
||||
StructureSize = Length;
|
||||
Command = commandName;
|
||||
}
|
||||
|
||||
public SMB2Header(byte[] buffer, int offset)
|
||||
{
|
||||
ProtocolId = ByteReader.ReadBytes(buffer, offset + 0, 4);
|
||||
StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + 4);
|
||||
CreditCharge = LittleEndianConverter.ToUInt16(buffer, offset + 6);
|
||||
Status = (NTStatus)LittleEndianConverter.ToUInt32(buffer, offset + 8);
|
||||
Command = (SMB2CommandName)LittleEndianConverter.ToUInt16(buffer, offset + 12);
|
||||
Credits = LittleEndianConverter.ToUInt16(buffer, offset + 14);
|
||||
Flags = (SMB2PacketHeaderFlags)LittleEndianConverter.ToUInt32(buffer, offset + 16);
|
||||
NextCommand = LittleEndianConverter.ToUInt32(buffer, offset + 20);
|
||||
MessageID = LittleEndianConverter.ToUInt64(buffer, offset + 24);
|
||||
if ((Flags & SMB2PacketHeaderFlags.AsyncCommand) > 0)
|
||||
{
|
||||
AsyncID = LittleEndianConverter.ToUInt64(buffer, offset + 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
Reserved = LittleEndianConverter.ToUInt32(buffer, offset + 32);
|
||||
TreeID = LittleEndianConverter.ToUInt32(buffer, offset + 36);
|
||||
}
|
||||
SessionID = LittleEndianConverter.ToUInt64(buffer, offset + 40);
|
||||
if ((Flags & SMB2PacketHeaderFlags.Signed) > 0)
|
||||
{
|
||||
Signature = ByteReader.ReadBytes(buffer, offset + 48, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] buffer, int offset)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + 0, ProtocolId);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 4, StructureSize);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 6, CreditCharge);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 8, (uint)Status);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 12, (ushort)Command);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 14, Credits);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 16, (uint)Flags);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 20, NextCommand);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 24, MessageID);
|
||||
if ((Flags & SMB2PacketHeaderFlags.AsyncCommand) > 0)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 32, AsyncID);
|
||||
}
|
||||
else
|
||||
{
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 32, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 36, TreeID);
|
||||
}
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 40, SessionID);
|
||||
if ((Flags & SMB2PacketHeaderFlags.Signed) > 0)
|
||||
{
|
||||
ByteWriter.WriteBytes(buffer, offset + 48, Signature);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsResponse
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Flags & SMB2PacketHeaderFlags.ServerToRedir) > 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Flags |= SMB2PacketHeaderFlags.ServerToRedir;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags &= ~SMB2PacketHeaderFlags.ServerToRedir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRelatedOperations
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Flags & SMB2PacketHeaderFlags.RelatedOperations) > 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Flags |= SMB2PacketHeaderFlags.RelatedOperations;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags &= ~SMB2PacketHeaderFlags.RelatedOperations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsValidSMB2Header(byte[] buffer)
|
||||
{
|
||||
if (buffer.Length >= 4)
|
||||
{
|
||||
byte[] signature = ByteReader.ReadBytes(buffer, 0, 4);
|
||||
return ByteUtils.AreByteArraysEqual(signature, ProtocolSignature);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
150
SMBLibrary/SMB2/Structures/CreateContext.cs
Normal file
150
SMBLibrary/SMB2/Structures/CreateContext.cs
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// [MS-SMB2] 2.2.13.2 - SMB2_CREATE_CONTEXT
|
||||
/// </summary>
|
||||
public class CreateContext
|
||||
{
|
||||
public int FixedLength = 16;
|
||||
|
||||
/// <summary>
|
||||
/// The offset from the beginning of this Create Context to the beginning of a subsequent 8-byte aligned Create Context.
|
||||
/// This field MUST be set to 0 if there are no subsequent contexts.
|
||||
/// </summary>
|
||||
public uint Next;
|
||||
private ushort NameOffset; // The offset from the beginning of this structure to the 8-byte aligned name value
|
||||
private ushort NameLength;
|
||||
public ushort Reserved;
|
||||
private ushort DataOffset; // The offset from the beginning of this structure to the 8-byte aligned data payload
|
||||
private uint DataLength;
|
||||
public string Name = String.Empty;
|
||||
public byte[] Data = new byte[0];
|
||||
|
||||
public CreateContext()
|
||||
{
|
||||
}
|
||||
|
||||
public CreateContext(byte[] buffer, int offset)
|
||||
{
|
||||
Next = LittleEndianConverter.ToUInt32(buffer, offset + 0);
|
||||
NameOffset = LittleEndianConverter.ToUInt16(buffer, offset + 4);
|
||||
NameLength = LittleEndianConverter.ToUInt16(buffer, offset + 6);
|
||||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + 8);
|
||||
DataOffset = LittleEndianConverter.ToUInt16(buffer, offset + 10);
|
||||
DataLength = LittleEndianConverter.ToUInt32(buffer, offset + 12);
|
||||
if (NameLength > 0)
|
||||
{
|
||||
Name = ByteReader.ReadUTF16String(buffer, offset + NameOffset, NameLength / 2);
|
||||
}
|
||||
if (DataLength > 0)
|
||||
{
|
||||
Data = ByteReader.ReadBytes(buffer, offset + DataOffset, (int)DataLength);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 0, Next);
|
||||
NameOffset = 0;
|
||||
NameLength = (ushort)(Name.Length * 2);
|
||||
if (Name.Length > 0)
|
||||
{
|
||||
NameOffset = (ushort)FixedLength;
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 4, NameOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 6, NameLength);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 8, Reserved);
|
||||
DataOffset = 0;
|
||||
DataLength = (uint)Data.Length;
|
||||
if (Data.Length > 0)
|
||||
{
|
||||
int paddedNameLength = (int)Math.Ceiling((double)(Name.Length * 2) / 8) * 8;
|
||||
DataOffset = (ushort)(FixedLength + paddedNameLength);
|
||||
}
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 10, DataOffset);
|
||||
ByteWriter.WriteUTF16String(buffer, NameOffset, Name);
|
||||
ByteWriter.WriteBytes(buffer, DataOffset, Data);
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Data.Length > 0)
|
||||
{
|
||||
int paddedNameLength = (int)Math.Ceiling((double)(Name.Length * 2) / 8) * 8;
|
||||
return FixedLength + paddedNameLength + Data.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FixedLength + Name.Length * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<CreateContext> ReadCreateContextList(byte[] buffer, int offset)
|
||||
{
|
||||
List<CreateContext> result = new List<CreateContext>();
|
||||
CreateContext createContext;
|
||||
do
|
||||
{
|
||||
createContext = new CreateContext(buffer, offset);
|
||||
result.Add(createContext);
|
||||
offset += (int)createContext.Next;
|
||||
}
|
||||
while (createContext.Next != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void WriteCreateContextList(byte[] buffer, int offset, List<CreateContext> createContexts)
|
||||
{
|
||||
for (int index = 0; index < createContexts.Count; index++)
|
||||
{
|
||||
CreateContext createContext = createContexts[index];
|
||||
int length = createContext.Length;
|
||||
int paddedLength = (int)Math.Ceiling((double)length / 8) * 8;
|
||||
if (index < createContexts.Count - 1)
|
||||
{
|
||||
createContext.Next = (uint)paddedLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
createContext.Next = 0;
|
||||
}
|
||||
createContext.WriteBytes(buffer, offset);
|
||||
offset += paddedLength;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetCreateContextListLength(List<CreateContext> createContexts)
|
||||
{
|
||||
int result = 0;
|
||||
for(int index = 0; index < createContexts.Count; index++)
|
||||
{
|
||||
CreateContext createContext = createContexts[index];
|
||||
int length = createContext.Length;
|
||||
if (index < createContexts.Count - 1)
|
||||
{
|
||||
int paddedLength = (int)Math.Ceiling((double)length / 8) * 8;
|
||||
result += paddedLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += length;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
13
SMBLibrary/SMB2/Structures/Enums/LockFlags.cs
Normal file
13
SMBLibrary/SMB2/Structures/Enums/LockFlags.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
[Flags]
|
||||
public enum LockFlags : uint
|
||||
{
|
||||
SharedLock = 0x00000001, // SMB2_LOCKFLAG_SHARED_LOCK
|
||||
ExclusiveLock = 0x00000002, // SMB2_LOCKFLAG_EXCLUSIVE_LOCK
|
||||
Unlock = 0x00000004, // SMB2_LOCKFLAG_UNLOCK
|
||||
FailImmediately = 0x00000008, // SMB2_LOCKFLAG_FAIL_IMMEDIATELY
|
||||
}
|
||||
}
|
34
SMBLibrary/SMB2/Structures/FileID.cs
Normal file
34
SMBLibrary/SMB2/Structures/FileID.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// [MS-SMB2] 2.2.14.1 - SMB2_FILEID
|
||||
/// </summary>
|
||||
public struct FileID
|
||||
{
|
||||
public const int Length = 16;
|
||||
|
||||
public ulong Persistent;
|
||||
public ulong Volatile;
|
||||
|
||||
public FileID(byte[] buffer, int offset)
|
||||
{
|
||||
Persistent = LittleEndianConverter.ToUInt64(buffer, offset + 0);
|
||||
Volatile = LittleEndianConverter.ToUInt64(buffer, offset + 8);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 0, Persistent);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 8, Volatile);
|
||||
}
|
||||
}
|
||||
}
|
58
SMBLibrary/SMB2/Structures/LockElement.cs
Normal file
58
SMBLibrary/SMB2/Structures/LockElement.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
public struct LockElement
|
||||
{
|
||||
public const int StructureLength = 24;
|
||||
|
||||
public ulong Offset;
|
||||
public ulong Length;
|
||||
public LockFlags Flags;
|
||||
public uint Reserved;
|
||||
|
||||
public LockElement(byte[] buffer, int offset)
|
||||
{
|
||||
Offset = LittleEndianConverter.ToUInt64(buffer, offset + 0);
|
||||
Length = LittleEndianConverter.ToUInt64(buffer, offset + 8);
|
||||
Flags = (LockFlags)LittleEndianConverter.ToUInt32(buffer, offset + 16);
|
||||
Reserved = LittleEndianConverter.ToUInt32(buffer, offset + 20);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] buffer, int offset)
|
||||
{
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 0, Offset);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 8, Length);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 16, (uint)Flags);
|
||||
LittleEndianWriter.WriteUInt64(buffer, offset + 20, Reserved);
|
||||
}
|
||||
|
||||
public static List<LockElement> ReadLockList(byte[] buffer, int offset, int lockCount)
|
||||
{
|
||||
List<LockElement> result = new List<LockElement>();
|
||||
for(int lockIndex = 0; lockIndex > lockCount; lockIndex++)
|
||||
{
|
||||
LockElement element = new LockElement(buffer, offset + lockIndex * StructureLength);
|
||||
result.Add(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void WriteLockList(byte[] buffer, int offset, List<LockElement> locks)
|
||||
{
|
||||
for (int lockIndex = 0; lockIndex > locks.Count; lockIndex++)
|
||||
{
|
||||
LockElement element = locks[lockIndex];
|
||||
element.WriteBytes(buffer, offset + lockIndex * StructureLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
99
SMBLibrary/SMB2/Structures/NegotiateContext.cs
Normal file
99
SMBLibrary/SMB2/Structures/NegotiateContext.cs
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
namespace SMBLibrary.SMB2
|
||||
{
|
||||
/// <summary>
|
||||
/// [MS-SMB2] 2.2.3.1 - NEGOTIATE_CONTEXT
|
||||
/// </summary>
|
||||
public class NegotiateContext
|
||||
{
|
||||
public const int FixedLength = 8;
|
||||
|
||||
public NegotiateContextType ContextType;
|
||||
private ushort DataLength;
|
||||
public uint Reserved;
|
||||
public byte[] Data = new byte[0];
|
||||
|
||||
public NegotiateContext()
|
||||
{
|
||||
}
|
||||
|
||||
public NegotiateContext(byte[] buffer, int offset)
|
||||
{
|
||||
ContextType = (NegotiateContextType)LittleEndianConverter.ToUInt16(buffer, offset + 0);
|
||||
DataLength = LittleEndianConverter.ToUInt16(buffer, offset + 2);
|
||||
Reserved = LittleEndianConverter.ToUInt32(buffer, offset + 4);
|
||||
ByteReader.ReadBytes(buffer, offset + 8, DataLength);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] buffer, int offset)
|
||||
{
|
||||
DataLength = (ushort)Data.Length;
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 0, (ushort)ContextType);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, DataLength);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, Reserved);
|
||||
ByteWriter.WriteBytes(buffer, offset + 8, Data);
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return FixedLength + Data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<NegotiateContext> ReadNegotiateContextList(byte[] buffer, int offset, int count)
|
||||
{
|
||||
List<NegotiateContext> result = new List<NegotiateContext>();
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
NegotiateContext context = new NegotiateContext(buffer, offset);
|
||||
result.Add(context);
|
||||
offset += context.Length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void WriteNegotiateContextList(byte[] buffer, int offset, List<NegotiateContext> negotiateContextList)
|
||||
{
|
||||
// Subsequent negotiate contexts MUST appear at the first 8-byte aligned offset following the previous negotiate context
|
||||
for (int index = 0; index < negotiateContextList.Count; index++)
|
||||
{
|
||||
NegotiateContext context = negotiateContextList[index];
|
||||
int length = context.Length;
|
||||
int paddedLength = (int)Math.Ceiling((double)length / 8) * 8;
|
||||
context.WriteBytes(buffer, offset);
|
||||
offset += paddedLength;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetNegotiateContextListLength(List<NegotiateContext> negotiateContextList)
|
||||
{
|
||||
int result = 0;
|
||||
for (int index = 0; index < negotiateContextList.Count; index++)
|
||||
{
|
||||
NegotiateContext context = negotiateContextList[index];
|
||||
int length = context.Length;
|
||||
if (index < negotiateContextList.Count - 1)
|
||||
{
|
||||
int paddedLength = (int)Math.Ceiling((double)length / 8) * 8;
|
||||
result += paddedLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += length;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -398,6 +398,72 @@
|
|||
<Compile Include="SMB1\TransactionSubcommands\TransactionWriteNamedPipeRequest.cs" />
|
||||
<Compile Include="SMB1\TransactionSubcommands\TransactionWriteNamedPipeResponse.cs" />
|
||||
<Compile Include="SMB1\UTimeHelper.cs" />
|
||||
<Compile Include="SMB2\Commands\CancelRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\ChangeNotifyRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\ChangeNotifyResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\CloseRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\CloseResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\CreateRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\CreateResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\EchoRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\EchoResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\ErrorResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\FlushRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\FlushResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\IOCtlRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\IOCtlResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\LockRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\LockResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\LogoffRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\LogoffResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\NegotiateRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\NegotiateResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\QueryDirectoryRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\QueryDirectoryResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\QueryInfoRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\QueryInfoResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\ReadRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\ReadResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\SessionSetupRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\SessionSetupResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\SetInfoRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\SetInfoResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\SMB2Command.cs" />
|
||||
<Compile Include="SMB2\Commands\TreeConnectRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\TreeConnectResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\TreeDisconnectRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\TreeDisconnectResponse.cs" />
|
||||
<Compile Include="SMB2\Commands\WriteRequest.cs" />
|
||||
<Compile Include="SMB2\Commands\WriteResponse.cs" />
|
||||
<Compile Include="SMB2\Enums\ChangeNotify\ChangeNotifyFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\ChangeNotify\NotifyChange.cs" />
|
||||
<Compile Include="SMB2\Enums\Close\CloseFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\Create\CreateAction.cs" />
|
||||
<Compile Include="SMB2\Enums\Create\CreateResponseFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\Create\ImpersonationLevel.cs" />
|
||||
<Compile Include="SMB2\Enums\Create\OplockLevel.cs" />
|
||||
<Compile Include="SMB2\Enums\InfoType.cs" />
|
||||
<Compile Include="SMB2\Enums\IOCtl\IOCtlRequestFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\Negotiate\NegotiateContextType.cs" />
|
||||
<Compile Include="SMB2\Enums\Negotiate\SecurityMode.cs" />
|
||||
<Compile Include="SMB2\Enums\Negotiate\ServerCapabilities.cs" />
|
||||
<Compile Include="SMB2\Enums\Negotiate\SMB2Dialect.cs" />
|
||||
<Compile Include="SMB2\Enums\QueryDirectory\QueryDirectoryFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\Read\ReadFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\SessionSetup\SessionFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\SessionSetup\SessionSetupFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\SMB2CommandName.cs" />
|
||||
<Compile Include="SMB2\Enums\SMB2PacketHeaderFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\TreeConnect\ShareCapabilities.cs" />
|
||||
<Compile Include="SMB2\Enums\TreeConnect\ShareFlags.cs" />
|
||||
<Compile Include="SMB2\Enums\TreeConnect\ShareType.cs" />
|
||||
<Compile Include="SMB2\Enums\Write\WriteFlags.cs" />
|
||||
<Compile Include="SMB2\SMB2Header.cs" />
|
||||
<Compile Include="SMB2\Structures\CreateContext.cs" />
|
||||
<Compile Include="SMB2\Structures\Enums\LockFlags.cs" />
|
||||
<Compile Include="SMB2\Structures\FileID.cs" />
|
||||
<Compile Include="SMB2\Structures\LockElement.cs" />
|
||||
<Compile Include="SMB2\Structures\NegotiateContext.cs" />
|
||||
<Compile Include="Structures\ACE\AccessAllowedACE.cs" />
|
||||
<Compile Include="Structures\ACE\ACE.cs" />
|
||||
<Compile Include="Structures\ACE\AceHeader.cs" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue