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.

670 lines
21 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_GCCNC);
  3. /*
  4. * mcsdllif.cpp
  5. *
  6. * Copyright (c) 1993 by DataBeam Corporation, Lexington, KY
  7. *
  8. * Abstract:
  9. * This is the implementation file for the MCAT MCS DLL interface class.
  10. * This class is designed to work with Microsoft's implementation of the
  11. * MCS DLL. All access by GCC to and from this DLL should pass through
  12. * this class.
  13. *
  14. * MCS interface objects represent the Service Access Point (SAP)
  15. * between GCC and MCS. Exactly how the interface works is an
  16. * implementation matter for those classes that inherit from this one.
  17. * This class defines the public member functions that GCC expects to be
  18. * able to call upon to utilize MCS.
  19. *
  20. * The public member functions defined here can be broken into two
  21. * categories: those that are part of T.122; and those that are not.
  22. * The T.122 functions include connect provider request, connect
  23. * provider response, disconnect provider request, create domain, delete
  24. * domain, send data request, etc. All other member functions are
  25. * considered a local matter from a standards point-of-view. These
  26. * functions include support for initialization and setup, as well as
  27. * functions allowing GCC to poll MCS for activity.
  28. *
  29. * This class contains a number of virtual functions which GCC needs to
  30. * operate. Making these functions virtual in the base class allows the
  31. * MCS interface to be portable to most any platform. All the platform
  32. * specific code required to access MCS is contained in classes that will
  33. * inherit from this one.
  34. *
  35. * Note that this class also handles the connect provider confirms by
  36. * keeping a list of all the objects with outstanding connect provider
  37. * request. These are held in the ConfirmObjectList.
  38. *
  39. * Portable
  40. * No
  41. *
  42. * Author:
  43. * Christos Tsollis
  44. */
  45. #include "mcsdllif.h"
  46. #include "mcsuser.h"
  47. #include "gcontrol.h"
  48. extern CRITICAL_SECTION g_csGCCProvider;
  49. /*
  50. * g_pMCSController
  51. * This is a pointer to the one-and-only controller created within the
  52. * MCS system. This object is created during MCSInitialize by the process
  53. * that is taking on the responsibilities of the node controller.
  54. */
  55. extern PController g_pMCSController;
  56. void CALLBACK MCSCallBackProcedure (UINT, LPARAM, PVoid);
  57. // MACROS used with the packet rebuilder
  58. #define SEND_DATA_PACKET 0
  59. #define UNIFORM_SEND_DATA_PACKET 1
  60. extern MCSDLLInterface *g_pMCSIntf;
  61. /*
  62. * MCSDLLInterface ( )
  63. *
  64. * Public
  65. *
  66. * Functional Description:
  67. * This is the constructor for the MCS Interface class. It is responsible
  68. * for initializing the MCAT MCS DLL. Any errors that occur during
  69. * initialization are returned in the error_value provided.
  70. */
  71. MCSDLLInterface::MCSDLLInterface(PMCSError error_value)
  72. :
  73. m_ConfirmConnHdlConfList2(),
  74. m_MCSUserList()
  75. {
  76. /*
  77. ** Create/initialize the MCS Controller object.
  78. */
  79. DBG_SAVE_FILE_LINE
  80. g_pMCSController = new Controller (error_value);
  81. if (g_pMCSController == NULL) {
  82. /*
  83. * The allocation of the controller failed. Report and return
  84. * the appropriate error.
  85. */
  86. WARNING_OUT (("MCSDLLInterface::MCSDLLInterface: controller creation failed"));
  87. *error_value = MCS_ALLOCATION_FAILURE;
  88. }
  89. #ifdef _DEBUG
  90. else if (*error_value != MCS_NO_ERROR) {
  91. WARNING_OUT (("MCSDLLInterface::MCSDLLInterface: MCS controller is faulty."));
  92. }
  93. #endif // _DEBUG
  94. }
  95. /*
  96. * ~MCSDLLInterface ()
  97. *
  98. * Public
  99. *
  100. * Functional Description:
  101. * This is the destructor for the MCS Interface class. It is responsible
  102. * for cleaning up both itself and the MCAT MCS DLL.
  103. */
  104. MCSDLLInterface::~MCSDLLInterface ()
  105. {
  106. /*
  107. * Destroy the controller, which will clean up all resources
  108. * in use at this time. Then reset the flag indicating that
  109. * MCS is initialized (since it no longer is).
  110. */
  111. TRACE_OUT (("MCSDLLInterface::~MCSDLLInterface: deleting controller"));
  112. if (NULL != g_pMCSController) {
  113. g_pMCSController->Release();
  114. }
  115. }
  116. /*
  117. * MCSError ConnectProviderRequest ()
  118. *
  119. * Public
  120. *
  121. * Functional Description:
  122. * This T.122 primitive is used to connect two domains. This request
  123. * should always be followed by a connect provider confirm. The
  124. * confirm will be sent to be object specified by the confirm object
  125. * the is passed into this routine.
  126. */
  127. MCSError MCSDLLInterface::ConnectProviderRequest (
  128. GCCConfID *calling_domain,
  129. GCCConfID *called_domain,
  130. TransportAddress calling_address,
  131. TransportAddress called_address,
  132. BOOL fSecure,
  133. DBBoolean upward_connection,
  134. PUChar user_data,
  135. ULong user_data_length,
  136. PConnectionHandle connection_handle,
  137. PDomainParameters domain_parameters,
  138. CConf *confirm_object)
  139. {
  140. MCSError mcs_error;
  141. ConnectRequestInfo connect_request_info;
  142. /*
  143. * Pack all necessary information into a structure, since it will not
  144. * all fit into the 4 byte parameter that is sent with the message.
  145. */
  146. connect_request_info.calling_domain = calling_domain;
  147. connect_request_info.called_domain = called_domain;
  148. connect_request_info.calling_address = calling_address;
  149. connect_request_info.called_address = called_address;
  150. connect_request_info.fSecure = fSecure;
  151. connect_request_info.upward_connection = upward_connection;
  152. connect_request_info.domain_parameters = domain_parameters;
  153. connect_request_info.user_data = user_data;
  154. connect_request_info.user_data_length = user_data_length;
  155. connect_request_info.connection_handle = connection_handle;
  156. /*
  157. * Send a connect provider request message to the controller through its
  158. * owner callback function.
  159. */
  160. ASSERT (g_pMCSController);
  161. mcs_error = g_pMCSController->HandleAppletConnectProviderRequest(&connect_request_info);
  162. if (mcs_error == MCS_NO_ERROR)
  163. {
  164. /*
  165. ** The confirm object list maintains a list of object
  166. ** pointers that have outstanding request. When the confirms
  167. ** come back in, they will be routed to the appropriate object
  168. ** based on the connection handle.
  169. */
  170. mcs_error = AddObjectToConfirmList (confirm_object,
  171. *connection_handle);
  172. }
  173. else
  174. {
  175. WARNING_OUT(("MCSDLLInterface::ConnectProviderRequest: error = %d", mcs_error));
  176. }
  177. return (mcs_error);
  178. }
  179. MCSError MCSDLLInterface::ConnectProviderResponse (
  180. ConnectionHandle connection_handle,
  181. GCCConfID *domain_selector,
  182. PDomainParameters domain_parameters,
  183. Result result,
  184. PUChar user_data,
  185. ULong user_data_length)
  186. {
  187. ConnectResponseInfo connect_response_info;
  188. /*
  189. * Pack all necessary information into a structure, since it will not
  190. * all fit into the 4 byte parameter that is sent with the message.
  191. */
  192. connect_response_info.connection_handle = connection_handle;
  193. connect_response_info.domain_selector = domain_selector;
  194. connect_response_info.domain_parameters = domain_parameters;
  195. connect_response_info.result = result;
  196. connect_response_info.user_data = user_data;
  197. connect_response_info.user_data_length = user_data_length;
  198. ASSERT (g_pMCSController);
  199. /*
  200. * Send a connect provider response message to the controller through its
  201. * owner callback function.
  202. */
  203. return g_pMCSController->HandleAppletConnectProviderResponse(&connect_response_info);
  204. }
  205. /*
  206. * MCSError DisconnectProviderRequest ()
  207. *
  208. * Public
  209. *
  210. * Functional Description:
  211. * This function is used to disconnect a node from a particular connection.
  212. * This can be either an upward or downward connection
  213. */
  214. MCSError MCSDLLInterface::DisconnectProviderRequest (
  215. ConnectionHandle connection_handle)
  216. {
  217. ASSERT (g_pMCSController);
  218. m_ConfirmConnHdlConfList2.Remove(connection_handle);
  219. return g_pMCSController->HandleAppletDisconnectProviderRequest(connection_handle);
  220. }
  221. /*
  222. * MCSError AttachUserRequest ()
  223. *
  224. * Public
  225. *
  226. * Functional Description:
  227. * This function is used to create a user attachment to MCS. It will result
  228. * in an attach user confirm.
  229. */
  230. MCSError MCSDLLInterface::AttachUserRequest
  231. (
  232. GCCConfID *domain_selector,
  233. PIMCSSap *ppMCSSap,
  234. MCSUser *user_object
  235. )
  236. {
  237. MCSError mcs_error;
  238. mcs_error = MCS_AttachRequest (ppMCSSap,
  239. (DomainSelector) domain_selector,
  240. sizeof(GCCConfID),
  241. MCSCallBackProcedure,
  242. (PVoid) user_object,
  243. ATTACHMENT_DISCONNECT_IN_DATA_LOSS |
  244. ATTACHMENT_MCS_FREES_DATA_IND_BUFFER);
  245. if (mcs_error == MCS_NO_ERROR)
  246. m_MCSUserList.Append(user_object);
  247. return (mcs_error);
  248. }
  249. /*
  250. * MCSError DetachUserRequest ()
  251. *
  252. * Public
  253. *
  254. * Functional Description:
  255. * This function is used when a user of MCS whishes to detach itself from
  256. * a domain.
  257. */
  258. MCSError MCSDLLInterface::DetachUserRequest (PIMCSSap pMCSSap,
  259. PMCSUser pMCSUser)
  260. {
  261. MCSError mcs_error;
  262. #ifdef DEBUG
  263. UINT_PTR storing = (UINT_PTR) this;
  264. #endif // DEBUG
  265. mcs_error = pMCSSap->ReleaseInterface();
  266. ASSERT ((UINT_PTR) this == storing);
  267. m_MCSUserList.Remove(pMCSUser);
  268. return (mcs_error);
  269. }
  270. /*
  271. * void ProcessCallback ()
  272. *
  273. * Public
  274. *
  275. * Functional Description:
  276. * This routine is called whenever a callback message is received by
  277. * the "C" callback routine. It is responsible for both processing
  278. * callback messages and forwarding callback messages on to the
  279. * appropriate object.
  280. */
  281. void MCSDLLInterface::ProcessCallback (unsigned int message,
  282. LPARAM parameter,
  283. PVoid object_ptr)
  284. {
  285. ConnectionHandle connection_handle;
  286. CConf *pConf;
  287. /*
  288. ** Before processing any callbacks from MCS we must enter a critical
  289. ** section to gaurantee that we do not attempt to process a message
  290. ** in GCC while its own thread is running.
  291. */
  292. EnterCriticalSection (&g_csGCCProvider);
  293. if (MCS_SEND_DATA_INDICATION == message ||
  294. MCS_UNIFORM_SEND_DATA_INDICATION == message) {
  295. /*
  296. ** First check the segmentation flag to make sure we have the
  297. ** entire packet. If not we must give the partial packet to
  298. ** the packet rebuilder and wait for the remainder of the data.
  299. */
  300. ASSERT(((PSendData)parameter)->segmentation == (SEGMENTATION_BEGIN | SEGMENTATION_END));
  301. if (IsUserAttachmentVaid ((PMCSUser)object_ptr)) {
  302. // Process the entire packet
  303. if (message == MCS_SEND_DATA_INDICATION)
  304. {
  305. ((PMCSUser)object_ptr)->ProcessSendDataIndication((PSendData) parameter);
  306. }
  307. else
  308. {
  309. ((PMCSUser)object_ptr)->ProcessUniformSendDataIndication((PSendData) parameter);
  310. }
  311. }
  312. }
  313. else {
  314. //
  315. // Non-Send-Data callbacks.
  316. //
  317. WORD wHiWordParam = HIWORD(parameter);
  318. WORD wLoWordParam = LOWORD(parameter);
  319. switch (message)
  320. {
  321. /*
  322. ** These messages are handled by the object passed in through
  323. ** the user data field.
  324. */
  325. case MCS_DETACH_USER_INDICATION:
  326. if (IsUserAttachmentVaid ((PMCSUser)object_ptr))
  327. {
  328. ((PMCSUser)object_ptr)->ProcessDetachUserIndication(
  329. (Reason) wHiWordParam,
  330. (UserID) wLoWordParam);
  331. }
  332. break;
  333. case MCS_ATTACH_USER_CONFIRM:
  334. if (IsUserAttachmentVaid ((PMCSUser)object_ptr))
  335. {
  336. ((PMCSUser)object_ptr)->ProcessAttachUserConfirm(
  337. (Result) wHiWordParam,
  338. (UserID) wLoWordParam);
  339. }
  340. break;
  341. case MCS_CHANNEL_JOIN_CONFIRM:
  342. if (IsUserAttachmentVaid ((PMCSUser)object_ptr))
  343. {
  344. ((PMCSUser)object_ptr)->ProcessChannelJoinConfirm(
  345. (Result) wHiWordParam,
  346. (ChannelID) wLoWordParam);
  347. }
  348. break;
  349. case MCS_CHANNEL_LEAVE_INDICATION:
  350. #if 0 // LONCHANC: MCSUser does not handle this message.
  351. if (IsUserAttachmentVaid ((PMCSUser)object_ptr))
  352. {
  353. ((PMCSUser)object_ptr)->OwnerCallback(CHANNEL_LEAVE_INDICATION,
  354. NULL,
  355. parameter);
  356. }
  357. #endif // 0
  358. break;
  359. case MCS_TOKEN_GRAB_CONFIRM:
  360. if (IsUserAttachmentVaid ((PMCSUser)object_ptr) )
  361. {
  362. ((PMCSUser)object_ptr)->ProcessTokenGrabConfirm(
  363. (TokenID) wLoWordParam,
  364. (Result) wHiWordParam);
  365. }
  366. break;
  367. case MCS_TOKEN_GIVE_INDICATION:
  368. if (IsUserAttachmentVaid ((PMCSUser)object_ptr) )
  369. {
  370. ((PMCSUser)object_ptr)->ProcessTokenGiveIndication(
  371. (TokenID) wLoWordParam,
  372. (UserID) wHiWordParam);
  373. }
  374. break;
  375. case MCS_TOKEN_GIVE_CONFIRM:
  376. if (IsUserAttachmentVaid ((PMCSUser)object_ptr) )
  377. {
  378. ((PMCSUser)object_ptr)->ProcessTokenGiveConfirm(
  379. (TokenID) wLoWordParam,
  380. (Result) wHiWordParam);
  381. }
  382. break;
  383. case MCS_TOKEN_PLEASE_INDICATION:
  384. #ifdef JASPER
  385. if (IsUserAttachmentVaid ((PMCSUser)object_ptr) )
  386. {
  387. ((PMCSUser)object_ptr)->ProcessTokenPleaseIndication(
  388. (TokenID) wLoWordParam,
  389. (UserID) wHiWordParam);
  390. }
  391. #endif // JASPER
  392. break;
  393. case MCS_TOKEN_RELEASE_CONFIRM:
  394. #ifdef JASPER
  395. if (IsUserAttachmentVaid ((PMCSUser)object_ptr) )
  396. {
  397. ((PMCSUser)object_ptr)->ProcessTokenReleaseConfirm(
  398. (TokenID) wLoWordParam,
  399. (Result) wHiWordParam);
  400. }
  401. #endif // JASPER
  402. break;
  403. case MCS_TOKEN_TEST_CONFIRM:
  404. if (IsUserAttachmentVaid ((PMCSUser)object_ptr) )
  405. {
  406. ((PMCSUser)object_ptr)->ProcessTokenTestConfirm(
  407. (TokenID) wLoWordParam,
  408. (TokenStatus) wHiWordParam);
  409. }
  410. break;
  411. /*
  412. ** These messages are handled by the object that created the
  413. ** MCS DLL interface.
  414. */
  415. #ifdef TSTATUS_INDICATION
  416. case MCS_TRANSPORT_STATUS_INDICATION:
  417. if (g_pControlSap != NULL)
  418. {
  419. g_pControlSap->TransportStatusIndication((PTransportStatus) parameter);
  420. }
  421. break;
  422. #endif
  423. case MCS_CONNECT_PROVIDER_INDICATION:
  424. g_pGCCController->ProcessConnectProviderIndication((PConnectProviderIndication) parameter);
  425. // Cleanup the controller message.
  426. delete (PConnectProviderIndication) parameter;
  427. break;
  428. case MCS_DISCONNECT_PROVIDER_INDICATION:
  429. connection_handle = (ConnectionHandle) parameter;
  430. g_pGCCController->ProcessDisconnectProviderIndication(connection_handle);
  431. /*
  432. ** If no entry exists in the confirm object list, there
  433. ** is a problem. All confirms must have an associated
  434. ** response.
  435. */
  436. if (m_ConfirmConnHdlConfList2.Remove(connection_handle))
  437. {
  438. DisconnectProviderRequest(connection_handle);
  439. }
  440. break;
  441. /*
  442. ** All connect provider confirms must be matched up with the
  443. ** connect provider request to determine where to route the
  444. ** message.
  445. */
  446. case MCS_CONNECT_PROVIDER_CONFIRM:
  447. connection_handle = ((PConnectProviderConfirm)parameter)->connection_handle;
  448. /*
  449. ** If no entry exists in the confirm object list, there
  450. ** is a problem. All confirms must have an associated
  451. ** response.
  452. */
  453. if (NULL != (pConf = m_ConfirmConnHdlConfList2.Remove(connection_handle)))
  454. {
  455. // Send the confirm to the appropriate object
  456. if ((LPVOID) pConf != (LPVOID) LPVOID_NULL)
  457. {
  458. // confirm_object is a CConf.
  459. pConf->ProcessConnectProviderConfirm((PConnectProviderConfirm) parameter);
  460. }
  461. else
  462. {
  463. // confirm_object is the GCC Controller.
  464. g_pGCCController->ProcessConnectProviderConfirm((PConnectProviderConfirm)parameter);
  465. }
  466. }
  467. else
  468. {
  469. WARNING_OUT(("MCSDLLInterface: ProcessCallback: Bad Connect"
  470. " Provider Confirm received"));
  471. }
  472. // Cleanup the controller message.
  473. CoTaskMemFree( ((PConnectProviderConfirm) parameter)->pb_cred );
  474. delete (PConnectProviderConfirm) parameter;
  475. break;
  476. default:
  477. WARNING_OUT(("MCSDLLInterface: ProcessCallback: Unsupported message"
  478. " received from MCS = %d",message));
  479. break;
  480. }
  481. }
  482. // Leave the critical section after the callback is processed.
  483. LeaveCriticalSection (&g_csGCCProvider);
  484. }
  485. /*
  486. * void CALLBACK MCSCallBackProcedure ( unsigned int message,
  487. * LPARAM parameter,
  488. * PVoid user_defined)
  489. *
  490. * Functional Description:
  491. * This routine receives callback messages directly from the MCAT MCS
  492. * DLL.
  493. *
  494. * Formal Parameters:
  495. * message (i)
  496. * This is the mcs message to be processed
  497. * parameter (i)
  498. * Varies according to the message. See the MCAT programmers manual
  499. * object_ptr (i)
  500. * This is the user defined field that was passed to MCS on
  501. * initialization.
  502. *
  503. * Return Value:
  504. * See ProcessCallback
  505. *
  506. * Side Effects:
  507. * None.
  508. *
  509. * Caveats:
  510. * None.
  511. */
  512. void CALLBACK MCSCallBackProcedure (unsigned int message,
  513. LPARAM parameter,
  514. PVoid user_defined)
  515. {
  516. if (g_pMCSIntf != NULL)
  517. g_pMCSIntf->ProcessCallback (message, parameter, user_defined);
  518. }
  519. /*
  520. * TranslateMCSResultToGCCResult ()
  521. *
  522. * Public Function Description
  523. * This routine translate a standard MCS result to a GCC result.
  524. */
  525. GCCResult
  526. TranslateMCSResultToGCCResult ( Result mcs_result )
  527. {
  528. GCCResult gcc_result;
  529. switch (mcs_result)
  530. {
  531. case RESULT_SUCCESSFUL:
  532. gcc_result = GCC_RESULT_SUCCESSFUL;
  533. break;
  534. case RESULT_PARAMETERS_UNACCEPTABLE:
  535. gcc_result = GCC_RESULT_DOMAIN_PARAMETERS_UNACCEPTABLE;
  536. break;
  537. case RESULT_USER_REJECTED:
  538. gcc_result = GCC_RESULT_USER_REJECTED;
  539. break;
  540. /*
  541. ** Note that we are making the assumption here that the only token
  542. ** that GCC deals with is a conductor token.
  543. */
  544. case RESULT_TOKEN_NOT_AVAILABLE:
  545. gcc_result = GCC_RESULT_IN_CONDUCTED_MODE;
  546. break;
  547. case RESULT_TOKEN_NOT_POSSESSED:
  548. gcc_result = GCC_RESULT_NOT_THE_CONDUCTOR;
  549. break;
  550. /****************************************************************/
  551. case RESULT_UNSPECIFIED_FAILURE:
  552. default:
  553. gcc_result = GCC_RESULT_UNSPECIFIED_FAILURE;
  554. break;
  555. }
  556. return (gcc_result);
  557. }
  558. /*
  559. * MCSError AddObjectToConfirmList ()
  560. *
  561. * Functional Description:
  562. * This function is used to add information about an object to the list
  563. * which holds all information required to send connect provider confirms.
  564. *
  565. * Formal Parameters:
  566. * confirm_object (i)
  567. * This is a pointer to the object the made the connect provider
  568. * request.
  569. * connection_handle (i)
  570. * This is the connection handle returned from the connect provider
  571. * request.
  572. *
  573. * Return Value:
  574. *
  575. * Side Effects:
  576. * None.
  577. *
  578. * Caveats:
  579. * None.
  580. */
  581. MCSError MCSDLLInterface::AddObjectToConfirmList (
  582. CConf *pConf,
  583. ConnectionHandle connection_handle)
  584. {
  585. MCSError return_value;
  586. /*
  587. ** First check to make sure that the list doesn't already contain the
  588. ** connection.
  589. */
  590. if (m_ConfirmConnHdlConfList2.Find(connection_handle) == FALSE)
  591. {
  592. // Add it to the list
  593. m_ConfirmConnHdlConfList2.Append(connection_handle, pConf ? pConf : (CConf *) LPVOID_NULL);
  594. return_value = MCS_NO_ERROR;
  595. }
  596. else
  597. return_value = MCS_INVALID_PARAMETER;
  598. return (return_value);
  599. }
  600.