Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1202 lines
56 KiB

  1. /****************************************************************************/
  2. // mcs.h
  3. //
  4. // MCS Class header file
  5. //
  6. // Copyright (C) 1997-1999 Microsoft Corporation
  7. /****************************************************************************/
  8. #ifndef _H_MCS
  9. #define _H_MCS
  10. extern "C" {
  11. #include <adcgdata.h>
  12. }
  13. #include "objs.h"
  14. #include "cd.h"
  15. #define TRC_FILE "mcs"
  16. #define TRC_GROUP TRC_GROUP_NETWORK
  17. // This constant is the equivalent with the one defined by the mcsimpl.h on
  18. // the servers side. The meaning of it is the fact that the input buffers
  19. // have to be actually bigger with 8 bytes to avoid any overread in the
  20. // decompression routines. The decompression function does not strictly
  21. // check the input pointers for overread (for performance reasons) so it
  22. // can overread a maximum of 7 bytes. The bias will make the input buffer
  23. // 8 bytes bigger so the overread can't happen.
  24. #define MCS_INPUT_BUFFER_BIAS 8
  25. /****************************************************************************/
  26. /* MCS result codes. */
  27. /****************************************************************************/
  28. #define MCS_RESULT_SUCCESSFUL 0
  29. #define MCS_RESULT_DOMAIN_MERGING 1
  30. #define MCS_RESULT_DOMAIN_NOT_HIERARCHICAL 2
  31. #define MCS_RESULT_NO_SUCH_CHANNEL 3
  32. #define MCS_RESULT_NO_SUCH_DOMAIN 4
  33. #define MCS_RESULT_NO_SUCH_USER 5
  34. #define MCS_RESULT_NOT_ADMITTED 6
  35. #define MCS_RESULT_OTHER_USER_ID 7
  36. #define MCS_RESULT_PARAMETERS_UNACCEPTABLE 8
  37. #define MCS_RESULT_TOKEN_NOT_AVAILABLE 9
  38. #define MCS_RESULT_TOKEN_NOT_POSSESSED 10
  39. #define MCS_RESULT_TOO_MANY_CHANNELS 11
  40. #define MCS_RESULT_TOO_MANY_TOKENS 12
  41. #define MCS_RESULT_TOO_MANY_USERS 13
  42. #define MCS_RESULT_UNSPECIFIED_FAILURE 14
  43. #define MCS_RESULT_USER_REJECTED 15
  44. /****************************************************************************/
  45. /* MCS reason codes. */
  46. /****************************************************************************/
  47. #define MCS_REASON_DOMAIN_DISCONNECTED 0
  48. #define MCS_REASON_PROVIDER_INITIATED 1
  49. #define MCS_REASON_TOKEN_PURGED 2
  50. #define MCS_REASON_USER_REQUESTED 3
  51. #define MCS_REASON_CHANNEL_PURGED 4
  52. /****************************************************************************/
  53. /* Buffer handle (returned on MCS_GetBuffer). */
  54. /****************************************************************************/
  55. typedef ULONG_PTR MCS_BUFHND;
  56. typedef MCS_BUFHND DCPTR PMCS_BUFHND;
  57. #define MCS_INVALID_CHANNEL_ID 0xFFFF
  58. /****************************************************************************/
  59. // MCS_SetDataLengthToReceive
  60. //
  61. // Mcro to allow XT to set up the required length for MCS data buffer
  62. // reception.
  63. /****************************************************************************/
  64. #define MCS_SetDataLengthToReceive(mcsinst, len) \
  65. (##mcsinst)->_MCS.dataBytesNeeded = (len); \
  66. (##mcsinst)->_MCS.dataBytesRead = 0;
  67. /****************************************************************************/
  68. // MCS_RecvToDataBuf
  69. //
  70. // Receives data into the MCS data buffer. Implemented as a macro for speed
  71. // and for easy use within XT for fast-path output receives. rc is:
  72. // S_OK if all the data is finished.
  73. // S_FALSE if there is more data.
  74. // E_* if an error occurred.
  75. /****************************************************************************/
  76. #define MCS_RecvToDataBuf(rc, xtinst, mcsinst) { \
  77. unsigned bytesRecv; \
  78. \
  79. /* Make sure that we're expected to receive some data. */ \
  80. TRC_ASSERT(((mcsinst)->_MCS.dataBytesNeeded != 0), (TB, _T("No data to receive"))); \
  81. TRC_ASSERT(((mcsinst)->_MCS.dataBytesNeeded < 65535), \
  82. (TB,_T("Data recv size %u too large"), (mcsinst)->_MCS.dataBytesNeeded)); \
  83. TRC_ASSERT(((mcsinst)->_MCS.pReceivedPacket != NULL), \
  84. (TB, _T("Null rcv packet buffer"))); \
  85. \
  86. if (((mcsinst)->_MCS.dataBytesRead + (mcsinst)->_MCS.dataBytesNeeded <= \
  87. sizeof((mcsinst)->_MCS.dataBuf) - 2 - MCS_INPUT_BUFFER_BIAS)) \
  88. { \
  89. /* Get some data into the data buffer. */ \
  90. bytesRecv = ##xtinst->XT_Recv((mcsinst)->_MCS.pReceivedPacket + (mcsinst)->_MCS.dataBytesRead, \
  91. (mcsinst)->_MCS.dataBytesNeeded); \
  92. TRC_ASSERT((bytesRecv <= (mcsinst)->_MCS.dataBytesNeeded), \
  93. (TB,_T("XT_Recv returned more bytes read (%u) than requested (%u)"), \
  94. bytesRecv, (mcsinst)->_MCS.dataBytesNeeded)); \
  95. (mcsinst)->_MCS.dataBytesNeeded -= bytesRecv; \
  96. (mcsinst)->_MCS.dataBytesRead += bytesRecv; \
  97. rc = ((mcsinst)->_MCS.dataBytesNeeded == 0) ? S_OK : S_FALSE; \
  98. } \
  99. else \
  100. { \
  101. TRC_ABORT((TB, _T("Data buffer size %u too small for %u read + %u needed"), \
  102. sizeof((mcsinst)->_MCS.dataBuf) - 2 - MCS_INPUT_BUFFER_BIAS, \
  103. (mcsinst)->_MCS.dataBytesRead, \
  104. (mcsinst)->_MCS.dataBytesNeeded)); \
  105. rc = E_ABORT; \
  106. } \
  107. }
  108. //
  109. // Internal use
  110. //
  111. /****************************************************************************/
  112. /* */
  113. /* DEFINITIONS */
  114. /* */
  115. /****************************************************************************/
  116. /****************************************************************************/
  117. /* MCS receive state variables. */
  118. /****************************************************************************/
  119. #define MCS_RCVST_PDUENCODING 1
  120. #define MCS_RCVST_BERHEADER 2
  121. #define MCS_RCVST_BERLENGTH 3
  122. #define MCS_RCVST_CONTROL 4
  123. #define MCS_RCVST_DATA 5
  124. /****************************************************************************/
  125. /* MCS receive data state variables. */
  126. /****************************************************************************/
  127. #define MCS_DATAST_SIZE1 1
  128. #define MCS_DATAST_SIZE2 2
  129. #define MCS_DATAST_SIZE3 3
  130. #define MCS_DATAST_READFRAG 4
  131. #define MCS_DATAST_READREMAINDER 5
  132. /****************************************************************************/
  133. /* Number of bytes required to determine the MCS PDU encoding. */
  134. /****************************************************************************/
  135. #define MCS_NUM_PDUENCODING_BYTES 1
  136. /****************************************************************************/
  137. /* Size of the common part of an MCS header. */
  138. /****************************************************************************/
  139. #define MCS_SIZE_HEADER 3
  140. /****************************************************************************/
  141. /* The MCS BER connect PDU prefix. */
  142. /****************************************************************************/
  143. #define MCS_BER_CONNECT_PREFIX 0x7F
  144. /****************************************************************************/
  145. /* Maximum length of the size data in a PER encoded MCS PDU. */
  146. /****************************************************************************/
  147. #define MCS_MAX_SIZE_DATA_LENGTH 2
  148. /****************************************************************************/
  149. /* Maximum length of a MCS header. */
  150. /****************************************************************************/
  151. #define MCS_DEFAULT_HEADER_LENGTH 4096
  152. /****************************************************************************/
  153. /* Maximum length of a T.Share packet. */
  154. /****************************************************************************/
  155. #ifdef DC_HICOLOR
  156. #define MCS_MAX_RCVPKT_LENGTH (1024*16)
  157. #else
  158. #define MCS_MAX_RCVPKT_LENGTH (1024*12)
  159. #endif
  160. /****************************************************************************/
  161. /* Maximum length of a MCS packet to be sent. */
  162. /****************************************************************************/
  163. #define MCS_MAX_SNDPKT_LENGTH 16384
  164. /****************************************************************************/
  165. /* MCS user IDs are encoded as constrained integers in the range */
  166. /* 1001-65535. The packed encoding rules (PER) encoded this as an integer */
  167. /* starting at 0, so we need this constant in decode/encode user-ids. */
  168. /****************************************************************************/
  169. #define MCS_USERID_PER_OFFSET 1001
  170. /****************************************************************************/
  171. /* Number of fields in a MCS connect-response PDU. */
  172. /****************************************************************************/
  173. #define MCS_CRPDU_NUMFIELDS 4
  174. /****************************************************************************/
  175. /* Field offsets within a MCS connect-response PDU. */
  176. /****************************************************************************/
  177. #define MCS_CRPDU_RESULTOFFSET 0
  178. #define MCS_CRPDU_USERDATAOFFSET 3
  179. /****************************************************************************/
  180. /* Length of the connect-response result field. */
  181. /****************************************************************************/
  182. #define MCS_CR_RESULTLEN 1
  183. /****************************************************************************/
  184. /* PER encoded field lengths and masks. The lengths are in bits. */
  185. /****************************************************************************/
  186. #define MCS_PDUTYPELENGTH 6
  187. #define MCS_PDUTYPEMASK 0xFC
  188. #define MCS_RESULTCODELENGTH 4
  189. #define MCS_RESULTCODEMASK 0xF
  190. #define MCS_REASONCODELENGTH 3
  191. #define MCS_REASONCODEMASK 0x7
  192. /****************************************************************************/
  193. /* Offsets for the following: */
  194. /* */
  195. /* - result and reason codes. */
  196. /* - optional fields (user-id in AUC and channel-id in CJC). */
  197. /****************************************************************************/
  198. #define MCS_AUC_RESULTCODEOFFSET 7
  199. #define MCS_AUC_OPTIONALUSERIDLENGTH 1
  200. #define MCS_AUC_OPTIONALUSERIDMASK 0x02
  201. #define MCS_CJC_RESULTCODEOFFSET 7
  202. #define MCS_CJC_OPTIONALCHANNELIDLENGTH 1
  203. #define MCS_CJC_OPTIONALCHANNELIDMASK 0x02
  204. #define MCS_DPUM_REASONCODEOFFSET 6
  205. /****************************************************************************/
  206. /* MCS PDU types. */
  207. /****************************************************************************/
  208. #define MCS_TYPE_UNKNOWN 0
  209. #define MCS_TYPE_CONNECTINITIAL 0x65
  210. #define MCS_TYPE_CONNECTRESPONSE 0x66
  211. #define MCS_TYPE_ATTACHUSERREQUEST 0x28
  212. #define MCS_TYPE_ATTACHUSERCONFIRM 0x2C
  213. #define MCS_TYPE_DETACHUSERREQUEST 0x30
  214. #define MCS_TYPE_DETACHUSERINDICATION 0x34
  215. #define MCS_TYPE_CHANNELJOINREQUEST 0x38
  216. #define MCS_TYPE_CHANNELJOINCONFIRM 0x3C
  217. #define MCS_TYPE_SENDDATAREQUEST 0x64
  218. #define MCS_TYPE_SENDDATAINDICATION 0x68
  219. #define MCS_TYPE_DISCONNECTPROVIDERUM 0x20
  220. /****************************************************************************/
  221. /* Masks used to identify the segmentation flags in a Send-Data-Indication */
  222. /* PDU. */
  223. /****************************************************************************/
  224. #define MCS_SDI_BEGINSEGMASK 0x20
  225. #define MCS_SDI_ENDSEGMASK 0x10
  226. /****************************************************************************/
  227. /* MCS hard-coded PDUs - first of all MCS connect initial. */
  228. /****************************************************************************/
  229. #define MCS_DATA_CONNECTINITIAL \
  230. {0x657F, /* PDU type. 7F65 = CI */ \
  231. 0x82, 0x00, /* PDU length (length > 128) */ \
  232. 0x04, 0x01, 0x01, /* Calling domain selector */ \
  233. 0x04, 0x01, 0x01, /* Called domain selector */ \
  234. 0x01, 0x01, 0xFF, /* Upward flag */ \
  235. 0x30, 0x19, /* Target domain params */ \
  236. 0x02, 0x01, 0x22, /* Max channel IDs */ \
  237. 0x02, 0x01, 0x02, /* Max user IDs */ \
  238. 0x02, 0x01, 0x00, /* Max token IDs */ \
  239. 0x02, 0x01, 0x01, /* Number of priorities */ \
  240. 0x02, 0x01, 0x00, /* Min throughput */ \
  241. 0x02, 0x01, 0x01, /* Max height */ \
  242. 0x02, 0x02, 0xFF, 0xFF, /* Max MCSPDU size */ \
  243. 0x02, 0x01, 0x02, /* Protocol version */ \
  244. 0x30, 0x19, /* Minimum domain parameters */ \
  245. 0x02, 0x01, 0x01, /* Max channel IDs */ \
  246. 0x02, 0x01, 0x01, /* Max user IDs */ \
  247. 0x02, 0x01, 0x01, /* Max token IDs */ \
  248. 0x02, 0x01, 0x01, /* Number of priorities */ \
  249. 0x02, 0x01, 0x00, /* Min throughput */ \
  250. 0x02, 0x01, 0x01, /* Max height */ \
  251. 0x02, 0x02, 0x04, 0x20, /* Max MCSPDU size */ \
  252. 0x02, 0x01, 0x02, /* Protocol version */ \
  253. 0x30, 0x1C, /* Maximum domain parameters */ \
  254. 0x02, 0x02, 0xFF, 0xFF, /* Max channel IDs */ \
  255. 0x02, 0x02, 0xFC, 0x17, /* Max user IDs */ \
  256. 0x02, 0x02, 0xFF, 0xFF, /* Max token IDs */ \
  257. 0x02, 0x01, 0x01, /* Number of priorities */ \
  258. 0x02, 0x01, 0x00, /* Min throughput */ \
  259. 0x02, 0x01, 0x01, /* Max height */ \
  260. 0x02, 0x02, 0xFF, 0xFF, /* Max MCSPDU size */ \
  261. 0x02, 0x01, 0x02, /* Protocol version */ \
  262. 0x04, 0x82, 0x00} /* User data */ \
  263. /****************************************************************************/
  264. /* Hard-coded data for Erect-Domain-Request PDU. */
  265. /****************************************************************************/
  266. #define MCS_DATA_ERECTDOMAINREQUEST \
  267. {0x04, /* EDrq choice */ \
  268. 0x0001, /* Sub-height */ \
  269. 0x0001} /* Sub-interval */ \
  270. /****************************************************************************/
  271. /* Hard-coded data for Disconnect-Provider-Ultimatum PDU. The reason */
  272. /* is hard-coded to rn-user-requested. */
  273. /****************************************************************************/
  274. #define MCS_DATA_DISCONNECTPROVIDERUM \
  275. {0x8021} /* DPum choice and reason */ \
  276. /****************************************************************************/
  277. /* Hard-coded data for Attach-User-Request PDU. */
  278. /****************************************************************************/
  279. #define MCS_DATA_ATTACHUSERREQUEST \
  280. {0x28} /* AUrq choice */ \
  281. /****************************************************************************/
  282. /* Hard-coded data for Detach-User-Request PDU. */
  283. /****************************************************************************/
  284. #define MCS_DATA_DETACHUSERREQUEST \
  285. {0x31, 0x80, /* DUrq choice and reason */ \
  286. 0x01, /* Set of one user-id */ \
  287. 0x0000} /* User ID */ \
  288. /****************************************************************************/
  289. /* Hard-coded data for Channel-Join-Request PDU. */
  290. /****************************************************************************/
  291. #define MCS_DATA_CHANNELJOINREQUEST \
  292. {0x38, /* CJrq choice */ \
  293. 0x0000, /* User ID */ \
  294. 0x0000} /* Channel ID */ \
  295. /****************************************************************************/
  296. /* Hard-coded data for Send-Data-Request PDU. */
  297. /****************************************************************************/
  298. #define MCS_DATA_SENDDATAREQUEST \
  299. {0x64, /* SDrq choice */ \
  300. 0x0000, /* User ID */ \
  301. 0x0000, /* Channel ID */ \
  302. 0x70} /* Priority and segmentation */ \
  303. /****************************************************************************/
  304. /* */
  305. /* TYPEDEFS */
  306. /* */
  307. /****************************************************************************/
  308. /****************************************************************************/
  309. /* Turn on single-byte packing for these structures which we use to */
  310. /* overlay a byte stream from the network. */
  311. /****************************************************************************/
  312. #pragma pack(push, MCSpack, 1)
  313. /**STRUCT+*******************************************************************/
  314. /* Structure: MCS_BER_1DATABYTE */
  315. /* */
  316. /* Description: A BER encoded 1 byte value. */
  317. /****************************************************************************/
  318. typedef struct tagMCS_BER_1DATABYTE
  319. {
  320. DCUINT8 tag;
  321. DCUINT8 length;
  322. DCUINT8 value;
  323. } MCS_BER_1DATABYTE;
  324. /**STRUCT-*******************************************************************/
  325. /**STRUCT+*******************************************************************/
  326. /* Structure: MCS_BER_2DATABYTES */
  327. /* */
  328. /* Description: A BER encoded 2 byte value. */
  329. /****************************************************************************/
  330. typedef struct tagMCS_BER_2DATABYTES
  331. {
  332. DCUINT8 tag;
  333. DCUINT8 length;
  334. DCUINT8 value[2];
  335. } MCS_BER_2DATABYTES;
  336. /**STRUCT-*******************************************************************/
  337. /**STRUCT+*******************************************************************/
  338. /* Structure: MCS_BER_3DATABYTES */
  339. /* */
  340. /* Description: A BER encoded 3 byte value. */
  341. /****************************************************************************/
  342. typedef struct tagMCS_BER_3DATABYTES
  343. {
  344. DCUINT8 tag;
  345. DCUINT8 length;
  346. DCUINT8 value[3];
  347. } MCS_BER_3DATABYTES;
  348. /**STRUCT-*******************************************************************/
  349. /**STRUCT+*******************************************************************/
  350. /* Structure: MCS_BER_4DATABYTES */
  351. /* */
  352. /* Description: A BER encoded 4 byte value. */
  353. /****************************************************************************/
  354. typedef struct tagMCS_BER_4DATABYTES
  355. {
  356. DCUINT8 tag;
  357. DCUINT8 length;
  358. DCUINT8 value[4];
  359. } MCS_BER_4DATABYTES;
  360. /**STRUCT-*******************************************************************/
  361. /**STRUCT+*******************************************************************/
  362. /* Structure: MCS_DOMAINPARAMETERS */
  363. /* */
  364. /* Description: Represents a Domain-Parameters sequence. */
  365. /****************************************************************************/
  366. typedef struct tagMCS_DOMAINPARAMETERS
  367. {
  368. DCUINT8 tag;
  369. DCUINT8 length;
  370. MCS_BER_2DATABYTES maxChanIDs;
  371. MCS_BER_2DATABYTES maxUserIDs;
  372. MCS_BER_2DATABYTES maxTokenIDs;
  373. MCS_BER_1DATABYTE numPriorities;
  374. MCS_BER_1DATABYTE minThroughPut;
  375. MCS_BER_1DATABYTE maxHeight;
  376. MCS_BER_2DATABYTES maxMCSPDUSize;
  377. MCS_BER_1DATABYTE protocolVersion;
  378. } MCS_DOMAINPARAMETERS;
  379. /**STRUCT-*******************************************************************/
  380. /**STRUCT+*******************************************************************/
  381. /* Structure: MCS_TARGETDOMAINPARAMETERS */
  382. /* */
  383. /* Description: Represents a Domain-Parameters sequence. */
  384. /****************************************************************************/
  385. typedef struct tagMCS_TARGETDOMAINPARAMETERS
  386. {
  387. DCUINT8 tag;
  388. DCUINT8 length;
  389. MCS_BER_1DATABYTE maxChanIDs;
  390. MCS_BER_1DATABYTE maxUserIDs;
  391. MCS_BER_1DATABYTE maxTokenIDs;
  392. MCS_BER_1DATABYTE numPriorities;
  393. MCS_BER_1DATABYTE minThroughPut;
  394. MCS_BER_1DATABYTE maxHeight;
  395. MCS_BER_2DATABYTES maxMCSPDUSize;
  396. MCS_BER_1DATABYTE protocolVersion;
  397. } MCS_TARGETDOMAINPARAMETERS;
  398. /**STRUCT-*******************************************************************/
  399. /**STRUCT+*******************************************************************/
  400. /* Structure: MCS_MINDOMAINPARAMETERS */
  401. /* */
  402. /* Description: Represents a Domain-Parameters sequence. */
  403. /****************************************************************************/
  404. typedef struct tagMCS_MINDOMAINPARAMETERS
  405. {
  406. DCUINT8 tag;
  407. DCUINT8 length;
  408. MCS_BER_1DATABYTE maxChanIDs;
  409. MCS_BER_1DATABYTE maxUserIDs;
  410. MCS_BER_1DATABYTE maxTokenIDs;
  411. MCS_BER_1DATABYTE numPriorities;
  412. MCS_BER_1DATABYTE minThroughPut;
  413. MCS_BER_1DATABYTE maxHeight;
  414. MCS_BER_2DATABYTES maxMCSPDUSize;
  415. MCS_BER_1DATABYTE protocolVersion;
  416. } MCS_MINDOMAINPARAMETERS;
  417. /**STRUCT-*******************************************************************/
  418. /**STRUCT+*******************************************************************/
  419. /* Structure: MCS_MAXDOMAINPARAMETERS */
  420. /* */
  421. /* Description: Represents a Domain-Parameters sequence. */
  422. /****************************************************************************/
  423. typedef struct tagMCS_MAXDOMAINPARAMETERS
  424. {
  425. DCUINT8 tag;
  426. DCUINT8 length;
  427. MCS_BER_2DATABYTES maxChanIDs;
  428. MCS_BER_2DATABYTES maxUserIDs;
  429. MCS_BER_2DATABYTES maxTokenIDs;
  430. MCS_BER_1DATABYTE numPriorities;
  431. MCS_BER_1DATABYTE minThroughPut;
  432. MCS_BER_1DATABYTE maxHeight;
  433. MCS_BER_2DATABYTES maxMCSPDUSize;
  434. MCS_BER_1DATABYTE protocolVersion;
  435. } MCS_MAXDOMAINPARAMETERS;
  436. /**STRUCT-*******************************************************************/
  437. /**STRUCT+*******************************************************************/
  438. /* Structure: MCS_PDU_CONNECTINITIAL */
  439. /* */
  440. /* Description: Represents a Connect-Initial PDU. */
  441. /****************************************************************************/
  442. typedef struct tagMCS_PDU_CONNECTINITIAL
  443. {
  444. DCUINT16 type;
  445. DCUINT8 lengthLength;
  446. DCUINT16 length;
  447. MCS_BER_1DATABYTE callingDS;
  448. MCS_BER_1DATABYTE calledDS;
  449. MCS_BER_1DATABYTE upwardFlag;
  450. MCS_TARGETDOMAINPARAMETERS targetParams;
  451. MCS_MINDOMAINPARAMETERS minimumParams;
  452. MCS_MAXDOMAINPARAMETERS maximumParams;
  453. DCUINT8 udIdentifier;
  454. DCUINT8 udLengthLength;
  455. DCUINT16 udLength;
  456. } MCS_PDU_CONNECTINITIAL, DCPTR PMCS_PDU_CONNECTINITIAL;
  457. /**STRUCT-*******************************************************************/
  458. /**STRUCT+*******************************************************************/
  459. /* Structure: MCS_PDU_CONNECTRESPONSE */
  460. /* */
  461. /* Description: Represents a Connect-Response PDU. */
  462. /****************************************************************************/
  463. typedef struct tagMCS_PDU_CONNECTRESPONSE
  464. {
  465. DCUINT16 type;
  466. DCUINT8 length;
  467. MCS_BER_1DATABYTE result;
  468. MCS_BER_1DATABYTE connectID;
  469. MCS_DOMAINPARAMETERS domainParams;
  470. DCUINT8 userDataType;
  471. DCUINT8 userDataLength;
  472. } MCS_PDU_CONNECTRESPONSE, DCPTR PMCS_PDU_CONNECTRESPONSE;
  473. /**STRUCT-*******************************************************************/
  474. /**STRUCT+*******************************************************************/
  475. /* Structure: MCS_PDU_ERECTDOMAINREQUEST */
  476. /* */
  477. /* Description: Represents a Erect-Domain-Request PDU. */
  478. /****************************************************************************/
  479. typedef struct tagMCS_PDU_ERECTDOMAINREQUEST
  480. {
  481. DCUINT8 type;
  482. DCUINT16 subHeight;
  483. DCUINT16 subInterval;
  484. } MCS_PDU_ERECTDOMAINREQUEST, DCPTR PMCS_PDU_ERECTDOMAINREQUEST;
  485. /**STRUCT-*******************************************************************/
  486. /**STRUCT+*******************************************************************/
  487. /* Structure: MCS_PDU_DISCONNECTPROVIDERUM */
  488. /* */
  489. /* Description: Represents a Disconnect-Provider-Ultimatum PDU */
  490. /****************************************************************************/
  491. typedef struct tagMCS_PDU_DISCONNECTPROVIDERUM
  492. {
  493. DCUINT16 typeReason;
  494. } MCS_PDU_DISCONNECTPROVIDERUM, DCPTR PMCS_PDU_DISCONNECTPROVIDERUM;
  495. /**STRUCT-*******************************************************************/
  496. /**STRUCT+*******************************************************************/
  497. /* Structure: MCS_PDU_ATTACHUSERREQUEST */
  498. /* */
  499. /* Description: Represents an Attach-User-Request PDU. */
  500. /****************************************************************************/
  501. typedef struct tagMCS_PDU_ATTACHUSERREQUEST
  502. {
  503. DCUINT8 type;
  504. } MCS_PDU_ATTACHUSERREQUEST, DCPTR PMCS_PDU_ATTACHUSERREQUEST;
  505. /**STRUCT-*******************************************************************/
  506. /**STRUCT+*******************************************************************/
  507. /* Structure: MCS_PDU_ATTACHUSERCONFIRMCOMMON */
  508. /* */
  509. /* Description: Represents the always present part of a Attach-User-Confirm */
  510. /* PDU. */
  511. /****************************************************************************/
  512. typedef struct tagMCS_PDU_ATTACHUSERCONFIRMCOMMON
  513. {
  514. DCUINT16 typeResult;
  515. } MCS_PDU_ATTACHUSERCONFIRMCOMMON, DCPTR PMCS_PDU_ATTACHUSERCONFIRMCOMMON;
  516. /**STRUCT-*******************************************************************/
  517. /**STRUCT+*******************************************************************/
  518. /* Structure: MCS_PDU_ATTACHUSERCONFIRMFULL */
  519. /* */
  520. /* Description: Represents a full Attach-User-Confirm PDU with the optional */
  521. /* userID. */
  522. /****************************************************************************/
  523. typedef struct tagMCS_PDU_ATTACHUSERCONFIRMFULL
  524. {
  525. MCS_PDU_ATTACHUSERCONFIRMCOMMON common;
  526. DCUINT16 userID;
  527. } MCS_PDU_ATTACHUSERCONFIRMFULL, DCPTR PMCS_PDU_ATTACHUSERCONFIRMFULL;
  528. /**STRUCT-*******************************************************************/
  529. /**STRUCT+*******************************************************************/
  530. /* Structure: MCS_PDU_DETACHUSERREQUEST */
  531. /* */
  532. /* Description: Represents a Detach-User-Request PDU. */
  533. /****************************************************************************/
  534. typedef struct tagMCS_PDU_DETACHUSERREQUEST
  535. {
  536. DCUINT8 type;
  537. DCUINT8 reason;
  538. DCUINT8 set;
  539. DCUINT16 userID;
  540. } MCS_PDU_DETACHUSERREQUEST, DCPTR PMCS_PDU_DETACHUSERREQUEST;
  541. /**STRUCT-*******************************************************************/
  542. /**STRUCT+*******************************************************************/
  543. /* Structure: MCS_PDU_DETACHUSERINDICATION */
  544. /* */
  545. /* Description: Represents a Detach-User-Indication PDU. */
  546. /****************************************************************************/
  547. typedef struct tagMCS_PDU_DETACHUSERINDICATION
  548. {
  549. DCUINT8 type;
  550. DCUINT8 reason;
  551. DCUINT8 set;
  552. DCUINT16 userID;
  553. } MCS_PDU_DETACHUSERINDICATION, DCPTR PMCS_PDU_DETACHUSERINDICATION;
  554. /**STRUCT-*******************************************************************/
  555. /**STRUCT+*******************************************************************/
  556. /* Structure: MCS_PDU_CHANNELJOINREQUEST */
  557. /* */
  558. /* Description: Represents a Channel-Join-Request PDU. */
  559. /****************************************************************************/
  560. typedef struct tagMCS_PDU_CHANNELJOINREQUEST
  561. {
  562. DCUINT8 type;
  563. DCUINT16 initiator;
  564. DCUINT16 channelID;
  565. } MCS_PDU_CHANNELJOINREQUEST, DCPTR PMCS_PDU_CHANNELJOINREQUEST;
  566. /**STRUCT-*******************************************************************/
  567. /**STRUCT+*******************************************************************/
  568. /* Structure: MCS_PDU_CHANNELJOINCONFIRMCOMMON */
  569. /* */
  570. /* Description: Represents the always present part of a */
  571. /* Channel-Join-Confirm PDU. */
  572. /****************************************************************************/
  573. typedef struct tagMCS_PDU_CHANNELJOINCONFIRMCOMMON
  574. {
  575. DCUINT16 typeResult;
  576. DCUINT16 initiator;
  577. DCUINT16 requested;
  578. } MCS_PDU_CHANNELJOINCONFIRMCOMMON, DCPTR PMCS_PDU_CHANNELJOINCONFIRMCOMMON;
  579. /**STRUCT-*******************************************************************/
  580. /**STRUCT+*******************************************************************/
  581. /* Structure: MCS_PDU_CHANNELJOINCONFIRMFULL */
  582. /* */
  583. /* Description: Represents a full Channel-Join-Confirm PDU including the */
  584. /* optional channel-ID. */
  585. /****************************************************************************/
  586. typedef struct tagMCS_PDU_CHANNELJOINCONFIRM
  587. {
  588. MCS_PDU_CHANNELJOINCONFIRMCOMMON common;
  589. DCUINT16 channelID;
  590. } MCS_PDU_CHANNELJOINCONFIRMFULL, DCPTR PMCS_PDU_CHANNELJOINCONFIRMFULL;
  591. /**STRUCT-*******************************************************************/
  592. /**STRUCT+*******************************************************************/
  593. /* Structure: MCS_PDU_SENDDATAINDICATION */
  594. /* */
  595. /* Description: Represents a Send-Data-Indication PDU. */
  596. /****************************************************************************/
  597. typedef struct tagMCS_PDU_SENDDATAINDICATION
  598. {
  599. DCUINT8 type;
  600. DCUINT16 userID;
  601. DCUINT16 channelID;
  602. DCUINT8 priSeg;
  603. } MCS_PDU_SENDDATAINDICATION, DCPTR PMCS_PDU_SENDDATAINDICATION;
  604. /**STRUCT-*******************************************************************/
  605. /**STRUCT+*******************************************************************/
  606. /* Structure: MCS_PDU_SENDDATAREQUEST */
  607. /* */
  608. /* Description: Represents a Send-Data-Request PDU. */
  609. /****************************************************************************/
  610. typedef struct tagMCS_PDU_SENDDATAREQUEST
  611. {
  612. DCUINT8 type;
  613. DCUINT16 userID;
  614. DCUINT16 channelID;
  615. DCUINT8 priSeg;
  616. } MCS_PDU_SENDDATAREQUEST;
  617. /**STRUCT-*******************************************************************/
  618. /****************************************************************************/
  619. /* Reset structure packing to its default. */
  620. /****************************************************************************/
  621. #pragma pack(pop, MCSpack)
  622. /**STRUCT+*******************************************************************/
  623. /* Structure: MCS_DECOUPLEINFO */
  624. /* */
  625. /* Description: Structure used when decoupling channel and userIDs. */
  626. /****************************************************************************/
  627. typedef struct tagMCS_DECOUPLEINFO
  628. {
  629. DCUINT channel;
  630. DCUINT userID;
  631. } MCS_DECOUPLEINFO, DCPTR PMCS_DECOUPLEINFO;
  632. /**STRUCT-*******************************************************************/
  633. /****************************************************************************/
  634. /* */
  635. /* TYPEDEFS */
  636. /* */
  637. /****************************************************************************/
  638. /**STRUCT+*******************************************************************/
  639. /* Structure: MCS_GLOBAL_DATA */
  640. /* */
  641. /* Description: The MCS global data. */
  642. /****************************************************************************/
  643. typedef struct tagMCS_GLOBAL_DATA
  644. {
  645. DCUINT rcvState;
  646. DCUINT hdrBytesNeeded;
  647. DCUINT hdrBytesRead;
  648. DCUINT dataState;
  649. DCUINT dataBytesNeeded;
  650. DCUINT dataBytesRead;
  651. DCUINT userDataLength;
  652. DCUINT disconnectReason;
  653. PDCUINT8 pReceivedPacket;
  654. DCUINT8 pSizeBuf[MCS_MAX_SIZE_DATA_LENGTH];
  655. PDCUINT8 pHdrBuf;
  656. DCUINT hdrBufLen;
  657. //
  658. // Channel with a pending join request - use this
  659. // to validate that the server isn't sending us bogus
  660. // joins for channels we didn't request
  661. //
  662. DCUINT16 pendingChannelJoin;
  663. DCUINT16 pad;
  664. /* Note: dataBuf must start on 4-byte boundary */
  665. // The decompression function does not check strictly the input buffer
  666. // for performance reasons. So it can overread up to 8 bytes. So we pad
  667. // the input buffer with enough bytes to avoid the overread.
  668. DCUINT8 dataBuf[MCS_MAX_RCVPKT_LENGTH + 2 + MCS_INPUT_BUFFER_BIAS];
  669. } MCS_GLOBAL_DATA;
  670. /**STRUCT-*******************************************************************/
  671. //
  672. // Class definition
  673. //
  674. class CCD;
  675. class CNC;
  676. class CUT;
  677. class CXT;
  678. class CNL;
  679. class CSL;
  680. class CMCS
  681. {
  682. public:
  683. CMCS(CObjs* objs);
  684. ~CMCS();
  685. public:
  686. //
  687. // API functions
  688. //
  689. /****************************************************************************/
  690. /* FUNCTIONS */
  691. /****************************************************************************/
  692. DCVOID DCAPI MCS_Init(DCVOID);
  693. DCVOID DCAPI MCS_Term(DCVOID);
  694. DCVOID DCAPI MCS_Connect(BOOL bInitateConnect,
  695. PDCTCHAR pServerAddress,
  696. PDCUINT8 pUserData,
  697. DCUINT userDataLength);
  698. DCVOID DCAPI MCS_Disconnect(DCVOID);
  699. DCVOID DCAPI MCS_AttachUser(DCVOID);
  700. DCVOID DCAPI MCS_JoinChannel(DCUINT channel, DCUINT userID);
  701. DCBOOL DCAPI MCS_GetBuffer(DCUINT dataLen,
  702. PPDCUINT8 ppBuffer,
  703. PMCS_BUFHND pBufHandle);
  704. DCVOID DCAPI MCS_SendPacket(PDCUINT8 pData,
  705. DCUINT dataLen,
  706. DCUINT flags,
  707. MCS_BUFHND bufHandle,
  708. DCUINT userID,
  709. DCUINT channel,
  710. DCUINT priority);
  711. DCVOID DCAPI MCS_FreeBuffer(MCS_BUFHND bufHandle);
  712. public:
  713. //
  714. // Callbacks
  715. //
  716. DCVOID DCCALLBACK MCS_OnXTConnected(DCVOID);
  717. DCVOID DCCALLBACK MCS_OnXTDisconnected(DCUINT reason);
  718. DCBOOL DCCALLBACK MCS_OnXTDataAvailable(DCVOID);
  719. DCVOID DCCALLBACK MCS_OnXTBufferAvailable(DCVOID);
  720. //
  721. // Static versions
  722. //
  723. DCVOID DCCALLBACK MCS_StaticOnXTConnected(CMCS* inst)
  724. {
  725. inst->MCS_OnXTConnected();
  726. }
  727. DCVOID DCCALLBACK MCS_StaticOnXTDisconnected(CMCS* inst, DCUINT reason)
  728. {
  729. inst->MCS_OnXTDisconnected(reason);
  730. }
  731. DCBOOL DCCALLBACK MCS_StaticOnXTDataAvailable(CMCS* inst)
  732. {
  733. return inst->MCS_OnXTDataAvailable();
  734. }
  735. DCVOID DCCALLBACK MCS_StaticOnXTBufferAvailable(CMCS* inst)
  736. {
  737. inst->MCS_OnXTBufferAvailable();
  738. }
  739. DCUINT16 MCS_GetPendingChannelJoin()
  740. {
  741. return _MCS.pendingChannelJoin;
  742. }
  743. VOID MCS_SetPendingChannelJoin(DCUINT16 pendingChannelJoin)
  744. {
  745. _MCS.pendingChannelJoin = pendingChannelJoin;
  746. }
  747. DCVOID DCINTERNAL MCSSendConnectInitial(ULONG_PTR event);
  748. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CMCS, MCSSendConnectInitial);
  749. DCVOID DCINTERNAL MCSSendErectDomainRequest(ULONG_PTR event);
  750. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CMCS, MCSSendErectDomainRequest);
  751. DCVOID DCINTERNAL MCSSendAttachUserRequest(ULONG_PTR unused);
  752. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CMCS, MCSSendAttachUserRequest);
  753. DCVOID DCINTERNAL MCSSendChannelJoinRequest(PDCVOID pData, DCUINT dataLen);
  754. EXPOSE_CD_NOTIFICATION_FN(CMCS, MCSSendChannelJoinRequest);
  755. DCVOID DCINTERNAL MCSSendDisconnectProviderUltimatum(ULONG_PTR unused);
  756. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CMCS, MCSSendDisconnectProviderUltimatum);
  757. DCVOID DCINTERNAL MCSContinueDisconnect(ULONG_PTR unused);
  758. EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CMCS, MCSContinueDisconnect);
  759. public:
  760. //
  761. // Public data members
  762. //
  763. MCS_GLOBAL_DATA _MCS;
  764. private:
  765. //
  766. // Internal functions
  767. //
  768. /****************************************************************************/
  769. /* Inline functions to convert between MCS byte order and local byte order. */
  770. /****************************************************************************/
  771. DCUINT16 DCINTERNAL MCSWireToLocal16(DCUINT16 val)
  772. {
  773. return((DCUINT16) (((DCUINT16)(((PDCUINT8)&(val))[0]) << 8) | \
  774. ((DCUINT16)(((PDCUINT8)&(val))[1]))));
  775. }
  776. #define MCSLocalToWire16 MCSWireToLocal16
  777. /****************************************************************************/
  778. /* Inline function to extract the result code from a PER encoded PDU. */
  779. /* Typically the bits in the first two bytes are used as follows (the */
  780. /* following is for an Attach-User-Confirm PDU). */
  781. /* */
  782. /* BYTE1 BYTE2 */
  783. /* MSB LSB MSB LSB */
  784. /* T T T T T T O R R R R P P P P P */
  785. /* */
  786. /* T: 6 bits used to identify the PDU type. */
  787. /* O: 1 bit indicating whether the optional field is present. */
  788. /* R: 4 bits used for the result code. */
  789. /* P: 5 bits of padding. */
  790. /* */
  791. /* Note: the optional bit "O" may or may not be present depending on the */
  792. /* PDU. */
  793. /* */
  794. /* Parameters: IN value - the value from which to extract the reason */
  795. /* code in wire format. */
  796. /* IN offset - the offset from the MSB to the first bit of */
  797. /* the result code. */
  798. /****************************************************************************/
  799. DCUINT DCINTERNAL MCSGetResult(DCUINT16 value, DCUINT offset)
  800. {
  801. DCUINT16 machineValue;
  802. DCUINT shiftValue;
  803. DCUINT result;
  804. DC_BEGIN_FN("MCSGetResult");
  805. /************************************************************************/
  806. /* Convert the value from wire to local machine format. */
  807. /************************************************************************/
  808. machineValue = MCSWireToLocal16(value);
  809. /************************************************************************/
  810. /* Now shift it right by the appropriate amount. This amount is 16 */
  811. /* bits minus (the offset plus the length of the result code). */
  812. /************************************************************************/
  813. shiftValue = 16 - (offset + MCS_RESULTCODELENGTH);
  814. machineValue >>= shiftValue;
  815. /************************************************************************/
  816. /* Finally mask off the bottom byte which contains the result code. */
  817. /************************************************************************/
  818. result = machineValue & MCS_RESULTCODEMASK;
  819. TRC_NRM((TB, _T("Shift %#hx right by %u to get %#hx. Mask to get %#x"),
  820. MCSWireToLocal16(value),
  821. shiftValue,
  822. machineValue,
  823. result));
  824. DC_END_FN();
  825. return(result);
  826. }
  827. /****************************************************************************/
  828. /* Macro to extract the reason code from a PER encoded PDU. Typically */
  829. /* the bits in the first two bytes are used as follows (the following is */
  830. /* for a Disconnect-Provider-Ultimatum). */
  831. /* */
  832. /* BYTE1 BYTE2 */
  833. /* MSB LSB MSB LSB */
  834. /* T T T T T T R R R P P P P P P P */
  835. /* */
  836. /* T: 6 bits used to identify the PDU type. */
  837. /* R: 3 bits used for the result code. */
  838. /* P: 7 bits of padding. */
  839. /* */
  840. /* Parameters: IN value - the value from which to extract the reason */
  841. /* code in wire format. */
  842. /* IN offset - the offset from the MSB to the first bit of */
  843. /* the reason code. */
  844. /****************************************************************************/
  845. DCUINT DCINTERNAL MCSGetReason(DCUINT16 value, DCUINT offset)
  846. {
  847. DCUINT16 machineValue;
  848. DCUINT shiftValue;
  849. DCUINT reason;
  850. DC_BEGIN_FN("MCSGetResult");
  851. /************************************************************************/
  852. /* Convert the value from wire to local machine format. */
  853. /************************************************************************/
  854. machineValue = MCSWireToLocal16(value);
  855. /************************************************************************/
  856. /* Now shift it right by the appropriate amount. This amount is 16 */
  857. /* bits minus (the offset plus the length of the reason code). */
  858. /************************************************************************/
  859. shiftValue = 16 - (offset + MCS_REASONCODELENGTH);
  860. machineValue >>= shiftValue;
  861. /************************************************************************/
  862. /* Finally mask off the bottom byte which contains the reason code. */
  863. /************************************************************************/
  864. reason = machineValue & MCS_REASONCODEMASK;
  865. TRC_NRM((TB, _T("Shift %#hx right by %u to get %#hx. Mask to get %#x"),
  866. MCSWireToLocal16(value),
  867. shiftValue,
  868. machineValue,
  869. reason));
  870. DC_END_FN();
  871. return(reason);
  872. }
  873. /****************************************************************************/
  874. /* Inline functions to convert user-ids between the PER encoded values and */
  875. /* the wire format. */
  876. /****************************************************************************/
  877. DCUINT16 DCINTERNAL MCSWireUserIDToLocalUserID(DCUINT16 wireUserID)
  878. {
  879. /************************************************************************/
  880. /* Convert from wire to local byte order and then add the PER encoding */
  881. /* offset. */
  882. /************************************************************************/
  883. return((DCUINT16)(MCSWireToLocal16(wireUserID) + MCS_USERID_PER_OFFSET));
  884. }
  885. DCUINT16 DCINTERNAL MCSLocalUserIDToWireUserID(DCUINT16 localUserID)
  886. {
  887. /************************************************************************/
  888. /* Subtract the PER encoding offset and then convert from local to wire */
  889. /* byte order. */
  890. /************************************************************************/
  891. return(MCSLocalToWire16((DCUINT16)(localUserID - MCS_USERID_PER_OFFSET)));
  892. }
  893. /****************************************************************************/
  894. /* Inline function to calculate the number of length bytes in a BER */
  895. /* encoded length. */
  896. /****************************************************************************/
  897. DCUINT DCINTERNAL MCSGetBERLengthSize(DCUINT8 firstByte)
  898. {
  899. DCUINT numLenBytes;
  900. DC_BEGIN_FN("MCSGetBERLengthSize");
  901. /************************************************************************/
  902. /* Check if the top bit is set. */
  903. /************************************************************************/
  904. if (0x80 & firstByte)
  905. {
  906. /********************************************************************/
  907. /* The top bit is set - the low seven bits contain the number of */
  908. /* length bytes. */
  909. /********************************************************************/
  910. numLenBytes = (firstByte & 0x7F) + 1;
  911. TRC_NRM((TB, _T("Top bit set - numLenBytes:%u"), numLenBytes));
  912. }
  913. else
  914. {
  915. /********************************************************************/
  916. /* The top bit was not set - this field contains the length. */
  917. /********************************************************************/
  918. numLenBytes = 1;
  919. TRC_NRM((TB, _T("Top bit NOT set - numLenBytes:%u firstByte:%u"),
  920. numLenBytes,
  921. firstByte));
  922. }
  923. DC_END_FN();
  924. return(numLenBytes);
  925. }
  926. /****************************************************************************/
  927. /* Inline function to calculate the length of a BER encoded field. */
  928. /****************************************************************************/
  929. DCUINT DCINTERNAL MCSGetBERLength(PDCUINT8 pLength)
  930. {
  931. DCUINT length = 0;
  932. DCUINT numLenBytes;
  933. DC_BEGIN_FN("MCSGetBERLength");
  934. TRC_ASSERT((pLength != NULL), (TB, _T("pLength is NULL")));
  935. /************************************************************************/
  936. /* Calculate the number of length bytes. */
  937. /************************************************************************/
  938. numLenBytes = MCSGetBERLengthSize(*pLength);
  939. switch (numLenBytes)
  940. {
  941. case 1:
  942. {
  943. /****************************************************************/
  944. /* The length is less than 128 bytes so the first field */
  945. /* contains the length. */
  946. /****************************************************************/
  947. length = *pLength;
  948. }
  949. break;
  950. case 2:
  951. {
  952. /****************************************************************/
  953. /* The length is >= 128 bytes but less than 256 bytes so it */
  954. /* is encoded in the second byte. */
  955. /****************************************************************/
  956. pLength++;
  957. length = *pLength;
  958. }
  959. break;
  960. case 3:
  961. {
  962. /****************************************************************/
  963. /* The length is >= 256 bytes and less than 65535 bytes so it */
  964. /* is encoded in bytes two and three. */
  965. /****************************************************************/
  966. pLength++;
  967. length = (DCUINT16)*pLength;
  968. pLength++;
  969. length = (length << 8) + (DCUINT16)*pLength;
  970. }
  971. break;
  972. default:
  973. {
  974. TRC_ABORT((TB, _T("Too many length bytes:%u"), numLenBytes));
  975. }
  976. break;
  977. }
  978. TRC_NRM((TB, _T("numLenBytes:%u length:%u"), numLenBytes, length));
  979. DC_END_FN();
  980. return(length);
  981. }
  982. /****************************************************************************/
  983. /* */
  984. /* FUNCTIONS */
  985. /* */
  986. /****************************************************************************/
  987. DCUINT DCINTERNAL MCSGetSDRHeaderLength(DCUINT dataLength);
  988. DCBOOL DCINTERNAL MCSRecvToHdrBuf(DCVOID);
  989. DCBOOL DCINTERNAL MCSRecvToDataBuf(DCVOID);
  990. DCVOID DCINTERNAL MCSGetPERInfo(PDCUINT pType, PDCUINT pSize);
  991. DCVOID DCINTERNAL MCSHandleControlPkt(DCVOID);
  992. DCVOID DCINTERNAL MCSHandleCRPDU(DCVOID);
  993. HRESULT DCINTERNAL MCSRecvData(BOOL *pfFinishedData);
  994. DCVOID DCINTERNAL MCSSetReasonAndDisconnect(DCUINT reason);
  995. private:
  996. CCD* _pCd;
  997. CNC* _pNc;
  998. CUT* _pUt;
  999. CXT* _pXt;
  1000. CNL* _pNl;
  1001. CSL* _pSl;
  1002. private:
  1003. CObjs* _pClientObjects;
  1004. };
  1005. #undef TRC_FILE
  1006. #undef TRC_GROUP
  1007. #endif // _H_MCS