CreateRequest.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using Utilities;
  10. namespace SMBLibrary.SMB2
  11. {
  12. /// <summary>
  13. /// SMB2 CREATE Request
  14. /// </summary>
  15. public class CreateRequest : SMB2Command
  16. {
  17. public const int FixedLength = 56;
  18. public const int DeclaredSize = 57;
  19. public ushort StructureSize;
  20. public byte SecurityFlags; // Reserved
  21. public OplockLevel RequestedOplockLevel;
  22. public ImpersonationLevel ImpersonationLevel;
  23. public ulong SmbCreateFlags;
  24. public ulong Reserved;
  25. public AccessMask DesiredAccess;
  26. public FileAttributes FileAttributes;
  27. public ShareAccess ShareAccess;
  28. public CreateDisposition CreateDisposition;
  29. public CreateOptions CreateOptions;
  30. private ushort NameOffset;
  31. private ushort NameLength;
  32. public string Name;
  33. private uint CreateContextsOffsets;
  34. private uint CreateContextsLength;
  35. public List<CreateContext> CreateContexts = new List<CreateContext>();
  36. public CreateRequest() : base(SMB2CommandName.Create)
  37. {
  38. StructureSize = DeclaredSize;
  39. }
  40. public CreateRequest(byte[] buffer, int offset) : base(buffer, offset)
  41. {
  42. StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
  43. SecurityFlags = ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 2);
  44. RequestedOplockLevel = (OplockLevel)ByteReader.ReadByte(buffer, offset + SMB2Header.Length + 3);
  45. ImpersonationLevel = (ImpersonationLevel)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
  46. SmbCreateFlags = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 8);
  47. Reserved = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 16);
  48. DesiredAccess = new AccessMask(buffer, offset + SMB2Header.Length + 24);
  49. FileAttributes = (FileAttributes)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
  50. ShareAccess = (ShareAccess)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
  51. CreateDisposition = (CreateDisposition)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
  52. CreateOptions = (CreateOptions)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 40);
  53. NameOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 44);
  54. NameLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 46);
  55. CreateContextsOffsets = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 48);
  56. CreateContextsLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 52);
  57. Name = ByteReader.ReadUTF16String(buffer, offset + NameOffset, NameLength / 2);
  58. if (CreateContextsLength > 0)
  59. {
  60. CreateContexts = CreateContext.ReadCreateContextList(buffer, (int)CreateContextsOffsets);
  61. }
  62. }
  63. public override void WriteCommandBytes(byte[] buffer, int offset)
  64. {
  65. NameOffset = 0;
  66. NameLength = (ushort)(Name.Length * 2);
  67. if (Name.Length > 0)
  68. {
  69. NameOffset = SMB2Header.Length + FixedLength;
  70. }
  71. CreateContextsOffsets = 0;
  72. CreateContextsLength = 0;
  73. int paddedNameLength = (int)Math.Ceiling((double)(Name.Length * 2) / 8) * 8;
  74. if (CreateContexts.Count > 0)
  75. {
  76. CreateContextsOffsets = (uint)(SMB2Header.Length + 56 + paddedNameLength);
  77. CreateContextsLength = (uint)CreateContext.GetCreateContextListLength(CreateContexts);
  78. }
  79. LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
  80. ByteWriter.WriteByte(buffer, offset + 2, SecurityFlags);
  81. ByteWriter.WriteByte(buffer, offset + 3, (byte)RequestedOplockLevel);
  82. LittleEndianWriter.WriteUInt32(buffer, offset + 4, (uint)ImpersonationLevel);
  83. LittleEndianWriter.WriteUInt64(buffer, offset + 8, (ulong)SmbCreateFlags);
  84. LittleEndianWriter.WriteUInt64(buffer, offset + 16, (ulong)Reserved);
  85. DesiredAccess.WriteBytes(buffer, offset + 24);
  86. LittleEndianWriter.WriteUInt32(buffer, offset + 28, (uint)FileAttributes);
  87. LittleEndianWriter.WriteUInt32(buffer, offset + 32, (uint)ShareAccess);
  88. LittleEndianWriter.WriteUInt32(buffer, offset + 36, (uint)CreateDisposition);
  89. LittleEndianWriter.WriteUInt32(buffer, offset + 40, (uint)CreateOptions);
  90. LittleEndianWriter.WriteUInt16(buffer, offset + 44, NameOffset);
  91. LittleEndianWriter.WriteUInt16(buffer, offset + 46, NameLength);
  92. LittleEndianWriter.WriteUInt32(buffer, offset + 48, CreateContextsOffsets);
  93. LittleEndianWriter.WriteUInt32(buffer, offset + 52, CreateContextsLength);
  94. ByteWriter.WriteUTF16String(buffer, offset + 56, Name);
  95. CreateContext.WriteCreateContextList(buffer, offset + 56 + paddedNameLength, CreateContexts);
  96. }
  97. public override int CommandLength
  98. {
  99. get
  100. {
  101. if (CreateContexts.Count == 0)
  102. {
  103. return FixedLength + Name.Length * 2;
  104. }
  105. else
  106. {
  107. int paddedNameLength = (int)Math.Ceiling((double)(Name.Length * 2) / 8) * 8;
  108. return FixedLength + paddedNameLength + CreateContext.GetCreateContextListLength(CreateContexts);
  109. }
  110. }
  111. }
  112. }
  113. }