Source code of Windows XP (NT5)
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.

616 lines
23 KiB

  1. /*
  2. * control.h
  3. *
  4. * Copyright (c) 1993 - 1996 by DataBeam Corporation, Lexington, KY
  5. *
  6. * Abstract:
  7. * This is the interface file for the MCS Controller class. There will
  8. * be exactly one instance of this class at run-time, whose job it is
  9. * to coordinate the creation, deletion, and linking of other objects
  10. * in the system.
  11. *
  12. * The controller is primarily responsible for managing five "layers"
  13. * of objects in the system at run-time. These layers can be depicted
  14. * as follows:
  15. *
  16. * +---+ +------------------------+
  17. * | | <---> | Application Interfaces |
  18. * | | +------------------------+
  19. * | | |
  20. * | C | +------------------------+
  21. * | o | <---> | User Attachments |
  22. * | n | +------------------------+
  23. * | t | |
  24. * | r | +------------------------+
  25. * | o | <---> | Domains |
  26. * | l | +------------------------+
  27. * | l | |
  28. * | e | +------------------------+
  29. * | r | <---> | MCS Connections |
  30. * | | +------------------------+
  31. * | | |
  32. * | | +------------------------+
  33. * | | <---> | Transport Interfaces |
  34. * +---+ +------------------------+
  35. *
  36. * The controller is the first object created in the MCS system. It is
  37. * responsible for creating all other objects during initialization. In
  38. * the constructor, the controller creates all necessary application
  39. * interface and transport interface objects. These are the objects
  40. * through which MCS communicates with the outside world. They are
  41. * static in that they live throughout the lifetime of MCS itself.
  42. *
  43. * During initialization, the node controller must register itself with
  44. * the controller so that the controller knows which application interface
  45. * object to use when issuing indications and confirms back to the node
  46. * controller. Note that even though it is possible to have more than
  47. * one way to communicate with applications, there is still only one node
  48. * controller.
  49. *
  50. * Four of the five layers of objects communicate with the controller
  51. * through the owner callback facility. This mechanism is used to send
  52. * requests to the controller.
  53. *
  54. * User attachments (instances of class User) are created when the
  55. * controller receives an AttachUserRequest from one of the application
  56. * interface objects (with a valid domain selector). A new user object
  57. * is created, who in turn registers with the correct application interface
  58. * object to insure proper data flow at run-time.
  59. *
  60. * Domains (instances of class Domain) are created when the controller
  61. * receives a CreateDomain from one of the application interface objects.
  62. * Since both user attachments and MCS connections identify specific
  63. * domains, this must occur before any attaching or connecting can be
  64. * done.
  65. *
  66. * MCS connections (instances of class Connection) are created in two
  67. * possible ways. First, when a ConnectProviderRequest is received from
  68. * one of the application interface objects (with a valid local domain
  69. * selector and a valid transport address). Second, when a
  70. * ConnectProviderResponse is received from one of the application
  71. * interface objects in response to a previous connect provider indication.
  72. * Either way, a Connection object is created to represent the new MCS
  73. * connection.
  74. *
  75. * User attachments are deleted in one of two ways. First, when a
  76. * DetachUserRequest is received from an application interface with a
  77. * valid user handle. Second, if the user attachment is told by the
  78. * domain that the attachment is severed. In the latter case, the user
  79. * object asks the controller to delete it using the owner callback
  80. * facility.
  81. *
  82. * Domains are deleted when a DeleteDomain is received from an application
  83. * interface.
  84. *
  85. * Connections are deleted in one of three ways. First, when a
  86. * DisconnectProviderRequest is received from an application interface
  87. * with a valid connection handle. Second, if the transport interface
  88. * detects a loss of the connection at a lower layer. Third, if the
  89. * connection is told by the domain that the connection is to be severed.
  90. * In the latter two cases, the connection object asks the controller to
  91. * delete it using the owner callback facility.
  92. *
  93. * The primary role of the controller is to create and delete all of these
  94. * objects, and to "plug" them together as needed.
  95. *
  96. * During initialization, the controller also creates a single instance
  97. * of a memory manager. This objects is then passed on to all other
  98. * objects that require its services (in their constructors). A possible
  99. * way to improve upon this scheme would be to create a memory manager
  100. * for each domain, so that traffic in one domain does not influence
  101. * traffic in another.
  102. *
  103. * Portable:
  104. * Not completely. During initialization, the constructor "knows"
  105. * how to create application interface and transport interface objects
  106. * that are specific to the environment. In the case of the transport
  107. * interfaces, it actually reads a windows ".INI" file. It can also
  108. * optionally allocate a windows timer in order have a "heartbeat". Other
  109. * than initialization, everything else is portable.
  110. *
  111. * Caveats:
  112. * There can be only one instance of this class in an MCS provider.
  113. *
  114. * Author:
  115. * James P. Galvin, Jr.
  116. */
  117. #ifndef _CONTROLLER_
  118. #define _CONTROLLER_
  119. /*
  120. * Include files.
  121. */
  122. #include "omcscode.h"
  123. /*
  124. * This structure is used to hold information about an incoming connection,
  125. * while MCS waits for a connect provider response from the node controller.
  126. */
  127. typedef struct
  128. {
  129. TransportConnection transport_connection;
  130. BOOL upward_connection;
  131. DomainParameters domain_parameters;
  132. DomainParameters minimum_domain_parameters;
  133. DomainParameters maximum_domain_parameters;
  134. } ConnectionPending;
  135. typedef ConnectionPending * PConnectionPending;
  136. /*
  137. * This is the set of container definitions defined using templates. All
  138. * containers are based on classes in the Rogue Wave Tools.h++ class
  139. * library.
  140. *
  141. * The controller keeps a list of objects at each of the five levels, as
  142. * follows:
  143. *
  144. * DomainList
  145. * This is a dictionary of currently existing domain objects, which is
  146. * keyed by DomainSelector.
  147. * CConnectionList2
  148. * This is a dictionary of currently existing connection objects, which is
  149. * keyed by connection handle.
  150. * TransportList
  151. * This is a dictionary of currently existing transport interface objects,
  152. * which is keyed by transport identifier. Note that the transport
  153. * identifier is just a character string.
  154. * ConnectionPendingList
  155. * This is a dictionary of pending connections. The key is the connection
  156. * handle, and the value is a pointer to a connection pending structure
  157. * that "remembers" details about a pending connection that are not
  158. * going to be passed back in the connect provider response.
  159. * ConnectionPollList
  160. * This is a singly-linked list that is used to hold all connection
  161. * objects. This list is used to iterate through the list, granting a time
  162. * slice to each object during the heartbeat.
  163. */
  164. class CConnPendingList2 : public CList2
  165. {
  166. DEFINE_CLIST2_(CConnPendingList2, PConnectionPending, ConnectionHandle)
  167. };
  168. class CConnPollList : public CList
  169. {
  170. DEFINE_CLIST(CConnPollList, PConnection)
  171. };
  172. /*
  173. * The controller makes extensive use of the owner callback mechanism to
  174. * receive requests from the objects that it owns. In order for the
  175. * requests to be differentiated here in the controller, each object must
  176. * issue its message using a different message offset. The required message
  177. * offset is given to each object as it is created by the controller. The
  178. * message offsets for the five layers of objects are as follows.
  179. *
  180. * This allows the controller to easily determine what type of object a
  181. * given owner callback message is from (see the implementation of the
  182. * OwnerCallback member function for details).
  183. */
  184. #define APPLICATION_MESSAGE_BASE 0
  185. #define USER_MESSAGE_BASE 100
  186. #define DOMAIN_MESSAGE_BASE 200
  187. #define CONNECTION_MESSAGE_BASE 300
  188. #ifndef TRANSPORT_MESSAGE_BASE
  189. #define TRANSPORT_MESSAGE_BASE 400
  190. #endif // !TRANSPORT_MESSAGE_BASE
  191. /*
  192. ** The following are timeout times that are used to set and test the
  193. ** Controller_Wait_Timeout instance variable of a Controller object.
  194. ** When the controller is signalled thru an event to process and send
  195. ** msgs to an application, GCC, etc..., tries to process it. Sometimes
  196. ** the event can't be processed immediately. In these cases, we make
  197. ** the controller timeout in the WaitForMultipleObjects finite, and set
  198. ** the Controller_Event_Mask to store which event we want to re-try
  199. ** later. When the event is processed, the mask is reset.
  200. */
  201. #define CONTROLLER_THREAD_TIMEOUT 200
  202. #define TRANSPORT_RECEIVE_TIMEOUT 300
  203. #define TRANSPORT_TRANSMIT_TIMEOUT 10000
  204. /*
  205. ** The following are the indices in the arrays of masks and timeouts.
  206. */
  207. #define TRANSPORT_RECEIVE_INDEX 0
  208. #define TRANSPORT_TRANSMIT_INDEX 1
  209. #define GCC_FLUSH_OUTGOING_PDU_INDEX 3
  210. /*
  211. ** The following values are the masks used for checking against
  212. ** the Controller_Event_Mask in the PollMCSDevices() member of the
  213. ** MCS Controller.
  214. */
  215. #define TRANSPORT_RECEIVE_MASK (0x1 << TRANSPORT_RECEIVE_INDEX)
  216. #define TRANSPORT_TRANSMIT_MASK (0x1 << TRANSPORT_TRANSMIT_INDEX)
  217. #define GCC_FLUSH_OUTGOING_PDU_MASK (0x1 << GCC_FLUSH_OUTGOING_PDU_INDEX)
  218. #define TRANSPORT_MASK (TRANSPORT_RECEIVE_MASK | TRANSPORT_TRANSMIT_MASK)
  219. /*
  220. * These are the owner callback functions that an application interface object
  221. * can send to its creator (which is typically the MCS controller). The
  222. * first one allows an application interface object to tell the controller that
  223. * it represents the interface to the node controller application. The rest
  224. * are primitives that would generally come from the node controller
  225. * application, but must be acted upon internally by the MCS controller.
  226. *
  227. * When an object instantiates an application interface object (or any other
  228. * object that uses owner callbacks), it is accepting the responsibility of
  229. * receiving and handling those callbacks. For that reason, any object that
  230. * issues owner callbacks will have those callbacks defined as part of the
  231. * interface file (since they really are part of a bi-directional interface).
  232. *
  233. * Each owner callback function, along with a description of how its parameters
  234. * are packed, is described in the following section.
  235. */
  236. #define REGISTER_NODE_CONTROLLER 0
  237. #define RESET_DEVICE 1
  238. #define CREATE_DOMAIN 2
  239. #define DELETE_DOMAIN 3
  240. #define CONNECT_PROVIDER_REQUEST 4
  241. #define CONNECT_PROVIDER_RESPONSE 5
  242. #define DISCONNECT_PROVIDER_REQUEST 6
  243. #define APPLICATION_ATTACH_USER_REQUEST 7
  244. /*
  245. * These are the structures used by some of the owner callback function listed
  246. * above (for the case that the parameters to a function cannot fit into two
  247. * 32-bit parameters).
  248. */
  249. #ifdef NM_RESET_DEVICE
  250. typedef struct
  251. {
  252. PChar device_identifier;
  253. } ResetDeviceInfo;
  254. typedef ResetDeviceInfo * PResetDeviceInfo;
  255. #endif // #ifdef NM_RESET_DEVICE
  256. typedef struct
  257. {
  258. TransportAddress local_address;
  259. PInt local_address_length;
  260. } LocalAddressInfo;
  261. typedef LocalAddressInfo * PLocalAddressInfo;
  262. typedef struct
  263. {
  264. GCCConfID *calling_domain;
  265. GCCConfID *called_domain;
  266. PChar calling_address;
  267. PChar called_address;
  268. BOOL fSecure;
  269. BOOL upward_connection;
  270. PDomainParameters domain_parameters;
  271. PUChar user_data;
  272. ULong user_data_length;
  273. PConnectionHandle connection_handle;
  274. } ConnectRequestInfo;
  275. typedef ConnectRequestInfo * PConnectRequestInfo;
  276. typedef struct
  277. {
  278. ConnectionHandle connection_handle;
  279. GCCConfID *domain_selector;
  280. PDomainParameters domain_parameters;
  281. Result result;
  282. PUChar user_data;
  283. ULong user_data_length;
  284. } ConnectResponseInfo;
  285. typedef ConnectResponseInfo * PConnectResponseInfo;
  286. typedef struct
  287. {
  288. GCCConfID *domain_selector;
  289. PUser *ppuser;
  290. } AttachRequestInfo;
  291. typedef AttachRequestInfo * PAttachRequestInfo;
  292. /*
  293. * These structures are used to hold information that would not fit into
  294. * the one parameter defined as part of an MCS call back function. In the case
  295. * where these structures are used for call backs, the address of the structure
  296. * is passed as the only parameter.
  297. */
  298. // LONCHANC: we dropped calling and called domain selectors here.
  299. typedef struct
  300. {
  301. ConnectionHandle connection_handle;
  302. BOOL upward_connection;
  303. DomainParameters domain_parameters;
  304. unsigned char * user_data;
  305. unsigned long user_data_length;
  306. BOOL fSecure;
  307. } ConnectProviderIndication;
  308. typedef ConnectProviderIndication * PConnectProviderIndication;
  309. typedef struct
  310. {
  311. ConnectionHandle connection_handle;
  312. DomainParameters domain_parameters;
  313. Result result;
  314. unsigned char * user_data;
  315. unsigned long user_data_length;
  316. PBYTE pb_cred;
  317. DWORD cb_cred;
  318. } ConnectProviderConfirm;
  319. typedef ConnectProviderConfirm * PConnectProviderConfirm;
  320. /*
  321. * This is the class definition for the Controller class. It is worth
  322. * noting that there are only three public member functions defined in the
  323. * controller (besides the constructor and the destructor). The Owner
  324. * callback function is used by all "owned" objects to make requests
  325. * of the controller (who created them). The poll routine, which is
  326. * called from the windows timer event handler. This is the heartbeat
  327. * of MCS at the current time.
  328. */
  329. class Controller : public CRefCount
  330. {
  331. public:
  332. Controller (
  333. PMCSError mcs_error);
  334. ~Controller ();
  335. Void CreateTCPWindow ();
  336. Void DestroyTCPWindow ();
  337. Void EventLoop ();
  338. BOOL FindSocketNumber(ConnectionHandle connection_handle, SOCKET * socket_number);
  339. BOOL GetLocalAddress(
  340. ConnectionHandle connection_handle,
  341. TransportAddress local_address,
  342. PInt local_address_length);
  343. // the old owner callback
  344. void HandleTransportDataIndication(PTransportData);
  345. void HandleTransportWaitUpdateIndication(BOOL fMoreData);
  346. #ifdef NM_RESET_DEVICE
  347. MCSError HandleAppletResetDevice(PResetDeviceInfo);
  348. #endif
  349. MCSError HandleAppletCreateDomain(GCCConfID *domain_selector);
  350. MCSError HandleAppletDeleteDomain(GCCConfID *domain_selector);
  351. MCSError HandleAppletConnectProviderRequest(PConnectRequestInfo);
  352. MCSError HandleAppletConnectProviderResponse(PConnectResponseInfo);
  353. MCSError HandleAppletDisconnectProviderRequest(ConnectionHandle);
  354. MCSError HandleAppletAttachUserRequest(PAttachRequestInfo);
  355. void HandleConnDeleteConnection(ConnectionHandle);
  356. void HandleConnConnectProviderConfirm(PConnectConfirmInfo, ConnectionHandle);
  357. void HandleTransportDisconnectIndication(TransportConnection, ULONG *pnNotify);
  358. #ifdef TSTATUS_INDICATION
  359. void HandleTransportStatusIndication(PTransportStatus);
  360. #endif
  361. private:
  362. #ifdef NM_RESET_DEVICE
  363. ULong ApplicationResetDevice (
  364. PChar device_identifier);
  365. #endif // NM_RESET_DEVICE
  366. MCSError ApplicationCreateDomain(GCCConfID *domain_selector);
  367. MCSError ApplicationDeleteDomain(GCCConfID *domain_selector);
  368. MCSError ApplicationConnectProviderRequest (
  369. PConnectRequestInfo pcriConnectRequestInfo);
  370. MCSError ApplicationConnectProviderResponse (
  371. ConnectionHandle connection_handle,
  372. GCCConfID *domain_selector,
  373. PDomainParameters domain_parameters,
  374. Result result,
  375. PUChar user_data,
  376. ULong user_data_length);
  377. MCSError ApplicationDisconnectProviderRequest (
  378. ConnectionHandle connection_handle);
  379. MCSError ApplicationAttachUserRequest (
  380. GCCConfID *domain_selector,
  381. PUser *ppUser);
  382. Void ConnectionDeleteConnection (
  383. ConnectionHandle connection_handle);
  384. void ConnectionConnectProviderConfirm (
  385. ConnectionHandle connection_handle,
  386. PDomainParameters domain_parameters,
  387. Result result,
  388. PMemory memory);
  389. Void TransportDisconnectIndication (
  390. TransportConnection transport_connection);
  391. Void TransportDataIndication (
  392. TransportConnection transport_connection,
  393. PUChar user_data,
  394. ULong user_data_length);
  395. #ifdef TSTATUS_INDICATION
  396. Void TransportStatusIndication (
  397. PTransportStatus transport_status);
  398. #endif
  399. Void ProcessConnectInitial (
  400. TransportConnection transport_connection,
  401. ConnectInitialPDU *pdu_structure);
  402. Void ProcessConnectAdditional (
  403. TransportConnection transport_connection,
  404. ConnectAdditionalPDU *pdu_structure);
  405. Void ConnectResponse (
  406. TransportConnection transport_connection,
  407. Result result,
  408. PDomainParameters domain_parameters,
  409. ConnectID connect_id,
  410. PUChar user_data,
  411. ULong user_data_length);
  412. Void ConnectResult (
  413. TransportConnection transport_connection,
  414. Result result);
  415. ConnectionHandle AllocateConnectionHandle ();
  416. Void PollMCSDevices ();
  417. Void UpdateWaitInfo (
  418. BOOL bMoreData,
  419. UINT index);
  420. ConnectionHandle Connection_Handle_Counter;
  421. HANDLE Transport_Transmit_Event;
  422. HANDLE Connection_Deletion_Pending_Event;
  423. BOOL Controller_Closing;
  424. BOOL m_fControllerThreadActive;
  425. CDomainList2 m_DomainList2;
  426. CConnectionList2 m_ConnectionList2;
  427. CConnPollList m_ConnPollList;
  428. CConnPendingList2 m_ConnPendingList2;
  429. CConnectionList2 m_ConnectionDeletionList2;
  430. BOOL Connection_Deletion_Pending;
  431. BOOL Domain_Traffic_Allowed;
  432. DWORD Controller_Wait_Timeout;
  433. DWORD Controller_Event_Mask;
  434. #ifndef NO_TCP_TIMER
  435. UINT_PTR Timer_ID;
  436. #endif /* NO_TCP_TIMER */
  437. public:
  438. HANDLE Synchronization_Event;
  439. };
  440. typedef Controller * PController;
  441. /*
  442. * Controller (
  443. * UShort timer_duration,
  444. * PMCSError mcs_error)
  445. *
  446. * Functional Description:
  447. * This is the constructor for the MCS controller. Its primary
  448. * duty is to instantiate the application interface and transport
  449. * interface objects that will be used by this provider. These objects
  450. * are static in that they are created by the controller constructor
  451. * and destroyed by the controller destructor (below). Unlike other
  452. * objects in the system, they are NOT created and destroyed as needed.
  453. *
  454. * The constructor also instantiates the memory manager that will be
  455. * used throughout the MCS system.
  456. *
  457. * The constructor also allocates a windows timer that is used to
  458. * provide MCS with a "heartbeat". This is VERY platform specific and
  459. * will definitely change before final release.
  460. *
  461. * Note that if anything goes wrong, the mcs_error variable will be
  462. * set to the appropriate error. It is assumed that whoever is creating
  463. * the controller will check this return value and destroy the newly
  464. * created controller if something is wrong.
  465. *
  466. * Note that it is not possible to use MCS if there is not at least
  467. * one application interface object successfully created. However, it
  468. * is possible to use MCS if there are no transport interfaces. Multiple
  469. * user applications could use this to communicate with one another. On the
  470. * other hand, MCS_NO_TRANSPORT_STACKS is considered a fatal error.
  471. *
  472. * Formal Parameters:
  473. * timer_duration (i)
  474. * If non-zero, this causes the constructor to allocate a timer to
  475. * provide the heartbeat, and this variable is in milliseconds. If
  476. * zero, no timer is allocated, and the application is responsible
  477. * for providing the heartbeat.
  478. * mcs_error (o)
  479. * This is the return value for the constructor. In C++ constructors
  480. * cannot directly return a value, but this can be simulated by passing
  481. * in the address of a return value variable. This value should be
  482. * checked by whoever creates the controller. If it is anything but
  483. * MCS_NO_ERROR, the controller should be
  484. * deleted immediately, as this is a non-recoverable failure.
  485. *
  486. * Return Value:
  487. * MCS_NO_ERROR
  488. * Everything worked fine, and the controller is ready to be used.
  489. * MCS_NO_TRANSPORT_STACKS
  490. * The controller initialized okay, but the TCP transport did
  491. * not initialize.
  492. * MCS_ALLOCATION_FAILURE
  493. * MCS was unable to initialize properly due to a memory allocation
  494. * failure. The controller should be deleted immediately.
  495. *
  496. * Side Effects:
  497. * The proper initialization of the application interface and transport
  498. * interface objects will probably cause device initializations to occur
  499. * in readying for communication.
  500. *
  501. * Caveats:
  502. * None.
  503. */
  504. /*
  505. * ~Controller ();
  506. *
  507. * Functional Description:
  508. * This is the controller destructor. Its primary purpose is to free up
  509. * all resources used by this MCS provider. It attempts to destroy all
  510. * objects in a controlled fashion so as to cleanly sever both user
  511. * attachments and MCS connections. It does this by destroying
  512. * connections first, and then transport interfaces. Next it deletes
  513. * user attachments, followed by application interfaces. Only then does
  514. * it destroy existing domains (which should be empty as a result of all
  515. * the previous destruction).
  516. *
  517. * Note that this is the ONLY place where application interface and
  518. * transport interface objects are destroyed.
  519. *
  520. * Formal Parameters:
  521. * Destructors have no parameters.
  522. *
  523. * Return Value:
  524. * Destructors have no return value.
  525. *
  526. * Side Effects:
  527. * All external connections are broken, and devices will be released.
  528. *
  529. * Caveats:
  530. * None.
  531. */
  532. /*
  533. * ULong OwnerCallback (
  534. * unsigned int message,
  535. * PVoid parameter1,
  536. * ULong parameter2)
  537. *
  538. * Functional Description:
  539. * This is the owner callback routine for the MCS controller. This member
  540. * function is used when it is necessary for an object created by the
  541. * controller to send a message back to it.
  542. * Essentially, it allows objects to make requests of their creators
  543. * without having to "tightly couple" the two classes by having them
  544. * both aware of the public interface of the other.
  545. *
  546. * When an object such as the controller creates an object that expects
  547. * to use the owner callback facility, the creator is accepting the
  548. * responsibility of handling owner callbacks. All owner callbacks
  549. * are defined as part of the interface specification for the object
  550. * that will issue them.
  551. *
  552. * How the controller handles each owner callback is considered an
  553. * implementation issue within the controller. As such, that information
  554. * can be found in the controller implementation file.
  555. *
  556. * Formal Parameters:
  557. * message (i)
  558. * This is the message to processed. Note that when the controller
  559. * creates each object, it gives it a message offset to use for owner
  560. * callbacks, so that the controller can differentiate between
  561. * callbacks from different classes.
  562. * parameter1 (i)
  563. * The meaning of this parameter varies according to the message being
  564. * processed. See the interface specification for the class issuing
  565. * the owner callback for a detailed explanation.
  566. * parameter2 (i)
  567. * The meaning of this parameter varies according to the message being
  568. * processed. See the interface specification for the class issuing
  569. * the owner callback for a detailed explanation.
  570. *
  571. * Return Value:
  572. * Each owner callback returns an unsigned long. The meaning of this
  573. * return value varies according to the message being processed. See the
  574. * interface specification for the class issuing the owner callback for a
  575. * detailed explanation.
  576. *
  577. * Side Effects:
  578. * Message specific.
  579. *
  580. * Caveats:
  581. * None.
  582. */
  583. #endif
  584.