SmbComTransaction.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. // This code is derived from jcifs smb client library <jcifs at samba dot org>
  2. // Ported by J. Arturo <webmaster at komodosoft dot net>
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. using System;
  18. using SharpCifs.Util;
  19. namespace SharpCifs.Smb
  20. {
  21. internal abstract class SmbComTransaction : ServerMessageBlock
  22. {
  23. private static readonly int DefaultMaxDataCount
  24. = Config.GetInt("jcifs.smb.client.transaction_buf_size", TransactionBufSize) - 512;
  25. private const int PrimarySetupOffset = 61;
  26. private const int SecondaryParameterOffset = 51;
  27. private const int DisconnectTid = unchecked(0x01);
  28. private const int OneWayTransaction = unchecked(0x02);
  29. private const int PaddingSize = 2;
  30. private int _flags = unchecked(0x00);
  31. private int _fid;
  32. private int _pad;
  33. private int _pad1;
  34. private bool _hasMore = true;
  35. private bool _isPrimary = true;
  36. private int _bufParameterOffset;
  37. private int _bufDataOffset;
  38. internal const int TransactionBufSize = unchecked(0xFFFF);
  39. internal const byte Trans2FindFirst2 = unchecked(unchecked(0x01));
  40. internal const byte Trans2FindNext2 = unchecked(unchecked(0x02));
  41. internal const byte Trans2QueryFsInformation = unchecked(unchecked(0x03));
  42. internal const byte Trans2QueryPathInformation = unchecked(unchecked(0x05));
  43. internal const byte Trans2GetDfsReferral = unchecked(unchecked(0x10));
  44. internal const byte Trans2SetFileInformation = unchecked(unchecked(0x08));
  45. internal const int NetShareEnum = unchecked(0x0000);
  46. internal const int NetServerEnum2 = unchecked(0x0068);
  47. internal const int NetServerEnum3 = unchecked(0x00D7);
  48. internal const byte TransPeekNamedPipe = unchecked(unchecked(0x23));
  49. internal const byte TransWaitNamedPipe = unchecked(unchecked(0x53));
  50. internal const byte TransCallNamedPipe = unchecked(unchecked(0x54));
  51. internal const byte TransTransactNamedPipe = unchecked(unchecked(0x26));
  52. protected internal int primarySetupOffset;
  53. protected internal int secondaryParameterOffset;
  54. protected internal int ParameterCount;
  55. protected internal int ParameterOffset;
  56. protected internal int ParameterDisplacement;
  57. protected internal int DataCount;
  58. protected internal int DataOffset;
  59. protected internal int DataDisplacement;
  60. internal int TotalParameterCount;
  61. internal int TotalDataCount;
  62. internal int MaxParameterCount;
  63. internal int MaxDataCount = DefaultMaxDataCount;
  64. internal byte MaxSetupCount;
  65. internal int Timeout = 0;
  66. internal int SetupCount = 1;
  67. internal byte SubCommand;
  68. internal string Name = string.Empty;
  69. internal int MaxBufferSize;
  70. internal byte[] TxnBuf;
  71. public SmbComTransaction()
  72. {
  73. // relative to headerStart
  74. // set in SmbTransport.sendTransaction() before nextElement called
  75. MaxParameterCount = 1024;
  76. primarySetupOffset = PrimarySetupOffset;
  77. secondaryParameterOffset = SecondaryParameterOffset;
  78. }
  79. internal override void Reset()
  80. {
  81. base.Reset();
  82. _isPrimary = _hasMore = true;
  83. }
  84. internal virtual void Reset(int key, string lastName)
  85. {
  86. Reset();
  87. }
  88. public virtual bool MoveNext()
  89. {
  90. return _hasMore;
  91. }
  92. public virtual object Current()
  93. {
  94. if (_isPrimary)
  95. {
  96. _isPrimary = false;
  97. ParameterOffset = primarySetupOffset + (SetupCount * 2) + 2;
  98. if (Command != SmbComNtTransact)
  99. {
  100. if (Command == SmbComTransaction && IsResponse() == false)
  101. {
  102. ParameterOffset += StringWireLength(Name, ParameterOffset);
  103. }
  104. }
  105. else
  106. {
  107. if (Command == SmbComNtTransact)
  108. {
  109. ParameterOffset += 2;
  110. }
  111. }
  112. _pad = ParameterOffset % PaddingSize;
  113. _pad = _pad == 0 ? 0 : PaddingSize - _pad;
  114. ParameterOffset += _pad;
  115. TotalParameterCount = WriteParametersWireFormat(TxnBuf, _bufParameterOffset);
  116. _bufDataOffset = TotalParameterCount;
  117. // data comes right after data
  118. int available = MaxBufferSize - ParameterOffset;
  119. ParameterCount = Math.Min(TotalParameterCount, available);
  120. available -= ParameterCount;
  121. DataOffset = ParameterOffset + ParameterCount;
  122. _pad1 = DataOffset % PaddingSize;
  123. _pad1 = _pad1 == 0 ? 0 : PaddingSize - _pad1;
  124. DataOffset += _pad1;
  125. TotalDataCount = WriteDataWireFormat(TxnBuf, _bufDataOffset);
  126. DataCount = Math.Min(TotalDataCount, available);
  127. }
  128. else
  129. {
  130. if (Command != SmbComNtTransact)
  131. {
  132. Command = SmbComTransactionSecondary;
  133. }
  134. else
  135. {
  136. Command = SmbComNtTransactSecondary;
  137. }
  138. // totalParameterCount and totalDataCount are set ok from primary
  139. ParameterOffset = SecondaryParameterOffset;
  140. if ((TotalParameterCount - ParameterDisplacement) > 0)
  141. {
  142. _pad = ParameterOffset % PaddingSize;
  143. _pad = _pad == 0 ? 0 : PaddingSize - _pad;
  144. ParameterOffset += _pad;
  145. }
  146. // caclulate parameterDisplacement before calculating new parameterCount
  147. ParameterDisplacement += ParameterCount;
  148. int available = MaxBufferSize - ParameterOffset - _pad;
  149. ParameterCount = Math.Min(TotalParameterCount - ParameterDisplacement, available);
  150. available -= ParameterCount;
  151. DataOffset = ParameterOffset + ParameterCount;
  152. _pad1 = DataOffset % PaddingSize;
  153. _pad1 = _pad1 == 0 ? 0 : PaddingSize - _pad1;
  154. DataOffset += _pad1;
  155. DataDisplacement += DataCount;
  156. available -= _pad1;
  157. DataCount = Math.Min(TotalDataCount - DataDisplacement, available);
  158. }
  159. if ((ParameterDisplacement + ParameterCount) >= TotalParameterCount
  160. && (DataDisplacement + DataCount) >= TotalDataCount)
  161. {
  162. _hasMore = false;
  163. }
  164. return this;
  165. }
  166. internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex)
  167. {
  168. int start = dstIndex;
  169. WriteInt2(TotalParameterCount, dst, dstIndex);
  170. dstIndex += 2;
  171. WriteInt2(TotalDataCount, dst, dstIndex);
  172. dstIndex += 2;
  173. if (Command != SmbComTransactionSecondary)
  174. {
  175. WriteInt2(MaxParameterCount, dst, dstIndex);
  176. dstIndex += 2;
  177. WriteInt2(MaxDataCount, dst, dstIndex);
  178. dstIndex += 2;
  179. dst[dstIndex++] = MaxSetupCount;
  180. dst[dstIndex++] = unchecked(unchecked(0x00));
  181. // Reserved1
  182. WriteInt2(_flags, dst, dstIndex);
  183. dstIndex += 2;
  184. WriteInt4(Timeout, dst, dstIndex);
  185. dstIndex += 4;
  186. dst[dstIndex++] = unchecked(unchecked(0x00));
  187. // Reserved2
  188. dst[dstIndex++] = unchecked(unchecked(0x00));
  189. }
  190. WriteInt2(ParameterCount, dst, dstIndex);
  191. dstIndex += 2;
  192. // writeInt2(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex );
  193. WriteInt2(ParameterOffset, dst, dstIndex);
  194. dstIndex += 2;
  195. if (Command == SmbComTransactionSecondary)
  196. {
  197. WriteInt2(ParameterDisplacement, dst, dstIndex);
  198. dstIndex += 2;
  199. }
  200. WriteInt2(DataCount, dst, dstIndex);
  201. dstIndex += 2;
  202. WriteInt2((DataCount == 0 ? 0 : DataOffset), dst, dstIndex);
  203. dstIndex += 2;
  204. if (Command == SmbComTransactionSecondary)
  205. {
  206. WriteInt2(DataDisplacement, dst, dstIndex);
  207. dstIndex += 2;
  208. }
  209. else
  210. {
  211. dst[dstIndex++] = unchecked((byte)SetupCount);
  212. dst[dstIndex++] = unchecked(unchecked(0x00));
  213. // Reserved3
  214. dstIndex += WriteSetupWireFormat(dst, dstIndex);
  215. }
  216. return dstIndex - start;
  217. }
  218. internal override int WriteBytesWireFormat(byte[] dst, int dstIndex)
  219. {
  220. int start = dstIndex;
  221. int p = _pad;
  222. if (Command == SmbComTransaction && IsResponse() == false)
  223. {
  224. dstIndex += WriteString(Name, dst, dstIndex);
  225. }
  226. if (ParameterCount > 0)
  227. {
  228. while (p-- > 0)
  229. {
  230. dst[dstIndex++] = unchecked(unchecked(0x00));
  231. }
  232. // Pad
  233. Array.Copy(TxnBuf, _bufParameterOffset, dst, dstIndex, ParameterCount);
  234. dstIndex += ParameterCount;
  235. }
  236. if (DataCount > 0)
  237. {
  238. p = _pad1;
  239. while (p-- > 0)
  240. {
  241. dst[dstIndex++] = unchecked(unchecked(0x00));
  242. }
  243. // Pad1
  244. Array.Copy(TxnBuf, _bufDataOffset, dst, dstIndex, DataCount);
  245. _bufDataOffset += DataCount;
  246. dstIndex += DataCount;
  247. }
  248. return dstIndex - start;
  249. }
  250. internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex)
  251. {
  252. return 0;
  253. }
  254. internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex)
  255. {
  256. return 0;
  257. }
  258. internal abstract int WriteSetupWireFormat(byte[] dst, int dstIndex);
  259. internal abstract int WriteParametersWireFormat(byte[] dst, int dstIndex);
  260. internal abstract int WriteDataWireFormat(byte[] dst, int dstIndex);
  261. internal abstract int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len);
  262. internal abstract int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int len);
  263. internal abstract int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len);
  264. public override string ToString()
  265. {
  266. return base.ToString()
  267. + ",totalParameterCount=" + TotalParameterCount
  268. + ",totalDataCount=" + TotalDataCount
  269. + ",maxParameterCount=" + MaxParameterCount
  270. + ",maxDataCount=" + MaxDataCount
  271. + ",maxSetupCount=" + (int)MaxSetupCount
  272. + ",flags=0x" + Hexdump.ToHexString(_flags, 2)
  273. + ",timeout=" + Timeout
  274. + ",parameterCount=" + ParameterCount
  275. + ",parameterOffset=" + ParameterOffset
  276. + ",parameterDisplacement=" + ParameterDisplacement
  277. + ",dataCount=" + DataCount
  278. + ",dataOffset=" + DataOffset
  279. + ",dataDisplacement=" + DataDisplacement
  280. + ",setupCount=" + SetupCount
  281. + ",pad=" + _pad
  282. + ",pad1=" + _pad1;
  283. }
  284. }
  285. }