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.

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