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.

510 lines
22 KiB

  1. /**MOD+**********************************************************************/
  2. /* Module: ncapi.cpp */
  3. /* */
  4. /* Purpose: Node Controller API/callbacks */
  5. /* */
  6. /* Copyright(C) Microsoft Corporation 1997-1999 */
  7. /* */
  8. /****************************************************************************/
  9. #include <adcg.h>
  10. extern "C" {
  11. #define TRC_GROUP TRC_GROUP_NETWORK
  12. #define TRC_FILE "ncapi"
  13. #include <atrcapi.h>
  14. }
  15. #include "autil.h"
  16. #include "nc.h"
  17. #include "cd.h"
  18. #include "nl.h"
  19. #include "mcs.h"
  20. #include "cchan.h"
  21. /****************************************************************************/
  22. /* MCS user data header bytes. */
  23. /****************************************************************************/
  24. const DCINT8 ncMCSHeader[NC_MCS_HDRLEN] =
  25. {
  26. 0x00, 0x05, 0x00, 0x14, 0x7C, 0x00, 0x01
  27. };
  28. /****************************************************************************/
  29. /* GCC CreateConferenceRequest PDU body */
  30. /****************************************************************************/
  31. const DCINT8 ncGCCBody[NC_GCC_REQLEN] =
  32. {
  33. 0x00, /* extension bit; 3 * choice bits; 3 * optional fields */
  34. 0x08, /* 5*Optional (user data only);2*ConfName options;length bit 0 */
  35. 0x00, /* Length bits 1-7; pad bit */
  36. 0x10, /* Conference name (numeric) = "1"; locked; listed; */
  37. 0x00, /* conductible; 2*Terminate =automatic; pad */
  38. 0x01, /* Number of UserData fields */
  39. '\xC0', /* optional;choice;6*size (0=>4 octets) */
  40. 0x00 /* 2* size; 6* pad */
  41. };
  42. CNC::CNC(CObjs* objs)
  43. {
  44. _pClientObjects = objs;
  45. }
  46. CNC::~CNC()
  47. {
  48. }
  49. #ifdef OS_WIN32
  50. /**PROC+*********************************************************************/
  51. /* Name: NC_Main */
  52. /* */
  53. /* Purpose: Receiver Thread message loop */
  54. /* */
  55. /* Returns: None */
  56. /* */
  57. /* Params: None */
  58. /* */
  59. /**PROC-*********************************************************************/
  60. DCVOID DCAPI CNC::NC_Main(DCVOID)
  61. {
  62. MSG msg;
  63. DC_BEGIN_FN("NC_Main");
  64. TRC_NRM((TB, _T("Receiver Thread initialization")));
  65. #if defined(OS_WINCE) && defined(WINCE_USEBRUSHCACHE)
  66. BrushCacheInitialize();
  67. #endif
  68. _pCd = _pClientObjects->_pCdObject;
  69. _pCc = _pClientObjects->_pCcObject;
  70. _pMcs = _pClientObjects->_pMCSObject;
  71. _pUt = _pClientObjects->_pUtObject;
  72. _pRcv = _pClientObjects->_pRcvObject;
  73. _pNl = _pClientObjects->_pNlObject;
  74. _pSl = _pClientObjects->_pSlObject;
  75. _pUi = _pClientObjects->_pUiObject;
  76. _pChan = _pClientObjects->_pChanObject;
  77. NC_Init();
  78. TRC_NRM((TB, _T("Start Receiver Thread message loop")));
  79. while (GetMessage (&msg, NULL, 0, 0))
  80. {
  81. TranslateMessage(&msg);
  82. DispatchMessage(&msg);
  83. }
  84. TRC_NRM((TB, _T("Exit Receiver Thread message loop")));
  85. NC_Term();
  86. #if defined(OS_WINCE) && defined(WINCE_USEBRUSHCACHE)
  87. BrushCacheUninitialize();
  88. #endif
  89. /************************************************************************/
  90. /* This is the end of the Receiver Thread. */
  91. /************************************************************************/
  92. TRC_NRM((TB, _T("Receiver Thread terminates")));
  93. DC_END_FN();
  94. return;
  95. } /* NC_Main */
  96. #endif /* OS_WIN32 */
  97. /**PROC+*********************************************************************/
  98. /* Name: NC_Init */
  99. /* */
  100. /* Purpose: Initialize the Node Controller */
  101. /* */
  102. /* Returns: None */
  103. /* */
  104. /* Params: None */
  105. /* */
  106. /**PROC-*********************************************************************/
  107. DCVOID DCAPI CNC::NC_Init(DCVOID)
  108. {
  109. DC_BEGIN_FN("NC_Init");
  110. /************************************************************************/
  111. /* Initialize global data. */
  112. /************************************************************************/
  113. DC_MEMSET(&_NC, 0, sizeof(_NC));
  114. /************************************************************************/
  115. /* Register with CD, to receive messages. */
  116. /************************************************************************/
  117. _pCd->CD_RegisterComponent(CD_RCV_COMPONENT);
  118. /************************************************************************/
  119. /* Initialize lower layers. */
  120. /************************************************************************/
  121. _pMcs->MCS_Init();
  122. /************************************************************************/
  123. /* Initialize virtual channel stuff */
  124. /************************************************************************/
  125. _pChan->ChannelOnInitializing();
  126. TRC_NRM((TB, _T("NC successfully initialized")));
  127. /************************************************************************/
  128. /* Tell the Core that we are initialized */
  129. /************************************************************************/
  130. _pNl->_NL.callbacks.onInitialized(_pSl);
  131. _pChan->ChannelOnInitialized();
  132. DC_END_FN();
  133. return;
  134. } /* NC_Init */
  135. /**PROC+*********************************************************************/
  136. /* Name: NC_Term */
  137. /* */
  138. /* Purpose: Terminate the Node Controller */
  139. /* */
  140. /* Returns: None */
  141. /* */
  142. /* Params: None */
  143. /* */
  144. /**PROC-*********************************************************************/
  145. DCVOID DCAPI CNC::NC_Term(DCVOID)
  146. {
  147. DC_BEGIN_FN("NC_Term");
  148. /************************************************************************/
  149. /* Tell core that we are terminating */
  150. /************************************************************************/
  151. _pNl->_NL.callbacks.onTerminating(_pSl);
  152. _pChan->ChannelOnTerminating();
  153. /************************************************************************/
  154. /* Terminate lower NL layers. */
  155. /************************************************************************/
  156. _pMcs->MCS_Term();
  157. /************************************************************************/
  158. /* Unregister with CD */
  159. /************************************************************************/
  160. _pCd->CD_UnregisterComponent(CD_RCV_COMPONENT);
  161. DC_END_FN();
  162. return;
  163. } /* NC_Term */
  164. /**PROC+*********************************************************************/
  165. /* Name: NC_Connect */
  166. /* */
  167. /* Purpose: Connect to the requested Server by calling MCS */
  168. /* */
  169. /* Returns: None */
  170. /* */
  171. /* Params: IN pData - user data (SL + Core) */
  172. /* IN dataLen - length */
  173. /* */
  174. /* Operation: Send an MCSConnectProvider request with a GCC Create */
  175. /* Conference request encoded in the user data. The encoding is */
  176. /* as follows: */
  177. /* */
  178. /* number of bytes value */
  179. /* =============== ===== */
  180. /* NC_MCS_HDRLEN MCS header */
  181. /* 1 or 2 Total GCC PDU length */
  182. /* NC_GCC_REQLEN GCC CreateConference PDU body */
  183. /* 4 H221 key */
  184. /* 1 or 2 length of GCC user data */
  185. /* ? GCC user data */
  186. /* */
  187. /**PROC-*********************************************************************/
  188. DCVOID DCAPI CNC::NC_Connect(PDCVOID pData, DCUINT dataLen)
  189. {
  190. PNC_CONNECT_DATA pConn;
  191. PDCUINT8 pAddress;
  192. PDCUINT8 pProtocol;
  193. PDCUINT8 pUserData;
  194. DCUINT userDataLen;
  195. DCUINT mcsUserDataLen;
  196. DCUINT gccPDULen;
  197. PDCUINT8 pGCCPDU;
  198. DCUINT8 mcsUserData[NC_GCCREQ_MAX_PDULEN];
  199. RNS_UD_CS_NET netUserData;
  200. PCHANNEL_DEF pVirtualChannels;
  201. BOOL bInitateConnect;
  202. DC_BEGIN_FN("NC_Connect");
  203. DC_IGNORE_PARAMETER(dataLen);
  204. /************************************************************************/
  205. /* We are about to dereference pData as NC_CONNECT_DATA. Thus, we must */
  206. /* have at least that much in our PDU. */
  207. /************************************************************************/
  208. if (dataLen < ((ULONG)FIELDOFFSET(NC_CONNECT_DATA, userDataLen) +
  209. (ULONG)FIELDSIZE(NC_CONNECT_DATA, userDataLen)))
  210. {
  211. DCUINT errorCode;
  212. TRC_ABORT((TB, _T("Not enough data for NC_CONNECT_DATA struct: %u"), dataLen));
  213. /************************************************************************/
  214. /* We haven't even called into the MCS layer yet, so the disconnect */
  215. /* is a bit tricky. Uninitialize our layer and bubble up. */
  216. /************************************************************************/
  217. errorCode = NL_MAKE_DISCONNECT_ERR(NL_ERR_NCNOUSERDATA);
  218. NC_OnMCSDisconnected(errorCode);
  219. DC_QUIT;
  220. }
  221. pConn = (PNC_CONNECT_DATA)pData;
  222. bInitateConnect = pConn->bInitateConnect;
  223. if( bInitateConnect )
  224. {
  225. pAddress = pConn->data;
  226. TRC_ASSERT((pConn->addressLen > 0),
  227. (TB, _T("Invalid address length")));
  228. }
  229. else
  230. {
  231. pAddress = NULL;
  232. TRC_ASSERT((pConn->addressLen == 0),
  233. (TB, _T("Invalid address length %u"), pConn->addressLen));
  234. }
  235. pProtocol = pConn->data + pConn->addressLen;
  236. pUserData = pConn->data + pConn->addressLen + pConn->protocolLen;
  237. /************************************************************************/
  238. /* Verify that pUserdata sits within the data passed in, since */
  239. /* we just get the pointer from an offset specified in the packet. */
  240. /************************************************************************/
  241. if (!IsContainedPointer(pData,dataLen,pUserData))
  242. {
  243. DCUINT errorCode;
  244. TRC_ABORT((TB, _T("Invalid offset in data (pConn->addressLen): %u"), pConn->addressLen));
  245. /************************************************************************/
  246. /* We haven't even called into the MCS layer yet, so the disconnect */
  247. /* is a bit tricky. Uninitialize our layer and bubble up. */
  248. /************************************************************************/
  249. errorCode = NL_MAKE_DISCONNECT_ERR(NL_ERR_NCNOUSERDATA);
  250. NC_OnMCSDisconnected(errorCode);
  251. DC_QUIT;
  252. }
  253. if( bInitateConnect )
  254. {
  255. TRC_DBG((TB, _T("Server address %s"), pProtocol));
  256. }
  257. else
  258. {
  259. TRC_DBG((TB, _T("Server address : not initiate connection%s")));
  260. }
  261. TRC_DBG((TB, _T("Protocol %s"), pProtocol));
  262. TRC_DBG((TB, _T("User data length %u"), pConn->userDataLen));
  263. TRC_DATA_NRM("User data from Core+SL", pUserData, pConn->userDataLen);
  264. /************************************************************************/
  265. /* Get Virtual Channel user data */
  266. /************************************************************************/
  267. userDataLen = pConn->userDataLen;
  268. _pChan->ChannelOnConnecting(&pVirtualChannels, &(netUserData.channelCount));
  269. TRC_NRM((TB, _T("%d virtual channels"), netUserData.channelCount));
  270. if (netUserData.channelCount != 0)
  271. {
  272. netUserData.header.type = RNS_UD_CS_NET_ID;
  273. netUserData.header.length = (DCUINT16)(sizeof(RNS_UD_CS_NET) +
  274. (netUserData.channelCount * sizeof(CHANNEL_DEF)));
  275. pConn->userDataLen += netUserData.header.length;
  276. TRC_NRM((TB, _T("User data length (NET/total): %d/%d"),
  277. netUserData.header.length, pConn->userDataLen));
  278. }
  279. TRC_ASSERT((pConn->userDataLen <= NC_MAX_UDLEN),
  280. (TB, _T("Too much userdata (%u)"), pConn->userDataLen));
  281. /************************************************************************/
  282. /* Work out the length of the GCC PDU: Fixed body + H221 Key + */
  283. /* userDataLength (1 or 2) + user Data */
  284. /************************************************************************/
  285. gccPDULen = NC_GCC_REQLEN + H221_KEY_LEN + 1 + pConn->userDataLen;
  286. if (pConn->userDataLen >= 128)
  287. {
  288. TRC_DBG((TB, _T("Two byte GCC PDU length field")));
  289. gccPDULen++;
  290. }
  291. TRC_DBG((TB, _T("GCC PDU Length %u"), gccPDULen));
  292. /************************************************************************/
  293. /* Write fixed MCS header */
  294. /************************************************************************/
  295. pGCCPDU = &(mcsUserData[0]);
  296. DC_MEMCPY(pGCCPDU, ncMCSHeader, NC_MCS_HDRLEN);
  297. pGCCPDU += NC_MCS_HDRLEN;
  298. /************************************************************************/
  299. /* SECURITY: Note that the first few fields that we write into pGCCPDU */
  300. /* don't have to be validated for buffer overruns. This is because */
  301. /* they are fixed-size, and pGCCPDU points to a fixed-size buffer. */
  302. /* The first variable-length field that is written into this buffer is */
  303. /* pUserData (len==userDataLen), which is below. */
  304. /************************************************************************/
  305. if (gccPDULen < 128)
  306. {
  307. /********************************************************************/
  308. /* single length byte */
  309. /********************************************************************/
  310. *pGCCPDU++ = (DCUINT8)gccPDULen;
  311. }
  312. else
  313. {
  314. /********************************************************************/
  315. /* two length bytes */
  316. /********************************************************************/
  317. *pGCCPDU++ = (DCUINT8)((gccPDULen >> 8) | 0x0080);
  318. *pGCCPDU++ = (DCUINT8)(gccPDULen & 0x00FF);
  319. }
  320. /************************************************************************/
  321. /* Fixed GCC PDU body */
  322. /************************************************************************/
  323. DC_MEMCPY(pGCCPDU, ncGCCBody, NC_GCC_REQLEN);
  324. pGCCPDU += NC_GCC_REQLEN;
  325. /************************************************************************/
  326. /* H221 key */
  327. /************************************************************************/
  328. DC_MEMCPY(pGCCPDU, CLIENT_H221_KEY, H221_KEY_LEN);
  329. pGCCPDU += H221_KEY_LEN;
  330. /************************************************************************/
  331. /* Total Length = MCS header + GCC PDU + 1 or 2 length bytes. */
  332. /************************************************************************/
  333. mcsUserDataLen = NC_MCS_HDRLEN + gccPDULen + 1;
  334. /************************************************************************/
  335. /* The GCC user data length field - 2 bytes if length > 127. */
  336. /************************************************************************/
  337. if (pConn->userDataLen < 128)
  338. {
  339. *pGCCPDU++ = (DCUINT8)(pConn->userDataLen & 0x00ff);
  340. }
  341. else
  342. {
  343. TRC_NRM((TB, _T("Long UserData %d"), pConn->userDataLen));
  344. *pGCCPDU++ = (DCUINT8)((pConn->userDataLen >> 8) | 0x0080);
  345. *pGCCPDU++ = (DCUINT8)(pConn->userDataLen & 0x00ff);
  346. /********************************************************************/
  347. /* Add extra length byte */
  348. /********************************************************************/
  349. mcsUserDataLen++;
  350. }
  351. /********************************************************************/
  352. /* Verify that the buffer has enough room, AND the source has */
  353. /* enough data. */
  354. /********************************************************************/
  355. if (!IsContainedMemory(&(mcsUserData[0]), NC_GCCREQ_MAX_PDULEN, pGCCPDU, userDataLen) ||
  356. !IsContainedMemory(pData, dataLen, pUserData, userDataLen))
  357. {
  358. DCUINT errorCode;
  359. TRC_ABORT((TB, _T("Data source/dest size mismatch: targetsize=%u, sourcebuf=%u, copysize=%u"),
  360. NC_GCCREQ_MAX_PDULEN, dataLen, userDataLen));
  361. /************************************************************************/
  362. /* Again, haven't called into MCS layer yet, so disconnect by calling */
  363. /* NC_OnMCSDisconnected directly. */
  364. /************************************************************************/
  365. errorCode = NL_MAKE_DISCONNECT_ERR(NL_ERR_NCNOUSERDATA);
  366. NC_OnMCSDisconnected(errorCode);
  367. DC_QUIT;
  368. }
  369. /************************************************************************/
  370. /* Write the SL + core UserData. */
  371. /************************************************************************/
  372. DC_MEMCPY(pGCCPDU, pUserData, userDataLen);
  373. /************************************************************************/
  374. /* Write the NET user data */
  375. /************************************************************************/
  376. if (netUserData.channelCount != 0)
  377. {
  378. TRC_NRM((TB, _T("Append NET user data")));
  379. pGCCPDU += userDataLen;
  380. DC_MEMCPY(pGCCPDU, &netUserData, sizeof(netUserData));
  381. pGCCPDU += sizeof(netUserData);
  382. DC_MEMCPY(pGCCPDU,
  383. pVirtualChannels,
  384. netUserData.header.length - sizeof(netUserData));
  385. }
  386. TRC_DATA_NRM("MCS User Data passed in", mcsUserData, mcsUserDataLen);
  387. /************************************************************************/
  388. /* Call MCS_Connect passing in the GCC CreateConference PDU as */
  389. /* userdata. */
  390. /************************************************************************/
  391. _pMcs->MCS_Connect(bInitateConnect,
  392. (PDCTCHAR)pAddress,
  393. mcsUserData,
  394. mcsUserDataLen);
  395. DC_EXIT_POINT:
  396. DC_END_FN();
  397. return;
  398. } /* NC_Connect */
  399. /**PROC+*********************************************************************/
  400. /* Name: NC_Disconnect */
  401. /* */
  402. /* Purpose: Disconnect from the Server by calling MCS */
  403. /* */
  404. /* Returns: None */
  405. /* */
  406. /* Params: IN unused - unused parameter */
  407. /* */
  408. /**PROC-*********************************************************************/
  409. DCVOID DCAPI CNC::NC_Disconnect(ULONG_PTR unused)
  410. {
  411. DC_BEGIN_FN("NC_Disconnect");
  412. DC_IGNORE_PARAMETER(unused);
  413. /************************************************************************/
  414. /* Disconnect from the server by calling MCS_Disconnect. */
  415. /************************************************************************/
  416. TRC_NRM((TB, _T("Call MCS_Disconnect")));
  417. _pMcs->MCS_Disconnect();
  418. DC_END_FN();
  419. return;
  420. } /* NC_Disconnect */