WriteAndXRequest.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* Copyright (C) 2014 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 System.Text;
  10. using Utilities;
  11. namespace SMBLibrary.SMB1
  12. {
  13. /// <summary>
  14. /// SMB_COM_WRITE_ANDX Request
  15. /// SMB 1.0: The 2 reserved bytes at offset 18 become DataLengthHigh (used when the CAP_LARGE_WRITEX capability has been negotiated)
  16. /// </summary>
  17. public class WriteAndXRequest : SMBAndXCommand
  18. {
  19. public const int ParametersFixedLength = 24;
  20. // Parameters:
  21. //CommandName AndXCommand;
  22. //byte AndXReserved;
  23. //ushort AndXOffset;
  24. public ushort FID;
  25. public ulong Offset; // 4 bytes + 4 optional 'OffsetHigh' bytes
  26. public uint Timeout;
  27. public WriteMode WriteMode;
  28. public ushort Remaining;
  29. //uint DataLength; // 2 bytes + 2 'DataLengthHigh' bytes
  30. //ushort DataOffset;
  31. // ulong OffsetHigh; // Optional
  32. // Data:
  33. // Optional 1 byte padding
  34. public byte[] Data;
  35. public WriteAndXRequest() : base()
  36. {}
  37. public WriteAndXRequest(byte[] buffer, int offset, bool isUnicode) : base(buffer, offset, isUnicode)
  38. {
  39. FID = LittleEndianConverter.ToUInt16(this.SMBParameters, 4);
  40. Offset = LittleEndianConverter.ToUInt32(this.SMBParameters, 6);
  41. Timeout = LittleEndianConverter.ToUInt32(this.SMBParameters, 10);
  42. WriteMode = (WriteMode)LittleEndianConverter.ToUInt16(this.SMBParameters, 14);
  43. Remaining = LittleEndianConverter.ToUInt16(this.SMBParameters, 16);
  44. ushort dataLengthHigh = LittleEndianConverter.ToUInt16(this.SMBParameters, 18);
  45. uint DataLength = LittleEndianConverter.ToUInt16(this.SMBParameters, 20);
  46. ushort DataOffset = LittleEndianConverter.ToUInt16(this.SMBParameters, 22);
  47. if (SMBParameters.Length == ParametersFixedLength + 4)
  48. {
  49. uint offsetHigh = LittleEndianConverter.ToUInt32(this.SMBParameters, 24);
  50. Offset |= ((ulong)offsetHigh << 32);
  51. }
  52. DataLength |= (uint)(dataLengthHigh << 16);
  53. Data = ByteReader.ReadBytes(buffer, (int)DataOffset, (int)DataLength);
  54. }
  55. public override byte[] GetBytes(bool isUnicode)
  56. {
  57. uint DataLength = (uint)Data.Length;
  58. // WordCount + ByteCount are additional 3 bytes
  59. ushort DataOffset = SMB1Header.Length + 3 + ParametersFixedLength;
  60. if (isUnicode)
  61. {
  62. DataOffset++;
  63. }
  64. ushort dataLengthHigh = (ushort)(DataLength >> 16);
  65. int parametersLength = ParametersFixedLength;
  66. if (Offset > UInt32.MaxValue)
  67. {
  68. parametersLength += 4;
  69. DataOffset += 4;
  70. }
  71. this.SMBParameters = new byte[parametersLength];
  72. LittleEndianWriter.WriteUInt16(this.SMBParameters, 4, FID);
  73. LittleEndianWriter.WriteUInt32(this.SMBParameters, 6, (uint)(Offset & 0xFFFFFFFF));
  74. LittleEndianWriter.WriteUInt32(this.SMBParameters, 10, Timeout);
  75. LittleEndianWriter.WriteUInt16(this.SMBParameters, 14, (ushort)WriteMode);
  76. LittleEndianWriter.WriteUInt16(this.SMBParameters, 16, Remaining);
  77. LittleEndianWriter.WriteUInt16(this.SMBParameters, 18, dataLengthHigh);
  78. LittleEndianWriter.WriteUInt16(this.SMBParameters, 20, (ushort)(DataLength & 0xFFFF));
  79. LittleEndianWriter.WriteUInt16(this.SMBParameters, 22, DataOffset);
  80. if (Offset > UInt32.MaxValue)
  81. {
  82. uint offsetHigh = (uint)(Offset >> 32);
  83. LittleEndianWriter.WriteUInt32(this.SMBParameters, 24, offsetHigh);
  84. }
  85. int smbDataLength = Data.Length;
  86. if (isUnicode)
  87. {
  88. smbDataLength++;
  89. }
  90. this.SMBData = new byte[smbDataLength];
  91. int offset = 0;
  92. if (isUnicode)
  93. {
  94. offset++;
  95. }
  96. ByteWriter.WriteBytes(this.SMBData, ref offset, this.Data);
  97. return base.GetBytes(isUnicode);
  98. }
  99. public override CommandName CommandName
  100. {
  101. get
  102. {
  103. return CommandName.SMB_COM_WRITE_ANDX;
  104. }
  105. }
  106. }
  107. }