SmbComTransaction.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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 = Config.GetInt("jcifs.smb.client.transaction_buf_size"
  24. , 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. ));
  50. internal const byte TransWaitNamedPipe = unchecked(unchecked(0x53
  51. ));
  52. internal const byte TransCallNamedPipe = unchecked(unchecked(0x54
  53. ));
  54. internal const byte TransTransactNamedPipe = unchecked(unchecked(0x26));
  55. protected internal int primarySetupOffset;
  56. protected internal int secondaryParameterOffset;
  57. protected internal int ParameterCount;
  58. protected internal int ParameterOffset;
  59. protected internal int ParameterDisplacement;
  60. protected internal int DataCount;
  61. protected internal int DataOffset;
  62. protected internal int DataDisplacement;
  63. internal int TotalParameterCount;
  64. internal int TotalDataCount;
  65. internal int MaxParameterCount;
  66. internal int MaxDataCount = DefaultMaxDataCount;
  67. internal byte MaxSetupCount;
  68. internal int Timeout = 0;
  69. internal int SetupCount = 1;
  70. internal byte SubCommand;
  71. internal string Name = string.Empty;
  72. internal int MaxBufferSize;
  73. internal byte[] TxnBuf;
  74. public SmbComTransaction()
  75. {
  76. // relative to headerStart
  77. // set in SmbTransport.sendTransaction() before nextElement called
  78. MaxParameterCount = 1024;
  79. primarySetupOffset = PrimarySetupOffset;
  80. secondaryParameterOffset = SecondaryParameterOffset;
  81. }
  82. internal override void Reset()
  83. {
  84. base.Reset();
  85. _isPrimary = _hasMore = true;
  86. }
  87. internal virtual void Reset(int key, string lastName)
  88. {
  89. Reset();
  90. }
  91. public virtual bool MoveNext()
  92. {
  93. return _hasMore;
  94. }
  95. public virtual object Current()
  96. {
  97. if (_isPrimary)
  98. {
  99. _isPrimary = false;
  100. ParameterOffset = primarySetupOffset + (SetupCount * 2) + 2;
  101. if (Command != SmbComNtTransact)
  102. {
  103. if (Command == SmbComTransaction && IsResponse() == false)
  104. {
  105. ParameterOffset += StringWireLength(Name, ParameterOffset);
  106. }
  107. }
  108. else
  109. {
  110. if (Command == SmbComNtTransact)
  111. {
  112. ParameterOffset += 2;
  113. }
  114. }
  115. _pad = ParameterOffset % PaddingSize;
  116. _pad = _pad == 0 ? 0 : PaddingSize - _pad;
  117. ParameterOffset += _pad;
  118. TotalParameterCount = WriteParametersWireFormat(TxnBuf, _bufParameterOffset);
  119. _bufDataOffset = TotalParameterCount;
  120. // data comes right after data
  121. int available = MaxBufferSize - ParameterOffset;
  122. ParameterCount = Math.Min(TotalParameterCount, available);
  123. available -= ParameterCount;
  124. DataOffset = ParameterOffset + ParameterCount;
  125. _pad1 = DataOffset % PaddingSize;
  126. _pad1 = _pad1 == 0 ? 0 : PaddingSize - _pad1;
  127. DataOffset += _pad1;
  128. TotalDataCount = WriteDataWireFormat(TxnBuf, _bufDataOffset);
  129. DataCount = Math.Min(TotalDataCount, available);
  130. }
  131. else
  132. {
  133. if (Command != SmbComNtTransact)
  134. {
  135. Command = SmbComTransactionSecondary;
  136. }
  137. else
  138. {
  139. Command = SmbComNtTransactSecondary;
  140. }
  141. // totalParameterCount and totalDataCount are set ok from primary
  142. ParameterOffset = SecondaryParameterOffset;
  143. if ((TotalParameterCount - ParameterDisplacement) > 0)
  144. {
  145. _pad = ParameterOffset % PaddingSize;
  146. _pad = _pad == 0 ? 0 : PaddingSize - _pad;
  147. ParameterOffset += _pad;
  148. }
  149. // caclulate parameterDisplacement before calculating new parameterCount
  150. ParameterDisplacement += ParameterCount;
  151. int available = MaxBufferSize - ParameterOffset - _pad;
  152. ParameterCount = Math.Min(TotalParameterCount - ParameterDisplacement, available);
  153. available -= ParameterCount;
  154. DataOffset = ParameterOffset + ParameterCount;
  155. _pad1 = DataOffset % PaddingSize;
  156. _pad1 = _pad1 == 0 ? 0 : PaddingSize - _pad1;
  157. DataOffset += _pad1;
  158. DataDisplacement += DataCount;
  159. available -= _pad1;
  160. DataCount = Math.Min(TotalDataCount - DataDisplacement, available);
  161. }
  162. if ((ParameterDisplacement + ParameterCount) >= TotalParameterCount && (DataDisplacement
  163. + DataCount) >= TotalDataCount)
  164. {
  165. _hasMore = false;
  166. }
  167. return this;
  168. }
  169. internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex)
  170. {
  171. int start = dstIndex;
  172. WriteInt2(TotalParameterCount, dst, dstIndex);
  173. dstIndex += 2;
  174. WriteInt2(TotalDataCount, dst, dstIndex);
  175. dstIndex += 2;
  176. if (Command != SmbComTransactionSecondary)
  177. {
  178. WriteInt2(MaxParameterCount, dst, dstIndex);
  179. dstIndex += 2;
  180. WriteInt2(MaxDataCount, dst, dstIndex);
  181. dstIndex += 2;
  182. dst[dstIndex++] = MaxSetupCount;
  183. dst[dstIndex++] = unchecked(unchecked(0x00));
  184. // Reserved1
  185. WriteInt2(_flags, dst, dstIndex);
  186. dstIndex += 2;
  187. WriteInt4(Timeout, dst, dstIndex);
  188. dstIndex += 4;
  189. dst[dstIndex++] = unchecked(unchecked(0x00));
  190. // Reserved2
  191. dst[dstIndex++] = unchecked(unchecked(0x00));
  192. }
  193. WriteInt2(ParameterCount, dst, dstIndex);
  194. dstIndex += 2;
  195. // writeInt2(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex );
  196. WriteInt2(ParameterOffset, dst, dstIndex);
  197. dstIndex += 2;
  198. if (Command == SmbComTransactionSecondary)
  199. {
  200. WriteInt2(ParameterDisplacement, dst, dstIndex);
  201. dstIndex += 2;
  202. }
  203. WriteInt2(DataCount, dst, dstIndex);
  204. dstIndex += 2;
  205. WriteInt2((DataCount == 0 ? 0 : DataOffset), dst, dstIndex);
  206. dstIndex += 2;
  207. if (Command == SmbComTransactionSecondary)
  208. {
  209. WriteInt2(DataDisplacement, dst, dstIndex);
  210. dstIndex += 2;
  211. }
  212. else
  213. {
  214. dst[dstIndex++] = unchecked((byte)SetupCount);
  215. dst[dstIndex++] = unchecked(unchecked(0x00));
  216. // Reserved3
  217. dstIndex += WriteSetupWireFormat(dst, dstIndex);
  218. }
  219. return dstIndex - start;
  220. }
  221. internal override int WriteBytesWireFormat(byte[] dst, int dstIndex)
  222. {
  223. int start = dstIndex;
  224. int p = _pad;
  225. if (Command == SmbComTransaction && IsResponse() == false)
  226. {
  227. dstIndex += WriteString(Name, dst, dstIndex);
  228. }
  229. if (ParameterCount > 0)
  230. {
  231. while (p-- > 0)
  232. {
  233. dst[dstIndex++] = unchecked(unchecked(0x00));
  234. }
  235. // Pad
  236. Array.Copy(TxnBuf, _bufParameterOffset, dst, dstIndex, ParameterCount);
  237. dstIndex += ParameterCount;
  238. }
  239. if (DataCount > 0)
  240. {
  241. p = _pad1;
  242. while (p-- > 0)
  243. {
  244. dst[dstIndex++] = unchecked(unchecked(0x00));
  245. }
  246. // Pad1
  247. Array.Copy(TxnBuf, _bufDataOffset, dst, dstIndex, DataCount);
  248. _bufDataOffset += DataCount;
  249. dstIndex += DataCount;
  250. }
  251. return dstIndex - start;
  252. }
  253. internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex
  254. )
  255. {
  256. return 0;
  257. }
  258. internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex)
  259. {
  260. return 0;
  261. }
  262. internal abstract int WriteSetupWireFormat(byte[] dst, int dstIndex);
  263. internal abstract int WriteParametersWireFormat(byte[] dst, int dstIndex);
  264. internal abstract int WriteDataWireFormat(byte[] dst, int dstIndex);
  265. internal abstract int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len
  266. );
  267. internal abstract int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int
  268. len);
  269. internal abstract int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len);
  270. public override string ToString()
  271. {
  272. return base.ToString() + ",totalParameterCount=" + TotalParameterCount
  273. + ",totalDataCount=" + TotalDataCount + ",maxParameterCount=" + MaxParameterCount
  274. + ",maxDataCount=" + MaxDataCount + ",maxSetupCount=" + (int)MaxSetupCount + ",flags=0x"
  275. + Hexdump.ToHexString(_flags, 2) + ",timeout=" + Timeout + ",parameterCount=" +
  276. ParameterCount + ",parameterOffset=" + ParameterOffset + ",parameterDisplacement="
  277. + ParameterDisplacement + ",dataCount=" + DataCount + ",dataOffset=" + DataOffset
  278. + ",dataDisplacement=" + DataDisplacement + ",setupCount=" + SetupCount + ",pad="
  279. + _pad + ",pad1=" + _pad1;
  280. }
  281. }
  282. }