ServerMessageBlock.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  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. using SharpCifs.Util.Sharpen;
  20. using SharpCifs.Util.Transport;
  21. namespace SharpCifs.Smb
  22. {
  23. public abstract class ServerMessageBlock : Response
  24. {
  25. internal static LogStream Log = LogStream.GetInstance();
  26. internal static long Ticks1601 = new DateTime(1601, 1, 1).Ticks;
  27. internal static readonly byte[] Header =
  28. {
  29. 0xFF, (byte)('S'), (byte)('M'), (byte)('B'), 0x00,
  30. 0x00, 0x00, 0x00, 0x00, 0x00,
  31. 0x00, 0x00, 0x00, 0x00, 0x00,
  32. 0x00, 0x00, 0x00, 0x00, 0x00,
  33. 0x00, 0x00, 0x00, 0x00
  34. };
  35. internal static void WriteInt2(long val, byte[] dst, int dstIndex)
  36. {
  37. dst[dstIndex] = unchecked((byte)(val));
  38. dst[++dstIndex] = unchecked((byte)(val >> 8));
  39. }
  40. internal static void WriteInt4(long val, byte[] dst, int dstIndex)
  41. {
  42. dst[dstIndex] = unchecked((byte)(val));
  43. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  44. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  45. dst[++dstIndex] = unchecked((byte)(val >> 8));
  46. }
  47. internal static int ReadInt2(byte[] src, int srcIndex)
  48. {
  49. return unchecked(src[srcIndex] & 0xFF)
  50. + ((src[srcIndex + 1] & 0xFF) << 8);
  51. }
  52. internal static int ReadInt4(byte[] src, int srcIndex)
  53. {
  54. return unchecked(src[srcIndex] & 0xFF)
  55. + ((src[srcIndex + 1] & 0xFF) << 8)
  56. + ((src[srcIndex + 2] & 0xFF) << 16)
  57. + ((src[srcIndex + 3] & 0xFF) << 24);
  58. }
  59. internal static long ReadInt8(byte[] src, int srcIndex)
  60. {
  61. return unchecked(ReadInt4(src, srcIndex) & unchecked(0xFFFFFFFFL))
  62. + unchecked((long)(ReadInt4(src, srcIndex + 4)) << 32);
  63. }
  64. internal static void WriteInt8(long val, byte[] dst, int dstIndex)
  65. {
  66. dst[dstIndex] = unchecked((byte)(val));
  67. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  68. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  69. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  70. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  71. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  72. dst[++dstIndex] = unchecked((byte)(val >>= 8));
  73. dst[++dstIndex] = unchecked((byte)(val >> 8));
  74. }
  75. internal static long ReadTime(byte[] src, int srcIndex)
  76. {
  77. int low = ReadInt4(src, srcIndex);
  78. int hi = ReadInt4(src, srcIndex + 4);
  79. long t = ((long)hi << (int)32L) | (low & unchecked((long)(0xFFFFFFFFL)));
  80. t = (t / 10000L - SmbConstants.MillisecondsBetween1970And1601);
  81. return t;
  82. }
  83. internal static void WriteTime(long t, byte[] dst, int dstIndex)
  84. {
  85. if (t != 0L)
  86. {
  87. t = (t + SmbConstants.MillisecondsBetween1970And1601) * 10000L;
  88. }
  89. WriteInt8(t, dst, dstIndex);
  90. }
  91. internal static long ReadUTime(byte[] buffer, int bufferIndex)
  92. {
  93. return ReadInt4(buffer, bufferIndex) * 1000L;
  94. }
  95. internal static void WriteUTime(long t, byte[] dst, int dstIndex)
  96. {
  97. if (t == 0L || t == unchecked((long)(0xFFFFFFFFFFFFFFFFL)))
  98. {
  99. WriteInt4(unchecked((int)(0xFFFFFFFF)), dst, dstIndex);
  100. return;
  101. }
  102. // t isn't in DST either
  103. WriteInt4((int)(t / 1000L), dst, dstIndex);
  104. }
  105. internal const byte SmbComCreateDirectory = 0x00;
  106. internal const byte SmbComDeleteDirectory = 0x01;
  107. internal const byte SmbComClose = 0x04;
  108. internal const byte SmbComDelete = 0x06;
  109. internal const byte SmbComRename = 0x07;
  110. internal const byte SmbComQueryInformation = 0x08;
  111. internal const byte SmbComWrite = 0x0B;
  112. internal const byte SmbComCheckDirectory = 0x10;
  113. internal const byte SmbComTransaction = 0x25;
  114. internal const byte SmbComTransactionSecondary = 0x26;
  115. internal const byte SmbComMove = 0x2A;
  116. internal const byte SmbComEcho = 0x2B;
  117. internal const byte SmbComOpenAndx = 0x2D;
  118. internal const byte SmbComReadAndx = 0x2E;
  119. internal const byte SmbComWriteAndx = 0x2F;
  120. internal const byte SmbComTransaction2 = 0x32;
  121. internal const byte SmbComFindClose2 = 0x34;
  122. internal const byte SmbComTreeDisconnect = 0x71;
  123. internal const byte SmbComNegotiate = 0x72;
  124. internal const byte SmbComSessionSetupAndx = 0x73;
  125. internal const byte SmbComLogoffAndx = 0x74;
  126. internal const byte SmbComTreeConnectAndx = 0x75;
  127. internal const byte SmbComNtTransact = 0xA0;
  128. internal const byte SmbComNtTransactSecondary = 0xA1;
  129. internal const byte SmbComNtCreateAndx = 0xA2;
  130. internal byte Command;
  131. internal byte Flags;
  132. internal int HeaderStart;
  133. internal int Length;
  134. internal int BatchLevel;
  135. internal int ErrorCode;
  136. internal int Flags2;
  137. internal int Tid;
  138. internal int Pid;
  139. internal int Uid;
  140. internal int Mid;
  141. internal int WordCount;
  142. internal int ByteCount;
  143. internal bool UseUnicode;
  144. internal bool Received;
  145. internal bool ExtendedSecurity;
  146. internal long ResponseTimeout = 1;
  147. internal int SignSeq;
  148. internal bool VerifyFailed;
  149. internal NtlmPasswordAuthentication Auth = null;
  150. internal string Path;
  151. internal SigningDigest Digest;
  152. internal ServerMessageBlock Response;
  153. public ServerMessageBlock()
  154. {
  155. Flags = unchecked(
  156. (byte)(SmbConstants.FlagsPathNamesCaseless
  157. | SmbConstants.FlagsPathNamesCanonicalized)
  158. );
  159. Pid = SmbConstants.Pid;
  160. BatchLevel = 0;
  161. }
  162. internal virtual void Reset()
  163. {
  164. Flags = unchecked(
  165. (byte)(SmbConstants.FlagsPathNamesCaseless
  166. | SmbConstants.FlagsPathNamesCanonicalized)
  167. );
  168. Flags2 = 0;
  169. ErrorCode = 0;
  170. Received = false;
  171. Digest = null;
  172. }
  173. internal virtual int WriteString(string str, byte[] dst, int dstIndex)
  174. {
  175. return WriteString(str, dst, dstIndex, UseUnicode);
  176. }
  177. internal virtual int WriteString(string str, byte[] dst, int dstIndex, bool useUnicode)
  178. {
  179. int start = dstIndex;
  180. try
  181. {
  182. if (useUnicode)
  183. {
  184. // Unicode requires word alignment
  185. if (((dstIndex - HeaderStart) % 2) != 0)
  186. {
  187. dst[dstIndex++] = (byte)('\0');
  188. }
  189. Array.Copy(Runtime.GetBytesForString(str, SmbConstants.UniEncoding),
  190. 0, dst, dstIndex, str.Length * 2);
  191. dstIndex += str.Length * 2;
  192. dst[dstIndex++] = (byte)('\0');
  193. dst[dstIndex++] = (byte)('\0');
  194. }
  195. else
  196. {
  197. byte[] b = Runtime.GetBytesForString(str, SmbConstants.OemEncoding);
  198. Array.Copy(b, 0, dst, dstIndex, b.Length);
  199. dstIndex += b.Length;
  200. dst[dstIndex++] = (byte)('\0');
  201. }
  202. }
  203. catch (UnsupportedEncodingException uee)
  204. {
  205. if (Log.Level > 1)
  206. {
  207. Runtime.PrintStackTrace(uee, Log);
  208. }
  209. }
  210. return dstIndex - start;
  211. }
  212. internal virtual string ReadString(byte[] src, int srcIndex)
  213. {
  214. return ReadString(src, srcIndex, 256, UseUnicode);
  215. }
  216. internal virtual string ReadString(byte[] src, int srcIndex, int maxLen, bool useUnicode)
  217. {
  218. int len = 0;
  219. string str = null;
  220. try
  221. {
  222. if (useUnicode)
  223. {
  224. // Unicode requires word alignment
  225. if (((srcIndex - HeaderStart) % 2) != 0)
  226. {
  227. srcIndex++;
  228. }
  229. while (src[srcIndex + len] != 0x00 || src[srcIndex
  230. + len + 1] != 0x00)
  231. {
  232. len += 2;
  233. if (len > maxLen)
  234. {
  235. if (Log.Level > 0)
  236. {
  237. Hexdump.ToHexdump(Console.Error,
  238. src,
  239. srcIndex,
  240. maxLen < 128
  241. ? maxLen + 8
  242. : 128);
  243. }
  244. throw new RuntimeException("zero termination not found");
  245. }
  246. }
  247. str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.UniEncoding);
  248. }
  249. else
  250. {
  251. while (src[srcIndex + len] != 0x00)
  252. {
  253. len++;
  254. if (len > maxLen)
  255. {
  256. if (Log.Level > 0)
  257. {
  258. Hexdump.ToHexdump(Console.Error,
  259. src,
  260. srcIndex,
  261. maxLen < 128
  262. ? maxLen + 8
  263. : 128);
  264. }
  265. throw new RuntimeException("zero termination not found");
  266. }
  267. }
  268. str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.OemEncoding);
  269. }
  270. }
  271. catch (UnsupportedEncodingException uee)
  272. {
  273. if (Log.Level > 1)
  274. {
  275. Runtime.PrintStackTrace(uee, Log);
  276. }
  277. }
  278. return str;
  279. }
  280. internal virtual string ReadString(byte[] src,
  281. int srcIndex,
  282. int srcEnd,
  283. int maxLen,
  284. bool useUnicode)
  285. {
  286. int len = 0;
  287. string str = null;
  288. try
  289. {
  290. if (useUnicode)
  291. {
  292. // Unicode requires word alignment
  293. if (((srcIndex - HeaderStart) % 2) != 0)
  294. {
  295. srcIndex++;
  296. }
  297. for (len = 0; (srcIndex + len + 1) < srcEnd; len += 2)
  298. {
  299. if (src[srcIndex + len] == 0x00 && src[srcIndex + len + 1] == 0x00)
  300. {
  301. break;
  302. }
  303. if (len > maxLen)
  304. {
  305. if (Log.Level > 0)
  306. {
  307. Hexdump.ToHexdump(Console.Error,
  308. src,
  309. srcIndex,
  310. maxLen < 128
  311. ? maxLen + 8
  312. : 128);
  313. }
  314. throw new RuntimeException("zero termination not found");
  315. }
  316. }
  317. str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.UniEncoding);
  318. }
  319. else
  320. {
  321. for (len = 0; srcIndex < srcEnd; len++)
  322. {
  323. if (src[srcIndex + len] == 0x00)
  324. {
  325. break;
  326. }
  327. if (len > maxLen)
  328. {
  329. if (Log.Level > 0)
  330. {
  331. Hexdump.ToHexdump(Console.Error,
  332. src,
  333. srcIndex,
  334. maxLen < 128
  335. ? maxLen + 8
  336. : 128);
  337. }
  338. throw new RuntimeException("zero termination not found");
  339. }
  340. }
  341. str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.OemEncoding);
  342. }
  343. }
  344. catch (UnsupportedEncodingException uee)
  345. {
  346. if (Log.Level > 1)
  347. {
  348. Runtime.PrintStackTrace(uee, Log);
  349. }
  350. }
  351. return str;
  352. }
  353. internal virtual int StringWireLength(string str, int offset)
  354. {
  355. int len = str.Length + 1;
  356. if (UseUnicode)
  357. {
  358. len = str.Length * 2 + 2;
  359. len = (offset % 2) != 0 ? len + 1 : len;
  360. }
  361. return len;
  362. }
  363. internal virtual int ReadStringLength(byte[] src, int srcIndex, int max)
  364. {
  365. int len = 0;
  366. while (src[srcIndex + len] != 0x00)
  367. {
  368. if (len++ > max)
  369. {
  370. throw new RuntimeException("zero termination not found: " + this);
  371. }
  372. }
  373. return len;
  374. }
  375. internal virtual int Encode(byte[] dst, int dstIndex)
  376. {
  377. int start = HeaderStart = dstIndex;
  378. dstIndex += WriteHeaderWireFormat(dst, dstIndex);
  379. WordCount = WriteParameterWordsWireFormat(dst, dstIndex + 1);
  380. dst[dstIndex++] = unchecked((byte)((WordCount / 2) & 0xFF));
  381. dstIndex += WordCount;
  382. WordCount /= 2;
  383. ByteCount = WriteBytesWireFormat(dst, dstIndex + 2);
  384. dst[dstIndex++] = unchecked((byte)(ByteCount & 0xFF));
  385. dst[dstIndex++] = unchecked((byte)((ByteCount >> 8) & 0xFF));
  386. dstIndex += ByteCount;
  387. Length = dstIndex - start;
  388. if (Digest != null)
  389. {
  390. Digest.Sign(dst, HeaderStart, Length, this, Response);
  391. }
  392. return Length;
  393. }
  394. internal virtual int Decode(byte[] buffer, int bufferIndex)
  395. {
  396. int start = HeaderStart = bufferIndex;
  397. bufferIndex += ReadHeaderWireFormat(buffer, bufferIndex);
  398. WordCount = buffer[bufferIndex++];
  399. if (WordCount != 0)
  400. {
  401. int n;
  402. if ((n = ReadParameterWordsWireFormat(buffer, bufferIndex)) != WordCount * 2)
  403. {
  404. if (Log.Level >= 5)
  405. {
  406. Log.WriteLine("wordCount * 2=" + (WordCount * 2)
  407. + " but readParameterWordsWireFormat returned " + n);
  408. }
  409. }
  410. bufferIndex += WordCount * 2;
  411. }
  412. ByteCount = ReadInt2(buffer, bufferIndex);
  413. bufferIndex += 2;
  414. if (ByteCount != 0)
  415. {
  416. int n;
  417. if ((n = ReadBytesWireFormat(buffer, bufferIndex)) != ByteCount)
  418. {
  419. if (Log.Level >= 5)
  420. {
  421. Log.WriteLine("byteCount=" + ByteCount
  422. + " but readBytesWireFormat returned " + n);
  423. }
  424. }
  425. // Don't think we can rely on n being correct here. Must use byteCount.
  426. // Last paragraph of section 3.13.3 eludes to this.
  427. bufferIndex += ByteCount;
  428. }
  429. Length = bufferIndex - start;
  430. return Length;
  431. }
  432. internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex)
  433. {
  434. Array.Copy(Header, 0, dst, dstIndex, Header.Length);
  435. dst[dstIndex + SmbConstants.CmdOffset] = Command;
  436. dst[dstIndex + SmbConstants.FlagsOffset] = Flags;
  437. WriteInt2(Flags2, dst, dstIndex + SmbConstants.FlagsOffset + 1);
  438. dstIndex += SmbConstants.TidOffset;
  439. WriteInt2(Tid, dst, dstIndex);
  440. WriteInt2(Pid, dst, dstIndex + 2);
  441. WriteInt2(Uid, dst, dstIndex + 4);
  442. WriteInt2(Mid, dst, dstIndex + 6);
  443. return SmbConstants.HeaderLength;
  444. }
  445. internal virtual int ReadHeaderWireFormat(byte[] buffer, int bufferIndex)
  446. {
  447. Command = buffer[bufferIndex + SmbConstants.CmdOffset];
  448. ErrorCode = ReadInt4(buffer, bufferIndex + SmbConstants.ErrorCodeOffset);
  449. Flags = buffer[bufferIndex + SmbConstants.FlagsOffset];
  450. Flags2 = ReadInt2(buffer, bufferIndex + SmbConstants.FlagsOffset + 1);
  451. Tid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset);
  452. Pid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset + 2);
  453. Uid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset + 4);
  454. Mid = ReadInt2(buffer, bufferIndex + SmbConstants.TidOffset + 6);
  455. return SmbConstants.HeaderLength;
  456. }
  457. internal virtual bool IsResponse()
  458. {
  459. return (Flags & SmbConstants.FlagsResponse) == SmbConstants.FlagsResponse;
  460. }
  461. internal abstract int WriteParameterWordsWireFormat(byte[] dst, int dstIndex);
  462. internal abstract int WriteBytesWireFormat(byte[] dst, int dstIndex);
  463. internal abstract int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex);
  464. internal abstract int ReadBytesWireFormat(byte[] buffer, int bufferIndex);
  465. public override int GetHashCode()
  466. {
  467. return Mid;
  468. }
  469. public override bool Equals(object obj)
  470. {
  471. return obj is ServerMessageBlock && ((ServerMessageBlock)obj).Mid == Mid;
  472. }
  473. public override string ToString()
  474. {
  475. string c;
  476. switch (Command)
  477. {
  478. case SmbComNegotiate:
  479. {
  480. c = "SMB_COM_NEGOTIATE";
  481. break;
  482. }
  483. case SmbComSessionSetupAndx:
  484. {
  485. c = "SMB_COM_SESSION_SETUP_ANDX";
  486. break;
  487. }
  488. case SmbComTreeConnectAndx:
  489. {
  490. c = "SMB_COM_TREE_CONNECT_ANDX";
  491. break;
  492. }
  493. case SmbComQueryInformation:
  494. {
  495. c = "SMB_COM_QUERY_INFORMATION";
  496. break;
  497. }
  498. case SmbComCheckDirectory:
  499. {
  500. c = "SMB_COM_CHECK_DIRECTORY";
  501. break;
  502. }
  503. case SmbComTransaction:
  504. {
  505. c = "SMB_COM_TRANSACTION";
  506. break;
  507. }
  508. case SmbComTransaction2:
  509. {
  510. c = "SMB_COM_TRANSACTION2";
  511. break;
  512. }
  513. case SmbComTransactionSecondary:
  514. {
  515. c = "SMB_COM_TRANSACTION_SECONDARY";
  516. break;
  517. }
  518. case SmbComFindClose2:
  519. {
  520. c = "SMB_COM_FIND_CLOSE2";
  521. break;
  522. }
  523. case SmbComTreeDisconnect:
  524. {
  525. c = "SMB_COM_TREE_DISCONNECT";
  526. break;
  527. }
  528. case SmbComLogoffAndx:
  529. {
  530. c = "SMB_COM_LOGOFF_ANDX";
  531. break;
  532. }
  533. case SmbComEcho:
  534. {
  535. c = "SMB_COM_ECHO";
  536. break;
  537. }
  538. case SmbComMove:
  539. {
  540. c = "SMB_COM_MOVE";
  541. break;
  542. }
  543. case SmbComRename:
  544. {
  545. c = "SMB_COM_RENAME";
  546. break;
  547. }
  548. case SmbComDelete:
  549. {
  550. c = "SMB_COM_DELETE";
  551. break;
  552. }
  553. case SmbComDeleteDirectory:
  554. {
  555. c = "SMB_COM_DELETE_DIRECTORY";
  556. break;
  557. }
  558. case SmbComNtCreateAndx:
  559. {
  560. c = "SMB_COM_NT_CREATE_ANDX";
  561. break;
  562. }
  563. case SmbComOpenAndx:
  564. {
  565. c = "SMB_COM_OPEN_ANDX";
  566. break;
  567. }
  568. case SmbComReadAndx:
  569. {
  570. c = "SMB_COM_READ_ANDX";
  571. break;
  572. }
  573. case SmbComClose:
  574. {
  575. c = "SMB_COM_CLOSE";
  576. break;
  577. }
  578. case SmbComWriteAndx:
  579. {
  580. c = "SMB_COM_WRITE_ANDX";
  581. break;
  582. }
  583. case SmbComCreateDirectory:
  584. {
  585. c = "SMB_COM_CREATE_DIRECTORY";
  586. break;
  587. }
  588. case SmbComNtTransact:
  589. {
  590. c = "SMB_COM_NT_TRANSACT";
  591. break;
  592. }
  593. case SmbComNtTransactSecondary:
  594. {
  595. c = "SMB_COM_NT_TRANSACT_SECONDARY";
  596. break;
  597. }
  598. default:
  599. {
  600. c = "UNKNOWN";
  601. break;
  602. }
  603. }
  604. string str = ErrorCode == 0
  605. ? "0"
  606. : SmbException.GetMessageByCode(ErrorCode);
  607. return "command=" + c
  608. + ",received=" + Received
  609. + ",errorCode=" + str
  610. + ",flags=0x" + Hexdump.ToHexString(Flags & 0xFF, 4)
  611. + ",flags2=0x" + Hexdump.ToHexString(Flags2, 4)
  612. + ",signSeq=" + SignSeq
  613. + ",tid=" + Tid
  614. + ",pid=" + Pid
  615. + ",uid=" + Uid
  616. + ",mid=" + Mid
  617. + ",wordCount=" + WordCount
  618. + ",byteCount=" + ByteCount;
  619. }
  620. }
  621. }