diff --git a/SMBLibrary/Authentication/AuthenticateMessage/AVPairUtils.cs b/SMBLibrary/Authentication/AuthenticateMessage/AVPairUtils.cs
new file mode 100644
index 0000000..12d4396
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/AVPairUtils.cs
@@ -0,0 +1,74 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ public class AVPairUtils
+ {
+ public static byte[] GetAVPairSequence(string domainName, string computerName)
+ {
+ KeyValuePairList pairs = new KeyValuePairList();
+ pairs.Add(AVPairKey.NbDomainName, UnicodeEncoding.Unicode.GetBytes(domainName));
+ pairs.Add(AVPairKey.NbComputerName, UnicodeEncoding.Unicode.GetBytes(computerName));
+ return AVPairUtils.GetAVPairSequenceBytes(pairs);
+ }
+
+ public static byte[] GetAVPairSequenceBytes(KeyValuePairList pairs)
+ {
+ int length = 0;
+ foreach (KeyValuePair pair in pairs)
+ {
+ length += 4 + pair.Value.Length;
+ }
+ length += 4;
+
+ byte[] result = new byte[length];
+ int offset = 0;
+ foreach (KeyValuePair pair in pairs)
+ {
+ WriteAVPair(result, ref offset, pair.Key, pair.Value);
+ }
+ LittleEndianWriter.WriteUInt16(result, ref offset, (ushort)AVPairKey.EOL);
+ LittleEndianWriter.WriteUInt16(result, ref offset, 0);
+
+ return result;
+ }
+
+ public static void WriteAVPair(byte[] buffer, ref int offset, AVPairKey key, byte[] value)
+ {
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)key);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)value.Length);
+ ByteWriter.WriteBytes(buffer, ref offset, value);
+ }
+
+ public static KeyValuePairList ReadAVPairSequence(byte[] buffer, int offset)
+ {
+ KeyValuePairList result = new KeyValuePairList();
+ AVPairKey key = (AVPairKey)LittleEndianConverter.ToUInt16(buffer, offset);
+ while (key != AVPairKey.EOL)
+ {
+ KeyValuePair pair = ReadAVPair(buffer, ref offset);
+ result.Add(pair);
+ key = (AVPairKey)LittleEndianConverter.ToUInt16(buffer, offset);
+ }
+
+ return result;
+ }
+
+ public static KeyValuePair ReadAVPair(byte[] buffer, ref int offset)
+ {
+ AVPairKey key = (AVPairKey)LittleEndianReader.ReadUInt16(buffer, ref offset);
+ ushort length = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ byte[] value = ByteReader.ReadBytes(buffer, ref offset, length);
+ return new KeyValuePair(key, value);
+ }
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/AuthenticateMessage.cs b/SMBLibrary/Authentication/AuthenticateMessage/AuthenticateMessage.cs
new file mode 100644
index 0000000..79e50a9
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/AuthenticateMessage.cs
@@ -0,0 +1,94 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ ///
+ /// [MS-NLMP] AUTHENTICATE_MESSAGE (Type 3 Message)
+ ///
+ public class AuthenticateMessage
+ {
+ public string Signature; // 8 bytes
+ public MessageTypeName MessageType;
+ public byte[] LmChallengeResponse;
+ public byte[] NtChallengeResponse;
+ public string DomainName;
+ public string UserName;
+ public string WorkStation;
+ public byte[] EncryptedRandomSessionKey;
+ public NegotiateFlags NegotiateFlags;
+ public Version Version;
+ // 16-byte MIC field is omitted for Windows NT / 2000 / XP / Server 2003
+
+ public AuthenticateMessage()
+ {
+ Signature = AuthenticationMessageUtils.ValidSignature;
+ MessageType = MessageTypeName.Authenticate;
+ DomainName = String.Empty;
+ UserName = String.Empty;
+ WorkStation = String.Empty;
+ EncryptedRandomSessionKey = new byte[0];
+ }
+
+ public AuthenticateMessage(byte[] buffer)
+ {
+ Signature = ByteReader.ReadAnsiString(buffer, 0, 8);
+ MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
+ LmChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 12);
+ NtChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 20);
+ DomainName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 28);
+ UserName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 36);
+ WorkStation = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 44);
+ EncryptedRandomSessionKey = AuthenticationMessageUtils.ReadBufferPointer(buffer, 52);
+ NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 60);
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ Version = new Version(buffer, 64);
+ }
+ }
+
+ public byte[] GetBytes()
+ {
+ int fixedLength = 64;
+
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ fixedLength += 8;
+ }
+
+ int payloadLength = LmChallengeResponse.Length + NtChallengeResponse.Length + DomainName.Length * 2 + UserName.Length * 2 + WorkStation.Length * 2 + EncryptedRandomSessionKey.Length;
+ byte[] buffer = new byte[fixedLength + payloadLength];
+ ByteWriter.WriteAnsiString(buffer, 0, AuthenticationMessageUtils.ValidSignature, 8);
+ LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType);
+ LittleEndianWriter.WriteUInt32(buffer, 60, (uint)NegotiateFlags);
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ Version.WriteBytes(buffer, 64);
+ }
+
+ int offset = fixedLength;
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)LmChallengeResponse.Length, (uint)offset);
+ ByteWriter.WriteBytes(buffer, ref offset, LmChallengeResponse);
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 20, (ushort)NtChallengeResponse.Length, (uint)offset);
+ ByteWriter.WriteBytes(buffer, ref offset, NtChallengeResponse);
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 28, (ushort)(DomainName.Length * 2), (uint)offset);
+ ByteWriter.WriteUTF16String(buffer, ref offset, DomainName);
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 36, (ushort)(UserName.Length * 2), (uint)offset);
+ ByteWriter.WriteUTF16String(buffer, ref offset, UserName);
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 44, (ushort)(WorkStation.Length * 2), (uint)offset);
+ ByteWriter.WriteUTF16String(buffer, ref offset, WorkStation);
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 52, (ushort)EncryptedRandomSessionKey.Length, (uint)offset);
+ ByteWriter.WriteBytes(buffer, ref offset, EncryptedRandomSessionKey);
+
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/AuthenticationMessageUtils.cs b/SMBLibrary/Authentication/AuthenticateMessage/AuthenticationMessageUtils.cs
new file mode 100644
index 0000000..78b6385
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/AuthenticationMessageUtils.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ public class AuthenticationMessageUtils
+ {
+ public const string ValidSignature = "NTLMSSP\0";
+
+ public static string ReadAnsiStringBufferPointer(byte[] buffer, int offset)
+ {
+ byte[] bytes = ReadBufferPointer(buffer, offset);
+ return ASCIIEncoding.Default.GetString(bytes);
+ }
+
+ public static string ReadUnicodeStringBufferPointer(byte[] buffer, int offset)
+ {
+ byte[] bytes = ReadBufferPointer(buffer, offset);
+ return UnicodeEncoding.Unicode.GetString(bytes);
+ }
+
+ public static byte[] ReadBufferPointer(byte[] buffer, int offset)
+ {
+ ushort length = LittleEndianConverter.ToUInt16(buffer, offset);
+ ushort maxLength = LittleEndianConverter.ToUInt16(buffer, offset + 2);
+ uint bufferOffset = LittleEndianConverter.ToUInt32(buffer, offset + 4);
+
+ if (length == 0)
+ {
+ return new byte[0];
+ }
+ else
+ {
+ return ByteReader.ReadBytes(buffer, (int)bufferOffset, length);
+ }
+ }
+
+ public static void WriteBufferPointer(byte[] buffer, int offset, ushort bufferLength, uint bufferOffset)
+ {
+ LittleEndianWriter.WriteUInt16(buffer, offset, bufferLength);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 2, bufferLength);
+ LittleEndianWriter.WriteUInt32(buffer, offset + 4, bufferOffset);
+ }
+
+ public static bool IsSignatureValid(byte[] messageBytes)
+ {
+ string signature = ByteReader.ReadAnsiString(messageBytes, 0, 8);
+ return (signature == ValidSignature);
+ }
+
+ public static MessageTypeName GetMessageType(byte[] messageBytes)
+ {
+ return (MessageTypeName)LittleEndianConverter.ToUInt32(messageBytes, 8);
+ }
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/ChallengeMessage.cs b/SMBLibrary/Authentication/AuthenticateMessage/ChallengeMessage.cs
new file mode 100644
index 0000000..31797e3
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/ChallengeMessage.cs
@@ -0,0 +1,77 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ ///
+ /// [MS-NLMP] CHALLENGE_MESSAGE (Type 2 Message)
+ ///
+ public class ChallengeMessage
+ {
+ public string Signature; // 8 bytes
+ public MessageTypeName MessageType;
+ public string TargetName;
+ public NegotiateFlags NegotiateFlags;
+ public byte[] ServerChallenge; // 8 bytes
+ // Reserved - 8 bytes
+ public byte[] TargetInfo; // sequence of AV_PAIR structures
+ public Version Version;
+
+ public ChallengeMessage()
+ {
+ Signature = AuthenticationMessageUtils.ValidSignature;
+ MessageType = MessageTypeName.Challenge;
+ }
+
+ public ChallengeMessage(byte[] buffer)
+ {
+ Signature = ByteReader.ReadAnsiString(buffer, 0, 8);
+ MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
+ TargetName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 12);
+ NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 20);
+ ServerChallenge = ByteReader.ReadBytes(buffer, 24, 8);
+ // Reserved
+ TargetInfo = AuthenticationMessageUtils.ReadBufferPointer(buffer, 40);
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ Version = new Version(buffer, 48);
+ }
+ }
+
+ public byte[] GetBytes()
+ {
+ int fixedLength = 48;
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ fixedLength += 8;
+ }
+
+ int payloadLength = TargetName.Length * 2 + TargetInfo.Length;
+ byte[] buffer = new byte[fixedLength + payloadLength];
+ ByteWriter.WriteAnsiString(buffer, 0, AuthenticationMessageUtils.ValidSignature, 8);
+ LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType);
+ LittleEndianWriter.WriteUInt32(buffer, 20, (uint)NegotiateFlags);
+ ByteWriter.WriteBytes(buffer, 24, ServerChallenge);
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ Version.WriteBytes(buffer, 48);
+ }
+
+ int offset = fixedLength;
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)(TargetName.Length * 2), (uint)offset);
+ ByteWriter.WriteUTF16String(buffer, ref offset, TargetName);
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 40, (ushort)TargetInfo.Length, (uint)offset);
+ ByteWriter.WriteBytes(buffer, ref offset, TargetInfo);
+
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/Enums/AVPairKey.cs b/SMBLibrary/Authentication/AuthenticateMessage/Enums/AVPairKey.cs
new file mode 100644
index 0000000..3fede6a
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/Enums/AVPairKey.cs
@@ -0,0 +1,18 @@
+
+namespace SMBLibrary.Authentication
+{
+ public enum AVPairKey : ushort
+ {
+ EOL = 0x0000,
+ NbComputerName = 0x0001, // Unicode
+ NbDomainName = 0x0002, // Unicode
+ DnsComputerName = 0x0003, // Unicode
+ DnsDomainName = 0x0004, // Unicode
+ DnsTreeName = 0x0005, // Unicode
+ Flags = 0x0006, // UInt32
+ Timestamp = 0x0006, // Filetime
+ SingleHost = 0x0008, // platform-specific BLOB
+ TargetName = 0x0009, // Unicode
+ ChannelBindings = 0x000A, // MD5 Hash
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/Enums/MessageTypeName.cs b/SMBLibrary/Authentication/AuthenticateMessage/Enums/MessageTypeName.cs
new file mode 100644
index 0000000..f75dcae
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/Enums/MessageTypeName.cs
@@ -0,0 +1,10 @@
+
+namespace SMBLibrary.Authentication
+{
+ public enum MessageTypeName : uint
+ {
+ Negotiate = 0x01,
+ Challenge = 0x02,
+ Authenticate = 0x03,
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/Enums/NegotiateFlags.cs b/SMBLibrary/Authentication/AuthenticateMessage/Enums/NegotiateFlags.cs
new file mode 100644
index 0000000..38cd8bf
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/Enums/NegotiateFlags.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace SMBLibrary.Authentication
+{
+ [Flags]
+ public enum NegotiateFlags : uint
+ {
+ NegotiateUnicode = 0x01, // NTLMSSP_NEGOTIATE_UNICODE
+ NegotiateOEM = 0x02, // NTLM_NEGOTIATE_OEM
+ RequestTarget = 0x04, // NTLMSSP_REQUEST_TARGET
+ NegotiateSign = 0x10, // NTLMSSP_NEGOTIATE_SIGN
+ NegotiateSeal = 0x20, // NTLMSSP_NEGOTIATE_SEAL
+ NegotiateDatagram = 0x40, // NTLMSSP_NEGOTIATE_DATAGRAM
+
+ ///
+ /// NegotiateLanManagerKey and NegotiateExtendedSecurity are mutually exclusive
+ /// If both are set then NegotiateLanManagerKey must be ignored
+ ///
+ NegotiateLanManagerKey = 0x80, // NTLMSSP_NEGOTIATE_LM_KEY
+ NegotiateNTLMKey = 0x200, // NTLMSSP_NEGOTIATE_NTLM
+ //NegotiateNTOnly = 0x400, // Unused, must be clear
+
+ ///
+ /// If set, the connection SHOULD be anonymous
+ ///
+ NegotiateAnonymous = 0x800,
+
+ NegotiateOEMDomainSupplied = 0x1000, // NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED
+ NegotiateOEMWorkstationSupplied = 0x2000, // NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED
+ NegotiateAlwaysSign = 0x8000, // NTLMSSP_NEGOTIATE_ALWAYS_SIGN
+ NegotiateTargetTypeDomain = 0x10000, // NTLMSSP_TARGET_TYPE_DOMAIN
+ NegotiateTargetTypeServer = 0x20000, // NTLMSSP_TARGET_TYPE_SERVER
+ NegotiateTargetTypeShare = 0x40000, // Unused, must be clear
+
+ ///
+ /// NegotiateLanManagerKey and NegotiateExtendedSecurity are mutually exclusive
+ /// If both are set then NegotiateLanManagerKey must be ignored
+ ///
+ NegotiateExtendedSecurity = 0x80000, // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
+ NegotiateIdentify = 0x100000, // NTLMSSP_NEGOTIATE_IDENTIFY
+ RequestNonNTSession = 0x400000, // NTLMSSP_REQUEST_NON_NT_SESSION_KEY
+ NegotiateTargetInfo = 0x800000, // NTLMSSP_NEGOTIATE_TARGET_INFO
+ NegotiateVersion = 0x2000000, // NTLMSSP_NEGOTIATE_VERSION
+ Negotiate128 = 0x20000000, // NTLMSSP_NEGOTIATE_128
+ NegotiateKeyExchange = 0x40000000, // NTLMSSP_NEGOTIATE_KEY_EXCH
+ Negotiate56 = 0x80000000, // NTLMSSP_NEGOTIATE_56
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/NTLMv2ClientChallenge.cs b/SMBLibrary/Authentication/AuthenticateMessage/NTLMv2ClientChallenge.cs
new file mode 100644
index 0000000..8f4daa2
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/NTLMv2ClientChallenge.cs
@@ -0,0 +1,79 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ ///
+ /// NTLMv2_CLIENT_CHALLENGE
+ ///
+ public class NTLMv2ClientChallengeStructure
+ {
+ public static readonly DateTime EpochTime = DateTime.FromFileTimeUtc(0);
+
+ public byte ResponseVersion;
+ public byte ResponseVersionHigh;
+ public DateTime Time;
+ public byte[] ClientChallenge;
+ public KeyValuePairList AVPairs;
+
+ public NTLMv2ClientChallengeStructure()
+ {
+ }
+
+ public NTLMv2ClientChallengeStructure(DateTime time, byte[] clientChallenge, string domainName, string computerName)
+ {
+ ResponseVersion = 1;
+ ResponseVersionHigh = 1;
+ Time = time;
+ ClientChallenge = clientChallenge;
+ AVPairs = new KeyValuePairList();
+ AVPairs.Add(AVPairKey.NbDomainName, UnicodeEncoding.Unicode.GetBytes(domainName));
+ AVPairs.Add(AVPairKey.NbComputerName, UnicodeEncoding.Unicode.GetBytes(computerName));
+ }
+
+ public NTLMv2ClientChallengeStructure(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public NTLMv2ClientChallengeStructure(byte[] buffer, int offset)
+ {
+ ResponseVersion = ByteReader.ReadByte(buffer, offset + 0);
+ ResponseVersionHigh = ByteReader.ReadByte(buffer, offset + 1);
+ long temp = LittleEndianConverter.ToInt64(buffer, offset + 8);
+ Time = DateTime.FromFileTimeUtc(temp);
+ ClientChallenge = ByteReader.ReadBytes(buffer, offset + 16, 8);
+ AVPairs = AVPairUtils.ReadAVPairSequence(buffer, offset + 28);
+ }
+
+ public byte[] GetBytes()
+ {
+ byte[] sequenceBytes = AVPairUtils.GetAVPairSequenceBytes(AVPairs);
+ byte[] timeBytes = LittleEndianConverter.GetBytes((ulong)Time.ToFileTimeUtc());
+
+ byte[] buffer = new byte[28 + sequenceBytes.Length];
+ ByteWriter.WriteByte(buffer, 0, ResponseVersion);
+ ByteWriter.WriteByte(buffer, 1, ResponseVersionHigh);
+ ByteWriter.WriteBytes(buffer, 8, timeBytes);
+ ByteWriter.WriteBytes(buffer, 16, ClientChallenge, 8);
+ ByteWriter.WriteBytes(buffer, 28, sequenceBytes);
+ return buffer;
+ }
+
+ ///
+ /// [MS-NLMP] Page 60, Response key calculation algorithm:
+ /// To create 'temp', 4 zero bytes will be appended to NTLMv2_CLIENT_CHALLENGE
+ ///
+ public byte[] GetBytesPadded()
+ {
+ return ByteUtils.Concatenate(GetBytes(), new byte[4]);
+ }
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/NegotiateMessage.cs b/SMBLibrary/Authentication/AuthenticateMessage/NegotiateMessage.cs
new file mode 100644
index 0000000..10f58ad
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/NegotiateMessage.cs
@@ -0,0 +1,74 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ ///
+ /// [MS-NLMP] NEGOTIATE_MESSAGE (Type 1 Message)
+ ///
+ public class NegotiateMessage
+ {
+ public string Signature; // 8 bytes
+ public MessageTypeName MessageType;
+ public NegotiateFlags NegotiateFlags;
+ public string DomainName;
+ public string Workstation;
+ public Version Version;
+
+ public NegotiateMessage()
+ {
+ Signature = AuthenticationMessageUtils.ValidSignature;
+ MessageType = MessageTypeName.Negotiate;
+ DomainName = String.Empty;
+ Workstation = String.Empty;
+ }
+
+ public NegotiateMessage(byte[] buffer)
+ {
+ Signature = ByteReader.ReadAnsiString(buffer, 0, 8);
+ MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
+ NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 12);
+ DomainName = AuthenticationMessageUtils.ReadAnsiStringBufferPointer(buffer, 16);
+ Workstation = AuthenticationMessageUtils.ReadAnsiStringBufferPointer(buffer, 24);
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ Version = new Version(buffer, 32);
+ }
+ }
+
+ public byte[] GetBytes()
+ {
+ int fixedLength = 32;
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ fixedLength += 8;
+ }
+ int payloadLength = DomainName.Length * 2 + Workstation.Length * 2;
+ byte[] buffer = new byte[fixedLength + payloadLength];
+ ByteWriter.WriteAnsiString(buffer, 0, AuthenticationMessageUtils.ValidSignature, 8);
+ LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType);
+ LittleEndianWriter.WriteUInt32(buffer, 12, (uint)NegotiateFlags);
+
+ if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0)
+ {
+ Version.WriteBytes(buffer, 32);
+ }
+
+ int offset = fixedLength;
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 16, (ushort)(DomainName.Length * 2), (uint)offset);
+ ByteWriter.WriteUTF16String(buffer, ref offset, DomainName);
+ AuthenticationMessageUtils.WriteBufferPointer(buffer, 16, (ushort)(Workstation.Length * 2), (uint)offset);
+ ByteWriter.WriteUTF16String(buffer, ref offset, Workstation);
+
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/Authentication/AuthenticateMessage/Version.cs b/SMBLibrary/Authentication/AuthenticateMessage/Version.cs
new file mode 100644
index 0000000..c4e765e
--- /dev/null
+++ b/SMBLibrary/Authentication/AuthenticateMessage/Version.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ public class Version
+ {
+ public const byte NTLMSSP_REVISION_W2K3 = 0x0F;
+
+ public byte ProductMajorVersion;
+ public byte ProductMinorVersion;
+ public ushort ProductBuild;
+ // Reserved - 3 bytes
+ public byte NTLMRevisionCurrent;
+
+ public Version(byte majorVersion, byte minorVersion, ushort build, byte ntlmRevisionCurrent)
+ {
+ ProductMajorVersion = majorVersion;
+ ProductMinorVersion = minorVersion;
+ ProductBuild = build;
+ NTLMRevisionCurrent = ntlmRevisionCurrent;
+ }
+
+ public Version(byte[] buffer, int offset)
+ {
+ ProductMajorVersion = ByteReader.ReadByte(buffer, offset + 0);
+ ProductMinorVersion = ByteReader.ReadByte(buffer, offset + 1);
+ ProductBuild = LittleEndianConverter.ToUInt16(buffer, offset + 2);
+ NTLMRevisionCurrent = ByteReader.ReadByte(buffer, offset + 7);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ ByteWriter.WriteByte(buffer, offset + 0, ProductMajorVersion);
+ ByteWriter.WriteByte(buffer, offset + 1, ProductMinorVersion);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 2, ProductBuild);
+ ByteWriter.WriteByte(buffer, offset + 7, NTLMRevisionCurrent);
+ }
+
+ public static Version WindowsXP
+ {
+ get
+ {
+ return new Version(5, 1, 2600, NTLMSSP_REVISION_W2K3);
+ }
+ }
+
+ public static Version Server2003
+ {
+ get
+ {
+ return new Version(5, 2, 3790, NTLMSSP_REVISION_W2K3);
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/Authentication/MD4.cs b/SMBLibrary/Authentication/MD4.cs
new file mode 100644
index 0000000..64d8ec8
--- /dev/null
+++ b/SMBLibrary/Authentication/MD4.cs
@@ -0,0 +1,418 @@
+/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD4 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+
+ --------------------------------------------------------------
+
+ Ported from Norbert Hranitzky's (norbert.hranitzky@mchp.siemens.de)
+ Java version by Oren Novotny (osn@po.cwru.edu)
+
+ --------------------------------------------------------------
+ Adapted to C# 2.0 By Tal Aloni
+ --------------------------------------------------------------
+
+
+*/
+
+using System.Text;
+
+namespace System.Security.Cryptography
+{
+ using System;
+
+
+ ///
+ /// Implements the MD4 message digest algorithm in C#
+ ///
+ ///
+ ///
+ /// References:
+ ///
+ /// - Ronald L. Rivest,
+ /// "
+ /// The MD4 Message-Digest Algorithm",
+ /// IETF RFC-1320 (informational).
+ ///
+ ///
+ ///
+ ///
+ internal class MD4
+ {
+ // MD4 specific object variables
+ //-----------------------------------------------------------------------
+
+ ///
+ /// The size in bytes of the input block to the transformation algorithm
+ ///
+ private const int BLOCK_LENGTH = 64; // = 512 / 8
+
+ ///
+ /// 512-bit work buffer = 16 x 32-bit words
+ ///
+ private readonly uint[] X = new uint[16];
+
+ ///
+ /// 4 32-bit words (interim result)
+ ///
+ private readonly uint[] context = new uint[4];
+
+ ///
+ /// 512-bit input buffer = 16 x 32-bit words holds until it reaches 512 bits
+ ///
+ private byte[] buffer = new byte[BLOCK_LENGTH];
+
+ ///
+ /// Number of bytes procesed so far mod. 2 power of 64.
+ ///
+ private long count;
+
+
+ // Constructors
+ //------------------------------------------------------------------------
+ public MD4()
+ {
+ EngineReset();
+ }
+
+ ///
+ /// This constructor is here to implement the clonability of this class
+ ///
+ ///
+ private MD4(MD4 md)
+ : this()
+ {
+ //this();
+ context = (uint[])md.context.Clone();
+ buffer = (byte[])md.buffer.Clone();
+ count = md.count;
+ }
+
+ // Clonable method implementation
+ //-------------------------------------------------------------------------
+ public object Clone()
+ {
+ return new MD4(this);
+ }
+
+ // JCE methods
+ //-------------------------------------------------------------------------
+
+ ///
+ /// Resets this object disregarding any temporary data present at the
+ /// time of the invocation of this call.
+ ///
+ private void EngineReset()
+ {
+ // initial values of MD4 i.e. A, B, C, D
+ // as per rfc-1320; they are low-order byte first
+ context[0] = 0x67452301;
+ context[1] = 0xEFCDAB89;
+ context[2] = 0x98BADCFE;
+ context[3] = 0x10325476;
+ count = 0L;
+ for (int i = 0; i < BLOCK_LENGTH; i++)
+ buffer[i] = 0;
+ }
+
+
+ ///
+ /// Continues an MD4 message digest using the input byte
+ ///
+ /// byte to input
+ private void EngineUpdate(byte b)
+ {
+ // compute number of bytes still unhashed; ie. present in buffer
+ int i = (int)(count % BLOCK_LENGTH);
+ count++; // update number of bytes
+ buffer[i] = b;
+ if (i == BLOCK_LENGTH - 1)
+ Transform(ref buffer, 0);
+ }
+
+ ///
+ /// MD4 block update operation
+ ///
+ ///
+ /// Continues an MD4 message digest operation by filling the buffer,
+ /// transform(ing) data in 512-bit message block(s), updating the variables
+ /// context and count, and leaving (buffering) the remaining bytes in buffer
+ /// for the next update or finish.
+ ///
+ /// input block
+ /// start of meaningful bytes in input
+ /// count of bytes in input blcok to consider
+ private void EngineUpdate(byte[] input, int offset, int len)
+ {
+ // make sure we don't exceed input's allocated size/length
+ if (offset < 0 || len < 0 || (long)offset + len > input.Length)
+ throw new ArgumentOutOfRangeException();
+
+ // compute number of bytes still unhashed; ie. present in buffer
+ int bufferNdx = (int)(count % BLOCK_LENGTH);
+ count += len; // update number of bytes
+ int partLen = BLOCK_LENGTH - bufferNdx;
+ int i = 0;
+ if (len >= partLen)
+ {
+ Array.Copy(input, offset + i, buffer, bufferNdx, partLen);
+
+ Transform(ref buffer, 0);
+
+ for (i = partLen; i + BLOCK_LENGTH - 1 < len; i += BLOCK_LENGTH)
+ Transform(ref input, offset + i);
+ bufferNdx = 0;
+ }
+ // buffer remaining input
+ if (i < len)
+ Array.Copy(input, offset + i, buffer, bufferNdx, len - i);
+ }
+
+ ///
+ /// Completes the hash computation by performing final operations such
+ /// as padding. At the return of this engineDigest, the MD engine is
+ /// reset.
+ ///
+ /// the array of bytes for the resulting hash value.
+ private byte[] EngineDigest()
+ {
+ // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512
+ int bufferNdx = (int)(count % BLOCK_LENGTH);
+ int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx);
+
+ // padding is always binary 1 followed by binary 0's
+ byte[] tail = new byte[padLen + 8];
+ tail[0] = 0x80;
+
+ // append length before final transform
+ // save number of bits, casting the long to an array of 8 bytes
+ // save low-order byte first.
+ for (int i = 0; i < 8; i++)
+ tail[padLen + i] = (byte)((count * 8) >> (8 * i));
+
+ EngineUpdate(tail, 0, tail.Length);
+
+ byte[] result = new byte[16];
+ // cast this MD4's context (array of 4 uints) into an array of 16 bytes.
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ result[i * 4 + j] = (byte)(context[i] >> (8 * j));
+
+ // reset the engine
+ EngineReset();
+ return result;
+ }
+
+ ///
+ /// Returns a byte hash from a string
+ ///
+ /// string to hash
+ /// byte-array that contains the hash
+ public byte[] GetByteHashFromString(string s)
+ {
+ byte[] b = Encoding.UTF8.GetBytes(s);
+ MD4 md4 = new MD4();
+
+ md4.EngineUpdate(b, 0, b.Length);
+
+ return md4.EngineDigest();
+ }
+
+ ///
+ /// Returns a binary hash from an input byte array
+ ///
+ /// byte-array to hash
+ /// binary hash of input
+ public byte[] GetByteHashFromBytes(byte[] b)
+ {
+ MD4 md4 = new MD4();
+
+ md4.EngineUpdate(b, 0, b.Length);
+
+ return md4.EngineDigest();
+ }
+
+ ///
+ /// Returns a string that contains the hexadecimal hash
+ ///
+ /// byte-array to input
+ /// String that contains the hex of the hash
+ public string GetHexHashFromBytes(byte[] b)
+ {
+ byte[] e = GetByteHashFromBytes(b);
+ return BytesToHex(e, e.Length);
+ }
+
+ ///
+ /// Returns a byte hash from the input byte
+ ///
+ /// byte to hash
+ /// binary hash of the input byte
+ public byte[] GetByteHashFromByte(byte b)
+ {
+ MD4 md4 = new MD4();
+
+ md4.EngineUpdate(b);
+
+ return md4.EngineDigest();
+ }
+
+ ///
+ /// Returns a string that contains the hexadecimal hash
+ ///
+ /// byte to hash
+ /// String that contains the hex of the hash
+ public string GetHexHashFromByte(byte b)
+ {
+ byte[] e = GetByteHashFromByte(b);
+ return BytesToHex(e, e.Length);
+ }
+
+ ///
+ /// Returns a string that contains the hexadecimal hash
+ ///
+ /// string to hash
+ /// String that contains the hex of the hash
+ public string GetHexHashFromString(string s)
+ {
+ byte[] b = GetByteHashFromString(s);
+ return BytesToHex(b, b.Length);
+ }
+
+ private static string BytesToHex(byte[] a, int len)
+ {
+ string temp = BitConverter.ToString(a);
+
+ // We need to remove the dashes that come from the BitConverter
+ StringBuilder sb = new StringBuilder((len - 2) / 2); // This should be the final size
+
+ for (int i = 0; i < temp.Length; i++)
+ if (temp[i] != '-')
+ sb.Append(temp[i]);
+
+ return sb.ToString();
+ }
+
+ // own methods
+ //-----------------------------------------------------------------------------------
+
+ ///
+ /// MD4 basic transformation
+ ///
+ ///
+ /// Transforms context based on 512 bits from input block starting
+ /// from the offset'th byte.
+ ///
+ /// input sub-array
+ /// starting position of sub-array
+ private void Transform(ref byte[] block, int offset)
+ {
+ // decodes 64 bytes from input block into an array of 16 32-bit
+ // entities. Use A as a temp var.
+ for (int i = 0; i < 16; i++)
+ X[i] = ((uint)block[offset++] & 0xFF) |
+ (((uint)block[offset++] & 0xFF) << 8) |
+ (((uint)block[offset++] & 0xFF) << 16) |
+ (((uint)block[offset++] & 0xFF) << 24);
+
+
+ uint A = context[0];
+ uint B = context[1];
+ uint C = context[2];
+ uint D = context[3];
+
+ A = FF(A, B, C, D, X[0], 3);
+ D = FF(D, A, B, C, X[1], 7);
+ C = FF(C, D, A, B, X[2], 11);
+ B = FF(B, C, D, A, X[3], 19);
+ A = FF(A, B, C, D, X[4], 3);
+ D = FF(D, A, B, C, X[5], 7);
+ C = FF(C, D, A, B, X[6], 11);
+ B = FF(B, C, D, A, X[7], 19);
+ A = FF(A, B, C, D, X[8], 3);
+ D = FF(D, A, B, C, X[9], 7);
+ C = FF(C, D, A, B, X[10], 11);
+ B = FF(B, C, D, A, X[11], 19);
+ A = FF(A, B, C, D, X[12], 3);
+ D = FF(D, A, B, C, X[13], 7);
+ C = FF(C, D, A, B, X[14], 11);
+ B = FF(B, C, D, A, X[15], 19);
+
+ A = GG(A, B, C, D, X[0], 3);
+ D = GG(D, A, B, C, X[4], 5);
+ C = GG(C, D, A, B, X[8], 9);
+ B = GG(B, C, D, A, X[12], 13);
+ A = GG(A, B, C, D, X[1], 3);
+ D = GG(D, A, B, C, X[5], 5);
+ C = GG(C, D, A, B, X[9], 9);
+ B = GG(B, C, D, A, X[13], 13);
+ A = GG(A, B, C, D, X[2], 3);
+ D = GG(D, A, B, C, X[6], 5);
+ C = GG(C, D, A, B, X[10], 9);
+ B = GG(B, C, D, A, X[14], 13);
+ A = GG(A, B, C, D, X[3], 3);
+ D = GG(D, A, B, C, X[7], 5);
+ C = GG(C, D, A, B, X[11], 9);
+ B = GG(B, C, D, A, X[15], 13);
+
+ A = HH(A, B, C, D, X[0], 3);
+ D = HH(D, A, B, C, X[8], 9);
+ C = HH(C, D, A, B, X[4], 11);
+ B = HH(B, C, D, A, X[12], 15);
+ A = HH(A, B, C, D, X[2], 3);
+ D = HH(D, A, B, C, X[10], 9);
+ C = HH(C, D, A, B, X[6], 11);
+ B = HH(B, C, D, A, X[14], 15);
+ A = HH(A, B, C, D, X[1], 3);
+ D = HH(D, A, B, C, X[9], 9);
+ C = HH(C, D, A, B, X[5], 11);
+ B = HH(B, C, D, A, X[13], 15);
+ A = HH(A, B, C, D, X[3], 3);
+ D = HH(D, A, B, C, X[11], 9);
+ C = HH(C, D, A, B, X[7], 11);
+ B = HH(B, C, D, A, X[15], 15);
+
+ context[0] += A;
+ context[1] += B;
+ context[2] += C;
+ context[3] += D;
+ }
+
+ // The basic MD4 atomic functions.
+
+ private uint FF(uint a, uint b, uint c, uint d, uint x, int s)
+ {
+ uint t = a + ((b & c) | (~b & d)) + x;
+ return t << s | t >> (32 - s);
+ }
+
+ private uint GG(uint a, uint b, uint c, uint d, uint x, int s)
+ {
+ uint t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999;
+ return t << s | t >> (32 - s);
+ }
+
+ private uint HH(uint a, uint b, uint c, uint d, uint x, int s)
+ {
+ uint t = a + (b ^ c ^ d) + x + 0x6ED9EBA1;
+ return t << s | t >> (32 - s);
+ }
+ }
+
+ // class MD4
+}
+
+// namespace MD4Hash
\ No newline at end of file
diff --git a/SMBLibrary/Authentication/NTAuthentication.cs b/SMBLibrary/Authentication/NTAuthentication.cs
new file mode 100644
index 0000000..50d5441
--- /dev/null
+++ b/SMBLibrary/Authentication/NTAuthentication.cs
@@ -0,0 +1,220 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Globalization;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.Authentication
+{
+ public class NTAuthentication
+ {
+ public static byte[] ComputeLMv1Response(byte[] challenge, string password)
+ {
+ byte[] hash = LMOWFv1(password);
+ return DesLongEncrypt(hash, challenge);
+ }
+
+ public static byte[] ComputeNTLMv1Response(byte[] challenge, string password)
+ {
+ byte[] hash = NTOWFv1(password);
+ return DesLongEncrypt(hash, challenge);
+ }
+
+ public static byte[] ComputeNTLMv1ExtendedSecurityResponse(byte[] serverChallenge, byte[] clientChallenge, string password)
+ {
+ byte[] passwordHash = NTOWFv1(password);
+ byte[] challengeHash = MD5.Create().ComputeHash(ByteUtils.Concatenate(serverChallenge, clientChallenge));
+ byte[] challengeHashShort = new byte[8];
+ Array.Copy(challengeHash, 0, challengeHashShort, 0, 8);
+ return DesLongEncrypt(passwordHash, challengeHashShort);
+ }
+
+ public static byte[] ComputeLMv2Response(byte[] serverChallenge, byte[] clientChallenge, string password, string user, string domain)
+ {
+ byte[] key = LMOWFv2(password, user, domain);
+ byte[] bytes = ByteUtils.Concatenate(serverChallenge, clientChallenge);
+ HMACMD5 hmac = new HMACMD5(key);
+ byte[] hash = hmac.ComputeHash(bytes, 0, bytes.Length);
+
+ return ByteUtils.Concatenate(hash, clientChallenge);
+ }
+
+ ///
+ /// [MS-NLMP] page 60
+ /// 'temp' is the same as ClientChallengeStructure with 4 zero bytes padding
+ ///
+ public static byte[] ComputeNTLMv2Response(byte[] serverChallenge, byte[] clientChallengeStructurePadded, string password, string user, string domain)
+ {
+ byte[] key = NTOWFv2(password, user, domain);
+ byte[] temp = clientChallengeStructurePadded;
+
+ HMACMD5 hmac = new HMACMD5(key);
+ byte[] _NTProof = hmac.ComputeHash(ByteUtils.Concatenate(serverChallenge, temp), 0, serverChallenge.Length + temp.Length);
+
+ return ByteUtils.Concatenate(_NTProof, temp);
+ }
+
+ ///
+ /// NTLMv2_CLIENT_CHALLENGE
+ ///
+ [Obsolete]
+ public static byte[] GetNTLMv2ClientChallengeStructure(byte[] clientChallenge, byte responseVersion, byte responseVersionHigh, byte[] time, byte[] serverAVPair)
+ {
+ byte[] temp = new byte[28 + serverAVPair.Length];
+ temp[0] = responseVersion;
+ temp[1] = responseVersionHigh;
+ Array.Copy(time, 0, temp, 8, 8);
+ Array.Copy(clientChallenge, 0, temp, 16, 8);
+ Array.Copy(serverAVPair, 0, temp, 28, serverAVPair.Length);
+
+ return temp;
+ }
+
+ public static byte[] DesEncrypt(byte[] key, byte[] plainText)
+ {
+ return DesEncrypt(key, plainText, 0, plainText.Length);
+ }
+
+ public static byte[] DesEncrypt(byte[] key, byte[] plainText, int inputOffset, int inputCount)
+ {
+ ICryptoTransform encryptor = CreateWeakDesEncryptor(CipherMode.ECB, key, new byte[key.Length]);
+ byte[] result = new byte[inputCount];
+ encryptor.TransformBlock(plainText, inputOffset, inputCount, result, 0);
+ return result;
+ }
+
+ public static ICryptoTransform CreateWeakDesEncryptor(CipherMode mode, byte[] rgbKey, byte[] rgbIV)
+ {
+ DES des = DES.Create();
+ des.Mode = mode;
+ DESCryptoServiceProvider sm = des as DESCryptoServiceProvider;
+ MethodInfo mi = sm.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
+ object[] Par = { rgbKey, mode, rgbIV, sm.FeedbackSize, 0 };
+ ICryptoTransform trans = mi.Invoke(sm, Par) as ICryptoTransform;
+ return trans;
+ }
+
+ ///
+ /// DESL()
+ ///
+ public static byte[] DesLongEncrypt(byte[] key, byte[] plainText)
+ {
+ if (key.Length != 16)
+ {
+ throw new ArgumentException("Invalid key length");
+ }
+
+ if (plainText.Length != 8)
+ {
+ throw new ArgumentException("Invalid plain-text length");
+ }
+ byte[] padded = new byte[21];
+ Array.Copy(key, padded, key.Length);
+
+ byte[] k1 = new byte[7];
+ byte[] k2 = new byte[7];
+ byte[] k3 = new byte[7];
+ Array.Copy(padded, 0, k1, 0, 7);
+ Array.Copy(padded, 7, k2, 0, 7);
+ Array.Copy(padded, 14, k3, 0, 7);
+
+ byte[] r1 = DesEncrypt(ExtendDESKey(k1), plainText);
+ byte[] r2 = DesEncrypt(ExtendDESKey(k2), plainText);
+ byte[] r3 = DesEncrypt(ExtendDESKey(k3), plainText);
+
+ byte[] result = new byte[24];
+ Array.Copy(r1, 0, result, 0, 8);
+ Array.Copy(r2, 0, result, 8, 8);
+ Array.Copy(r3, 0, result, 16, 8);
+
+ return result;
+ }
+
+ public static Encoding GetOEMEncoding()
+ {
+ return Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage);
+ }
+
+ ///
+ /// LM Hash
+ ///
+ public static byte[] LMOWFv1(string password)
+ {
+ byte[] plainText = ASCIIEncoding.ASCII.GetBytes("KGS!@#$%");
+ byte[] passwordBytes = GetOEMEncoding().GetBytes(password.ToUpper());
+ byte[] key = new byte[14];
+ Array.Copy(passwordBytes, key, Math.Min(passwordBytes.Length, 14));
+
+ byte[] k1 = new byte[7];
+ byte[] k2 = new byte[7];
+ Array.Copy(key, 0, k1, 0, 7);
+ Array.Copy(key, 7, k2, 0, 7);
+
+ byte[] part1 = DesEncrypt(ExtendDESKey(k1), plainText);
+ byte[] part2 = DesEncrypt(ExtendDESKey(k2), plainText);
+
+ return ByteUtils.Concatenate(part1, part2);
+ }
+
+ ///
+ /// NTLM hash (NT hash)
+ ///
+ public static byte[] NTOWFv1(string password)
+ {
+ byte[] passwordBytes = UnicodeEncoding.Unicode.GetBytes(password);
+ return new MD4().GetByteHashFromBytes(passwordBytes);
+ }
+
+ ///
+ /// LMOWFv2 is identical to NTOWFv2
+ ///
+ public static byte[] LMOWFv2(string password, string user, string domain)
+ {
+ return NTOWFv2(password, user, domain);
+ }
+
+ public static byte[] NTOWFv2(string password, string user, string domain)
+ {
+ byte[] passwordBytes = UnicodeEncoding.Unicode.GetBytes(password);
+ byte[] key = new MD4().GetByteHashFromBytes(passwordBytes);
+ string text = user.ToUpper() + domain;
+ byte[] bytes = UnicodeEncoding.Unicode.GetBytes(text);
+ HMACMD5 hmac = new HMACMD5(key);
+ return hmac.ComputeHash(bytes, 0, bytes.Length);
+ }
+
+ ///
+ /// Extends a 7-byte key into an 8-byte key.
+ /// Note: The DES key ostensibly consists of 64 bits, however, only 56 of these are actually used by the algorithm.
+ /// Eight bits are used solely for checking parity, and are thereafter discarded
+ ///
+ private static byte[] ExtendDESKey(byte[] key)
+ {
+ byte[] result = new byte[8];
+ int i;
+
+ result[0] = (byte)((key[0] >> 1) & 0xff);
+ result[1] = (byte)((((key[0] & 0x01) << 6) | (((key[1] & 0xff) >> 2) & 0xff)) & 0xff);
+ result[2] = (byte)((((key[1] & 0x03) << 5) | (((key[2] & 0xff) >> 3) & 0xff)) & 0xff);
+ result[3] = (byte)((((key[2] & 0x07) << 4) | (((key[3] & 0xff) >> 4) & 0xff)) & 0xff);
+ result[4] = (byte)((((key[3] & 0x0F) << 3) | (((key[4] & 0xff) >> 5) & 0xff)) & 0xff);
+ result[5] = (byte)((((key[4] & 0x1F) << 2) | (((key[5] & 0xff) >> 6) & 0xff)) & 0xff);
+ result[6] = (byte)((((key[5] & 0x3F) << 1) | (((key[6] & 0xff) >> 7) & 0xff)) & 0xff);
+ result[7] = (byte)(key[6] & 0x7F);
+ for (i = 0; i < 8; i++)
+ {
+ result[i] = (byte)(result[i] << 1);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/SMBLibrary/Client/SMBClient.cs b/SMBLibrary/Client/SMBClient.cs
new file mode 100644
index 0000000..c1da15a
--- /dev/null
+++ b/SMBLibrary/Client/SMBClient.cs
@@ -0,0 +1,69 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Net;
+using System.Net.Sockets;
+using System.Text;
+using SMBLibrary.NetBios;
+using SMBLibrary.SMB1;
+using Utilities;
+
+namespace SMBLibrary.Client
+{
+ public class SMBClient
+ {
+ public const int NetBiosOverTCPPort = 139;
+ public const int DirectTCPPort = 445;
+ public const string NTLanManagerDialect = "NT LM 0.12";
+
+ public SMBClient(IPAddress serverAddress, SMBTransportType transport)
+ {
+ NegotiateRequest request = new NegotiateRequest();
+ request.Dialects.Add(NTLanManagerDialect);
+
+ Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ if (transport == SMBTransportType.DirectTCPTransport)
+ {
+ serverSocket.Connect(serverAddress, DirectTCPPort);
+ }
+ else
+ {
+ serverSocket.Connect(serverAddress, NetBiosOverTCPPort);
+ }
+ TrySendMessage(serverSocket, request);
+ }
+
+ public static void TrySendMessage(Socket serverSocket, SMBCommand request)
+ {
+ SMBMessage message = new SMBMessage();
+ message.Commands.Add(request);
+ TrySendMessage(serverSocket, message);
+ }
+
+ public static void TrySendMessage(Socket serverSocket, SMBMessage message)
+ {
+ SessionMessagePacket packet = new SessionMessagePacket();
+ packet.Trailer = message.GetBytes();
+ TrySendPacket(serverSocket, packet);
+ }
+
+ public static void TrySendPacket(Socket serverSocket, SessionPacket response)
+ {
+ try
+ {
+ serverSocket.Send(response.GetBytes());
+ }
+ catch (SocketException)
+ {
+ }
+ catch (ObjectDisposedException)
+ {
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/EnumStructures/AccessMask.cs b/SMBLibrary/EnumStructures/AccessMask.cs
new file mode 100644
index 0000000..8d2f310
--- /dev/null
+++ b/SMBLibrary/EnumStructures/AccessMask.cs
@@ -0,0 +1,101 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary
+{
+ ///
+ /// [MS-SMB] 2.2.1.4.1 - File_Pipe_Printer_Access_Mask
+ ///
+ [Flags]
+ public enum FileAccessMask : uint
+ {
+ FILE_READ_DATA = 0x00000001,
+ FILE_WRITE_DATA = 0x00000002,
+ FILE_APPEND_DATA = 0x00000004,
+ FILE_READ_EA = 0x00000008,
+ FILE_WRITE_EA = 0x00000010,
+ FILE_EXECUTE = 0x00000020,
+ FILE_READ_ATTRIBUTES = 0x00000080,
+ FILE_WRITE_ATTRIBUTES = 0x00000100,
+ DELETE = 0x00010000,
+ READ_CONTROL = 0x00020000,
+ WRITE_DAC = 0x00040000,
+ WRITE_OWNER = 0x00080000,
+ SYNCHRONIZE = 0x00100000,
+ ACCESS_SYSTEM_SECURITY = 0x01000000,
+ MAXIMUM_ALLOWED = 0x02000000,
+ GENERIC_ALL = 0x20000000,
+ GENERIC_EXECUTE = 0x20000000,
+ GENERIC_WRITE = 0x40000000,
+ GENERIC_READ = 0x80000000,
+ }
+
+ ///
+ /// [MS-SMB] 2.2.1.4.2 - Directory_Access_Mask
+ ///
+ [Flags]
+ public enum DirectoryAccessMask : uint
+ {
+ FILE_LIST_DIRECTORY = 0x00000001,
+ FILE_ADD_FILE = 0x00000002,
+ FILE_ADD_SUBDIRECTORY = 0x00000004,
+ FILE_READ_EA = 0x00000008,
+ FILE_WRITE_EA = 0x00000010,
+ FILE_TRAVERSE = 0x00000020,
+ FILE_DELETE_CHILD = 0x00000040,
+ FILE_READ_ATTRIBUTES = 0x00000080,
+ FILE_WRITE_ATTRIBUTES = 0x00000100,
+ DELETE = 0x00010000,
+ READ_CONTROL = 0x00020000,
+ WRITE_DAC = 0x00040000,
+ WRITE_OWNER = 0x00080000,
+ SYNCHRONIZE = 0x00100000,
+ ACCESS_SYSTEM_SECURITY = 0x01000000,
+ MAXIMUM_ALLOWED = 0x02000000,
+ GENERIC_ALL = 0x20000000,
+ GENERIC_EXECUTE = 0x20000000,
+ GENERIC_WRITE = 0x40000000,
+ GENERIC_READ = 0x80000000,
+ }
+
+ ///
+ /// [MS-DTYP] 2.4.3 - ACCESS_MASK
+ ///
+ public struct AccessMask // uint
+ {
+ public FileAccessMask File;
+ public FileAccessMask Directory;
+
+ public AccessMask(byte[] buffer, ref int offset) : this(buffer, offset)
+ {
+ offset += 4;
+ }
+
+ public AccessMask(byte[] buffer, int offset)
+ {
+ uint value = LittleEndianConverter.ToUInt32(buffer, offset);
+ File = (FileAccessMask)value;
+ Directory = (FileAccessMask)value;
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ uint value = (uint)(this.File | this.Directory);
+ LittleEndianWriter.WriteUInt32(buffer, offset, value);
+ }
+
+ public void WriteBytes(byte[] buffer, ref int offset)
+ {
+ WriteBytes(buffer, offset);
+ offset += 4;
+ }
+ }
+}
diff --git a/SMBLibrary/Enums/NTStatus.cs b/SMBLibrary/Enums/NTStatus.cs
new file mode 100644
index 0000000..69d887e
--- /dev/null
+++ b/SMBLibrary/Enums/NTStatus.cs
@@ -0,0 +1,36 @@
+
+namespace SMBLibrary
+{
+ public enum NTStatus : uint
+ {
+ STATUS_SUCCESS = 0x00000000,
+ STATUS_NOT_IMPLEMENTED = 0xC0000002,
+ STATUS_INVALID_HANDLE = 0xC0000008,
+ STATUS_INVALID_PARAMETER = 0xC000000D,
+ STATUS_NO_SUCH_DEVICE = 0xC000000E,
+ STATUS_NO_SUCH_FILE = 0xC000000F,
+ STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016,
+ STATUS_ACCESS_DENIED = 0xC0000022, // The user is not authorized to access the resource.
+ STATUS_OBJECT_NAME_INVALID = 0xC0000033,
+ STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034,
+ STATUS_OBJECT_NAME_COLLISION = 0xC0000035, // The file already exists
+ STATUS_OBJECT_PATH_INVALID = 0xC0000039,
+ STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003A, // The share path does not reference a valid resource.
+ STATUS_OBJECT_PATH_SYNTAX_BAD = 0xC000003B,
+ STATUS_DATA_ERROR = 0xC000003E, // IO error
+ STATUS_SHARING_VIOLATION = 0xC0000043,
+ STATUS_FILE_LOCK_CONFLICT = 0xC0000054,
+ STATUS_LOGON_FAILURE = 0xC000006D, // Authentication failure.
+ STATUS_ACCOUNT_RESTRICTION = 0xC000006E, // The user has an empty password, which is not allowed
+ STATUS_DISK_FULL = 0xC000007F,
+ STATUS_MEDIA_WRITE_PROTECTED = 0xC00000A2,
+ STATUS_FILE_IS_A_DIRECTORY = 0xC00000BA,
+ STATUS_CANNOT_DELETE = 0xC0000121,
+
+ STATUS_INVALID_SMB = 0x00010002, // CIFS/SMB1: A corrupt or invalid SMB request was received
+ STATUS_SMB_BAD_COMMAND = 0x00160002, // CIFS/SMB1: An unknown SMB command code was received by the server
+ STATUS_SMB_BAD_FID = 0x00060001, // CIFS/SMB1
+ STATUS_SMB_BAD_TID = 0x00050002, // CIFS/SMB1
+ STATUS_OS2_NO_MORE_SIDS = 0x00710001, // CIFS/SMB1
+ }
+}
diff --git a/SMBLibrary/Enums/SMBTransportType.cs b/SMBLibrary/Enums/SMBTransportType.cs
new file mode 100644
index 0000000..00f0210
--- /dev/null
+++ b/SMBLibrary/Enums/SMBTransportType.cs
@@ -0,0 +1,9 @@
+
+namespace SMBLibrary
+{
+ public enum SMBTransportType
+ {
+ NetBiosOverTCP, // Port 139
+ DirectTCPTransport, // Port 445
+ }
+}
diff --git a/SMBLibrary/Enums/Win32Error.cs b/SMBLibrary/Enums/Win32Error.cs
new file mode 100644
index 0000000..ee8587d
--- /dev/null
+++ b/SMBLibrary/Enums/Win32Error.cs
@@ -0,0 +1,16 @@
+
+namespace SMBLibrary
+{
+ // All Win32 error codes MUST be in the range 0x0000 to 0xFFFF
+ public enum Win32Error : ushort
+ {
+ ERROR_SUCCESS = 0x0000,
+ ERROR_ACCESS_DENIED = 0x0005,
+ ERROR_SHARING_VIOLATION = 0x0020,
+ ERROR_DISK_FULL = 0x0070,
+ ERROR_LOGON_FAILURE = 0x0000052E,
+ ERROR_ACCOUNT_RESTRICTION = 0x0000052F,
+ ERROR_LOGON_TYPE_NOT_GRANTED = 0x00000569,
+ NERR_NetNameNotFound = 0x00000906
+ }
+}
diff --git a/SMBLibrary/IOCTL/FileFullEAInformation.cs b/SMBLibrary/IOCTL/FileFullEAInformation.cs
new file mode 100644
index 0000000..73e2de9
--- /dev/null
+++ b/SMBLibrary/IOCTL/FileFullEAInformation.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary
+{
+ ///
+ /// [MS-FSCC] FILE_FULL_EA_INFORMATION data element
+ ///
+ public class FileFullEAInformation
+ {
+ public uint NextEntryOffset;
+ public byte Flags;
+ //byte EaNameLength;
+ //ushort EaValueLength;
+ public string EaName; // ASCII
+ public string EaValue; // ASCII
+
+ public FileFullEAInformation()
+ {
+ }
+
+ public FileFullEAInformation(byte[] buffer, int offset)
+ {
+ NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Flags = ByteReader.ReadByte(buffer, ref offset);
+ byte eaNameLength = ByteReader.ReadByte(buffer, ref offset);
+ ushort eaValueLength = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ EaName = ByteReader.ReadAnsiString(buffer, ref offset, eaNameLength);
+ EaValue = ByteReader.ReadAnsiString(buffer, ref offset, eaValueLength);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ byte eaNameLength = (byte)EaName.Length;
+ ushort eaValueLength = (ushort)EaValue.Length;
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NextEntryOffset);
+ ByteWriter.WriteByte(buffer, ref offset, Flags);
+ ByteWriter.WriteByte(buffer, ref offset, eaNameLength);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, eaValueLength);
+ ByteWriter.WriteAnsiString(buffer, ref offset, EaName);
+ ByteWriter.WriteAnsiString(buffer, ref offset, EaValue);
+ }
+
+ public int Length
+ {
+ get
+ {
+ return 8 + EaName.Length + EaValue.Length;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/IOCTL/FileFullEAInformationList.cs b/SMBLibrary/IOCTL/FileFullEAInformationList.cs
new file mode 100644
index 0000000..b640e86
--- /dev/null
+++ b/SMBLibrary/IOCTL/FileFullEAInformationList.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary
+{
+ ///
+ /// [MS-FSCC] FILE_FULL_EA_INFORMATION buffer
+ ///
+ public class FileFullEAInformationList : List
+ {
+ public FileFullEAInformationList()
+ {
+ }
+
+ public FileFullEAInformationList(byte[] buffer, int offset)
+ {
+ FileFullEAInformation entry = new FileFullEAInformation(buffer, offset);
+ this.Add(entry);
+ while (entry.NextEntryOffset != 0)
+ {
+ entry = new FileFullEAInformation(buffer, (int)entry.NextEntryOffset);
+ this.Add(entry);
+ }
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ // When multiple FILE_FULL_EA_INFORMATION data elements are present in the buffer, each MUST be aligned on a 4-byte boundary
+ for (int index = 0; index < this.Count; index++)
+ {
+ this[index].WriteBytes(buffer, offset);
+ offset += this[index].Length;
+ if (index < this.Count - 1)
+ {
+ int padding = (4 - (offset % 4)) % 4;
+ offset += padding;
+ }
+ }
+ }
+
+ public int Length
+ {
+ get
+ {
+ // When multiple FILE_FULL_EA_INFORMATION data elements are present in the buffer, each MUST be aligned on a 4-byte boundary
+ int length = 0;
+ for(int index = 0; index < this.Count; index++)
+ {
+ length += this[index].Length;
+ if (index < this.Count - 1)
+ {
+ int padding = (4 - (length % 4)) % 4;
+ length += padding;
+ }
+ }
+ return length;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/IOCTL/ObjectIDBufferType1.cs b/SMBLibrary/IOCTL/ObjectIDBufferType1.cs
new file mode 100644
index 0000000..0f1b474
--- /dev/null
+++ b/SMBLibrary/IOCTL/ObjectIDBufferType1.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary
+{
+ ///
+ /// [MS-FSCC] FILE_OBJECTID_BUFFER Type 1
+ ///
+ public class ObjectIDBufferType1
+ {
+ public const int Length = 64;
+
+ public Guid ObjectId;
+ public Guid BirthVolumeId;
+ public Guid BirthObjectId;
+ public Guid DomainId;
+
+ public ObjectIDBufferType1()
+ {
+ }
+
+ public ObjectIDBufferType1(byte[] buffer)
+ {
+ ObjectId = LittleEndianConverter.ToGuid(buffer, 0);
+ BirthVolumeId = LittleEndianConverter.ToGuid(buffer, 16);
+ BirthObjectId = LittleEndianConverter.ToGuid(buffer, 32);
+ DomainId = LittleEndianConverter.ToGuid(buffer, 48);
+ }
+
+ public byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ LittleEndianWriter.WriteGuidBytes(buffer, 0, ObjectId);
+ LittleEndianWriter.WriteGuidBytes(buffer, 16, BirthVolumeId);
+ LittleEndianWriter.WriteGuidBytes(buffer, 32, BirthObjectId);
+ LittleEndianWriter.WriteGuidBytes(buffer, 48, DomainId);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/EnumStructures/NameFlags.cs b/SMBLibrary/NetBios/NameServicePackets/EnumStructures/NameFlags.cs
new file mode 100644
index 0000000..cc9e6fe
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/EnumStructures/NameFlags.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public enum OwnerNodeType : byte
+ {
+ BNode = 0x00,
+ PNode = 0x01,
+ MNode = 0x10,
+ }
+
+ public struct NameFlags // ushort
+ {
+ public const int Length = 2;
+
+ public OwnerNodeType NodeType;
+ public bool WorkGroup;
+
+ public ushort Value
+ {
+ get
+ {
+ ushort value = (ushort)(((byte)NodeType) << 13);
+ if (WorkGroup)
+ {
+ value |= 0x8000;
+ }
+ return value;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/Enums/NameRecordType.cs b/SMBLibrary/NetBios/NameServicePackets/Enums/NameRecordType.cs
new file mode 100644
index 0000000..fdfc1e3
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/Enums/NameRecordType.cs
@@ -0,0 +1,9 @@
+
+namespace SMBLibrary.NetBios
+{
+ public enum NameRecordType : ushort
+ {
+ NB = 0x0020,
+ NBStat = 0x0021,
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/Enums/NameServiceOperation.cs b/SMBLibrary/NetBios/NameServicePackets/Enums/NameServiceOperation.cs
new file mode 100644
index 0000000..88b82a4
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/Enums/NameServiceOperation.cs
@@ -0,0 +1,17 @@
+
+namespace SMBLibrary.NetBios
+{
+ public enum NameServiceOperation : byte
+ {
+ QueryRequest = 0x00,
+ RegistrationRequest = 0x05,
+ ReleaseRequest = 0x06,
+ WackRequest = 0x07,
+ RefreshRequest = 0x08,
+ QueryResponse = 0x10,
+ RegistrationResponse = 0x15,
+ ReleaseResponse = 0x16,
+ WackResponse = 0x17,
+ RefreshResponse = 0x18,
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/Enums/NetBiosSuffix.cs b/SMBLibrary/NetBios/NameServicePackets/Enums/NetBiosSuffix.cs
new file mode 100644
index 0000000..a7126fc
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/Enums/NetBiosSuffix.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// 16th character suffix for netbios name.
+ /// see http://support.microsoft.com/kb/163409/en-us
+ ///
+ public enum NetBiosSuffix : byte
+ {
+ WorkstationService = 0x00,
+ MessengerService = 0x03,
+ DomainMasterBrowser = 0x1B,
+ MasterBrowser = 0x1D,
+ BrowserServiceElections = 0x1E,
+ FileServiceService = 0x20,
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/Enums/OperationFlags.cs b/SMBLibrary/NetBios/NameServicePackets/Enums/OperationFlags.cs
new file mode 100644
index 0000000..090279b
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/Enums/OperationFlags.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.1.1. HEADER
+ ///
+ [Flags]
+ public enum OperationFlags : byte
+ {
+ Broadcast = 0x01,
+ RecursionAvailable = 0x08,
+ RecursionDesired = 0x10,
+ Truncated = 0x20,
+ AuthoritativeAnswer = 0x40,
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/NameQueryRequest.cs b/SMBLibrary/NetBios/NameServicePackets/NameQueryRequest.cs
new file mode 100644
index 0000000..36ab9ec
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/NameQueryRequest.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.12. NAME QUERY REQUEST
+ ///
+ public class NameQueryRequest
+ {
+ public NameServicePacketHeader Header;
+ public QuestionSection Question;
+
+ public NameQueryRequest()
+ {
+ Header = new NameServicePacketHeader();
+ Header.OpCode = NameServiceOperation.QueryRequest;
+ Header.ARCount = 1;
+ Question = new QuestionSection();
+ }
+
+ public NameQueryRequest(byte[] buffer, int offset)
+ {
+ Header = new NameServicePacketHeader(buffer, ref offset);
+ Question = new QuestionSection(buffer, ref offset);
+ }
+
+ public byte[] GetBytes()
+ {
+ MemoryStream stream = new MemoryStream();
+ Header.WriteBytes(stream);
+ Question.WriteBytes(stream);
+ return stream.ToArray();
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/NameRegistrationRequest.cs b/SMBLibrary/NetBios/NameServicePackets/NameRegistrationRequest.cs
new file mode 100644
index 0000000..866453d
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/NameRegistrationRequest.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Net;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.2. NAME REGISTRATION REQUEST
+ ///
+ public class NameRegistrationRequest
+ {
+ public const int DataLength = 6;
+
+ public NameServicePacketHeader Header;
+ public QuestionSection Question;
+ public ResourceRecord Resource;
+ public NameFlags NameFlags;
+ public byte[] Address; // IPv4 address
+
+ public NameRegistrationRequest()
+ {
+ Header = new NameServicePacketHeader();
+ Header.OpCode = NameServiceOperation.RegistrationRequest;
+ Header.QDCount = 1;
+ Header.ARCount = 1;
+ Header.Flags = OperationFlags.Broadcast | OperationFlags.RecursionDesired;
+ Question = new QuestionSection();
+ Resource = new ResourceRecord();
+ Address = new byte[4];
+ }
+
+ public NameRegistrationRequest(string machineName, NetBiosSuffix suffix, IPAddress address) : this()
+ {
+ Question.Name = NetBiosUtils.GetMSNetBiosName(machineName, suffix);
+ Address = address.GetAddressBytes();
+ }
+
+ public byte[] GetBytes()
+ {
+ Resource.Data = GetData();
+
+ MemoryStream stream = new MemoryStream();
+ Header.WriteBytes(stream);
+ Question.WriteBytes(stream);
+ Resource.WriteBytes(stream, NameServicePacketHeader.Length);
+ return stream.ToArray();
+ }
+
+ public byte[] GetData()
+ {
+ byte[] data = new byte[DataLength];
+ BigEndianWriter.WriteUInt16(data, 0, NameFlags.Value);
+ ByteWriter.WriteBytes(data, 2, Address, 4);
+ return data;
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/NameServicePacketHeader.cs b/SMBLibrary/NetBios/NameServicePackets/NameServicePacketHeader.cs
new file mode 100644
index 0000000..8127b18
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/NameServicePacketHeader.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.1.1. HEADER
+ ///
+ public class NameServicePacketHeader
+ {
+ public const int Length = 12;
+
+ public ushort TransactionID;
+ public NameServiceOperation OpCode;
+ public OperationFlags Flags;
+ public byte ResultCode;
+ public ushort QDCount;
+ public ushort ANCount;
+ public ushort NSCount;
+ public ushort ARCount;
+
+ public NameServicePacketHeader()
+ {
+ }
+
+ public NameServicePacketHeader(byte[] buffer, ref int offset) : this(buffer, offset)
+ {
+ offset += Length;
+ }
+
+ public NameServicePacketHeader(byte[] buffer, int offset)
+ {
+ TransactionID = BigEndianConverter.ToUInt16(buffer, offset + 0);
+ ushort temp = BigEndianConverter.ToUInt16(buffer, offset + 2);
+ ResultCode = (byte)(temp & 0xF);
+ Flags = (OperationFlags)((temp >> 4) & 0x7F);
+ OpCode = (NameServiceOperation)((temp >> 11) & 0x1F);
+ QDCount = BigEndianConverter.ToUInt16(buffer, offset + 4);
+ ANCount = BigEndianConverter.ToUInt16(buffer, offset + 6);
+ NSCount = BigEndianConverter.ToUInt16(buffer, offset + 8);
+ ARCount = BigEndianConverter.ToUInt16(buffer, offset + 10);
+ }
+
+ public void WriteBytes(Stream stream)
+ {
+ BigEndianWriter.WriteUInt16(stream, TransactionID);
+ ushort temp = (ushort)(ResultCode & (0xF));
+ temp |= (ushort)((byte)Flags << 4);
+ temp |= (ushort)((byte)OpCode << 11);
+ BigEndianWriter.WriteUInt16(stream, temp);
+ BigEndianWriter.WriteUInt16(stream, QDCount);
+ BigEndianWriter.WriteUInt16(stream, ANCount);
+ BigEndianWriter.WriteUInt16(stream, NSCount);
+ BigEndianWriter.WriteUInt16(stream, ARCount);
+
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/NodeStatusResponse.cs b/SMBLibrary/NetBios/NameServicePackets/NodeStatusResponse.cs
new file mode 100644
index 0000000..ca86251
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/NodeStatusResponse.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.18. NODE STATUS RESPONSE
+ ///
+ public class NodeStatusResponse
+ {
+ public NameServicePacketHeader Header;
+ public ResourceRecord Resource;
+ // byte NumberOfNames;
+ public KeyValuePairList Names = new KeyValuePairList();
+ public NodeStatistics Statistics;
+
+ public NodeStatusResponse()
+ {
+ Header = new NameServicePacketHeader();
+ Header.OpCode = NameServiceOperation.QueryResponse;
+ Header.Flags = OperationFlags.AuthoritativeAnswer | OperationFlags.RecursionAvailable;
+ Header.ANCount = 1;
+ Resource = new ResourceRecord();
+ Resource.Type = NameRecordType.NBStat;
+ Statistics = new NodeStatistics();
+ }
+
+ public byte[] GetBytes()
+ {
+ Resource.Data = GetData();
+
+ MemoryStream stream = new MemoryStream();
+ Header.WriteBytes(stream);
+ Resource.WriteBytes(stream);
+ return stream.ToArray();
+ }
+
+ public byte[] GetData()
+ {
+ MemoryStream stream = new MemoryStream();
+ stream.WriteByte((byte)Names.Count);
+ foreach (KeyValuePair entry in Names)
+ {
+ ByteWriter.WriteAnsiString(stream, entry.Key);
+ //byte[] encodedName = NetBiosUtils.EncodeName(entry.Key, String.Empty);
+ //ByteWriter.WriteBytes(stream, encodedName);
+ BigEndianWriter.WriteUInt16(stream, entry.Value.Value);
+ }
+
+ ByteWriter.WriteBytes(stream, Statistics.GetBytes());
+
+ return stream.ToArray();
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/PositiveNameQueryResponse.cs b/SMBLibrary/NetBios/NameServicePackets/PositiveNameQueryResponse.cs
new file mode 100644
index 0000000..70cb79c
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/PositiveNameQueryResponse.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.13. POSITIVE NAME QUERY RESPONSE
+ ///
+ public class PositiveNameQueryResponse
+ {
+ public const int EntryLength = 6;
+
+ public NameServicePacketHeader Header;
+ public ResourceRecord Resource;
+ public KeyValuePairList Addresses = new KeyValuePairList();
+
+ public PositiveNameQueryResponse()
+ {
+ Header = new NameServicePacketHeader();
+ Header.Flags = OperationFlags.AuthoritativeAnswer | OperationFlags.RecursionDesired;
+ Header.OpCode = NameServiceOperation.QueryResponse;
+ Header.ANCount = 1;
+ Resource = new ResourceRecord();
+ }
+
+ public byte[] GetBytes()
+ {
+ Resource.Data = GetData();
+
+ MemoryStream stream = new MemoryStream();
+ Header.WriteBytes(stream);
+ Resource.WriteBytes(stream);
+ return stream.ToArray();
+ }
+
+ public byte[] GetData()
+ {
+ byte[] data = new byte[EntryLength * Addresses.Count];
+ int offset = 0;
+ foreach (KeyValuePair entry in Addresses)
+ {
+ BigEndianWriter.WriteUInt16(data, ref offset, entry.Value.Value);
+ ByteWriter.WriteBytes(data, ref offset, entry.Key, 4);
+ }
+ return data;
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/Structures/NodeStatistics.cs b/SMBLibrary/NetBios/NameServicePackets/Structures/NodeStatistics.cs
new file mode 100644
index 0000000..94153eb
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/Structures/NodeStatistics.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class NodeStatistics
+ {
+ public const int Length = 46;
+
+ public byte[] UnitID; // MAC address, 6 bytes;
+ public byte Jumpers;
+ public byte TestResult;
+ public ushort VersionNumber;
+ public ushort PeriodOfStatistics;
+ public ushort NumberOfCRCs;
+ public ushort NumberOfAlignmentErrors;
+ public ushort NumberOfCollisions;
+ public ushort NumberOfSendAborts;
+ public uint NumberOfGoodSends;
+ public uint NumberOfGoodReceives;
+ public ushort NumberOfRetransmits;
+ public ushort NumberOfNoResourceConditions;
+ public ushort NumberOfFreeCommandBlocks;
+ public ushort TotalNumberOfCommandBlocks;
+ public ushort MaxTotalNumberOfCommandBlocks;
+ public ushort NumberOfPendingSessions;
+ public ushort MaxNumberOfPendingSessions;
+ public ushort MaxTotalsSessionsPossible;
+ public ushort SessionDataPacketSize;
+
+ public NodeStatistics()
+ {
+ UnitID = new byte[6];
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ ByteWriter.WriteBytes(buffer, ref offset, UnitID, 6);
+ ByteWriter.WriteByte(buffer, ref offset, Jumpers);
+ ByteWriter.WriteByte(buffer, ref offset, TestResult);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, VersionNumber);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, PeriodOfStatistics);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfCRCs);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfAlignmentErrors);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfCollisions);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfSendAborts);
+ BigEndianWriter.WriteUInt32(buffer, ref offset, NumberOfGoodSends);
+ BigEndianWriter.WriteUInt32(buffer, ref offset, NumberOfGoodReceives);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfRetransmits);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfNoResourceConditions);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfFreeCommandBlocks);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, TotalNumberOfCommandBlocks);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, MaxTotalNumberOfCommandBlocks);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, NumberOfPendingSessions);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, MaxNumberOfPendingSessions);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, MaxTotalsSessionsPossible);
+ BigEndianWriter.WriteUInt16(buffer, ref offset, SessionDataPacketSize);
+ }
+
+ public byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ WriteBytes(buffer, 0);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/Structures/QuestionSection.cs b/SMBLibrary/NetBios/NameServicePackets/Structures/QuestionSection.cs
new file mode 100644
index 0000000..00449fa
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/Structures/QuestionSection.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.1.2. QUESTION SECTION
+ ///
+ public class QuestionSection
+ {
+ public string Name;
+ public NameRecordType Type = NameRecordType.NB; // NB
+ public ushort Class = 0x0001; // IN
+
+ public QuestionSection()
+ {
+ }
+
+ public QuestionSection(byte[] buffer, ref int offset)
+ {
+ Name = NetBiosUtils.DecodeName(buffer, ref offset);
+ Type = (NameRecordType)BigEndianReader.ReadUInt16(buffer, ref offset);
+ Class = BigEndianReader.ReadUInt16(buffer, ref offset);
+ }
+
+ public void WriteBytes(Stream stream)
+ {
+ byte[] encodedName = NetBiosUtils.EncodeName(Name, String.Empty);
+ ByteWriter.WriteBytes(stream, encodedName);
+ BigEndianWriter.WriteUInt16(stream, (ushort)Type);
+ BigEndianWriter.WriteUInt16(stream, Class);
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NameServicePackets/Structures/ResourceRecord.cs b/SMBLibrary/NetBios/NameServicePackets/Structures/ResourceRecord.cs
new file mode 100644
index 0000000..7a8ae7d
--- /dev/null
+++ b/SMBLibrary/NetBios/NameServicePackets/Structures/ResourceRecord.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.1.3. RESOURCE RECORD
+ ///
+ public class ResourceRecord
+ {
+ public string Name;
+ public NameRecordType Type = NameRecordType.NB; // NB
+ public ushort Class = 0x0001; // IN
+ public uint TTL;
+ // ushort DataLength
+ public byte[] Data;
+
+ public ResourceRecord()
+ {
+ Name = String.Empty;
+ TTL = (uint)new TimeSpan(7, 0, 0, 0).TotalSeconds;
+ Data = new byte[0];
+ }
+
+ public void WriteBytes(Stream stream)
+ {
+ WriteBytes(stream, null);
+ }
+
+ public void WriteBytes(Stream stream, int? nameOffset)
+ {
+ if (nameOffset.HasValue)
+ {
+ NetBiosUtils.WriteNamePointer(stream, nameOffset.Value);
+ }
+ else
+ {
+ byte[] encodedName = NetBiosUtils.EncodeName(Name, String.Empty);
+ ByteWriter.WriteBytes(stream, encodedName);
+ }
+ BigEndianWriter.WriteUInt16(stream, (ushort)Type);
+ BigEndianWriter.WriteUInt16(stream, Class);
+ BigEndianWriter.WriteUInt32(stream, TTL);
+ BigEndianWriter.WriteUInt16(stream, (ushort)Data.Length);
+ ByteWriter.WriteBytes(stream, Data);
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/NetBiosUtils.cs b/SMBLibrary/NetBios/NetBiosUtils.cs
new file mode 100644
index 0000000..1553bf8
--- /dev/null
+++ b/SMBLibrary/NetBios/NetBiosUtils.cs
@@ -0,0 +1,207 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class NetBiosUtils
+ {
+ ///
+ /// The NetBIOS naming convention allows for 16 characters in a NetBIOS name.
+ /// Microsoft, however, limits NetBIOS names to 15 characters and uses the 16th character as a NetBIOS suffix
+ /// See http://support.microsoft.com/kb/163409/en-us
+ ///
+ public static string GetMSNetBiosName(string name, NetBiosSuffix suffix)
+ {
+ if (name.Length > 15)
+ {
+ name = name.Substring(0, 15);
+ }
+ else if (name.Length < 15)
+ {
+ name = name.PadRight(15);
+ }
+
+ return name + (char)suffix;
+ }
+
+ public static string GetNameFromMSNetBiosName(string netBiosName)
+ {
+ if (netBiosName.Length != 16)
+ {
+ throw new ArgumentException("Invalid MS NetBIOS name");
+ }
+
+ netBiosName = netBiosName.Substring(0, 15);
+ return netBiosName.TrimEnd(' ');
+ }
+
+ public static byte[] EncodeName(string name, NetBiosSuffix suffix, string scopeID)
+ {
+ string netBiosName = GetMSNetBiosName(name, suffix);
+ return EncodeName(netBiosName, scopeID);
+ }
+
+ /// NetBIOS name
+ /// dot-separated labels, formatted per DNS naming rules
+ public static byte[] EncodeName(string netBiosName, string scopeID)
+ {
+ string domainName = FirstLevelEncoding(netBiosName, scopeID);
+ return SecondLevelEncoding(domainName);
+ }
+
+ // The conversion of a NetBIOS name to a format complying with DNS "best practices".
+ // NetBIOS names may contain characters which are not considered valid for use in DNS names,
+ // yet RFC 1001 and RFC 1002 attempted to map the NetBIOS name space into the DNS name space.
+ // To work around this conflict, NetBIOS names are encoded by splitting each byte of the name
+ // into two nibbles and then adding the value of 'A' (0x41).
+ // Thus, the '&' character (0x26) would be encoded as "CG".
+ // NetBIOS names are usually padded with spaces before being encoded.
+ /// NetBIOS name
+ /// dot-separated labels, formatted per DNS naming rules
+ public static string FirstLevelEncoding(string netBiosName, string scopeID)
+ {
+ // RFC 1001: NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long
+ if (netBiosName.Length != 16)
+ {
+ throw new ArgumentException("Invalid MS NetBIOS name");
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (int index = 0; index < netBiosName.Length; index++)
+ {
+ byte c = (byte)netBiosName[index];
+ byte high = (byte)(0x41 + (c >> 4));
+ byte low = (byte)(0x41 + (c & 0x0F));
+ builder.Append((char)high);
+ builder.Append((char)low);
+ }
+
+ if (scopeID.Length > 0)
+ {
+ builder.Append(".");
+ builder.Append(scopeID);
+ }
+
+ return builder.ToString();
+ }
+
+ // Domain names messages are expressed in terms of a sequence
+ // of labels. Each label is represented as a one octet length
+ // field followed by that number of octets. Since every domain
+ // name ends with the null label of the root, a compressed
+ // domain name is terminated by a length byte of zero
+ ///
+ /// The on-the-wire format of an NBT name. The encoding scheme replaces the familiar dot characters
+ /// used in DNS names with a byte containing the length of the next label.
+ ///
+ public static byte[] SecondLevelEncoding(string domainName)
+ {
+ string[] labels = domainName.Split('.');
+ int length = 1; // null terminator
+ for (int index = 0; index < labels.Length; index++)
+ {
+ length += 1 + labels[index].Length;
+ if (labels[index].Length > 63)
+ {
+ throw new ArgumentException("Invalid NetBIOS label length");
+ }
+ }
+
+ byte[] result = new byte[length];
+ int offset = 0;
+ foreach(string label in labels)
+ {
+ result[offset] = (byte)label.Length;
+ offset++;
+ ByteWriter.WriteAnsiString(result, offset, label, label.Length);
+ offset += label.Length;
+ }
+
+ result[offset] = 0; // null termination
+ return result;
+ }
+
+ public static string DecodeName(byte[] buffer, ref int offset)
+ {
+ string domainName = SecondLevelDecoding(buffer, ref offset);
+ string name = domainName.Split('.')[0];
+ return FirstLevelDecoding(name);
+ }
+
+ public static string SecondLevelDecoding(byte[] buffer, ref int offset)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ byte labelLength = ByteReader.ReadByte(buffer, ref offset);
+ while (labelLength > 0)
+ {
+ if (builder.Length > 0)
+ {
+ builder.Append(".");
+ }
+
+ // The high order two bits of the length field must be zero
+ if (labelLength > 63)
+ {
+ throw new ArgumentException("Invalid NetBIOS label length");
+ }
+
+ string label = ByteReader.ReadAnsiString(buffer, offset, labelLength);
+ builder.Append(label);
+ offset += labelLength;
+
+ labelLength = ByteReader.ReadByte(buffer, ref offset);
+ }
+
+ return builder.ToString();
+ }
+
+ public static string FirstLevelDecoding(string name)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for(int index = 0; index < name.Length; index += 2)
+ {
+ byte c0 = (byte)name[index];
+ byte c1 = (byte)name[index + 1];
+ byte high = (byte)(((c0 - 0x41) & 0xF) << 4);
+ byte low = (byte)((c1 - 0x41) & 0xF);
+ byte c = (byte)(high | low);
+ builder.Append((char)c);
+ }
+
+ return builder.ToString();
+ }
+
+ public static void WriteNamePointer(byte[] buffer, ref int offset, int nameOffset)
+ {
+ WriteNamePointer(buffer, offset, nameOffset);
+ offset += 2;
+ }
+
+ ///
+ /// Will write a 2 bytes pointer to a name
+ /// Note: NetBIOS implementations can only use label string pointers in Name Service packets
+ ///
+ public static void WriteNamePointer(byte[] buffer, int offset, int nameOffset)
+ {
+ ushort pointer = (ushort)(0xC000 | (nameOffset & 0x3FFF));
+ BigEndianWriter.WriteUInt16(buffer, offset, pointer);
+ }
+
+ public static void WriteNamePointer(Stream stream, int nameOffset)
+ {
+ ushort pointer = (ushort)(0xC000 | (nameOffset & 0x3FFF));
+ BigEndianWriter.WriteUInt16(stream, pointer);
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/Enums/SessionPacketTypeName.cs b/SMBLibrary/NetBios/SessionPackets/Enums/SessionPacketTypeName.cs
new file mode 100644
index 0000000..ed6f90b
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/Enums/SessionPacketTypeName.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2014 Tal Aloni . 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.
+ */
+namespace SMBLibrary.NetBios
+{
+ ///
+ /// [RFC 1002] 4.2.1.1. HEADER
+ ///
+ public enum SessionPacketTypeName : byte
+ {
+ SessionMessage = 0x00,
+ SessionRequest = 0x81,
+ PositiveSessionResponse = 0x82,
+ NegativeSessionResponse = 0x83,
+ RetargetSessionResponse = 0x84,
+ SessionKeepAlive = 0x85,
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/NegativeSessionResponsePacket.cs b/SMBLibrary/NetBios/SessionPackets/NegativeSessionResponsePacket.cs
new file mode 100644
index 0000000..dee829c
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/NegativeSessionResponsePacket.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class NegativeSessionResponsePacket : SessionPacket
+ {
+ public byte ErrorCode;
+
+ public NegativeSessionResponsePacket() : base()
+ {
+ this.Type = SessionPacketTypeName.NegativeSessionResponse;
+ }
+
+ public NegativeSessionResponsePacket(byte[] buffer) : base(buffer)
+ {
+ ErrorCode = ByteReader.ReadByte(this.Trailer, 0);
+ }
+
+ public override byte[] GetBytes()
+ {
+ this.Trailer = new byte[1];
+ this.Trailer[0] = ErrorCode;
+
+ return base.GetBytes();
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/PositiveSessionResponsePacket.cs b/SMBLibrary/NetBios/SessionPackets/PositiveSessionResponsePacket.cs
new file mode 100644
index 0000000..050893e
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/PositiveSessionResponsePacket.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class PositiveSessionResponsePacket : SessionPacket
+ {
+ public PositiveSessionResponsePacket() : base()
+ {
+ this.Type = SessionPacketTypeName.PositiveSessionResponse;
+ }
+
+ public PositiveSessionResponsePacket(byte[] buffer) : base(buffer)
+ {
+ }
+
+ public override byte[] GetBytes()
+ {
+ this.Trailer = new byte[0];
+ return base.GetBytes();
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/SessionKeepAlivePacket.cs b/SMBLibrary/NetBios/SessionPackets/SessionKeepAlivePacket.cs
new file mode 100644
index 0000000..e6bcb6c
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/SessionKeepAlivePacket.cs
@@ -0,0 +1,31 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class SessionKeepAlivePacket : SessionPacket
+ {
+ public SessionKeepAlivePacket()
+ {
+ this.Type = SessionPacketTypeName.SessionKeepAlive;
+ }
+
+ public SessionKeepAlivePacket(byte[] buffer) : base(buffer)
+ {
+ }
+
+ public override byte[] GetBytes()
+ {
+ this.Trailer = new byte[0];
+ return base.GetBytes();
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/SessionMessagePacket.cs b/SMBLibrary/NetBios/SessionPackets/SessionMessagePacket.cs
new file mode 100644
index 0000000..2385f83
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/SessionMessagePacket.cs
@@ -0,0 +1,25 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class SessionMessagePacket : SessionPacket
+ {
+ public SessionMessagePacket() : base()
+ {
+ this.Type = SessionPacketTypeName.SessionMessage;
+ }
+
+ public SessionMessagePacket(byte[] buffer) : base(buffer)
+ {
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/SessionPacket.cs b/SMBLibrary/NetBios/SessionPackets/SessionPacket.cs
new file mode 100644
index 0000000..71d20d2
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/SessionPacket.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public abstract class SessionPacket
+ {
+ public SessionPacketTypeName Type;
+ public byte Flags;
+ public int Length; // 2 bytes + length extension bit
+ public byte[] Trailer;
+
+ public SessionPacket()
+ {
+ }
+
+ public SessionPacket(byte[] buffer)
+ {
+ Type = (SessionPacketTypeName)ByteReader.ReadByte(buffer, 0);
+ Flags = ByteReader.ReadByte(buffer, 1);
+ Length = (Flags & 0x01) << 16 | BigEndianConverter.ToUInt16(buffer, 2);
+
+ this.Trailer = ByteReader.ReadBytes(buffer, 4, Length);
+ }
+
+ public virtual byte[] GetBytes()
+ {
+ Length = this.Trailer.Length;
+ if (Length > 0x1FFFF)
+ {
+ throw new ArgumentException("Invalid NBT packet length");
+ }
+
+ Flags = Convert.ToByte(Length > 0xFFFF);
+
+ byte[] buffer = new byte[4 + Trailer.Length];
+ ByteWriter.WriteByte(buffer, 0, (byte)this.Type);
+ ByteWriter.WriteByte(buffer, 1, Flags);
+ BigEndianWriter.WriteUInt16(buffer, 2, (ushort)(Length & 0xFFFF));
+ ByteWriter.WriteBytes(buffer, 4, this.Trailer);
+
+ return buffer;
+ }
+
+ public static SessionPacket GetSessionPacket(byte[] buffer)
+ {
+ SessionPacketTypeName type = (SessionPacketTypeName)ByteReader.ReadByte(buffer, 0);
+ switch (type)
+ {
+ case SessionPacketTypeName.SessionMessage:
+ return new SessionMessagePacket(buffer);
+ case SessionPacketTypeName.SessionRequest:
+ return new SessionRequestPacket(buffer);
+ case SessionPacketTypeName.PositiveSessionResponse:
+ return new PositiveSessionResponsePacket(buffer);
+ case SessionPacketTypeName.NegativeSessionResponse:
+ return new NegativeSessionResponsePacket(buffer);
+ case SessionPacketTypeName.RetargetSessionResponse:
+ return new SessionRetargetResponsePacket(buffer);
+ case SessionPacketTypeName.SessionKeepAlive:
+ return new SessionKeepAlivePacket(buffer);
+ default:
+ throw new InvalidRequestException("Invalid NetBIOS Session Packet");
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/SessionRequestPacket.cs b/SMBLibrary/NetBios/SessionPackets/SessionRequestPacket.cs
new file mode 100644
index 0000000..1aba6d5
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/SessionRequestPacket.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class SessionRequestPacket : SessionPacket
+ {
+ public string CalledName;
+ public string CallingName;
+
+ public SessionRequestPacket()
+ {
+ this.Type = SessionPacketTypeName.SessionRequest;
+ }
+
+ public SessionRequestPacket(byte[] buffer) : base(buffer)
+ {
+ int offset = 0;
+ CalledName = NetBiosUtils.DecodeName(this.Trailer, ref offset);
+ CallingName = NetBiosUtils.DecodeName(this.Trailer, ref offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] part1 = NetBiosUtils.EncodeName(CalledName, String.Empty);
+ byte[] part2 = NetBiosUtils.EncodeName(CallingName, String.Empty);
+ this.Trailer = new byte[part1.Length + part2.Length];
+ ByteWriter.WriteBytes(this.Trailer, 0, part1);
+ ByteWriter.WriteBytes(this.Trailer, part1.Length, part2);
+ return base.GetBytes();
+ }
+ }
+}
diff --git a/SMBLibrary/NetBios/SessionPackets/SessionRetargetResponsePacket.cs b/SMBLibrary/NetBios/SessionPackets/SessionRetargetResponsePacket.cs
new file mode 100644
index 0000000..341510c
--- /dev/null
+++ b/SMBLibrary/NetBios/SessionPackets/SessionRetargetResponsePacket.cs
@@ -0,0 +1,38 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.NetBios
+{
+ public class SessionRetargetResponsePacket : SessionPacket
+ {
+ uint IPAddress;
+ ushort Port;
+
+ public SessionRetargetResponsePacket() : base()
+ {
+ this.Type = SessionPacketTypeName.RetargetSessionResponse;
+ }
+
+ public SessionRetargetResponsePacket(byte[] buffer) : base(buffer)
+ {
+ IPAddress = BigEndianConverter.ToUInt32(this.Trailer, 0);
+ Port = BigEndianConverter.ToUInt16(this.Trailer, 4);
+ }
+
+ public override byte[] GetBytes()
+ {
+ this.Trailer = new byte[6];
+ BigEndianWriter.WriteUInt32(this.Trailer, 0, IPAddress);
+ BigEndianWriter.WriteUInt16(this.Trailer, 4, Port);
+ return base.GetBytes();
+ }
+ }
+}
diff --git a/SMBLibrary/Properties/AssemblyInfo.cs b/SMBLibrary/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e133a0a
--- /dev/null
+++ b/SMBLibrary/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SMBLibrary")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Tal Aloni")]
+[assembly: AssemblyProduct("SMBLibrary")]
+[assembly: AssemblyCopyright("Copyright © Tal Aloni 2014-2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("301890e4-fc53-448e-8070-79d17086f922")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.5.0")]
+[assembly: AssemblyFileVersion("1.0.5.0")]
diff --git a/SMBLibrary/RPC/Enum/NegotiationResult.cs b/SMBLibrary/RPC/Enum/NegotiationResult.cs
new file mode 100644
index 0000000..7dc9595
--- /dev/null
+++ b/SMBLibrary/RPC/Enum/NegotiationResult.cs
@@ -0,0 +1,16 @@
+
+namespace SMBLibrary.RPC
+{
+ public enum NegotiationResult : ushort
+ {
+ Acceptance,
+ UserRejection,
+ ProviderRejection,
+
+ ///
+ /// Microsoft extension:
+ /// [MS-RPCE] 2.2.2.4 - negotiate_ack
+ ///
+ NegotiateAck
+ }
+}
diff --git a/SMBLibrary/RPC/Enum/PacketFlags.cs b/SMBLibrary/RPC/Enum/PacketFlags.cs
new file mode 100644
index 0000000..b536203
--- /dev/null
+++ b/SMBLibrary/RPC/Enum/PacketFlags.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace SMBLibrary.RPC
+{
+ [Flags]
+ public enum PacketFlags : byte
+ {
+ FirstFragment = 0x01, // PFC_FIRST_FRAG
+ LastFragment = 0x02, // PFC_LAST_FRAG
+ PendingCancel = 0x04, // PFC_PENDING_CANCEL
+ ConcurrntMultiplexing = 0x10, // PFC_CONC_MPX
+ DidNotExecute = 0x20, // PFC_DID_NOT_EXECUTE
+ Maybe = 0x40, // PFC_MAYBE
+ ObjectUUID = 0x80, // PFC_OBJECT_UUID
+ }
+}
diff --git a/SMBLibrary/RPC/Enum/PacketTypeName.cs b/SMBLibrary/RPC/Enum/PacketTypeName.cs
new file mode 100644
index 0000000..b20b110
--- /dev/null
+++ b/SMBLibrary/RPC/Enum/PacketTypeName.cs
@@ -0,0 +1,27 @@
+
+namespace SMBLibrary.RPC
+{
+ // Commented out packet types are connectionless-only
+ public enum PacketTypeName : byte
+ {
+ Request = 0x00,
+ // Ping = 0x01,
+ Response = 0x02,
+ Fault = 0x03,
+ //Working = 0x04,
+ //NoCall = 0x05,
+ //Reject = 0x06,
+ //Ack = 0x07,
+ //CLCancel = 0x08, // cl_cancel
+ //FAck = 0x09,
+ //CancelAck = 0x0A, // cancel_ack
+ Bind = 0x0B,
+ BindAck = 0x0C,
+ BindNak = 0x0D, // bind_nak
+ AlterContext = 0x0E, // alter_context
+ AlterContextResponse = 0x0F, // alter_context_resp
+ Shutdown = 0x11,
+ COCancel = 0x12, // co_cancel
+ Orphaned = 0x13,
+ }
+}
diff --git a/SMBLibrary/RPC/Enum/RejectionReason.cs b/SMBLibrary/RPC/Enum/RejectionReason.cs
new file mode 100644
index 0000000..f7fe094
--- /dev/null
+++ b/SMBLibrary/RPC/Enum/RejectionReason.cs
@@ -0,0 +1,11 @@
+
+namespace SMBLibrary.RPC
+{
+ public enum RejectionReason : ushort
+ {
+ NotSpecified,
+ AbstractSyntaxNotSupported,
+ ProposedTransferSyntaxesNotSupported,
+ LocalLimitExceeded,
+ }
+}
diff --git a/SMBLibrary/RPC/EnumStructures/DataRepresentationFormat.cs b/SMBLibrary/RPC/EnumStructures/DataRepresentationFormat.cs
new file mode 100644
index 0000000..f3ce352
--- /dev/null
+++ b/SMBLibrary/RPC/EnumStructures/DataRepresentationFormat.cs
@@ -0,0 +1,52 @@
+/* Copyright (C) 2014 Tal Aloni . 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;
+
+namespace SMBLibrary.RPC
+{
+ // See DCE 1.1: Remote Procedure Call, Chapter 14.1 - Data Representation Format Label
+ public enum CharacterFormat : byte
+ {
+ ASCII = 0x00,
+ EBCDIC = 0x01,
+ }
+
+ public enum ByteOrder : byte
+ {
+ BigEndian = 0x00,
+ LittleEndian = 0x01,
+ }
+
+ public enum FloatingPointRepresentation : byte
+ {
+ IEEE = 0x00,
+ VAX = 0x01,
+ Cray = 0x02,
+ IBM = 0x03,
+ }
+
+ public struct DataRepresentationFormat // uint
+ {
+ public CharacterFormat CharacterFormat;
+ public ByteOrder ByteOrder;
+ public FloatingPointRepresentation FloatingPointRepresentation;
+
+ public DataRepresentationFormat(byte[] buffer, int offset)
+ {
+ CharacterFormat = (CharacterFormat)(buffer[offset + 0] & 0x0F);
+ ByteOrder = (ByteOrder)(buffer[offset + 0] >> 4);
+ FloatingPointRepresentation = (FloatingPointRepresentation)(buffer[offset + 1]);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ buffer[offset + 0] = (byte)CharacterFormat;
+ buffer[offset + 0] |= (byte)((byte)ByteOrder << 4);
+ buffer[offset + 1] = (byte)FloatingPointRepresentation;
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/NDR/INDRStructure.cs b/SMBLibrary/RPC/NDR/INDRStructure.cs
new file mode 100644
index 0000000..928ae27
--- /dev/null
+++ b/SMBLibrary/RPC/NDR/INDRStructure.cs
@@ -0,0 +1,21 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// Serializable Structure / Union / Array
+ ///
+ public interface INDRStructure
+ {
+ void Read(NDRParser parser);
+ void Write(NDRWriter writer);
+ }
+}
diff --git a/SMBLibrary/RPC/NDR/NDRConformantArray.cs b/SMBLibrary/RPC/NDR/NDRConformantArray.cs
new file mode 100644
index 0000000..221507c
--- /dev/null
+++ b/SMBLibrary/RPC/NDR/NDRConformantArray.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary.RPC
+{
+ public class NDRConformantArray : List, INDRStructure where T : INDRStructure, new()
+ {
+ ///
+ /// See DCE 1.1: Remote Procedure Call - 14.3.3.2 - Uni-dimensional Conformant Arrays
+ ///
+ ///
+ public void Read(NDRParser parser)
+ {
+ parser.BeginStructure();
+ uint maxCount = parser.ReadUInt32();
+ for (int index = 0; index < maxCount; index++)
+ {
+ T entry = new T();
+ entry.Read(parser);
+ this.Add(entry);
+ }
+
+ parser.EndStructure();
+ }
+
+ public void Write(NDRWriter writer)
+ {
+ writer.BeginStructure();
+ uint maxCount = (uint)this.Count;
+ writer.WriteUInt32(maxCount);
+ for (int index = 0; index < this.Count; index++)
+ {
+ this[index].Write(writer);
+ }
+ writer.EndStructure();
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/NDR/NDRParser.cs b/SMBLibrary/RPC/NDR/NDRParser.cs
new file mode 100644
index 0000000..29d7684
--- /dev/null
+++ b/SMBLibrary/RPC/NDR/NDRParser.cs
@@ -0,0 +1,140 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// NDR - Native Data Representation
+ /// See DCE 1.1: Remote Procedure Call, Chapter 14 - Transfer Syntax NDR
+ ///
+ public class NDRParser
+ {
+ private byte[] m_buffer;
+ private int m_offset;
+ private int m_depth;
+ private List m_deferredStructures = new List();
+ private Dictionary m_referentToInstance = new Dictionary();
+
+ public NDRParser(byte[] buffer)
+ {
+ m_buffer = buffer;
+ m_offset = 0;
+ m_depth = 0;
+ }
+
+ public void BeginStructure()
+ {
+ m_depth++;
+ }
+
+ ///
+ /// Add embedded pointer deferred structure (referent) parser
+ ///
+ private void AddDeferredStructure(INDRStructure structure)
+ {
+ m_deferredStructures.Add(structure);
+ }
+
+ public void EndStructure()
+ {
+ m_depth--;
+ // 14.3.12.3 - Algorithm for Deferral of Referents
+ // Representations of (embedded) pointer referents are ordered according to a left-to-right, depth-first traversal of the embedding construction.
+ // referent representations for the embedded construction are further deferred to a position in the octet stream that
+ // follows the representation of the embedding construction. The set of referent representations for the embedded construction
+ // is inserted among the referent representations for any pointers in the embedding construction, according to the order of elements or
+ // members in the embedding construction
+ if (m_depth == 0)
+ {
+ // Make a copy of all the deferred structures, additional deferred structures will be inserted to m_deferredStructures
+ // as we process the existing list
+ List deferredStructures = new List(m_deferredStructures);
+ m_deferredStructures.Clear();
+ // Read all deferred types:
+ foreach (INDRStructure deferredStructure in deferredStructures)
+ {
+ deferredStructure.Read(this);
+ }
+ }
+ }
+
+ public string ReadUnicodeString()
+ {
+ NDRUnicodeString unicodeString = new NDRUnicodeString(this);
+ return unicodeString.Value;
+ }
+
+ public void ReadStructure(INDRStructure structure)
+ {
+ structure.Read(this);
+ }
+
+ // 14.3.11.1 - Top-level Full Pointers
+ public string ReadTopLevelUnicodeStringPointer()
+ {
+ uint referentID = ReadUInt32();
+ if (referentID == 0)
+ {
+ return null;
+ }
+
+ if (m_referentToInstance.ContainsKey(referentID))
+ {
+ NDRUnicodeString unicodeString = (NDRUnicodeString)m_referentToInstance[referentID];
+ return unicodeString.Value;
+ }
+ else
+ {
+ NDRUnicodeString unicodeString = new NDRUnicodeString(this);
+ m_referentToInstance.Add(referentID, unicodeString);
+ return unicodeString.Value;
+ }
+ }
+
+ public void ReadEmbeddedStructureFullPointer(ref NDRUnicodeString structure)
+ {
+ ReadEmbeddedStructureFullPointer(ref structure);
+ }
+
+ public void ReadEmbeddedStructureFullPointer(ref T structure) where T : INDRStructure, new ()
+ {
+ uint referentID = ReadUInt32();
+ if (referentID != 0) // not null
+ {
+ if (structure == null)
+ {
+ structure = new T();
+ }
+ AddDeferredStructure(structure);
+ }
+ else
+ {
+ structure = default(T);
+ }
+ }
+
+ // 14.2.2 - Alignment of Primitive Types
+ public uint ReadUInt16()
+ {
+ m_offset += (2 - (m_offset % 2)) % 2;
+ return LittleEndianReader.ReadUInt16(m_buffer, ref m_offset);
+ }
+
+ // 14.2.2 - Alignment of Primitive Types
+ public uint ReadUInt32()
+ {
+ m_offset += (4 - (m_offset % 4)) % 4;
+ return LittleEndianReader.ReadUInt32(m_buffer, ref m_offset);
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/NDR/NDRTypeName.cs b/SMBLibrary/RPC/NDR/NDRTypeName.cs
new file mode 100644
index 0000000..218fa79
--- /dev/null
+++ b/SMBLibrary/RPC/NDR/NDRTypeName.cs
@@ -0,0 +1,16 @@
+/* Copyright (C) 2014 Tal Aloni . 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.
+ */
+namespace SMBLibrary.RPC
+{
+ ///
+ /// Primitive and construced types
+ ///
+ public enum NDRTypeName
+ {
+ UnicodeString,
+ }
+}
diff --git a/SMBLibrary/RPC/NDR/NDRUnicodeString.cs b/SMBLibrary/RPC/NDR/NDRUnicodeString.cs
new file mode 100644
index 0000000..bab3f62
--- /dev/null
+++ b/SMBLibrary/RPC/NDR/NDRUnicodeString.cs
@@ -0,0 +1,74 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ public class NDRUnicodeString : INDRStructure
+ {
+ public string Value;
+
+ public NDRUnicodeString()
+ {
+ Value = String.Empty;
+ }
+
+ public NDRUnicodeString(string value)
+ {
+ Value = value;
+ }
+
+ public NDRUnicodeString(NDRParser parser)
+ {
+ Read(parser);
+ }
+
+ // 14.3.4.2 - Conformant and Varying Strings
+ public void Read(NDRParser parser)
+ {
+ uint maxCount = parser.ReadUInt32();
+ // the offset from the first index of the string to the first index of the actual subset being passed
+ uint index = parser.ReadUInt32();
+ // actualCount includes the null terminator
+ uint actualCount = parser.ReadUInt32();
+ StringBuilder builder = new StringBuilder();
+ for (int position = 0; position < actualCount - 1; position++)
+ {
+ builder.Append((char)parser.ReadUInt16());
+ }
+ this.Value = builder.ToString();
+ parser.ReadUInt16(); // null terminator
+ }
+
+ public void Write(NDRWriter writer)
+ {
+ int length = 0;
+ if (Value != null)
+ {
+ length = Value.Length;
+ }
+
+ // maxCount includes the null terminator
+ uint maxCount = (uint)(length + 1);
+ writer.WriteUInt32(maxCount);
+ // the offset from the first index of the string to the first index of the actual subset being passed
+ uint index = 0;
+ writer.WriteUInt32(index);
+ // actualCount includes the null terminator
+ uint actualCount = (uint)(length + 1);
+ writer.WriteUInt32(actualCount);
+ for (int position = 0; position < length; position++)
+ {
+ writer.WriteUInt16((ushort)Value[position]);
+ }
+ writer.WriteUInt16(0); // null terminator
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/NDR/NDRWriter.cs b/SMBLibrary/RPC/NDR/NDRWriter.cs
new file mode 100644
index 0000000..78b7f3c
--- /dev/null
+++ b/SMBLibrary/RPC/NDR/NDRWriter.cs
@@ -0,0 +1,140 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// NDR - Native Data Representation
+ /// See DCE 1.1: Remote Procedure Call, Chapter 14 - Transfer Syntax NDR
+ ///
+ public class NDRWriter
+ {
+ private MemoryStream m_stream = new MemoryStream();
+ private int m_depth;
+ private List m_deferredStructures = new List();
+ private Dictionary m_referentToInstance = new Dictionary();
+ private uint m_nextReferentID = 0x00020000;
+
+ public void BeginStructure()
+ {
+ m_depth++;
+ }
+
+ ///
+ /// Add embedded pointer deferred structure (referent) writer
+ ///
+ private void AddDeferredStructure(INDRStructure structure)
+ {
+ m_deferredStructures.Add(structure);
+ }
+
+ public void EndStructure()
+ {
+ m_depth--;
+ // 14.3.12.3 - Algorithm for Deferral of Referents
+ // Representations of (embedded) pointer referents are ordered according to a left-to-right, depth-first traversal of the embedding construction.
+ // referent representations for the embedded construction are further deferred to a position in the octet stream that
+ // follows the representation of the embedding construction. The set of referent representations for the embedded construction
+ // is inserted among the referent representations for any pointers in the embedding construction, according to the order of elements or
+ // members in the embedding construction
+ if (m_depth == 0)
+ {
+ // Make a copy of all the deferred structures, additional deferred structures will be inserted to m_deferredStructures
+ // as we process the existing list
+ List deferredStructures = new List(m_deferredStructures);
+ m_deferredStructures.Clear();
+ // Write all deferred types:
+ foreach (INDRStructure deferredStructure in deferredStructures)
+ {
+ deferredStructure.Write(this);
+ }
+ }
+ }
+
+ public void WriteUnicodeString(string value)
+ {
+ NDRUnicodeString unicodeString = new NDRUnicodeString(value);
+ unicodeString.Write(this);
+ }
+
+ public void WriteStructure(INDRStructure structure)
+ {
+ structure.Write(this);
+ }
+
+ public void WriteTopLevelUnicodeStringPointer(string value)
+ {
+ if (value == null)
+ {
+ WriteUInt32(0);
+ return;
+ }
+
+ // Note: We do not bother searching for existing values
+ uint referentID = GetNextReferentID();
+ WriteUInt32(referentID);
+ NDRUnicodeString unicodeString = new NDRUnicodeString(value);
+ unicodeString.Write(this);
+ m_referentToInstance.Add(referentID, unicodeString);
+ }
+
+ // 14.3.12.1 Embedded Full Pointers
+ public void WriteEmbeddedStructureFullPointer(INDRStructure structure)
+ {
+ if (structure == null)
+ {
+ WriteUInt32(0); // null
+ return;
+ }
+ else
+ {
+ // Note: We do not bother searching for existing values
+ uint referentID = GetNextReferentID();
+ WriteUInt32(referentID);
+ AddDeferredStructure(structure);
+ m_referentToInstance.Add(referentID, structure);
+ }
+ }
+
+ // 14.2.2 - Alignment of Primitive Types
+ public void WriteUInt16(ushort value)
+ {
+ uint padding = (uint)(2 - (m_stream.Position % 2)) % 2;
+ m_stream.Position += padding;
+ LittleEndianWriter.WriteUInt16(m_stream, value);
+ }
+
+ // 14.2.2 - Alignment of Primitive Types
+ public void WriteUInt32(uint value)
+ {
+ uint padding = (uint)(4 - (m_stream.Position % 4)) % 4;
+ m_stream.Position += padding;
+ LittleEndianWriter.WriteUInt32(m_stream, value);
+ }
+
+ public byte[] GetBytes()
+ {
+ byte[] buffer = new byte[m_stream.Length];
+ m_stream.Seek(0, SeekOrigin.Begin);
+ m_stream.Read(buffer, 0, buffer.Length);
+ return buffer;
+ }
+
+ private uint GetNextReferentID()
+ {
+ uint result = m_nextReferentID;
+ m_nextReferentID++;
+ return result;
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/PDU/BindAckPDU.cs b/SMBLibrary/RPC/PDU/BindAckPDU.cs
new file mode 100644
index 0000000..262ff11
--- /dev/null
+++ b/SMBLibrary/RPC/PDU/BindAckPDU.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// rpcconn_bind_ack_hdr_t
+ ///
+ public class BindAckPDU : RPCPDU
+ {
+ public ushort MaxTransmitFragmentSize; // max_xmit_frag
+ public ushort MaxReceiveFragmentSize; // max_recv_frag
+ public uint AssociationGroupID; // assoc_group_id
+ public string SecondaryAddress; // sec_addr (port_any_t)
+ // Padding (alignment to 4 byte boundary)
+ public ResultList ResultList; // p_result_list
+ public byte[] AuthVerifier;
+
+ public BindAckPDU() : base()
+ {
+ PacketType = PacketTypeName.BindAck;
+ SecondaryAddress = String.Empty;
+ ResultList = new ResultList();
+ AuthVerifier = new byte[0];
+ }
+
+ public BindAckPDU(byte[] buffer) : base(buffer)
+ {
+ int offset = RPCPDU.CommonFieldsLength;
+ MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ SecondaryAddress = RPCHelper.ReadPortAddress(buffer, ref offset);
+ int padding = (4 - (offset % 4)) % 4;
+ offset += padding;
+ ResultList = new ResultList(buffer, offset);
+ offset += ResultList.Length;
+ AuthVerifier = ByteReader.ReadBytes(buffer, offset, AuthLength);
+ }
+
+ public override byte[] GetBytes()
+ {
+ AuthLength = (ushort)AuthVerifier.Length;
+ int padding = (4 - ((SecondaryAddress.Length + 3) % 4)) % 4;
+ FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + SecondaryAddress.Length + 3 + padding + ResultList.Length + AuthLength);
+ byte[] buffer = new byte[FragmentLength];
+ WriteCommonFieldsBytes(buffer);
+ int offset = RPCPDU.CommonFieldsLength;
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxTransmitFragmentSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxReceiveFragmentSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AssociationGroupID);
+ RPCHelper.WritePortAddress(buffer, ref offset, SecondaryAddress);
+ offset += padding;
+ ResultList.WriteBytes(buffer, ref offset);
+ ByteWriter.WriteBytes(buffer, offset, AuthVerifier);
+
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/PDU/BindPDU.cs b/SMBLibrary/RPC/PDU/BindPDU.cs
new file mode 100644
index 0000000..efad960
--- /dev/null
+++ b/SMBLibrary/RPC/PDU/BindPDU.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// rpcconn_bind_hdr_t
+ ///
+ public class BindPDU : RPCPDU
+ {
+ public ushort MaxTransmitFragmentSize; // max_xmit_frag
+ public ushort MaxReceiveFragmentSize; // max_recv_frag
+ public uint AssociationGroupID; // assoc_group_id
+ public ContextList ContextList;
+ public byte[] AuthVerifier;
+
+ public BindPDU() : base()
+ {
+ PacketType = PacketTypeName.Bind;
+ ContextList = new ContextList();
+ AuthVerifier = new byte[0];
+ }
+
+ public BindPDU(byte[] buffer) : base(buffer)
+ {
+ int offset = RPCPDU.CommonFieldsLength;
+ MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ ContextList = new ContextList(buffer, offset);
+ offset += ContextList.Length;
+ AuthVerifier = ByteReader.ReadBytes(buffer, offset, AuthLength);
+ }
+
+ public override byte[] GetBytes()
+ {
+ AuthLength =(ushort)AuthVerifier.Length;
+ FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + ContextList.Length + AuthLength);
+ byte[] buffer = new byte[FragmentLength];
+ WriteCommonFieldsBytes(buffer);
+ int offset = RPCPDU.CommonFieldsLength;
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxTransmitFragmentSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxReceiveFragmentSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AssociationGroupID);
+ ContextList.WriteBytes(buffer, ref offset);
+ ByteWriter.WriteBytes(buffer, offset, AuthVerifier);
+
+ return buffer;
+ }
+
+ }
+}
diff --git a/SMBLibrary/RPC/PDU/FaultPDU.cs b/SMBLibrary/RPC/PDU/FaultPDU.cs
new file mode 100644
index 0000000..07df1d1
--- /dev/null
+++ b/SMBLibrary/RPC/PDU/FaultPDU.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// rpcconn_fault_hdr_t
+ ///
+ public class FaultPDU : RPCPDU
+ {
+ public uint AllocationHint;
+ public ushort ContextID;
+ public byte CancelCount;
+ public byte Reserved;
+ public uint Status;
+ public uint Reserved2;
+ public byte[] Data;
+ public byte[] AuthVerifier;
+
+ public FaultPDU() : base()
+ {
+ PacketType = PacketTypeName.Fault;
+ AuthVerifier = new byte[0];
+ }
+
+ public FaultPDU(byte[] buffer) : base(buffer)
+ {
+ int offset = RPCPDU.CommonFieldsLength;
+ AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ CancelCount = ByteReader.ReadByte(buffer, ref offset);
+ Reserved = ByteReader.ReadByte(buffer, ref offset);
+ Status = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Reserved2 = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ int dataLength = FragmentLength - AuthLength - offset;
+ Data = ByteReader.ReadBytes(buffer, ref offset, dataLength);
+ AuthVerifier = ByteReader.ReadBytes(buffer, offset, AuthLength);
+ }
+
+ public override byte[] GetBytes()
+ {
+ AuthLength = (ushort)AuthVerifier.Length;
+ FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 16 + Data.Length + AuthVerifier.Length);
+ byte[] buffer = new byte[FragmentLength];
+ WriteCommonFieldsBytes(buffer);
+ int offset = RPCPDU.CommonFieldsLength;
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationHint);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, ContextID);
+ ByteWriter.WriteByte(buffer, ref offset, CancelCount);
+ ByteWriter.WriteByte(buffer, ref offset, Reserved);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, Status);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, Reserved2);
+ ByteWriter.WriteBytes(buffer, ref offset, Data);
+ ByteWriter.WriteBytes(buffer, ref offset, AuthVerifier);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/PDU/RPCPDU.cs b/SMBLibrary/RPC/PDU/RPCPDU.cs
new file mode 100644
index 0000000..50cafb5
--- /dev/null
+++ b/SMBLibrary/RPC/PDU/RPCPDU.cs
@@ -0,0 +1,83 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// See DCE 1.1: Remote Procedure Call, Chapter 12.6 - Connection-oriented RPC PDUs
+ ///
+ public abstract class RPCPDU
+ {
+ public const int CommonFieldsLength = 16;
+
+ // The common header fields, which appear in all (connection oriented) PDU types:
+ public byte VersionMajor; // rpc_vers
+ public byte VersionMinor; // rpc_vers_minor
+ public PacketTypeName PacketType;
+ public PacketFlags Flags;
+ public DataRepresentationFormat DataRepresentation;
+ public ushort FragmentLength;
+ public ushort AuthLength;
+ public uint CallID;
+
+ public RPCPDU()
+ {
+ VersionMajor = 5;
+ VersionMinor = 0;
+ }
+
+ public RPCPDU(byte[] buffer)
+ {
+ VersionMajor = ByteReader.ReadByte(buffer, 0);
+ VersionMinor = ByteReader.ReadByte(buffer, 1);
+ PacketType = (PacketTypeName)ByteReader.ReadByte(buffer, 2);
+ Flags = (PacketFlags)ByteReader.ReadByte(buffer, 3);
+ DataRepresentation = new DataRepresentationFormat(buffer, 4);
+ FragmentLength = LittleEndianConverter.ToUInt16(buffer, 8);
+ AuthLength = LittleEndianConverter.ToUInt16(buffer, 10);
+ CallID = LittleEndianConverter.ToUInt32(buffer, 12);
+ }
+
+ public abstract byte[] GetBytes();
+
+ public void WriteCommonFieldsBytes(byte[] buffer)
+ {
+ ByteWriter.WriteByte(buffer, 0, VersionMajor);
+ ByteWriter.WriteByte(buffer, 1, VersionMinor);
+ ByteWriter.WriteByte(buffer, 2, (byte)PacketType);
+ ByteWriter.WriteByte(buffer, 3, (byte)Flags);
+ DataRepresentation.WriteBytes(buffer, 4);
+ LittleEndianWriter.WriteUInt16(buffer, 8, FragmentLength);
+ LittleEndianWriter.WriteUInt16(buffer, 10, AuthLength);
+ LittleEndianWriter.WriteUInt32(buffer, 12, CallID);
+ }
+
+ public static RPCPDU GetPDU(byte[] buffer)
+ {
+ PacketTypeName packetType = (PacketTypeName)ByteReader.ReadByte(buffer, 2);
+ switch (packetType)
+ {
+ case PacketTypeName.Request:
+ return new RequestPDU(buffer);
+ case PacketTypeName.Response:
+ return new ResponsePDU(buffer);
+ case PacketTypeName.Fault:
+ return new FaultPDU(buffer);
+ case PacketTypeName.Bind:
+ return new BindPDU(buffer);
+ case PacketTypeName.BindAck:
+ return new BindAckPDU(buffer);
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/PDU/RequestPDU.cs b/SMBLibrary/RPC/PDU/RequestPDU.cs
new file mode 100644
index 0000000..58d3f06
--- /dev/null
+++ b/SMBLibrary/RPC/PDU/RequestPDU.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// rpcconn_request_hdr_t
+ ///
+ public class RequestPDU : RPCPDU
+ {
+ public uint AllocationHint; // alloc_hint
+ public ushort ContextID;
+ public ushort OpNum;
+ public Guid ObjectGuid; // Optional field
+ public byte[] Data;
+ public byte[] AuthVerifier;
+
+ public RequestPDU() : base()
+ {
+ PacketType = PacketTypeName.Request;
+ AuthVerifier = new byte[0];
+ }
+
+ public RequestPDU(byte[] buffer) : base(buffer)
+ {
+ int offset = RPCPDU.CommonFieldsLength;
+ AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ OpNum = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ if ((Flags & PacketFlags.ObjectUUID) > 0)
+ {
+ ObjectGuid = LittleEndianReader.ReadGuid(buffer, ref offset);
+ }
+ int dataLength = FragmentLength - AuthLength - offset;
+ Data = ByteReader.ReadBytes(buffer, ref offset, dataLength);
+ AuthVerifier = ByteReader.ReadBytes(buffer, offset, AuthLength);
+ }
+
+ public override byte[] GetBytes()
+ {
+ AuthLength = (ushort)AuthVerifier.Length;
+ FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + Data.Length + AuthVerifier.Length);
+ if ((Flags & PacketFlags.ObjectUUID) > 0)
+ {
+ FragmentLength += 16;
+ }
+ byte[] buffer = new byte[FragmentLength];
+ WriteCommonFieldsBytes(buffer);
+ int offset = RPCPDU.CommonFieldsLength;
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationHint);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, ContextID);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, OpNum);
+ if ((Flags & PacketFlags.ObjectUUID) > 0)
+ {
+ LittleEndianWriter.WriteGuidBytes(buffer, ref offset, ObjectGuid);
+ }
+ ByteWriter.WriteBytes(buffer, ref offset, Data);
+ ByteWriter.WriteBytes(buffer, ref offset, AuthVerifier);
+ return buffer;
+ }
+
+
+ }
+}
diff --git a/SMBLibrary/RPC/PDU/ResponsePDU.cs b/SMBLibrary/RPC/PDU/ResponsePDU.cs
new file mode 100644
index 0000000..9c94308
--- /dev/null
+++ b/SMBLibrary/RPC/PDU/ResponsePDU.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// rpcconn_response_hdr_t
+ ///
+ public class ResponsePDU : RPCPDU
+ {
+ private uint AllocationHint;
+ public ushort ContextID;
+ public byte CancelCount;
+ public byte Reserved;
+ public byte[] Data;
+ public byte[] AuthVerifier;
+
+ public ResponsePDU() : base()
+ {
+ PacketType = PacketTypeName.Response;
+ AuthVerifier = new byte[0];
+ }
+
+ public ResponsePDU(byte[] buffer) : base(buffer)
+ {
+ int offset = RPCPDU.CommonFieldsLength;
+ AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ CancelCount = ByteReader.ReadByte(buffer, ref offset);
+ Reserved = ByteReader.ReadByte(buffer, ref offset);
+ int dataLength = FragmentLength - AuthLength - offset;
+ Data = ByteReader.ReadBytes(buffer, ref offset, dataLength);
+ AuthVerifier = ByteReader.ReadBytes(buffer, offset, AuthLength);
+ }
+
+ public override byte[] GetBytes()
+ {
+ AuthLength = (ushort)AuthVerifier.Length;
+ FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + Data.Length + AuthVerifier.Length);
+ AllocationHint = (ushort)Data.Length;
+
+ byte[] buffer = new byte[FragmentLength];
+ WriteCommonFieldsBytes(buffer);
+ int offset = RPCPDU.CommonFieldsLength;
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationHint);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, ContextID);
+ ByteWriter.WriteByte(buffer, ref offset, CancelCount);
+ ByteWriter.WriteByte(buffer, ref offset, Reserved);
+ ByteWriter.WriteBytes(buffer, ref offset, Data);
+ ByteWriter.WriteBytes(buffer, ref offset, AuthVerifier);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/RPCHelper.cs b/SMBLibrary/RPC/RPCHelper.cs
new file mode 100644
index 0000000..ce2078b
--- /dev/null
+++ b/SMBLibrary/RPC/RPCHelper.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ public class RPCHelper
+ {
+ ///
+ /// Read port_any_t string structure
+ ///
+ public static string ReadPortAddress(byte[] buffer, int offset)
+ {
+ ushort length = LittleEndianConverter.ToUInt16(buffer, offset + 0);
+ // The length includes the C NULL string termination
+ return ByteReader.ReadAnsiString(buffer, offset + 2, length - 1);
+ }
+
+ public static string ReadPortAddress(byte[] buffer, ref int offset)
+ {
+ string result = ReadPortAddress(buffer, offset);
+ offset += result.Length + 3;
+ return result;
+ }
+
+ public static void WritePortAddress(byte[] buffer, int offset, string value)
+ {
+ ushort length = (ushort)(value.Length + 1);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 0, length);
+ ByteWriter.WriteNullTerminatedAnsiString(buffer, offset + 2, value);
+ }
+
+ public static void WritePortAddress(byte[] buffer, ref int offset, string value)
+ {
+ WritePortAddress(buffer, offset, value);
+ offset += value.Length + 3;
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/Structures/ContextElement.cs b/SMBLibrary/RPC/Structures/ContextElement.cs
new file mode 100644
index 0000000..d76588a
--- /dev/null
+++ b/SMBLibrary/RPC/Structures/ContextElement.cs
@@ -0,0 +1,65 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// p_cont_elem_t
+ ///
+ public class ContextElement // Presentation Context Element
+ {
+ public ushort ContextID;
+ //byte NumberOfTransferSyntaxItems;
+ public byte Reserved;
+ public SyntaxID AbstractSyntax;
+ public List TransferSyntaxList = new List();
+
+ public ContextElement(byte[] buffer, int offset)
+ {
+ ContextID = LittleEndianConverter.ToUInt16(buffer, offset + 0);
+ byte numberOfTransferSyntaxItems = ByteReader.ReadByte(buffer, offset + 2);
+ Reserved = ByteReader.ReadByte(buffer, offset + 3);
+ AbstractSyntax = new SyntaxID(buffer, offset + 4);
+ offset += 4 + SyntaxID.Length;
+ for (int index = 0; index < numberOfTransferSyntaxItems; index++)
+ {
+ SyntaxID syntax = new SyntaxID(buffer, offset);
+ TransferSyntaxList.Add(syntax);
+ offset += SyntaxID.Length;
+ }
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ byte numberOfTransferSyntaxItems = (byte)TransferSyntaxList.Count;
+
+ LittleEndianWriter.WriteUInt16(buffer, offset + 0, ContextID);
+ ByteWriter.WriteByte(buffer, offset + 2, numberOfTransferSyntaxItems);
+ ByteWriter.WriteByte(buffer, offset + 3, Reserved);
+ AbstractSyntax.WriteBytes(buffer, offset + 4);
+ offset += 4 + SyntaxID.Length;
+
+ for (int index = 0; index < numberOfTransferSyntaxItems; index++)
+ {
+ TransferSyntaxList[index].WriteBytes(buffer, offset);
+ offset += SyntaxID.Length;
+ }
+ }
+
+ public int Length
+ {
+ get
+ {
+ return 4 + SyntaxID.Length * (TransferSyntaxList.Count + 1);
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/Structures/ContextList.cs b/SMBLibrary/RPC/Structures/ContextList.cs
new file mode 100644
index 0000000..492f4d3
--- /dev/null
+++ b/SMBLibrary/RPC/Structures/ContextList.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// p_cont_list_t
+ /// Presentation Context List
+ ///
+ public class ContextList : List
+ {
+ //byte NumberOfContextElements;
+ public byte Reserved1;
+ public ushort Reserved2;
+
+ public ContextList() : base()
+ {
+ }
+
+ public ContextList(byte[] buffer, int offset) : base()
+ {
+ byte numberOfContextElements = ByteReader.ReadByte(buffer, offset + 0);
+ Reserved1 = ByteReader.ReadByte(buffer, offset + 1);
+ Reserved2 = LittleEndianConverter.ToUInt16(buffer, offset + 2);
+ offset += 4;
+ for (int index = 0; index < numberOfContextElements; index++)
+ {
+ ContextElement element = new ContextElement(buffer, offset);
+ this.Add(element);
+ offset += element.Length;
+ }
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ byte numberOfContextElements = (byte)this.Count;
+
+ ByteWriter.WriteByte(buffer, offset + 0, numberOfContextElements);
+ ByteWriter.WriteByte(buffer, offset + 1, Reserved1);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved2);
+ offset += 4;
+ for (int index = 0; index < numberOfContextElements; index++)
+ {
+ this[index].WriteBytes(buffer, offset);
+ offset += this[index].Length;
+ }
+ }
+
+ public void WriteBytes(byte[] buffer, ref int offset)
+ {
+ WriteBytes(buffer, offset);
+ offset += this.Length;
+ }
+
+ public int Length
+ {
+ get
+ {
+ int length = 4;
+ for (int index = 0; index < this.Count; index++)
+ {
+ length += this[index].Length;
+ }
+ return length;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/Structures/ResultElement.cs b/SMBLibrary/RPC/Structures/ResultElement.cs
new file mode 100644
index 0000000..1f74311
--- /dev/null
+++ b/SMBLibrary/RPC/Structures/ResultElement.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// p_result_t
+ ///
+ public struct ResultElement
+ {
+ public const int Length = 24;
+
+ public NegotiationResult Result;
+ public RejectionReason Reason;
+ public SyntaxID TransferSyntax;
+
+ public ResultElement(byte[] buffer, int offset)
+ {
+ Result = (NegotiationResult)LittleEndianConverter.ToUInt16(buffer, offset + 0);
+ Reason = (RejectionReason)LittleEndianConverter.ToUInt16(buffer, offset + 2);
+ TransferSyntax = new SyntaxID(buffer, offset + 4);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ LittleEndianWriter.WriteUInt16(buffer, offset + 0, (ushort)Result);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 2, (ushort)Reason);
+ TransferSyntax.WriteBytes(buffer, offset + 4);
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/Structures/ResultList.cs b/SMBLibrary/RPC/Structures/ResultList.cs
new file mode 100644
index 0000000..2315f19
--- /dev/null
+++ b/SMBLibrary/RPC/Structures/ResultList.cs
@@ -0,0 +1,69 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// p_result_list_t
+ ///
+ public class ResultList : List
+ {
+ //byte NumberOfResults;
+ public byte Reserved;
+ public ushort Reserved2;
+
+ public ResultList() : base()
+ {}
+
+ public ResultList(byte[] buffer, int offset) : base()
+ {
+ byte numberOfResults = ByteReader.ReadByte(buffer, offset + 0);
+ Reserved = ByteReader.ReadByte(buffer, offset + 1);
+ Reserved2 = LittleEndianConverter.ToUInt16(buffer, offset + 2);
+ offset += 4;
+ for (int index = 0; index < numberOfResults; index++)
+ {
+ ResultElement element = new ResultElement(buffer, offset);
+ this.Add(element);
+ offset += ResultElement.Length;
+ }
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ byte numberOfResults = (byte)this.Count;
+
+ ByteWriter.WriteByte(buffer, offset + 0, numberOfResults);
+ ByteWriter.WriteByte(buffer, offset + 1, Reserved);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 2, Reserved2);
+ offset += 4;
+ for (int index = 0; index < numberOfResults; index++)
+ {
+ this[index].WriteBytes(buffer, offset);
+ offset += ResultElement.Length;
+ }
+ }
+
+ public void WriteBytes(byte[] buffer, ref int offset)
+ {
+ WriteBytes(buffer, offset);
+ offset += this.Length;
+ }
+
+ public int Length
+ {
+ get
+ {
+ return 4 + ResultElement.Length * this.Count;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/RPC/Structures/SyntaxID.cs b/SMBLibrary/RPC/Structures/SyntaxID.cs
new file mode 100644
index 0000000..ccb5a1c
--- /dev/null
+++ b/SMBLibrary/RPC/Structures/SyntaxID.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.RPC
+{
+ ///
+ /// p_syntax_id_t
+ ///
+ public struct SyntaxID
+ {
+ public const int Length = 20;
+
+ public Guid InterfaceUUID; // if_uuid
+ public uint InterfaceVersion; // if_version
+
+ public SyntaxID(Guid interfaceUUID, uint interfaceVersion)
+ {
+ InterfaceUUID = interfaceUUID;
+ InterfaceVersion = interfaceVersion;
+ }
+
+ public SyntaxID(byte[] buffer, int offset)
+ {
+ InterfaceUUID = LittleEndianConverter.ToGuid(buffer, offset + 0);
+ InterfaceVersion = LittleEndianConverter.ToUInt32(buffer, offset + 16);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ LittleEndianWriter.WriteGuidBytes(buffer, offset + 0, InterfaceUUID);
+ LittleEndianWriter.WriteUInt32(buffer, offset + 16, InterfaceVersion);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is SyntaxID)
+ {
+ return this.InterfaceUUID.Equals(((SyntaxID)obj).InterfaceUUID) && this.InterfaceVersion.Equals(((SyntaxID)obj).InterfaceVersion);
+ }
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return InterfaceUUID.GetHashCode() * InterfaceVersion.GetHashCode();
+ }
+ }
+}
diff --git a/SMBLibrary/Readme.txt b/SMBLibrary/Readme.txt
new file mode 100644
index 0000000..3eb3fd5
--- /dev/null
+++ b/SMBLibrary/Readme.txt
@@ -0,0 +1,43 @@
+About SMBLibrary:
+=================
+SMBLibrary is an open-source C# SMB 1.0/CIFS 1.0 server implementation.
+SMBLibrary gives .NET developers an easy way to share a directory / file system / virtual file system, with any operating system that supports the SMB protocol.
+SMBLibrary shares can be accessed from any Windows version since Windows NT 4.0.
+
+Supported SMB / CIFS transport methods:
+=======================================
+NetBIOS over TCP (port 139)
+Direct TCP hosting (port 445)
+
+Notes:
+------
+1. Windows bind port 139 on a per-adapter basis, while port 445 is bound globally.
+This means that you can't use direct TCP hosting without disabling Windows File and Printer Sharing server completely.
+However, NetBIOS over TCP is almost identical, and for this reason, it's recommended to use port 139.
+
+2. To free port 139 for a given adapter, go to 'Internet Protocol (TCP/IP) Properties' > Advanced > WINS,
+and select 'Disable NetBIOS over TCP/IP'. in addition you need to uncheck 'File and Printer Sharing for Microsoft Networks'.
+
+3. It's important to note that disabling NetBIOS over TCP/IP will also disable NetBIOS name service for that adapter (a.k.a. WINS),
+This service uses UDP port 137. SMBLibrary offers a name service of its own.
+
+4. You can install a virtual network adapter driver for Windows to be used solely with SMBLibrary:
+- You can install the 'Microsoft Loopback adapter' and use it for server-only communication with SMBLibrary.
+- A limited alternative is 'OpenVPN TAP-Windows Adapter' that can be used for client communication with SMBLibrary,
+However, you will have to configure this adapter to use a separate network segment.
+The driver installation can be downloaded from: https://openvpn.net/index.php/open-source/downloads.html
+To get started, go to Adapter properties > 'Advanced' and set 'Media Status' to 'Always Connected'.
+
+5. The differences between 'Direct TCP hosting' and 'NetBIOS over TCP' are:
+- A 'session request' packet is initiating the NBT connection.
+- A 'keep alive' packet is sent from time to time over NBT connections.
+
+Using SMBLibrary:
+=================
+Any directory / filesystem / object you wish to share must implement the IFileSystem interface.
+You can share anything from actual directories to custom objects, as long as they expose a directory structure.
+
+Contact:
+========
+If you have any question, feel free to contact me.
+Tal Aloni
\ No newline at end of file
diff --git a/SMBLibrary/RevisionHistory.txt b/SMBLibrary/RevisionHistory.txt
new file mode 100644
index 0000000..2d3ef06
--- /dev/null
+++ b/SMBLibrary/RevisionHistory.txt
@@ -0,0 +1,14 @@
+Revision History:
+-----------------
+1.0.0 - Initial release.
+
+1.0.1 - Better handling of invalid read / write operations.
+
+1.0.2 - Improved documentation and updated SMB_COM_TRANSACTION2 request (Technical Specifications Errata was found).
+
+1.0.3 - Search handles (SID) are now properly closed.
+
+1.0.4 - Added support for IPv6.
+
+1.0.5 - bugfix: SMB_COM_OPEN_ANDX was not returning the requested response format.
+ File buffering logic logic was moved to a separate class.
diff --git a/SMBLibrary/SMB1/EnumStructures/NamedPipeStatus.cs b/SMBLibrary/SMB1/EnumStructures/NamedPipeStatus.cs
new file mode 100644
index 0000000..c3eadec
--- /dev/null
+++ b/SMBLibrary/SMB1/EnumStructures/NamedPipeStatus.cs
@@ -0,0 +1,95 @@
+/* Copyright (C) 2014 Tal Aloni . 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;
+
+namespace SMBLibrary.SMB1
+{
+ public enum ReadMode : byte
+ {
+ ByteMode = 0x00,
+ MessageMode = 0x01,
+ }
+
+ public enum NamedPipeType : byte
+ {
+ ByteNamedPipe = 0x00,
+ MessageNodePipe = 0x01,
+ }
+
+ public enum Endpoint : byte
+ {
+ ClientSideEnd = 0x00,
+ ServerSideEnd = 0x01,
+ }
+
+ public enum NonBlocking : byte
+ {
+ Block = 0x00,
+ DoNotBlock = 0x01,
+ }
+
+ ///
+ /// SMB_NMPIPE_STATUS
+ ///
+ public struct NamedPipeStatus // ushort
+ {
+ public byte ICount;
+ public ReadMode ReadMode;
+ public NamedPipeType NamedPipeType;
+ public Endpoint Endpoint;
+ public NonBlocking NonBlocking;
+
+ public NamedPipeStatus(byte[] buffer, int offset)
+ {
+ ICount = buffer[offset];
+ ReadMode = (ReadMode)(buffer[offset + 1] & 0x03);
+ NamedPipeType = (NamedPipeType)((buffer[offset + 1] & 0x0C) >> 2);
+ Endpoint = (Endpoint)((buffer[offset + 1] & 0x40) >> 6);
+ NonBlocking = (NonBlocking)((buffer[offset + 1] & 0x80) >> 7);
+ }
+
+ public NamedPipeStatus(ushort value)
+ {
+ ICount = (byte)(value & 0xFF);
+ ReadMode = (ReadMode)((value & 0x0300) >> 8);
+ NamedPipeType = (NamedPipeType)((value & 0x0C00) >> 10);
+ Endpoint = (Endpoint)((value & 0x4000) >> 14);
+ NonBlocking = (NonBlocking)((value & 0x80) >> 15);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ buffer[offset + 0] = ICount;
+ buffer[offset + 1] = (byte)((byte)ReadMode & 0x03);
+ buffer[offset + 1] |= (byte)(((byte)NamedPipeType << 2) & 0x0C);
+ buffer[offset + 1] |= (byte)(((byte)Endpoint << 6) & 0x40);
+ buffer[offset + 1] |= (byte)(((byte)NonBlocking << 7) & 0x80);
+ }
+
+ public void WriteBytes(byte[] buffer, ref int offset)
+ {
+ WriteBytes(buffer, offset);
+ offset += 2;
+ }
+
+ public ushort ToUInt16()
+ {
+ ushort result = ICount;
+ result |= (ushort)(((byte)ReadMode << 8) & 0x0300);
+ result |= (ushort)(((byte)NamedPipeType << 10) & 0x0C00);
+ result |= (ushort)(((byte)Endpoint << 14) & 0x4000);
+ result |= (ushort)(((byte)NonBlocking << 15) & 0x8000);
+ return result;
+ }
+
+ public static NamedPipeStatus Read(byte[] buffer, ref int offset)
+ {
+ offset += 2;
+ return new NamedPipeStatus(buffer, offset - 2);
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/EnumStructures/OpenResults.cs b/SMBLibrary/SMB1/EnumStructures/OpenResults.cs
new file mode 100644
index 0000000..12f0e07
--- /dev/null
+++ b/SMBLibrary/SMB1/EnumStructures/OpenResults.cs
@@ -0,0 +1,50 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public struct OpenResults // 2 bytes
+ {
+ public OpenResult OpenResult;
+ public bool OpLockGranted;
+
+ public OpenResults(byte[] buffer, int offset)
+ {
+ OpenResult = (OpenResult)(buffer[offset] & 0x3);
+ OpLockGranted = (buffer[offset + 1] & 0x80) > 0;
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ buffer[0] = (byte)OpenResult;
+ if (OpLockGranted)
+ {
+ buffer[1] = 0x80;
+ }
+ else
+ {
+ buffer[1] = 0x00;
+ }
+ }
+
+ public void WriteBytes(byte[] buffer, ref int offset)
+ {
+ WriteBytes(buffer, offset);
+ offset += 2;
+ }
+
+ public static OpenResults Read(byte[] buffer, ref int offset)
+ {
+ offset += 2;
+ return new OpenResults(buffer, offset - 2);
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/CommandName.cs b/SMBLibrary/SMB1/Enums/CommandName.cs
new file mode 100644
index 0000000..a5775d9
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/CommandName.cs
@@ -0,0 +1,40 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum CommandName : byte
+ {
+ SMB_COM_CREATE_DIRECTORY = 0x00,
+ SMB_COM_DELETE_DIRECTORY = 0x01,
+ SMB_COM_CLOSE = 0x04,
+ SMB_COM_FLUSH = 0x05,
+ SMB_COM_DELETE = 0x06,
+ SMB_COM_RENAME = 0x07,
+ SMB_COM_QUERY_INFORMATION = 0x08,
+ SMB_COM_SET_INFORMATION = 0x09,
+ SMB_COM_READ = 0x0A,
+ SMB_COM_WRITE = 0x0B,
+ SMB_COM_CHECK_DIRECTORY = 0x10,
+ SMB_COM_WRITE_RAW = 0x1D,
+ SMB_COM_WRITE_COMPLETE = 0x20, // Write RAW final response
+ SMB_COM_SET_INFORMATION2 = 0x22,
+ SMB_COM_LOCKING_ANDX = 0x24,
+ SMB_COM_TRANSACTION = 0x25,
+ SMB_COM_TRANSACTION_SECONDARY = 0x26,
+ SMB_COM_ECHO = 0x2B,
+ SMB_COM_OPEN_ANDX = 0x2D,
+ SMB_COM_READ_ANDX = 0x2E,
+ SMB_COM_WRITE_ANDX = 0x2F,
+ SMB_COM_TRANSACTION2 = 0x32,
+ SMB_COM_TRANSACTION2_SECONDARY = 0x33,
+ SMB_COM_FIND_CLOSE2 = 0x34,
+ SMB_COM_TREE_DISCONNECT = 0x71,
+ SMB_COM_NEGOTIATE = 0x72,
+ SMB_COM_SESSION_SETUP_ANDX = 0x73,
+ SMB_COM_LOGOFF_ANDX = 0x74,
+ SMB_COM_TREE_CONNECT_ANDX = 0x75,
+ SMB_COM_NT_TRANSACT = 0xA0,
+ SMB_COM_NT_TRANSACT_SECONDARY = 0xA1,
+ SMB_COM_NT_CREATE_ANDX = 0xA2,
+ SMB_COM_NO_ANDX_COMMAND = 0xFF,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/ExtendedFileAttributes.cs b/SMBLibrary/SMB1/Enums/ExtendedFileAttributes.cs
new file mode 100644
index 0000000..b6a5e07
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/ExtendedFileAttributes.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_EXT_FILE_ATTR
+ ///
+ [Flags]
+ public enum ExtendedFileAttributes : uint
+ {
+ Readonly = 0x001, // ATTR_READONLY
+ Hidden = 0x0002, // ATTR_HIDDEN
+ System = 0x0004, // ATTR_SYSTEM
+ Directory = 0x0010, // ATTR_DIRECTORY
+ Archive = 0x0020, // ATTR_ARCHIVE
+
+ ///
+ /// The file has no other attributes set. This attribute is valid only if used alone.
+ ///
+ Normal = 0x0080, // ATTR_NORMAL
+ Temporary = 0x0100, // ATTR_TEMPORARY
+ Sparse = 0x0200, // ATTR_SPARSE, SMB 1.0 Addition
+ ReparsePoint = 0x0400, // ATTR_REPARSE_POINT, SMB 1.0 Addition
+ Compressed = 0x0800, // ATTR_COMPRESSED
+ Offline = 0x1000, // ATTR_OFFLINE, SMB 1.0 Addition
+ NotIndexed = 0x2000, // ATTR_NOT_CONTENT_INDEXED, SMB 1.0 Addition
+ Encrypted = 0x4000, // ATTR_ENCRYPTED, SMB 1.0 Addition
+ PosixSemantics = 0x01000000, // POSIX_SEMANTICS
+ BackupSemantics = 0x02000000, // BACKUP_SEMANTICS
+ DeleteOnClose = 0x04000000, // DELETE_ON_CLOSE
+ SequentialScan = 0x08000000, // SEQUENTIAL_SCAN
+ RandomAccess = 0x10000000, // RANDOM_ACCESS
+ NoBuffering = 0x10000000, // NO_BUFFERING
+ WriteThrough = 0x80000000, // WRITE_THROUGH
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/FileAttributes.cs b/SMBLibrary/SMB1/Enums/FileAttributes.cs
new file mode 100644
index 0000000..ddc3a49
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/FileAttributes.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_FILE_ATTRIBUTES
+ ///
+ [Flags]
+ public enum FileAttributes : ushort
+ {
+ Normal = 0x0000, // SMB_FILE_ATTRIBUTE_NORMAL
+ ReadOnly = 0x0001, // SMB_FILE_ATTRIBUTE_READONLY
+ Hidden = 0x0002, // SMB_FILE_ATTRIBUTE_HIDDEN
+ System = 0x0004, // SMB_FILE_ATTRIBUTE_SYSTEM
+ Volume = 0x0008, // SMB_FILE_ATTRIBUTE_VOLUME
+ Directory = 0x0010, // SMB_FILE_ATTRIBUTE_DIRECTORY
+ Archive = 0x0020, // SMB_FILE_ATTRIBUTE_ARCHIVE
+ SearchReadOnly = 0x0100, // SMB_SEARCH_ATTRIBUTE_READONLY
+ SearchHidden = 0x0200, // SMB_SEARCH_ATTRIBUTE_HIDDEN
+ SearchSystem = 0x0400, // SMB_SEARCH_ATTRIBUTE_SYSTEM
+ SearchDirectory = 0x1000, // SMB_SEARCH_ATTRIBUTE_DIRECTORY
+ SearchArchive = 0x2000, // SMB_SEARCH_ATTRIBUTE_ARCHIVE
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/HeaderFlags.cs b/SMBLibrary/SMB1/Enums/HeaderFlags.cs
new file mode 100644
index 0000000..d1af0f8
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/HeaderFlags.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum HeaderFlags : byte
+ {
+ LockAndRead = 0x01, // SMB_FLAGS_LOCK_AND_READ_OK
+ CaseInsensitive = 0x08, // SMB_FLAGS_CASE_INSENSITIVE
+ CanonicalizedPaths = 0x10, // SMB_FLAGS_CANONICALIZED_PATHS
+ Oplock = 0x20, // SMB_FLAGS_OPLOCK
+ Reply = 0x80, // SMB_FLAGS_REPLY
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/HeaderFlags2.cs b/SMBLibrary/SMB1/Enums/HeaderFlags2.cs
new file mode 100644
index 0000000..daf54d8
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/HeaderFlags2.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum HeaderFlags2 : ushort
+ {
+ LongNamesAllowed = 0x0001, // SMB_FLAGS2_LONG_NAMES
+ ExtendedAttributes = 0x0002, // SMB_FLAGS2_EAS
+ SecuritySignature = 0x0004, // SMB_FLAGS2_SMB_SECURITY_SIGNATURE
+ CompressedData = 0x0008, // SMB_FLAGS2_COMPRESSED
+ SecuritySignatureRequired = 0x0010, // SMB_FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED
+ LongNameUsed = 0x0040, // SMB_FLAGS2_IS_LONG_NAME
+ ReparsePath = 0x400, // SMB_FLAGS2_REPARSE_PATH
+
+ ///
+ /// Indicates that the client or server supports extended security
+ ///
+ ExtendedSecurity = 0x0800, // SMB_FLAGS2_EXTENDED_SECURITY
+ DFS = 0x1000, // SMB_FLAGS2_DFS
+ ReadIfExecute = 0x2000, // SMB_FLAGS2_PAGING_IO
+ NTStatusCode = 0x4000, // SMB_FLAGS2_NT_STATUS
+ Unicode = 0x8000, // SMB_FLAGS2_UNICODE
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Locking/LockType.cs b/SMBLibrary/SMB1/Enums/Locking/LockType.cs
new file mode 100644
index 0000000..5a4a32a
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Locking/LockType.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum LockType : byte
+ {
+ READ_WRITE_LOCK = 0x00,
+ SHARED_LOCK = 0x01,
+ OPLOCK_RELEASE = 0x02,
+ CHANGE_LOCKTYPE = 0x04,
+
+ ///
+ /// Request to cancel all outstanding lock requests for the specified FID and PID.
+ ///
+ CANCEL_LOCK = 0x08,
+
+ ///
+ /// Indicates that the LOCKING_ANDX_RANGE format is the 64-bit file offset version.
+ /// If this flag is not set, then the LOCKING_ANDX_RANGE format is the 32-bit file offset version
+ ///
+ LARGE_FILES = 0x10,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/CreateDisposition.cs b/SMBLibrary/SMB1/Enums/NTCreate/CreateDisposition.cs
new file mode 100644
index 0000000..1800d0c
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/CreateDisposition.cs
@@ -0,0 +1,45 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum CreateDisposition : uint
+ {
+ ///
+ /// If the file already exists, it SHOULD be superseded (overwritten).
+ /// If it does not already exist, then it SHOULD be created.
+ ///
+ FILE_SUPERSEDE = 0x0000,
+
+ ///
+ /// If the file already exists, it SHOULD be opened rather than created.
+ /// If the file does not already exist, the operation MUST fail.
+ ///
+ FILE_OPEN = 0x0001,
+
+ ///
+ /// If the file already exists, the operation MUST fail.
+ /// If the file does not already exist, it SHOULD be created.
+ ///
+ FILE_CREATE = 0x0002,
+
+ ///
+ /// If the file already exists, it SHOULD be opened.
+ /// If the file does not already exist, then it SHOULD be created.
+ /// This value is equivalent to (FILE_OPEN | FILE_CREATE).
+ ///
+ FILE_OPEN_IF = 0x0003,
+
+ ///
+ /// If the file already exists, it SHOULD be opened and truncated.
+ /// If the file does not already exist, the operation MUST fail.
+ /// The client MUST open the file with at least GENERIC_WRITE access for the command to succeed.
+ ///
+ FILE_OVERWRITE = 0x0004,
+
+ ///
+ /// If the file already exists, it SHOULD be opened and truncated.
+ /// If the file does not already exist, it SHOULD be created.
+ /// The client MUST open the file with at least GENERIC_WRITE access.
+ ///
+ FILE_OVERWRITE_IF = 0x0005,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/CreateOptions.cs b/SMBLibrary/SMB1/Enums/NTCreate/CreateOptions.cs
new file mode 100644
index 0000000..e53333c
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/CreateOptions.cs
@@ -0,0 +1,101 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum CreateOptions : uint
+ {
+ ///
+ /// The file being created or opened is a directory file.
+ /// With this option, the CreateDisposition field MUST be set to FILE_CREATE, FILE_OPEN, or FILE_OPEN_IF.
+ ///
+ FILE_DIRECTORY_FILE = 0x0001,
+
+ ///
+ /// Applications that write data to the file MUST actually transfer the data into the file before any write request is considered complete.
+ /// If FILE_NO_INTERMEDIATE_BUFFERING is set, the server MUST perform as if FILE_WRITE_THROUGH is set in the create request.
+ ///
+ FILE_WRITE_THROUGH = 0x0002,
+
+ ///
+ /// This option indicates that access to the file can be sequential.
+ /// The server can use this information to influence its caching and read-ahead strategy for this file.
+ /// The file MAY in fact be accessed randomly, but the server can optimize its caching and read-ahead policy for sequential access.
+ ///
+ FILE_SEQUENTIAL_ONLY = 0x0004,
+
+ ///
+ /// The file SHOULD NOT be cached or buffered in an internal buffer by the server.
+ /// This option is incompatible when the FILE_APPEND_DATA bit field is set in the DesiredAccess field.
+ ///
+ FILE_NO_INTERMEDIATE_BUFFERING = 0x0008,
+
+ FILE_SYNCHRONOUS_IO_ALERT = 0x0010,
+
+ FILE_SYNCHRONOUS_IO_NONALERT = 0x0020,
+
+ ///
+ /// If the file being opened is a directory, the server MUST fail the request with STATUS_FILE_IS_A_DIRECTORY
+ ///
+ FILE_NON_DIRECTORY_FILE = 0x0040,
+
+ FILE_CREATE_TREE_CONNECTION = 0x0080,
+
+ FILE_COMPLETE_IF_OPLOCKED = 0x0100,
+
+ ///
+ /// The application that initiated the client's request does not support extended attributes (EAs).
+ /// If the EAs on an existing file being opened indicate that the caller SHOULD support EAs to correctly interpret the file, the server SHOULD fail this request with STATUS_ACCESS_DENIED.
+ ///
+ FILE_NO_EA_KNOWLEDGE = 0x0200,
+
+ FILE_OPEN_FOR_RECOVERY = 0x0400,
+
+ ///
+ /// Indicates that access to the file can be random.
+ /// The server MAY use this information to influence its caching and read-ahead strategy for this file.
+ /// This is a hint to the server that sequential read-ahead operations might not be appropriate on the file.
+ ///
+ FILE_RANDOM_ACCESS = 0x0800,
+
+ ///
+ /// The file SHOULD be automatically deleted when the last open request on this file is closed.
+ /// When this option is set, the DesiredAccess field MUST include the DELETE flag.
+ /// This option is often used for temporary files.
+ ///
+ FILE_DELETE_ON_CLOSE = 0x1000,
+
+ ///
+ /// Opens a file based on the FileId.
+ /// If this option is set, the server MUST fail the request with STATUS_NOT_SUPPORTED in the Status field of the SMB Header in the server response.
+ ///
+ FILE_OPEN_BY_FILE_ID = 0x2000,
+
+ ///
+ /// The file is being opened or created for the purposes of either a backup or a restore operation.
+ /// Thus, the server can make appropriate checks to ensure that the caller is capable of overriding
+ /// whatever security checks have been placed on the file to allow a backup or restore operation to occur.
+ /// The server can check for certain access rights to the file before checking the DesiredAccess field.
+ ///
+ FILE_OPEN_FOR_BACKUP_INTENT = 0x4000,
+
+ ///
+ /// When a new file is created, the file MUST NOT be compressed, even if it is on a compressed volume.
+ /// The flag MUST be ignored when opening an existing file.
+ ///
+ FILE_NO_COMPRESSION = 0x8000,
+
+ FILE_RESERVE_OPFILTER = 0x00100000,
+
+ FILE_OPEN_REPARSE_POINT = 0x00200000,
+
+ ///
+ /// In a hierarchical storage management environment, this option requests that the file SHOULD NOT be recalled from tertiary storage such as tape.
+ /// A file recall can take up to several minutes in a hierarchical storage management environment.
+ /// The clients can specify this option to avoid such delays.
+ ///
+ FILE_OPEN_NO_RECALL = 0x00400000,
+
+ FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/DesiredAccess.cs b/SMBLibrary/SMB1/Enums/NTCreate/DesiredAccess.cs
new file mode 100644
index 0000000..2307f92
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/DesiredAccess.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum DesiredAccess : uint
+ {
+ FILE_READ_DATA = 0x0001,
+ FILE_WRITE_DATA = 0x0002,
+ FILE_APPEND_DATA = 0x0004,
+ FILE_READ_EA = 0x0008,
+ FILE_WRITE_EA = 0x0010,
+ FILE_EXECUTE = 0x0020,
+ FILE_READ_ATTRIBUTES = 0x0080,
+ FILE_WRITE_ATTRIBUTES = 0x0100,
+ DELETE = 0x00010000,
+ READ_CONTROL = 0x00020000,
+ WRITE_DAC = 0x00040000,
+ WRITE_OWNER = 0x00080000,
+ SYNCHRONIZE = 0x00100000,
+ ACCESS_SYSTEM_SECURITY = 0x01000000,
+ MAXIMUM_ALLOWED = 0x02000000,
+ GENERIC_ALL = 0x10000000,
+ GENERIC_EXECUTE = 0x20000000,
+ GENERIC_WRITE = 0x40000000,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/FileStatus.cs b/SMBLibrary/SMB1/Enums/NTCreate/FileStatus.cs
new file mode 100644
index 0000000..2a1edf5
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/FileStatus.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum FileStatus : ushort
+ {
+ NO_EAS = 0x01,
+ NO_SUBSTREAMS = 0x02,
+ NO_REPARSETAG = 0x04,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/ImpersonationLevel.cs b/SMBLibrary/SMB1/Enums/NTCreate/ImpersonationLevel.cs
new file mode 100644
index 0000000..63b0ddc
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/ImpersonationLevel.cs
@@ -0,0 +1,11 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum ImpersonationLevel : uint
+ {
+ SEC_ANONYMOUS = 0x00,
+ SEC_IDENTIFY = 0x01,
+ SEC_IMPERSONATE = 0x02,
+ SECURITY_DELEGATION = 0x04, // SMB 1.0 addition
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/NTCreateFlags.cs b/SMBLibrary/SMB1/Enums/NTCreate/NTCreateFlags.cs
new file mode 100644
index 0000000..1a63808
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/NTCreateFlags.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum NTCreateFlags : uint
+ {
+ ///
+ /// If set, the client requests an exclusive OpLock.
+ ///
+ NT_CREATE_REQUEST_OPLOCK = 0x0002,
+
+ ///
+ /// If set, the client requests an exclusive batch OpLock.
+ ///
+ NT_CREATE_REQUEST_OPBATCH = 0x0004,
+ NT_CREATE_OPEN_TARGET_DIR = 0x0008,
+ NT_CREATE_REQUEST_EXTENDED_RESPONSE = 0x0010, // SMB 1.0 addition
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/OpLockLevel.cs b/SMBLibrary/SMB1/Enums/NTCreate/OpLockLevel.cs
new file mode 100644
index 0000000..017731b
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/OpLockLevel.cs
@@ -0,0 +1,11 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum OpLockLevel : byte
+ {
+ NoOpLockGranted = 0x00,
+ ExclusiveOpLockGranted = 0x01,
+ BatchOpLockGranted = 0x02,
+ Level2OpLockGranted = 0x03,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/SecurityFlags.cs b/SMBLibrary/SMB1/Enums/NTCreate/SecurityFlags.cs
new file mode 100644
index 0000000..74d6633
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/SecurityFlags.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ public enum SecurityFlags : byte
+ {
+ SMB_SECURITY_CONTEXT_TRACKING = 0x01,
+ SMB_SECURITY_EFFECTIVE_ONLY = 0x02,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/NTCreate/ShareAccess.cs b/SMBLibrary/SMB1/Enums/NTCreate/ShareAccess.cs
new file mode 100644
index 0000000..05e1eed
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/NTCreate/ShareAccess.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// No bits set = Prevents the file from being shared
+ ///
+ [Flags]
+ public enum ShareAccess : uint
+ {
+ FILE_SHARE_READ = 0x0001,
+ FILE_SHARE_WRITE = 0x0002,
+ FILE_SHARE_DELETE = 0x0004,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Negotiate/SecurityMode.cs b/SMBLibrary/SMB1/Enums/Negotiate/SecurityMode.cs
new file mode 100644
index 0000000..e23bc49
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Negotiate/SecurityMode.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum SecurityMode : byte
+ {
+ ///
+ /// If clear, the server supports only Share Level access control.
+ /// If set, the server supports only User Level access control.
+ ///
+ UserSecurityMode = 0x01, // NEGOTIATE_USER_SECURITY
+
+ ///
+ /// If clear, the server supports only plaintext password authentication.
+ /// If set, the server supports challenge/response authentication.
+ /// Note: Windows 2000 and above do not support plain-text passwords by default.
+ ///
+ EncryptPasswords = 0x02, // NEGOTIATE_ENCRYPT_PASSWORDS
+ SecuritySignaturesEnabled = 0x04, // NEGOTIATE_SECURITY_SIGNATURES_ENABLED
+ SecuritySignaturesRequired = 0x08, // NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Negotiate/ServerCapabilities.cs b/SMBLibrary/SMB1/Enums/Negotiate/ServerCapabilities.cs
new file mode 100644
index 0000000..88c5526
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Negotiate/ServerCapabilities.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum ServerCapabilities : uint
+ {
+ RawMode = 0x00000001, // CAP_RAW_MODE
+ MPXMode = 0x00000002, // SMB_COM_READ_MPX
+ Unicode = 0x00000004, // CAP_UNICODE
+ LargeFiles = 0x00000008, // CAP_LARGE_FILES
+ NTSMB = 0x00000010, // CAP_NT_SMBS
+ RpcRemoteApi = 0x00000020, // CAP_RPC_REMOTE_APIS
+ NTStatusCode = 0x00000040, // CAP_STATUS32
+ Level2Oplocks = 0x00000080, // CAP_LEVEL_II_OPLOCKS
+ LockAndRead = 0x00000100, // CAP_LOCK_AND_READ
+ NTFind = 0x00000200, // CAP_NT_FIND
+ DFS = 0x00001000, // CAP_DFS
+ InfoLevelPassthrough = 0x00002000, // CAP_INFOLEVEL_PASSTHRU
+ LargeRead = 0x00004000, // CAP_LARGE_READX
+ LargeWrite = 0x00008000, // CAP_LARGE_WRITEX
+ LightWeightIO = 0x00010000, // CAP_LWIO
+ Unix = 0x00800000, // CAP_UNIX
+ DynamicReauthentication = 0x20000000, // CAP_DYNAMIC_REAUTH
+
+ ///
+ /// The server supports extended security for authentication
+ ///
+ ExtendedSecurity = 0x80000000, // CAP_EXTENDED_SECURITY
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Open/AccessRights.cs b/SMBLibrary/SMB1/Enums/Open/AccessRights.cs
new file mode 100644
index 0000000..255d080
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Open/AccessRights.cs
@@ -0,0 +1,10 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum AccessRights : ushort
+ {
+ SMB_DA_ACCESS_READ = 0x00,
+ SMB_DA_ACCESS_WRITE = 0x01,
+ SMB_DA_ACCESS_READ_WRITE = 0x02,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Open/OpenFlags.cs b/SMBLibrary/SMB1/Enums/Open/OpenFlags.cs
new file mode 100644
index 0000000..883837c
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Open/OpenFlags.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum OpenFlags : ushort
+ {
+ ///
+ /// If this bit is set, the client requests that the file attribute data in the response be populated.
+ /// All fields after the FID in the response are also populated. If this bit is not set,
+ /// all fields after the FID in the response are zero.
+ ///
+ REQ_ATTRIB = 0x0001,
+
+ ///
+ /// Client requests an exclusive OpLock on the file.
+ ///
+ REQ_OPLOCK = 0x0002,
+
+ ///
+ /// Client requests a Batch OpLock on the file.
+ ///
+ REQ_OPLOCK_BATCH = 0x0004,
+
+ ///
+ /// SMB 1.0 Addition.
+ /// If set, the client is requesting the extended format of the response.
+ ///
+ SMB_OPEN_EXTENDED_RESPONSE = 0x0010,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Open/OpenResult.cs b/SMBLibrary/SMB1/Enums/Open/OpenResult.cs
new file mode 100644
index 0000000..e0cc7cb
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Open/OpenResult.cs
@@ -0,0 +1,11 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum OpenResult : byte
+ {
+ Reserved = 0x00,
+ FileExistedAndWasOpened = 0x01,
+ NotExistedAndWasCreated = 0x02,
+ FileExistedAndWasTruncated = 0x03,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/ResourceType.cs b/SMBLibrary/SMB1/Enums/ResourceType.cs
new file mode 100644
index 0000000..b4edf2e
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/ResourceType.cs
@@ -0,0 +1,28 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum ResourceType : ushort
+ {
+ FileTypeDisk = 0x0000,
+ FileTypeByteModePipe = 0x0001,
+ FileTypeMessageModePipe = 0x0002,
+ FileTypePrinter = 0x0003,
+
+ ///
+ /// OpenAndX Response: Valid.
+ /// OpenAndX Extended Response: Invalid (SMB 1.0).
+ /// NTCreateAndX Response: Valid.
+ /// NTCreateAndX Extended Response: Invalid (SMB 1.0).
+ /// Transact2Open2: Was never valid
+ ///
+ FileTypeCommDevice = 0x0004,
+
+ ///
+ /// OpenAndX Response: Valid
+ /// NTCreateAndX Response: Invalid
+ /// Transact2Open2 Response: Valid
+ /// TransactCreate Response: Valid
+ ///
+ FileTypeUnknown = 0xFFFF,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/SessionSetup/SessionSetupAction.cs b/SMBLibrary/SMB1/Enums/SessionSetup/SessionSetupAction.cs
new file mode 100644
index 0000000..1563674
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/SessionSetup/SessionSetupAction.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum SessionSetupAction : ushort
+ {
+ SetupGuest = 0x01, // SMB_SETUP_GUEST
+ UseLanmanKey = 0x02, // SMB_SETUP_USE_LANMAN_KEY
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Transaction/TransactionFlags.cs b/SMBLibrary/SMB1/Enums/Transaction/TransactionFlags.cs
new file mode 100644
index 0000000..9b0eed1
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Transaction/TransactionFlags.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum TransactionFlags : ushort
+ {
+ DISCONNECT_TID = 0x0001,
+ NO_RESPONSE = 0x0002,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/TreeConnect/OptionalSupportFlags.cs b/SMBLibrary/SMB1/Enums/TreeConnect/OptionalSupportFlags.cs
new file mode 100644
index 0000000..c54f216
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/TreeConnect/OptionalSupportFlags.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum OptionalSupportFlags : ushort
+ {
+ ///
+ /// The server supports the use of SMB_FILE_ATTRIBUTES exclusive search attributes in client requests.
+ ///
+ SMB_SUPPORT_SEARCH_BITS = 0x01,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/TreeConnect/ServiceName.cs b/SMBLibrary/SMB1/Enums/TreeConnect/ServiceName.cs
new file mode 100644
index 0000000..6632468
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/TreeConnect/ServiceName.cs
@@ -0,0 +1,16 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum ServiceName
+ {
+ DiskShare,
+ PrinterShare,
+ NamedPipe,
+ SerialCommunicationsDevice,
+
+ ///
+ /// Valid only for request
+ ///
+ AnyType,
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/TreeConnect/TreeConnectFlags.cs b/SMBLibrary/SMB1/Enums/TreeConnect/TreeConnectFlags.cs
new file mode 100644
index 0000000..e78e166
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/TreeConnect/TreeConnectFlags.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum TreeConnectFlags : ushort
+ {
+ ///
+ /// If set and SMB_Header.TID is valid, the tree connect specified by the TID in the SMB
+ /// header of the request SHOULD be disconnected when the server sends the response. If this tree disconnect fails, then the error SHOULD be ignored
+ /// If set and TID is invalid, the server MUST ignore this bit.
+ ///
+ DisconnectTID = 0x0001, // TREE_CONNECT_ANDX_DISCONNECT_TID
+
+ ///
+ /// SMB 1.0 addition.
+ /// If set, then the client is requesting signing key protection.
+ ///
+ ExtendedSignatures = 0x0004, // TREE_CONNECT_ANDX_EXTENDED_SIGNATURES
+
+ ///
+ /// SMB 1.0 addition.
+ /// If set, then the client is requesting extended information in the SMB_COM_TREE_CONNECT_ANDX response.
+ ///
+ ExtendedResponse = 0x0008, // TREE_CONNECT_ANDX_EXTENDED_RESPONSE
+ }
+}
diff --git a/SMBLibrary/SMB1/Enums/Write/WriteMode.cs b/SMBLibrary/SMB1/Enums/Write/WriteMode.cs
new file mode 100644
index 0000000..e569394
--- /dev/null
+++ b/SMBLibrary/SMB1/Enums/Write/WriteMode.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum WriteMode : ushort
+ {
+ WritethroughMode = 0x0001,
+ ReadBytesAvailable = 0x0002,
+ RAW_MODE = 0x0004,
+ MSG_START = 0x0008,
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/Enums/CompletionFilter.cs b/SMBLibrary/SMB1/NTTransactSubcommands/Enums/CompletionFilter.cs
new file mode 100644
index 0000000..e3d6c65
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/Enums/CompletionFilter.cs
@@ -0,0 +1,20 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum CompletionFilter : uint
+ {
+ FILE_NOTIFY_CHANGE_FILE_NAME = 0x00000001,
+ FILE_NOTIFY_CHANGE_DIR_NAME = 0x00000002,
+ FILE_NOTIFY_CHANGE_NAME = 0x00000003,
+ FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x00000004,
+ FILE_NOTIFY_CHANGE_SIZE = 0x00000008,
+ FILE_NOTIFY_CHANGE_LAST_WRITE = 0x00000010,
+ FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x00000020,
+ FILE_NOTIFY_CHANGE_CREATION = 0x00000040,
+ FILE_NOTIFY_CHANGE_EA = 0x00000080,
+ FILE_NOTIFY_CHANGE_SECURITY = 0x00000100,
+ FILE_NOTIFY_CHANGE_STREAM_NAME = 0x00000200,
+ FILE_NOTIFY_CHANGE_STREAM_SIZE = 0x00000400,
+ FILE_NOTIFY_CHANGE_STREAM_WRITE = 0x00000800,
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/Enums/NTTransactSubcommandName.cs b/SMBLibrary/SMB1/NTTransactSubcommands/Enums/NTTransactSubcommandName.cs
new file mode 100644
index 0000000..c9b05a7
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/Enums/NTTransactSubcommandName.cs
@@ -0,0 +1,16 @@
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// This is the Function field in NTTransactRequest
+ ///
+ public enum NTTransactSubcommandName : ushort
+ {
+ NT_TRANSACT_CREATE = 0x0001,
+ NT_TRANSACT_IOCTL = 0x0002,
+ NT_TRANSACT_SET_SECURITY_DESC = 0x0003,
+ NT_TRANSACT_NOTIFY_CHANGE = 0x0004,
+ // NT_TRANSACT_RENAME = 0x0005,
+ NT_TRANSACT_QUERY_SECURITY_DESC = 0x0006,
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/Enums/SecurityInfoFields.cs b/SMBLibrary/SMB1/NTTransactSubcommands/Enums/SecurityInfoFields.cs
new file mode 100644
index 0000000..d741d7e
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/Enums/SecurityInfoFields.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum SecurityInfoFields : uint
+ {
+ OWNER_SECURITY_INFORMATION = 0x00000001,
+ GROUP_SECURITY_INFORMATION = 0x00000002,
+ DACL_SECURITY_INFORMATION = 0x00000004,
+ SACL_SECURITY_INFORMATION = 0x00000008,
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactCreateRequest.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactCreateRequest.cs
new file mode 100644
index 0000000..0db6d0c
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactCreateRequest.cs
@@ -0,0 +1,90 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// NT_TRANSACT_CREATE Request
+ ///
+ public class NTTransactCreateRequest : NTTransactSubcommand
+ {
+ public const int ParametersFixedLength = 53;
+ // Parameters:
+ public NTCreateFlags Flags;
+ public uint RootDirectoryFID;
+ public DesiredAccess DesiredAccess;
+ public ulong AllocationSize;
+ public ExtendedFileAttributes ExtFileAttributes;
+ public ShareAccess ShareAccess;
+ public CreateDisposition CreateDisposition;
+ public CreateOptions CreateOptions;
+ //uint SecurityDescriptiorLength;
+ //uint EALength;
+ //uint NameLength;
+ public ImpersonationLevel ImpersonationLevel;
+ public SecurityFlags SecurityFlags;
+ public string Name; // OEM / Unicode. NOT null terminated. (MUST be aligned to start on a 2-byte boundary from the start of the NT_Trans_Parameters)
+ // Data:
+ public SecurityDescriptor SecurityDescriptor;
+ public FileFullEAInformationList ExtendedAttributes;
+
+ public NTTransactCreateRequest()
+ {
+ }
+
+ public NTTransactCreateRequest(byte[] parameters, byte[] data, bool isUnicode)
+ {
+ int parametersOffset = 0;
+ Flags = (NTCreateFlags)LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ RootDirectoryFID = LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ DesiredAccess = (DesiredAccess)LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ AllocationSize = LittleEndianReader.ReadUInt64(parameters, ref parametersOffset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ ShareAccess = (ShareAccess)LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ CreateDisposition = (CreateDisposition)LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ CreateOptions = (CreateOptions)LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ uint securityDescriptiorLength = LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ uint eaLength = LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ uint nameLength = LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ ImpersonationLevel = (ImpersonationLevel)LittleEndianReader.ReadUInt32(parameters, ref parametersOffset);
+ SecurityFlags = (SecurityFlags)ByteReader.ReadByte(parameters, ref parametersOffset);
+
+ if (isUnicode)
+ {
+ parametersOffset++;
+ }
+ Name = SMBHelper.ReadFixedLengthString(parameters, ref parametersOffset, isUnicode, (int)nameLength);
+ if (securityDescriptiorLength > 0)
+ {
+ SecurityDescriptor = new SecurityDescriptor(data, 0);
+ }
+ ExtendedAttributes = new FileFullEAInformationList(data, (int)securityDescriptiorLength);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override byte[] GetData()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override NTTransactSubcommandName SubcommandName
+ {
+ get
+ {
+ return NTTransactSubcommandName.NT_TRANSACT_CREATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactIOCTLRequest.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactIOCTLRequest.cs
new file mode 100644
index 0000000..f3055dc
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactIOCTLRequest.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// NT_TRANSACT_IOCTL Request
+ ///
+ public class NTTransactIOCTLRequest : NTTransactSubcommand
+ {
+ public const int SetupLength = 8;
+ // Setup:
+ public uint FunctionCode;
+ public ushort FID;
+ public bool IsFsctl;
+ public bool IsFlags;
+ // Data:
+ public byte[] Data;
+
+ public NTTransactIOCTLRequest() : base()
+ {
+ Data = new byte[0];
+ }
+
+ public NTTransactIOCTLRequest(byte[] setup, byte[] data) : base()
+ {
+ FunctionCode = LittleEndianConverter.ToUInt32(setup, 0);
+ FID = LittleEndianConverter.ToUInt16(setup, 4);
+ IsFsctl = (ByteReader.ReadByte(setup, 6) != 0);
+ IsFlags = (ByteReader.ReadByte(setup, 7) != 0);
+
+ Data = data;
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[SetupLength];
+ LittleEndianWriter.WriteUInt32(setup, 0, FunctionCode);
+ LittleEndianWriter.WriteUInt32(setup, 4, FID);
+ ByteWriter.WriteByte(setup, 6, Convert.ToByte(IsFsctl));
+ ByteWriter.WriteByte(setup, 7, Convert.ToByte(IsFlags));
+ return setup;
+ }
+
+ public override byte[] GetData()
+ {
+ return Data;
+ }
+
+ public override NTTransactSubcommandName SubcommandName
+ {
+ get
+ {
+ return NTTransactSubcommandName.NT_TRANSACT_IOCTL;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactIOCTLResponse.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactIOCTLResponse.cs
new file mode 100644
index 0000000..9428503
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactIOCTLResponse.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// NT_TRANSACT_IOCTL Response
+ ///
+ public class NTTransactIOCTLResponse : NTTransactSubcommand
+ {
+ public const int SetupLength = 2;
+ // Setup:
+ public ushort TransactionDataSize; // in bytes
+ // Data:
+ public byte[] Data;
+
+ public NTTransactIOCTLResponse() : base()
+ {
+ }
+
+ public NTTransactIOCTLResponse(byte[] setup, byte[] data) : base()
+ {
+ TransactionDataSize = LittleEndianConverter.ToUInt16(setup, 0);
+
+ Data = data;
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[SetupLength];
+ LittleEndianWriter.WriteUInt16(setup, 0, TransactionDataSize);
+ return setup;
+ }
+
+ public override byte[] GetData()
+ {
+ return Data;
+ }
+
+ public override NTTransactSubcommandName SubcommandName
+ {
+ get
+ {
+ return NTTransactSubcommandName.NT_TRANSACT_IOCTL;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactNotifyChangeRequest.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactNotifyChangeRequest.cs
new file mode 100644
index 0000000..b3d6304
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactNotifyChangeRequest.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// NT_TRANSACT_NOTIFY_CHANGE Request
+ ///
+ public class NTTransactNotifyChangeRequest : NTTransactSubcommand
+ {
+ public const int SetupLength = 8;
+ // Setup:
+ public CompletionFilter CompletionFilter;
+ public ushort FID;
+ public bool WatchTree;
+ public byte Reserved;
+
+ public NTTransactNotifyChangeRequest() : base()
+ {
+ }
+
+ public NTTransactNotifyChangeRequest(byte[] setup) : base()
+ {
+ CompletionFilter = (CompletionFilter)LittleEndianConverter.ToUInt32(setup, 0);
+ FID = LittleEndianConverter.ToUInt16(setup, 4);
+ WatchTree = (ByteReader.ReadByte(setup, 6) != 0);
+ Reserved = ByteReader.ReadByte(setup, 7);
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[SetupLength];
+ LittleEndianWriter.WriteUInt32(setup, 0, (uint)CompletionFilter);
+ LittleEndianWriter.WriteUInt32(setup, 4, FID);
+ ByteWriter.WriteByte(setup, 6, Convert.ToByte(WatchTree));
+ ByteWriter.WriteByte(setup, 7, Reserved);
+ return setup;
+ }
+
+ public override NTTransactSubcommandName SubcommandName
+ {
+ get
+ {
+ return NTTransactSubcommandName.NT_TRANSACT_NOTIFY_CHANGE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactQuerySecurityDescriptorRequest.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactQuerySecurityDescriptorRequest.cs
new file mode 100644
index 0000000..9bb9271
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactQuerySecurityDescriptorRequest.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// NT_TRANSACT_QUERY_SECURITY_DESC Request
+ ///
+ public class NTTransactQuerySecurityDescriptorRequest :NTTransactSubcommand
+ {
+ public const int ParametersLength = 8;
+ // Parameters:
+ public ushort FID;
+ public ushort Reserved;
+ public SecurityInfoFields SecurityInfoFields;
+
+ public NTTransactQuerySecurityDescriptorRequest()
+ {
+ }
+
+ public NTTransactQuerySecurityDescriptorRequest(byte[] parameters)
+ {
+ FID = LittleEndianConverter.ToUInt16(parameters, 0);
+ Reserved = LittleEndianConverter.ToUInt16(parameters, 2);
+ SecurityInfoFields = (SecurityInfoFields)LittleEndianConverter.ToUInt32(parameters, 4);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, FID);
+ LittleEndianWriter.WriteUInt16(parameters, 2, Reserved);
+ LittleEndianWriter.WriteUInt32(parameters, 4, (uint)SecurityInfoFields);
+ return parameters;
+ }
+
+ public override NTTransactSubcommandName SubcommandName
+ {
+ get
+ {
+ return NTTransactSubcommandName.NT_TRANSACT_QUERY_SECURITY_DESC;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactQuerySecurityDescriptorResponse.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactQuerySecurityDescriptorResponse.cs
new file mode 100644
index 0000000..f84184b
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactQuerySecurityDescriptorResponse.cs
@@ -0,0 +1,47 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// NTTransactQuerySecurityDescription Response
+ ///
+ public class NTTransactQuerySecurityDescriptorResponse : NTTransactSubcommand
+ {
+ public const uint ParametersLength = 4;
+ // Parameters:
+ public uint LengthNeeded; // We might return STATUS_BUFFER_OVERFLOW without the SecurityDescriptor field
+ // Data
+ public SecurityDescriptor SecurityDescriptor;
+
+ public NTTransactQuerySecurityDescriptorResponse()
+ {
+ }
+
+ public NTTransactQuerySecurityDescriptorResponse(byte[] parameters, byte[] data)
+ {
+ LengthNeeded = LittleEndianConverter.ToUInt32(parameters, 0);
+
+ if (data.Length == LengthNeeded)
+ {
+ SecurityDescriptor = new SecurityDescriptor(data, 0);
+ }
+ }
+
+ public override NTTransactSubcommandName SubcommandName
+ {
+ get
+ {
+ return NTTransactSubcommandName.NT_TRANSACT_QUERY_SECURITY_DESC;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactSetSecurityDescriptor.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactSetSecurityDescriptor.cs
new file mode 100644
index 0000000..9905475
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactSetSecurityDescriptor.cs
@@ -0,0 +1,62 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// NT_TRANSACT_SET_SECURITY_DESC Request
+ ///
+ public class NTTransactSetSecurityDescriptor : NTTransactSubcommand
+ {
+ public const int ParametersLength = 8;
+ // Parameters:
+ public ushort FID;
+ public ushort Reserved;
+ public SecurityInfoFields SecurityInfoFields;
+ // Data:
+ public SecurityDescriptor SecurityDescriptor;
+
+ public NTTransactSetSecurityDescriptor()
+ {
+ }
+
+ public NTTransactSetSecurityDescriptor(byte[] parameters, byte[] data)
+ {
+ FID = LittleEndianConverter.ToUInt16(parameters, 0);
+ Reserved = LittleEndianConverter.ToUInt16(parameters, 2);
+ SecurityInfoFields = (SecurityInfoFields)LittleEndianConverter.ToUInt32(parameters, 4);
+
+ SecurityDescriptor = new SecurityDescriptor(data, 0);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, FID);
+ LittleEndianWriter.WriteUInt16(parameters, 2, Reserved);
+ LittleEndianWriter.WriteUInt32(parameters, 4, (uint)SecurityInfoFields);
+ return parameters;
+ }
+
+ public override byte[] GetData()
+ {
+ return SecurityDescriptor.GetBytes();
+ }
+
+ public override NTTransactSubcommandName SubcommandName
+ {
+ get
+ {
+ return NTTransactSubcommandName.NT_TRANSACT_SET_SECURITY_DESC;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactSubcommand.cs b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactSubcommand.cs
new file mode 100644
index 0000000..f8aacfa
--- /dev/null
+++ b/SMBLibrary/SMB1/NTTransactSubcommands/NTTransactSubcommand.cs
@@ -0,0 +1,58 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class NTTransactSubcommand
+ {
+ public NTTransactSubcommand()
+ {
+ }
+
+ public virtual byte[] GetSetup()
+ {
+ return new byte[0];
+ }
+
+ public virtual byte[] GetParameters(bool isUnicode)
+ {
+ return new byte[0];
+ }
+
+ public virtual byte[] GetData()
+ {
+ return new byte[0];
+ }
+
+ public abstract NTTransactSubcommandName SubcommandName
+ {
+ get;
+ }
+
+ public static NTTransactSubcommand GetSubcommandRequest(NTTransactSubcommandName subcommandName, byte[] setup, byte[] parameters, byte[] data, bool isUnicode)
+ {
+ switch (subcommandName)
+ {
+ case NTTransactSubcommandName.NT_TRANSACT_CREATE:
+ return new NTTransactCreateRequest(parameters, data, isUnicode);
+ case NTTransactSubcommandName.NT_TRANSACT_IOCTL:
+ return new NTTransactIOCTLRequest(setup, data);
+ case NTTransactSubcommandName.NT_TRANSACT_SET_SECURITY_DESC:
+ return new NTTransactSetSecurityDescriptor(parameters, data);
+ case NTTransactSubcommandName.NT_TRANSACT_NOTIFY_CHANGE:
+ return new NTTransactNotifyChangeRequest(setup);
+ case NTTransactSubcommandName.NT_TRANSACT_QUERY_SECURITY_DESC:
+ return new NTTransactQuerySecurityDescriptorRequest(parameters);
+ }
+ throw new InvalidRequestException();
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/CheckDirectoryRequest.cs b/SMBLibrary/SMB1/SMBCommands/CheckDirectoryRequest.cs
new file mode 100644
index 0000000..a70bf9a
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/CheckDirectoryRequest.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_CHECK_DIRECTORY Request
+ ///
+ public class CheckDirectoryRequest : SMBCommand
+ {
+ public const byte SupportedBufferFormat = 0x04;
+ // Data:
+ public byte BufferFormat;
+ public string DirectoryName; // SMB_STRING
+
+ public CheckDirectoryRequest() : base()
+ {
+ BufferFormat = SupportedBufferFormat;
+ DirectoryName = String.Empty;
+ }
+
+ public CheckDirectoryRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ DirectoryName = SMBHelper.ReadSMBString(this.SMBData, 1, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ int length = 1;
+ if (isUnicode)
+ {
+ length += DirectoryName.Length * 2 + 2;
+ }
+ else
+ {
+ length += DirectoryName.Length + 1;
+ }
+ this.SMBData = new byte[1 + length];
+ ByteWriter.WriteByte(this.SMBData, 0, BufferFormat);
+ SMBHelper.WriteSMBString(this.SMBData, 1, isUnicode, DirectoryName);
+
+ return base.GetBytes(isUnicode);
+ }
+
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_CHECK_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/CheckDirectoryResponse.cs b/SMBLibrary/SMB1/SMBCommands/CheckDirectoryResponse.cs
new file mode 100644
index 0000000..fb27384
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/CheckDirectoryResponse.cs
@@ -0,0 +1,40 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_CHECK_DIRECTORY Response
+ ///
+ public class CheckDirectoryResponse : SMBCommand
+ {
+ public CheckDirectoryResponse() : base()
+ {
+ }
+
+ public CheckDirectoryResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_CHECK_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/CloseRequest.cs b/SMBLibrary/SMB1/SMBCommands/CloseRequest.cs
new file mode 100644
index 0000000..c4c050b
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/CloseRequest.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_CLOSE Request
+ ///
+ public class CloseRequest : SMBCommand
+ {
+ public const int ParametersLength = 6;
+ // Parameters:
+ public ushort FID;
+ ///
+ /// A value of 0x00000000 or 0xFFFFFFFF results in the server not updating the last modification time
+ ///
+ public DateTime LastTimeModified;
+
+ public CloseRequest() : base()
+ {
+ LastTimeModified = SMBHelper.UTimeNotSpecified;
+ }
+
+ public CloseRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ LastTimeModified = SMBHelper.ReadUTime(this.SMBParameters, 2);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, FID);
+ SMBHelper.WriteUTime(this.SMBParameters, 2, LastTimeModified);
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_CLOSE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/CloseResponse.cs b/SMBLibrary/SMB1/SMBCommands/CloseResponse.cs
new file mode 100644
index 0000000..4a10fd2
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/CloseResponse.cs
@@ -0,0 +1,33 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_CLOSE Response
+ ///
+ public class CloseResponse : SMBCommand
+ {
+ public CloseResponse() : base()
+ {}
+
+ public CloseResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ { }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_CLOSE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/CreateDirectoryRequest.cs b/SMBLibrary/SMB1/SMBCommands/CreateDirectoryRequest.cs
new file mode 100644
index 0000000..c448217
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/CreateDirectoryRequest.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_CREATE_DIRECTORY Request.
+ /// This command is obsolete.
+ /// This command is used by Windows NT4 SP6.
+ ///
+ public class CreateDirectoryRequest : SMBCommand
+ {
+ public const byte SupportedBufferFormat = 0x04;
+ // Data:
+ public byte BufferFormat;
+ public string DirectoryName; // SMB_STRING
+
+ public CreateDirectoryRequest() : base()
+ {
+ BufferFormat = SupportedBufferFormat;
+ DirectoryName = String.Empty;
+ }
+
+ public CreateDirectoryRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ DirectoryName = SMBHelper.ReadSMBString(this.SMBData, 1, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ int length = 1;
+ if (isUnicode)
+ {
+ length += DirectoryName.Length * 2 + 2;
+ }
+ else
+ {
+ length += DirectoryName.Length + 1;
+ }
+ this.SMBData = new byte[1 + length];
+ ByteWriter.WriteByte(this.SMBData, 0, BufferFormat);
+ SMBHelper.WriteSMBString(this.SMBData, 1, isUnicode, DirectoryName);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_CREATE_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/CreateDirectoryResponse.cs b/SMBLibrary/SMB1/SMBCommands/CreateDirectoryResponse.cs
new file mode 100644
index 0000000..d9b7bd5
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/CreateDirectoryResponse.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_CREATE_DIRECTORY Response.
+ /// This command is obsolete.
+ /// This command is used by Windows NT4 SP6.
+ ///
+ public class CreateDirectoryResponse : SMBCommand
+ {
+ public CreateDirectoryResponse() : base()
+ {
+ }
+
+ public CreateDirectoryResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_CREATE_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/DeleteDirectoryRequest.cs b/SMBLibrary/SMB1/SMBCommands/DeleteDirectoryRequest.cs
new file mode 100644
index 0000000..3bf2eb6
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/DeleteDirectoryRequest.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_DELETE_DIRECTORY Request
+ ///
+ public class DeleteDirectoryRequest : SMBCommand
+ {
+ public const int SupportedBufferFormat = 0x04;
+ // Data:
+ public byte BufferFormat;
+ public string DirectoryName; // SMB_STRING
+
+ public DeleteDirectoryRequest() : base()
+ {
+ BufferFormat = SupportedBufferFormat;
+ }
+
+ public DeleteDirectoryRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ DirectoryName = SMBHelper.ReadSMBString(this.SMBData, 1, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ int length = 1;
+ if (isUnicode)
+ {
+ length += DirectoryName.Length * 2 + 2;
+ }
+ else
+ {
+ length += DirectoryName.Length + 1;
+ }
+ this.SMBData = new byte[length];
+ ByteWriter.WriteByte(this.SMBData, 0, BufferFormat);
+ SMBHelper.WriteSMBString(this.SMBData, 1, isUnicode, DirectoryName);
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_DELETE_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/DeleteDirectoryResponse.cs b/SMBLibrary/SMB1/SMBCommands/DeleteDirectoryResponse.cs
new file mode 100644
index 0000000..b41f7c1
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/DeleteDirectoryResponse.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_DELETE_DIRECTORY Response
+ ///
+ public class DeleteDirectoryResponse : SMBCommand
+ {
+ public DeleteDirectoryResponse() : base()
+ {
+ }
+
+ public DeleteDirectoryResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_DELETE_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/DeleteRequest.cs b/SMBLibrary/SMB1/SMBCommands/DeleteRequest.cs
new file mode 100644
index 0000000..4639f58
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/DeleteRequest.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_DELETE Request
+ ///
+ public class DeleteRequest : SMBCommand
+ {
+ public const int SupportedBufferFormat = 0x04;
+ public const int ParametersLength = 2;
+ // Parameters;
+ public FileAttributes SearchAttributes;
+ // Data:
+ public byte BufferFormat;
+ public string FileName; // SMB_STRING
+
+ public DeleteRequest() : base()
+ {
+ BufferFormat = SupportedBufferFormat;
+ }
+
+ public DeleteRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ SearchAttributes = (FileAttributes)LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ FileName = SMBHelper.ReadSMBString(this.SMBData, 1, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_DELETE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/DeleteResponse.cs b/SMBLibrary/SMB1/SMBCommands/DeleteResponse.cs
new file mode 100644
index 0000000..729b709
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/DeleteResponse.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_DELETE Response
+ ///
+ public class DeleteResponse : SMBCommand
+ {
+ public DeleteResponse() : base()
+ {
+ }
+
+ public DeleteResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_DELETE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/EchoRequest.cs b/SMBLibrary/SMB1/SMBCommands/EchoRequest.cs
new file mode 100644
index 0000000..9fe3b74
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/EchoRequest.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_ECHO
+ ///
+ public class EchoRequest : SMBCommand
+ {
+ public const int ParametersLength = 1;
+ // Parameters
+ public byte EchoCount;
+
+ public EchoRequest() : base()
+ {
+
+ }
+
+ public EchoRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ EchoCount = ByteReader.ReadByte(this.SMBParameters, 0);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ ByteWriter.WriteByte(this.SMBParameters, 0, EchoCount);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_ECHO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/EchoResponse.cs b/SMBLibrary/SMB1/SMBCommands/EchoResponse.cs
new file mode 100644
index 0000000..34896fc
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/EchoResponse.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_ECHO
+ ///
+ public class EchoResponse : SMBCommand
+ {
+ public const int ParametersLength = 2;
+ // Parameters
+ public ushort SequenceNumber;
+
+ public EchoResponse() : base()
+ {
+ }
+
+ public EchoResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ SequenceNumber = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, SequenceNumber);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_ECHO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/ErrorResponse.cs b/SMBLibrary/SMB1/SMBCommands/ErrorResponse.cs
new file mode 100644
index 0000000..bca6194
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/ErrorResponse.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// The Command trailer of an error response message.
+ /// See [MS-CIFS]3.3.4.1.2 - Sending Any Error Response Message.
+ ///
+ public class ErrorResponse : SMBCommand
+ {
+ private CommandName m_commandName;
+
+ public ErrorResponse(CommandName commandName) : base()
+ {
+ m_commandName = commandName;
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return m_commandName;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/FindClose2Request.cs b/SMBLibrary/SMB1/SMBCommands/FindClose2Request.cs
new file mode 100644
index 0000000..ecd4bcd
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/FindClose2Request.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_FIND_CLOSE2 Request
+ ///
+ public class FindClose2Request : SMBCommand
+ {
+ public const int ParameterCount = 2;
+ // Parameters:
+ public ushort SearchHandle;
+
+ public FindClose2Request() : base()
+ {
+ }
+
+ public FindClose2Request(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ SearchHandle = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_FIND_CLOSE2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/FindClose2Response.cs b/SMBLibrary/SMB1/SMBCommands/FindClose2Response.cs
new file mode 100644
index 0000000..921a8bb
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/FindClose2Response.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_FIND_CLOSE2 Response
+ ///
+ public class FindClose2Response : SMBCommand
+ {
+ public FindClose2Response() : base()
+ {
+ }
+
+ public FindClose2Response(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_FIND_CLOSE2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/FlushRequest.cs b/SMBLibrary/SMB1/SMBCommands/FlushRequest.cs
new file mode 100644
index 0000000..2ab11dc
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/FlushRequest.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_FLUSH Request
+ ///
+ public class FlushRequest : SMBCommand
+ {
+ public const int ParametersLength = 2;
+ // Parameters:
+ public ushort FID;
+
+ public FlushRequest() : base()
+ {
+ }
+
+ public FlushRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, FID);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_FLUSH;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/FlushResponse.cs b/SMBLibrary/SMB1/SMBCommands/FlushResponse.cs
new file mode 100644
index 0000000..86acbf0
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/FlushResponse.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_FLUSH Response
+ ///
+ public class FlushResponse : SMBCommand
+ {
+ public FlushResponse() : base()
+ {
+ }
+
+ public FlushResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_FLUSH;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/LockingAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/LockingAndXRequest.cs
new file mode 100644
index 0000000..14778c3
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/LockingAndXRequest.cs
@@ -0,0 +1,180 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// LOCKING_ANDX_RANGE32 (10-byte)
+ /// or
+ /// LOCKING_ANDX_RANGE64 (24-byte )
+ ///
+ public class LockingRange
+ {
+ public const int Length32 = 10;
+ public const int Length64 = 20;
+
+ public ushort PID;
+ public ulong ByteOffset;
+ public ulong LengthInBytes;
+
+ public void Write32(byte[] buffer, ref int offset)
+ {
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, this.PID);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, (uint)this.ByteOffset);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, (uint)this.LengthInBytes);
+ }
+
+ public void Write64(byte[] buffer, ref int offset)
+ {
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, this.PID);
+ offset += 2; // padding
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, this.ByteOffset);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, this.LengthInBytes);
+ }
+
+ public static LockingRange Read32(byte[] buffer, ref int offset)
+ {
+ LockingRange entry = new LockingRange();
+ entry.PID = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ entry.ByteOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ entry.LengthInBytes = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ return entry;
+ }
+
+ public static LockingRange Read64(byte[] buffer, ref int offset)
+ {
+ LockingRange entry = new LockingRange();
+ entry.PID = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ offset += 2; // padding
+ entry.ByteOffset = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ entry.LengthInBytes = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ return entry;
+ }
+ }
+
+ ///
+ /// SMB_COM_LOCKING_ANDX Request
+ ///
+ public class LockingAndXRequest : SMBAndXCommand
+ {
+ public const int ParametersLength = 12;
+ // Parameters:
+ public ushort FID;
+ public LockType TypeOfLock;
+ public byte NewOpLockLevel;
+ public uint Timeout;
+ //ushort NumberOfRequestedUnlocks;
+ //ushort NumberOfRequestedLocks;
+ // Data:
+ public List Unlocks = new List();
+ public List Locks = new List();
+
+ public LockingAndXRequest() : base()
+ {
+ }
+
+ public LockingAndXRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ TypeOfLock = (LockType)ByteReader.ReadByte(this.SMBParameters, 6);
+ NewOpLockLevel = ByteReader.ReadByte(this.SMBParameters, 7);
+ Timeout = LittleEndianConverter.ToUInt32(this.SMBParameters, 8);
+ ushort numberOfRequestedUnlocks = LittleEndianConverter.ToUInt16(this.SMBParameters, 12);
+ ushort numberOfRequestedLocks = LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
+
+ int dataOffset = 0;
+ if ((TypeOfLock & LockType.LARGE_FILES) > 0)
+ {
+ for (int index = 0; index < numberOfRequestedUnlocks; index++)
+ {
+ LockingRange entry = LockingRange.Read64(this.SMBData, ref dataOffset);
+ Unlocks.Add(entry);
+ }
+
+ for (int index = 0; index < numberOfRequestedLocks; index++)
+ {
+ LockingRange entry = LockingRange.Read64(this.SMBData, ref dataOffset);
+ Locks.Add(entry);
+ }
+ }
+ else
+ {
+ for (int index = 0; index < numberOfRequestedUnlocks; index++)
+ {
+ LockingRange entry = LockingRange.Read32(this.SMBData, ref dataOffset);
+ Unlocks.Add(entry);
+ }
+
+ for (int index = 0; index < numberOfRequestedLocks; index++)
+ {
+ LockingRange entry = LockingRange.Read32(this.SMBData, ref dataOffset);
+ Locks.Add(entry);
+ }
+ }
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, FID);
+ ByteWriter.WriteByte(this.SMBParameters, 6, (byte)TypeOfLock);
+ ByteWriter.WriteByte(this.SMBParameters, 7, NewOpLockLevel);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 8, Timeout);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 12, (ushort)Unlocks.Count);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, (ushort)Locks.Count);
+
+ int dataLength;
+ bool isLargeFile = (TypeOfLock & LockType.LARGE_FILES) > 0;
+ if (isLargeFile)
+ {
+ dataLength = (Unlocks.Count + Locks.Count) * LockingRange.Length64;
+ }
+ else
+ {
+ dataLength = (Unlocks.Count + Locks.Count) * LockingRange.Length32;
+ }
+ int dataOffset = 0;
+ this.SMBData = new byte[dataLength];
+ for (int index = 0; index < Unlocks.Count; index++)
+ {
+ if (isLargeFile)
+ {
+ Unlocks[index].Write64(this.SMBData, ref dataOffset);
+ }
+ else
+ {
+ Unlocks[index].Write32(this.SMBData, ref dataOffset);
+ }
+ }
+
+ for (int index = 0; index < Locks.Count; index++)
+ {
+ if (isLargeFile)
+ {
+ Locks[index].Write64(this.SMBData, ref dataOffset);
+ }
+ else
+ {
+ Locks[index].Write32(this.SMBData, ref dataOffset);
+ }
+ }
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_LOCKING_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/LockingAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/LockingAndXResponse.cs
new file mode 100644
index 0000000..5060031
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/LockingAndXResponse.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_LOCKING_ANDX Response
+ ///
+ public class LockingAndXResponse : SMBAndXCommand
+ {
+ public const uint ParametersLength = 4;
+
+ public LockingAndXResponse() : base()
+ {
+ }
+
+ public LockingAndXResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_LOCKING_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/LogoffAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/LogoffAndXRequest.cs
new file mode 100644
index 0000000..c2a89a2
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/LogoffAndXRequest.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_LOGOFF_ANDX Request
+ ///
+ public class LogoffAndXRequest : SMBAndXCommand
+ {
+ public const uint ParametersLength = 4;
+
+ public LogoffAndXRequest() : base()
+ {
+ }
+
+ public LogoffAndXRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_LOGOFF_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/LogoffAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/LogoffAndXResponse.cs
new file mode 100644
index 0000000..0939414
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/LogoffAndXResponse.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_LOGOFF_ANDX Response
+ ///
+ public class LogoffAndXResponse : SMBAndXCommand
+ {
+ public const uint ParametersLength = 4;
+
+ public LogoffAndXResponse() : base()
+ {
+ }
+
+ public LogoffAndXResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_LOGOFF_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NTCreateAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/NTCreateAndXRequest.cs
new file mode 100644
index 0000000..9b8f0de
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NTCreateAndXRequest.cs
@@ -0,0 +1,110 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NT_CREATE_ANDX Request
+ ///
+ public class NTCreateAndXRequest : SMBAndXCommand
+ {
+ public const int ParametersLength = 48;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public byte Reserved;
+ //ushort NameLength; // in bytes
+ public NTCreateFlags Flags;
+ public uint RootDirectoryFID;
+ public DesiredAccess DesiredAccess;
+ public ulong AllocationSize;
+ public ExtendedFileAttributes ExtFileAttributes;
+ public ShareAccess ShareAccess;
+ public CreateDisposition CreateDisposition;
+ public CreateOptions CreateOptions;
+ public ImpersonationLevel ImpersonationLevel;
+ public SecurityFlags SecurityFlags;
+ // Data:
+ public string FileName; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public NTCreateAndXRequest() : base()
+ {
+ }
+
+ public NTCreateAndXRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ Reserved = ByteReader.ReadByte(this.SMBParameters, 4);
+ ushort nameLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 5);
+ Flags = (NTCreateFlags)LittleEndianConverter.ToUInt32(this.SMBParameters, 7);
+ RootDirectoryFID = LittleEndianConverter.ToUInt32(this.SMBParameters, 11);
+ DesiredAccess = (DesiredAccess)LittleEndianConverter.ToUInt32(this.SMBParameters, 15);
+ AllocationSize = LittleEndianConverter.ToUInt64(this.SMBParameters, 19);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianConverter.ToUInt32(this.SMBParameters, 27);
+ ShareAccess = (ShareAccess)LittleEndianConverter.ToUInt32(this.SMBParameters, 31);
+ CreateDisposition = (CreateDisposition)LittleEndianConverter.ToUInt32(this.SMBParameters, 35);
+ CreateOptions = (CreateOptions)LittleEndianConverter.ToUInt32(this.SMBParameters, 39);
+ ImpersonationLevel = (ImpersonationLevel)LittleEndianConverter.ToUInt32(this.SMBParameters, 43);
+ SecurityFlags = (SecurityFlags)ByteReader.ReadByte(this.SMBParameters, 47);
+
+ int dataOffset = 0;
+ if (isUnicode)
+ {
+ dataOffset = 1; // 1 byte padding for 2 byte alignment
+ }
+ FileName = SMBHelper.ReadSMBString(this.SMBData, dataOffset, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ ushort nameLength = (ushort)FileName.Length;
+ this.SMBParameters = new byte[ParametersLength];
+ ByteWriter.WriteByte(this.SMBParameters, 0, (byte)AndXCommand);
+ ByteWriter.WriteByte(this.SMBParameters, 1, AndXReserved);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, AndXOffset);
+ ByteWriter.WriteByte(this.SMBParameters, 4, Reserved);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 5, nameLength);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 7, (uint)Flags);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 11, (uint)RootDirectoryFID);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 15, (uint)DesiredAccess);
+ LittleEndianWriter.WriteUInt64(this.SMBParameters, 19, (ulong)AllocationSize);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 27, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 31, (uint)ShareAccess);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 35, (uint)CreateDisposition);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 39, (uint)CreateOptions);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 43, (uint)ImpersonationLevel);
+ ByteWriter.WriteByte(this.SMBParameters, 47, (byte)SecurityFlags);
+
+ if (isUnicode)
+ {
+ int padding = 1;
+ this.SMBData = new byte[padding + FileName.Length * 2 + 2];
+ int offset = padding;
+ ByteWriter.WriteNullTerminatedUTF16String(this.SMBData, offset, FileName);
+ }
+ else
+ {
+ this.SMBData = new byte[FileName.Length + 1];
+ ByteWriter.WriteNullTerminatedUTF16String(this.SMBData, 0, FileName);
+ }
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NT_CREATE_ANDX;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/SMBLibrary/SMB1/SMBCommands/NTCreateAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/NTCreateAndXResponse.cs
new file mode 100644
index 0000000..61ece40
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NTCreateAndXResponse.cs
@@ -0,0 +1,92 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NT_CREATE_ANDX Response
+ ///
+ public class NTCreateAndXResponse : SMBAndXCommand
+ {
+ public const int ParametersLength = 68;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public OpLockLevel OpLockLevel;
+ public ushort FID;
+ public CreateDisposition CreateDisposition;
+ public DateTime CreateTime;
+ public DateTime LastAccessTime;
+ public DateTime LastWriteTime;
+ public DateTime LastChangeTime;
+ public ExtendedFileAttributes ExtFileAttributes;
+ public ulong AllocationSize;
+ public ulong EndOfFile;
+ public ResourceType ResourceType;
+ public NamedPipeStatus NMPipeStatus;
+ public bool Directory;
+
+ public NTCreateAndXResponse() : base()
+ {
+ CreateTime = SMBHelper.FileTimeNotSpecified;
+ LastAccessTime = SMBHelper.FileTimeNotSpecified;
+ LastWriteTime = SMBHelper.FileTimeNotSpecified;
+ LastChangeTime = SMBHelper.FileTimeNotSpecified;
+ }
+
+ public NTCreateAndXResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ int parametersOffset = 4;
+ OpLockLevel = (OpLockLevel)ByteReader.ReadByte(this.SMBParameters, ref parametersOffset);
+ FID = LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ CreateDisposition = (CreateDisposition)LittleEndianReader.ReadUInt32(this.SMBParameters, ref parametersOffset);
+ CreateTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ LastAccessTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ LastWriteTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ LastChangeTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(this.SMBParameters, ref parametersOffset);
+ AllocationSize = LittleEndianReader.ReadUInt64(buffer, ref parametersOffset);
+ EndOfFile = LittleEndianReader.ReadUInt64(buffer, ref parametersOffset);
+ ResourceType = (ResourceType)LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ NMPipeStatus = NamedPipeStatus.Read(this.SMBParameters, ref parametersOffset);
+ Directory = (ByteReader.ReadByte(this.SMBParameters, ref parametersOffset) > 0);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ int parametersOffset = 4;
+ ByteWriter.WriteByte(this.SMBParameters, ref parametersOffset, (byte)OpLockLevel);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, FID);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref parametersOffset, (uint)CreateDisposition);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, CreateTime);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, LastAccessTime);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, LastWriteTime);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, LastChangeTime);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref parametersOffset, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt64(this.SMBParameters, ref parametersOffset, AllocationSize);
+ LittleEndianWriter.WriteUInt64(this.SMBParameters, ref parametersOffset, EndOfFile);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)ResourceType);
+ NMPipeStatus.WriteBytes(this.SMBParameters, ref parametersOffset);
+ ByteWriter.WriteByte(this.SMBParameters, ref parametersOffset, Convert.ToByte(Directory));
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NT_CREATE_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NTCreateAndXResponseExtended.cs b/SMBLibrary/SMB1/SMBCommands/NTCreateAndXResponseExtended.cs
new file mode 100644
index 0000000..9bcfdf1
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NTCreateAndXResponseExtended.cs
@@ -0,0 +1,128 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NT_CREATE_ANDX Extended Response
+ ///
+ public class NTCreateAndXResponseExtended : SMBAndXCommand
+ {
+ public const int ParametersLength = 100;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public OpLockLevel OpLockLevel;
+ public ushort FID;
+ public CreateDisposition CreateDisposition;
+ public DateTime CreateTime;
+ public DateTime LastAccessTime;
+ public DateTime LastWriteTime;
+ public DateTime LastChangeTime;
+ public ExtendedFileAttributes ExtFileAttributes;
+ public ulong AllocationSize;
+ public ulong EndOfFile;
+ public ResourceType ResourceType;
+ public ushort NMPipeStatus_or_FileStatusFlags;
+ public bool Directory;
+ public Guid VolumeGuid;
+ public ulong FileID;
+ public AccessMask MaximalAccessRights;
+ public AccessMask GuestMaximalAccessRights;
+
+ public NTCreateAndXResponseExtended() : base()
+ {
+ CreateTime = SMBHelper.FileTimeNotSpecified;
+ LastAccessTime = SMBHelper.FileTimeNotSpecified;
+ LastWriteTime = SMBHelper.FileTimeNotSpecified;
+ LastChangeTime = SMBHelper.FileTimeNotSpecified;
+ }
+
+ public NTCreateAndXResponseExtended(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ int parametersOffset = 4;
+ OpLockLevel = (OpLockLevel)ByteReader.ReadByte(this.SMBParameters, ref parametersOffset);
+ FID = LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ CreateDisposition = (CreateDisposition)LittleEndianReader.ReadUInt32(this.SMBParameters, ref parametersOffset);
+ CreateTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ LastAccessTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ LastWriteTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ LastChangeTime = SMBHelper.ReadFileTime(buffer, ref parametersOffset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(this.SMBParameters, ref parametersOffset);
+ AllocationSize = LittleEndianReader.ReadUInt64(buffer, ref parametersOffset);
+ EndOfFile = LittleEndianReader.ReadUInt64(buffer, ref parametersOffset);
+ ResourceType = (ResourceType)LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ NMPipeStatus_or_FileStatusFlags = LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ Directory = (ByteReader.ReadByte(this.SMBParameters, ref parametersOffset) > 0);
+ VolumeGuid = LittleEndianReader.ReadGuid(this.SMBParameters, ref parametersOffset);
+ FileID = LittleEndianReader.ReadUInt64(this.SMBParameters, ref parametersOffset);
+ MaximalAccessRights = new AccessMask(this.SMBParameters, ref parametersOffset);
+ GuestMaximalAccessRights = new AccessMask(this.SMBParameters, ref parametersOffset);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ int parametersOffset = 4;
+ ByteWriter.WriteByte(this.SMBParameters, ref parametersOffset, (byte)OpLockLevel);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, FID);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref parametersOffset, (uint)CreateDisposition);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, CreateTime);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, LastAccessTime);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, LastWriteTime);
+ SMBHelper.WriteFileTime(this.SMBParameters, ref parametersOffset, LastChangeTime);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref parametersOffset, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt64(this.SMBParameters, ref parametersOffset, AllocationSize);
+ LittleEndianWriter.WriteUInt64(this.SMBParameters, ref parametersOffset, EndOfFile);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)ResourceType);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, NMPipeStatus_or_FileStatusFlags);
+ ByteWriter.WriteByte(this.SMBParameters, ref parametersOffset, Convert.ToByte(Directory));
+ LittleEndianWriter.WriteGuidBytes(this.SMBParameters, ref parametersOffset, VolumeGuid);
+ LittleEndianWriter.WriteUInt64(this.SMBParameters, ref parametersOffset, FileID);
+ MaximalAccessRights.WriteBytes(this.SMBParameters, ref parametersOffset);
+ GuestMaximalAccessRights.WriteBytes(this.SMBParameters, ref parametersOffset);
+ return base.GetBytes(isUnicode);
+ }
+
+ public NamedPipeStatus NMPipeStatus
+ {
+ get
+ {
+ return new NamedPipeStatus(NMPipeStatus_or_FileStatusFlags);
+ }
+ set
+ {
+ NMPipeStatus_or_FileStatusFlags = value.ToUInt16();
+ }
+ }
+
+ public FileStatus FileStatus
+ {
+ get
+ {
+ return (FileStatus)NMPipeStatus_or_FileStatusFlags;
+ }
+ set
+ {
+ NMPipeStatus_or_FileStatusFlags = (ushort)value;
+ }
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NT_CREATE_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NTTransactInterimResponse.cs b/SMBLibrary/SMB1/SMBCommands/NTTransactInterimResponse.cs
new file mode 100644
index 0000000..d06e4df
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NTTransactInterimResponse.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NT_TRANSACT Interim Response
+ ///
+ public class NTTransactInterimResponse : SMBCommand
+ {
+ public const int ParametersLength = 0;
+
+ public NTTransactInterimResponse() : base()
+ {
+ }
+
+ public NTTransactInterimResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NT_TRANSACT;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NTTransactRequest.cs b/SMBLibrary/SMB1/SMBCommands/NTTransactRequest.cs
new file mode 100644
index 0000000..0f62374
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NTTransactRequest.cs
@@ -0,0 +1,110 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NT_TRANSACT Request
+ ///
+ public class NTTransactRequest : SMBCommand
+ {
+ public const int FixedSMBParametersLength = 38;
+ // Parameters:
+ public byte MaxSetupCount;
+ public ushort Reserved1;
+ public uint TotalParameterCount;
+ public uint TotalDataCount;
+ public uint MaxParameterCount;
+ public uint MaxDataCount;
+ //uint ParameterCount;
+ //uint ParameterOffset;
+ //uint DataCount;
+ //uint DataOffset;
+ //byte SetupCount; // In 2-byte words
+ public NTTransactSubcommandName Function;
+ public byte[] Setup;
+ // Data:
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransParameters; // Trans_Parameters
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransData; // Trans_Data
+
+ public NTTransactRequest() : base()
+ {
+ }
+
+ public NTTransactRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ int readOffset = 0;
+ MaxSetupCount = ByteReader.ReadByte(this.SMBParameters, ref readOffset);
+ Reserved1 = LittleEndianReader.ReadUInt16(this.SMBParameters, ref readOffset);
+ TotalParameterCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ TotalDataCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ MaxParameterCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ MaxDataCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint parameterCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint parameterOffset = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint dataCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint dataOffset = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ byte setupCount = ByteReader.ReadByte(this.SMBParameters, ref readOffset);
+ Function = (NTTransactSubcommandName)LittleEndianReader.ReadUInt16(this.SMBParameters, ref readOffset);
+ Setup = ByteReader.ReadBytes(this.SMBParameters, ref readOffset, setupCount * 2);
+
+ TransParameters = ByteReader.ReadBytes(buffer, (int)parameterOffset, (int)parameterCount);
+ TransData = ByteReader.ReadBytes(buffer, (int)dataOffset, (int)dataCount);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte setupCount = (byte)(Setup.Length / 2);
+ uint parameterCount = (ushort)TransParameters.Length;
+ uint dataCount = (ushort)TransData.Length;
+
+ // WordCount + ByteCount are additional 3 bytes
+ uint parameterOffset = (ushort)(SMBHeader.Length + 3 + (FixedSMBParametersLength + Setup.Length));
+ int padding1 = (int)(4 - (parameterOffset % 4)) % 4;
+ parameterOffset += (ushort)padding1;
+ uint dataOffset = (ushort)(parameterOffset + parameterCount);
+ int padding2 = (int)(4 - (dataOffset % 4)) % 4;
+ dataOffset += (ushort)padding2;
+
+ this.SMBParameters = new byte[FixedSMBParametersLength + Setup.Length];
+ int writeOffset = 0;
+ ByteWriter.WriteByte(this.SMBParameters, ref writeOffset, MaxSetupCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref writeOffset, Reserved1);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, TotalParameterCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, TotalDataCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, MaxParameterCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, MaxDataCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, parameterCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, parameterOffset);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, dataCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, dataOffset);
+ ByteWriter.WriteByte(this.SMBParameters, ref writeOffset, setupCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref writeOffset, (ushort)Function);
+ ByteWriter.WriteBytes(this.SMBParameters, ref writeOffset, Setup);
+
+ this.SMBData = new byte[parameterCount + dataCount + padding1 + padding2];
+ ByteWriter.WriteBytes(this.SMBData, padding1, TransParameters);
+ ByteWriter.WriteBytes(this.SMBData, (int)(padding1 + parameterCount + padding2), TransData);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NT_TRANSACT;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NTTransactResponse.cs b/SMBLibrary/SMB1/SMBCommands/NTTransactResponse.cs
new file mode 100644
index 0000000..d237e2e
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NTTransactResponse.cs
@@ -0,0 +1,121 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NT_TRANSACT Response
+ ///
+ public class NTTransactResponse : SMBCommand
+ {
+ public const int FixedSMBParametersLength = 36;
+ // Parameters:
+ public byte[] Reserved1; // 3 bytes
+ public uint TotalParameterCount;
+ public uint TotalDataCount;
+ //uint ParameterCount;
+ //uint ParameterOffset;
+ //uint ParameterDisplacement;
+ //uint DataCount;
+ //uint DataOffset;
+ //uint DataDisplacement;
+ //byte SetupCount; // In 2-byte words
+ public byte[] Setup;
+ // Data:
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransParameters; // Trans_Parameters
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransData; // Trans_Data
+
+ public NTTransactResponse() : base()
+ {
+ Reserved1 = new byte[3];
+ }
+
+ public NTTransactResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ int readOffset = 0;
+ Reserved1 = ByteReader.ReadBytes(this.SMBParameters, ref readOffset, 3);
+ TotalParameterCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ TotalDataCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint parameterCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint parameterOffset = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint parameterDisplacement = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint dataCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint dataOffset = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint dataDisplacement = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ byte setupCount = ByteReader.ReadByte(this.SMBParameters, ref readOffset);
+ Setup = ByteReader.ReadBytes(this.SMBParameters, ref offset, setupCount * 2);
+
+ TransParameters = ByteReader.ReadBytes(buffer, (int)parameterOffset, (int)parameterCount);
+ TransData = ByteReader.ReadBytes(buffer, (int)dataOffset, (int)dataCount);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte setupCount = (byte)(Setup.Length / 2);
+ uint parameterCount = (ushort)TransParameters.Length;
+ uint dataCount = (ushort)TransData.Length;
+ uint parameterDisplacement = 0;
+ uint dataDisplacement = 0;
+
+ // WordCount + ByteCount are additional 3 bytes
+ uint parameterOffset = (ushort)(SMBHeader.Length + 3 + (FixedSMBParametersLength + Setup.Length));
+ int padding1 = (int)(4 - (parameterOffset % 4)) % 4;
+ parameterOffset += (ushort)padding1;
+ uint dataOffset = (ushort)(parameterOffset + parameterCount);
+ int padding2 = (int)(4 - (dataOffset % 4)) % 4;
+ dataOffset += (ushort)padding2;
+
+ this.SMBParameters = new byte[FixedSMBParametersLength + Setup.Length];
+ int writeOffset = 0;
+ ByteWriter.WriteBytes(this.SMBParameters, ref writeOffset, Reserved1, 3);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, TotalParameterCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, TotalDataCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, parameterCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, parameterOffset);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, parameterDisplacement);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, dataCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, dataOffset);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, dataDisplacement);
+ ByteWriter.WriteByte(this.SMBParameters, ref writeOffset, setupCount);
+ ByteWriter.WriteBytes(this.SMBParameters, ref writeOffset, Setup);
+
+ this.SMBData = new byte[parameterCount + dataCount + padding1 + padding2];
+ ByteWriter.WriteBytes(this.SMBData, padding1, TransParameters);
+ ByteWriter.WriteBytes(this.SMBData, (int)(padding1 + parameterCount + padding2), TransData);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NT_TRANSACT;
+ }
+ }
+
+ public static int CalculateMessageSize(int setupLength, int trans2ParametersLength, int trans2DataLength)
+ {
+ int parameterOffset = SMBHeader.Length + 3 + (FixedSMBParametersLength + setupLength);
+ int padding1 = (4 - (parameterOffset % 4)) % 4;
+ parameterOffset += padding1;
+ int dataOffset = (parameterOffset + trans2ParametersLength);
+ int padding2 = (4 - (dataOffset % 4)) % 4;
+
+ int messageParametersLength = FixedSMBParametersLength + setupLength;
+ int messageDataLength = trans2ParametersLength + trans2DataLength + padding1 + padding2;
+ // WordCount + ByteCount are additional 3 bytes
+ return SMBHeader.Length + messageParametersLength + messageDataLength + 3;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NTTransactSecondaryRequest.cs b/SMBLibrary/SMB1/SMBCommands/NTTransactSecondaryRequest.cs
new file mode 100644
index 0000000..3f7a0e2
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NTTransactSecondaryRequest.cs
@@ -0,0 +1,101 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NT_TRANSACT_SECONDARY Request
+ ///
+ public class NTTransactSecondaryRequest : SMBCommand
+ {
+ public const int SMBParametersLength = 36;
+ // Parameters:
+ public byte[] Reserved1; // 3 bytes
+ public uint TotalParameterCount;
+ public uint TotalDataCount;
+ //uint ParameterCount;
+ //uint ParameterOffset;
+ public uint ParameterDisplacement;
+ //uint DataCount;
+ //uint DataOffset;
+ public uint DataDisplacement;
+ public byte Reserved2;
+ // Data:
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransParameters; // Trans_Parameters
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransData; // Trans_Data
+
+ public NTTransactSecondaryRequest() : base()
+ {
+ Reserved1 = new byte[3];
+ }
+
+ public NTTransactSecondaryRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ int readOffset = 0;
+ Reserved1 = ByteReader.ReadBytes(this.SMBParameters, ref readOffset, 3);
+ TotalParameterCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ TotalDataCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint parameterCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint parameterOffset = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ ParameterDisplacement = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint dataCount = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ uint dataOffset = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ DataDisplacement = LittleEndianReader.ReadUInt32(this.SMBParameters, ref readOffset);
+ Reserved2 = ByteReader.ReadByte(this.SMBParameters, ref readOffset);
+
+ TransParameters = ByteReader.ReadBytes(buffer, (int)parameterOffset, (int)parameterCount);
+ TransData = ByteReader.ReadBytes(buffer, (int)dataOffset, (int)dataCount);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ uint parameterCount = (ushort)TransParameters.Length;
+ uint dataCount = (ushort)TransData.Length;
+
+ // WordCount + ByteCount are additional 3 bytes
+ uint parameterOffset = (ushort)(SMBHeader.Length + 3 + (SMBParametersLength));
+ int padding1 = (int)(4 - (parameterOffset % 4)) % 4;
+ parameterOffset += (ushort)padding1;
+ uint dataOffset = (ushort)(parameterOffset + parameterCount);
+ int padding2 = (int)(4 - (dataOffset % 4)) % 4;
+ dataOffset += (ushort)padding2;
+
+ this.SMBParameters = new byte[SMBParametersLength];
+ int writeOffset = 0;
+ ByteWriter.WriteBytes(this.SMBParameters, ref writeOffset, Reserved1, 3);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, TotalParameterCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, TotalDataCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, parameterCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, parameterOffset);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, ParameterDisplacement);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, dataCount);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, dataOffset);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref writeOffset, DataDisplacement);
+ ByteWriter.WriteByte(this.SMBParameters, ref writeOffset, Reserved2);
+
+ this.SMBData = new byte[parameterCount + dataCount + padding1 + padding2];
+ ByteWriter.WriteBytes(this.SMBData, padding1, TransParameters);
+ ByteWriter.WriteBytes(this.SMBData, (int)(padding1 + parameterCount + padding2), TransData);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NT_TRANSACT_SECONDARY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NegotiateRequest.cs b/SMBLibrary/SMB1/SMBCommands/NegotiateRequest.cs
new file mode 100644
index 0000000..8dc92cf
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NegotiateRequest.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NEGOTIATE Request
+ ///
+ public class NegotiateRequest : SMBCommand
+ {
+ public const int SupportedBufferFormat = 0x02;
+ // Data:
+ public List Dialects = new List();
+
+ public NegotiateRequest() : base()
+ {
+ }
+
+ public NegotiateRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ int dataOffset = 0;
+ while (dataOffset < this.SMBData.Length)
+ {
+ byte bufferFormat = ByteReader.ReadByte(this.SMBData, ref dataOffset);
+ if (bufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ string dialect = ByteReader.ReadNullTerminatedAnsiString(this.SMBData, dataOffset);
+ Dialects.Add(dialect);
+ dataOffset += dialect.Length + 1;
+ }
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ int length = 0;
+ foreach (string dialect in this.Dialects)
+ {
+ length += 1 + dialect.Length + 1;
+ }
+
+ this.SMBParameters = new byte[0];
+ this.SMBData = new byte[length];
+ int offset = 0;
+ foreach (string dialect in this.Dialects)
+ {
+ ByteWriter.WriteByte(this.SMBData, offset, 0x02);
+ ByteWriter.WriteAnsiString(this.SMBData, offset + 1, dialect, dialect.Length);
+ ByteWriter.WriteByte(this.SMBData, offset + 1 + dialect.Length, 0x00);
+ offset += 1 + dialect.Length + 1;
+ }
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NEGOTIATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNTLM.cs b/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNTLM.cs
new file mode 100644
index 0000000..07ab51a
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNTLM.cs
@@ -0,0 +1,88 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NEGOTIATE Response, NT LAN Manager dialect
+ ///
+ public class NegotiateResponseNTLM : SMBCommand
+ {
+ public const int ParametersLength = 34;
+ // Parameters:
+ public ushort DialectIndex;
+ public SecurityMode SecurityMode;
+ public ushort MaxMpxCount;
+ public ushort MaxNumberVcs;
+ public uint MaxBufferSize;
+ public uint MaxRawSize;
+ public uint SessionKey;
+ public ServerCapabilities Capabilities;
+ public DateTime SystemTime;
+ public short ServerTimeZone;
+ //byte ChallengeLength;
+ // Data:
+ public byte[] Challenge;
+ public string DomainName; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string ServerName; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public NegotiateResponseNTLM() : base()
+ {
+ Challenge = new byte[0];
+ DomainName = String.Empty;
+ ServerName = String.Empty;
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte challengeLength = (byte)this.Challenge.Length;
+
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, DialectIndex);
+ ByteWriter.WriteByte(this.SMBParameters, 2, (byte)SecurityMode);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 3, MaxMpxCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 5, MaxNumberVcs);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 7, MaxBufferSize);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 11, MaxRawSize);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 15, SessionKey);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 19, (uint)Capabilities);
+ LittleEndianWriter.WriteInt64(this.SMBParameters, 23, SystemTime.ToFileTimeUtc());
+ LittleEndianWriter.WriteInt16(this.SMBParameters, 31, ServerTimeZone);
+ ByteWriter.WriteByte(this.SMBParameters, 33, challengeLength);
+
+ int padding = 0;
+ if (isUnicode)
+ {
+ padding = Challenge.Length % 2;
+ this.SMBData = new byte[Challenge.Length + padding + DomainName.Length * 2 + ServerName.Length * 2 + 4];
+ }
+ else
+ {
+ this.SMBData = new byte[Challenge.Length + DomainName.Length + ServerName.Length + 2];
+ }
+ int offset = 0;
+ ByteWriter.WriteBytes(this.SMBData, ref offset, Challenge);
+ offset += padding;
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, DomainName);
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, ServerName);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NEGOTIATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNTLMExtended.cs b/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNTLMExtended.cs
new file mode 100644
index 0000000..a69c825
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNTLMExtended.cs
@@ -0,0 +1,79 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NEGOTIATE Response, NT LAN Manager dialect, Extended Security response
+ ///
+ public class NegotiateResponseNTLMExtended : SMBCommand
+ {
+ public const int ParametersLength = 34;
+ // Parameters:
+ public ushort DialectIndex;
+ public SecurityMode SecurityMode;
+ public ushort MaxMpxCount;
+ public ushort MaxNumberVcs;
+ public uint MaxBufferSize;
+ public uint MaxRawSize;
+ public uint SessionKey;
+ public ServerCapabilities Capabilities;
+ public DateTime SystemTime;
+ public short ServerTimeZone;
+ //byte ChallengeLength; // MUST be set to 0
+ // Data:
+ public Guid ServerGuid;
+ public byte[] SecurityBlob;
+
+ public NegotiateResponseNTLMExtended() : base()
+ {
+ // MS-SMB Page 129: The server can leave SecurityBlob empty if not configured to send GSS token
+ SecurityBlob = new byte[0];
+ }
+
+ public NegotiateResponseNTLMExtended(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte challengeLength = 0;
+
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, DialectIndex);
+ ByteWriter.WriteByte(this.SMBParameters, 2, (byte)SecurityMode);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 3, MaxMpxCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 5, MaxNumberVcs);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 7, MaxBufferSize);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 11, MaxRawSize);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 15, SessionKey);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 19, (uint)Capabilities);
+ LittleEndianWriter.WriteInt64(this.SMBParameters, 23, SystemTime.ToFileTimeUtc());
+ LittleEndianWriter.WriteInt16(this.SMBParameters, 31, ServerTimeZone);
+ ByteWriter.WriteByte(this.SMBParameters, 33, challengeLength);
+
+ this.SMBData = new byte[16 + SecurityBlob.Length];
+ LittleEndianWriter.WriteGuidBytes(this.SMBData, 0, ServerGuid);
+ ByteWriter.WriteBytes(this.SMBData, 16, SecurityBlob);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NEGOTIATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNotSupported.cs b/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNotSupported.cs
new file mode 100644
index 0000000..e784621
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/NegotiateResponseNotSupported.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_NEGOTIATE Response
+ ///
+ public class NegotiateResponseNotSupported : SMBCommand
+ {
+ public const int ParametersLength = 2;
+ public const ushort DialectsNotSupported = 0xFFFF;
+
+ public NegotiateResponseNotSupported() : base()
+ {
+ }
+
+ public NegotiateResponseNotSupported(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, DialectsNotSupported);
+
+ this.SMBData = new byte[0];
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_NEGOTIATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/OpenAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/OpenAndXRequest.cs
new file mode 100644
index 0000000..a48bcd1
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/OpenAndXRequest.cs
@@ -0,0 +1,74 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_OPEN_ANDX Request
+ ///
+ public class OpenAndXRequest : SMBAndXCommand
+ {
+ public const int ParametersLength = 30;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public OpenFlags Flags;
+ public AccessModeOptions AccessMode;
+ public FileAttributes SearchAttrs;
+ public FileAttributes FileAttrs;
+ public DateTime CreationTime; // UTime
+ public OpenMode OpenMode;
+ public uint AllocationSize;
+ public uint Timeout;
+ public uint Reserved;
+ // Data:
+ public string FileName; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public OpenAndXRequest() : base()
+ {
+ }
+
+ public OpenAndXRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ int parametersOffset = 4;
+ Flags = (OpenFlags)LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ AccessMode = AccessModeOptions.Read(this.SMBParameters, ref parametersOffset);
+ SearchAttrs = (FileAttributes)LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ FileAttrs = (FileAttributes)LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ CreationTime = SMBHelper.ReadUTime(this.SMBParameters, ref parametersOffset);
+ OpenMode = OpenMode.Read(this.SMBParameters, ref parametersOffset);
+ AllocationSize = LittleEndianReader.ReadUInt32(this.SMBParameters, ref parametersOffset);
+ Timeout = LittleEndianReader.ReadUInt32(this.SMBParameters, ref parametersOffset);
+ Reserved = LittleEndianReader.ReadUInt32(this.SMBParameters, ref parametersOffset);
+
+ int dataOffset = 0;
+ if (isUnicode)
+ {
+ dataOffset = 1; // 1 byte padding for 2 byte alignment
+ }
+ FileName = SMBHelper.ReadSMBString(this.SMBData, dataOffset, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_OPEN_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/OpenAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/OpenAndXResponse.cs
new file mode 100644
index 0000000..23d23d1
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/OpenAndXResponse.cs
@@ -0,0 +1,69 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_OPEN_ANDX Response
+ ///
+ public class OpenAndXResponse : SMBAndXCommand
+ {
+ public const int ParametersLength = 30;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public ushort FID;
+ public FileAttributes FileAttrs;
+ public DateTime LastWriteTime; // UTime
+ public uint FileDataSize;
+ public AccessRights AccessRights;
+ public ResourceType ResourceType;
+ public NamedPipeStatus NMPipeStatus;
+ public OpenResults OpenResults;
+ public byte[] Reserved; // 6 bytes
+
+ public OpenAndXResponse() : base()
+ {
+ LastWriteTime = SMBHelper.UTimeNotSpecified;
+ Reserved = new byte[6];
+ }
+
+ public OpenAndXResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ int parametersOffset = 4;
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, FID);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)FileAttrs);
+ SMBHelper.WriteUTime(this.SMBParameters, ref parametersOffset, LastWriteTime);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref parametersOffset, FileDataSize);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)AccessRights);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)ResourceType);
+ NMPipeStatus.WriteBytes(this.SMBParameters, ref parametersOffset);
+ OpenResults.WriteBytes(this.SMBParameters, ref parametersOffset);
+ ByteWriter.WriteBytes(this.SMBParameters, ref parametersOffset, Reserved, 6);
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_OPEN_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/OpenAndXResponseExtended.cs b/SMBLibrary/SMB1/SMBCommands/OpenAndXResponseExtended.cs
new file mode 100644
index 0000000..16739d4
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/OpenAndXResponseExtended.cs
@@ -0,0 +1,74 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_OPEN_ANDX Response Extended
+ ///
+ public class OpenAndXResponseExtended : SMBAndXCommand
+ {
+ public const int ParametersLength = 38;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public ushort FID;
+ public FileAttributes FileAttrs;
+ public DateTime LastWriteTime; // UTime
+ public uint FileDataSize;
+ public AccessRights AccessRights;
+ public ResourceType ResourceType;
+ public NamedPipeStatus NMPipeStatus;
+ public OpenResults OpenResults;
+ public uint ServerFID;
+ public ushort Reserved;
+ public AccessMask MaximalAccessRights;
+ public AccessMask GuestMaximalAccessRights;
+
+ public OpenAndXResponseExtended() : base()
+ {
+ LastWriteTime = SMBHelper.UTimeNotSpecified;
+ }
+
+ public OpenAndXResponseExtended(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ int parametersOffset = 4;
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, FID);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)FileAttrs);
+ SMBHelper.WriteUTime(this.SMBParameters, ref parametersOffset, LastWriteTime);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref parametersOffset, FileDataSize);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)AccessRights);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)ResourceType);
+ NMPipeStatus.WriteBytes(this.SMBParameters, ref parametersOffset);
+ OpenResults.WriteBytes(this.SMBParameters, ref parametersOffset);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, ref parametersOffset, ServerFID);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, Reserved);
+ MaximalAccessRights.WriteBytes(this.SMBParameters, ref parametersOffset);
+ GuestMaximalAccessRights.WriteBytes(this.SMBParameters, ref parametersOffset);
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_OPEN_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/QueryInformationRequest.cs b/SMBLibrary/SMB1/SMBCommands/QueryInformationRequest.cs
new file mode 100644
index 0000000..736c1a0
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/QueryInformationRequest.cs
@@ -0,0 +1,68 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_QUERY_INFORMATION Request.
+ /// This command is deprecated.
+ /// This command is used by Windows NT4 SP6.
+ ///
+ public class QueryInformationRequest : SMBCommand
+ {
+ public const byte SupportedBufferFormat = 0x04;
+ // Data:
+ public byte BufferFormat;
+ public string FileName; // SMB_STRING
+
+ public QueryInformationRequest() : base()
+ {
+ BufferFormat = SupportedBufferFormat;
+ FileName = String.Empty;
+ }
+
+ public QueryInformationRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ FileName = SMBHelper.ReadSMBString(this.SMBData, 1, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ int length = 1;
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ this.SMBData = new byte[1 + length];
+ ByteWriter.WriteByte(this.SMBData, 0, BufferFormat);
+ SMBHelper.WriteSMBString(this.SMBData, 1, isUnicode, FileName);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_QUERY_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/QueryInformationResponse.cs b/SMBLibrary/SMB1/SMBCommands/QueryInformationResponse.cs
new file mode 100644
index 0000000..ee4770d
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/QueryInformationResponse.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_QUERY_INFORMATION Request.
+ /// This command is deprecated.
+ /// This command is used by Windows NT4 SP6.
+ ///
+ public class QueryInformationResponse : SMBCommand
+ {
+ public const int ParameterLength = 20;
+ // Parameters:
+ public FileAttributes FileAttributes;
+ public DateTime LastWriteTime;
+ public uint FileSize;
+ public byte[] Reserved; // 10 bytes
+
+ public QueryInformationResponse() : base()
+ {
+ Reserved = new byte[10];
+ }
+
+ public QueryInformationResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ LastWriteTime = SMBHelper.ReadSMBDateTime(this.SMBParameters, 2);
+ FileSize = LittleEndianConverter.ToUInt32(this.SMBParameters, 6);
+ Reserved = ByteReader.ReadBytes(this.SMBParameters, 10, 10);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParameterLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, (ushort)FileAttributes);
+ SMBHelper.WriteSMBDateTime(this.SMBParameters, 2, LastWriteTime);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 6, FileSize);
+ ByteWriter.WriteBytes(this.SMBParameters, 10, Reserved, 10);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_QUERY_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/ReadAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/ReadAndXRequest.cs
new file mode 100644
index 0000000..5f8b73e
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/ReadAndXRequest.cs
@@ -0,0 +1,120 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_READ_ANDX Request
+ /// SMB 1.0: The Timeout field becomes Timeout_or_MaxCountHigh (used when the CAP_LARGE_READX capability has been negotiated)
+ ///
+ public class ReadAndXRequest : SMBAndXCommand
+ {
+ public const int ParametersFixedLength = 20;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public ushort FID;
+ public ulong Offset; // 4 bytes + 4 optional 'OffsetHigh' bytes
+ private ushort MaxCountOfBytesToReturn; // See 'Timeout_or_MaxCountHigh' comment
+ public ushort MinCountOfBytesToReturn;
+ ///
+ /// SMB 1.0: When reading from a regular file, the field MUST be interpreted as
+ /// MaxCountHigh and the two unused bytes MUST be zero.
+ /// When reading from a name pipe or I/O device, the field MUST be interpreted as Timeout.
+ ///
+ public uint Timeout_or_MaxCountHigh; // CIFS 1.0: Timeout only
+ public ushort Remaining;
+
+ public ReadAndXRequest() : base()
+ {
+ }
+
+ public ReadAndXRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ Offset = LittleEndianConverter.ToUInt32(this.SMBParameters, 6);
+ MaxCountOfBytesToReturn = LittleEndianConverter.ToUInt16(this.SMBParameters, 10);
+ MinCountOfBytesToReturn = LittleEndianConverter.ToUInt16(this.SMBParameters, 12);
+ Timeout_or_MaxCountHigh = LittleEndianConverter.ToUInt32(this.SMBParameters, 14);
+ Remaining = LittleEndianConverter.ToUInt16(this.SMBParameters, 18);
+ if (SMBParameters.Length == ParametersFixedLength + 4)
+ {
+ uint offsetHigh = LittleEndianConverter.ToUInt32(this.SMBParameters, 20);
+ Offset |= ((ulong)offsetHigh << 32);
+ }
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ int parametersLength = ParametersFixedLength;
+ if (Offset > UInt32.MaxValue)
+ {
+ parametersLength += 4;
+ }
+
+ this.SMBParameters = new byte[parametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, FID);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 6, (uint)(Offset & 0xFFFFFFFF));
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 10, (ushort)(MaxCountOfBytesToReturn & 0xFFFF));
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 12, MinCountOfBytesToReturn);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 14, Timeout_or_MaxCountHigh);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 18, Remaining);
+ if (Offset > UInt32.MaxValue)
+ {
+ uint offsetHigh = (uint)(Offset >> 32);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 20, offsetHigh);
+ }
+
+ return base.GetBytes(isUnicode);
+ }
+
+ ///
+ /// The number of bytes to return when reading from a file and LargeRead is negotiated
+ ///
+ public uint MaxCountLarge
+ {
+ get
+ {
+ ushort maxCountHigh = (ushort)(Timeout_or_MaxCountHigh & 0xFFFF);
+ return (uint)(maxCountHigh << 16) | MaxCountOfBytesToReturn;
+ }
+ set
+ {
+ MaxCountOfBytesToReturn = (ushort)(value & 0xFFFF);
+ Timeout_or_MaxCountHigh = (ushort)(value >> 16);
+ }
+ }
+
+ ///
+ /// The number of bytes to return when reading from a named pipe or LargeRead is not negotiated
+ ///
+ public ushort MaxCount
+ {
+ get
+ {
+ return MaxCountOfBytesToReturn;
+ }
+ set
+ {
+ MaxCountOfBytesToReturn = value;
+ }
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_READ_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/ReadAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/ReadAndXResponse.cs
new file mode 100644
index 0000000..6930e35
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/ReadAndXResponse.cs
@@ -0,0 +1,99 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_READ_ANDX Response
+ /// SMB 1.0: The 2 reserved bytes at offset 14 become DataLengthHigh (used when the CAP_LARGE_READX capability has been negotiated)
+ ///
+ public class ReadAndXResponse : SMBAndXCommand
+ {
+ public const int ParametersLength = 24;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public ushort Available;
+ public ushort DataCompactionMode; // Not used and MUST be 0x0000
+ public ushort Reserved1;
+ //uint DataLength; // 2 bytes + 2 'DataLengthHigh' bytes
+ //ushort DataOffset;
+ public byte[] Reserved2; // 8 bytes
+ // Data:
+ // 1 byte padding - if unicode strings are being used, this field MUST be present, otherwise it's optional.
+ public byte[] Data;
+
+ public ReadAndXResponse() : base()
+ {
+ Reserved2 = new byte[8];
+ }
+
+ public ReadAndXResponse(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ Available = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ DataCompactionMode = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
+ Reserved1 = LittleEndianConverter.ToUInt16(this.SMBParameters, 8);
+ uint DataLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 10);
+ ushort DataOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 12);
+ ushort dataLengthHigh = LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
+ Reserved2 = ByteReader.ReadBytes(buffer, 16, 8);
+
+ DataLength |= (uint)(dataLengthHigh << 16);
+
+ Data = ByteReader.ReadBytes(buffer, DataOffset, (int)DataLength);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ uint DataLength = (uint)Data.Length;
+ // WordCount + ByteCount are additional 3 bytes
+ ushort DataOffset = SMBHeader.Length + 3 + ParametersLength;
+ if (isUnicode)
+ {
+ DataOffset++;
+ }
+ ushort dataLengthHigh = (ushort)(DataLength >> 16);
+
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, Available);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, DataCompactionMode);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 8, Reserved1);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 10, (ushort)(DataLength & 0xFFFF));
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 12, DataOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, dataLengthHigh);
+ ByteWriter.WriteBytes(this.SMBParameters, 16, Reserved2);
+
+ int smbDataLength = Data.Length;
+ if (isUnicode)
+ {
+ smbDataLength++;
+ }
+ this.SMBData = new byte[smbDataLength];
+ int offset = 0;
+ if (isUnicode)
+ {
+ offset++;
+ }
+ ByteWriter.WriteBytes(this.SMBData, offset, this.Data);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_READ_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/ReadRequest.cs b/SMBLibrary/SMB1/SMBCommands/ReadRequest.cs
new file mode 100644
index 0000000..1c18a52
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/ReadRequest.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_READ Request
+ ///
+ public class ReadRequest : SMBCommand
+ {
+ public const int ParametersLength = 10;
+ // Parameters:
+ public ushort FID;
+ public ushort CountOfBytesToRead;
+ public uint ReadOffsetInBytes;
+ public ushort EstimateOfRemainingBytesToBeRead;
+
+ public ReadRequest() : base()
+ {
+ }
+
+ public ReadRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ CountOfBytesToRead = LittleEndianConverter.ToUInt16(this.SMBParameters, 2);
+ ReadOffsetInBytes = LittleEndianConverter.ToUInt32(this.SMBParameters, 4);
+ CountOfBytesToRead = LittleEndianConverter.ToUInt16(this.SMBParameters, 8);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, FID);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, CountOfBytesToRead);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 4, ReadOffsetInBytes);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 8, CountOfBytesToRead);
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_READ;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/ReadResponse.cs b/SMBLibrary/SMB1/SMBCommands/ReadResponse.cs
new file mode 100644
index 0000000..eeb7511
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/ReadResponse.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_READ Response
+ ///
+ public class ReadResponse : SMBCommand
+ {
+ public const int ParametersLength = 10;
+ public const int SupportedBufferFormat = 0x01;
+ // Parameters:
+ public ushort CountOfBytesReturned;
+ public byte[] Reserved; // 8 reserved bytes
+ // Data:
+ public byte BufferFormat;
+ // ushort CountOfBytesRead;
+ public byte[] Bytes;
+
+ public ReadResponse() : base()
+ {
+ Reserved = new byte[8];
+ }
+
+ public ReadResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ CountOfBytesReturned = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ Reserved = ByteReader.ReadBytes(this.SMBParameters, 2, 8);
+
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ ushort CountOfBytesRead = LittleEndianConverter.ToUInt16(this.SMBData, 1);
+ Bytes = ByteReader.ReadBytes(this.SMBData, 3, CountOfBytesRead);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, CountOfBytesReturned);
+ ByteWriter.WriteBytes(this.SMBParameters, 2, Reserved, 8);
+
+ this.SMBData = new byte[3 + Bytes.Length];
+ ByteWriter.WriteByte(this.SMBData, 0, BufferFormat);
+ LittleEndianWriter.WriteUInt16(this.SMBData, 1, (ushort)Bytes.Length);
+ ByteWriter.WriteBytes(this.SMBData, 3, Bytes);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_READ;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/RenameRequest.cs b/SMBLibrary/SMB1/SMBCommands/RenameRequest.cs
new file mode 100644
index 0000000..aa61675
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/RenameRequest.cs
@@ -0,0 +1,93 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_RENAME Request
+ ///
+ public class RenameRequest : SMBCommand
+ {
+ public const int SupportedBufferFormat = 0x04;
+ public const int ParametersLength = 2;
+ // Parameters:
+ public FileAttributes SearchAttributes;
+ // Data:
+ public byte BufferFormat1;
+ public string OldFileName; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public byte BufferFormat2;
+ public string NewFileName; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public RenameRequest() : base()
+ {
+ BufferFormat1 = SupportedBufferFormat;
+ BufferFormat2 = SupportedBufferFormat;
+ }
+
+ public RenameRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ SearchAttributes = (FileAttributes)LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+
+ int dataOffset = 0;
+ BufferFormat1 = ByteReader.ReadByte(this.SMBData, ref dataOffset);
+ if (BufferFormat1 != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ OldFileName = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ BufferFormat2 = ByteReader.ReadByte(this.SMBData, ref dataOffset);
+ if (BufferFormat2 != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ if (isUnicode)
+ {
+ dataOffset++;
+ }
+ NewFileName = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, (ushort)SearchAttributes);
+
+ if (isUnicode)
+ {
+ int padding = 1;
+ this.SMBData = new byte[2 + OldFileName.Length * 2 + NewFileName.Length * 2 + 4 + padding];
+ }
+ else
+ {
+ this.SMBData = new byte[2 + OldFileName.Length + NewFileName.Length + 2];
+ }
+ int dataOffset = 0;
+ ByteWriter.WriteByte(this.SMBData, ref dataOffset, BufferFormat1);
+ SMBHelper.WriteSMBString(this.SMBData, ref dataOffset, isUnicode, OldFileName);
+ ByteWriter.WriteByte(this.SMBData, ref dataOffset, BufferFormat2);
+ if (isUnicode)
+ {
+ dataOffset++; // padding
+ }
+ SMBHelper.WriteSMBString(this.SMBData, ref dataOffset, isUnicode, NewFileName);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_RENAME;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/RenameResponse.cs b/SMBLibrary/SMB1/SMBCommands/RenameResponse.cs
new file mode 100644
index 0000000..f0383e6
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/RenameResponse.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_RENAME Response
+ ///
+ public class RenameResponse : SMBCommand
+ {
+ public RenameResponse() : base()
+ {
+ }
+
+ public RenameResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_RENAME;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SMBAndXCommand.cs b/SMBLibrary/SMB1/SMBCommands/SMBAndXCommand.cs
new file mode 100644
index 0000000..f258eef
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SMBAndXCommand.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class SMBAndXCommand : SMBCommand
+ {
+ public CommandName AndXCommand;
+ public byte AndXReserved;
+ public ushort AndXOffset;
+
+ public SMBAndXCommand() : base()
+ {
+ }
+
+ public SMBAndXCommand(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ AndXCommand = (CommandName)ByteReader.ReadByte(this.SMBParameters, 0);
+ AndXReserved = ByteReader.ReadByte(this.SMBParameters, 1);
+ AndXOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 2);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ ByteWriter.WriteByte(this.SMBParameters, 0, (byte)AndXCommand);
+ ByteWriter.WriteByte(this.SMBParameters, 1, AndXReserved);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, AndXOffset);
+ return base.GetBytes(isUnicode);
+ }
+
+ public static void WriteAndXOffset(byte[] buffer, int commandOffset, ushort AndXOffset)
+ {
+ // 3 preceding bytes: WordCount, AndXCommand and AndXReserved
+ LittleEndianWriter.WriteUInt16(buffer, commandOffset + 3, AndXOffset);
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SMBCommand.cs b/SMBLibrary/SMB1/SMBCommands/SMBCommand.cs
new file mode 100644
index 0000000..84ccfb1
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SMBCommand.cs
@@ -0,0 +1,268 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class SMBCommand
+ {
+ public byte[] SMBParameters; // SMB_Parameters
+ public byte[] SMBData; // SMB_Data
+
+ public SMBCommand()
+ {
+ SMBParameters = new byte[0];
+ SMBData = new byte[0];
+ }
+
+ public SMBCommand(byte[] buffer, int offset, bool isUnicode)
+ {
+ byte wordCount = ByteReader.ReadByte(buffer, ref offset);
+ SMBParameters = ByteReader.ReadBytes(buffer, ref offset, wordCount * 2);
+ ushort byteCount = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ SMBData = ByteReader.ReadBytes(buffer, ref offset, byteCount);
+ }
+
+ public abstract CommandName CommandName
+ {
+ get;
+ }
+
+ public virtual byte[] GetBytes(bool isUnicode)
+ {
+ if (SMBParameters.Length % 2 > 0)
+ {
+ throw new Exception("SMB_Parameters Length must be a multiple of 2");
+ }
+ int length = 1 + SMBParameters.Length + 2 + SMBData.Length;
+ byte[] buffer = new byte[length];
+ byte wordCount = (byte)(SMBParameters.Length / 2);
+ if (this is NTCreateAndXResponseExtended)
+ {
+ // [MS-SMB] Section 2.2.4.9.2 and Note <51>:
+ // Windows-based SMB servers send 50 (0x32) words in the extended response
+ // although they set the WordCount field to 0x2A
+ // wordCount SHOULD be 0x2A
+ wordCount = 0x2A;
+ }
+ ushort byteCount = (ushort)SMBData.Length;
+
+ int offset = 0;
+ ByteWriter.WriteByte(buffer, ref offset, wordCount);
+ ByteWriter.WriteBytes(buffer, ref offset, SMBParameters);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, byteCount);
+ ByteWriter.WriteBytes(buffer, ref offset, SMBData);
+
+ return buffer;
+ }
+
+ public static SMBCommand ReadCommand(byte[] buffer, int offset, CommandName commandName, SMBHeader header)
+ {
+ if ((header.Flags & HeaderFlags.Reply) > 0)
+ {
+ return ReadCommandResponse(buffer, offset, commandName, header.UnicodeFlag);
+ }
+ else
+ {
+ return ReadCommandRequest(buffer, offset, commandName, header.UnicodeFlag);
+ }
+ }
+
+ public static SMBCommand ReadCommandRequest(byte[] buffer, int offset, CommandName commandName, bool isUnicode)
+ {
+ switch (commandName)
+ {
+ case CommandName.SMB_COM_CREATE_DIRECTORY:
+ return new CreateDirectoryRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_DELETE_DIRECTORY:
+ return new DeleteDirectoryRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_CLOSE:
+ return new CloseRequest(buffer, offset);
+ case CommandName.SMB_COM_FLUSH:
+ return new FlushRequest(buffer, offset);
+ case CommandName.SMB_COM_DELETE:
+ return new DeleteRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_RENAME:
+ return new RenameRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_QUERY_INFORMATION:
+ return new QueryInformationRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_SET_INFORMATION:
+ return new SetInformationRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_READ:
+ return new ReadRequest(buffer, offset);
+ case CommandName.SMB_COM_WRITE:
+ return new WriteRequest(buffer, offset);
+ case CommandName.SMB_COM_CHECK_DIRECTORY:
+ return new CheckDirectoryRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_WRITE_RAW:
+ return new WriteRawRequest(buffer, offset);
+ case CommandName.SMB_COM_SET_INFORMATION2:
+ return new SetInformation2Request(buffer, offset);
+ case CommandName.SMB_COM_LOCKING_ANDX:
+ return new LockingAndXRequest(buffer, offset);
+ case CommandName.SMB_COM_TRANSACTION:
+ return new TransactionRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_TRANSACTION_SECONDARY:
+ return new TransactionSecondaryRequest(buffer, offset);
+ case CommandName.SMB_COM_ECHO:
+ return new EchoRequest(buffer, offset);
+ case CommandName.SMB_COM_OPEN_ANDX:
+ return new OpenAndXRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_READ_ANDX:
+ return new ReadAndXRequest(buffer, offset);
+ case CommandName.SMB_COM_WRITE_ANDX:
+ return new WriteAndXRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_TRANSACTION2:
+ return new Transaction2Request(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_TRANSACTION2_SECONDARY:
+ return new Transaction2SecondaryRequest(buffer, offset);
+ case CommandName.SMB_COM_FIND_CLOSE2:
+ return new FindClose2Request(buffer, offset);
+ case CommandName.SMB_COM_TREE_DISCONNECT:
+ return new TreeDisconnectRequest(buffer, offset);
+ case CommandName.SMB_COM_NEGOTIATE:
+ return new NegotiateRequest(buffer, offset);
+ case CommandName.SMB_COM_SESSION_SETUP_ANDX:
+ {
+ byte wordCount = ByteReader.ReadByte(buffer, offset);
+ if (wordCount * 2 == SessionSetupAndXRequest.ParametersLength)
+ {
+ return new SessionSetupAndXRequest(buffer, offset, isUnicode);
+ }
+ else if (wordCount * 2 == SessionSetupAndXRequestExtended.ParametersLength)
+ {
+ return new SessionSetupAndXRequestExtended(buffer, offset, isUnicode);
+ }
+ else
+ {
+ throw new InvalidRequestException();
+ }
+ }
+ case CommandName.SMB_COM_LOGOFF_ANDX:
+ return new LogoffAndXRequest(buffer, offset);
+ case CommandName.SMB_COM_TREE_CONNECT_ANDX:
+ return new TreeConnectAndXRequest(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_NT_TRANSACT:
+ return new NTTransactRequest(buffer, offset);
+ case CommandName.SMB_COM_NT_TRANSACT_SECONDARY:
+ return new NTTransactSecondaryRequest(buffer, offset);
+ case CommandName.SMB_COM_NT_CREATE_ANDX:
+ return new NTCreateAndXRequest(buffer, offset, isUnicode);
+ default:
+ throw new NotImplementedException("SMB Command 0x" + ((byte)commandName).ToString("X"));
+ }
+ }
+
+ public static SMBCommand ReadCommandResponse(byte[] buffer, int offset, CommandName commandName, bool isUnicode)
+ {
+ byte wordCount = ByteReader.ReadByte(buffer, offset);
+ switch (commandName)
+ {
+ case CommandName.SMB_COM_CREATE_DIRECTORY:
+ return new CreateDirectoryResponse(buffer, offset);
+ case CommandName.SMB_COM_DELETE_DIRECTORY:
+ return new DeleteDirectoryResponse(buffer, offset);
+ case CommandName.SMB_COM_CLOSE:
+ return new CloseResponse(buffer, offset);
+ case CommandName.SMB_COM_FLUSH:
+ return new FlushResponse(buffer, offset);
+ case CommandName.SMB_COM_DELETE:
+ return new DeleteResponse(buffer, offset);
+ case CommandName.SMB_COM_RENAME:
+ return new RenameResponse(buffer, offset);
+ case CommandName.SMB_COM_QUERY_INFORMATION:
+ return new QueryInformationResponse(buffer, offset);
+ case CommandName.SMB_COM_SET_INFORMATION:
+ return new SetInformationResponse(buffer, offset);
+ case CommandName.SMB_COM_READ:
+ return new ReadResponse(buffer, offset);
+ case CommandName.SMB_COM_WRITE:
+ return new WriteResponse(buffer, offset);
+ case CommandName.SMB_COM_CHECK_DIRECTORY:
+ return new CheckDirectoryResponse(buffer, offset);
+ case CommandName.SMB_COM_WRITE_RAW:
+ return new WriteRawInterimResponse(buffer, offset);
+ case CommandName.SMB_COM_WRITE_COMPLETE:
+ return new WriteRawFinalResponse(buffer, offset);
+ case CommandName.SMB_COM_SET_INFORMATION2:
+ return new SetInformation2Response(buffer, offset);
+ case CommandName.SMB_COM_LOCKING_ANDX:
+ return new LockingAndXResponse(buffer, offset);
+ case CommandName.SMB_COM_TRANSACTION:
+ return new TransactionResponse(buffer, offset);
+ case CommandName.SMB_COM_ECHO:
+ return new EchoResponse(buffer, offset);
+ case CommandName.SMB_COM_OPEN_ANDX:
+ {
+ if (wordCount * 2 == OpenAndXResponse.ParametersLength)
+ {
+ throw new NotImplementedException();
+ }
+ else if (wordCount * 2 == OpenAndXResponseExtended.ParametersLength)
+ {
+ throw new NotImplementedException();
+ }
+ else
+ {
+ throw new InvalidRequestException(); ;
+ }
+ }
+ case CommandName.SMB_COM_READ_ANDX:
+ return new ReadAndXResponse(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_WRITE_ANDX:
+ return new WriteAndXResponse(buffer, offset);
+ case CommandName.SMB_COM_TRANSACTION2:
+ return new Transaction2Response(buffer, offset);
+ case CommandName.SMB_COM_FIND_CLOSE2:
+ return new FindClose2Response(buffer, offset);
+ case CommandName.SMB_COM_TREE_DISCONNECT:
+ return new TreeDisconnectResponse(buffer, offset);
+ case CommandName.SMB_COM_NEGOTIATE:
+ {
+ if (wordCount * 2 == NegotiateResponseNTLM.ParametersLength)
+ {
+ throw new NotImplementedException();
+ //return new NegotiateResponseNTLM(header.UnicodeFlag);
+ }
+ else if (wordCount * 2 == NegotiateResponseNTLMExtended.ParametersLength)
+ {
+ throw new NotImplementedException();
+ //return new NegotiateResponseNTLMExtended(header.UnicodeFlag);
+ }
+ else
+ {
+ throw new InvalidRequestException();;
+ }
+ }
+ case CommandName.SMB_COM_SESSION_SETUP_ANDX:
+ return new SessionSetupAndXResponse(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_LOGOFF_ANDX:
+ return new LogoffAndXResponse(buffer, offset);
+ case CommandName.SMB_COM_TREE_CONNECT_ANDX:
+ return new TreeConnectAndXResponse(buffer, offset, isUnicode);
+ case CommandName.SMB_COM_NT_TRANSACT:
+ {
+ if (wordCount * 2 == NTTransactInterimResponse.ParametersLength)
+ {
+ return new NTTransactInterimResponse(buffer, offset);
+ }
+ else
+ {
+ return new NTTransactResponse(buffer, offset);
+ }
+ }
+ case CommandName.SMB_COM_NT_CREATE_ANDX:
+ return new NTCreateAndXResponse(buffer, offset);
+ default:
+ throw new NotImplementedException("SMB Command 0x" + ((byte)commandName).ToString("X"));
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXRequest.cs
new file mode 100644
index 0000000..30fa905
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXRequest.cs
@@ -0,0 +1,73 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_SESSION_SETUP_ANDX Request
+ ///
+ public class SessionSetupAndXRequest : SMBAndXCommand
+ {
+ public const int ParametersLength = 26;
+ // Parameters:
+ public ushort MaxBufferSize;
+ public ushort MaxMpxCount;
+ public ushort VcNumber;
+ public uint SessionKey;
+ //ushort OEMPasswordLength;
+ //ushort UnicodePasswordLength;
+ public uint Reserved;
+ public ServerCapabilities Capabilities;
+ // Data:
+ public byte[] OEMPassword;
+ public byte[] UnicodePassword;
+ // Padding
+ public string AccountName; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string PrimaryDomain; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string NativeOS; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string NativeLanMan; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public SessionSetupAndXRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ MaxBufferSize = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ MaxMpxCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
+ VcNumber = LittleEndianConverter.ToUInt16(this.SMBParameters, 8);
+ SessionKey = LittleEndianConverter.ToUInt32(this.SMBParameters, 10);
+ ushort OEMPasswordLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
+ ushort UnicodePasswordLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 16);
+ Reserved = LittleEndianConverter.ToUInt32(this.SMBParameters, 18);
+ Capabilities = (ServerCapabilities)LittleEndianConverter.ToUInt32(this.SMBParameters, 22);
+
+ OEMPassword = ByteReader.ReadBytes(this.SMBData, 0, OEMPasswordLength);
+ UnicodePassword = ByteReader.ReadBytes(this.SMBData, OEMPasswordLength, UnicodePasswordLength);
+
+ int dataOffset = OEMPasswordLength + UnicodePasswordLength;
+ if (isUnicode)
+ {
+ // wordCount is 1 byte
+ int padding = (1 + OEMPasswordLength + UnicodePasswordLength) % 2;
+ dataOffset += padding;
+ }
+ AccountName = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ PrimaryDomain = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ NativeOS = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ NativeLanMan = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SESSION_SETUP_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXRequestExtended.cs b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXRequestExtended.cs
new file mode 100644
index 0000000..400a276
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXRequestExtended.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_SESSION_SETUP_ANDX Extended Request
+ ///
+ public class SessionSetupAndXRequestExtended : SMBAndXCommand
+ {
+ public const int ParametersLength = 24;
+ // Parameters:
+ public ushort MaxBufferSize;
+ public ushort MaxMpxCount;
+ public ushort VcNumber;
+ public uint SessionKey;
+ //ushort SecurityBlobLength;
+ public uint Reserved;
+ public ServerCapabilities Capabilities;
+ // Data:
+ public byte[] SecurityBlob;
+ public string NativeOS; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string NativeLanMan; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public SessionSetupAndXRequestExtended(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ MaxBufferSize = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ MaxMpxCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
+ VcNumber = LittleEndianConverter.ToUInt16(this.SMBParameters, 8);
+ SessionKey = LittleEndianConverter.ToUInt32(this.SMBParameters, 10);
+ ushort securityBlobLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
+ Reserved = LittleEndianConverter.ToUInt32(this.SMBParameters, 16);
+ Capabilities = (ServerCapabilities)LittleEndianConverter.ToUInt32(this.SMBParameters, 20);
+
+ SecurityBlob = ByteReader.ReadBytes(this.SMBData, 0, securityBlobLength);
+
+ int dataOffset = SecurityBlob.Length;
+ if (isUnicode)
+ {
+ int padding = securityBlobLength % 2;
+ dataOffset += padding;
+ }
+ NativeOS = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ NativeLanMan = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SESSION_SETUP_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXResponse.cs
new file mode 100644
index 0000000..fccc681
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXResponse.cs
@@ -0,0 +1,76 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public class SessionSetupAndXResponse : SMBAndXCommand
+ {
+ public const int ParametersLength = 6;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public SessionSetupAction Action;
+ // Data:
+ public string NativeOS; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string NativeLanMan; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string PrimaryDomain; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public SessionSetupAndXResponse() : base()
+ {
+ }
+
+ public SessionSetupAndXResponse(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ Action = (SessionSetupAction)LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+
+ int dataOffset = 0;
+ if (isUnicode)
+ {
+ dataOffset++;
+ }
+ NativeOS = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ NativeLanMan = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ PrimaryDomain = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, (ushort)Action);
+
+ int offset = 0;
+ if (isUnicode)
+ {
+ int padding = 1; // 1 byte padding for 2 byte alignment
+ this.SMBData = new byte[padding + NativeOS.Length * 2 + NativeLanMan.Length * 2 + PrimaryDomain.Length * 2 + 6];
+ offset = padding;
+ }
+ else
+ {
+ this.SMBData = new byte[NativeOS.Length + NativeLanMan.Length + PrimaryDomain.Length + 3];
+ }
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeOS);
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeLanMan);
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, PrimaryDomain);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SESSION_SETUP_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXResponseExtended.cs b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXResponseExtended.cs
new file mode 100644
index 0000000..7ffd593
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SessionSetupAndXResponseExtended.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public class SessionSetupAndXResponseExtended : SMBAndXCommand
+ {
+ public const int ParametersLength = 8;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public SessionSetupAction Action;
+ //ushort SecurityBlobLength;
+ // Data:
+ public byte[] SecurityBlob;
+ public string NativeOS; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public string NativeLanMan; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public SessionSetupAndXResponseExtended() : base()
+ {
+ SecurityBlob = new byte[0];
+ NativeOS = String.Empty;
+ NativeLanMan = String.Empty;
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ ushort securityBlobLength = (ushort)SecurityBlob.Length;
+
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, (ushort)Action);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, securityBlobLength);
+
+ int padding = 0;
+ if (isUnicode)
+ {
+ // wordCount is 1 byte
+ padding = (1 + securityBlobLength) % 2;
+ this.SMBData = new byte[SecurityBlob.Length + padding + NativeOS.Length * 2 + NativeLanMan.Length * 2 + 4];
+ }
+ else
+ {
+ this.SMBData = new byte[SecurityBlob.Length + NativeOS.Length + NativeLanMan.Length + 2];
+ }
+ int offset = 0;
+ ByteWriter.WriteBytes(this.SMBData, ref offset, SecurityBlob);
+ offset += padding;
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeOS);
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeLanMan);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SESSION_SETUP_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SetInformation2Request.cs b/SMBLibrary/SMB1/SMBCommands/SetInformation2Request.cs
new file mode 100644
index 0000000..40fbea1
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SetInformation2Request.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_SET_INFORMATION2 Request
+ ///
+ public class SetInformation2Request : SMBCommand
+ {
+ public const int ParametersLength = 14;
+ // Parameters:
+ public ushort FID;
+ public DateTime? CreationDateTime; // A date and time value of 0 indicates to the server that the values MUST NOT be changed
+ public DateTime? LastAccessDateTime; // A date and time value of 0 indicates to the server that the values MUST NOT be changed
+ public DateTime? LastWriteDateTime; // A date and time value of 0 indicates to the server that the values MUST NOT be changed
+
+ public SetInformation2Request() : base()
+ {
+ }
+
+ public SetInformation2Request(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ CreationDateTime = ReadSetSMBDateTime(this.SMBParameters, 2);
+ LastAccessDateTime = ReadSetSMBDateTime(this.SMBParameters, 6);
+ LastWriteDateTime = ReadSetSMBDateTime(this.SMBParameters, 10);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, FID);
+ WriteSetSMBDateTime(this.SMBParameters, 2, CreationDateTime);
+ WriteSetSMBDateTime(this.SMBParameters, 6, LastAccessDateTime);
+ WriteSetSMBDateTime(this.SMBParameters, 10, LastWriteDateTime);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SET_INFORMATION2;
+ }
+ }
+
+ public static DateTime? ReadSetSMBDateTime(byte[] buffer, int offset)
+ {
+ uint value = LittleEndianConverter.ToUInt32(buffer, offset);
+ if (value > 0)
+ {
+ return SMBHelper.ReadSMBDateTime(buffer, offset);
+ }
+ return null;
+ }
+
+ public static void WriteSetSMBDateTime(byte[] buffer, int offset, DateTime? datetime)
+ {
+ if (datetime.HasValue)
+ {
+ SMBHelper.WriteSMBDateTime(buffer, offset, datetime.Value);
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SetInformation2Response.cs b/SMBLibrary/SMB1/SMBCommands/SetInformation2Response.cs
new file mode 100644
index 0000000..01192a0
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SetInformation2Response.cs
@@ -0,0 +1,40 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_SET_INFORMATION2 Response
+ ///
+ public class SetInformation2Response : SMBCommand
+ {
+ public SetInformation2Response() : base()
+ {
+ }
+
+ public SetInformation2Response(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SET_INFORMATION2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SetInformationRequest.cs b/SMBLibrary/SMB1/SMBCommands/SetInformationRequest.cs
new file mode 100644
index 0000000..74b0a9e
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SetInformationRequest.cs
@@ -0,0 +1,80 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_SET_INFORMATION Request
+ ///
+ public class SetInformationRequest : SMBCommand
+ {
+ public const int ParametersLength = 16;
+ public const int SupportedBufferFormat = 0x04;
+ // Parameters:
+ public FileAttributes FileAttributes;
+ public DateTime LastWriteTime;
+ public byte[] Reserved; // 10 bytes
+ // Data:
+ public byte BufferFormat;
+ public string FileName; // SMB_STRING
+
+ public SetInformationRequest() : base()
+ {
+ Reserved = new byte[10];
+ BufferFormat = SupportedBufferFormat;
+ }
+
+ public SetInformationRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ LastWriteTime = SMBHelper.ReadUTime(this.SMBParameters, 2);
+ Reserved = ByteReader.ReadBytes(this.SMBParameters, 6, 10);
+
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ FileName = SMBHelper.ReadSMBString(this.SMBData, 1, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, (ushort)FileAttributes);
+ SMBHelper.WriteUTime(this.SMBParameters, 2, LastWriteTime);
+ ByteWriter.WriteBytes(this.SMBParameters, 6, Reserved, 10);
+
+ int length = 1;
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ this.SMBData = new byte[length];
+ ByteWriter.WriteByte(this.SMBData, 0, BufferFormat);
+ SMBHelper.WriteSMBString(this.SMBData, 1, isUnicode, FileName);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SET_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/SetInformationResponse.cs b/SMBLibrary/SMB1/SMBCommands/SetInformationResponse.cs
new file mode 100644
index 0000000..a33bc81
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/SetInformationResponse.cs
@@ -0,0 +1,40 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_SET_INFORMATION Response
+ ///
+ public class SetInformationResponse : SMBCommand
+ {
+ public SetInformationResponse() : base()
+ {
+ }
+
+ public SetInformationResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_SET_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/Transaction2Request.cs b/SMBLibrary/SMB1/SMBCommands/Transaction2Request.cs
new file mode 100644
index 0000000..7389f99
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/Transaction2Request.cs
@@ -0,0 +1,37 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TRANSACTION2 Request
+ /// The SMB_COM_TRANSACTION2 request format is similar to that of the SMB_COM_TRANSACTION request except for the Name field.
+ /// The differences are in the subcommands supported, and in the purposes and usages of some of the fields.
+ ///
+ public class Transaction2Request : TransactionRequest
+ {
+ public Transaction2Request() : base()
+ {
+ }
+
+ public Transaction2Request(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TRANSACTION2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/Transaction2Response.cs b/SMBLibrary/SMB1/SMBCommands/Transaction2Response.cs
new file mode 100644
index 0000000..30d179d
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/Transaction2Response.cs
@@ -0,0 +1,36 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TRANSACTION2 Response
+ /// The SMB_COM_TRANSACTION2 response format is identical to that of the SMB_COM_TRANSACTION response.
+ ///
+ public class Transaction2Response : TransactionResponse
+ {
+ public Transaction2Response() : base()
+ {
+ }
+
+ public Transaction2Response(byte[] buffer, int offset) : base(buffer, offset)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TRANSACTION2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/Transaction2SecondaryRequest.cs b/SMBLibrary/SMB1/SMBCommands/Transaction2SecondaryRequest.cs
new file mode 100644
index 0000000..caeb30a
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/Transaction2SecondaryRequest.cs
@@ -0,0 +1,81 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TRANSACTION2_SECONDARY Request
+ ///
+ public class Transaction2SecondaryRequest : TransactionSecondaryRequest
+ {
+ public new const int SMBParametersLength = 18;
+ // Parameters:
+ public ushort FID;
+
+ public Transaction2SecondaryRequest() : base()
+ {
+ }
+
+ public Transaction2SecondaryRequest(byte[] buffer, int offset) : base(buffer, offset)
+ {
+ TotalParameterCount = LittleEndianConverter.ToUInt16(this.SMBData, 0);
+ TotalDataCount = LittleEndianConverter.ToUInt16(this.SMBData, 2);
+ ParameterCount = LittleEndianConverter.ToUInt16(this.SMBData, 4);
+ ParameterOffset = LittleEndianConverter.ToUInt16(this.SMBData, 6);
+ ParameterDisplacement = LittleEndianConverter.ToUInt16(this.SMBData, 8);
+ DataCount = LittleEndianConverter.ToUInt16(this.SMBData, 10);
+ DataOffset = LittleEndianConverter.ToUInt16(this.SMBData, 12);
+ DataDisplacement = LittleEndianConverter.ToUInt16(this.SMBData, 14);
+ FID = LittleEndianConverter.ToUInt16(this.SMBData, 16);
+
+ TransParameters = ByteReader.ReadBytes(buffer, ParameterOffset, ParameterCount);
+ TransData = ByteReader.ReadBytes(buffer, DataOffset, DataCount);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ ParameterCount = (ushort)TransParameters.Length;
+ DataCount = (ushort)TransData.Length;
+
+ ParameterOffset = (ushort)(SMBHeader.Length + SMBParametersLength);
+ int padding1 = (4 - (ParameterOffset % 4)) % 4;
+ ParameterOffset += (ushort)padding1;
+ DataOffset = (ushort)(ParameterOffset + ParameterCount);
+ int padding2 = (4 - (DataOffset % 4)) % 4;
+ DataOffset += (ushort)padding2;
+
+ this.SMBParameters = new byte[SMBParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, TotalParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, TotalDataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, ParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, ParameterOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 8, ParameterDisplacement);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 10, DataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 12, DataOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, DataDisplacement);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 16, FID);
+
+ this.SMBData = new byte[ParameterCount + DataCount + padding1 + padding2];
+ ByteWriter.WriteBytes(this.SMBData, padding1, TransParameters);
+ ByteWriter.WriteBytes(this.SMBData, padding1 + ParameterCount + padding2, TransData);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TRANSACTION2_SECONDARY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TransactionRequest.cs b/SMBLibrary/SMB1/SMBCommands/TransactionRequest.cs
new file mode 100644
index 0000000..0c2a806
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TransactionRequest.cs
@@ -0,0 +1,172 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TRANSACTION Request
+ ///
+ public class TransactionRequest : SMBCommand
+ {
+ public const int FixedSMBParametersLength = 28;
+ // Parameters:
+ public ushort TotalParameterCount;
+ public ushort TotalDataCount;
+ public ushort MaxParameterCount;
+ public ushort MaxDataCount;
+ public byte MaxSetupCount;
+ public byte Reserved1;
+ public TransactionFlags Flags;
+ public uint Timeout;
+ public ushort Reserved2;
+ //ushort ParameterCount;
+ //ushort ParameterOffset;
+ //ushort DataCount;
+ //ushort DataOffset;
+ //byte SetupCount; // In 2-byte words
+ public byte Reserved3;
+ public byte[] Setup;
+ // Data:
+ public string Name; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransParameters; // Trans_Parameters
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransData; // Trans_Data
+
+ public TransactionRequest() : base()
+ {
+ Name = String.Empty;
+ }
+
+ public TransactionRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ TotalParameterCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ TotalDataCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 2);
+ MaxParameterCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ MaxDataCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
+ MaxSetupCount = ByteReader.ReadByte(this.SMBParameters, 8);
+ Reserved1 = ByteReader.ReadByte(this.SMBParameters, 9);
+ Flags = (TransactionFlags)LittleEndianConverter.ToUInt16(this.SMBParameters, 10);
+ Timeout = LittleEndianConverter.ToUInt32(this.SMBParameters, 12);
+ Reserved2 = LittleEndianConverter.ToUInt16(this.SMBParameters, 16);
+ ushort ParameterCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 18);
+ ushort ParameterOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 20);
+ ushort DataCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 22);
+ ushort DataOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 24);
+ byte SetupCount = ByteReader.ReadByte(this.SMBParameters, 26);
+ Reserved3 = ByteReader.ReadByte(this.SMBParameters, 27);
+ Setup = ByteReader.ReadBytes(this.SMBParameters, 28, SetupCount * 2);
+
+ if (this.SMBData.Length > 0) // Workaround, Some SAMBA clients will set ByteCount to 0 (Popcorn Hour A-400)
+ {
+ int dataOffset = 0;
+ if (this is Transaction2Request)
+ {
+ Name = String.Empty;
+ dataOffset += 1;
+ }
+ else
+ {
+ if (isUnicode)
+ {
+ int namePadding = 1;
+ dataOffset += namePadding;
+ }
+ Name = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ }
+ }
+ TransParameters = ByteReader.ReadBytes(buffer, ParameterOffset, ParameterCount);
+ TransData = ByteReader.ReadBytes(buffer, DataOffset, DataCount);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte SetupCount = (byte)(Setup.Length / 2);
+ ushort ParameterCount = (ushort)TransParameters.Length;
+ ushort DataCount = (ushort)TransData.Length;
+
+ // WordCount + ByteCount are additional 3 bytes
+ ushort ParameterOffset = (ushort)(SMBHeader.Length + 3 + (FixedSMBParametersLength + Setup.Length));
+ if (this is Transaction2Request)
+ {
+ ParameterOffset += 1;
+ }
+ else
+ {
+ if (isUnicode)
+ {
+ ParameterOffset += (ushort)(Name.Length * 2 + 2);
+ }
+ else
+ {
+ ParameterOffset += (ushort)(Name.Length + 1);
+ }
+ }
+ int padding1 = (4 - (ParameterOffset % 4)) % 4;
+ ParameterOffset += (ushort)padding1;
+ ushort DataOffset = (ushort)(ParameterOffset + ParameterCount);
+ int padding2 = (4 - (DataOffset % 4)) % 4;
+ DataOffset += (ushort)padding2;
+
+ this.SMBParameters = new byte[FixedSMBParametersLength + Setup.Length];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, TotalParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, TotalDataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, MaxParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, MaxDataCount);
+ ByteWriter.WriteByte(this.SMBParameters, 8, MaxSetupCount);
+ ByteWriter.WriteByte(this.SMBParameters, 9, Reserved1);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 10, (ushort)Flags);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 12, Timeout);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 16, Reserved2);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 18, ParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 20, ParameterOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 22, DataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 24, DataOffset);
+ ByteWriter.WriteByte(this.SMBParameters, 26, SetupCount);
+ ByteWriter.WriteByte(this.SMBParameters, 27, Reserved3);
+ ByteWriter.WriteBytes(this.SMBParameters, 28, Setup);
+
+ int offset;
+ if (this is Transaction2Request)
+ {
+ offset = 0;
+ this.SMBData = new byte[1 + ParameterCount + DataCount + padding1 + padding2];
+ }
+ else
+ {
+ if (isUnicode)
+ {
+ int namePadding = 1;
+ offset = namePadding;
+ this.SMBData = new byte[namePadding + Name.Length * 2 + 2 + ParameterCount + DataCount + padding1 + padding2];
+ }
+ else
+ {
+ offset = 0;
+ this.SMBData = new byte[Name.Length + 1 + ParameterCount + DataCount + padding1 + padding2];
+ }
+ }
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, Name);
+ ByteWriter.WriteBytes(this.SMBData, offset + padding1, TransParameters);
+ ByteWriter.WriteBytes(this.SMBData, offset + padding1 + ParameterCount + padding2, TransData);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TRANSACTION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TransactionResponse.cs b/SMBLibrary/SMB1/SMBCommands/TransactionResponse.cs
new file mode 100644
index 0000000..6478221
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TransactionResponse.cs
@@ -0,0 +1,126 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TRANSACTION Response
+ ///
+ public class TransactionResponse : SMBCommand
+ {
+ public const int FixedSMBParametersLength = 20;
+ // Parameters:
+ public ushort TotalParameterCount;
+ public ushort TotalDataCount;
+ public ushort Reserved1;
+ //ushort ParameterCount;
+ //ushort ParameterOffset;
+ public ushort ParameterDisplacement;
+ //ushort DataCount;
+ //ushort DataOffset;
+ public ushort DataDisplacement;
+ //byte SetupCount; // In 2-byte words
+ public byte Reserved2;
+ public byte[] Setup;
+ // Data:
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransParameters; // Trans_Parameters
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransData; // Trans_Data
+
+ public TransactionResponse() : base()
+ {
+ Setup = new byte[0];
+ TransParameters = new byte[0];
+ TransData = new byte[0];
+ }
+
+ public TransactionResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ TotalParameterCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ TotalDataCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 2);
+ Reserved1 = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ ushort parameterCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
+ ushort parameterOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 8);
+ ParameterDisplacement = LittleEndianConverter.ToUInt16(this.SMBParameters, 10);
+ ushort dataCount = LittleEndianConverter.ToUInt16(this.SMBParameters, 12);
+ ushort dataOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
+ DataDisplacement = LittleEndianConverter.ToUInt16(this.SMBParameters, 16);
+ byte setupCount = ByteReader.ReadByte(this.SMBParameters, 18);
+ Reserved2 = ByteReader.ReadByte(this.SMBParameters, 19);
+ Setup = ByteReader.ReadBytes(this.SMBParameters, 20, setupCount * 2);
+
+ TransParameters = ByteReader.ReadBytes(buffer, parameterOffset, parameterCount);
+ TransData = ByteReader.ReadBytes(buffer, dataOffset, dataCount);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ if (TransData.Length > UInt16.MaxValue)
+ {
+ throw new ArgumentException("Invalid Trans_Data length");
+ }
+ byte setupCount = (byte)(Setup.Length / 2);
+ ushort parameterCount = (ushort)TransParameters.Length;
+ ushort dataCount = (ushort)TransData.Length;
+
+ // WordCount + ByteCount are additional 3 bytes
+ ushort parameterOffset = (ushort)(SMBHeader.Length + 3 + (FixedSMBParametersLength + Setup.Length));
+ int padding1 = (4 - (parameterOffset %4)) % 4;
+ parameterOffset += (ushort)padding1;
+ ushort dataOffset = (ushort)(parameterOffset + parameterCount);
+ int padding2 = (4 - (dataOffset % 4)) % 4;
+ dataOffset += (ushort)padding2;
+
+ this.SMBParameters = new byte[FixedSMBParametersLength + Setup.Length];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, TotalParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, TotalDataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, Reserved1);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, parameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 8, parameterOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 10, ParameterDisplacement);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 12, dataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, dataOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 16, DataDisplacement);
+ ByteWriter.WriteByte(this.SMBParameters, 18, setupCount);
+ ByteWriter.WriteByte(this.SMBParameters, 19, Reserved2);
+ ByteWriter.WriteBytes(this.SMBParameters, 20, Setup);
+
+ this.SMBData = new byte[parameterCount + dataCount + padding1 + padding2];
+ ByteWriter.WriteBytes(this.SMBData, padding1, TransParameters);
+ ByteWriter.WriteBytes(this.SMBData, padding1 + parameterCount + padding2, TransData);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TRANSACTION;
+ }
+ }
+
+ public static int CalculateMessageSize(int setupLength, int trans2ParametersLength, int trans2DataLength)
+ {
+ int parameterOffset = SMBHeader.Length + 3 + (FixedSMBParametersLength + setupLength);
+ int padding1 = (4 - (parameterOffset %4)) % 4;
+ parameterOffset += padding1;
+ int dataOffset = (parameterOffset + trans2ParametersLength);
+ int padding2 = (4 - (dataOffset % 4)) % 4;
+
+ int messageParametersLength = FixedSMBParametersLength + setupLength;
+ int messageDataLength = trans2ParametersLength + trans2DataLength + padding1 + padding2;
+ // WordCount + ByteCount are additional 3 bytes
+ return SMBHeader.Length + messageParametersLength + messageDataLength + 3;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TransactionSecondaryRequest.cs b/SMBLibrary/SMB1/SMBCommands/TransactionSecondaryRequest.cs
new file mode 100644
index 0000000..c75da71
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TransactionSecondaryRequest.cs
@@ -0,0 +1,92 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TRANSACTION_SECONDARY Request
+ ///
+ public class TransactionSecondaryRequest : SMBCommand
+ {
+ public const int SMBParametersLength = 16;
+ // Parameters:
+ public ushort TotalParameterCount;
+ public ushort TotalDataCount;
+ protected ushort ParameterCount;
+ protected ushort ParameterOffset;
+ public ushort ParameterDisplacement;
+ protected ushort DataCount;
+ protected ushort DataOffset;
+ public ushort DataDisplacement;
+ // Data:
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransParameters; // Trans_Parameters
+ // Padding (alignment to 4 byte boundary)
+ public byte[] TransData; // Trans_Data
+
+ public TransactionSecondaryRequest() : base()
+ {
+ }
+
+ public TransactionSecondaryRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ TotalParameterCount = LittleEndianConverter.ToUInt16(this.SMBData, 0);
+ TotalDataCount = LittleEndianConverter.ToUInt16(this.SMBData, 2);
+ ParameterCount = LittleEndianConverter.ToUInt16(this.SMBData, 4);
+ ParameterOffset = LittleEndianConverter.ToUInt16(this.SMBData, 6);
+ ParameterDisplacement = LittleEndianConverter.ToUInt16(this.SMBData, 8);
+ DataCount = LittleEndianConverter.ToUInt16(this.SMBData, 10);
+ DataOffset = LittleEndianConverter.ToUInt16(this.SMBData, 12);
+ DataDisplacement = LittleEndianConverter.ToUInt16(this.SMBData, 14);
+
+ TransParameters = ByteReader.ReadBytes(buffer, ParameterOffset, ParameterCount);
+ TransData = ByteReader.ReadBytes(buffer, DataOffset, DataCount);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ ParameterCount = (ushort)TransParameters.Length;
+ DataCount = (ushort)TransData.Length;
+
+ // WordCount + ByteCount are additional 3 bytes
+ ParameterOffset = (ushort)(SMBHeader.Length + 3 + SMBParametersLength);
+ int padding1 = (4 - (ParameterOffset % 4)) % 4;
+ ParameterOffset += (ushort)padding1;
+ DataOffset = (ushort)(ParameterOffset + ParameterCount);
+ int padding2 = (4 - (DataOffset % 4)) % 4;
+ DataOffset += (ushort)padding2;
+
+ this.SMBParameters = new byte[SMBParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, TotalParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, TotalDataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, ParameterCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, ParameterOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 8, ParameterDisplacement);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 10, DataCount);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 12, DataOffset);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, DataDisplacement);
+
+ this.SMBData = new byte[ParameterCount + DataCount + padding1 + padding2];
+ ByteWriter.WriteBytes(this.SMBData, padding1, TransParameters);
+ ByteWriter.WriteBytes(this.SMBData, padding1 + ParameterCount + padding2, TransData);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TRANSACTION_SECONDARY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXRequest.cs
new file mode 100644
index 0000000..c22b7a4
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXRequest.cs
@@ -0,0 +1,92 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TREE_CONNECT_ANDX Request
+ ///
+ public class TreeConnectAndXRequest : SMBAndXCommand
+ {
+ public const int ParametersLength = 8;
+ // Parameters:
+ public TreeConnectFlags Flags;
+ //ushort PasswordLength;
+ // Data:
+ public byte[] Password;
+ // Padding
+ public string Path; // SMB_STRING (If Unicode, this field MUST be aligned to start on a 2-byte boundary from the start of the SMB header)
+ public ServiceName Service; // OEM string
+
+ public TreeConnectAndXRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ int parametersOffset = 4;
+ Flags = (TreeConnectFlags)LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ ushort passwordLength = LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+
+ int dataOffset = 0;
+ Password = ByteReader.ReadBytes(this.SMBData, ref dataOffset, passwordLength);
+ if (isUnicode)
+ {
+ // wordCount is 1 byte
+ int padding = (1 + passwordLength) % 2;
+ dataOffset += padding;
+ }
+ Path = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+ // Should be read as OEM string but it doesn't really matter
+ string serviceString = ByteReader.ReadNullTerminatedAnsiString(this.SMBData, ref dataOffset);
+ Service = TreeConnectHelper.GetServiceName(serviceString);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ ushort passwordLength = (ushort)Password.Length;
+
+ this.SMBParameters = new byte[ParametersLength];
+ int parametersOffset = 4;
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)Flags);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, passwordLength);
+
+ string serviceString = TreeConnectHelper.GetServiceString(Service);
+ int dataLength = Password.Length + serviceString.Length;
+ if (isUnicode)
+ {
+ int padding = (1 + passwordLength) % 2;
+ dataLength += Path.Length * 2 + 2 + padding;
+ }
+ else
+ {
+ dataLength += Path.Length + 1;
+ }
+ this.SMBData = new byte[dataLength];
+ int dataOffset = 0;
+ ByteWriter.WriteBytes(this.SMBData, ref dataOffset, Password);
+ if (isUnicode)
+ {
+ // wordCount is 1 byte
+ int padding = (1 + passwordLength) % 2;
+ dataOffset += padding;
+ }
+ SMBHelper.WriteSMBString(this.SMBData, ref dataOffset, isUnicode, Path);
+ ByteWriter.WriteNullTerminatedAnsiString(this.SMBData, ref dataOffset, serviceString);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TREE_CONNECT_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXResponse.cs
new file mode 100644
index 0000000..3331151
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXResponse.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TREE_CONNECT_ANDX Response
+ ///
+ public class TreeConnectAndXResponse : SMBAndXCommand
+ {
+ public const int ParametersLength = 6;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public OptionalSupportFlags OptionalSupport;
+ // Data:
+ public ServiceName Service; // OEM String
+ public string NativeFileSystem; // SMB_STRING
+
+ public TreeConnectAndXResponse() : base()
+ {
+ }
+
+ public TreeConnectAndXResponse(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ OptionalSupport = (OptionalSupportFlags)LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+
+ int dataOffset = 0;
+ string serviceString = ByteReader.ReadNullTerminatedAnsiString(this.SMBData, ref dataOffset);
+ NativeFileSystem = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+
+ Service = TreeConnectHelper.GetServiceName(serviceString);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, (ushort)OptionalSupport);
+
+ // Should be written as OEM string but it doesn't really matter
+ string serviceString = TreeConnectHelper.GetServiceString(Service);
+ if (isUnicode)
+ {
+ this.SMBData = new byte[serviceString.Length + NativeFileSystem.Length * 2 + 3];
+ }
+ else
+ {
+ this.SMBData = new byte[serviceString.Length + NativeFileSystem.Length + 2];
+ }
+
+ int offset = 0;
+ ByteWriter.WriteNullTerminatedAnsiString(this.SMBData, ref offset, serviceString);
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeFileSystem);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TREE_CONNECT_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXResponseExtended.cs b/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXResponseExtended.cs
new file mode 100644
index 0000000..20b342c
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TreeConnectAndXResponseExtended.cs
@@ -0,0 +1,83 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TREE_CONNECT_ANDX Extended Response
+ ///
+ public class TreeConnectAndXResponseExtended : SMBAndXCommand
+ {
+ public const int ParametersLength = 14;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public OptionalSupportFlags OptionalSupport;
+ public AccessMask MaximalShareAccessRights;
+ public AccessMask GuestMaximalShareAccessRights;
+ // Data:
+ public ServiceName Service; // OEM String
+ public string NativeFileSystem; // SMB_STRING
+
+ public TreeConnectAndXResponseExtended() : base()
+ {
+ }
+
+ public TreeConnectAndXResponseExtended(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ int parametersOffset = 4;
+ OptionalSupport = (OptionalSupportFlags)LittleEndianReader.ReadUInt16(this.SMBParameters, ref parametersOffset);
+ MaximalShareAccessRights = new AccessMask(this.SMBParameters, ref parametersOffset);
+ GuestMaximalShareAccessRights = new AccessMask(this.SMBParameters, ref parametersOffset);
+
+ int dataOffset = 0;
+ string serviceString = ByteReader.ReadNullTerminatedAnsiString(this.SMBData, ref dataOffset);
+ NativeFileSystem = SMBHelper.ReadSMBString(this.SMBData, ref dataOffset, isUnicode);
+
+ Service = TreeConnectHelper.GetServiceName(serviceString);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ int parametersOffset = 4;
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, ref parametersOffset, (ushort)OptionalSupport);
+ MaximalShareAccessRights.WriteBytes(this.SMBParameters, ref parametersOffset);
+ GuestMaximalShareAccessRights.WriteBytes(this.SMBParameters, ref parametersOffset);
+
+ // Should be written as OEM string but it doesn't really matter
+ string serviceString = TreeConnectHelper.GetServiceString(Service);
+ if (isUnicode)
+ {
+ this.SMBData = new byte[serviceString.Length + NativeFileSystem.Length * 2 + 3];
+ }
+ else
+ {
+ this.SMBData = new byte[serviceString.Length + NativeFileSystem.Length + 2];
+ }
+
+ int offset = 0;
+ ByteWriter.WriteNullTerminatedAnsiString(this.SMBData, ref offset, serviceString);
+ SMBHelper.WriteSMBString(this.SMBData, ref offset, isUnicode, NativeFileSystem);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TREE_CONNECT_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TreeDisconnectRequest.cs b/SMBLibrary/SMB1/SMBCommands/TreeDisconnectRequest.cs
new file mode 100644
index 0000000..f20ece8
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TreeDisconnectRequest.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TREE_DISCONNECT Request
+ ///
+ public class TreeDisconnectRequest : SMBCommand
+ {
+ public TreeDisconnectRequest() : base()
+ {
+ }
+
+ public TreeDisconnectRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TREE_DISCONNECT;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/TreeDisconnectResponse.cs b/SMBLibrary/SMB1/SMBCommands/TreeDisconnectResponse.cs
new file mode 100644
index 0000000..af6e4ac
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/TreeDisconnectResponse.cs
@@ -0,0 +1,35 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_TREE_DISCONNECT Response
+ ///
+ public class TreeDisconnectResponse : SMBCommand
+ {
+ public TreeDisconnectResponse() : base()
+ {
+ }
+
+ public TreeDisconnectResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_TREE_DISCONNECT;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/WriteAndXRequest.cs b/SMBLibrary/SMB1/SMBCommands/WriteAndXRequest.cs
new file mode 100644
index 0000000..77d62ad
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/WriteAndXRequest.cs
@@ -0,0 +1,118 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_WRITE_ANDX Request
+ /// SMB 1.0: The 2 reserved bytes at offset 18 become DataLengthHigh (used when the CAP_LARGE_WRITEX capability has been negotiated)
+ ///
+ public class WriteAndXRequest : SMBAndXCommand
+ {
+ public const int ParametersFixedLength = 24;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public ushort FID;
+ public ulong Offset; // 4 bytes + 4 optional 'OffsetHigh' bytes
+ public uint Timeout;
+ public WriteMode WriteMode;
+ public ushort Remaining;
+ //uint DataLength; // 2 bytes + 2 'DataLengthHigh' bytes
+ //ushort DataOffset;
+ // ulong OffsetHigh; // Optional
+ // Data:
+ // Optional 1 byte padding
+ public byte[] Data;
+
+ public WriteAndXRequest() : base()
+ {}
+
+ public WriteAndXRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ Offset = LittleEndianConverter.ToUInt32(this.SMBParameters, 6);
+ Timeout = LittleEndianConverter.ToUInt32(this.SMBParameters, 10);
+ WriteMode = (WriteMode)LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
+ Remaining = LittleEndianConverter.ToUInt16(this.SMBParameters, 16);
+ ushort dataLengthHigh = LittleEndianConverter.ToUInt16(this.SMBParameters, 18);
+ uint DataLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 20);
+ ushort DataOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 22);
+ if (SMBParameters.Length == ParametersFixedLength + 4)
+ {
+ uint offsetHigh = LittleEndianConverter.ToUInt32(this.SMBParameters, 24);
+ Offset |= ((ulong)offsetHigh << 32);
+ }
+
+ DataLength |= (uint)(dataLengthHigh << 16);
+
+ Data = ByteReader.ReadBytes(buffer, (int)DataOffset, (int)DataLength);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ uint DataLength = (uint)Data.Length;
+ // WordCount + ByteCount are additional 3 bytes
+ ushort DataOffset = SMBHeader.Length + 3 + ParametersFixedLength;
+ if (isUnicode)
+ {
+ DataOffset++;
+ }
+ ushort dataLengthHigh = (ushort)(DataLength >> 16);
+
+ int parametersLength = ParametersFixedLength;
+ if (Offset > UInt32.MaxValue)
+ {
+ parametersLength += 4;
+ DataOffset += 4;
+ }
+
+ this.SMBParameters = new byte[parametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, FID);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 6, (uint)(Offset & 0xFFFFFFFF));
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 10, Timeout);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, (ushort)WriteMode);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 16, Remaining);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 18, dataLengthHigh);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 20, (ushort)(DataLength & 0xFFFF));
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 22, DataOffset);
+ if (Offset > UInt32.MaxValue)
+ {
+ uint offsetHigh = (uint)(Offset >> 32);
+ LittleEndianWriter.WriteUInt32(this.SMBParameters, 24, offsetHigh);
+ }
+
+ int smbDataLength = Data.Length;
+ if (isUnicode)
+ {
+ smbDataLength++;
+ }
+ this.SMBData = new byte[smbDataLength];
+ int offset = 0;
+ if (isUnicode)
+ {
+ offset++;
+ }
+ ByteWriter.WriteBytes(this.SMBData, ref offset, this.Data);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_WRITE_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/WriteAndXResponse.cs b/SMBLibrary/SMB1/SMBCommands/WriteAndXResponse.cs
new file mode 100644
index 0000000..2895e9f
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/WriteAndXResponse.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_WRITE_ANDX Response
+ /// SMB 1.0: The 2 reserved bytes at offset 8 become CountHigh (used when the CAP_LARGE_WRITEX capability has been negotiated)
+ ///
+ public class WriteAndXResponse : SMBAndXCommand
+ {
+ public const int ParametersLength = 12;
+ // Parameters:
+ //CommandName AndXCommand;
+ //byte AndXReserved;
+ //ushort AndXOffset;
+ public uint Count; // The number of bytes written to the file, 2 bytes + 2 'CountHigh' bytes
+ public ushort Available;
+ public ushort Reserved;
+
+ public WriteAndXResponse() : base()
+ {}
+
+ public WriteAndXResponse(byte[] buffer, int offset): base(buffer, offset, false)
+ {
+ Count = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ Available = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
+ ushort countHigh = LittleEndianConverter.ToUInt16(this.SMBParameters, 8);
+ Reserved = LittleEndianConverter.ToUInt16(this.SMBParameters, 10);
+
+ Count |= (uint)(countHigh << 16);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ ushort counthHigh = (ushort)(Count >> 16);
+
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, (ushort)(Count & 0xFFFF));
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, Available);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 8, counthHigh);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 10, Reserved);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_WRITE_ANDX;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/WriteRawFinalResponse.cs b/SMBLibrary/SMB1/SMBCommands/WriteRawFinalResponse.cs
new file mode 100644
index 0000000..73f5cf5
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/WriteRawFinalResponse.cs
@@ -0,0 +1,47 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_WRITE_RAW Final Response
+ ///
+ public class WriteRawFinalResponse : SMBCommand
+ {
+ public ushort ParametersLength = 2;
+ // Parameters;
+ public ushort Count;
+
+ public WriteRawFinalResponse() : base()
+ {}
+
+ public WriteRawFinalResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ Count = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, Count);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_WRITE_COMPLETE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/WriteRawInterimResponse.cs b/SMBLibrary/SMB1/SMBCommands/WriteRawInterimResponse.cs
new file mode 100644
index 0000000..bf4125f
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/WriteRawInterimResponse.cs
@@ -0,0 +1,47 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_WRITE_RAW Interim Response
+ ///
+ public class WriteRawInterimResponse : SMBCommand
+ {
+ public ushort ParametersLength = 2;
+ // Parameters;
+ public ushort Available;
+
+ public WriteRawInterimResponse() : base()
+ {}
+
+ public WriteRawInterimResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ Available = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, Available);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_WRITE_RAW;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/WriteRawRequest.cs b/SMBLibrary/SMB1/SMBCommands/WriteRawRequest.cs
new file mode 100644
index 0000000..d010fca
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/WriteRawRequest.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_WRITE_RAW Request
+ ///
+ public class WriteRawRequest : SMBCommand
+ {
+ public const int ParametersFixedLength = 24; // + 4 optional bytes
+ // Parameters:
+ public ushort FID;
+ public ushort CountOfBytes;
+ public ushort Reserved1;
+ public uint Offset;
+ public uint Timeout;
+ public WriteMode WriteMode;
+ public uint Reserved2;
+ //ushort DataLength;
+ //ushort DataOffset;
+ public uint OffsetHigh; // Optional
+ // Data:
+ public byte[] Data;
+
+ public WriteRawRequest() : base()
+ {
+ Data = new byte[0];
+ }
+
+ public WriteRawRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ CountOfBytes = LittleEndianConverter.ToUInt16(this.SMBParameters, 2);
+ Reserved1 = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ Offset = LittleEndianConverter.ToUInt32(this.SMBParameters, 6);
+ Timeout = LittleEndianConverter.ToUInt32(this.SMBParameters, 10);
+ WriteMode = (WriteMode)LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
+ Reserved2 = LittleEndianConverter.ToUInt32(this.SMBParameters, 16);
+ ushort dataLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 20);
+ ushort dataOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 22);
+ if (SMBParameters.Length == ParametersFixedLength + 4)
+ {
+ OffsetHigh = LittleEndianConverter.ToUInt32(this.SMBParameters, 24);
+ }
+
+ Data = ByteReader.ReadBytes(buffer, dataOffset, dataLength);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_WRITE_RAW;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/WriteRequest.cs b/SMBLibrary/SMB1/SMBCommands/WriteRequest.cs
new file mode 100644
index 0000000..12cdf0b
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/WriteRequest.cs
@@ -0,0 +1,83 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_WRITE Request.
+ /// This command is obsolete.
+ /// Windows NT4 SP6 will send this command with empty data for some reason.
+ ///
+ public class WriteRequest : SMBCommand
+ {
+ public const int ParametersLength = 8;
+ public const int SupportedBufferFormat = 0x01;
+ // Parameters:
+ public ushort FID;
+ public ushort CountOfBytesToWrite;
+ public ushort WriteOffsetInBytes;
+ public ushort EstimateOfRemainingBytesToBeWritten;
+ // Data:
+ public byte BufferFormat;
+ // ushort DataLength;
+ public byte[] Data;
+
+ public WriteRequest() : base()
+ {
+ BufferFormat = SupportedBufferFormat;
+ Data = new byte[0];
+ }
+
+ public WriteRequest(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ CountOfBytesToWrite = LittleEndianConverter.ToUInt16(this.SMBParameters, 2);
+ WriteOffsetInBytes = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
+ EstimateOfRemainingBytesToBeWritten = LittleEndianConverter.ToUInt16(this.SMBParameters, 6);
+
+ BufferFormat = ByteReader.ReadByte(this.SMBData, 0);
+ if (BufferFormat != SupportedBufferFormat)
+ {
+ throw new InvalidRequestException("Unsupported Buffer Format");
+ }
+ ushort dataLength = LittleEndianConverter.ToUInt16(this.SMBData, 1);
+ Data = ByteReader.ReadBytes(this.SMBData, 3, dataLength);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ if (Data.Length > UInt16.MaxValue)
+ {
+ throw new ArgumentException("Invalid Data length");
+ }
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, FID);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 2, CountOfBytesToWrite);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, WriteOffsetInBytes);
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 6, EstimateOfRemainingBytesToBeWritten);
+
+ this.SMBData = new byte[3 + Data.Length];
+ ByteWriter.WriteByte(this.SMBData, 0, BufferFormat);
+ LittleEndianWriter.WriteUInt16(this.SMBData, 1, (ushort)Data.Length);
+ ByteWriter.WriteBytes(this.SMBData, 3, Data);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_WRITE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBCommands/WriteResponse.cs b/SMBLibrary/SMB1/SMBCommands/WriteResponse.cs
new file mode 100644
index 0000000..f475942
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBCommands/WriteResponse.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_COM_WRITE Response.
+ /// This command is obsolete.
+ /// Windows NT4 SP6 will send this command with empty data for some reason.
+ ///
+ public class WriteResponse : SMBCommand
+ {
+ public const int ParametersLength = 2;
+ // Parameters:
+ public ushort CountOfBytesWritten;
+
+ public WriteResponse() : base()
+ {
+ }
+
+ public WriteResponse(byte[] buffer, int offset) : base(buffer, offset, false)
+ {
+ CountOfBytesWritten = LittleEndianConverter.ToUInt16(this.SMBParameters, 0);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ this.SMBParameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(this.SMBParameters, 0, CountOfBytesWritten);
+
+ return base.GetBytes(isUnicode);
+ }
+
+ public override CommandName CommandName
+ {
+ get
+ {
+ return CommandName.SMB_COM_WRITE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBHeader.cs b/SMBLibrary/SMB1/SMBHeader.cs
new file mode 100644
index 0000000..361c537
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBHeader.cs
@@ -0,0 +1,119 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public class SMBHeader
+ {
+ public const int Length = 32;
+ public static readonly byte[] ProtocolSignature = new byte[] { 0xFF, 0x53, 0x4D, 0x42 };
+
+ public byte[] Protocol; // byte[4], 0xFF followed by "SMB"
+ public CommandName Command;
+ public NTStatus Status;
+ public HeaderFlags Flags;
+ public HeaderFlags2 Flags2;
+ //ushort PIDHigh
+ public ulong SecurityFeatures;
+ // public ushort Reserved;
+ public ushort TID; // Tree ID
+ //ushort PIDLow;
+ public ushort UID; // User ID
+ public ushort MID; // Multiplex ID
+
+ public uint PID; // Process ID
+
+ public SMBHeader()
+ {
+ Protocol = ProtocolSignature;
+ }
+
+ public SMBHeader(byte[] buffer)
+ {
+ Protocol = ByteReader.ReadBytes(buffer, 0, 4);
+ Command = (CommandName)ByteReader.ReadByte(buffer, 4);
+ Status = (NTStatus)LittleEndianConverter.ToUInt32(buffer, 5);
+ Flags = (HeaderFlags)ByteReader.ReadByte(buffer, 9);
+ Flags2 = (HeaderFlags2)LittleEndianConverter.ToUInt16(buffer, 10);
+ ushort PIDHigh = LittleEndianConverter.ToUInt16(buffer, 12);
+ SecurityFeatures = LittleEndianConverter.ToUInt64(buffer, 14);
+ TID = LittleEndianConverter.ToUInt16(buffer, 24);
+ ushort PIDLow = LittleEndianConverter.ToUInt16(buffer, 26);
+ UID = LittleEndianConverter.ToUInt16(buffer, 28);
+ MID = LittleEndianConverter.ToUInt16(buffer, 30);
+
+ PID = (uint)((PIDHigh << 16) | PIDLow);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ ushort PIDHigh = (ushort)(PID >> 16);
+ ushort PIDLow = (ushort)(PID & 0xFFFF);
+
+ ByteWriter.WriteBytes(buffer, offset + 0, Protocol);
+ ByteWriter.WriteByte(buffer, offset + 4, (byte)Command);
+ LittleEndianWriter.WriteUInt32(buffer, offset + 5, (uint)Status);
+ ByteWriter.WriteByte(buffer, offset + 9, (byte)Flags);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 10, (ushort)Flags2);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 12, PIDHigh);
+ LittleEndianWriter.WriteUInt64(buffer, offset + 14, SecurityFeatures);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 24, TID);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 26, PIDLow);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 28, UID);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 30, MID);
+ }
+
+ public byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ WriteBytes(buffer, 0);
+ return buffer;
+ }
+
+ public bool ReplyFlag
+ {
+ get
+ {
+ return (Flags & HeaderFlags.Reply) > 0;
+ }
+ }
+
+ ///
+ /// SMB_FLAGS2_EXTENDED_SECURITY
+ ///
+ public bool ExtendedSecurityFlag
+ {
+ get
+ {
+ return (this.Flags2 & HeaderFlags2.ExtendedSecurity) > 0;
+ }
+ set
+ {
+ if (value)
+ {
+ this.Flags2 |= HeaderFlags2.ExtendedSecurity;
+ }
+ else
+ {
+ this.Flags2 &= ~HeaderFlags2.ExtendedSecurity;
+ }
+ }
+ }
+
+ public bool UnicodeFlag
+ {
+ get
+ {
+ return (Flags2 & HeaderFlags2.Unicode) > 0;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBHelper.cs b/SMBLibrary/SMB1/SMBHelper.cs
new file mode 100644
index 0000000..daed92b
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBHelper.cs
@@ -0,0 +1,228 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary
+{
+ public class SMBHelper
+ {
+ public static readonly DateTime UTimeNotSpecified = new DateTime(1970, 1, 1);
+ public static readonly DateTime FileTimeNotSpecified = new DateTime(1601, 1, 1);
+
+ public static DateTime ReadFileTime(byte[] buffer, int offset)
+ {
+ long span = LittleEndianConverter.ToInt64(buffer, offset);
+ if (span >= 0)
+ {
+ return DateTime.FromFileTimeUtc(span);
+ }
+ else
+ {
+ // Tick = 100ns
+ return DateTime.Now.Subtract(TimeSpan.FromTicks(span));
+ }
+ }
+
+ public static DateTime ReadFileTime(byte[] buffer, ref int offset)
+ {
+ offset += 8;
+ return ReadFileTime(buffer, offset - 8);
+ }
+
+ public static DateTime ReadSetFileTime(byte[] buffer, int offset)
+ {
+ long span = LittleEndianConverter.ToInt64(buffer, offset);
+ if (span >= 0)
+ {
+ return DateTime.FromFileTimeUtc(span);
+ }
+ else
+ {
+ return FileTimeNotSpecified;
+ }
+ }
+
+ public static void WriteFileTime(byte[] buffer, int offset, DateTime time)
+ {
+ long span = time.ToFileTimeUtc();
+ LittleEndianWriter.WriteInt64(buffer, offset, span);
+ }
+
+ public static void WriteFileTime(byte[] buffer, ref int offset, DateTime time)
+ {
+ WriteFileTime(buffer, offset, time);
+ offset += 8;
+ }
+
+ // UTime - The number of seconds since Jan 1, 1970, 00:00:00
+ public static DateTime ReadUTime(byte[] buffer, int offset)
+ {
+ uint span = LittleEndianConverter.ToUInt32(buffer, offset);
+ DateTime result = new DateTime(1970, 1, 1);
+ return result.AddSeconds(span);
+ }
+
+ public static DateTime ReadUTime(byte[] buffer, ref int offset)
+ {
+ offset += 4;
+ return ReadUTime(buffer, offset - 4);
+ }
+
+ // UTime - The number of seconds since Jan 1, 1970, 00:00:00
+ public static void WriteUTime(byte[] buffer, int offset, DateTime time)
+ {
+ TimeSpan timespan = time - new DateTime(1970, 1, 1);
+ uint span = (uint)timespan.TotalSeconds;
+ LittleEndianWriter.WriteUInt32(buffer, offset, span);
+ }
+
+ public static void WriteUTime(byte[] buffer, ref int offset, DateTime time)
+ {
+ WriteUTime(buffer, offset, time);
+ offset += 4;
+ }
+
+ ///
+ /// SMB_DATE
+ ///
+ public static DateTime ReadSMBDate(byte[] buffer, int offset)
+ {
+ ushort value = LittleEndianConverter.ToUInt16(buffer, offset);
+ int year = ((value & 0xFE00) >> 9) + 1980;
+ int month = ((value & 0x01E0) >> 5);
+ int day = (value & 0x001F);
+ return new DateTime(year, month, day);
+ }
+
+ public static void WriteSMBDate(byte[] buffer, int offset, DateTime date)
+ {
+ int year = date.Year - 1980;
+ int month = date.Month;
+ int day = date.Day;
+ ushort value = (ushort)(year << 9 | month << 5 | day);
+ LittleEndianWriter.WriteUInt16(buffer, offset, value);
+ }
+
+ ///
+ /// SMB_DATE
+ ///
+ public static TimeSpan ReadSMBTime(byte[] buffer, int offset)
+ {
+ ushort value = LittleEndianConverter.ToUInt16(buffer, offset);
+ int hours = ((value & 0xF800) >> 11);
+ int minutes = ((value & 0x07E0) >> 5);
+ int seconds = (value & 0x001F);
+ return new TimeSpan(hours, minutes, seconds);
+ }
+
+ public static void WriteSMBTime(byte[] buffer, int offset, TimeSpan time)
+ {
+ ushort value = (ushort)(time.Hours << 11 | time.Minutes << 5 | time.Seconds);
+ LittleEndianWriter.WriteUInt16(buffer, offset, value);
+ }
+
+ public static DateTime ReadSMBDateTime(byte[] buffer, int offset)
+ {
+ DateTime date = ReadSMBDate(buffer, offset);
+ TimeSpan time = ReadSMBTime(buffer, offset + 2);
+ return date.Add(time);
+ }
+
+ public static DateTime ReadSMBDateTime(byte[] buffer, ref int offset)
+ {
+ offset += 4;
+ return ReadSMBDateTime(buffer, offset - 4);
+ }
+
+ public static void WriteSMBDateTime(byte[] buffer, int offset, DateTime dateTime)
+ {
+ WriteSMBDate(buffer, offset, dateTime.Date);
+ WriteSMBTime(buffer, offset + 2, dateTime.TimeOfDay);
+ }
+
+ public static void WriteSMBDateTime(byte[] buffer, ref int offset, DateTime dateTime)
+ {
+ WriteSMBDateTime(buffer, offset, dateTime);
+ offset += 4;
+ }
+
+ public static string ReadSMBString(byte[] buffer, int offset, bool isUnicode)
+ {
+ if (isUnicode)
+ {
+ return ByteReader.ReadNullTerminatedUTF16String(buffer, offset);
+ }
+ else
+ {
+ return ByteReader.ReadNullTerminatedAnsiString(buffer, offset);
+ }
+ }
+
+ public static string ReadSMBString(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ if (isUnicode)
+ {
+ return ByteReader.ReadNullTerminatedUTF16String(buffer, ref offset);
+ }
+ else
+ {
+ return ByteReader.ReadNullTerminatedAnsiString(buffer, ref offset);
+ }
+ }
+
+ public static void WriteSMBString(byte[] buffer, int offset, bool isUnicode, string value)
+ {
+ if (isUnicode)
+ {
+ ByteWriter.WriteNullTerminatedUTF16String(buffer, offset, value);
+ }
+ else
+ {
+ ByteWriter.WriteNullTerminatedAnsiString(buffer, offset, value);
+ }
+ }
+
+ public static void WriteSMBString(byte[] buffer, ref int offset, bool isUnicode, string value)
+ {
+ if (isUnicode)
+ {
+ ByteWriter.WriteNullTerminatedUTF16String(buffer, ref offset, value);
+ }
+ else
+ {
+ ByteWriter.WriteNullTerminatedAnsiString(buffer, ref offset, value);
+ }
+ }
+
+ public static string ReadFixedLengthString(byte[] buffer, ref int offset, bool isUnicode, int byteCount)
+ {
+ if (isUnicode)
+ {
+ return ByteReader.ReadUTF16String(buffer, ref offset, byteCount / 2);
+ }
+ else
+ {
+ return ByteReader.ReadAnsiString(buffer, ref offset, byteCount);
+ }
+ }
+
+ public static void WriteFixedLengthString(byte[] buffer, ref int offset, bool isUnicode, string value)
+ {
+ if (isUnicode)
+ {
+ ByteWriter.WriteUTF16String(buffer, ref offset, value);
+ }
+ else
+ {
+ ByteWriter.WriteAnsiString(buffer, ref offset, value);
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/SMBMessage.cs b/SMBLibrary/SMB1/SMBMessage.cs
new file mode 100644
index 0000000..0e8d2bc
--- /dev/null
+++ b/SMBLibrary/SMB1/SMBMessage.cs
@@ -0,0 +1,122 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.IO;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// Each message has a single header and either a single command or multiple batched (AndX) commands.
+ /// Multiple command requests or responses can be sent in a single message.
+ ///
+ public class SMBMessage
+ {
+ public SMBHeader Header;
+ public List Commands = new List();
+
+ public SMBMessage()
+ {
+ Header = new SMBHeader();
+ }
+
+ public SMBMessage(byte[] buffer)
+ {
+ Header = new SMBHeader(buffer);
+ SMBCommand command = SMBCommand.ReadCommand(buffer, SMBHeader.Length, Header.Command, Header);
+ Commands.Add(command);
+ while(command is SMBAndXCommand)
+ {
+ SMBAndXCommand andXCommand = (SMBAndXCommand)command;
+ if (andXCommand.AndXCommand == CommandName.SMB_COM_NO_ANDX_COMMAND)
+ {
+ break;
+ }
+ command = SMBCommand.ReadCommand(buffer, andXCommand.AndXOffset, andXCommand.AndXCommand, Header);
+ Commands.Add(command);
+ }
+ }
+
+ public byte[] GetBytes()
+ {
+ if (Commands.Count == 0)
+ {
+ throw new ArgumentException("Invalid command sequence");
+ }
+
+ for (int index = 0; index < Commands.Count - 1; index++)
+ {
+ if (!(Commands[index] is SMBAndXCommand))
+ {
+ throw new ArgumentException("Invalid command sequence");
+ }
+ }
+
+ SMBCommand lastCommand = Commands[Commands.Count - 1];
+ if (lastCommand is SMBAndXCommand)
+ {
+ ((SMBAndXCommand)lastCommand).AndXCommand = CommandName.SMB_COM_NO_ANDX_COMMAND;
+ }
+
+ List sequence = new List();
+ int length = SMBHeader.Length;
+ byte[] commandBytes;
+ for (int index = 0; index < Commands.Count - 1; index++)
+ {
+ SMBAndXCommand andXCommand = (SMBAndXCommand)Commands[index];
+ andXCommand.AndXCommand = Commands[index + 1].CommandName;
+ commandBytes = Commands[index].GetBytes(Header.UnicodeFlag);
+ ushort nextOffset = (ushort)(length + commandBytes.Length);
+ SMBAndXCommand.WriteAndXOffset(commandBytes, 0, nextOffset);
+ sequence.Add(commandBytes);
+ length += commandBytes.Length;
+ }
+
+ commandBytes = lastCommand.GetBytes(Header.UnicodeFlag);
+ sequence.Add(commandBytes);
+ length += commandBytes.Length;
+
+ Header.Command = Commands[0].CommandName;
+
+ byte[] buffer = new byte[length];
+ Header.WriteBytes(buffer, 0);
+ int offset = SMBHeader.Length;
+ foreach (byte[] bytes in sequence)
+ {
+ ByteWriter.WriteBytes(buffer, ref offset, bytes);
+ }
+
+ return buffer;
+ }
+
+ public static bool IsValidSMBMessage(byte[] buffer)
+ {
+ if (buffer[0] == SMBHeader.ProtocolSignature[0] &&
+ buffer[1] == SMBHeader.ProtocolSignature[1] &&
+ buffer[2] == SMBHeader.ProtocolSignature[2] &&
+ buffer[3] == SMBHeader.ProtocolSignature[3])
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public static SMBMessage GetSMBMessage(byte[] buffer)
+ {
+ if (!IsValidSMBMessage(buffer))
+ {
+ throw new InvalidRequestException("Invalid SMB message signature");;
+ }
+ return new SMBMessage(buffer);
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/DfsReferralEntry.cs b/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/DfsReferralEntry.cs
new file mode 100644
index 0000000..0b3fad6
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/DfsReferralEntry.cs
@@ -0,0 +1,17 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class DfsReferralEntry
+ {
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/RequestGetDfsReferral.cs b/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/RequestGetDfsReferral.cs
new file mode 100644
index 0000000..9fa793b
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/RequestGetDfsReferral.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// [MS-DFSC] REQ_GET_DFS_REFERRAL
+ ///
+ public class RequestGetDfsReferral
+ {
+ public ushort MaxReferralLevel;
+ public string RequestFileName; // Unicode
+
+ public RequestGetDfsReferral()
+ {
+ }
+
+ public RequestGetDfsReferral(byte[] buffer)
+ {
+ MaxReferralLevel = LittleEndianConverter.ToUInt16(buffer, 0);
+ RequestFileName = ByteReader.ReadNullTerminatedUTF16String(buffer, 2);
+ }
+
+ public byte[] GetBytes()
+ {
+ int length = 2 + RequestFileName.Length * 2 + 2;
+ byte[] buffer = new byte[length];
+ LittleEndianWriter.WriteUInt16(buffer, 0, MaxReferralLevel);
+ ByteWriter.WriteUTF16String(buffer, 2, RequestFileName);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/ResponseGetDfsReferral.cs.cs b/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/ResponseGetDfsReferral.cs.cs
new file mode 100644
index 0000000..235682b
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/DFSReferral/ResponseGetDfsReferral.cs.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// [MS-DFSC] RESP_GET_DFS_REFERRAL
+ ///
+ public class ResponseGetDfsReferral
+ {
+ public ushort PathConsumed;
+ public ushort NumberOfReferrals;
+ public uint ReferralHeaderFlags;
+ public List ReferralEntries;
+ public List StringBuffer;
+ // Padding
+
+ public ResponseGetDfsReferral()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ResponseGetDfsReferral(byte[] buffer)
+ {
+ throw new NotImplementedException();
+ }
+
+ public byte[] GetBytes()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/AccessModeOptions.cs b/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/AccessModeOptions.cs
new file mode 100644
index 0000000..e4d3942
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/AccessModeOptions.cs
@@ -0,0 +1,89 @@
+/* Copyright (C) 2014-2016 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public enum AccessMode : byte
+ {
+ Read = 0x00,
+ Write = 0x01,
+ ReadWrite = 0x02,
+ Execute = 0x03,
+ }
+
+ public enum SharingMode : byte
+ {
+ Compatibility = 0x00,
+ DenyReadWriteExecute = 0x01, // Exclusive use
+ DenyWrite = 0x02,
+ DenyReadExecute = 0x03,
+ DenyNothing = 0x04,
+ }
+
+ public enum ReferenceLocality : byte
+ {
+ Unknown = 0x00,
+ Sequential = 0x01,
+ Random = 0x02,
+ RandomWithLocality = 0x03,
+ }
+
+ public enum CachedMode : byte
+ {
+ CachingAllowed = 0x00,
+ DoNotCacheFile = 0x01,
+ }
+
+ public enum WriteThroughMode : byte
+ {
+ Disabled = 0x00,
+
+ ///
+ /// Write-through mode.
+ /// If this flag is set, then no read ahead or write behind is allowed on this file or device.
+ /// When the response is returned, data is expected to be on the disk or device.
+ ///
+ WriteThrough = 0x01,
+ }
+
+ public struct AccessModeOptions // 2 bytes
+ {
+ public AccessMode AccessMode;
+ public SharingMode SharingMode;
+ public ReferenceLocality ReferenceLocality;
+ public CachedMode CachedMode;
+ public WriteThroughMode WriteThroughMode;
+
+ public AccessModeOptions(byte[] buffer, int offset)
+ {
+ AccessMode = (AccessMode)(buffer[offset] & 0x07);
+ SharingMode = (SharingMode)((buffer[offset] & 0x70) >> 4);
+ ReferenceLocality = (ReferenceLocality)(buffer[offset + 1] & 0x07);
+ CachedMode = (CachedMode)((buffer[offset + 1] & 0x10) >> 4);
+ WriteThroughMode = (WriteThroughMode)((buffer[offset + 1] & 0x40) >> 6);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ buffer[offset + 0] = (byte)((byte)AccessMode & 0x07);
+ buffer[offset + 0] |= (byte)(((byte)SharingMode << 4) & 0x70);
+ buffer[offset + 1] = (byte)((byte)ReferenceLocality & 0x07);
+ buffer[offset + 1] |= (byte)(((byte)CachedMode << 4) & 0x10);
+ buffer[offset + 1] |= (byte)(((byte)WriteThroughMode << 6) & 0x40);
+ }
+
+ public static AccessModeOptions Read(byte[] buffer, ref int offset)
+ {
+ offset += 2;
+ return new AccessModeOptions(buffer, offset - 2);
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/ActionTaken.cs b/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/ActionTaken.cs
new file mode 100644
index 0000000..c8e0cf2
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/ActionTaken.cs
@@ -0,0 +1,34 @@
+/* Copyright (C) 2014 Tal Aloni . 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;
+
+namespace SMBLibrary.SMB1
+{
+ public enum LockStatus : byte
+ {
+ NoOpLockWasRequestedOrGranted = 0x00,
+ OpLockWasRequestedAndGranted = 0x01,
+ }
+
+ public struct ActionTaken
+ {
+ public OpenResult OpenResult;
+ public LockStatus LockStatus;
+
+ public ActionTaken(byte[] buffer, int offset)
+ {
+ OpenResult = (OpenResult)(buffer[offset + 0] & 0x03);
+ LockStatus = (LockStatus)(buffer[offset + 1] >> 7);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ buffer[offset + 0] = (byte)((byte)OpenResult & 0x03);
+ buffer[offset + 1] = (byte)((byte)LockStatus << 7);
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/OpenMode.cs b/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/OpenMode.cs
new file mode 100644
index 0000000..fb7330b
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/EnumStructures/OpenMode.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary.SMB1
+{
+ public enum CreateFile : byte
+ {
+ ReturnErrorIfNotExist = 0x00,
+ CreateIfNotExist = 0x01,
+ }
+
+ public enum FileExistsOpts : byte
+ {
+ ReturnError = 0x00,
+ Append = 0x01,
+ TruncateToZero = 0x02,
+ }
+
+ public struct OpenMode // 2 bytes
+ {
+ public FileExistsOpts FileExistsOpts;
+ public CreateFile CreateFile;
+
+ public OpenMode(byte[] buffer, int offset)
+ {
+ FileExistsOpts = (FileExistsOpts)(buffer[offset] & 0x3);
+ CreateFile = (CreateFile)((buffer[offset] & 0x10) >> 4);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ buffer[0] = (byte)FileExistsOpts;
+ buffer[0] |= (byte)((byte)CreateFile << 4);
+ }
+
+ public static OpenMode Read(byte[] buffer, ref int offset)
+ {
+ offset += 2;
+ return new OpenMode(buffer, offset - 2);
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/ExtendedAttributeFlag.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/ExtendedAttributeFlag.cs
new file mode 100644
index 0000000..55010cd
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/ExtendedAttributeFlag.cs
@@ -0,0 +1,8 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum ExtendedAttributeFlag : byte
+ {
+ FILE_NEED_EA = 0x80,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/FindFlags.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/FindFlags.cs
new file mode 100644
index 0000000..888aa16
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/FindFlags.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum FindFlags : ushort
+ {
+ SMB_FIND_CLOSE_AFTER_REQUEST = 0x0001,
+ SMB_FIND_CLOSE_AT_EOS = 0x0002,
+ SMB_FIND_RETURN_RESUME_KEYS = 0x0004,
+ SMB_FIND_CONTINUE_FROM_LAST = 0x0008,
+ SMB_FIND_WITH_BACKUP_INTENT = 0x0010,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/FindInformationLevel.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/FindInformationLevel.cs
new file mode 100644
index 0000000..756e424
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/FindInformationLevel.cs
@@ -0,0 +1,14 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum FindInformationLevel : ushort
+ {
+ SMB_INFO_STANDARD = 0x0001,
+ SMB_INFO_QUERY_EA_SIZE = 0x0002,
+ SMB_INFO_QUERY_EAS_FROM_LIST = 0x0003,
+ SMB_FIND_FILE_DIRECTORY_INFO = 0x0101,
+ SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x0102,
+ SMB_FIND_FILE_NAMES_INFO = 0x0103,
+ SMB_FIND_FILE_BOTH_DIRECTORY_INFO = 0x0104,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/Open2Flags.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/Open2Flags.cs
new file mode 100644
index 0000000..f76eefc
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/Open2Flags.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum Open2Flags : ushort
+ {
+ ///
+ /// Return additional information in the response;
+ /// populate the CreationTime, FileDataSize, AccessMode, ResourceType, and NMPipeStatus fields in the response.
+ ///
+ REQ_ATTRIB = 0x0001,
+
+ ///
+ /// Exclusive OpLock requested.
+ ///
+ REQ_OPLOCK = 0x0002,
+
+ ///
+ /// Batch OpLock requested.
+ ///
+ REQ_OPBATCH = 0x0004,
+
+ ///
+ /// Return total length of Extended Attributes (EAs);
+ /// populate the ExtendedAttributeLength field in the response.
+ ///
+ REQ_EASIZE = 0x0008,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/QueryFSInformationLevel.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/QueryFSInformationLevel.cs
new file mode 100644
index 0000000..92b2fd9
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/QueryFSInformationLevel.cs
@@ -0,0 +1,13 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum QueryFSInformationLevel : ushort
+ {
+ SMB_INFO_ALLOCATION = 0x0001,
+ SMB_INFO_VOLUME = 0x0002,
+ SMB_QUERY_FS_VOLUME_INFO = 0x0102,
+ SMB_QUERY_FS_SIZE_INFO = 0x0103,
+ SMB_QUERY_FS_DEVICE_INFO = 0x0104,
+ SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/QueryInformationLevel.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/QueryInformationLevel.cs
new file mode 100644
index 0000000..c11380c
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/QueryInformationLevel.cs
@@ -0,0 +1,20 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum QueryInformationLevel : ushort
+ {
+ SMB_INFO_STANDARD = 0x0001,
+ SMB_INFO_QUERY_EA_SIZE = 0x0002,
+ SMB_INFO_QUERY_EAS_FROM_LIST = 0x0003,
+ SMB_INFO_QUERY_ALL_EAS = 0x0004,
+ SMB_INFO_IS_NAME_VALID = 0x0006,
+ SMB_QUERY_FILE_BASIC_INFO = 0x0101,
+ SMB_QUERY_FILE_STANDARD_INFO = 0x0102,
+ SMB_QUERY_FILE_EA_INFO = 0x0103,
+ SMB_QUERY_FILE_NAME_INFO = 0x0104,
+ SMB_QUERY_FILE_ALL_INFO = 0x0107,
+ SMB_QUERY_FILE_ALT_NAME_INFO = 0x0108,
+ SMB_QUERY_FILE_STREAM_INFO = 0x0109,
+ SMB_QUERY_FILE_COMPRESSION_INFO = 0x010B,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/SearchStorageType.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/SearchStorageType.cs
new file mode 100644
index 0000000..68483c7
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/SearchStorageType.cs
@@ -0,0 +1,9 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum SearchStorageType : uint
+ {
+ FILE_DIRECTORY_FILE = 0x01,
+ FILE_NON_DIRECTORY_FILE = 0x40,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/SetInformationLevel.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/SetInformationLevel.cs
new file mode 100644
index 0000000..a17a91b
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/SetInformationLevel.cs
@@ -0,0 +1,13 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum SetInformationLevel : ushort
+ {
+ SMB_INFO_STANDARD = 0x0001,
+ SMB_INFO_SET_EAS = 0x0002,
+ SMB_SET_FILE_BASIC_INFO = 0x0101,
+ SMB_SET_FILE_DISPOSITION_INFO = 0x0102,
+ SMB_SET_FILE_ALLOCATION_INFO = 0x0103,
+ SMB_SET_FILE_END_OF_FILE_INFO = 0x0104,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Enums/Transaction2SubcommandName.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/Transaction2SubcommandName.cs
new file mode 100644
index 0000000..2ef40c8
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Enums/Transaction2SubcommandName.cs
@@ -0,0 +1,17 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum Transaction2SubcommandName : ushort
+ {
+ TRANS2_OPEN2 = 0x0000,
+ TRANS2_FIND_FIRST2 = 0x0001,
+ TRANS2_FIND_NEXT2 = 0x0002,
+ TRANS2_QUERY_FS_INFORMATION = 0x0003,
+ TRANS2_QUERY_PATH_INFORMATION = 0x0005,
+ TRANS2_SET_PATH_INFORMATION = 0x006,
+ TRANS2_QUERY_FILE_INFORMATION = 0x0007,
+ TRANS2_SET_FILE_INFORMATION = 0x0008,
+ TRANS2_CREATE_DIRECTORY = 0x000D,
+ TRANS2_GET_DFS_REFERRAL = 0x0010,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileBothDirectoryInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileBothDirectoryInfo.cs
new file mode 100644
index 0000000..b5cd67b
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileBothDirectoryInfo.cs
@@ -0,0 +1,102 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_FIND_FILE_BOTH_DIRECTORY_INFO
+ ///
+ public class FindFileBothDirectoryInfo : FindInformationEntry
+ {
+ public const int FixedLength = 94;
+
+ public uint NextEntryOffset;
+ public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
+ public DateTime CreationTime;
+ public DateTime LastAccessTime;
+ public DateTime LastWriteTime;
+ public DateTime LastChangeTime;
+ public ulong EndOfFile;
+ public ulong AllocationSize;
+ public ExtendedFileAttributes ExtFileAttributes;
+ //uint FileNameLength; // In bytes, MUST exclude the null termination.
+ public uint EASize;
+ //byte ShortNameLength; // In bytes
+ public byte Reserved;
+ public string ShortName; // 24 bytes, 8.3 name of the file in Unicode format
+ public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
+ // Omitting the NULL termination from the FileName field in a single SMB_FIND_FILE_BOTH_DIRECTORY_INFO structure
+ // (as a response to TRANS2_QUERY_PATH_INFORMATION on a single directory)
+ // Will, in some rare but repeatable cases, cause issues with Windows XP SP3 as a client
+ // (the client will display an error message that the folder "refers to a location that is unavailable"...)
+
+ public FindFileBothDirectoryInfo() : base(false)
+ {
+ }
+
+ public FindFileBothDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+ {
+ NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ CreationTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastAccessTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastWriteTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastChangeTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ EndOfFile = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(buffer, ref offset);
+ uint fileNameLength = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ EASize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ byte shortNameLength = ByteReader.ReadByte(buffer, ref offset);
+ Reserved = ByteReader.ReadByte(buffer, ref offset);
+ ShortName = ByteReader.ReadUTF16String(buffer, ref offset, 12);
+ ShortName = ShortName.Substring(0, shortNameLength);
+ FileName = SMBHelper.ReadFixedLengthString(buffer, ref offset, isUnicode, (int)fileNameLength);
+ }
+
+ public override void WriteBytes(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ uint fileNameLength = (uint)(isUnicode ? FileName.Length * 2 : FileName.Length);
+ byte shortNameLength = (byte)(ShortName.Length * 2);
+
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NextEntryOffset);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileIndex);
+ SMBHelper.WriteFileTime(buffer, ref offset, CreationTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastAccessTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastWriteTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastChangeTime);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, EndOfFile);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, fileNameLength);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, EASize);
+ ByteWriter.WriteByte(buffer, ref offset, shortNameLength);
+ ByteWriter.WriteByte(buffer, ref offset, Reserved);
+ ByteWriter.WriteUTF16String(buffer, ref offset, ShortName, 12);
+ SMBHelper.WriteSMBString(buffer, ref offset, isUnicode, FileName);
+ }
+
+ public override int GetLength(bool isUnicode)
+ {
+ int length = FixedLength;
+
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileDirectoryInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileDirectoryInfo.cs
new file mode 100644
index 0000000..98fde65
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileDirectoryInfo.cs
@@ -0,0 +1,84 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_FIND_FILE_DIRECTORY_INFO
+ ///
+ public class FindFileDirectoryInfo : FindInformationEntry
+ {
+ public const int FixedLength = 64;
+
+ public uint NextEntryOffset;
+ public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
+ public DateTime CreationTime;
+ public DateTime LastAccessTime;
+ public DateTime LastWriteTime;
+ public DateTime LastAttrChangeTime;
+ public ulong EndOfFile;
+ public ulong AllocationSize;
+ public ExtendedFileAttributes ExtFileAttributes;
+ //uint FileNameLength; // In bytes, MUST exclude the null termination.
+ public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
+
+ public FindFileDirectoryInfo() : base(false)
+ {
+ }
+
+ public FindFileDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+ {
+ NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ CreationTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastAccessTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastWriteTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastAttrChangeTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ EndOfFile = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(buffer, ref offset);
+ uint fileNameLength = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileName = SMBHelper.ReadFixedLengthString(buffer, ref offset, isUnicode, (int)fileNameLength);
+ }
+
+ public override void WriteBytes(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ uint fileNameLength = (byte)(isUnicode ? FileName.Length * 2 : FileName.Length);
+
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NextEntryOffset);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileIndex);
+ SMBHelper.WriteFileTime(buffer, ref offset, CreationTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastAccessTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastWriteTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastAttrChangeTime);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, EndOfFile);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, fileNameLength);
+ SMBHelper.WriteSMBString(buffer, ref offset, isUnicode, FileName);
+ }
+
+ public override int GetLength(bool isUnicode)
+ {
+ int length = FixedLength;
+
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileFullDirectoryInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileFullDirectoryInfo.cs
new file mode 100644
index 0000000..ca8d1ca
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileFullDirectoryInfo.cs
@@ -0,0 +1,87 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_FIND_FILE_FULL_DIRECTORY_INFO
+ ///
+ public class FindFileFullDirectoryInfo : FindInformationEntry
+ {
+ public const int FixedLength = 68;
+
+ public uint NextEntryOffset;
+ public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
+ public DateTime CreationTime;
+ public DateTime LastAccessTime;
+ public DateTime LastWriteTime;
+ public DateTime LastAttrChangeTime;
+ public ulong EndOfFile;
+ public ulong AllocationSize;
+ public ExtendedFileAttributes ExtFileAttributes;
+ //uint FileNameLength; // In bytes, MUST exclude the null termination.
+ public uint EASize;
+ public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
+
+ public FindFileFullDirectoryInfo() : base(false)
+ {
+ }
+
+ public FindFileFullDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+ {
+ NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ CreationTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastAccessTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastWriteTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastAttrChangeTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ EndOfFile = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(buffer, ref offset);
+ uint fileNameLength = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ EASize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileName = SMBHelper.ReadFixedLengthString(buffer, ref offset, isUnicode, (int)fileNameLength);
+ }
+
+ public override void WriteBytes(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ uint fileNameLength = (byte)(isUnicode ? FileName.Length * 2 : FileName.Length);
+
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NextEntryOffset);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileIndex);
+ SMBHelper.WriteFileTime(buffer, ref offset, CreationTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastAccessTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastWriteTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastAttrChangeTime);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, EndOfFile);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, fileNameLength);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, EASize);
+ SMBHelper.WriteSMBString(buffer, ref offset, isUnicode, FileName);
+ }
+
+ public override int GetLength(bool isUnicode)
+ {
+ int length = FixedLength;
+
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileNamesInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileNamesInfo.cs
new file mode 100644
index 0000000..1b2daa2
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindFileNamesInfo.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_FIND_FILE_NAMES_INFO
+ ///
+ public class FindFileNamesInfo : FindInformationEntry
+ {
+ public const int FixedLength = 12;
+
+ public uint NextEntryOffset;
+ public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
+ //uint FileNameLength; // In bytes, MUST exclude the null termination.
+ public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
+
+ public FindFileNamesInfo() : base(false)
+ {
+ }
+
+ public FindFileNamesInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+ {
+ NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ uint fileNameLength = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileName = SMBHelper.ReadFixedLengthString(buffer, ref offset, isUnicode, (int)fileNameLength);
+ }
+
+ public override void WriteBytes(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ uint fileNameLength = (uint)(isUnicode ? FileName.Length * 2 : FileName.Length);
+
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NextEntryOffset);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileIndex);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, fileNameLength);
+ SMBHelper.WriteSMBString(buffer, ref offset, isUnicode, FileName);
+ }
+
+ public override int GetLength(bool isUnicode)
+ {
+ int length = FixedLength;
+
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoQueryEASize.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoQueryEASize.cs
new file mode 100644
index 0000000..b576932
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoQueryEASize.cs
@@ -0,0 +1,89 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_QUERY_EA_SIZE
+ ///
+ public class FindInfoQueryEASize : FindInformationEntry
+ {
+ public uint ResumeKey; // Optional
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public uint FileDataSize;
+ public uint AllocationSize;
+ public FileAttributes Attributes;
+ public uint EASize;
+ //byte FileNameLength; // In bytes, MUST exclude the null termination.
+ public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
+
+ public FindInfoQueryEASize(bool returnResumeKeys) : base(returnResumeKeys)
+ {
+ }
+
+ public FindInfoQueryEASize(byte[] buffer, ref int offset, bool isUnicode, bool returnResumeKeys) : base(returnResumeKeys)
+ {
+ if (returnResumeKeys)
+ {
+ ResumeKey = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ }
+ CreationDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastAccessDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastWriteDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ FileDataSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Attributes = (FileAttributes)LittleEndianReader.ReadUInt16(buffer, ref offset);
+ EASize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ byte fileNameLength = ByteReader.ReadByte(buffer, ref offset);
+ FileName = SMBHelper.ReadFixedLengthString(buffer, ref offset, isUnicode, fileNameLength);
+ }
+
+ public override void WriteBytes(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ byte fileNameLength = (byte)(isUnicode ? FileName.Length * 2 : FileName.Length);
+
+ if (ReturnResumeKeys)
+ {
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, ResumeKey);
+ }
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, CreationDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastAccessDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastWriteDateTime);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileDataSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)Attributes);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, EASize);
+ ByteWriter.WriteByte(buffer, ref offset, fileNameLength);
+ SMBHelper.WriteSMBString(buffer, ref offset, isUnicode, FileName);
+ }
+
+ public override int GetLength(bool isUnicode)
+ {
+ int length = 31;
+ if (ReturnResumeKeys)
+ {
+ length += 4;
+ }
+
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoQueryExtendedAttributesFromList.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoQueryExtendedAttributesFromList.cs
new file mode 100644
index 0000000..54d027b
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoQueryExtendedAttributesFromList.cs
@@ -0,0 +1,89 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_QUERY_EAS_FROM_LIST
+ ///
+ public class FindInfoQueryExtendedAttributesFromList : FindInformationEntry
+ {
+ public uint ResumeKey; // Optional
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public uint FileDataSize;
+ public uint AllocationSize;
+ public FileAttributes Attributes;
+ public FullExtendedAttributeList ExtendedAttributeList;
+ //byte FileNameLength; // In bytes, MUST exclude the null termination.
+ public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
+
+ public FindInfoQueryExtendedAttributesFromList(bool returnResumeKeys) : base(returnResumeKeys)
+ {
+ }
+
+ public FindInfoQueryExtendedAttributesFromList(byte[] buffer, ref int offset, bool isUnicode, bool returnResumeKeys) : base(returnResumeKeys)
+ {
+ if (returnResumeKeys)
+ {
+ ResumeKey = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ }
+ CreationDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastAccessDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastWriteDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ FileDataSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Attributes = (FileAttributes)LittleEndianReader.ReadUInt16(buffer, ref offset);
+ ExtendedAttributeList = new FullExtendedAttributeList(buffer, offset);
+ byte fileNameLength = ByteReader.ReadByte(buffer, ref offset);
+ FileName = SMBHelper.ReadFixedLengthString(buffer, ref offset, isUnicode, fileNameLength);
+ }
+
+ public override void WriteBytes(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ byte fileNameLength = (byte)(isUnicode ? FileName.Length * 2 : FileName.Length);
+
+ if (ReturnResumeKeys)
+ {
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, ResumeKey);
+ }
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, CreationDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastAccessDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastWriteDateTime);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileDataSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)Attributes);
+ ExtendedAttributeList.WriteBytes(buffer, ref offset);
+ ByteWriter.WriteByte(buffer, ref offset, fileNameLength);
+ SMBHelper.WriteSMBString(buffer, ref offset, isUnicode, FileName);
+ }
+
+ public override int GetLength(bool isUnicode)
+ {
+ int length = 27 + ExtendedAttributeList.Length;
+ if (ReturnResumeKeys)
+ {
+ length += 4;
+ }
+
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoStandard.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoStandard.cs
new file mode 100644
index 0000000..bafb915
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInfoStandard.cs
@@ -0,0 +1,88 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_STANDARD
+ ///
+ public class FindInfoStandard : FindInformationEntry
+ {
+ public const int FixedLength = 23;
+
+ public uint ResumeKey; // Optional
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public uint FileDataSize;
+ public uint AllocationSize;
+ public FileAttributes Attributes;
+ //byte FileNameLength;
+ public string FileName; // SMB_STRING
+
+ public FindInfoStandard(bool returnResumeKeys) : base(returnResumeKeys)
+ {
+ }
+
+ public FindInfoStandard(byte[] buffer, ref int offset, bool isUnicode, bool returnResumeKeys) : base(returnResumeKeys)
+ {
+ if (returnResumeKeys)
+ {
+ ResumeKey = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ }
+ CreationDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastAccessDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastWriteDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ FileDataSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Attributes = (FileAttributes)LittleEndianReader.ReadUInt16(buffer, ref offset);
+ byte fileNameLength = ByteReader.ReadByte(buffer, ref offset);
+ FileName = SMBHelper.ReadSMBString(buffer, ref offset, isUnicode);
+ }
+
+ public override void WriteBytes(byte[] buffer, ref int offset, bool isUnicode)
+ {
+ byte fileNameLength = (byte)(isUnicode ? FileName.Length * 2 : FileName.Length);
+
+ if (ReturnResumeKeys)
+ {
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, ResumeKey);
+ }
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, CreationDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastAccessDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastWriteDateTime);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileDataSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)Attributes);
+ ByteWriter.WriteByte(buffer, ref offset, fileNameLength);
+ SMBHelper.WriteSMBString(buffer, ref offset, isUnicode, FileName);
+ }
+
+ public override int GetLength(bool isUnicode)
+ {
+ int length = FixedLength;
+ if (ReturnResumeKeys)
+ {
+ length += 4;
+ }
+
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInformation.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInformation.cs
new file mode 100644
index 0000000..81a4826
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInformation.cs
@@ -0,0 +1,78 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public class FindInformation : List
+ {
+ public FindInformation()
+ {
+ }
+
+ public FindInformation(byte[] buffer, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys)
+ {
+ int offset = 0;
+ while (offset < buffer.Length)
+ {
+ FindInformationEntry entry = FindInformationEntry.ReadEntry(buffer, ref offset, informationLevel, isUnicode, returnResumeKeys);
+ this.Add(entry);
+ }
+ }
+
+ public byte[] GetBytes(bool isUnicode)
+ {
+ for(int index = 0; index < this.Count; index++)
+ {
+ if (index < this.Count - 1)
+ {
+ FindInformationEntry entry = this[index];
+ int entryLength = entry.GetLength(isUnicode);
+ if (entry is FindFileBothDirectoryInfo)
+ {
+ ((FindFileBothDirectoryInfo)entry).NextEntryOffset = (uint)entryLength;
+ }
+ else if (entry is FindFileDirectoryInfo)
+ {
+ ((FindFileDirectoryInfo)entry).NextEntryOffset = (uint)entryLength;
+ }
+ else if (entry is FindFileFullDirectoryInfo)
+ {
+ ((FindFileFullDirectoryInfo)entry).NextEntryOffset = (uint)entryLength;
+ }
+ else if (entry is FindFileNamesInfo)
+ {
+ ((FindFileNamesInfo)entry).NextEntryOffset = (uint)entryLength;
+ }
+ }
+ }
+ int length = GetLength(isUnicode);
+ byte[] buffer = new byte[length];
+ int offset = 0;
+ foreach (FindInformationEntry entry in this)
+ {
+ entry.WriteBytes(buffer, ref offset, isUnicode);
+ }
+ return buffer;
+ }
+
+ public int GetLength(bool isUnicode)
+ {
+ int length = 0;
+ for (int index = 0; index < this.Count; index++)
+ {
+ FindInformationEntry entry = this[index];
+ int entryLength = entry.GetLength(isUnicode);
+ length += entryLength;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInformationEntry.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInformationEntry.cs
new file mode 100644
index 0000000..5c0bcae
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FindInformation/FindInformationEntry.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class FindInformationEntry
+ {
+ private bool m_returnResumeKeys;
+
+ public FindInformationEntry(bool returnResumeKeys)
+ {
+ m_returnResumeKeys = returnResumeKeys;
+ }
+
+ public abstract void WriteBytes(byte[] buffer, ref int offset, bool isUnicode);
+
+ public abstract int GetLength(bool isUnicode);
+
+ public bool ReturnResumeKeys
+ {
+ get
+ {
+ return m_returnResumeKeys;
+ }
+ }
+
+ public static FindInformationEntry ReadEntry(byte[] buffer, ref int offset, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys)
+ {
+ switch (informationLevel)
+ {
+ case FindInformationLevel.SMB_INFO_STANDARD:
+ return new FindInfoStandard(buffer, ref offset, isUnicode, returnResumeKeys);
+ case FindInformationLevel.SMB_INFO_QUERY_EA_SIZE:
+ return new FindInfoQueryEASize(buffer, ref offset, isUnicode, returnResumeKeys);
+ case FindInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST:
+ return new FindInfoQueryExtendedAttributesFromList(buffer, ref offset, isUnicode, returnResumeKeys);
+ case FindInformationLevel.SMB_FIND_FILE_DIRECTORY_INFO:
+ return new FindFileDirectoryInfo(buffer, ref offset, isUnicode);
+ case FindInformationLevel.SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+ return new FindFileFullDirectoryInfo(buffer, ref offset, isUnicode);
+ case FindInformationLevel.SMB_FIND_FILE_NAMES_INFO:
+ return new FindFileNamesInfo(buffer, ref offset, isUnicode);
+ case FindInformationLevel.SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
+ return new FindFileBothDirectoryInfo(buffer, ref offset, isUnicode);
+ default:
+ throw new InvalidRequestException();;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FullExtendedAttribute.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FullExtendedAttribute.cs
new file mode 100644
index 0000000..4da1c8e
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FullExtendedAttribute.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_FEA
+ ///
+ public class FullExtendedAttribute
+ {
+ public ExtendedAttributeFlag ExtendedAttributeFlag;
+ //byte AttributeNameLengthInBytes;
+ //ushort AttributeValueLengthInBytes;
+ public string AttributeName; // ANSI, AttributeNameLengthInBytes + 1 byte null termination
+ public string AttributeValue; // ANSI
+
+ public FullExtendedAttribute(byte[] buffer, int offset)
+ {
+ ExtendedAttributeFlag = (ExtendedAttributeFlag)ByteReader.ReadByte(buffer, offset);
+ byte attributeNameLengthInBytes = ByteReader.ReadByte(buffer, offset + 1);
+ ushort attributeValueLengthInBytes = LittleEndianConverter.ToUInt16(buffer, offset + 2);
+ AttributeName = ByteReader.ReadAnsiString(buffer, offset + 4, attributeNameLengthInBytes);
+ AttributeValue = ByteReader.ReadAnsiString(buffer, offset + 4 + attributeNameLengthInBytes + 1, attributeValueLengthInBytes);
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ byte attributeNameLengthInBytes = (byte)AttributeName.Length;
+ ushort attributeValueLengthInBytes = (ushort)AttributeValue.Length;
+ ByteWriter.WriteByte(buffer, offset, (byte)ExtendedAttributeFlag);
+ ByteWriter.WriteByte(buffer, offset + 1, attributeNameLengthInBytes);
+ LittleEndianWriter.WriteUInt16(buffer, offset + 2, attributeValueLengthInBytes);
+ ByteWriter.WriteAnsiString(buffer, offset + 4, AttributeName, AttributeValue.Length);
+ ByteWriter.WriteAnsiString(buffer, offset + 4 + attributeNameLengthInBytes + 1, AttributeValue, AttributeValue.Length);
+ }
+
+ public int Length
+ {
+ get
+ {
+ return 4 + AttributeName.Length + 1 + AttributeValue.Length;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/FullExtendedAttributeList.cs b/SMBLibrary/SMB1/Transaction2Subcommands/FullExtendedAttributeList.cs
new file mode 100644
index 0000000..ab8f1eb
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/FullExtendedAttributeList.cs
@@ -0,0 +1,83 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_FEA_LIST
+ ///
+ public class FullExtendedAttributeList : List
+ {
+ public FullExtendedAttributeList()
+ {
+ }
+
+ public FullExtendedAttributeList(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public FullExtendedAttributeList(byte[] buffer, ref int offset) : this(buffer, offset)
+ {
+ // length MUST contain the total size of the FEAList field, plus the size of the SizeOfListInBytes field
+ int length = (int)LittleEndianConverter.ToUInt32(buffer, offset);
+ offset += length;
+ }
+
+ public FullExtendedAttributeList(byte[] buffer, int offset)
+ {
+ // length MUST contain the total size of the FEAList field, plus the size of the SizeOfListInBytes field
+ int length = (int)LittleEndianConverter.ToUInt32(buffer, offset);
+ int position = offset + 4;
+ int eof = offset + length;
+ while (position < eof)
+ {
+ FullExtendedAttribute attribute = new FullExtendedAttribute(buffer, position);
+ this.Add(attribute);
+ position += attribute.Length;
+ }
+ }
+
+ public byte[] GetBytes()
+ {
+ byte[] buffer = new byte[this.Length];
+ WriteBytes(buffer, 0);
+ return buffer;
+ }
+
+ public void WriteBytes(byte[] buffer, ref int offset)
+ {
+ WriteBytes(buffer, offset);
+ offset += this.Length;
+ }
+
+ public void WriteBytes(byte[] buffer, int offset)
+ {
+ foreach (FullExtendedAttribute entry in this)
+ {
+ entry.WriteBytes(buffer, offset);
+ offset += entry.Length;
+ }
+ }
+
+ public int Length
+ {
+ get
+ {
+ int length = 0;
+ foreach (FullExtendedAttribute entry in this)
+ {
+ length += entry.Length;
+ }
+ return length;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/DeviceCharacteristics.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/DeviceCharacteristics.cs
new file mode 100644
index 0000000..69f47d2
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/DeviceCharacteristics.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum DeviceCharacteristics : uint
+ {
+ FILE_REMOVABLE_MEDIA = 0x0001,
+ FILE_READ_ONLY_DEVICE = 0x0002,
+ FILE_FLOPPY_DISKETTE = 0x0004,
+ FILE_WRITE_ONCE_MEDIA = 0x0008,
+ FILE_REMOTE_DEVICE = 0x0010,
+ FILE_DEVICE_IS_MOUNTED = 0x0020,
+ FILE_VIRTUAL_VOLUME = 0x0040,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/DeviceType.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/DeviceType.cs
new file mode 100644
index 0000000..cc0810c
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/DeviceType.cs
@@ -0,0 +1,51 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum DeviceType : uint
+ {
+ FILE_DEVICE_BEEP = 0x0001,
+ FILE_DEVICE_CD_ROM = 0x0002,
+ FILE_DEVICE_CD_ROM_FILE_SYSTEM = 0x0003,
+ FILE_DEVICE_CONTROLLER = 0x0004,
+ FILE_DEVICE_DATALINK = 0x0005,
+ FILE_DEVICE_DFS = 0x0006,
+ FILE_DEVICE_DISK = 0x0007,
+ FILE_DEVICE_DISK_FILE_SYSTEM = 0x0008,
+ FILE_DEVICE_FILE_SYSTEM = 0x0009,
+ FILE_DEVICE_INPORT_PORT = 0x000A,
+ FILE_DEVICE_KEYBOARD = 0x000B,
+ FILE_DEVICE_MAILSLOT = 0x000C,
+ FILE_DEVICE_MIDI_IN = 0x000D,
+ FILE_DEVICE_MIDI_OUT = 0x000E,
+ FILE_DEVICE_MOUSE = 0x000F,
+ FILE_DEVICE_MULTI_UNC_PROVIDER = 0x0010,
+ FILE_DEVICE_NAMED_PIPE = 0x0011,
+ FILE_DEVICE_NETWORK = 0x0012,
+ FILE_DEVICE_NETWORK_BROWSER = 0x0013,
+ FILE_DEVICE_NETWORK_FILE_SYSTEM = 0x0014,
+ FILE_DEVICE_NULL = 0x0015,
+ FILE_DEVICE_PARALLEL_PORT = 0x0016,
+ FILE_DEVICE_PHYSICAL_NETCARD = 0x0017,
+ FILE_DEVICE_PRINTER = 0x0018,
+ FILE_DEVICE_SCANNER = 0x0019,
+ FILE_DEVICE_SERIAL_MOUSE_PORT = 0x001A,
+ FILE_DEVICE_SERIAL_PORT = 0x001B,
+ FILE_DEVICE_SCREEN = 0x001C,
+ FILE_DEVICE_SOUND = 0x001D,
+ FILE_DEVICE_STREAMS = 0x001E,
+ FILE_DEVICE_TAPE = 0x001F,
+ FILE_DEVICE_TAPE_FILE_SYSTEM = 0x0020,
+ FILE_DEVICE_TRANSPORT = 0x0021,
+ FILE_DEVICE_UNKNOWN = 0x0022,
+ FILE_DEVICE_VIDEO = 0x0023,
+ FILE_DEVICE_VIRTUAL_DISK = 0x0024,
+ FILE_DEVICE_WAVE_IN = 0x0025,
+ FILE_DEVICE_WAVE_OUT = 0x0026,
+ FILE_DEVICE_8042_PORT = 0x0027,
+ FILE_DEVICE_NETWORK_REDIRECTOR = 0x0028,
+ FILE_DEVICE_BATTERY = 0x0029,
+ FILE_DEVICE_BUS_EXTENDER = 0x002A,
+ FILE_DEVICE_MODEM = 0x002B,
+ FILE_DEVICE_VDM = 0x002C,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/FileSystemAttributes.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/FileSystemAttributes.cs
new file mode 100644
index 0000000..f3d315a
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/Enums/FileSystemAttributes.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum FileSystemAttributes : uint
+ {
+ FILE_CASE_SENSITIVE_SEARCH = 0x0001,
+ FILE_CASE_PRESERVED_NAMES = 0x0002,
+ FILE_UNICODE_ON_DISK = 0x0004,
+ FILE_PERSISTENT_ACLS = 0x0008,
+ FILE_FILE_COMPRESSION = 0x0010,
+ FILE_VOLUME_QUOTAS = 0x0020, // SMB 1.0 addition
+ FILE_SUPPORTS_SPARSE_FILES = 0x0040, // SMB 1.0 addition
+ FILE_SUPPORTS_REPARSE_POINTS = 0x0080, // SMB 1.0 addition
+ FILE_SUPPORTS_REMOTE_STORAGE = 0x0100, // SMB 1.0 addition
+ FILE_VOLUME_IS_COMPRESSED = 0x8000,
+ FILE_SUPPORTS_OBJECT_IDS = 0x00010000, // SMB 1.0 addition
+ FILE_SUPPORTS_ENCRYPTION = 0x00020000, // SMB 1.0 addition
+ FILE_NAMED_STREAMS = 0x00040000, // SMB 1.0 addition
+ FILE_READ_ONLY_VOLUME = 0x00080000, // SMB 1.0 addition
+ FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000, // SMB 1.0 addition
+ FILE_SUPPORTS_TRANSACTIONS = 0x00200000, // SMB 1.0 addition
+ FILE_SUPPORTS_HARD_LINKS = 0x00400000, // SMB 1.0 addition
+ FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000, // SMB 1.0 addition
+ FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000, // SMB 1.0 addition
+ FILE_SUPPORTS_USN_JOURNAL = 0x02000000, // SMB 1.0 addition
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSAttibuteInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSAttibuteInfo.cs
new file mode 100644
index 0000000..ee68d39
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSAttibuteInfo.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FS_ATTRIBUTE_INFO
+ ///
+ public class QueryFSAttibuteInfo : QueryFSInformation
+ {
+ public const int FixedLength = 12;
+
+ public FileSystemAttributes FileSystemAttributes;
+ public uint MaxFileNameLengthInBytes;
+ //uint LengthOfFileSystemName; // In bytes
+ public string FileSystemName; // Unicode
+
+ public QueryFSAttibuteInfo()
+ {
+ }
+
+ public QueryFSAttibuteInfo(byte[] buffer, int offset)
+ {
+ FileSystemAttributes = (FileSystemAttributes)LittleEndianConverter.ToUInt32(buffer, offset + 0);
+ MaxFileNameLengthInBytes = LittleEndianConverter.ToUInt32(buffer, offset + 4);
+ uint lengthOfFileSystemName = LittleEndianConverter.ToUInt32(buffer, offset + 8);
+ FileSystemName = ByteReader.ReadUTF16String(buffer, offset + 12, (int)(lengthOfFileSystemName / 2));
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ uint lengthOfFileSystemName = (uint)(FileSystemName.Length * 2);
+ byte[] buffer = new byte[this.Length];
+ LittleEndianWriter.WriteUInt32(buffer, 0, (uint)FileSystemAttributes);
+ LittleEndianWriter.WriteUInt32(buffer, 4, MaxFileNameLengthInBytes);
+ LittleEndianWriter.WriteUInt32(buffer, 8, lengthOfFileSystemName);
+ ByteWriter.WriteUTF16String(buffer, 12, FileSystemName);
+ return buffer;
+ }
+
+ public int Length
+ {
+ get
+ {
+ return FixedLength + FileSystemName.Length * 2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSDeviceInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSDeviceInfo.cs
new file mode 100644
index 0000000..fb767d8
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSDeviceInfo.cs
@@ -0,0 +1,42 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FS_DEVICE_INFO
+ ///
+ public class QueryFSDeviceInfo : QueryFSInformation
+ {
+ public const int Length = 8;
+
+ public DeviceType DeviceType;
+ public DeviceCharacteristics DeviceCharacteristics;
+
+ public QueryFSDeviceInfo()
+ {
+ }
+
+ public QueryFSDeviceInfo(byte[] buffer, int offset)
+ {
+ DeviceType = (DeviceType)LittleEndianConverter.ToUInt32(buffer, offset + 0);
+ DeviceCharacteristics = (DeviceCharacteristics)LittleEndianConverter.ToUInt32(buffer, offset + 4);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte[] buffer = new byte[Length];
+ LittleEndianWriter.WriteUInt32(buffer, 0, (uint)DeviceType);
+ LittleEndianWriter.WriteUInt32(buffer, 4, (uint)DeviceCharacteristics);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInfoAllocation.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInfoAllocation.cs
new file mode 100644
index 0000000..ad3c200
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInfoAllocation.cs
@@ -0,0 +1,51 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_ALLOCATION
+ ///
+ public class QueryFSInfoAllocation : QueryFSInformation
+ {
+ public const int Length = 18;
+
+ public uint FileSystemID; // File system identifier, Windows Server will set it to 0
+ public uint SectorUnit; // Number of sectors per allocation unit
+ public uint UnitsTotal; // Total number of allocation units
+ public uint UnitsAvailable; // Total number of available allocation units
+ public ushort Sector; // Number of bytes per sector
+
+ public QueryFSInfoAllocation()
+ {
+ }
+
+ public QueryFSInfoAllocation(byte[] buffer, int offset)
+ {
+ FileSystemID = LittleEndianConverter.ToUInt32(buffer, offset + 0);
+ SectorUnit = LittleEndianConverter.ToUInt32(buffer, offset + 4);
+ UnitsTotal = LittleEndianConverter.ToUInt32(buffer, offset + 8);
+ UnitsAvailable = LittleEndianConverter.ToUInt32(buffer, offset + 12);
+ Sector = LittleEndianConverter.ToUInt16(buffer, offset + 16);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte[] buffer = new byte[Length];
+ LittleEndianWriter.WriteUInt32(buffer, 0, FileSystemID);
+ LittleEndianWriter.WriteUInt32(buffer, 4, SectorUnit);
+ LittleEndianWriter.WriteUInt32(buffer, 8, UnitsTotal);
+ LittleEndianWriter.WriteUInt32(buffer, 12, UnitsAvailable);
+ LittleEndianWriter.WriteUInt16(buffer, 16, Sector);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInfoVolume.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInfoVolume.cs
new file mode 100644
index 0000000..fad2dcd
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInfoVolume.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_VOLUME
+ ///
+ public class QueryFSInfoVolume : QueryFSInformation
+ {
+ public uint VolumeSerialNumber;
+ //byte CharCount;
+ public string VolumeLabel; // SMB_STRING
+
+ public QueryFSInfoVolume()
+ {
+ }
+
+ public QueryFSInfoVolume(bool isUnicode, byte[] buffer, int offset)
+ {
+ VolumeSerialNumber = LittleEndianConverter.ToUInt32(buffer, offset + 0);
+ byte charCount = ByteReader.ReadByte(buffer, offset + 4);
+ VolumeLabel = SMBHelper.ReadSMBString(buffer, offset + 5, isUnicode);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte charCount = (byte)VolumeLabel.Length;
+
+ int length = GetLength(isUnicode);
+ byte[] buffer = new byte[length];
+ LittleEndianWriter.WriteUInt32(buffer, 0, VolumeSerialNumber);
+ ByteWriter.WriteByte(buffer, 4, charCount);
+ SMBHelper.WriteSMBString(buffer, 5, isUnicode, VolumeLabel);
+ return buffer;
+ }
+
+ public int GetLength(bool isUnicode)
+ {
+ int length = 5;
+ if (isUnicode)
+ {
+ length += VolumeLabel.Length * 2;
+ }
+ else
+ {
+ length += VolumeLabel.Length;
+ }
+ return length;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInformation.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInformation.cs
new file mode 100644
index 0000000..61ab50c
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSInformation.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class QueryFSInformation
+ {
+ public abstract byte[] GetBytes(bool isUnicode);
+
+ public static QueryFSInformation GetQueryFSInformation(byte[] buffer, QueryFSInformationLevel informationLevel, bool isUnicode)
+ {
+ switch (informationLevel)
+ {
+ case QueryFSInformationLevel.SMB_INFO_ALLOCATION:
+ return new QueryFSInfoAllocation(buffer, 0);
+ case QueryFSInformationLevel.SMB_INFO_VOLUME:
+ return new QueryFSInfoVolume(isUnicode, buffer, 0);
+ case QueryFSInformationLevel.SMB_QUERY_FS_VOLUME_INFO:
+ return new QueryFSVolumeInfo(buffer, 0);
+ case QueryFSInformationLevel.SMB_QUERY_FS_SIZE_INFO:
+ return new QueryFSSizeInfo(buffer, 0);
+ case QueryFSInformationLevel.SMB_QUERY_FS_DEVICE_INFO:
+ return new QueryFSDeviceInfo(buffer, 0);
+ case QueryFSInformationLevel.SMB_QUERY_FS_ATTRIBUTE_INFO:
+ return new QueryFSAttibuteInfo(buffer, 0);
+ default:
+ throw new InvalidRequestException();
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSSizeInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSSizeInfo.cs
new file mode 100644
index 0000000..3200812
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSSizeInfo.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FS_SIZE_INFO
+ ///
+ public class QueryFSSizeInfo : QueryFSInformation
+ {
+ public const int Length = 24;
+
+ public ulong TotalAllocationUnits;
+ public ulong TotalFreeAllocationUnits;
+ public uint SectorsPerAllocationUnit;
+ public uint BytesPerSector;
+
+ public QueryFSSizeInfo()
+ {
+ }
+
+ public QueryFSSizeInfo(byte[] buffer, int offset)
+ {
+ TotalAllocationUnits = LittleEndianConverter.ToUInt64(buffer, 0);
+ TotalFreeAllocationUnits = LittleEndianConverter.ToUInt64(buffer, 8);
+ SectorsPerAllocationUnit = LittleEndianConverter.ToUInt32(buffer, 16);
+ BytesPerSector = LittleEndianConverter.ToUInt32(buffer, 20);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ byte[] buffer = new byte[Length];
+ LittleEndianWriter.WriteUInt64(buffer, 0, TotalAllocationUnits);
+ LittleEndianWriter.WriteUInt64(buffer, 8, TotalFreeAllocationUnits);
+ LittleEndianWriter.WriteUInt32(buffer, 16, SectorsPerAllocationUnit);
+ LittleEndianWriter.WriteUInt32(buffer, 20, BytesPerSector);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSVolumeInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSVolumeInfo.cs
new file mode 100644
index 0000000..ae24bd9
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryFSInformation/QueryFSVolumeInfo.cs
@@ -0,0 +1,54 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FS_VOLUME_INFO
+ ///
+ public class QueryFSVolumeInfo : QueryFSInformation
+ {
+ public const int FixedLength = 18;
+
+ public DateTime VolumeCreationTime;
+ public uint SerialNumber;
+ //uint VolumeLabelSize;
+ public ushort Reserved;
+ public string VolumeLabel; // Unicode
+
+ public QueryFSVolumeInfo()
+ {
+ VolumeLabel = String.Empty;
+ }
+
+ public QueryFSVolumeInfo(byte[] buffer, int offset)
+ {
+ VolumeCreationTime = SMBHelper.ReadFileTime(buffer, offset + 0);
+ SerialNumber = LittleEndianConverter.ToUInt32(buffer, offset + 8);
+ uint volumeLabelSize = LittleEndianConverter.ToUInt32(buffer, offset + 12);
+ Reserved = LittleEndianConverter.ToUInt16(buffer, offset + 16);
+ VolumeLabel = ByteReader.ReadUTF16String(buffer, offset + 18, (int)volumeLabelSize);
+ }
+
+ public override byte[] GetBytes(bool isUnicode)
+ {
+ uint volumeLabelSize = (uint)(VolumeLabel.Length * 2);
+
+ byte[] buffer = new byte[FixedLength + volumeLabelSize];
+ SMBHelper.WriteFileTime(buffer, 0, VolumeCreationTime);
+ LittleEndianWriter.WriteUInt32(buffer, 8, SerialNumber);
+ LittleEndianWriter.WriteUInt32(buffer, 12, volumeLabelSize);
+ LittleEndianWriter.WriteUInt16(buffer, 16, Reserved);
+ ByteWriter.WriteUTF16String(buffer, 18, VolumeLabel);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/Enums/CompressionFormat.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/Enums/CompressionFormat.cs
new file mode 100644
index 0000000..cb9fa27
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/Enums/CompressionFormat.cs
@@ -0,0 +1,10 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum CompressionFormat : ushort
+ {
+ COMPRESSION_FORMAT_NONE = 0x0000,
+ COMPRESSION_FORMAT_DEFAULT = 0x0001,
+ COMPRESSION_FORMAT_LZNT1 = 0x0002,
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryAllExtendedAttributes.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryAllExtendedAttributes.cs
new file mode 100644
index 0000000..fc2c31e
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryAllExtendedAttributes.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_QUERY_ALL_EAS
+ ///
+ public class QueryAllExtendedAttributes : QueryInformation
+ {
+ public FullExtendedAttributeList ExtendedAttributeList;
+
+ public QueryAllExtendedAttributes()
+ {
+ ExtendedAttributeList = new FullExtendedAttributeList();
+ }
+
+ public QueryAllExtendedAttributes(byte[] buffer, int offset)
+ {
+ ExtendedAttributeList = new FullExtendedAttributeList(buffer, offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ return ExtendedAttributeList.GetBytes();
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_INFO_QUERY_ALL_EAS;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryEASize.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryEASize.cs
new file mode 100644
index 0000000..c8a405d
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryEASize.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_QUERY_EA_SIZE
+ ///
+ public class QueryEASize : QueryInformation
+ {
+ public const int Length = 26;
+
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public uint FileDataSize;
+ public uint AllocationSize;
+ public FileAttributes Attributes;
+ public uint EASize;
+
+ public QueryEASize()
+ {
+ }
+
+ public QueryEASize(byte[] buffer, int offset)
+ {
+ CreationDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastAccessDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastWriteDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ FileDataSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Attributes = (FileAttributes)LittleEndianReader.ReadUInt16(buffer, ref offset);
+ EASize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ int offset = 0;
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, CreationDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastAccessDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastWriteDateTime);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileDataSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)Attributes);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, EASize);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_INFO_QUERY_EA_SIZE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryExtendedAttributesFromList.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryExtendedAttributesFromList.cs
new file mode 100644
index 0000000..166a6a6
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryExtendedAttributesFromList.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_QUERY_EAS_FROM_LIST
+ ///
+ public class QueryExtendedAttributesFromList : QueryInformation
+ {
+ public FullExtendedAttributeList ExtendedAttributeList;
+
+ public QueryExtendedAttributesFromList()
+ {
+ ExtendedAttributeList = new FullExtendedAttributeList();
+ }
+
+ public QueryExtendedAttributesFromList(byte[] buffer, int offset)
+ {
+ ExtendedAttributeList = new FullExtendedAttributeList(buffer, offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ return ExtendedAttributeList.GetBytes();
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileAllInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileAllInfo.cs
new file mode 100644
index 0000000..ba67c07
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileAllInfo.cs
@@ -0,0 +1,91 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_ALL_INFO
+ ///
+ public class QueryFileAllInfo : QueryInformation
+ {
+ public const int FixedLength = 72;
+
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public DateTime LastChangeTime;
+ public ExtendedFileAttributes ExtFileAttributes;
+ public uint Reserved1;
+ public ulong AllocationSize;
+ public ulong EndOfFile;
+ public uint NumberOfLinks;
+ public bool DeletePending;
+ public bool Directory;
+ public ushort Reserved2;
+ public uint EASize;
+ //uint FileNameLength; // In bytes
+ public string FileName; // Unicode
+
+ public QueryFileAllInfo()
+ {
+ }
+
+ public QueryFileAllInfo(byte[] buffer, int offset)
+ {
+ CreationDateTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastAccessDateTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastWriteDateTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastChangeTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Reserved1 = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ EndOfFile = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ NumberOfLinks = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ DeletePending = (ByteReader.ReadByte(buffer, ref offset) > 0);
+ Directory = (ByteReader.ReadByte(buffer, ref offset) > 0);
+ Reserved2 = LittleEndianReader.ReadUInt16(buffer, ref offset);
+ EASize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ uint fileNameLength = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileName = ByteReader.ReadUTF16String(buffer, ref offset, (int)(fileNameLength / 2));
+ }
+
+ public override byte[] GetBytes()
+ {
+ uint fileNameLength = (uint)(FileName.Length * 2);
+ byte[] buffer = new byte[FixedLength + fileNameLength];
+ int offset = 0;
+ SMBHelper.WriteFileTime(buffer, ref offset, CreationDateTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastAccessDateTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastWriteDateTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastChangeTime);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, Reserved1);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, EndOfFile);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NumberOfLinks);
+ ByteWriter.WriteByte(buffer, ref offset, Convert.ToByte(DeletePending));
+ ByteWriter.WriteByte(buffer, ref offset, Convert.ToByte(Directory));
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, Reserved2);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, EASize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, fileNameLength);
+ ByteWriter.WriteUTF16String(buffer, ref offset, FileName);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileAltNameInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileAltNameInfo.cs
new file mode 100644
index 0000000..8f8ebf5
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileAltNameInfo.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_ALT_NAME_INFO
+ ///
+ public class QueryFileAltNameInfo : QueryInformation
+ {
+ //uint FileNameLength; // In bytes
+ public string FileName; // Unicode, 8.3 name of the file
+
+ public QueryFileAltNameInfo()
+ {
+ }
+
+ public QueryFileAltNameInfo(byte[] buffer, int offset)
+ {
+ uint fileNameLength = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ FileName = ByteReader.ReadUTF16String(buffer, ref offset, (int)(fileNameLength / 2));
+ }
+
+ public override byte[] GetBytes()
+ {
+ uint fileNameLength = (uint)(FileName.Length * 2);
+ byte[] buffer = new byte[4 + fileNameLength];
+ LittleEndianWriter.WriteUInt32(buffer, 0, fileNameLength);
+ ByteWriter.WriteUTF16String(buffer, 4, FileName);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_ALT_NAME_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileBasicInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileBasicInfo.cs
new file mode 100644
index 0000000..2c6b25c
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileBasicInfo.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_BASIC_INFO
+ ///
+ public class QueryFileBasicInfo : QueryInformation
+ {
+ public const int Length = 40;
+
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public DateTime LastChangeTime;
+ public ExtendedFileAttributes ExtFileAttributes;
+ public uint Reserved;
+
+ public QueryFileBasicInfo()
+ {
+ }
+
+ public QueryFileBasicInfo(byte[] buffer, int offset)
+ {
+ CreationDateTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastAccessDateTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastWriteDateTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ LastChangeTime = SMBHelper.ReadFileTime(buffer, ref offset);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Reserved = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ int offset = 0;
+ SMBHelper.WriteFileTime(buffer, ref offset, CreationDateTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastAccessDateTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastWriteDateTime);
+ SMBHelper.WriteFileTime(buffer, ref offset, LastChangeTime);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, Reserved);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_BASIC_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileCompressionInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileCompressionInfo.cs
new file mode 100644
index 0000000..61478a5
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileCompressionInfo.cs
@@ -0,0 +1,64 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_COMPRESSION_INFO
+ ///
+ public class QueryFileCompressionInfo : QueryInformation
+ {
+ public const int Length = 16;
+
+ public ulong CompressedFileSize;
+ public CompressionFormat CompressionFormat;
+ public byte CompressionUnitShift;
+ public byte ChunkShift;
+ public byte ClusterShift;
+ public byte[] Reserved; // 3 bytes
+
+ public QueryFileCompressionInfo()
+ {
+ Reserved = new byte[3];
+ }
+
+ public QueryFileCompressionInfo(byte[] buffer, int offset)
+ {
+ CompressedFileSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ CompressionFormat = (CompressionFormat)LittleEndianReader.ReadUInt16(buffer, ref offset);
+ CompressionUnitShift = ByteReader.ReadByte(buffer, ref offset);
+ ChunkShift = ByteReader.ReadByte(buffer, ref offset);
+ ClusterShift = ByteReader.ReadByte(buffer, ref offset);
+ Reserved = ByteReader.ReadBytes(buffer, ref offset, 3);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ int offset = 0;
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, CompressedFileSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)CompressionFormat);
+ ByteWriter.WriteByte(buffer, ref offset, CompressionUnitShift);
+ ByteWriter.WriteByte(buffer, ref offset, ChunkShift);
+ ByteWriter.WriteByte(buffer, ref offset, ClusterShift);
+ ByteWriter.WriteBytes(buffer, ref offset, Reserved, 3);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_COMPRESSION_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileExtendedAttributeInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileExtendedAttributeInfo.cs
new file mode 100644
index 0000000..f7a6013
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileExtendedAttributeInfo.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_EA_INFO
+ ///
+ public class QueryFileExtendedAttributeInfo : QueryInformation
+ {
+ public uint EASize;
+
+ public QueryFileExtendedAttributeInfo()
+ {
+ }
+
+ public QueryFileExtendedAttributeInfo(byte[] buffer, int offset)
+ {
+ EASize = LittleEndianConverter.ToUInt32(buffer, offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ return LittleEndianConverter.GetBytes(EASize);
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_EA_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileNameInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileNameInfo.cs
new file mode 100644
index 0000000..ff544ff
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileNameInfo.cs
@@ -0,0 +1,49 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_NAME_INFO
+ ///
+ public class QueryFileNameInfo : QueryInformation
+ {
+ //uint FileNameLength; // In bytes
+ public string FileName; // Unicode
+
+ public QueryFileNameInfo()
+ {
+ }
+
+ public QueryFileNameInfo(byte[] buffer, int offset)
+ {
+ uint fileNameLength = LittleEndianConverter.ToUInt32(buffer, 0);
+ FileName = ByteReader.ReadUTF16String(buffer, 4, (int)(fileNameLength / 2));
+ }
+
+ public override byte[] GetBytes()
+ {
+ uint fileNameLength = (uint)(FileName.Length * 2);
+ byte[] buffer = new byte[4 + fileNameLength];
+ LittleEndianWriter.WriteUInt32(buffer, 0, fileNameLength);
+ ByteWriter.WriteUTF16String(buffer, 4, FileName);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_NAME_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileStandardInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileStandardInfo.cs
new file mode 100644
index 0000000..afdde93
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileStandardInfo.cs
@@ -0,0 +1,60 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_STANDARD_INFO
+ ///
+ public class QueryFileStandardInfo : QueryInformation
+ {
+ public const int Length = 22;
+
+ public ulong AllocationSize;
+ public ulong EndOfFile;
+ public uint NumberOfLinks;
+ public bool DeletePending;
+ public bool Directory;
+
+ public QueryFileStandardInfo()
+ {
+ }
+
+ public QueryFileStandardInfo(byte[] buffer, int offset)
+ {
+ AllocationSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ EndOfFile = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ NumberOfLinks = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ DeletePending = (ByteReader.ReadByte(buffer, ref offset) > 0);
+ Directory = (ByteReader.ReadByte(buffer, ref offset) > 0);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ int offset = 0;
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, EndOfFile);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NumberOfLinks);
+ ByteWriter.WriteByte(buffer, ref offset, Convert.ToByte(DeletePending));
+ ByteWriter.WriteByte(buffer, ref offset, Convert.ToByte(Directory));
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_STANDARD_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileStreamInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileStreamInfo.cs
new file mode 100644
index 0000000..4a13013
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryFileStreamInfo.cs
@@ -0,0 +1,61 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_QUERY_FILE_STREAM_INFO
+ ///
+ public class QueryFileStreamInfo : QueryInformation
+ {
+ public const int FixedLength = 24;
+
+ public uint NextEntryOffset;
+ //uint StreamNameLength; // In bytes
+ public ulong StreamSize;
+ public ulong StreamAllocationSize;
+ public string StreamName; // Unicode
+
+ public QueryFileStreamInfo()
+ {
+ }
+
+ public QueryFileStreamInfo(byte[] buffer, int offset)
+ {
+ NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ uint streamNameLength = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ StreamSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ StreamAllocationSize = LittleEndianReader.ReadUInt64(buffer, ref offset);
+ StreamName = ByteReader.ReadUTF16String(buffer, ref offset, (int)(streamNameLength / 2));
+ }
+
+ public override byte[] GetBytes()
+ {
+ uint streamNameLength = (uint)(StreamName.Length * 2);
+ byte[] buffer = new byte[FixedLength + streamNameLength];
+ int offset = 0;
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, NextEntryOffset);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, streamNameLength);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, StreamSize);
+ LittleEndianWriter.WriteUInt64(buffer, ref offset, StreamAllocationSize);
+ ByteWriter.WriteUTF16String(buffer, ref offset, StreamName);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_QUERY_FILE_STREAM_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryInfoStandard.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryInfoStandard.cs
new file mode 100644
index 0000000..19c2904
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryInfoStandard.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_STANDARD
+ ///
+ public class QueryInfoStandard : QueryInformation
+ {
+ public const int Length = 22;
+
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public uint FileDataSize;
+ public uint AllocationSize;
+ public FileAttributes Attributes;
+
+ public QueryInfoStandard()
+ {
+ }
+
+ public QueryInfoStandard(byte[] buffer, int offset)
+ {
+ CreationDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastAccessDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ LastWriteDateTime = SMBHelper.ReadSMBDateTime(buffer, ref offset);
+ FileDataSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ AllocationSize = LittleEndianReader.ReadUInt32(buffer, ref offset);
+ Attributes = (FileAttributes)LittleEndianReader.ReadUInt16(buffer, ref offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ int offset = 0;
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, CreationDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastAccessDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, ref offset, LastWriteDateTime);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, FileDataSize);
+ LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationSize);
+ LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)Attributes);
+ return buffer;
+ }
+
+ public override QueryInformationLevel InformationLevel
+ {
+ get
+ {
+ return QueryInformationLevel.SMB_INFO_STANDARD;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryInformation.cs b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryInformation.cs
new file mode 100644
index 0000000..8dd0cd7
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/QueryInformation/QueryInformation.cs
@@ -0,0 +1,59 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class QueryInformation
+ {
+ public abstract byte[] GetBytes();
+
+ public abstract QueryInformationLevel InformationLevel
+ {
+ get;
+ }
+
+ ///
+ /// SMB_INFO_IS_NAME_VALID will return null
+ ///
+ public static QueryInformation GetQueryInformation(byte[] buffer, QueryInformationLevel informationLevel)
+ {
+ switch (informationLevel)
+ {
+ case QueryInformationLevel.SMB_INFO_STANDARD:
+ return new QueryInfoStandard(buffer, 0);
+ case QueryInformationLevel.SMB_INFO_QUERY_EA_SIZE:
+ return new QueryEASize(buffer, 0);
+ case QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST:
+ return new QueryExtendedAttributesFromList(buffer, 0);
+ case QueryInformationLevel.SMB_INFO_QUERY_ALL_EAS:
+ return new QueryAllExtendedAttributes(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_BASIC_INFO:
+ return new QueryFileBasicInfo(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_STANDARD_INFO:
+ return new QueryFileStandardInfo(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_EA_INFO:
+ return new QueryFileExtendedAttributeInfo(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_NAME_INFO:
+ return new QueryFileNameInfo(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO:
+ return new QueryFileAllInfo(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_ALT_NAME_INFO:
+ return new QueryFileAltNameInfo(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_STREAM_INFO:
+ return new QueryFileStreamInfo(buffer, 0);
+ case QueryInformationLevel.SMB_QUERY_FILE_COMPRESSION_INFO:
+ return new QueryFileCompressionInfo(buffer, 0);
+ default:
+ throw new InvalidRequestException();
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetExtendedAttributes.cs b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetExtendedAttributes.cs
new file mode 100644
index 0000000..b9c150b
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetExtendedAttributes.cs
@@ -0,0 +1,40 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_SET_EAS
+ ///
+ public class SetExtendedAttributes : SetInformation
+ {
+ public FullExtendedAttributeList ExtendedAttributeList;
+
+ public SetExtendedAttributes()
+ {
+ ExtendedAttributeList = new FullExtendedAttributeList();
+ }
+
+ public SetExtendedAttributes(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public SetExtendedAttributes(byte[] buffer, int offset)
+ {
+ ExtendedAttributeList = new FullExtendedAttributeList(buffer, offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ return ExtendedAttributeList.GetBytes();
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileAllocationInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileAllocationInfo.cs
new file mode 100644
index 0000000..82a62a8
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileAllocationInfo.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_SET_FILE_ALLOCATION_INFO
+ ///
+ public class SetFileAllocationInfo : SetInformation
+ {
+ public const int Length = 8;
+
+ public ulong AllocationSize;
+
+ public SetFileAllocationInfo()
+ {
+ }
+
+ public SetFileAllocationInfo(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public SetFileAllocationInfo(byte[] buffer, int offset)
+ {
+ AllocationSize = LittleEndianConverter.ToUInt64(buffer, offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ LittleEndianWriter.WriteUInt64(buffer, 0, AllocationSize);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileBasicInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileBasicInfo.cs
new file mode 100644
index 0000000..04b2840
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileBasicInfo.cs
@@ -0,0 +1,58 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_SET_FILE_BASIC_INFO
+ ///
+ public class SetFileBasicInfo : SetInformation
+ {
+ public const int Length = 40;
+
+ public DateTime CreationTime;
+ public DateTime LastAccessTime;
+ public DateTime LastWriteTime;
+ public DateTime LastChangeTime;
+ public ExtendedFileAttributes ExtFileAttributes;
+ public uint Reserved;
+
+ public SetFileBasicInfo()
+ {
+ }
+
+ public SetFileBasicInfo(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public SetFileBasicInfo(byte[] buffer, int offset)
+ {
+ CreationTime = SMBHelper.ReadSetFileTime(buffer, offset + 0);
+ LastAccessTime = SMBHelper.ReadSetFileTime(buffer, offset + 8);
+ LastWriteTime = SMBHelper.ReadSetFileTime(buffer, offset + 16);
+ LastChangeTime = SMBHelper.ReadSetFileTime(buffer, offset + 24);
+ ExtFileAttributes = (ExtendedFileAttributes)LittleEndianConverter.ToUInt32(buffer, offset + 32);
+ Reserved = LittleEndianConverter.ToUInt32(buffer, offset + 36);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ SMBHelper.WriteFileTime(buffer, 0, CreationTime);
+ SMBHelper.WriteFileTime(buffer, 8, LastAccessTime);
+ SMBHelper.WriteFileTime(buffer, 16, LastWriteTime);
+ SMBHelper.WriteFileTime(buffer, 24, LastChangeTime);
+ LittleEndianWriter.WriteUInt32(buffer, 32, (uint)ExtFileAttributes);
+ LittleEndianWriter.WriteUInt32(buffer, 36, Reserved);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileDispositionInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileDispositionInfo.cs
new file mode 100644
index 0000000..2a2e44a
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileDispositionInfo.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_SET_FILE_DISPOSITION_INFO
+ ///
+ public class SetFileDispositionInfo : SetInformation
+ {
+ public const int Length = 1;
+ ///
+ /// Indicate that a file SHOULD be deleted when it is closed.
+ ///
+ public bool DeletePending;
+
+ public SetFileDispositionInfo()
+ {
+ }
+
+ public SetFileDispositionInfo(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public SetFileDispositionInfo(byte[] buffer, int offset)
+ {
+ DeletePending = (ByteReader.ReadByte(buffer, ref offset) > 0);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ ByteWriter.WriteByte(buffer, 0, Convert.ToByte(DeletePending));
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileEndOfFileInfo.cs b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileEndOfFileInfo.cs
new file mode 100644
index 0000000..ea05df0
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetFileEndOfFileInfo.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_SET_FILE_END_OF_FILE_INFO
+ ///
+ public class SetFileEndOfFileInfo : SetInformation
+ {
+ public const int Length = 8;
+
+ public ulong EndOfFile;
+
+ public SetFileEndOfFileInfo()
+ {
+ }
+
+ public SetFileEndOfFileInfo(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public SetFileEndOfFileInfo(byte[] buffer, int offset)
+ {
+ EndOfFile = LittleEndianConverter.ToUInt64(buffer, offset);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ LittleEndianWriter.WriteUInt64(buffer, 0, EndOfFile);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetInfoStandard.cs b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetInfoStandard.cs
new file mode 100644
index 0000000..8d8da61
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetInfoStandard.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// SMB_INFO_STANDARD
+ ///
+ public class SetInfoStandard : SetInformation
+ {
+ public const int Length = 22;
+
+ public DateTime CreationDateTime;
+ public DateTime LastAccessDateTime;
+ public DateTime LastWriteDateTime;
+ public byte[] Reserved; // 10 bytes
+
+ public SetInfoStandard()
+ {
+ Reserved = new byte[10];
+ }
+
+ public SetInfoStandard(byte[] buffer) : this(buffer, 0)
+ {
+ }
+
+ public SetInfoStandard(byte[] buffer, int offset)
+ {
+ CreationDateTime = SMBHelper.ReadSMBDateTime(buffer, offset + 0);
+ LastAccessDateTime = SMBHelper.ReadSMBDateTime(buffer, offset + 4);
+ LastWriteDateTime = SMBHelper.ReadSMBDateTime(buffer, offset + 8);
+ Reserved = ByteReader.ReadBytes(buffer, offset + 12, 10);
+ }
+
+ public override byte[] GetBytes()
+ {
+ byte[] buffer = new byte[Length];
+ SMBHelper.WriteSMBDateTime(buffer, 0, CreationDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, 4, LastAccessDateTime);
+ SMBHelper.WriteSMBDateTime(buffer, 8, LastWriteDateTime);
+ ByteWriter.WriteBytes(buffer, 12, Reserved);
+ return buffer;
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetInformation.cs b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetInformation.cs
new file mode 100644
index 0000000..dc34f37
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/SetInformation/SetInformation.cs
@@ -0,0 +1,39 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class SetInformation
+ {
+ public abstract byte[] GetBytes();
+
+ public static SetInformation GetSetInformation(byte[] buffer, SetInformationLevel informationLevel)
+ {
+ switch (informationLevel)
+ {
+ case SetInformationLevel.SMB_INFO_STANDARD:
+ return new SetInfoStandard(buffer);
+ case SetInformationLevel.SMB_INFO_SET_EAS:
+ return new SetExtendedAttributes(buffer);
+ case SetInformationLevel.SMB_SET_FILE_BASIC_INFO:
+ return new SetFileBasicInfo(buffer);
+ case SetInformationLevel.SMB_SET_FILE_DISPOSITION_INFO:
+ return new SetFileDispositionInfo(buffer);
+ case SetInformationLevel.SMB_SET_FILE_ALLOCATION_INFO:
+ return new SetFileAllocationInfo(buffer);
+ case SetInformationLevel.SMB_SET_FILE_END_OF_FILE_INFO:
+ return new SetFileEndOfFileInfo(buffer);
+ default:
+ throw new UnsupportedInformationLevelException();
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryRequest.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryRequest.cs
new file mode 100644
index 0000000..bd670dd
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryRequest.cs
@@ -0,0 +1,63 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_CREATE_DIRECTORY Request
+ ///
+ public class Transaction2CreateDirectoryRequest : Transaction2Subcommand
+ {
+ // Parameters
+ public uint Reserved;
+ public string DirectoryName; // SMB_STRING
+ // Data
+ public FullExtendedAttributeList ExtendedAttributeList;
+
+ public Transaction2CreateDirectoryRequest() : base()
+ {}
+
+ public Transaction2CreateDirectoryRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ Reserved = LittleEndianConverter.ToUInt32(parameters, 0);
+ DirectoryName = SMBHelper.ReadSMBString(parameters, 4, isUnicode);
+ ExtendedAttributeList = new FullExtendedAttributeList(data);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ int length = 4;
+ length += isUnicode ? DirectoryName.Length * 2 + 2 : DirectoryName.Length + 1 + 1;
+ byte[] parameters = new byte[length];
+ LittleEndianWriter.WriteUInt32(parameters, 0, Reserved);
+ SMBHelper.WriteSMBString(parameters, 4, isUnicode, DirectoryName);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return ExtendedAttributeList.GetBytes();
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_CREATE_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryResponse.cs
new file mode 100644
index 0000000..64b9663
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2CreateDirectoryResponse.cs
@@ -0,0 +1,47 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_CREATE_DIRECTORY Response
+ ///
+ public class Transaction2CreateDirectoryResponse : Transaction2Subcommand
+ {
+ // Parameters:
+ public ushort EaErrorOffset;
+
+ public Transaction2CreateDirectoryResponse() : base()
+ {
+
+ }
+
+ public Transaction2CreateDirectoryResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base()
+ {
+ EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[2];
+ LittleEndianWriter.WriteUInt16(parameters, 0, EaErrorOffset);
+ return parameters;
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_CREATE_DIRECTORY;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Request.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Request.cs
new file mode 100644
index 0000000..ac7c968
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Request.cs
@@ -0,0 +1,97 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_FIND_FIRST2 Request
+ ///
+ public class Transaction2FindFirst2Request : Transaction2Subcommand
+ {
+ // Parameters:
+ public FileAttributes SearchAttributes;
+ public ushort SearchCount;
+ public FindFlags Flags;
+ public FindInformationLevel InformationLevel;
+ public SearchStorageType SearchStorageType;
+ public string FileName; // SMB_STRING
+ // Data:
+ FullExtendedAttributeList GetExtendedAttributeList; // Used with FindInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST
+
+ public Transaction2FindFirst2Request() : base()
+ {
+ GetExtendedAttributeList = new FullExtendedAttributeList();
+ }
+
+ public Transaction2FindFirst2Request(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ SearchAttributes = (FileAttributes)LittleEndianConverter.ToUInt16(parameters, 0);
+ SearchCount = LittleEndianConverter.ToUInt16(parameters, 2);
+ Flags = (FindFlags)LittleEndianConverter.ToUInt16(parameters, 4);
+ InformationLevel = (FindInformationLevel)LittleEndianConverter.ToUInt16(parameters, 6);
+ SearchStorageType = (SearchStorageType)LittleEndianConverter.ToUInt32(parameters, 8);
+ FileName = SMBHelper.ReadSMBString(parameters, 12, isUnicode);
+
+ if (InformationLevel == FindInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
+ {
+ GetExtendedAttributeList = new FullExtendedAttributeList(data, 0);
+ }
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ int length = 12;
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+
+ byte[] parameters = new byte[length];
+ LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)SearchAttributes);
+ LittleEndianWriter.WriteUInt16(parameters, 2, SearchCount);
+ LittleEndianWriter.WriteUInt16(parameters, 4, (ushort)Flags);
+ LittleEndianWriter.WriteUInt16(parameters, 6, (ushort)InformationLevel);
+ LittleEndianWriter.WriteUInt32(parameters, 8, (uint)SearchStorageType);
+ SMBHelper.WriteSMBString(parameters, 12, isUnicode, FileName);
+
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ if (InformationLevel == FindInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
+ {
+ return GetExtendedAttributeList.GetBytes();
+ }
+ else
+ {
+ return new byte[0];
+ }
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_FIND_FIRST2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Response.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Response.cs
new file mode 100644
index 0000000..7514a2a
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindFirst2Response.cs
@@ -0,0 +1,71 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_FIND_FIRST2 Response
+ ///
+ public class Transaction2FindFirst2Response : Transaction2Subcommand
+ {
+ public const int ParametersLength = 10;
+ // Parameters:
+ public ushort SID; // Search handle
+ public ushort SearchCount;
+ public bool EndOfSearch;
+ public ushort EaErrorOffset;
+ public ushort LastNameOffset;
+ // Data:
+ public FindInformation FindInfoList;
+
+ public Transaction2FindFirst2Response() : base()
+ {
+ FindInfoList = new FindInformation();
+ }
+
+ public Transaction2FindFirst2Response(byte[] parameters, byte[] data, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys) : base()
+ {
+ SID = LittleEndianConverter.ToUInt16(parameters, 0);
+ SearchCount = LittleEndianConverter.ToUInt16(parameters, 2);
+ EndOfSearch = LittleEndianConverter.ToUInt16(parameters, 4) != 0;
+ EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 6);
+ LastNameOffset = LittleEndianConverter.ToUInt16(parameters, 8);
+
+ FindInfoList = new FindInformation(data, informationLevel, isUnicode, returnResumeKeys);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ SearchCount = (ushort)FindInfoList.Count;
+
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, SID);
+ LittleEndianWriter.WriteUInt16(parameters, 2, SearchCount);
+ LittleEndianWriter.WriteUInt16(parameters, 4, Convert.ToUInt16(EndOfSearch));
+ LittleEndianWriter.WriteUInt16(parameters, 6, EaErrorOffset);
+ LittleEndianWriter.WriteUInt16(parameters, 8, LastNameOffset);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return FindInfoList.GetBytes(isUnicode);
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_FIND_FIRST2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Request.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Request.cs
new file mode 100644
index 0000000..aaa3db2
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Request.cs
@@ -0,0 +1,77 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_FIND_NEXT2 Request
+ ///
+ public class Transaction2FindNext2Request : Transaction2Subcommand
+ {
+ // Parameters:
+ public ushort SID; // Search handle
+ public ushort SearchCount;
+ public FindInformationLevel InformationLevel;
+ public uint ResumeKey;
+ public FindFlags Flags;
+ public string FileName; // SMB_STRING
+
+ public Transaction2FindNext2Request() : base()
+ {
+ }
+
+ public Transaction2FindNext2Request(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ SID = LittleEndianConverter.ToUInt16(parameters, 0);
+ SearchCount = LittleEndianConverter.ToUInt16(parameters, 2);
+ InformationLevel = (FindInformationLevel)LittleEndianConverter.ToUInt16(parameters, 4);
+ ResumeKey = LittleEndianConverter.ToUInt32(parameters, 6);
+ Flags = (FindFlags)LittleEndianConverter.ToUInt16(parameters, 10);
+ FileName = SMBHelper.ReadSMBString(parameters, 12, isUnicode);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ int length = 12;
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+
+ byte[] parameters = new byte[length];
+ LittleEndianWriter.WriteUInt16(parameters, 0, SID);
+ LittleEndianWriter.WriteUInt16(parameters, 2, SearchCount);
+ LittleEndianWriter.WriteUInt16(parameters, 4, (ushort)InformationLevel);
+ LittleEndianWriter.WriteUInt32(parameters, 6, ResumeKey);
+ LittleEndianWriter.WriteUInt16(parameters, 10, (ushort)Flags);
+ SMBHelper.WriteSMBString(parameters, 12, isUnicode, FileName);
+
+ return parameters;
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_FIND_NEXT2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Response.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Response.cs
new file mode 100644
index 0000000..1c19b52
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2FindNext2Response.cs
@@ -0,0 +1,66 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_FIND_NEXT2 Response
+ ///
+ public class Transaction2FindNext2Response : Transaction2Subcommand
+ {
+ public const int ParametersLength = 8;
+ // Parameters:
+ public ushort SearchCount;
+ public bool EndOfSearch;
+ public ushort EaErrorOffset;
+ public ushort LastNameOffset;
+ // Data:
+ public FindInformation FindInfoList;
+
+ public Transaction2FindNext2Response() : base()
+ {
+ FindInfoList = new FindInformation();
+ }
+
+ public Transaction2FindNext2Response(byte[] parameters, byte[] data, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys) : base()
+ {
+ SearchCount = LittleEndianConverter.ToUInt16(parameters, 0);
+ EndOfSearch = LittleEndianConverter.ToUInt16(parameters, 2) != 0;
+ EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 4);
+ LastNameOffset = LittleEndianConverter.ToUInt16(parameters, 6);
+
+ FindInfoList = new FindInformation(data, informationLevel, isUnicode, returnResumeKeys);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, SearchCount);
+ LittleEndianWriter.WriteUInt16(parameters, 2, Convert.ToUInt16(EndOfSearch));
+ LittleEndianWriter.WriteUInt16(parameters, 4, EaErrorOffset);
+ LittleEndianWriter.WriteUInt16(parameters, 6, LastNameOffset);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return FindInfoList.GetBytes(isUnicode);
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_FIND_NEXT2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2GetDfsReferralRequest.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2GetDfsReferralRequest.cs
new file mode 100644
index 0000000..fc904f8
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2GetDfsReferralRequest.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_GET_DFS_REFERRAL Request
+ ///
+ public class Transaction2GetDfsReferralRequest : Transaction2Subcommand
+ {
+ // Parameters:
+ RequestGetDfsReferral ReferralRequest;
+
+ public Transaction2GetDfsReferralRequest() : base()
+ {}
+
+ public Transaction2GetDfsReferralRequest(byte[] parameters, byte[] data) : base()
+ {
+ ReferralRequest = new RequestGetDfsReferral(parameters);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ return ReferralRequest.GetBytes();
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_GET_DFS_REFERRAL;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2GetDfsReferralResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2GetDfsReferralResponse.cs
new file mode 100644
index 0000000..e1627c5
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2GetDfsReferralResponse.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_GET_DFS_REFERRAL Response
+ /// We will always return STATUS_NO_SUCH_DEVICE
+ ///
+ public class Transaction2GetDfsReferralResponse : Transaction2Subcommand
+ {
+ // Data:
+ ResponseGetDfsReferral ReferralResponse;
+
+ public Transaction2GetDfsReferralResponse() : base()
+ {
+ }
+
+ public Transaction2GetDfsReferralResponse(byte[] parameters, byte[] data) : base()
+ {
+ ReferralResponse = new ResponseGetDfsReferral(data);
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return ReferralResponse.GetBytes();
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_GET_DFS_REFERRAL;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Open2Request.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Open2Request.cs
new file mode 100644
index 0000000..391500d
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Open2Request.cs
@@ -0,0 +1,96 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_OPEN2 Request
+ ///
+ public class Transaction2Open2Request : Transaction2Subcommand
+ {
+ // Parameters:
+ public Open2Flags Flags;
+ public AccessModeOptions AccessMode;
+ public ushort Reserved1;
+ public FileAttributes FileAttributes;
+ public DateTime CreationTime; // UTIME (seconds since Jan 1, 1970)
+ public OpenMode OpenMode;
+ public uint AllocationSize;
+ public byte[] Reserved; // 10 bytes
+ public string FileName; // SMB_STRING
+ // Data:
+ public FullExtendedAttributeList ExtendedAttributeList;
+
+ public Transaction2Open2Request() : base()
+ {
+ CreationTime = SMBHelper.UTimeNotSpecified;
+ Reserved = new byte[10];
+ }
+
+ public Transaction2Open2Request(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ Flags = (Open2Flags)LittleEndianConverter.ToUInt16(parameters, 0);
+ AccessMode = new AccessModeOptions(parameters, 2);
+ Reserved1 = LittleEndianConverter.ToUInt16(parameters, 4);
+ FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt16(parameters, 6);
+ CreationTime = SMBHelper.ReadUTime(parameters, 8);
+ OpenMode = new OpenMode(parameters, 12);
+ AllocationSize = LittleEndianConverter.ToUInt32(parameters, 14);
+ Reserved = ByteReader.ReadBytes(parameters, 18, 10);
+ FileName = SMBHelper.ReadSMBString(parameters, 28, isUnicode);
+
+ ExtendedAttributeList = new FullExtendedAttributeList(data, 0);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ int length = 28;
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+
+ byte[] parameters = new byte[length];
+ LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)Flags);
+ AccessMode.WriteBytes(parameters, 2);
+ LittleEndianWriter.WriteUInt16(parameters, 4, Reserved1);
+ LittleEndianWriter.WriteUInt16(parameters, 6, (ushort)FileAttributes);
+ SMBHelper.WriteUTime(parameters, 8, CreationTime);
+ OpenMode.WriteBytes(parameters, 12);
+ LittleEndianWriter.WriteUInt32(parameters, 14, AllocationSize);
+ ByteWriter.WriteBytes(parameters, 18, Reserved, 10);
+ SMBHelper.WriteSMBString(parameters, 28, isUnicode, FileName);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return ExtendedAttributeList.GetBytes();
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_OPEN2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Open2Response.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Open2Response.cs
new file mode 100644
index 0000000..68a71b9
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Open2Response.cs
@@ -0,0 +1,78 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_OPEN2 Response
+ ///
+ public class Transaction2Open2Response : Transaction2Subcommand
+ {
+ public int ParametersLength = 30;
+ // Parameters
+ public ushort FID;
+ public FileAttributes FileAttributes;
+ public DateTime CreationTime;
+ public uint FileDataSize;
+ public AccessModeOptions AccessMode;
+ public ResourceType ResourceType;
+ public NamedPipeStatus NMPipeStatus;
+ public ActionTaken ActionTaken;
+ public uint Reserved;
+ public ushort ExtendedAttributeErrorOffset;
+ public uint ExtendedAttributeLength;
+
+ public Transaction2Open2Response() : base()
+ {
+ CreationTime = SMBHelper.FileTimeNotSpecified;
+ }
+
+ public Transaction2Open2Response(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(parameters, 0);
+ FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt16(parameters, 2);
+ CreationTime = SMBHelper.ReadUTime(parameters, 4);
+ FileDataSize = LittleEndianConverter.ToUInt32(parameters, 8);
+ AccessMode = new AccessModeOptions(parameters, 12);
+ ResourceType = (ResourceType)LittleEndianConverter.ToUInt16(parameters, 14);
+ NMPipeStatus = new NamedPipeStatus(parameters, 16);
+ ActionTaken = new ActionTaken(parameters, 18);
+ Reserved = LittleEndianConverter.ToUInt32(parameters, 20);
+ ExtendedAttributeErrorOffset = LittleEndianConverter.ToUInt16(parameters, 24);
+ ExtendedAttributeLength = LittleEndianConverter.ToUInt32(parameters, 26);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, FID);
+ LittleEndianWriter.WriteUInt16(parameters, 2, (ushort)FileAttributes);
+ SMBHelper.WriteUTime(parameters, 4, CreationTime);
+ LittleEndianWriter.WriteUInt32(parameters, 8, FileDataSize);
+ AccessMode.WriteBytes(parameters, 12);
+ LittleEndianWriter.WriteUInt16(parameters, 14, (ushort)ResourceType);
+ NMPipeStatus.WriteBytes(parameters, 16);
+ ActionTaken.WriteBytes(parameters, 18);
+ LittleEndianWriter.WriteUInt32(parameters, 20, Reserved);
+ LittleEndianWriter.WriteUInt16(parameters, 24, ExtendedAttributeErrorOffset);
+ LittleEndianWriter.WriteUInt32(parameters, 26, ExtendedAttributeLength);
+ return parameters;
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_OPEN2;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationRequest.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationRequest.cs
new file mode 100644
index 0000000..37394fe
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationRequest.cs
@@ -0,0 +1,53 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_QUERY_FS_INFORMATION Request
+ ///
+ public class Transaction2QueryFSInformationRequest : Transaction2Subcommand
+ {
+ public int ParametersLength = 2;
+
+ public QueryFSInformationLevel InformationLevel;
+
+ public Transaction2QueryFSInformationRequest() : base()
+ {
+
+ }
+
+ public Transaction2QueryFSInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ InformationLevel = (QueryFSInformationLevel)LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)InformationLevel);
+ return parameters;
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_QUERY_FS_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationResponse.cs
new file mode 100644
index 0000000..0d328fa
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFSInformationResponse.cs
@@ -0,0 +1,45 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_QUERY_FS_INFORMATION Response
+ ///
+ public class Transaction2QueryFSInformationResponse : Transaction2Subcommand
+ {
+ // Data:
+ public QueryFSInformation QueryFSInfo;
+
+ public Transaction2QueryFSInformationResponse() : base()
+ {
+
+ }
+
+ public Transaction2QueryFSInformationResponse(byte[] parameters, byte[] data, QueryFSInformationLevel informationLevel, bool isUnicode) : base()
+ {
+ QueryFSInfo = QueryFSInformation.GetQueryFSInformation(data, informationLevel, isUnicode);
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return QueryFSInfo.GetBytes(isUnicode);
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_QUERY_FS_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationRequest.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationRequest.cs
new file mode 100644
index 0000000..3c0e820
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationRequest.cs
@@ -0,0 +1,75 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_QUERY_FILE_INFORMATION Request
+ ///
+ public class Transaction2QueryFileInformationRequest : Transaction2Subcommand
+ {
+ public int ParametersLength = 4;
+ // Parameters:
+ public ushort FID;
+ public QueryInformationLevel InformationLevel;
+ // Data:
+ FullExtendedAttributeList GetExtendedAttributeList; // Used with QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST
+
+ public Transaction2QueryFileInformationRequest() : base()
+ {
+ GetExtendedAttributeList = new FullExtendedAttributeList();
+ }
+
+ public Transaction2QueryFileInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(parameters, 0);
+ InformationLevel = (QueryInformationLevel)LittleEndianConverter.ToUInt16(parameters, 2);
+
+ if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
+ {
+ GetExtendedAttributeList = new FullExtendedAttributeList(data, 0);
+ }
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, FID);
+ LittleEndianWriter.WriteUInt16(parameters, 2, (ushort)InformationLevel);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
+ {
+ return GetExtendedAttributeList.GetBytes();
+ }
+ else
+ {
+ return new byte[0];
+ }
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_QUERY_FILE_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationResponse.cs
new file mode 100644
index 0000000..de4c8e2
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryFileInformationResponse.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_QUERY_FILE_INFORMATION Response
+ /// 0x0100)
+ {
+ EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+ QueryInfo = QueryInformation.GetQueryInformation(data, informationLevel);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ if ((ushort)QueryInfo.InformationLevel > 0x0100)
+ {
+ byte[] parameters = new byte[2];
+ LittleEndianWriter.WriteUInt16(parameters, 0, EaErrorOffset);
+ return parameters;
+ }
+ return new byte[0];
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ if (QueryInfo == null)
+ {
+ // SMB_INFO_IS_NAME_VALID
+ return new byte[0];
+ }
+ else
+ {
+ return QueryInfo.GetBytes();
+ }
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_QUERY_FILE_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationRequest.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationRequest.cs
new file mode 100644
index 0000000..988356e
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationRequest.cs
@@ -0,0 +1,86 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_QUERY_PATH_INFORMATION Request
+ ///
+ public class Transaction2QueryPathInformationRequest : Transaction2Subcommand
+ {
+ // Parameters:
+ public QueryInformationLevel InformationLevel;
+ public uint Reserved;
+ public string FileName; // SMB_STRING
+ // Data:
+ FullExtendedAttributeList GetExtendedAttributeList; // Used with QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST
+
+ public Transaction2QueryPathInformationRequest() : base()
+ {
+ GetExtendedAttributeList = new FullExtendedAttributeList();
+ }
+
+ public Transaction2QueryPathInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ InformationLevel = (QueryInformationLevel)LittleEndianConverter.ToUInt16(parameters, 0);
+ Reserved = LittleEndianConverter.ToUInt32(parameters, 4);
+ FileName = SMBHelper.ReadSMBString(parameters, 6, isUnicode);
+
+ if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
+ {
+ GetExtendedAttributeList = new FullExtendedAttributeList(data, 0);
+ }
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ int length = 6;
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+ byte[] parameters = new byte[length];
+ LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)InformationLevel);
+ LittleEndianWriter.WriteUInt32(parameters, 2, Reserved);
+ SMBHelper.WriteSMBString(parameters, 6, isUnicode, FileName);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ if (InformationLevel == QueryInformationLevel.SMB_INFO_QUERY_EAS_FROM_LIST)
+ {
+ return GetExtendedAttributeList.GetBytes();
+ }
+ else
+ {
+ return new byte[0];
+ }
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_QUERY_PATH_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationResponse.cs
new file mode 100644
index 0000000..cdda7cc
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2QueryPathInformationResponse.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_QUERY_PATH_INFORMATION Response
+ ///
+ public class Transaction2QueryPathInformationResponse : Transaction2Subcommand
+ {
+ // Parameters:
+ public ushort EaErrorOffset;
+ // Data:
+ public QueryInformation QueryInfo;
+
+ public Transaction2QueryPathInformationResponse() : base()
+ {
+
+ }
+
+ public Transaction2QueryPathInformationResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base()
+ {
+ if ((ushort)informationLevel > 0x0100)
+ {
+ EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+ QueryInfo = QueryInformation.GetQueryInformation(data, informationLevel);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ if ((ushort)QueryInfo.InformationLevel > 0x0100)
+ {
+ byte[] parameters = new byte[2];
+ LittleEndianWriter.WriteUInt16(parameters, 0, EaErrorOffset);
+ return parameters;
+ }
+ return new byte[0];
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ if (QueryInfo == null)
+ {
+ // SMB_INFO_IS_NAME_VALID
+ return new byte[0];
+ }
+ else
+ {
+ return QueryInfo.GetBytes();
+ }
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_QUERY_PATH_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationRequest.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationRequest.cs
new file mode 100644
index 0000000..5af2ed0
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationRequest.cs
@@ -0,0 +1,67 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_SET_FILE_INFORMATION Request
+ ///
+ public class Transaction2SetFileInformationRequest : Transaction2Subcommand
+ {
+ public int ParametersLength = 6;
+ // Parameters:
+ public ushort FID;
+ public SetInformationLevel InformationLevel;
+ public ushort Reserved;
+ // Data:
+ public SetInformation SetInfo;
+
+ public Transaction2SetFileInformationRequest() : base()
+ {
+ }
+
+ public Transaction2SetFileInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(parameters, 0);
+ InformationLevel = (SetInformationLevel)LittleEndianConverter.ToUInt16(parameters, 2);
+ Reserved = LittleEndianConverter.ToUInt16(parameters, 4);
+
+ SetInfo = SetInformation.GetSetInformation(data, InformationLevel);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, FID);
+ LittleEndianWriter.WriteUInt16(parameters, 2, (ushort)InformationLevel);
+ LittleEndianWriter.WriteUInt16(parameters, 4, Reserved);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return SetInfo.GetBytes();
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_SET_FILE_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationResponse.cs
new file mode 100644
index 0000000..312bfc4
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetFileInformationResponse.cs
@@ -0,0 +1,47 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_SET_FILE_INFORMATION Response
+ ///
+ public class Transaction2SetFileInformationResponse : Transaction2Subcommand
+ {
+ // Parameters:
+ public ushort EaErrorOffset;
+
+ public Transaction2SetFileInformationResponse() : base()
+ {
+
+ }
+
+ public Transaction2SetFileInformationResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base()
+ {
+ EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[2];
+ LittleEndianWriter.WriteUInt16(parameters, 0, EaErrorOffset);
+ return parameters;
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_SET_FILE_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationRequest.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationRequest.cs
new file mode 100644
index 0000000..deac64e
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationRequest.cs
@@ -0,0 +1,74 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_SET_PATH_INFORMATION Request
+ ///
+ public class Transaction2SetPathInformationRequest : Transaction2Subcommand
+ {
+ public const int ParametersFixedLength = 6;
+ // Parameters:
+ public SetInformationLevel InformationLevel;
+ public uint Reserved;
+ public string FileName; // SMB_STRING
+ // Data:
+ public SetInformation SetInfo;
+
+ public Transaction2SetPathInformationRequest() : base()
+ {}
+
+ public Transaction2SetPathInformationRequest(byte[] parameters, byte[] data, bool isUnicode) : base()
+ {
+ InformationLevel = (SetInformationLevel)LittleEndianConverter.ToUInt16(parameters, 0);
+ Reserved = LittleEndianConverter.ToUInt32(parameters, 2);
+ FileName = SMBHelper.ReadSMBString(parameters, 6, isUnicode);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ int length = ParametersFixedLength;
+ if (isUnicode)
+ {
+ length += FileName.Length * 2 + 2;
+ }
+ else
+ {
+ length += FileName.Length + 1;
+ }
+
+ byte[] parameters = new byte[length];
+ LittleEndianWriter.WriteUInt16(parameters, 0, (ushort)InformationLevel);
+ LittleEndianWriter.WriteUInt32(parameters, 2, Reserved);
+ SMBHelper.WriteSMBString(parameters, 6, isUnicode, FileName);
+ return parameters;
+ }
+
+ public override byte[] GetData(bool isUnicode)
+ {
+ return SetInfo.GetBytes();
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_SET_PATH_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationResponse.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationResponse.cs
new file mode 100644
index 0000000..3ea5e46
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2SetPathInformationResponse.cs
@@ -0,0 +1,47 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS2_SET_PATH_INFORMATION Response
+ ///
+ public class Transaction2SetPathInformationResponse : Transaction2Subcommand
+ {
+ // Parameters:
+ public ushort EaErrorOffset;
+
+ public Transaction2SetPathInformationResponse() : base()
+ {
+
+ }
+
+ public Transaction2SetPathInformationResponse(byte[] parameters, byte[] data, QueryInformationLevel informationLevel, bool isUnicode) : base()
+ {
+ EaErrorOffset = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[2];
+ LittleEndianWriter.WriteUInt16(parameters, 0, EaErrorOffset);
+ return parameters;
+ }
+
+ public override Transaction2SubcommandName SubcommandName
+ {
+ get
+ {
+ return Transaction2SubcommandName.TRANS2_SET_PATH_INFORMATION;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Subcommand.cs b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Subcommand.cs
new file mode 100644
index 0000000..9eb3f13
--- /dev/null
+++ b/SMBLibrary/SMB1/Transaction2Subcommands/Transaction2Subcommand.cs
@@ -0,0 +1,72 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class Transaction2Subcommand
+ {
+ public Transaction2Subcommand()
+ {
+ }
+
+ public virtual byte[] GetSetup()
+ {
+ return new byte[0];
+ }
+
+ public virtual byte[] GetParameters(bool isUnicode)
+ {
+ return new byte[0];
+ }
+
+ public virtual byte[] GetData(bool isUnicode)
+ {
+ return new byte[0];
+ }
+
+ public abstract Transaction2SubcommandName SubcommandName
+ {
+ get;
+ }
+
+ public static Transaction2Subcommand GetSubcommandRequest(byte[] setup, byte[] parameters, byte[] data, bool isUnicode)
+ {
+ if (setup.Length == 2)
+ {
+ Transaction2SubcommandName subcommandName = (Transaction2SubcommandName)LittleEndianConverter.ToUInt16(setup, 0);
+ switch (subcommandName)
+ {
+ case Transaction2SubcommandName.TRANS2_OPEN2:
+ return new Transaction2Open2Request(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_FIND_FIRST2:
+ return new Transaction2FindFirst2Request(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_FIND_NEXT2:
+ return new Transaction2FindNext2Request(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_QUERY_FS_INFORMATION:
+ return new Transaction2QueryFSInformationRequest(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_QUERY_PATH_INFORMATION:
+ return new Transaction2QueryPathInformationRequest(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_SET_PATH_INFORMATION:
+ return new Transaction2SetPathInformationRequest(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_QUERY_FILE_INFORMATION:
+ return new Transaction2QueryFileInformationRequest(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_SET_FILE_INFORMATION:
+ return new Transaction2SetFileInformationRequest(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_CREATE_DIRECTORY:
+ return new Transaction2CreateDirectoryRequest(parameters, data, isUnicode);
+ case Transaction2SubcommandName.TRANS2_GET_DFS_REFERRAL:
+ return new Transaction2GetDfsReferralRequest(parameters, data);
+ }
+ }
+ throw new InvalidRequestException();
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/Enums/NamedPipeState.cs b/SMBLibrary/SMB1/TransactionSubcommands/Enums/NamedPipeState.cs
new file mode 100644
index 0000000..b220f45
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/Enums/NamedPipeState.cs
@@ -0,0 +1,11 @@
+
+namespace SMBLibrary.SMB1
+{
+ public enum NamedPipeState : ushort
+ {
+ DisconnectedByServer = 0x0001,
+ Listening = 0x0002,
+ ConnectionToServerOK = 0x0003,
+ ServerEndClosed = 0x0004,
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/Enums/PipeState.cs b/SMBLibrary/SMB1/TransactionSubcommands/Enums/PipeState.cs
new file mode 100644
index 0000000..7a32e0c
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/Enums/PipeState.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace SMBLibrary.SMB1
+{
+ [Flags]
+ public enum PipeState : ushort
+ {
+ ///
+ /// If set, the named pipe is operating in message mode.
+ /// If not set, the named pipe is operating in byte mode.
+ /// In message mode, the system treats the bytes read or written in each I/O operation to the pipe as a message unit.
+ /// The system MUST perform write operations on message-type pipes as if write-through mode were enabled.
+ ///
+ ReadMode = 0x0100,
+
+ ///
+ /// If set, a read or a raw read request returns all data available to be read from the named pipe, up to the maximum read size set in the request.
+ /// A write request returns after writing data to the named pipe without waiting for the data to be consumed.
+ /// Named pipe non-blocking raw writes are not allowed. Raw writes MUST be performed in blocking mode.
+ /// If not set, a read or a raw read request will wait (block) until sufficient data to satisfy the read request becomes available,
+ /// or until the request is canceled. A write request blocks until its data is consumed, if the write request length is greater than zero.
+ ///
+ Nonblocking = 0x8000,
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/Enums/TransactionSubcommandName.cs b/SMBLibrary/SMB1/TransactionSubcommands/Enums/TransactionSubcommandName.cs
new file mode 100644
index 0000000..d9ddfcc
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/Enums/TransactionSubcommandName.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public enum TransactionSubcommandName : ushort
+ {
+ ///
+ /// The 0x0001 subcommand code is interpreted as TRANS_MAILSLOT_WRITE if the operation is being performed on a mailslot.
+ /// The same code is interpreted as a TRANS_SET_NMPIPE_STATE (section 2.2.5.1) if the operation is performed on a named pipe.
+ ///
+ TRANS_MAILSLOT_WRITE = 0x0001,
+ TRANS_SET_NMPIPE_STATE = 0x0001,
+ TRANS_RAW_READ_NMPIPE = 0x0011,
+ TRANS_QUERY_NMPIPE_STATE = 0x0021,
+ TRANS_QUERY_NMPIPE_INFO = 0x0022,
+ TRANS_PEEK_NMPIPE = 0x0023,
+ TRANS_TRANSACT_NMPIPE = 0x0026,
+ TRANS_RAW_WRITE_NMPIPE = 0x0031,
+ TRANS_READ_NMPIPE = 0x0036,
+ TRANS_WRITE_NMPIPE = 0x0037,
+ TRANS_WAIT_NMPIPE = 0x0053,
+ TRANS_CALL_NMPIPE = 0x0054,
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionCallNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionCallNamedPipeRequest.cs
new file mode 100644
index 0000000..de139f5
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionCallNamedPipeRequest.cs
@@ -0,0 +1,57 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_CALL_NMPIPE Request
+ ///
+ public class TransactionCallNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+ // Data:
+ public byte[] WriteData;
+
+ public TransactionCallNamedPipeRequest() : base()
+ {
+
+ }
+
+ public TransactionCallNamedPipeRequest(byte[] setup, byte[] data) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+
+ WriteData = data;
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override byte[] GetData()
+ {
+ return WriteData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_CALL_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionCallNamedPipeResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionCallNamedPipeResponse.cs
new file mode 100644
index 0000000..c7fa683
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionCallNamedPipeResponse.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_CALL_NMPIPE Response
+ ///
+ public class TransactionCallNamedPipeResponse : TransactionSubcommand
+ {
+ // Data:
+ public byte[] ReadData;
+
+ public TransactionCallNamedPipeResponse() : base()
+ {}
+
+ public TransactionCallNamedPipeResponse(byte[] data) : base()
+ {
+ ReadData = data;
+ }
+
+ public override byte[] GetData()
+ {
+ return ReadData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_CALL_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionPeekNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionPeekNamedPipeRequest.cs
new file mode 100644
index 0000000..577aca1
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionPeekNamedPipeRequest.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_PEEK_NMPIPE Request
+ ///
+ public class TransactionPeekNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+
+ public TransactionPeekNamedPipeRequest() : base()
+ {}
+
+ public TransactionPeekNamedPipeRequest(byte[] setup) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_PEEK_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionPeekNamedPipeResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionPeekNamedPipeResponse.cs
new file mode 100644
index 0000000..7f9a1a7
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionPeekNamedPipeResponse.cs
@@ -0,0 +1,61 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_PEEK_NMPIPE Response
+ ///
+ public class TransactionPeekNamedPipeResponse : TransactionSubcommand
+ {
+ public const int ParametersLength = 6;
+ // Parameters:
+ public ushort ReadDataAvailable;
+ public ushort MessageBytesLength;
+ public NamedPipeState NamedPipeState;
+ // Data:
+ public byte[] ReadData;
+
+ public TransactionPeekNamedPipeResponse() : base()
+ { }
+
+ public TransactionPeekNamedPipeResponse(byte[] parameters, byte[] data) : base()
+ {
+ ReadDataAvailable = LittleEndianConverter.ToUInt16(parameters, 0);
+ MessageBytesLength = LittleEndianConverter.ToUInt16(parameters, 2);
+ NamedPipeState = (NamedPipeState)LittleEndianConverter.ToUInt16(parameters, 4);
+
+ ReadData = data;
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[ParametersLength];
+ LittleEndianWriter.WriteUInt16(parameters, 0, ReadDataAvailable);
+ LittleEndianWriter.WriteUInt16(parameters, 2, MessageBytesLength);
+ LittleEndianWriter.WriteUInt16(parameters, 4, (ushort)NamedPipeState);
+ return parameters;
+ }
+
+ public override byte[] GetData()
+ {
+ return ReadData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_PEEK_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeInfoRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeInfoRequest.cs
new file mode 100644
index 0000000..26aea31
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeInfoRequest.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_QUERY_NMPIPE_INFO Request
+ ///
+ public class TransactionQueryNamedPipeInfoRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+ // Parameters:
+ public ushort Level; // Must be 0x0001
+
+ public TransactionQueryNamedPipeInfoRequest() : base()
+ {
+ }
+
+ public TransactionQueryNamedPipeInfoRequest(byte[] setup, byte[] parameters) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+
+ Level = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ return LittleEndianConverter.GetBytes(Level);
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_QUERY_NMPIPE_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeInfoResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeInfoResponse.cs
new file mode 100644
index 0000000..2ae6476
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeInfoResponse.cs
@@ -0,0 +1,70 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_QUERY_NMPIPE_INFO Response
+ ///
+ public class TransactionQueryNamedPipeInfoResponse : TransactionSubcommand
+ {
+ // Parameters:
+ public ushort OutputBufferSize;
+ public ushort InputBufferSize;
+ public byte MaximumInstances;
+ public byte CurrentInstances;
+ public byte PipeNameLength;
+ public string PipeName; // SMB_STRING (this field WILL be aligned to start on a 2-byte boundary from the start of the SMB header)
+
+ public TransactionQueryNamedPipeInfoResponse() : base()
+ {}
+
+ public TransactionQueryNamedPipeInfoResponse(byte[] parameters, bool isUnicode) : base()
+ {
+ OutputBufferSize = LittleEndianConverter.ToUInt16(parameters, 0);
+ InputBufferSize = LittleEndianConverter.ToUInt16(parameters, 2);
+ MaximumInstances = ByteReader.ReadByte(parameters, 4);
+ CurrentInstances = ByteReader.ReadByte(parameters, 5);
+ PipeNameLength = ByteReader.ReadByte(parameters, 6);
+ // Note: Trans_Parameters is aligned to 4 byte boundary
+ PipeName = SMBHelper.ReadSMBString(parameters, 8, isUnicode);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ int length = 8;
+ if (isUnicode)
+ {
+ length += PipeName.Length * 2 + 2;
+ }
+ else
+ {
+ length += PipeName.Length + 1;
+ }
+ byte[] parameters = new byte[length];
+ LittleEndianWriter.WriteUInt16(parameters, 0, OutputBufferSize);
+ LittleEndianWriter.WriteUInt16(parameters, 2, InputBufferSize);
+ ByteWriter.WriteByte(parameters, 4, MaximumInstances);
+ ByteWriter.WriteByte(parameters, 5, CurrentInstances);
+ ByteWriter.WriteByte(parameters, 6, PipeNameLength);
+ SMBHelper.WriteSMBString(parameters, 8, isUnicode, PipeName);
+ return parameters; ;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_QUERY_NMPIPE_INFO;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeStateRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeStateRequest.cs
new file mode 100644
index 0000000..a9dea32
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeStateRequest.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_QUERY_NMPIPE_STATE Request
+ ///
+ public class TransactionQueryNamedPipeStateRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+
+ public TransactionQueryNamedPipeStateRequest() : base()
+ {
+ }
+
+ public TransactionQueryNamedPipeStateRequest(byte[] setup, byte[] parameters) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+ }
+
+ public override byte[] GetSetup()
+ {
+ return LittleEndianConverter.GetBytes((ushort)SubcommandName);
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_QUERY_NMPIPE_STATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeStateResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeStateResponse.cs
new file mode 100644
index 0000000..832d657
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionQueryNamedPipeStateResponse.cs
@@ -0,0 +1,41 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_QUERY_NMPIPE_STATE Response
+ ///
+ public class TransactionQueryNamedPipeStateResponse : TransactionSubcommand
+ {
+ public NamedPipeStatus NMPipeStatus;
+
+ public override byte[] GetSetup()
+ {
+ return new byte[0];
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ byte[] parameters = new byte[2];
+ NMPipeStatus.WriteBytes(parameters, 0);
+ return parameters;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_QUERY_NMPIPE_STATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawReadNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawReadNamedPipeRequest.cs
new file mode 100644
index 0000000..c60bbc8
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawReadNamedPipeRequest.cs
@@ -0,0 +1,48 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_RAW_READ_NMPIPE Request
+ ///
+ public class TransactionRawReadNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+
+ public TransactionRawReadNamedPipeRequest()
+ {
+ }
+
+ public TransactionRawReadNamedPipeRequest(byte[] setup)
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_RAW_READ_NMPIPE;
+ }
+ }
+
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawReadNamedPipeResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawReadNamedPipeResponse.cs
new file mode 100644
index 0000000..661cbd2
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawReadNamedPipeResponse.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_RAW_READ_NMPIPE Request
+ ///
+ public class TransactionRawReadNamedPipeResponse : TransactionSubcommand
+ {
+ // Data:
+ public byte[] BytesRead;
+
+ public TransactionRawReadNamedPipeResponse() : base()
+ {}
+
+ public TransactionRawReadNamedPipeResponse(byte[] data) : base()
+ {
+ BytesRead = data;
+ }
+
+ public override byte[] GetData()
+ {
+ return BytesRead;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_RAW_READ_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawWriteNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawWriteNamedPipeRequest.cs
new file mode 100644
index 0000000..c37afab
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawWriteNamedPipeRequest.cs
@@ -0,0 +1,55 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_RAW_WRITE_NMPIPE Request
+ ///
+ public class TransactionRawWriteNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+ // Data:
+ public byte[] WriteData;
+
+ public TransactionRawWriteNamedPipeRequest() : base()
+ {
+ }
+ public TransactionRawWriteNamedPipeRequest(byte[] setup, byte[] data) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+
+ WriteData = data;
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override byte[] GetData()
+ {
+ return WriteData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_RAW_WRITE_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawWriteNamedPipeResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawWriteNamedPipeResponse.cs
new file mode 100644
index 0000000..a8d9a45
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionRawWriteNamedPipeResponse.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_RAW_WRITE_NMPIPE Response
+ ///
+ public class TransactionRawWriteNamedPipeResponse : TransactionSubcommand
+ {
+ // Parameters;
+ public ushort BytesWritten;
+
+ public TransactionRawWriteNamedPipeResponse() : base()
+ {
+ }
+
+ public TransactionRawWriteNamedPipeResponse(byte[] parameters) : base()
+ {
+ BytesWritten = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ return LittleEndianConverter.GetBytes(BytesWritten);
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_RAW_WRITE_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionReadNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionReadNamedPipeRequest.cs
new file mode 100644
index 0000000..febaecc
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionReadNamedPipeRequest.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_READ_NMPIPE Request
+ ///
+ public class TransactionReadNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+
+ public TransactionReadNamedPipeRequest() : base()
+ {}
+
+ public TransactionReadNamedPipeRequest(byte[] setup): base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_READ_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionReadNamedPipeResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionReadNamedPipeResponse.cs
new file mode 100644
index 0000000..53e7d46
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionReadNamedPipeResponse.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_READ_NMPIPE Request
+ ///
+ public class TransactionReadNamedPipeResponse : TransactionSubcommand
+ {
+ // Data:
+ public byte[] ReadData;
+
+ public TransactionReadNamedPipeResponse() : base()
+ {
+ }
+
+ public TransactionReadNamedPipeResponse(byte[] data) : base()
+ {
+ ReadData = data;
+ }
+
+ public override byte[] GetData()
+ {
+ return ReadData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_READ_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionSetNamedPipeStateRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionSetNamedPipeStateRequest.cs
new file mode 100644
index 0000000..bd87402
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionSetNamedPipeStateRequest.cs
@@ -0,0 +1,56 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_SET_NMPIPE_STATE Request
+ ///
+ public class TransactionSetNamedPipeStateRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+ // Parameters:
+ public PipeState PipeState;
+
+ public TransactionSetNamedPipeStateRequest() : base()
+ {
+ }
+
+ public TransactionSetNamedPipeStateRequest(byte[] setup, byte[] parameters) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+
+ PipeState = (PipeState)LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ return LittleEndianConverter.GetBytes((ushort)PipeState);
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_SET_NMPIPE_STATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionSetNamedPipeStateResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionSetNamedPipeStateResponse.cs
new file mode 100644
index 0000000..6a93b93
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionSetNamedPipeStateResponse.cs
@@ -0,0 +1,27 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_SET_NMPIPE_STATE Request
+ ///
+ public class TransactionSetNamedPipeStateResponse : TransactionSubcommand
+ {
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_SET_NMPIPE_STATE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionSubcommand.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionSubcommand.cs
new file mode 100644
index 0000000..d527359
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionSubcommand.cs
@@ -0,0 +1,79 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public abstract class TransactionSubcommand
+ {
+ public TransactionSubcommand()
+ {
+ }
+
+ public virtual byte[] GetSetup()
+ {
+ return new byte[0];
+ }
+
+ public virtual byte[] GetParameters(bool isUnicode)
+ {
+ return new byte[0];
+ }
+
+ public virtual byte[] GetData()
+ {
+ return new byte[0];
+ }
+
+ public abstract TransactionSubcommandName SubcommandName
+ {
+ get;
+ }
+
+ public static TransactionSubcommand GetSubcommandRequest(byte[] setup, byte[] parameters, byte[] data, bool isUnicode)
+ {
+ if (setup.Length == 4)
+ {
+ TransactionSubcommandName subcommandName = (TransactionSubcommandName)LittleEndianConverter.ToUInt16(setup, 0);
+ switch (subcommandName)
+ {
+ case TransactionSubcommandName.TRANS_SET_NMPIPE_STATE:
+ return new TransactionSetNamedPipeStateRequest(setup, parameters);
+ case TransactionSubcommandName.TRANS_RAW_READ_NMPIPE:
+ return new TransactionRawReadNamedPipeRequest(setup);
+ case TransactionSubcommandName.TRANS_QUERY_NMPIPE_STATE:
+ return new TransactionQueryNamedPipeStateRequest(setup, parameters);
+ case TransactionSubcommandName.TRANS_QUERY_NMPIPE_INFO:
+ return new TransactionQueryNamedPipeInfoRequest(setup, parameters);
+ case TransactionSubcommandName.TRANS_PEEK_NMPIPE:
+ return new TransactionPeekNamedPipeRequest(setup);
+ case TransactionSubcommandName.TRANS_TRANSACT_NMPIPE:
+ return new TransactionTransactNamedPipeRequest(setup, data);
+ case TransactionSubcommandName.TRANS_RAW_WRITE_NMPIPE:
+ return new TransactionRawWriteNamedPipeRequest(setup, data);
+ case TransactionSubcommandName.TRANS_READ_NMPIPE:
+ return new TransactionReadNamedPipeRequest(setup);
+ case TransactionSubcommandName.TRANS_WRITE_NMPIPE:
+ return new TransactionWriteNamedPipeRequest(setup, data);
+ case TransactionSubcommandName.TRANS_WAIT_NMPIPE:
+ return new TransactionWaitNamedPipeRequest(setup);
+ case TransactionSubcommandName.TRANS_CALL_NMPIPE:
+ return new TransactionCallNamedPipeRequest(setup, data);
+ }
+ }
+ else if (setup.Length == 0 && data.Length == 0)
+ {
+ // [MS-RAP] Remote Administration Protocol request
+ throw new NotImplementedException("Remote Administration Protocol request");
+ }
+ throw new InvalidRequestException();
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionTransactNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionTransactNamedPipeRequest.cs
new file mode 100644
index 0000000..7016978
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionTransactNamedPipeRequest.cs
@@ -0,0 +1,55 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_TRANSACT_NMPIPE Request
+ ///
+ public class TransactionTransactNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+ // Data:
+ public byte[] WriteData;
+
+ public TransactionTransactNamedPipeRequest() : base()
+ {
+ }
+ public TransactionTransactNamedPipeRequest(byte[] setup, byte[] data) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+
+ WriteData = data;
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override byte[] GetData()
+ {
+ return WriteData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_TRANSACT_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionTransactNamedPipeResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionTransactNamedPipeResponse.cs
new file mode 100644
index 0000000..17ead8e
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionTransactNamedPipeResponse.cs
@@ -0,0 +1,44 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_TRANSACT_NMPIPE Request
+ ///
+ public class TransactionTransactNamedPipeResponse : TransactionSubcommand
+ {
+ // Data:
+ public byte[] ReadData;
+
+ public TransactionTransactNamedPipeResponse() : base()
+ {
+ }
+
+ public TransactionTransactNamedPipeResponse(byte[] data) : base()
+ {
+ ReadData = data;
+ }
+
+ public override byte[] GetData()
+ {
+ return ReadData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_TRANSACT_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionWaitNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionWaitNamedPipeRequest.cs
new file mode 100644
index 0000000..9cf921b
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionWaitNamedPipeRequest.cs
@@ -0,0 +1,46 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_WAIT_NMPIPE Request
+ ///
+ public class TransactionWaitNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+ public TransactionWaitNamedPipeRequest() : base()
+ {
+ }
+
+ public TransactionWaitNamedPipeRequest(byte[] setup) : base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_WAIT_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionWriteNamedPipeRequest.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionWriteNamedPipeRequest.cs
new file mode 100644
index 0000000..9341432
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionWriteNamedPipeRequest.cs
@@ -0,0 +1,55 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_WRITE_NMPIPE Request
+ ///
+ public class TransactionWriteNamedPipeRequest : TransactionSubcommand
+ {
+ // Setup:
+ public ushort FID;
+ // Data:
+ public byte[] WriteData;
+
+ public TransactionWriteNamedPipeRequest() : base()
+ {
+ }
+
+ public TransactionWriteNamedPipeRequest(byte[] setup, byte[] data): base()
+ {
+ FID = LittleEndianConverter.ToUInt16(setup, 2);
+ WriteData = data;
+ }
+
+ public override byte[] GetSetup()
+ {
+ byte[] setup = new byte[4];
+ LittleEndianWriter.WriteUInt16(setup, 0, (ushort)this.SubcommandName);
+ LittleEndianWriter.WriteUInt16(setup, 2, FID);
+ return base.GetSetup();
+ }
+
+ public override byte[] GetData()
+ {
+ return WriteData;
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_WRITE_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TransactionSubcommands/TransactionWriteNamedPipeResponse.cs b/SMBLibrary/SMB1/TransactionSubcommands/TransactionWriteNamedPipeResponse.cs
new file mode 100644
index 0000000..78b9d99
--- /dev/null
+++ b/SMBLibrary/SMB1/TransactionSubcommands/TransactionWriteNamedPipeResponse.cs
@@ -0,0 +1,43 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ ///
+ /// TRANS_WRITE_NMPIPE Response
+ ///
+ public class TransactionWriteNamedPipeResponse : TransactionSubcommand
+ {
+ // Parameters;
+ public ushort BytesWritten;
+
+ public TransactionWriteNamedPipeResponse() : base()
+ {}
+
+ public TransactionWriteNamedPipeResponse(byte[] parameters) : base()
+ {
+ BytesWritten = LittleEndianConverter.ToUInt16(parameters, 0);
+ }
+
+ public override byte[] GetParameters(bool isUnicode)
+ {
+ return LittleEndianConverter.GetBytes(BytesWritten);
+ }
+
+ public override TransactionSubcommandName SubcommandName
+ {
+ get
+ {
+ return TransactionSubcommandName.TRANS_WRITE_NMPIPE;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMB1/TreeConnectHelper.cs b/SMBLibrary/SMB1/TreeConnectHelper.cs
new file mode 100644
index 0000000..7b04c9d
--- /dev/null
+++ b/SMBLibrary/SMB1/TreeConnectHelper.cs
@@ -0,0 +1,50 @@
+/* Copyright (C) 2014 Tal Aloni . 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 System.Text;
+using Utilities;
+
+namespace SMBLibrary.SMB1
+{
+ public class TreeConnectHelper
+ {
+ public static string GetServiceString(ServiceName serviceName)
+ {
+ switch (serviceName)
+ {
+ case ServiceName.DiskShare:
+ return "A:";
+ case ServiceName.PrinterShare:
+ return "LPT1:";
+ case ServiceName.NamedPipe:
+ return "IPC";
+ case ServiceName.SerialCommunicationsDevice:
+ return "COMM";
+ default:
+ return "?????";
+ }
+ }
+
+ public static ServiceName GetServiceName(string serviceString)
+ {
+ switch (serviceString)
+ {
+ case "A:":
+ return ServiceName.DiskShare;
+ case "LPT1:":
+ return ServiceName.PrinterShare;
+ case "IPC":
+ return ServiceName.NamedPipe;
+ case "COMM":
+ return ServiceName.SerialCommunicationsDevice;
+ default:
+ return ServiceName.AnyType;
+ }
+ }
+ }
+}
diff --git a/SMBLibrary/SMBLibrary.csproj b/SMBLibrary/SMBLibrary.csproj
new file mode 100644
index 0000000..a39afad
--- /dev/null
+++ b/SMBLibrary/SMBLibrary.csproj
@@ -0,0 +1,417 @@
+
+