WriteRequest.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 WRITE Request
  14. /// </summary>
  15. public class WriteRequest : SMB2Command
  16. {
  17. public const int FixedSize = 48;
  18. public const int DeclaredSize = 49;
  19. private ushort StructureSize;
  20. private ushort DataOffset;
  21. private uint DataLength;
  22. public ulong Offset;
  23. public FileID FileId;
  24. public uint Channel;
  25. public uint RemainingBytes;
  26. private ushort WriteChannelInfoOffset;
  27. private ushort WriteChannelInfoLength;
  28. public WriteFlags Flags;
  29. public byte[] Data = new byte[0];
  30. public byte[] WriteChannelInfo = new byte[0];
  31. public WriteRequest() : base(SMB2CommandName.Write)
  32. {
  33. StructureSize = DeclaredSize;
  34. }
  35. public WriteRequest(byte[] buffer, int offset) : base(buffer, offset)
  36. {
  37. StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0);
  38. DataOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2);
  39. DataLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4);
  40. Offset = LittleEndianConverter.ToUInt64(buffer, offset + SMB2Header.Length + 8);
  41. FileId = new FileID(buffer, offset + SMB2Header.Length + 16);
  42. Channel = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 32);
  43. RemainingBytes = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 36);
  44. WriteChannelInfoOffset = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 40);
  45. WriteChannelInfoLength = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 42);
  46. Flags = (WriteFlags)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 44);
  47. Data = ByteReader.ReadBytes(buffer, offset + DataOffset, (int)DataLength);
  48. WriteChannelInfo = ByteReader.ReadBytes(buffer, offset + WriteChannelInfoOffset, WriteChannelInfoLength);
  49. }
  50. public override void WriteCommandBytes(byte[] buffer, int offset)
  51. {
  52. // Note: DataLength is UInt32 while WriteChannelInfoOffset is UInt16
  53. // so it is best to put WriteChannelInfo before Data.
  54. WriteChannelInfoOffset = 0;
  55. WriteChannelInfoLength = (ushort)WriteChannelInfo.Length;
  56. if (WriteChannelInfo.Length > 0)
  57. {
  58. WriteChannelInfoOffset = SMB2Header.Length + FixedSize;
  59. }
  60. DataOffset = 0;
  61. DataLength = (uint)Data.Length;
  62. if (Data.Length > 0)
  63. {
  64. DataOffset = (ushort)(SMB2Header.Length + FixedSize + WriteChannelInfo.Length);
  65. }
  66. LittleEndianWriter.WriteUInt16(buffer, offset + 0, StructureSize);
  67. LittleEndianWriter.WriteUInt16(buffer, offset + 2, DataOffset);
  68. LittleEndianWriter.WriteUInt32(buffer, offset + 4, DataLength);
  69. LittleEndianWriter.WriteUInt64(buffer, offset + 8, Offset);
  70. FileId.WriteBytes(buffer, offset + 16);
  71. LittleEndianWriter.WriteUInt32(buffer, offset + 32, Channel);
  72. LittleEndianWriter.WriteUInt32(buffer, offset + 36, RemainingBytes);
  73. LittleEndianWriter.WriteUInt16(buffer, offset + 40, WriteChannelInfoOffset);
  74. LittleEndianWriter.WriteUInt16(buffer, offset + 42, WriteChannelInfoLength);
  75. LittleEndianWriter.WriteUInt32(buffer, offset + 44, (uint)Flags);
  76. if (WriteChannelInfo.Length > 0)
  77. {
  78. ByteWriter.WriteBytes(buffer, offset + FixedSize, WriteChannelInfo);
  79. }
  80. if (Data.Length > 0)
  81. {
  82. ByteWriter.WriteBytes(buffer, offset + FixedSize + WriteChannelInfo.Length, Data);
  83. }
  84. }
  85. public override int CommandLength
  86. {
  87. get
  88. {
  89. return FixedSize + Data.Length + WriteChannelInfo.Length;
  90. }
  91. }
  92. }
  93. }