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.

1169 lines
34 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_GCCNC);
  3. /*
  4. * invoklst.cpp
  5. *
  6. * Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
  7. *
  8. * Abstract:
  9. * This is the implementation file for the class
  10. * CInvokeSpecifierListContainer. This class manages the data associated
  11. * with an Application Invoke Request or Indication. This includes a list
  12. * of applications to be invoked. The CInvokeSpecifierListContainer data
  13. * container utilizes a CSessKeyContainer container to buffer part of the data
  14. * associated with each application invoke specifier. Each application
  15. * invoke specifier also includes a capability ID whose data is buffered
  16. * internally by the using a CCapIDContainer container. The list
  17. * of application invoke specifiers is maintained internally by the class
  18. * through the use of a Rogue Wave list container.
  19. *
  20. * Protected Instance Variables:
  21. * m_InvokeSpecifierList
  22. * List of structures used to hold the container data internally.
  23. * m_pAPEListPDU
  24. * Storage for the "PDU" form of the invoke data.
  25. * m_fValidAPEListPDU
  26. * Flag indicating that memory has been allocated to hold the internal
  27. * "PDU" invoke data.
  28. * m_cbDataSize
  29. * Variable holding the size of the memory which will be required to
  30. * hold any data referenced by the "API" structure.
  31. *
  32. * Caveats:
  33. * None.
  34. *
  35. * Author:
  36. * blp/jbo
  37. */
  38. #include "ms_util.h"
  39. #include "invoklst.h"
  40. /*
  41. * CInvokeSpecifierListContainer ()
  42. *
  43. * Public Function Description:
  44. * This constructor is used to create an CInvokeSpecifierListContainer
  45. * object from a list of "API" application protocol entities.
  46. */
  47. CInvokeSpecifierListContainer::CInvokeSpecifierListContainer(
  48. UINT number_of_protocol_entities,
  49. PGCCAppProtocolEntity * app_protocol_entity_list,
  50. PGCCError pRetCode)
  51. :
  52. CRefCount(MAKE_STAMP_ID('I','S','L','C')),
  53. m_fValidAPEListPDU(FALSE),
  54. m_cbDataSize(0)
  55. {
  56. UINT i;
  57. PGCCAppProtocolEntity ape;
  58. INVOKE_SPECIFIER *specifier_info;
  59. /*
  60. * Initialize instance variables.
  61. */
  62. GCCError rc = GCC_NO_ERROR;
  63. /*
  64. * Go through the list of application protocol entities (APE's), saving the
  65. * necessary information in the internal list of info. structures.
  66. */
  67. for (i = 0; i < number_of_protocol_entities; i++)
  68. {
  69. /*
  70. * Create a new INVOKE_SPECIFIER structure to hold the data for this
  71. * APE. Check to make sure it was successfully created.
  72. */
  73. DBG_SAVE_FILE_LINE
  74. specifier_info = new INVOKE_SPECIFIER;
  75. if (specifier_info != NULL)
  76. {
  77. /*
  78. * Get the APE from the list.
  79. */
  80. ape = app_protocol_entity_list[i];
  81. /*
  82. * Create a new CSessKeyContainer object to hold the session key.
  83. * Check to make sure construction was successful.
  84. */
  85. DBG_SAVE_FILE_LINE
  86. specifier_info->session_key = new CSessKeyContainer(&ape->session_key, &rc);
  87. if ((specifier_info->session_key != NULL) && (rc == GCC_NO_ERROR))
  88. {
  89. /*
  90. * Save the startup channel type and "invoke" flag.
  91. */
  92. specifier_info->startup_channel_type =ape->startup_channel_type;
  93. specifier_info->must_be_invoked = ape->must_be_invoked;
  94. /*
  95. * Save the capabilities list for this APE in the internal info.
  96. * structure.
  97. */
  98. rc = SaveAPICapabilities(specifier_info,
  99. ape->number_of_expected_capabilities,
  100. ape->expected_capabilities_list);
  101. /*
  102. * Insert the new invoke specifier info structure pointer into
  103. * the internal list if no error condition exists.
  104. */
  105. if (rc == GCC_NO_ERROR)
  106. {
  107. m_InvokeSpecifierList.Append(specifier_info);
  108. }
  109. else
  110. {
  111. ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error saving caps"));
  112. break;
  113. }
  114. }
  115. else if (specifier_info->session_key == NULL)
  116. {
  117. ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating CSessKeyContainer"));
  118. rc = GCC_ALLOCATION_FAILURE;
  119. break;
  120. }
  121. else
  122. {
  123. ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating CSessKeyContainer"));
  124. specifier_info->session_key->Release();
  125. delete specifier_info;
  126. break;
  127. }
  128. }
  129. else
  130. {
  131. ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating INVOKE_SPECIFIER"));
  132. break;
  133. }
  134. }
  135. *pRetCode = rc;
  136. }
  137. /*
  138. * CInvokeSpecifierListContainer ()
  139. *
  140. * Public Function Description:
  141. * This constructor is used to create an CInvokeSpecifierListContainer
  142. * object from a "PDU" ApplicationProtocolEntityList.
  143. */
  144. CInvokeSpecifierListContainer::CInvokeSpecifierListContainer (
  145. PApplicationProtocolEntityList protocol_entity_list,
  146. PGCCError pRetCode)
  147. :
  148. CRefCount(MAKE_STAMP_ID('I','S','L','C')),
  149. m_fValidAPEListPDU(FALSE),
  150. m_cbDataSize(0)
  151. {
  152. ApplicationInvokeSpecifier specifier;
  153. INVOKE_SPECIFIER *specifier_info;
  154. GCCError rc = GCC_NO_ERROR;
  155. while (protocol_entity_list != NULL)
  156. {
  157. /*
  158. * Create a new INVOKE_SPECIFIER structure to hold the data for this
  159. * APE. Check to make sure it was successfully created.
  160. */
  161. DBG_SAVE_FILE_LINE
  162. specifier_info = new INVOKE_SPECIFIER;
  163. if (specifier_info != NULL)
  164. {
  165. specifier = protocol_entity_list->value;
  166. /*
  167. * Create a CSessKeyContainer object to hold the session key
  168. * internally. Check to make sure the object is successfully
  169. * created.
  170. */
  171. DBG_SAVE_FILE_LINE
  172. specifier_info->session_key = new CSessKeyContainer(&specifier.session_key, &rc);
  173. if ((specifier_info->session_key != NULL) && (rc == GCC_NO_ERROR))
  174. {
  175. /*
  176. * The session key was saved correctly so check to see if a list
  177. * of expected capabilities is present and save them if so.
  178. */
  179. if (specifier.bit_mask & EXPECTED_CAPABILITY_SET_PRESENT)
  180. {
  181. rc = SavePDUCapabilities(specifier_info, specifier.expected_capability_set);
  182. if (rc != GCC_NO_ERROR)
  183. {
  184. specifier_info->session_key->Release();
  185. delete specifier_info;
  186. break;
  187. }
  188. }
  189. /*
  190. * Save the startup channel type. If the channel type is not
  191. * present in the PDU then set the channel type in the info
  192. * strucuture equal to MCS_NO_CHANNEL_TYPE_SPECIFIED;
  193. */
  194. if (specifier.bit_mask & INVOKE_STARTUP_CHANNEL_PRESENT)
  195. {
  196. switch (specifier.invoke_startup_channel)
  197. {
  198. case CHANNEL_TYPE_STATIC:
  199. specifier_info->startup_channel_type = MCS_STATIC_CHANNEL;
  200. break;
  201. case DYNAMIC_MULTICAST:
  202. specifier_info->startup_channel_type = MCS_DYNAMIC_MULTICAST_CHANNEL;
  203. break;
  204. case DYNAMIC_PRIVATE:
  205. specifier_info->startup_channel_type = MCS_DYNAMIC_PRIVATE_CHANNEL;
  206. break;
  207. case DYNAMIC_USER_ID:
  208. specifier_info->startup_channel_type = MCS_DYNAMIC_USER_ID_CHANNEL;
  209. break;
  210. }
  211. }
  212. else
  213. {
  214. specifier_info->startup_channel_type = MCS_NO_CHANNEL_TYPE_SPECIFIED;
  215. }
  216. /*
  217. * Insert the new invoke specifier info structure pointer into
  218. * the internal list if no error condition exists.
  219. */
  220. m_InvokeSpecifierList.Append(specifier_info);
  221. }
  222. else if (specifier_info->session_key == NULL)
  223. {
  224. ERROR_OUT(("CInvokeSpecifierListContainer::Construc2: Error creating CSessKeyContainer"));
  225. rc = GCC_ALLOCATION_FAILURE;
  226. break;
  227. }
  228. else
  229. {
  230. ERROR_OUT(("CInvokeSpecifierListContainer::Construc2: Error creating CSessKeyContainer"));
  231. specifier_info->session_key->Release();
  232. delete specifier_info;
  233. break;
  234. }
  235. /*
  236. * Retrieve the next APE in the list.
  237. */
  238. protocol_entity_list = protocol_entity_list->next;
  239. }
  240. else
  241. {
  242. ERROR_OUT(("CInvokeSpecifierListContainer::Construc2: Error creating INVOKE_SPECIFIER"));
  243. break;
  244. }
  245. }
  246. *pRetCode = rc;
  247. }
  248. /*
  249. * ~CInvokeSpecifierListContainer ()
  250. *
  251. * Public Function Description
  252. * The CInvokeSpecifierListContainer destructor is responsible for
  253. * freeing any memory allocated to hold the invoke data.
  254. *
  255. */
  256. CInvokeSpecifierListContainer::~CInvokeSpecifierListContainer(void)
  257. {
  258. INVOKE_SPECIFIER *lpInvSpecInfo;
  259. /*
  260. * If "PDU" data has been allocated for this object, free it now.
  261. */
  262. if (m_fValidAPEListPDU)
  263. FreeApplicationInvokeSpecifierListPDU ();
  264. /*
  265. * Delete any data containers held internally in the list of info.
  266. * structures by iterating through the internal list.
  267. */
  268. m_InvokeSpecifierList.Reset();
  269. while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
  270. {
  271. /*
  272. * Delete any CSessKeyContainer objects in the INVOKE_SPECIFIER list.
  273. */
  274. if (NULL != lpInvSpecInfo->session_key)
  275. {
  276. lpInvSpecInfo->session_key->Release();
  277. }
  278. /*
  279. * Iterate through the capabilities list held in the INVOKE_SPECIFIER
  280. * structure.
  281. */
  282. lpInvSpecInfo->ExpectedCapItemList.DeleteList();
  283. /*
  284. * Delete the INVOKE_SPECIFIER structure.
  285. */
  286. delete lpInvSpecInfo;
  287. }
  288. }
  289. /*
  290. * LockApplicationInvokeSpecifierList ()
  291. *
  292. * Public Function Description:
  293. * This routine locks the invoke specifier data and determines the amount
  294. * of memory necessary to hold the associated data.
  295. */
  296. UINT CInvokeSpecifierListContainer::LockApplicationInvokeSpecifierList(void)
  297. {
  298. /*
  299. * If this is the first time this routine is called, determine the size of
  300. * the memory required to hold the data for the application invoke
  301. * specifier. Otherwise, just increment the lock count.
  302. */
  303. if (Lock() == 1)
  304. {
  305. INVOKE_SPECIFIER *lpInvSpecInfo;
  306. APP_CAP_ITEM *pExpCapData;
  307. /*
  308. * Set aside memory to hold the pointers to the GCCAppProtocolEntity
  309. * structures as well as the structures themselves. The "sizeof" the
  310. * structure must be rounded to an even four-byte boundary.
  311. */
  312. m_cbDataSize = m_InvokeSpecifierList.GetCount() *
  313. (sizeof(PGCCAppProtocolEntity) + ROUNDTOBOUNDARY(sizeof(GCCAppProtocolEntity)));
  314. m_InvokeSpecifierList.Reset();
  315. while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
  316. {
  317. /*
  318. * Lock the data for the session keys, adding the amount of memory
  319. * necessary to hold the session key data to the total memory size.
  320. */
  321. m_cbDataSize += lpInvSpecInfo->session_key->LockSessionKeyData();
  322. lpInvSpecInfo->ExpectedCapItemList.Reset();
  323. /*
  324. * Set aside memory to hold the pointers to the
  325. * GCCApplicationCabability structures as well as the structures
  326. * themselves. The "sizeof" the structure must be rounded to an
  327. * even four-byte boundary.
  328. */
  329. m_cbDataSize += lpInvSpecInfo->ExpectedCapItemList.GetCount() *
  330. ( sizeof(PGCCApplicationCapability) + ROUNDTOBOUNDARY (sizeof(GCCApplicationCapability)) );
  331. /*
  332. * Lock the data for the capability ID's, adding the amount of
  333. * memory necessary to hold the capability ID data to the total
  334. * memory size.
  335. */
  336. while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
  337. {
  338. m_cbDataSize += pExpCapData->pCapID->LockCapabilityIdentifierData();
  339. }
  340. }
  341. }
  342. return m_cbDataSize;
  343. }
  344. /*
  345. * GetApplicationInvokeSpecifierList ()
  346. *
  347. * Public Function Description:
  348. * This routine retrieves the invoke specifier data in the form of a
  349. * list of application protocol entities which are written into the memory
  350. * provided. This routine is called after "locking" the data.
  351. */
  352. UINT CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierList(
  353. USHORT *number_of_protocol_entities,
  354. LPBYTE memory)
  355. {
  356. PGCCAppProtocolEntity * ape_list_ptr;
  357. PGCCAppProtocolEntity ape_ptr;
  358. PGCCApplicationCapability capability_ptr;
  359. UINT data_length = 0;
  360. Int ape_counter = 0;
  361. Int capability_counter = 0;
  362. UINT cbDataSizeToRet = 0;
  363. INVOKE_SPECIFIER *lpInvSpecInfo;
  364. APP_CAP_ITEM *pExpCapData;
  365. /*
  366. * If the object has been locked, fill in the output structure and
  367. * the data referenced by the structure. Otherwise, report that the object
  368. * key has yet to be locked into the "API" form.
  369. */
  370. if (GetLockCount() > 0)
  371. {
  372. /*
  373. * Fill in the output length parameter which indicates how much data
  374. * referenced outside the structure will be written. This value was
  375. * calculated on the call to "Lock".
  376. */
  377. cbDataSizeToRet = m_cbDataSize;
  378. /*
  379. * Fill in the number of protocol entities and save a pointer to
  380. * the memory location passed in. This is where the pointers to
  381. * the GCCAppProtocolEntity structures will be written. The actual
  382. * structures will be written into memory immediately following the list
  383. * of pointers.
  384. */
  385. *number_of_protocol_entities = (USHORT) m_InvokeSpecifierList.GetCount();
  386. ape_list_ptr = (PGCCAppProtocolEntity *)memory;
  387. /*
  388. * Save the amount of memory needed to hold the list of structure
  389. * pointers.
  390. */
  391. data_length = m_InvokeSpecifierList.GetCount() * sizeof(PGCCAppProtocolEntity);
  392. /*
  393. * Move the memory pointer past the list of APE pointers. This is where
  394. * thefirst APE structure will be written.
  395. */
  396. memory += data_length;
  397. /*
  398. * Iterate through the internal list of INVOKE_SPECIFIER structures,
  399. * building "API" GCCAppProtocolEntity structures in memory.
  400. */
  401. m_InvokeSpecifierList.Reset();
  402. while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
  403. {
  404. /*
  405. * Save the pointer to the APE structure in the list of pointers.
  406. */
  407. ape_ptr = (PGCCAppProtocolEntity)memory;
  408. ape_list_ptr[ape_counter++] = ape_ptr;
  409. /*
  410. * Move the memory pointer past the APE structure. This is where
  411. * thesession key data will be written.
  412. */
  413. memory += ROUNDTOBOUNDARY(sizeof(GCCAppProtocolEntity));
  414. /*
  415. * Fill in the APE structure starting with the session key.
  416. */
  417. data_length = lpInvSpecInfo->session_key->GetGCCSessionKeyData(&ape_ptr->session_key, memory);
  418. /*
  419. * Move the memory pointer past the session key data. This is
  420. * where the list of pointers to the GCCApplicationCapability
  421. * structures will be written so save the pointer in the APE
  422. * structure's capabilities list pointer.
  423. */
  424. memory += data_length;
  425. ape_ptr->expected_capabilities_list = (PGCCApplicationCapability *)memory;
  426. /*
  427. * Go ahead and fill in the APE's channel type and invoke flag.
  428. */
  429. ape_ptr->must_be_invoked = lpInvSpecInfo->must_be_invoked;
  430. ape_ptr->startup_channel_type = lpInvSpecInfo->startup_channel_type;
  431. ape_ptr->number_of_expected_capabilities = (USHORT) lpInvSpecInfo->ExpectedCapItemList.GetCount();
  432. /*
  433. * Move the memory pointer past the list of GCCApplicationCapability
  434. * pointers. This is where the first GCCApplicationCapability
  435. * structure will be written.
  436. */
  437. memory += (lpInvSpecInfo->ExpectedCapItemList.GetCount() *
  438. sizeof(PGCCApplicationCapability));
  439. /*
  440. * Iterate through the list of capabilities, writing the
  441. * GCCApplicationCapability structures into memory.
  442. */
  443. capability_counter = 0;
  444. lpInvSpecInfo->ExpectedCapItemList.Reset();
  445. while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
  446. {
  447. /*
  448. * Save the pointer to the capability structure in the list of
  449. * pointers. Move the memory pointer past the capability
  450. * structure. This is where the data associated with the
  451. * capability ID will be written.
  452. */
  453. capability_ptr = (PGCCApplicationCapability)memory;
  454. ape_ptr->expected_capabilities_list[capability_counter++] = capability_ptr;
  455. memory += ROUNDTOBOUNDARY(sizeof(GCCApplicationCapability));
  456. /*
  457. * Fill in the capability structure and add the amount of data
  458. * written into memory to the total data length.
  459. */
  460. data_length = GetApplicationCapability(pExpCapData, capability_ptr, memory);
  461. /*
  462. * Move the memory pointer past the capability data.
  463. */
  464. memory += data_length;
  465. }
  466. }
  467. }
  468. else
  469. {
  470. number_of_protocol_entities = 0;
  471. ERROR_OUT(("CInvokeSpecifierListContainer::GetAppInvokeSpecList: Error Data Not Locked"));
  472. }
  473. return cbDataSizeToRet;
  474. }
  475. /*
  476. * UnLockApplicationInvokeSpecifierList ()
  477. *
  478. * Public Function Description:
  479. * This routine decrements the lock count and frees the memory associated
  480. * with the "API" invoke specifier list once the lock count reaches zero.
  481. */
  482. void CInvokeSpecifierListContainer::UnLockApplicationInvokeSpecifierList(void)
  483. {
  484. if (Unlock(FALSE) == 0)
  485. {
  486. INVOKE_SPECIFIER *lpInvSpecInfo;
  487. APP_CAP_ITEM *pExpCapData;
  488. /*
  489. * Unlock any container data held internally in the list of info.
  490. * structures by iterating through the internal list.
  491. */
  492. m_InvokeSpecifierList.Reset();
  493. while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
  494. {
  495. /*
  496. * Unlock any CSessKeyContainer objects.
  497. */
  498. lpInvSpecInfo->session_key->UnLockSessionKeyData();
  499. /*
  500. * Iterate through the capabilities list held in the
  501. * INVOKE_SPECIFIER structure.
  502. */
  503. lpInvSpecInfo->ExpectedCapItemList.Reset();
  504. while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
  505. {
  506. /*
  507. * Unlock the CCapIDContainer objects.
  508. */
  509. pExpCapData->pCapID->UnLockCapabilityIdentifierData();
  510. }
  511. }
  512. }
  513. // we have to call Release() because we used Unlock(FALSE)
  514. Release();
  515. }
  516. /*
  517. * GetApplicationInvokeSpecifierListPDU ()
  518. *
  519. * Public Function Description:
  520. * This routine retrieves the "PDU" form of an
  521. * ApplicationProtocolEntityList.
  522. */
  523. GCCError CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierListPDU(
  524. PApplicationProtocolEntityList *protocol_entity_list)
  525. {
  526. GCCError rc = GCC_NO_ERROR;
  527. PApplicationProtocolEntityList new_pdu_ape_list_ptr;
  528. PApplicationProtocolEntityList old_pdu_ape_list_ptr = NULL;
  529. /*
  530. * If this is the first time that PDU data has been requested then we must
  531. * fill in the internal PDU structure and copy it into the structure pointed
  532. * to by the input parameter. On subsequent calls to "GetPDU" we can just
  533. * copy the internal PDU structure into the structure pointed to by the
  534. * input parameter.
  535. */
  536. if (m_fValidAPEListPDU == FALSE)
  537. {
  538. INVOKE_SPECIFIER *lpInvSpecInfo;
  539. m_fValidAPEListPDU = TRUE;
  540. /*
  541. * Initialize the output parameter to NULL so that the first time
  542. * through the loop it will be set equal to the first new APE list
  543. * created in the iterator loop.
  544. */
  545. m_pAPEListPDU = NULL;
  546. /*
  547. * Iterate through the list of "INVOKE_SPECIFIER" structures,
  548. * converting each into "PDU" form and saving the pointers in the
  549. * "ApplicationProtocolEntityList" which is a linked list of
  550. * "ApplicationInvokeSpecifiers".
  551. */
  552. m_InvokeSpecifierList.Reset();
  553. while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
  554. {
  555. DBG_SAVE_FILE_LINE
  556. new_pdu_ape_list_ptr = new ApplicationProtocolEntityList;
  557. /*
  558. * If an allocation failure occurs, call the routine which will
  559. * iterate through the list freeing any data which had been
  560. * allocated.
  561. */
  562. if (new_pdu_ape_list_ptr == NULL)
  563. {
  564. ERROR_OUT(("CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierListPDU: can't allocate ApplicationProtocolEntityList"));
  565. rc = GCC_ALLOCATION_FAILURE;
  566. FreeApplicationInvokeSpecifierListPDU ();
  567. break;
  568. }
  569. /*
  570. * The first time through, set the PDU structure pointer equal
  571. * to the first ApplicationProtocolEntityList created. On
  572. * subsequent loops, set the structure's "next" pointer equal to
  573. * the new structure.
  574. */
  575. if (m_pAPEListPDU == NULL)
  576. {
  577. m_pAPEListPDU = new_pdu_ape_list_ptr;
  578. }
  579. else
  580. {
  581. old_pdu_ape_list_ptr->next = new_pdu_ape_list_ptr;
  582. }
  583. old_pdu_ape_list_ptr = new_pdu_ape_list_ptr;
  584. /*
  585. * Initialize the new "next" pointer to NULL.
  586. */
  587. new_pdu_ape_list_ptr->next = NULL;
  588. if (ConvertInvokeSpecifierInfoToPDU (lpInvSpecInfo, new_pdu_ape_list_ptr) !=
  589. GCC_NO_ERROR)
  590. {
  591. ERROR_OUT(("CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierListPDU: can't convert UserDataInfo to PDU"));
  592. rc = GCC_ALLOCATION_FAILURE;
  593. break;
  594. }
  595. }
  596. }
  597. /*
  598. * Copy the internal PDU structure into the structure pointed to by the
  599. * input parameter.
  600. */
  601. *protocol_entity_list = m_pAPEListPDU;
  602. return rc;
  603. }
  604. /*
  605. * FreeApplicationInvokeSpecifierListPDU ()
  606. *
  607. * Public Function Description:
  608. * This routine is used to free the invoke specifier data held internally
  609. * in the "PDU" form of a "ApplicationProtocolEntityList".
  610. */
  611. void CInvokeSpecifierListContainer::FreeApplicationInvokeSpecifierListPDU(void)
  612. {
  613. PApplicationProtocolEntityList pCurr, pNext;
  614. INVOKE_SPECIFIER *lpInvSpecInfo;
  615. APP_CAP_ITEM *pExpCapData;
  616. if (m_pAPEListPDU != NULL)
  617. {
  618. m_fValidAPEListPDU = FALSE;
  619. /*
  620. * Loop through the list, freeing the data associated with
  621. * each structure contained in the list.
  622. */
  623. for (pCurr = m_pAPEListPDU; NULL != pCurr; pCurr = pNext)
  624. {
  625. pNext = pCurr->next;
  626. delete pCurr;
  627. }
  628. }
  629. /*
  630. * Iterate through the internal list, telling each data container object
  631. * to free any PDU data which it has allocated.
  632. */
  633. m_InvokeSpecifierList.Reset();
  634. while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
  635. {
  636. if (lpInvSpecInfo->session_key != NULL)
  637. {
  638. lpInvSpecInfo->session_key->FreeSessionKeyDataPDU();
  639. }
  640. /*
  641. * Iterate through the
  642. * list, freeing the PDU data for the capability ID's.
  643. */
  644. lpInvSpecInfo->ExpectedCapItemList.Reset();
  645. while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
  646. {
  647. pExpCapData->pCapID->FreeCapabilityIdentifierDataPDU();
  648. }
  649. }
  650. }
  651. /*
  652. * GCCError CInvokeSpecifierListContainer::SaveAPICapabilities (
  653. * INVOKE_SPECIFIER *invoke_specifier,
  654. * UINT number_of_capabilities,
  655. * PGCCApplicationCapability * capabilities_list)
  656. *
  657. * Private member function of CInvokeSpecifierListContainer.
  658. *
  659. * Function Description:
  660. * This routine is used to save the list of application capabilities passed
  661. * in as "API" data in the internal list of expected capability data
  662. * which is held in the internal info structure.
  663. *
  664. * Formal Parameters:
  665. * invoke_specifier (i) Internal structure used to hold invoke data.
  666. * number_of_capabilities (i) Number of capabilities in list.
  667. * capabilities_list (i) List of API capabilities to save.
  668. *
  669. * Return Value:
  670. * None.
  671. *
  672. * Side Effects:
  673. * None.
  674. *
  675. * Caveats:
  676. * None.
  677. */
  678. GCCError CInvokeSpecifierListContainer::SaveAPICapabilities(
  679. INVOKE_SPECIFIER *invoke_specifier,
  680. UINT number_of_capabilities,
  681. PGCCApplicationCapability * capabilities_list)
  682. {
  683. GCCError rc = GCC_NO_ERROR;
  684. APP_CAP_ITEM *pExpCapData;
  685. UINT i;
  686. for (i = 0; i < number_of_capabilities; i++)
  687. {
  688. /*
  689. * For each capability, create an APP_CAP_ITEM structure
  690. * to hold all the necessary data. This structure will be inserted into
  691. * the list held by the internal info. structure.
  692. */
  693. DBG_SAVE_FILE_LINE
  694. pExpCapData = new APP_CAP_ITEM((GCCCapabilityType) capabilities_list[i]->capability_class.eType);
  695. if (pExpCapData != NULL)
  696. {
  697. /*
  698. * Create a new CCapIDContainer object to hold the
  699. * identifier data.
  700. */
  701. DBG_SAVE_FILE_LINE
  702. pExpCapData->pCapID = new CCapIDContainer(&capabilities_list[i]->capability_id, &rc);
  703. if ((pExpCapData->pCapID != NULL) && (rc == GCC_NO_ERROR))
  704. {
  705. /*
  706. * The identifier object was successfully created so fill in the
  707. * rest of the ApplicationCapabilityData structure.
  708. */
  709. switch (pExpCapData->eCapType)
  710. {
  711. case GCC_UNSIGNED_MINIMUM_CAPABILITY:
  712. pExpCapData->nUnsignedMinimum = capabilities_list[i]->capability_class.nMinOrMax;
  713. break;
  714. case GCC_UNSIGNED_MAXIMUM_CAPABILITY:
  715. pExpCapData->nUnsignedMaximum = capabilities_list[i]->capability_class.nMinOrMax;
  716. break;
  717. }
  718. /*
  719. * Add this expected capability to the list.
  720. */
  721. invoke_specifier->ExpectedCapItemList.Append(pExpCapData);
  722. }
  723. else
  724. {
  725. delete pExpCapData;
  726. rc = GCC_ALLOCATION_FAILURE;
  727. break;
  728. }
  729. }
  730. else
  731. {
  732. rc = GCC_ALLOCATION_FAILURE;
  733. break;
  734. }
  735. }
  736. return rc;
  737. }
  738. /*
  739. * GCCError CInvokeSpecifierListContainer::SavePDUCapabilities (
  740. * INVOKE_SPECIFIER *invoke_specifier,
  741. * PSetOfExpectedCapabilities capabilities_set)
  742. *
  743. * Private member function of CInvokeSpecifierListContainer.
  744. *
  745. * Function Description:
  746. * This routine is used to save the list of application capabilities passed
  747. * in as "PDU" data in the internal list of expected capability data
  748. * which is held in the internal info. structure.
  749. *
  750. * Formal Parameters:
  751. * invoke_specifier (i) Internal structure used to hold invoke data.
  752. * capabilities_set (i) List of PDU capabilities to save.
  753. *
  754. * Return Value:
  755. * None.
  756. *
  757. * Side Effects:
  758. * None.
  759. *
  760. * Caveats:
  761. * None.
  762. */
  763. GCCError CInvokeSpecifierListContainer::SavePDUCapabilities(
  764. INVOKE_SPECIFIER *invoke_specifier,
  765. PSetOfExpectedCapabilities capabilities_set)
  766. {
  767. GCCError rc = GCC_NO_ERROR;
  768. APP_CAP_ITEM *pExpCapData;
  769. while ((capabilities_set != NULL) && (rc == GCC_NO_ERROR))
  770. {
  771. /*
  772. * Create and fill in the new expected capability.
  773. */
  774. DBG_SAVE_FILE_LINE
  775. pExpCapData = new APP_CAP_ITEM((GCCCapabilityType) capabilities_set->value.capability_class.choice);
  776. if (pExpCapData != NULL)
  777. {
  778. /*
  779. * Create the CCapIDContainer object used to hold the
  780. * capability ID data internally. Make sure creation is successful.
  781. */
  782. DBG_SAVE_FILE_LINE
  783. pExpCapData->pCapID = new CCapIDContainer(&capabilities_set->value.capability_id, &rc);
  784. if (pExpCapData->pCapID == NULL || rc != GCC_NO_ERROR)
  785. {
  786. rc = GCC_ALLOCATION_FAILURE;
  787. delete pExpCapData;
  788. }
  789. }
  790. else
  791. {
  792. rc = GCC_ALLOCATION_FAILURE;
  793. }
  794. /*
  795. * The capability ID was saved successfully, so go ahead and insert
  796. * the expected capability data structure into the internal list.
  797. * Fill in the capability class data.
  798. */
  799. if (rc == GCC_NO_ERROR)
  800. {
  801. invoke_specifier->ExpectedCapItemList.Append(pExpCapData);
  802. /*
  803. * Save the capability type and value.
  804. */
  805. switch (capabilities_set->value.capability_class.choice)
  806. {
  807. case UNSIGNED_MINIMUM_CHOSEN:
  808. pExpCapData->nUnsignedMinimum = capabilities_set->value.capability_class.u.unsigned_minimum;
  809. break;
  810. case UNSIGNED_MAXIMUM_CHOSEN:
  811. pExpCapData->nUnsignedMaximum = capabilities_set->value.capability_class.u.unsigned_maximum;
  812. break;
  813. }
  814. }
  815. capabilities_set = capabilities_set->next;
  816. }
  817. return rc;
  818. }
  819. /*
  820. * UINT CInvokeSpecifierListContainer::GetApplicationCapability (
  821. * APP_CAP_ITEM *capability_info_data,
  822. * PGCCApplicationCapability api_capability,
  823. * LPSTR memory)
  824. *
  825. * Private member function of CInvokeSpecifierListContainer.
  826. *
  827. * Function Description:
  828. * This routine is used to fill in an API GCCApplicationCapability
  829. * structure from an internal info structure.
  830. *
  831. * Formal Parameters:
  832. * capability_info_data (i) Internal capability data to convert into
  833. * API data.
  834. * api_capability (o) Structure to hold data in API form.
  835. * memory (o) Memory used to hold bulk data referenced by
  836. * the API structure.
  837. *
  838. * Return Value:
  839. * None.
  840. *
  841. * Side Effects:
  842. * None.
  843. *
  844. * Caveats:
  845. * None.
  846. */
  847. UINT CInvokeSpecifierListContainer::GetApplicationCapability(
  848. APP_CAP_ITEM *pExpCapData,
  849. PGCCApplicationCapability api_capability,
  850. LPBYTE memory)
  851. {
  852. UINT data_length = 0;
  853. /*
  854. * Call the CapabilityID object to retrieve the capability ID data.
  855. */
  856. data_length = pExpCapData->pCapID->GetGCCCapabilityIDData(
  857. &api_capability->capability_id,
  858. memory);
  859. /*
  860. * Fill in the remaining fields for the GCCApplicationCapability structure.
  861. */
  862. api_capability->capability_class.eType = pExpCapData->eCapType;
  863. switch (pExpCapData->eCapType)
  864. {
  865. case GCC_UNSIGNED_MINIMUM_CAPABILITY:
  866. api_capability->capability_class.nMinOrMax = pExpCapData->nUnsignedMinimum;
  867. break;
  868. case GCC_UNSIGNED_MAXIMUM_CAPABILITY:
  869. api_capability->capability_class.nMinOrMax = pExpCapData->nUnsignedMaximum;
  870. break;
  871. }
  872. /*
  873. * Fill in the number of entities. Note, however, that this field will not
  874. * be used in this context.
  875. */
  876. api_capability->number_of_entities = 0;
  877. return (data_length);
  878. }
  879. /*
  880. * GCCError CInvokeSpecifierListContainer::ConvertInvokeSpecifierInfoToPDU(
  881. * INVOKE_SPECIFIER *specifier_info_ptr,
  882. * PApplicationProtocolEntityList ape_list_ptr)
  883. *
  884. * Private member function of CInvokeSpecifierListContainer.
  885. *
  886. * Function Description:
  887. * This routine converts the invoke specifier from the internal form which
  888. * is an "INVOKE_SPECIFIER" structure into the "PDU" structure form of
  889. * a "ApplicationInvokeSpecifier".
  890. *
  891. * Formal Parameters:
  892. * specifier_info_ptr (i) Internal structure holding data to convert.
  893. * ape_list_ptr (o) PDU structure to hold converted data.
  894. *
  895. * Return Value:
  896. * None.
  897. *
  898. * Side Effects:
  899. * None.
  900. *
  901. * Caveats:
  902. * None.
  903. */
  904. GCCError CInvokeSpecifierListContainer::ConvertInvokeSpecifierInfoToPDU (
  905. INVOKE_SPECIFIER *specifier_info_ptr,
  906. PApplicationProtocolEntityList ape_list_ptr)
  907. {
  908. GCCError rc = GCC_NO_ERROR;
  909. PSetOfExpectedCapabilities new_capability_set_ptr;
  910. PSetOfExpectedCapabilities old_capability_set_ptr = NULL;
  911. /*
  912. * Initialize the invoke specifier bit mask to zero.
  913. */
  914. ape_list_ptr->value.bit_mask = 0;
  915. /*
  916. * Fill in the session key PDU data using the CSessKeyContainer object.
  917. */
  918. rc = specifier_info_ptr->session_key->GetSessionKeyDataPDU(&ape_list_ptr->value.session_key);
  919. /*
  920. * Fill in the capabilities list if any exist.
  921. */
  922. if ((rc == GCC_NO_ERROR) && (specifier_info_ptr->ExpectedCapItemList.GetCount() != 0))
  923. {
  924. APP_CAP_ITEM *pExpCapData;
  925. ape_list_ptr->value.bit_mask |= EXPECTED_CAPABILITY_SET_PRESENT;
  926. /*
  927. * Set the pointer to the capability set to NULL so that it will be
  928. * set equal to the first SetOfExpectedCapabilities created inside the
  929. * iterator loop.
  930. */
  931. ape_list_ptr->value.expected_capability_set = NULL;
  932. /*
  933. * Iterate through the list of APP_CAP_ITEM structures,
  934. * converting each into "PDU" form and saving the pointers in the
  935. * "SetOfExpectedCapabilities.
  936. */
  937. specifier_info_ptr->ExpectedCapItemList.Reset();
  938. while (NULL != (pExpCapData = specifier_info_ptr->ExpectedCapItemList.Iterate()))
  939. {
  940. DBG_SAVE_FILE_LINE
  941. new_capability_set_ptr = new SetOfExpectedCapabilities;
  942. /*
  943. * If an allocation failure occurs, call the routine which will
  944. * iterate through the list freeing any data which had been
  945. * allocated.
  946. */
  947. if (new_capability_set_ptr == NULL)
  948. {
  949. ERROR_OUT(("CInvokeSpecifierListContainer::ConvertToPDU: alloc error, cleaning up"));
  950. rc = GCC_ALLOCATION_FAILURE;
  951. FreeApplicationInvokeSpecifierListPDU();
  952. break;
  953. }
  954. /*
  955. * The first time through, set the PDU structure pointer equal
  956. * to the first SetOfExpectedCapabilities created. On
  957. * subsequent loops, set the structure's "next" pointer equal to
  958. * the new structure.
  959. */
  960. if (ape_list_ptr->value.expected_capability_set == NULL)
  961. {
  962. ape_list_ptr->value.expected_capability_set = new_capability_set_ptr;
  963. }
  964. else
  965. {
  966. old_capability_set_ptr->next = new_capability_set_ptr;
  967. }
  968. old_capability_set_ptr = new_capability_set_ptr;
  969. /*
  970. * Initialize the new "next" pointer to NULL.
  971. */
  972. new_capability_set_ptr->next = NULL;
  973. if (ConvertExpectedCapabilityDataToPDU(pExpCapData, new_capability_set_ptr) != GCC_NO_ERROR)
  974. {
  975. ERROR_OUT(("CInvokeSpecifierListContainer::ConvertToPDU: Error converting Capability to PDU"));
  976. rc = GCC_ALLOCATION_FAILURE;
  977. break;
  978. }
  979. }
  980. }
  981. /*
  982. * Fill in the channel type if one is specified.
  983. */
  984. if (specifier_info_ptr->startup_channel_type != MCS_NO_CHANNEL_TYPE_SPECIFIED)
  985. {
  986. ape_list_ptr->value.bit_mask |= INVOKE_STARTUP_CHANNEL_PRESENT;
  987. switch (specifier_info_ptr->startup_channel_type)
  988. {
  989. case MCS_STATIC_CHANNEL:
  990. ape_list_ptr->value.invoke_startup_channel = CHANNEL_TYPE_STATIC;
  991. break;
  992. case MCS_DYNAMIC_MULTICAST_CHANNEL:
  993. ape_list_ptr->value.invoke_startup_channel = DYNAMIC_MULTICAST;
  994. break;
  995. case MCS_DYNAMIC_PRIVATE_CHANNEL:
  996. ape_list_ptr->value.invoke_startup_channel = DYNAMIC_PRIVATE;
  997. break;
  998. case MCS_DYNAMIC_USER_ID_CHANNEL:
  999. ape_list_ptr->value.invoke_startup_channel = DYNAMIC_USER_ID;
  1000. break;
  1001. }
  1002. }
  1003. /*
  1004. * Fill in the invoke flag.
  1005. */
  1006. ape_list_ptr->value.invoke_is_mandatory = (ASN1bool_t)specifier_info_ptr->must_be_invoked;
  1007. return rc;
  1008. }
  1009. /*
  1010. * GCCError CInvokeSpecifierListContainer::ConvertExpectedCapabilityDataToPDU(
  1011. * APP_CAP_ITEM *info_ptr,
  1012. * PSetOfExpectedCapabilities pdu_ptr)
  1013. *
  1014. * Private member function of CInvokeSpecifierListContainer.
  1015. *
  1016. * Function Description:
  1017. * This routine converts the capability ID from the internal form which
  1018. * is an APP_CAP_ITEM structure into the "PDU" structure form
  1019. * of a "SetOfExpectedCapabilities".
  1020. *
  1021. * Formal Parameters:
  1022. * info_ptr (i) Internal structure holding data to convert.
  1023. * pdu_ptr (o) PDU structure to hold converted data.
  1024. *
  1025. * Return Value:
  1026. * None.
  1027. *
  1028. * Side Effects:
  1029. * None.
  1030. *
  1031. * Caveats:
  1032. * None.
  1033. */
  1034. GCCError CInvokeSpecifierListContainer::ConvertExpectedCapabilityDataToPDU (
  1035. APP_CAP_ITEM *pExpCapData,
  1036. PSetOfExpectedCapabilities pdu_ptr)
  1037. {
  1038. GCCError rc = GCC_NO_ERROR;
  1039. /*
  1040. * Retrieve the capability ID data from the internal
  1041. * CCapIDContainer object.
  1042. */
  1043. rc = pExpCapData->pCapID->GetCapabilityIdentifierDataPDU(&pdu_ptr->value.capability_id);
  1044. /*
  1045. * Fill in the capability class.
  1046. */
  1047. if (rc == GCC_NO_ERROR)
  1048. {
  1049. switch (pExpCapData->eCapType)
  1050. {
  1051. case GCC_LOGICAL_CAPABILITY:
  1052. pdu_ptr->value.capability_class.choice = LOGICAL_CHOSEN;
  1053. break;
  1054. case GCC_UNSIGNED_MINIMUM_CAPABILITY:
  1055. pdu_ptr->value.capability_class.choice = UNSIGNED_MINIMUM_CHOSEN;
  1056. pdu_ptr->value.capability_class.u.unsigned_minimum = pExpCapData->nUnsignedMinimum;
  1057. break;
  1058. case GCC_UNSIGNED_MAXIMUM_CAPABILITY:
  1059. pdu_ptr->value.capability_class.choice = UNSIGNED_MAXIMUM_CHOSEN;
  1060. pdu_ptr->value.capability_class.u.unsigned_maximum = pExpCapData->nUnsignedMaximum;
  1061. break;
  1062. }
  1063. }
  1064. return rc;
  1065. }
  1066.