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.

2686 lines
72 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_GCCNC);
  3. /*
  4. * registry.cpp
  5. *
  6. * Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
  7. *
  8. * Abstract:
  9. * This is the registry class implementation file. All registry operations
  10. * at both the Top Provider and subordinate nodes. It is responsible for
  11. * queing registry request, maintaining the registry, sending confirms to
  12. * the application SAP, etc. Registry objects at sub-ordinate nodes are
  13. * responsible for queuing up the registry request to be sent on to the
  14. * Top Provider. On of these classes should be created per node. This
  15. * class handles request from all existing application SAPs.
  16. *
  17. * FOR A MORE DETAILED EXPLANATION OF THIS CLASS SEE THE INTERFACE FILE
  18. *
  19. * Private Instance Variables:
  20. * m_pMCSUserObject
  21. * Pointer to the User Attachment object used to deliver all registry
  22. * request and responses to remote nodes.
  23. * m_RegEntryList
  24. * This is the list that holds all the registry entries associated
  25. * with this conference.
  26. * m_fTopProvider
  27. * This flag specifies if this is the top provider node (TRUE means
  28. * this is the top provider node).
  29. * m_nCurrentTokenID
  30. * This is a counter that is used to generate the token IDs by the
  31. * registry object at the top provider.
  32. * m_nConfID
  33. * Conference ID assocaited with this conference.
  34. * m_pEmptyRegItem
  35. * This is a pointer to an empty registry item that is used to generate
  36. * empty items for PDUs that don't contain a registry item.
  37. * m_AppSapEidList2
  38. * This list contains pointers to the command target objects associated
  39. * with each of the enrolled APEs
  40. * m_nRegHandle
  41. * This is a counter that is used to generate the handles allocated
  42. * by the registry object at the top provider.
  43. * m_pAppRosterMgrList
  44. * This list hold all the current application roster managers and
  45. * is used to verify that a requesting APE is actually enrolled with
  46. * the conference.
  47. *
  48. * Caveats:
  49. * None.
  50. *
  51. * Author:
  52. * blp
  53. */
  54. #include "registry.h"
  55. #include "appsap.h"
  56. #define FIRST_DYNAMIC_TOKEN_ID 16384
  57. #define MAXIMUM_ALLOWABLE_ALLOCATED_HANDLES (16 * 1024) // for T.126
  58. /*
  59. * CRegistry()
  60. *
  61. * Public Function Description
  62. * This is the registry constructor. It is responsible for initializing
  63. * instance variables.
  64. *
  65. */
  66. CRegistry::CRegistry(PMCSUser user_object,
  67. BOOL top_provider,
  68. GCCConfID conference_id,
  69. CAppRosterMgrList *app_roster_manager_list,
  70. PGCCError pRetCode)
  71. :
  72. CRefCount(MAKE_STAMP_ID('A','R','e','g')),
  73. m_AppSapEidList2(DESIRED_MAX_APP_SAP_ITEMS),
  74. m_pMCSUserObject(user_object),
  75. m_fTopProvider(top_provider),
  76. m_nCurrentTokenID(FIRST_DYNAMIC_TOKEN_ID),
  77. m_nConfID(conference_id),
  78. m_nRegHandle(0),
  79. m_pAppRosterMgrList(app_roster_manager_list)
  80. {
  81. GCCRegistryItem registry_item;
  82. *pRetCode = GCC_NO_ERROR;
  83. /*
  84. ** If this is the Top Provider we now build a vacant registry item to
  85. ** be used when an entry in the registry is being accessed that does not
  86. ** exists.
  87. */
  88. if (m_fTopProvider)
  89. {
  90. registry_item.item_type = GCC_REGISTRY_NONE;
  91. DBG_SAVE_FILE_LINE
  92. m_pEmptyRegItem = new CRegItem(&registry_item, pRetCode);
  93. if (m_pEmptyRegItem == NULL || GCC_NO_ERROR != *pRetCode)
  94. {
  95. *pRetCode = GCC_ALLOCATION_FAILURE;
  96. }
  97. }
  98. else
  99. {
  100. m_pEmptyRegItem = NULL;
  101. }
  102. }
  103. /*
  104. * ~CRegistry()
  105. *
  106. * Public Function Description
  107. * This is the registry destructor. It is responsible for freeing any
  108. * outstanding memory associated with the application registry.
  109. */
  110. CRegistry::~CRegistry(void)
  111. {
  112. REG_ENTRY *pRegEntry;
  113. m_RegEntryList.Reset();
  114. // Free up any registry entries
  115. while (NULL != (pRegEntry = m_RegEntryList.Iterate()))
  116. {
  117. if (NULL != pRegEntry->registry_key)
  118. {
  119. pRegEntry->registry_key->Release();
  120. }
  121. if (NULL != pRegEntry->entry_item)
  122. {
  123. pRegEntry->entry_item->Release();
  124. }
  125. delete pRegEntry;
  126. }
  127. if (NULL != m_pEmptyRegItem)
  128. {
  129. m_pEmptyRegItem->Release();
  130. }
  131. }
  132. /*
  133. * void EnrollAPE ()
  134. *
  135. * Public Function Description
  136. * This routine is used to inform the application registry of a newly
  137. * enrolling APE and its corresponding command target interface.
  138. */
  139. void CRegistry::EnrollAPE(EntityID eid, CAppSap *pAppSap)
  140. {
  141. m_AppSapEidList2.Append(eid, pAppSap);
  142. }
  143. /*
  144. * void UnEnrollApplicationSAP ()
  145. *
  146. * Public Function Description
  147. * This routine is used to inform the application registry of an
  148. * APE that is unerolling from the conference.
  149. *
  150. * Caveats
  151. * This routine removes ownership from all the entries currently owned by
  152. * the passed in application entity. It will also remove any outstanding
  153. * request for the SAP that unenrolled.
  154. */
  155. void CRegistry::UnEnrollAPE ( EntityID entity_id )
  156. {
  157. REG_ENTRY *lpRegEntry;
  158. UserID my_user_id = m_pMCSUserObject->GetMyNodeID();
  159. m_RegEntryList.Reset();
  160. while (NULL != (lpRegEntry = m_RegEntryList.Iterate()))
  161. {
  162. /*
  163. ** First we remove this APE from the list of nodes that are
  164. ** monitoring this entry.
  165. */
  166. lpRegEntry->monitoring_list.Remove(entity_id);
  167. /*
  168. ** Next, if this is the top provider, we clean up the the
  169. ** ownership properties of this entry and issue any PDUs and/or
  170. ** messages that are necessary.
  171. */
  172. if (m_fTopProvider)
  173. {
  174. if ((lpRegEntry->owner_id == my_user_id) &&
  175. (lpRegEntry->entity_id == entity_id))
  176. {
  177. /*
  178. ** Ownership is removed from any registry entries this
  179. ** entity owned.
  180. */
  181. lpRegEntry->owner_id = 0;
  182. lpRegEntry->entity_id = 0;
  183. // Send Monitor Indication if necessary
  184. if (lpRegEntry->monitoring_state == ON)
  185. {
  186. /*
  187. ** Deliver the monitor indication to the Top
  188. ** Provider's Node Controller if necessary.
  189. */
  190. SendMonitorEntryIndicationMessage (lpRegEntry);
  191. m_pMCSUserObject->RegistryMonitorEntryIndication(
  192. lpRegEntry->registry_key,
  193. lpRegEntry->entry_item,
  194. lpRegEntry->owner_id,
  195. lpRegEntry->entity_id,
  196. lpRegEntry->modification_rights);
  197. }
  198. }
  199. }
  200. }
  201. // Remove this enity from the command target list if it exists.
  202. m_AppSapEidList2.Remove(entity_id);
  203. }
  204. /*
  205. * GCCError RegisterChannel ()
  206. *
  207. * Public Function Description
  208. * This routine is responsible for registering a specified channel.
  209. * It has two different paths of execution based on whether this is
  210. * a Top Provider registry or a subordinate node registry object.
  211. */
  212. GCCError CRegistry::RegisterChannel (
  213. PGCCRegistryKey registry_key,
  214. ChannelID channel_id,
  215. EntityID entity_id)
  216. {
  217. GCCError rc = GCC_NO_ERROR;
  218. REG_ENTRY *registry_entry; // a must
  219. CRegKeyContainer *registry_key_data = NULL; // a must
  220. CRegItem *registry_item_data = NULL; // a must
  221. GCCRegistryItem registry_item;
  222. CAppSap *requester_sap;
  223. if (NULL == (requester_sap = m_AppSapEidList2.Find(entity_id)))
  224. return (GCC_APP_NOT_ENROLLED);
  225. /*
  226. ** Next set up the Registry Key and Registry Item. Return immediately if
  227. ** a resource failure occurs.
  228. */
  229. DBG_SAVE_FILE_LINE
  230. registry_key_data = new CRegKeyContainer(registry_key, &rc);
  231. if (NULL == registry_key_data || GCC_NO_ERROR != rc)
  232. {
  233. ERROR_OUT(("CRegistry::RegisterChannel: can't create regitry key"));
  234. rc = GCC_ALLOCATION_FAILURE;
  235. goto MyExit;
  236. }
  237. if (m_fTopProvider == FALSE)
  238. {
  239. m_pMCSUserObject->RegistryRegisterChannelRequest(registry_key_data, channel_id, entity_id);
  240. // The registry key data object is no longer needed here
  241. registry_key_data->Release();
  242. rc = GCC_NO_ERROR;
  243. goto MyExit;
  244. }
  245. // no PDU is sent when request occurs at the top provider
  246. /*
  247. ** First check to see if the registry entry exists and if it
  248. ** does check the ownership to make sure this node has
  249. ** permission to change the entry.
  250. */
  251. registry_entry = GetRegistryEntry(registry_key_data);
  252. if (registry_entry != NULL)
  253. {
  254. // Entry already exists, send back negative result
  255. requester_sap->RegistryConfirm(
  256. m_nConfID,
  257. GCC_REGISTER_CHANNEL_CONFIRM,
  258. registry_entry->registry_key,
  259. registry_entry->entry_item,
  260. registry_entry->modification_rights,
  261. registry_entry->owner_id,
  262. registry_entry->entity_id,
  263. FALSE,
  264. GCC_RESULT_ENTRY_ALREADY_EXISTS);
  265. // The registry key data object is no longer needed
  266. registry_key_data->Release();
  267. rc = GCC_NO_ERROR;
  268. goto MyExit;
  269. }
  270. // Set up the registry item here
  271. registry_item.item_type = GCC_REGISTRY_CHANNEL_ID;
  272. registry_item.channel_id = channel_id;
  273. DBG_SAVE_FILE_LINE
  274. registry_item_data = new CRegItem(&registry_item, &rc);
  275. if (registry_item_data == NULL || GCC_NO_ERROR != rc)
  276. {
  277. ERROR_OUT(("CRegistry::RegisterChannel: can't create regitry item"));
  278. rc = GCC_ALLOCATION_FAILURE;
  279. goto MyExit;
  280. }
  281. // Since entry does not exists create it here
  282. DBG_SAVE_FILE_LINE
  283. registry_entry = new REG_ENTRY;
  284. if (registry_entry == NULL)
  285. {
  286. ERROR_OUT(("CRegistry::RegisterChannel: can't create regitry entry"));
  287. rc = GCC_ALLOCATION_FAILURE;
  288. goto MyExit;
  289. }
  290. // Fill in the new entry
  291. registry_entry->registry_key = registry_key_data;
  292. registry_entry->entry_item = registry_item_data;
  293. registry_entry->monitoring_state = OFF;
  294. registry_entry->owner_id = m_pMCSUserObject->GetMyNodeID();
  295. registry_entry->entity_id = entity_id;
  296. /*
  297. ** Initialize to public incase entry is switched to
  298. ** a parameter. Note that as long as the entry is
  299. ** not a PARAMETER modification rights will not be
  300. ** used.
  301. */
  302. registry_entry->modification_rights = GCC_PUBLIC_RIGHTS;
  303. // Add registry entry to registry list
  304. m_RegEntryList.Append(registry_entry);
  305. // Send success for the result
  306. requester_sap->RegistryConfirm (
  307. m_nConfID,
  308. GCC_REGISTER_CHANNEL_CONFIRM,
  309. registry_entry->registry_key,
  310. registry_entry->entry_item,
  311. registry_entry->modification_rights,
  312. registry_entry->owner_id,
  313. registry_entry->entity_id,
  314. FALSE,
  315. GCC_RESULT_SUCCESSFUL);
  316. rc = GCC_NO_ERROR;
  317. MyExit:
  318. if (GCC_NO_ERROR != rc)
  319. {
  320. if (NULL != registry_key_data)
  321. {
  322. registry_key_data->Release();
  323. }
  324. if (NULL != registry_item_data)
  325. {
  326. registry_item_data->Release();
  327. }
  328. delete registry_entry;
  329. }
  330. return (rc);
  331. }
  332. /*
  333. * GCCError AssignToken ()
  334. *
  335. * Public Function Description
  336. * This routine is responsible for generating and registering a new token.
  337. * It has two different paths of execution based on whether this is
  338. * a Top Provider registry or a subordinate node registry object.
  339. */
  340. GCCError CRegistry::AssignToken (
  341. PGCCRegistryKey registry_key,
  342. EntityID entity_id )
  343. {
  344. GCCError rc = GCC_NO_ERROR;
  345. REG_ENTRY *registry_entry = NULL; // a must
  346. CRegKeyContainer *registry_key_data = NULL; // a must
  347. CRegItem *registry_item_data = NULL; // a must
  348. GCCRegistryItem registry_item;
  349. CAppSap *requester_sap;
  350. if (NULL == (requester_sap = m_AppSapEidList2.Find(entity_id)))
  351. return (GCC_APP_NOT_ENROLLED);
  352. DBG_SAVE_FILE_LINE
  353. registry_key_data = new CRegKeyContainer(registry_key, &rc);
  354. if ((registry_key_data == NULL) || (rc != GCC_NO_ERROR))
  355. {
  356. ERROR_OUT(("CRegistry::AssignToken: can't create regitry key"));
  357. rc = GCC_ALLOCATION_FAILURE;
  358. goto MyExit;
  359. }
  360. if (m_fTopProvider == FALSE)
  361. {
  362. m_pMCSUserObject->RegistryAssignTokenRequest(registry_key_data, entity_id);
  363. // The registry key data object is no longer needed here
  364. registry_key_data->Release();
  365. rc = GCC_NO_ERROR;
  366. goto MyExit;
  367. }
  368. // no PDU is sent when request occurs at the top provider
  369. /*
  370. ** First check to see if the registry entry exists and if it
  371. ** does check the ownership to make sure this node has
  372. ** permission to change the entry.
  373. */
  374. registry_entry = GetRegistryEntry(registry_key_data);
  375. if (registry_entry != NULL)
  376. {
  377. // Entry already exists, send back negative result
  378. requester_sap->RegistryConfirm(
  379. m_nConfID,
  380. GCC_ASSIGN_TOKEN_CONFIRM,
  381. registry_entry->registry_key,
  382. registry_entry->entry_item,
  383. registry_entry->modification_rights,
  384. registry_entry->owner_id,
  385. registry_entry->entity_id,
  386. FALSE,
  387. GCC_RESULT_ENTRY_ALREADY_EXISTS);
  388. // The registry key data object is no longer needed
  389. registry_key_data->Release();
  390. rc = GCC_NO_ERROR;
  391. goto MyExit;
  392. }
  393. // Set up the registry item here
  394. registry_item.item_type = GCC_REGISTRY_TOKEN_ID;
  395. registry_item.token_id = GetUnusedToken();
  396. DBG_SAVE_FILE_LINE
  397. registry_item_data = new CRegItem(&registry_item, &rc);
  398. if ((registry_item_data == NULL) || (rc != GCC_NO_ERROR))
  399. {
  400. ERROR_OUT(("CRegistry::AssignToken: can't create regitry item"));
  401. rc = GCC_ALLOCATION_FAILURE;
  402. goto MyExit;
  403. }
  404. DBG_SAVE_FILE_LINE
  405. registry_entry = new REG_ENTRY;
  406. if (registry_entry == NULL)
  407. {
  408. ERROR_OUT(("CRegistry::AssignToken: can't create regitry entry"));
  409. rc = GCC_ALLOCATION_FAILURE;
  410. goto MyExit;
  411. }
  412. // Fill in the new entry
  413. registry_entry->registry_key = registry_key_data;
  414. registry_entry->entry_item = registry_item_data;
  415. registry_entry->monitoring_state = OFF;
  416. registry_entry->owner_id = m_pMCSUserObject->GetMyNodeID();
  417. registry_entry->entity_id = entity_id;
  418. /*
  419. ** Initialize to public incase entry is switched to
  420. ** a parameter. Note that as long as the entry is
  421. ** not a PARAMETER modification rights will not be
  422. ** used.
  423. */
  424. registry_entry->modification_rights = GCC_PUBLIC_RIGHTS;
  425. // Add registry entry to registry list
  426. m_RegEntryList.Append(registry_entry);
  427. // Send success for the result
  428. requester_sap->RegistryConfirm (
  429. m_nConfID,
  430. GCC_ASSIGN_TOKEN_CONFIRM,
  431. registry_entry->registry_key,
  432. registry_entry->entry_item,
  433. registry_entry->modification_rights,
  434. registry_entry->owner_id,
  435. registry_entry->entity_id,
  436. FALSE,
  437. GCC_RESULT_SUCCESSFUL);
  438. rc = GCC_NO_ERROR;
  439. MyExit:
  440. if (GCC_NO_ERROR != rc)
  441. {
  442. if (NULL != registry_key_data)
  443. {
  444. registry_key_data->Release();
  445. }
  446. if (NULL != registry_item_data)
  447. {
  448. registry_item_data->Release();
  449. }
  450. delete registry_entry;
  451. }
  452. return (rc);
  453. }
  454. /*
  455. * GCCError SetParameter ()
  456. *
  457. * Public Function Description
  458. * This routine is responsible for generating and registering a new token.
  459. * It has two different paths of execution based on whether this is
  460. * a Top Provider registry or a subordinate node registry object.
  461. */
  462. GCCError CRegistry::SetParameter (
  463. PGCCRegistryKey registry_key,
  464. LPOSTR parameter_value,
  465. GCCModificationRights modification_rights,
  466. EntityID entity_id )
  467. {
  468. GCCError rc = GCC_NO_ERROR;
  469. REG_ENTRY *registry_entry = NULL; // a must
  470. CRegKeyContainer *registry_key_data = NULL; // a must
  471. CRegItem *registry_item_data = NULL; // a must
  472. GCCResult result;
  473. GCCRegistryItem registry_item;
  474. BOOL application_is_enrolled = FALSE;
  475. CAppSap *requester_sap;
  476. if (NULL == (requester_sap = m_AppSapEidList2.Find(entity_id)))
  477. return (GCC_APP_NOT_ENROLLED);
  478. DBG_SAVE_FILE_LINE
  479. registry_key_data = new CRegKeyContainer(registry_key, &rc);
  480. if ((registry_key_data == NULL) || (rc != GCC_NO_ERROR))
  481. {
  482. ERROR_OUT(("CRegistry::SetParameter: can't create regitry key"));
  483. rc = GCC_ALLOCATION_FAILURE;
  484. goto MyExit;
  485. }
  486. if (m_fTopProvider == FALSE)
  487. {
  488. m_pMCSUserObject->RegistrySetParameterRequest(registry_key_data,
  489. parameter_value,
  490. modification_rights,
  491. entity_id);
  492. // The registry key data object is no longer needed here
  493. registry_key_data->Release();
  494. rc = GCC_NO_ERROR;
  495. goto MyExit;
  496. }
  497. // no PDU is sent when request occurs at the top provider
  498. // Set up the registry item here
  499. if (parameter_value != NULL)
  500. {
  501. registry_item.item_type = GCC_REGISTRY_PARAMETER;
  502. registry_item.parameter = *parameter_value;
  503. }
  504. else
  505. {
  506. registry_item.item_type = GCC_REGISTRY_NONE;
  507. }
  508. DBG_SAVE_FILE_LINE
  509. registry_item_data = new CRegItem(&registry_item, &rc);
  510. if ((registry_item_data == NULL) || (rc != GCC_NO_ERROR))
  511. {
  512. ERROR_OUT(("CRegistry::SetParameter: can't create regitry item"));
  513. rc = GCC_ALLOCATION_FAILURE;
  514. goto MyExit;
  515. }
  516. /*
  517. ** First check to see if the registry entry exists and if it
  518. ** does check the ownership and modification rights to make
  519. ** sure this node has permission to change the entry.
  520. */
  521. registry_entry = GetRegistryEntry(registry_key_data);
  522. if (registry_entry != NULL)
  523. {
  524. /*
  525. ** Here we make sure that this request is comming from an
  526. ** APE that previously enrolled.
  527. */
  528. CAppRosterMgr *lpAppRosterMgr;
  529. m_pAppRosterMgrList->Reset();
  530. while (NULL != (lpAppRosterMgr = m_pAppRosterMgrList->Iterate()))
  531. {
  532. if (lpAppRosterMgr->IsAPEEnrolled(registry_key_data->GetSessionKey(),
  533. m_pMCSUserObject->GetMyNodeID(),
  534. entity_id))
  535. {
  536. application_is_enrolled = TRUE;
  537. break;
  538. }
  539. }
  540. /*
  541. ** Check ownership rights here: First check is to make
  542. ** sure that this is the owner if Owner rights is
  543. ** specified. Next check is to make sure that
  544. */
  545. if (((registry_entry->modification_rights == GCC_OWNER_RIGHTS) &&
  546. (registry_entry->owner_id == m_pMCSUserObject->GetMyNodeID()) &&
  547. (registry_entry->entity_id == entity_id)) ||
  548. ((registry_entry->modification_rights == GCC_SESSION_RIGHTS) &&
  549. (application_is_enrolled)) ||
  550. (registry_entry->modification_rights == GCC_PUBLIC_RIGHTS) ||
  551. (registry_entry->owner_id == 0))
  552. {
  553. /*
  554. ** Monitoring state should not be affected by
  555. ** this request.
  556. */
  557. *registry_entry->entry_item = *registry_item_data;
  558. /*
  559. ** Only the owner is allowed to change the modification
  560. ** rights of a registry entry (unless the entry is
  561. ** unowned). Also if there is no owner, we set up the
  562. ** new owner here.
  563. */
  564. if (((registry_entry->owner_id == m_pMCSUserObject->GetMyNodeID()) &&
  565. (registry_entry->entity_id == entity_id)) ||
  566. (registry_entry->owner_id == 0))
  567. {
  568. registry_entry->owner_id = m_pMCSUserObject->GetMyNodeID();
  569. registry_entry->entity_id = entity_id;
  570. /*
  571. ** If no modification rights are specified we must
  572. ** set the modification rights to be public.
  573. */
  574. if (modification_rights != GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
  575. {
  576. registry_entry->modification_rights = modification_rights;
  577. }
  578. }
  579. // Send Monitor Indication if necessary
  580. if (registry_entry->monitoring_state == ON)
  581. {
  582. /*
  583. ** Deliver the monitor indication to the Top
  584. ** Provider's Node Controller if necessary.
  585. */
  586. SendMonitorEntryIndicationMessage(registry_entry);
  587. /*
  588. ** Broadcast a monitor entry indication to all
  589. ** nodes in the conference.
  590. */
  591. m_pMCSUserObject->RegistryMonitorEntryIndication(
  592. registry_entry->registry_key,
  593. registry_entry->entry_item,
  594. registry_entry->owner_id,
  595. registry_entry->entity_id,
  596. registry_entry->modification_rights);
  597. }
  598. // Send success for the result
  599. result = GCC_RESULT_SUCCESSFUL;
  600. }
  601. else
  602. {
  603. result = GCC_RESULT_INDEX_ALREADY_OWNED;
  604. }
  605. requester_sap->RegistryConfirm(
  606. m_nConfID,
  607. GCC_SET_PARAMETER_CONFIRM,
  608. registry_entry->registry_key,
  609. registry_entry->entry_item,
  610. registry_entry->modification_rights,
  611. registry_entry->owner_id,
  612. registry_entry->entity_id,
  613. FALSE,
  614. result);
  615. // The registry key data object is no longer needed
  616. registry_key_data->Release();
  617. // The registry item data object is no longer needed
  618. registry_item_data->Release();
  619. rc = GCC_NO_ERROR;
  620. goto MyExit;
  621. }
  622. // registry entry does not exist, create one.
  623. DBG_SAVE_FILE_LINE
  624. registry_entry = new REG_ENTRY;
  625. if (registry_entry == NULL)
  626. {
  627. ERROR_OUT(("CRegistry::SetParameter: can't create regitry entry"));
  628. rc = GCC_ALLOCATION_FAILURE;
  629. goto MyExit;
  630. }
  631. // Fill in the new entry
  632. registry_entry->registry_key = registry_key_data;
  633. registry_entry->entry_item = registry_item_data;
  634. registry_entry->monitoring_state = OFF;
  635. registry_entry->owner_id = m_pMCSUserObject->GetMyNodeID();
  636. registry_entry->entity_id = entity_id;
  637. /*
  638. ** If no modification rights are specified we must
  639. ** initialize the modification rights to be public.
  640. ** Note that modification rights are only specified
  641. ** for the SetParameter call.
  642. */
  643. registry_entry->modification_rights =
  644. (modification_rights == GCC_NO_MODIFICATION_RIGHTS_SPECIFIED) ?
  645. GCC_PUBLIC_RIGHTS :
  646. modification_rights;
  647. // Add registry entry to registry list
  648. m_RegEntryList.Append(registry_entry);
  649. // Send success for the result
  650. requester_sap->RegistryConfirm(
  651. m_nConfID,
  652. GCC_SET_PARAMETER_CONFIRM,
  653. registry_entry->registry_key,
  654. registry_entry->entry_item,
  655. registry_entry->modification_rights,
  656. registry_entry->owner_id,
  657. registry_entry->entity_id,
  658. FALSE,
  659. GCC_RESULT_SUCCESSFUL);
  660. rc = GCC_NO_ERROR;
  661. MyExit:
  662. if (GCC_NO_ERROR != rc)
  663. {
  664. if (NULL != registry_key_data)
  665. {
  666. registry_key_data->Release();
  667. }
  668. if (NULL != registry_item_data)
  669. {
  670. registry_item_data->Release();
  671. }
  672. delete registry_entry;
  673. }
  674. return (rc);
  675. }
  676. /*
  677. * GCCError RetrieveEntry ()
  678. *
  679. * Public Function Description
  680. * This routine is used by a local APE to obtain an item that was
  681. * registered with GCC. If this registry object does NOT
  682. * live at the top provider node this class is responsible for
  683. * forwarding the request on up to the top provider.
  684. */
  685. GCCError CRegistry::RetrieveEntry (
  686. PGCCRegistryKey registry_key,
  687. EntityID entity_id )
  688. {
  689. GCCError rc;
  690. REG_ENTRY *registry_entry;
  691. CRegKeyContainer *registry_key_data = NULL; // a must
  692. CAppSap *requester_sap;
  693. if (NULL == (requester_sap = m_AppSapEidList2.Find(entity_id)))
  694. {
  695. return GCC_APP_NOT_ENROLLED;
  696. }
  697. DBG_SAVE_FILE_LINE
  698. registry_key_data = new CRegKeyContainer(registry_key, &rc);
  699. if ((registry_key_data == NULL) || (rc != GCC_NO_ERROR))
  700. {
  701. ERROR_OUT(("CRegistry::RetrieveEntry: can't create regitry key"));
  702. rc = GCC_ALLOCATION_FAILURE;
  703. goto MyExit;
  704. }
  705. if (m_fTopProvider == FALSE)
  706. {
  707. m_pMCSUserObject->RegistryRetrieveEntryRequest(registry_key_data, entity_id);
  708. rc = GCC_NO_ERROR;
  709. goto MyExit;
  710. }
  711. // no PDU is sent when request occurs at the top provider
  712. registry_entry = GetRegistryEntry(registry_key_data);
  713. if (registry_entry != NULL)
  714. {
  715. // Send back a positive result with the entry item
  716. requester_sap->RegistryConfirm(
  717. m_nConfID,
  718. GCC_RETRIEVE_ENTRY_CONFIRM,
  719. registry_entry->registry_key,
  720. registry_entry->entry_item,
  721. registry_entry->modification_rights,
  722. registry_entry->owner_id,
  723. registry_entry->entity_id,
  724. FALSE,
  725. GCC_RESULT_SUCCESSFUL);
  726. }
  727. else
  728. {
  729. // Send back a negative result
  730. requester_sap->RegistryConfirm(
  731. m_nConfID,
  732. GCC_RETRIEVE_ENTRY_CONFIRM,
  733. registry_key_data,
  734. m_pEmptyRegItem,
  735. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  736. 0, // No owner id
  737. 0, // No entity id
  738. FALSE,
  739. GCC_RESULT_ENTRY_DOES_NOT_EXIST);
  740. }
  741. rc = GCC_NO_ERROR;
  742. MyExit:
  743. if (NULL != registry_key_data)
  744. {
  745. registry_key_data->Release();
  746. }
  747. return (rc);
  748. }
  749. /*
  750. * GCCError DeleteEntry ()
  751. *
  752. * Public Function Description
  753. * This routine is used by a local APE to delete an item that was
  754. * registered with GCC. If this registry object does NOT
  755. * live at the top provider node this class is responsible for
  756. * forwarding the request on up to the top provider.
  757. */
  758. GCCError CRegistry::DeleteEntry (
  759. PGCCRegistryKey registry_key,
  760. EntityID entity_id )
  761. {
  762. GCCError rc;
  763. REG_ENTRY *registry_entry;
  764. CRegKeyContainer *registry_key_data = NULL; // a must
  765. CAppSap *requester_sap;
  766. if (NULL == (requester_sap = m_AppSapEidList2.Find(entity_id)))
  767. {
  768. return GCC_APP_NOT_ENROLLED;
  769. }
  770. DBG_SAVE_FILE_LINE
  771. registry_key_data = new CRegKeyContainer(registry_key, &rc);
  772. if ((registry_key_data == NULL) || (rc != GCC_NO_ERROR))
  773. {
  774. ERROR_OUT(("CRegistry::DeleteEntry: can't create regitry key"));
  775. rc = GCC_ALLOCATION_FAILURE;
  776. goto MyExit;
  777. }
  778. if (m_fTopProvider == FALSE)
  779. {
  780. m_pMCSUserObject->RegistryDeleteEntryRequest(registry_key_data, entity_id);
  781. rc = GCC_NO_ERROR;
  782. goto MyExit;
  783. }
  784. // no PDU is sent when request occurs at the top provider
  785. /*
  786. ** First check to see if the registry entry exists and if it does
  787. ** check the ownership to make sure this node has permission to
  788. ** change the entry.
  789. */
  790. registry_entry = GetRegistryEntry(registry_key_data);
  791. if (registry_entry != NULL)
  792. {
  793. if (((registry_entry->owner_id == m_pMCSUserObject->GetMyNodeID()) &&
  794. (registry_entry->entity_id == entity_id)) ||
  795. (registry_entry->owner_id == 0))
  796. {
  797. /*
  798. ** First convert this to a non-entry incase it needs to
  799. ** be included in a monitor indication. We first delete
  800. ** the old entry item and replace it with an Emtpy item.
  801. */
  802. registry_entry->entry_item->Release();
  803. registry_entry->entry_item = m_pEmptyRegItem;
  804. registry_entry->owner_id = 0;
  805. registry_entry->entity_id = 0;
  806. registry_entry->modification_rights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
  807. // Send Monitor Indication if necessary
  808. if (registry_entry->monitoring_state == ON)
  809. {
  810. /*
  811. ** Deliver the monitor indication to the Top
  812. ** Provider's Node Controller if necessary.
  813. */
  814. SendMonitorEntryIndicationMessage(registry_entry);
  815. /*
  816. ** Broadcast a monitor entry indication to all
  817. ** nodes in the conference.
  818. */
  819. m_pMCSUserObject->RegistryMonitorEntryIndication(
  820. registry_entry->registry_key,
  821. registry_entry->entry_item,
  822. registry_entry->owner_id,
  823. registry_entry->entity_id,
  824. registry_entry->modification_rights);
  825. }
  826. m_RegEntryList.Remove(registry_entry);
  827. if (NULL != registry_entry->registry_key)
  828. {
  829. registry_entry->registry_key->Release();
  830. }
  831. delete registry_entry;
  832. // Send success for the result
  833. requester_sap->RegistryConfirm(
  834. m_nConfID,
  835. GCC_DELETE_ENTRY_CONFIRM,
  836. registry_key_data,
  837. NULL,
  838. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  839. 0,
  840. 0,
  841. FALSE,
  842. GCC_RESULT_SUCCESSFUL);
  843. }
  844. else
  845. {
  846. // No ownership rights send back negative result
  847. requester_sap->RegistryConfirm (
  848. m_nConfID,
  849. GCC_DELETE_ENTRY_CONFIRM,
  850. registry_entry->registry_key,
  851. registry_entry->entry_item,
  852. registry_entry->modification_rights,
  853. registry_entry->owner_id,
  854. registry_entry->entity_id,
  855. FALSE,
  856. GCC_RESULT_INDEX_ALREADY_OWNED);
  857. }
  858. }
  859. else
  860. {
  861. // Send failure for the result. Entry does not exist
  862. requester_sap->RegistryConfirm (
  863. m_nConfID,
  864. GCC_DELETE_ENTRY_CONFIRM,
  865. registry_key_data,
  866. NULL,
  867. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  868. 0,
  869. 0,
  870. FALSE,
  871. GCC_RESULT_ENTRY_DOES_NOT_EXIST);
  872. }
  873. rc = GCC_NO_ERROR;
  874. MyExit:
  875. // The registry key data object is no longer needed here
  876. if (NULL != registry_key_data)
  877. {
  878. registry_key_data->Release();
  879. }
  880. return (rc);
  881. }
  882. /*
  883. * GCCError MonitorRequest ()
  884. *
  885. * Public Function Description
  886. * This routine is used by a local APE to monitor an item that was
  887. * registered with GCC. If this registry object does NOT
  888. * live at the top provider node this class is responsible for
  889. * forwarding the request on up to the top provider.
  890. */
  891. GCCError CRegistry::MonitorRequest (
  892. PGCCRegistryKey registry_key,
  893. BOOL enable_delivery,
  894. EntityID entity_id )
  895. {
  896. GCCError rc = GCC_NO_ERROR;
  897. REG_ENTRY *registry_entry;
  898. CRegKeyContainer *registry_key_data;
  899. GCCResult result = GCC_RESULT_SUCCESSFUL;
  900. CAppSap *requester_sap;
  901. BOOL fToConfirm = FALSE;
  902. if (NULL == (requester_sap = m_AppSapEidList2.Find(entity_id)))
  903. {
  904. return GCC_APP_NOT_ENROLLED;
  905. }
  906. /*
  907. ** First set up the Registry Key. Return immediately if a resource
  908. ** failure occurs.
  909. */
  910. DBG_SAVE_FILE_LINE
  911. registry_key_data = new CRegKeyContainer(registry_key, &rc);
  912. if ((registry_key_data != NULL) && (rc == GCC_NO_ERROR))
  913. {
  914. /*
  915. ** If the request is recieved at a node that is not the top
  916. ** provider we must send the request on to the top provider.
  917. */
  918. if (m_fTopProvider == FALSE)
  919. {
  920. if (enable_delivery)
  921. {
  922. /*
  923. ** Here we first go ahead and add the requesting APE to the
  924. ** list of applications wishing to monitor this particular
  925. ** entry. Note that if this entry does not exists at the top
  926. ** provider, this entry will be removed during the confirm.
  927. */
  928. rc = AddAPEToMonitoringList(registry_key_data, entity_id, requester_sap);
  929. if (rc == GCC_NO_ERROR)
  930. {
  931. /*
  932. ** Wait for the response before sending the confirm
  933. ** if we get this far.
  934. */
  935. m_pMCSUserObject->RegistryMonitorRequest(registry_key_data, entity_id);
  936. }
  937. else
  938. {
  939. result = GCC_RESULT_RESOURCES_UNAVAILABLE;
  940. fToConfirm = TRUE;
  941. }
  942. }
  943. else
  944. {
  945. RemoveAPEFromMonitoringList(registry_key_data, entity_id);
  946. result = GCC_RESULT_SUCCESSFUL;
  947. fToConfirm = TRUE;
  948. }
  949. }
  950. else // No PDU is sent when request occurs at the top provider
  951. {
  952. if (enable_delivery)
  953. {
  954. /*
  955. ** First check to see if the registry entry exists. If it does
  956. ** not we go ahead and create an empty entry so that we can
  957. ** add the monitoring APE to that entries list of monitoring
  958. ** APEs.
  959. */
  960. registry_entry = GetRegistryEntry(registry_key_data);
  961. if (registry_entry != NULL)
  962. {
  963. /*
  964. ** Here we go ahead and add the requesting APE to the
  965. ** list of applications wishing to monitor this entry.
  966. */
  967. rc = AddAPEToMonitoringList(registry_key_data, entity_id, requester_sap);
  968. if (rc == GCC_NO_ERROR)
  969. {
  970. // Set the monitoring state to ON
  971. registry_entry->monitoring_state = ON;
  972. }
  973. else
  974. {
  975. result = GCC_RESULT_RESOURCES_UNAVAILABLE;
  976. }
  977. }
  978. else
  979. {
  980. result = GCC_RESULT_ENTRY_DOES_NOT_EXIST;
  981. }
  982. }
  983. else
  984. {
  985. RemoveAPEFromMonitoringList(registry_key_data, entity_id);
  986. }
  987. fToConfirm = TRUE;
  988. }
  989. }
  990. else
  991. {
  992. ERROR_OUT(("CRegistry::MonitorRequest: can't create registry key"));
  993. rc = GCC_ALLOCATION_FAILURE;
  994. }
  995. if (fToConfirm)
  996. {
  997. ASSERT(NULL != registry_key_data);
  998. requester_sap->RegistryConfirm(
  999. m_nConfID,
  1000. GCC_MONITOR_CONFIRM,
  1001. registry_key_data,
  1002. NULL,
  1003. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1004. 0,
  1005. 0,
  1006. enable_delivery,
  1007. result);
  1008. }
  1009. // The registry key data object is no longer needed
  1010. if (NULL != registry_key_data)
  1011. {
  1012. registry_key_data->Release();
  1013. }
  1014. return (rc);
  1015. }
  1016. /*
  1017. * GCCError AllocateHandleRequest ()
  1018. *
  1019. * Public Function Description
  1020. * This routine is used by a local APE to allocate a specified number of
  1021. * handles from the application registry. If this registry object does NOT
  1022. * live at the top provider node this class is responsible for
  1023. * forwarding the request on up to the top provider.
  1024. */
  1025. GCCError CRegistry::AllocateHandleRequest(
  1026. UINT number_of_handles,
  1027. EntityID entity_id )
  1028. {
  1029. UINT temp_registry_handle;
  1030. CAppSap *requester_sap;
  1031. if (NULL == (requester_sap = m_AppSapEidList2.Find(entity_id)))
  1032. {
  1033. return GCC_APP_NOT_ENROLLED;
  1034. }
  1035. if (m_fTopProvider == FALSE)
  1036. {
  1037. m_pMCSUserObject->RegistryAllocateHandleRequest(number_of_handles, entity_id);
  1038. }
  1039. else // No PDU is sent when request occurs at the top provider
  1040. {
  1041. UINT nFirstHandle = 0;
  1042. GCCResult nResult;
  1043. if ((number_of_handles > 0) &&
  1044. (number_of_handles <= MAXIMUM_ALLOWABLE_ALLOCATED_HANDLES))
  1045. {
  1046. temp_registry_handle = m_nRegHandle + number_of_handles;
  1047. if (temp_registry_handle > m_nRegHandle)
  1048. {
  1049. nFirstHandle = m_nRegHandle;
  1050. nResult = GCC_RESULT_SUCCESSFUL;
  1051. m_nRegHandle = temp_registry_handle;
  1052. }
  1053. else
  1054. {
  1055. ASSERT(0 == nFirstHandle);
  1056. nResult = GCC_RESULT_NO_HANDLES_AVAILABLE;
  1057. }
  1058. }
  1059. else
  1060. {
  1061. ASSERT(0 == nFirstHandle);
  1062. nResult = GCC_RESULT_INVALID_NUMBER_OF_HANDLES;
  1063. }
  1064. requester_sap->RegistryAllocateHandleConfirm (
  1065. m_nConfID,
  1066. number_of_handles,
  1067. nFirstHandle,
  1068. nResult);
  1069. }
  1070. return (GCC_NO_ERROR);
  1071. }
  1072. /*
  1073. * GCCError ProcessRegisterChannelPDU ()
  1074. *
  1075. * Public Function Description
  1076. * This routine is used by the top provider node to process incomming
  1077. * register channel PDUs. It is responsible for returning any
  1078. * necessary responses that must be sent back to the requesting node.
  1079. */
  1080. GCCError CRegistry::ProcessRegisterChannelPDU (
  1081. CRegKeyContainer *registry_key_data,
  1082. ChannelID channel_id,
  1083. UserID requester_node_id,
  1084. EntityID requester_entity_id )
  1085. {
  1086. GCCError rc = GCC_NO_ERROR;
  1087. REG_ENTRY *registry_entry;
  1088. CRegItem *registry_item_data;
  1089. GCCRegistryItem registry_item;
  1090. BOOL application_is_enrolled = FALSE;
  1091. CAppRosterMgr *lpAppRosterMgr;
  1092. /*
  1093. ** We first make sure that this request is comming from an APE that
  1094. ** previously enrolled. Here we are not worried about a specific
  1095. ** session, only that the APE is enrolled.
  1096. */
  1097. m_pAppRosterMgrList->Reset();
  1098. while (NULL != (lpAppRosterMgr = m_pAppRosterMgrList->Iterate()))
  1099. {
  1100. if (lpAppRosterMgr->IsAPEEnrolled (requester_node_id, requester_entity_id))
  1101. {
  1102. application_is_enrolled = TRUE;
  1103. break;
  1104. }
  1105. }
  1106. if (application_is_enrolled)
  1107. {
  1108. /*
  1109. ** Next check to see if the registry entry exists and if it does
  1110. ** check the ownership to make sure this node has permission to
  1111. ** change the entry.
  1112. */
  1113. registry_entry = GetRegistryEntry ( registry_key_data );
  1114. if (registry_entry != NULL)
  1115. {
  1116. // Entry already exists, send back negative result
  1117. m_pMCSUserObject->RegistryResponse(
  1118. REGISTER_CHANNEL,
  1119. requester_node_id,
  1120. requester_entity_id,
  1121. registry_key_data,
  1122. registry_entry->entry_item,
  1123. registry_entry->modification_rights,
  1124. registry_entry->owner_id,
  1125. registry_entry->entity_id,
  1126. GCC_RESULT_ENTRY_ALREADY_EXISTS);
  1127. }
  1128. else
  1129. {
  1130. registry_item.item_type = GCC_REGISTRY_CHANNEL_ID;
  1131. registry_item.channel_id = channel_id;
  1132. DBG_SAVE_FILE_LINE
  1133. registry_item_data = new CRegItem(&registry_item, &rc);
  1134. if ((registry_item_data != NULL) && (rc == GCC_NO_ERROR))
  1135. {
  1136. DBG_SAVE_FILE_LINE
  1137. registry_entry = new REG_ENTRY;
  1138. if (registry_entry != NULL)
  1139. {
  1140. // Fill in the new entry
  1141. DBG_SAVE_FILE_LINE
  1142. registry_entry->registry_key = new CRegKeyContainer(registry_key_data, &rc);
  1143. if ((registry_entry->registry_key != NULL) && (rc == GCC_NO_ERROR))
  1144. {
  1145. registry_entry->entry_item = registry_item_data;
  1146. registry_entry->monitoring_state = OFF;
  1147. registry_entry->owner_id = requester_node_id;
  1148. registry_entry->entity_id = requester_entity_id;
  1149. /*
  1150. ** Initialize to public incase entry is switched to
  1151. ** a parameter. Note that as long as the entry is
  1152. ** not a PARAMETER modification rights will not be
  1153. ** used.
  1154. */
  1155. registry_entry->modification_rights = GCC_PUBLIC_RIGHTS;
  1156. m_RegEntryList.Append(registry_entry);
  1157. // Send success for the result
  1158. m_pMCSUserObject->RegistryResponse(
  1159. REGISTER_CHANNEL,
  1160. requester_node_id,
  1161. requester_entity_id,
  1162. registry_entry->registry_key,
  1163. registry_entry->entry_item,
  1164. registry_entry->modification_rights,
  1165. registry_entry->owner_id,
  1166. registry_entry->entity_id,
  1167. GCC_RESULT_SUCCESSFUL);
  1168. }
  1169. else if (registry_entry->registry_key == NULL)
  1170. {
  1171. delete registry_entry;
  1172. registry_item_data->Release();
  1173. rc = GCC_ALLOCATION_FAILURE;
  1174. }
  1175. else
  1176. {
  1177. registry_entry->registry_key->Release();
  1178. delete registry_entry;
  1179. registry_item_data->Release();
  1180. }
  1181. }
  1182. else
  1183. {
  1184. rc = GCC_ALLOCATION_FAILURE;
  1185. }
  1186. }
  1187. else if (registry_item_data == NULL)
  1188. {
  1189. rc = GCC_ALLOCATION_FAILURE;
  1190. }
  1191. else
  1192. {
  1193. registry_item_data->Release();
  1194. }
  1195. }
  1196. }
  1197. else
  1198. {
  1199. // Send back negative result stating invalid requester
  1200. m_pMCSUserObject->RegistryResponse(
  1201. REGISTER_CHANNEL,
  1202. requester_node_id,
  1203. requester_entity_id,
  1204. registry_key_data,
  1205. NULL,
  1206. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1207. 0,
  1208. 0,
  1209. GCC_RESULT_INVALID_REQUESTER);
  1210. }
  1211. return (rc);
  1212. }
  1213. /*
  1214. * GCCError ProcessAssignTokenPDU ()
  1215. *
  1216. * Public Function Description
  1217. * This routine is used by the top provider node to process incomming
  1218. * register token PDUs. It is responsible for returning any
  1219. * necessary responses that must be sent back to the requesting node.
  1220. */
  1221. GCCError CRegistry::ProcessAssignTokenPDU (
  1222. CRegKeyContainer *registry_key_data,
  1223. UserID requester_node_id,
  1224. EntityID requester_entity_id )
  1225. {
  1226. GCCError rc = GCC_NO_ERROR;
  1227. REG_ENTRY *registry_entry;
  1228. CRegItem *registry_item_data;
  1229. GCCRegistryItem registry_item;
  1230. BOOL application_is_enrolled = FALSE;
  1231. CAppRosterMgr *lpAppRosterMgr;
  1232. /*
  1233. ** We first make sure that this request is comming from an APE that
  1234. ** previously enrolled. Here we are not worried about a specific
  1235. ** session, only that the APE is enrolled.
  1236. */
  1237. m_pAppRosterMgrList->Reset();
  1238. while (NULL != (lpAppRosterMgr = m_pAppRosterMgrList->Iterate()))
  1239. {
  1240. if (lpAppRosterMgr->IsAPEEnrolled (requester_node_id, requester_entity_id))
  1241. {
  1242. application_is_enrolled = TRUE;
  1243. break;
  1244. }
  1245. }
  1246. if (application_is_enrolled)
  1247. {
  1248. /*
  1249. ** First check to see if the registry entry exists and if it does
  1250. ** check the ownership to make sure this node has permission to
  1251. ** change the entry.
  1252. */
  1253. registry_entry = GetRegistryEntry ( registry_key_data );
  1254. if (registry_entry != NULL)
  1255. {
  1256. // Entry already exists, send back negative result
  1257. m_pMCSUserObject->RegistryResponse(ASSIGN_TOKEN,
  1258. requester_node_id,
  1259. requester_entity_id,
  1260. registry_key_data,
  1261. registry_entry->entry_item,
  1262. registry_entry->modification_rights,
  1263. registry_entry->owner_id,
  1264. registry_entry->entity_id,
  1265. GCC_RESULT_ENTRY_ALREADY_EXISTS);
  1266. }
  1267. else
  1268. {
  1269. DBG_SAVE_FILE_LINE
  1270. registry_entry = new REG_ENTRY;
  1271. if (registry_entry != NULL)
  1272. {
  1273. registry_item.item_type = GCC_REGISTRY_TOKEN_ID;
  1274. registry_item.token_id = GetUnusedToken();
  1275. DBG_SAVE_FILE_LINE
  1276. registry_item_data = new CRegItem(&registry_item, &rc);
  1277. if ((registry_item_data != NULL) && (rc == GCC_NO_ERROR))
  1278. {
  1279. // Fill in the new entry
  1280. DBG_SAVE_FILE_LINE
  1281. registry_entry->registry_key = new CRegKeyContainer(registry_key_data, &rc);
  1282. if ((registry_entry->registry_key != NULL) && (rc == GCC_NO_ERROR))
  1283. {
  1284. registry_entry->entry_item = registry_item_data;
  1285. registry_entry->monitoring_state = OFF;
  1286. registry_entry->owner_id = requester_node_id;
  1287. registry_entry->entity_id = requester_entity_id;
  1288. /*
  1289. ** Initialize to public incase entry is switched to
  1290. ** a parameter. Note that as long as the entry is
  1291. ** not a PARAMETER modification rights will not be
  1292. ** used.
  1293. */
  1294. registry_entry->modification_rights = GCC_PUBLIC_RIGHTS;
  1295. // Add registry entry to registry list
  1296. m_RegEntryList.Append(registry_entry);
  1297. // Send success for the result
  1298. m_pMCSUserObject->RegistryResponse(
  1299. ASSIGN_TOKEN,
  1300. requester_node_id,
  1301. requester_entity_id,
  1302. registry_key_data,
  1303. registry_entry->entry_item,
  1304. registry_entry->modification_rights,
  1305. registry_entry->owner_id,
  1306. registry_entry->entity_id,
  1307. GCC_RESULT_SUCCESSFUL);
  1308. }
  1309. else if (registry_entry->registry_key == NULL)
  1310. {
  1311. registry_item_data->Release();
  1312. delete registry_entry;
  1313. rc = GCC_ALLOCATION_FAILURE;
  1314. }
  1315. else
  1316. {
  1317. registry_entry->registry_key->Release();
  1318. registry_item_data->Release();
  1319. delete registry_entry;
  1320. }
  1321. }
  1322. else
  1323. {
  1324. if (registry_item_data == NULL)
  1325. {
  1326. rc = GCC_ALLOCATION_FAILURE;
  1327. }
  1328. else
  1329. {
  1330. registry_item_data->Release();
  1331. }
  1332. delete registry_entry;
  1333. }
  1334. }
  1335. else
  1336. {
  1337. rc = GCC_ALLOCATION_FAILURE;
  1338. }
  1339. }
  1340. }
  1341. else
  1342. {
  1343. m_pMCSUserObject->RegistryResponse(
  1344. ASSIGN_TOKEN,
  1345. requester_node_id,
  1346. requester_entity_id,
  1347. registry_key_data,
  1348. NULL,
  1349. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1350. 0,
  1351. 0,
  1352. GCC_RESULT_INVALID_REQUESTER);
  1353. }
  1354. return (rc);
  1355. }
  1356. /*
  1357. * GCCError ProcessSetParameterPDU ()
  1358. *
  1359. * Public Function Description
  1360. * This routine is used by the top provider node to process incomming
  1361. * register parameter PDUs. It is responsible for returning any
  1362. * necessary responses that must be sent back to the requesting node.
  1363. */
  1364. GCCError CRegistry::ProcessSetParameterPDU (
  1365. CRegKeyContainer *registry_key_data,
  1366. LPOSTR parameter_value,
  1367. GCCModificationRights modification_rights,
  1368. UserID requester_node_id,
  1369. EntityID requester_entity_id )
  1370. {
  1371. GCCError rc = GCC_NO_ERROR;
  1372. REG_ENTRY *registry_entry;
  1373. CRegItem *registry_item_data;
  1374. GCCResult result;
  1375. GCCRegistryItem registry_item;
  1376. BOOL application_is_enrolled = FALSE;
  1377. CAppRosterMgr *lpAppRosterMgr;
  1378. /*
  1379. ** We first make sure that this request is comming from an APE that
  1380. ** previously enrolled. Here we are not worried about a specific
  1381. ** session, only that the APE is enrolled.
  1382. */
  1383. m_pAppRosterMgrList->Reset();
  1384. while (NULL != (lpAppRosterMgr = m_pAppRosterMgrList->Iterate()))
  1385. {
  1386. if (lpAppRosterMgr->IsAPEEnrolled (requester_node_id, requester_entity_id))
  1387. {
  1388. application_is_enrolled = TRUE;
  1389. break;
  1390. }
  1391. }
  1392. if (application_is_enrolled)
  1393. {
  1394. // Set up the registry item
  1395. if (parameter_value != NULL)
  1396. {
  1397. registry_item.item_type = GCC_REGISTRY_PARAMETER;
  1398. registry_item.parameter = *parameter_value;
  1399. }
  1400. else
  1401. registry_item.item_type = GCC_REGISTRY_NONE;
  1402. /*
  1403. ** Check to see if the registry entry exists and if it does
  1404. ** check the ownership to make sure this node has permission to
  1405. ** change the entry.
  1406. */
  1407. registry_entry = GetRegistryEntry ( registry_key_data );
  1408. if (registry_entry != NULL)
  1409. {
  1410. /*
  1411. ** Here we make sure that this request is comming from an
  1412. ** APE that previously enrolled in the appropriate session.
  1413. */
  1414. m_pAppRosterMgrList->Reset();
  1415. while (NULL != (lpAppRosterMgr = m_pAppRosterMgrList->Iterate()))
  1416. {
  1417. if (lpAppRosterMgr->IsAPEEnrolled (registry_key_data->GetSessionKey (),
  1418. requester_node_id,
  1419. requester_entity_id))
  1420. {
  1421. application_is_enrolled = TRUE;
  1422. break;
  1423. }
  1424. }
  1425. /*
  1426. ** Check ownership rights here: First check is to make
  1427. ** sure that this is the owner if Owner rights is
  1428. ** specified. Next check is to make sure that
  1429. */
  1430. if (((registry_entry->modification_rights == GCC_OWNER_RIGHTS) &&
  1431. (registry_entry->owner_id == requester_node_id) &&
  1432. (registry_entry->entity_id == requester_entity_id)) ||
  1433. ((registry_entry->modification_rights == GCC_SESSION_RIGHTS) &&
  1434. (application_is_enrolled)) ||
  1435. (registry_entry->modification_rights == GCC_PUBLIC_RIGHTS) ||
  1436. (registry_entry->owner_id == 0))
  1437. {
  1438. DBG_SAVE_FILE_LINE
  1439. registry_item_data = new CRegItem(&registry_item, &rc);
  1440. if ((registry_item_data != NULL) && (rc == GCC_NO_ERROR))
  1441. {
  1442. // Monitoring state should not be affected by this request
  1443. *registry_entry->entry_item = *registry_item_data;
  1444. /*
  1445. ** Only the owner is allowed to change the modification
  1446. ** rights of a registry entry (unless the entry is
  1447. ** unowned). Also if there is no owner, we set up the
  1448. ** new owner here.
  1449. */
  1450. if (((registry_entry->owner_id == requester_node_id) &&
  1451. (registry_entry->entity_id == requester_entity_id)) ||
  1452. (registry_entry->owner_id == 0))
  1453. {
  1454. /*
  1455. ** This will take care of setting up the new owner if
  1456. ** one exists.
  1457. */
  1458. registry_entry->owner_id = requester_node_id;
  1459. registry_entry->entity_id = requester_entity_id;
  1460. /*
  1461. ** If no modification rights are specified we must
  1462. ** set the modification rights to be public.
  1463. */
  1464. if (modification_rights !=
  1465. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
  1466. {
  1467. registry_entry->modification_rights = modification_rights;
  1468. }
  1469. }
  1470. // Send Monitor Indication if necessary
  1471. if (registry_entry->monitoring_state == ON)
  1472. {
  1473. /*
  1474. ** Deliver the monitor indication to the Top
  1475. ** Provider's Node Controller if necessary.
  1476. */
  1477. SendMonitorEntryIndicationMessage(registry_entry);
  1478. /*
  1479. ** Broadcast a monitor entry indication to all
  1480. ** nodes in the conference.
  1481. */
  1482. m_pMCSUserObject->RegistryMonitorEntryIndication(
  1483. registry_entry->registry_key,
  1484. registry_entry->entry_item,
  1485. registry_entry->owner_id,
  1486. registry_entry->entity_id,
  1487. registry_entry->modification_rights);
  1488. }
  1489. registry_item_data->Release();
  1490. // Send success for the result
  1491. result = GCC_RESULT_SUCCESSFUL;
  1492. }
  1493. else if (registry_item_data == NULL)
  1494. {
  1495. rc = GCC_ALLOCATION_FAILURE;
  1496. result = GCC_RESULT_RESOURCES_UNAVAILABLE;
  1497. }
  1498. else
  1499. {
  1500. registry_item_data->Release();
  1501. result = GCC_RESULT_RESOURCES_UNAVAILABLE;
  1502. }
  1503. }
  1504. else
  1505. result = GCC_RESULT_INDEX_ALREADY_OWNED;
  1506. // No ownership rights send back negative result
  1507. m_pMCSUserObject->RegistryResponse(SET_PARAMETER,
  1508. requester_node_id,
  1509. requester_entity_id,
  1510. registry_key_data,
  1511. registry_entry->entry_item,
  1512. registry_entry->modification_rights,
  1513. registry_entry->owner_id,
  1514. registry_entry->entity_id,
  1515. result);
  1516. }
  1517. else
  1518. {
  1519. DBG_SAVE_FILE_LINE
  1520. registry_entry = new REG_ENTRY;
  1521. if (registry_entry != NULL)
  1522. {
  1523. DBG_SAVE_FILE_LINE
  1524. registry_item_data = new CRegItem(&registry_item, &rc);
  1525. if ((registry_item_data != NULL) && (rc == GCC_NO_ERROR))
  1526. {
  1527. // Fill in the new entry
  1528. DBG_SAVE_FILE_LINE
  1529. registry_entry->registry_key = new CRegKeyContainer(registry_key_data, &rc);
  1530. if ((registry_entry->registry_key != NULL) && (rc == GCC_NO_ERROR))
  1531. {
  1532. registry_entry->entry_item = registry_item_data;
  1533. registry_entry->monitoring_state = OFF;
  1534. registry_entry->owner_id = requester_node_id;
  1535. registry_entry->entity_id = requester_entity_id;
  1536. /*
  1537. ** If no modification rights are specified we must
  1538. ** initialize the modification rights to be public.
  1539. ** Note that modification rights are only specified
  1540. ** for the SetParameter call.
  1541. */
  1542. if (modification_rights == GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
  1543. {
  1544. registry_entry->modification_rights = GCC_PUBLIC_RIGHTS;
  1545. }
  1546. else
  1547. {
  1548. registry_entry->modification_rights = modification_rights;
  1549. }
  1550. // Add registry entry to registry list
  1551. m_RegEntryList.Append(registry_entry);
  1552. // Send success for the result
  1553. m_pMCSUserObject->RegistryResponse(
  1554. SET_PARAMETER,
  1555. requester_node_id,
  1556. requester_entity_id,
  1557. registry_key_data,
  1558. registry_entry->entry_item,
  1559. registry_entry->modification_rights,
  1560. registry_entry->owner_id,
  1561. registry_entry->entity_id,
  1562. GCC_RESULT_SUCCESSFUL);
  1563. }
  1564. else if (registry_entry->registry_key == NULL)
  1565. {
  1566. registry_item_data->Release();
  1567. delete registry_entry;
  1568. rc = GCC_ALLOCATION_FAILURE;
  1569. }
  1570. else
  1571. {
  1572. registry_entry->registry_key->Release();
  1573. registry_item_data->Release();
  1574. delete registry_entry;
  1575. }
  1576. }
  1577. else if (registry_item_data == NULL)
  1578. {
  1579. delete registry_entry;
  1580. rc = GCC_ALLOCATION_FAILURE;
  1581. }
  1582. }
  1583. else
  1584. {
  1585. rc = GCC_ALLOCATION_FAILURE;
  1586. }
  1587. }
  1588. }
  1589. else
  1590. {
  1591. m_pMCSUserObject->RegistryResponse(
  1592. SET_PARAMETER,
  1593. requester_node_id,
  1594. requester_entity_id,
  1595. registry_key_data,
  1596. NULL,
  1597. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1598. 0,
  1599. 0,
  1600. GCC_RESULT_INVALID_REQUESTER);
  1601. }
  1602. return (rc);
  1603. }
  1604. /*
  1605. * void ProcessRetrieveEntryPDU ()
  1606. *
  1607. * Public Function Description
  1608. * This routine is used by the top provider node to process an incomming
  1609. * request to retrieve a registry entry. It is responsible for returning
  1610. * any necessary responses that must be sent back to the requesting node.
  1611. */
  1612. void CRegistry::ProcessRetrieveEntryPDU (
  1613. CRegKeyContainer *registry_key_data,
  1614. UserID requester_node_id,
  1615. EntityID requester_entity_id)
  1616. {
  1617. REG_ENTRY *registry_entry;
  1618. registry_entry = GetRegistryEntry ( registry_key_data );
  1619. if (registry_entry != NULL)
  1620. {
  1621. // Send back a positive result with the entry item
  1622. m_pMCSUserObject->RegistryResponse(RETRIEVE_ENTRY,
  1623. requester_node_id,
  1624. requester_entity_id,
  1625. registry_key_data,
  1626. registry_entry->entry_item,
  1627. registry_entry->modification_rights,
  1628. registry_entry->owner_id,
  1629. registry_entry->entity_id,
  1630. GCC_RESULT_SUCCESSFUL);
  1631. }
  1632. else
  1633. {
  1634. // Send back a negative result
  1635. m_pMCSUserObject->RegistryResponse(RETRIEVE_ENTRY,
  1636. requester_node_id,
  1637. requester_entity_id,
  1638. registry_key_data,
  1639. m_pEmptyRegItem,
  1640. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1641. 0,
  1642. 0,
  1643. GCC_RESULT_ENTRY_DOES_NOT_EXIST);
  1644. }
  1645. }
  1646. /*
  1647. * void ProcessDeleteEntryPDU ()
  1648. *
  1649. * Public Function Description
  1650. * This routine is used by the top provider node to process an incomming
  1651. * request to delete a registry entry. It is responsible for returning
  1652. * any necessary responses that must be sent back to the requesting node.
  1653. */
  1654. void CRegistry::ProcessDeleteEntryPDU (
  1655. CRegKeyContainer *registry_key_data,
  1656. UserID requester_node_id,
  1657. EntityID requester_entity_id)
  1658. {
  1659. REG_ENTRY *registry_entry;
  1660. BOOL application_is_enrolled = FALSE;
  1661. CAppRosterMgr *lpAppRosterMgr;
  1662. /*
  1663. ** We first make sure that this request is comming from an APE that
  1664. ** previously enrolled. Here we are not worried about a specific
  1665. ** session, only that the APE is enrolled.
  1666. */
  1667. m_pAppRosterMgrList->Reset();
  1668. while (NULL != (lpAppRosterMgr = m_pAppRosterMgrList->Iterate()))
  1669. {
  1670. if (lpAppRosterMgr->IsAPEEnrolled (requester_node_id, requester_entity_id))
  1671. {
  1672. application_is_enrolled = TRUE;
  1673. break;
  1674. }
  1675. }
  1676. if (application_is_enrolled)
  1677. {
  1678. /*
  1679. ** First check to see if the registry entry exists and if it does
  1680. ** check the ownership to make sure this node has permission to
  1681. ** change the entry.
  1682. */
  1683. registry_entry = GetRegistryEntry ( registry_key_data );
  1684. if (registry_entry != NULL)
  1685. {
  1686. if (((registry_entry->owner_id == requester_node_id) &&
  1687. (registry_entry->entity_id == requester_entity_id)) ||
  1688. (registry_entry->owner_id == NULL))
  1689. {
  1690. m_pMCSUserObject->RegistryResponse(
  1691. DELETE_ENTRY,
  1692. requester_node_id,
  1693. requester_entity_id,
  1694. registry_key_data,
  1695. registry_entry->entry_item,
  1696. registry_entry->modification_rights,
  1697. registry_entry->owner_id,
  1698. registry_entry->entity_id,
  1699. GCC_RESULT_SUCCESSFUL);
  1700. /*
  1701. ** First convert this to a non-entry incase it needs to
  1702. ** be included in a monitor indication. We first delete
  1703. ** the old entry item and replace it with an Emtpy item.
  1704. */
  1705. if (NULL != registry_entry->entry_item)
  1706. {
  1707. registry_entry->entry_item->Release();
  1708. }
  1709. registry_entry->entry_item = m_pEmptyRegItem;
  1710. registry_entry->owner_id = 0;
  1711. registry_entry->entity_id = 0;
  1712. registry_entry->modification_rights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
  1713. // Send Monitor Indication if necessary
  1714. if (registry_entry->monitoring_state == ON)
  1715. {
  1716. /*
  1717. ** Deliver the monitor indication to the Top
  1718. ** Provider's Node Controller if necessary.
  1719. */
  1720. SendMonitorEntryIndicationMessage(registry_entry);
  1721. /*
  1722. ** Broadcast a monitor entry indication to all
  1723. ** nodes in the conference.
  1724. */
  1725. m_pMCSUserObject->RegistryMonitorEntryIndication(
  1726. registry_entry->registry_key,
  1727. registry_entry->entry_item,
  1728. registry_entry->owner_id,
  1729. registry_entry->entity_id,
  1730. registry_entry->modification_rights);
  1731. }
  1732. // Remove the entry from the list
  1733. m_RegEntryList.Remove(registry_entry);
  1734. if (NULL != registry_entry->registry_key)
  1735. {
  1736. registry_entry->registry_key->Release();
  1737. }
  1738. delete registry_entry;
  1739. }
  1740. else
  1741. {
  1742. // No ownership rights send back negative result
  1743. m_pMCSUserObject->RegistryResponse(
  1744. DELETE_ENTRY,
  1745. requester_node_id,
  1746. requester_entity_id,
  1747. registry_key_data,
  1748. registry_entry->entry_item,
  1749. registry_entry->modification_rights,
  1750. registry_entry->owner_id,
  1751. registry_entry->entity_id,
  1752. GCC_RESULT_INDEX_ALREADY_OWNED);
  1753. }
  1754. }
  1755. else
  1756. {
  1757. // Send failure for the result. Entry does not exist
  1758. m_pMCSUserObject->RegistryResponse(
  1759. DELETE_ENTRY,
  1760. requester_node_id,
  1761. requester_entity_id,
  1762. registry_key_data,
  1763. m_pEmptyRegItem,
  1764. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1765. 0,
  1766. 0,
  1767. GCC_RESULT_ENTRY_DOES_NOT_EXIST);
  1768. }
  1769. }
  1770. else
  1771. {
  1772. m_pMCSUserObject->RegistryResponse(
  1773. DELETE_ENTRY,
  1774. requester_node_id,
  1775. requester_entity_id,
  1776. registry_key_data,
  1777. NULL,
  1778. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1779. 0,
  1780. 0,
  1781. GCC_RESULT_INVALID_REQUESTER);
  1782. }
  1783. }
  1784. /*
  1785. * void ProcessMonitorEntryPDU ()
  1786. *
  1787. * Public Function Description
  1788. * This routine is used by the top provider node to process an incomming
  1789. * request to monitor a registry entry. It is responsible for returning
  1790. * any necessary responses that must be sent back to the requesting node.
  1791. */
  1792. void CRegistry::ProcessMonitorEntryPDU (
  1793. CRegKeyContainer *registry_key_data,
  1794. UserID requester_node_id,
  1795. EntityID requester_entity_id )
  1796. {
  1797. REG_ENTRY *registry_entry;
  1798. /*
  1799. ** First check to see if the registry entry exists and if it does
  1800. ** check the ownership to make sure this node has permission to
  1801. ** change the entry.
  1802. */
  1803. registry_entry = GetRegistryEntry ( registry_key_data );
  1804. if (registry_entry != NULL)
  1805. {
  1806. // Set the monitoring state to on for the life of this entry.
  1807. registry_entry->monitoring_state = ON;
  1808. // No ownership rights send back negative result
  1809. m_pMCSUserObject->RegistryResponse(MONITOR_ENTRY,
  1810. requester_node_id,
  1811. requester_entity_id,
  1812. registry_key_data,
  1813. registry_entry->entry_item,
  1814. registry_entry->modification_rights,
  1815. registry_entry->owner_id,
  1816. registry_entry->entity_id,
  1817. GCC_RESULT_SUCCESSFUL);
  1818. }
  1819. else
  1820. {
  1821. // Send failure for the result. Entry does not exist
  1822. m_pMCSUserObject->RegistryResponse(MONITOR_ENTRY,
  1823. requester_node_id,
  1824. requester_entity_id,
  1825. registry_key_data,
  1826. m_pEmptyRegItem,
  1827. GCC_NO_MODIFICATION_RIGHTS_SPECIFIED,
  1828. 0,
  1829. 0,
  1830. GCC_RESULT_ENTRY_DOES_NOT_EXIST);
  1831. }
  1832. }
  1833. /*
  1834. * void ProcessRegistryResponsePDU ()
  1835. *
  1836. * Public Function Description
  1837. * This routine is used by nodes other than the top provider node to
  1838. * process registry responses from the top provider. It is responsible for
  1839. * generating any local messages associated with this response.
  1840. */
  1841. void CRegistry::ProcessRegistryResponsePDU (
  1842. RegistryResponsePrimitiveType primitive_type,
  1843. CRegKeyContainer *registry_key_data,
  1844. CRegItem *registry_item_data,
  1845. GCCModificationRights modification_rights,
  1846. EntityID requester_entity_id,
  1847. UserID owner_node_id,
  1848. EntityID owner_entity_id,
  1849. GCCResult result)
  1850. {
  1851. GCCError error_value = GCC_NO_ERROR;
  1852. GCCMessageType message_type;
  1853. CAppSap *pAppSap;
  1854. // Pop the next outstanding request off the queue
  1855. if (NULL != (pAppSap = m_AppSapEidList2.Find(requester_entity_id)))
  1856. {
  1857. switch (primitive_type)
  1858. {
  1859. case REGISTER_CHANNEL:
  1860. message_type = GCC_REGISTER_CHANNEL_CONFIRM;
  1861. break;
  1862. case ASSIGN_TOKEN:
  1863. message_type = GCC_ASSIGN_TOKEN_CONFIRM;
  1864. break;
  1865. case SET_PARAMETER:
  1866. message_type = GCC_SET_PARAMETER_CONFIRM;
  1867. break;
  1868. case RETRIEVE_ENTRY:
  1869. message_type = GCC_RETRIEVE_ENTRY_CONFIRM;
  1870. break;
  1871. case DELETE_ENTRY:
  1872. message_type = GCC_DELETE_ENTRY_CONFIRM;
  1873. break;
  1874. case MONITOR_ENTRY:
  1875. message_type = GCC_MONITOR_CONFIRM;
  1876. /*
  1877. ** Here we must check the result. If the result failed
  1878. ** we pull the monitoring SAP from the monitor list.
  1879. */
  1880. if (result != GCC_RESULT_SUCCESSFUL)
  1881. {
  1882. RemoveAPEFromMonitoringList ( registry_key_data,
  1883. requester_entity_id);
  1884. }
  1885. break;
  1886. default:
  1887. error_value = GCC_INVALID_PARAMETER;
  1888. ERROR_OUT(("CRegistry::ProcessRegistryResponsePDU: Bad request type, primitive_type=%d", (UINT) primitive_type));
  1889. break;
  1890. }
  1891. if (error_value == GCC_NO_ERROR)
  1892. {
  1893. /*
  1894. ** Note the the monitor enable variable is always set to TRUE
  1895. ** when a monitor response is received from the Top Provider.
  1896. ** Otherwise, this is not even used.
  1897. */
  1898. pAppSap->RegistryConfirm(m_nConfID,
  1899. message_type,
  1900. registry_key_data,
  1901. registry_item_data,
  1902. modification_rights,
  1903. owner_node_id,
  1904. owner_entity_id,
  1905. TRUE,
  1906. result);
  1907. }
  1908. }
  1909. else
  1910. {
  1911. WARNING_OUT(("CRegistry::ProcessRegistryResponsePDU: no such app sap"));
  1912. }
  1913. }
  1914. /*
  1915. * void ProcessMonitorIndicationPDU ()
  1916. *
  1917. * Public Function Description
  1918. * This routine is used by nodes other than the top provider node to
  1919. * process registry monitor indications from the top provider. It is
  1920. * responsible for generating any local messages associated with this
  1921. * response.
  1922. */
  1923. void CRegistry::ProcessMonitorIndicationPDU (
  1924. CRegKeyContainer *registry_key_data,
  1925. CRegItem *registry_item_data,
  1926. GCCModificationRights modification_rights,
  1927. UserID owner_node_id,
  1928. EntityID owner_entity_id)
  1929. {
  1930. REG_ENTRY *lpRegEntry;
  1931. EntityID eid;
  1932. CAppSap *pAppSap;
  1933. m_RegEntryList.Reset();
  1934. while (NULL != (lpRegEntry = m_RegEntryList.Iterate()))
  1935. {
  1936. if (*registry_key_data == *lpRegEntry->registry_key)
  1937. {
  1938. lpRegEntry->monitoring_list.Reset();
  1939. while (GCC_INVALID_EID != (eid = lpRegEntry->monitoring_list.Iterate()))
  1940. {
  1941. if (NULL != (pAppSap = m_AppSapEidList2.Find(eid)))
  1942. {
  1943. pAppSap->RegistryMonitorIndication(m_nConfID,
  1944. registry_key_data,
  1945. registry_item_data,
  1946. modification_rights,
  1947. owner_node_id,
  1948. owner_entity_id);
  1949. }
  1950. }
  1951. }
  1952. }
  1953. }
  1954. /*
  1955. * void ProcessAllocateHandleRequestPDU ()
  1956. *
  1957. * Public Function Description
  1958. * This routine is used by the top provider node to process an incomming
  1959. * request to allocate a number of handles. It is responsible for
  1960. * returning any necessary responses that must be sent back to the
  1961. * requesting node.
  1962. */
  1963. void CRegistry::ProcessAllocateHandleRequestPDU (
  1964. UINT number_of_handles,
  1965. EntityID requester_entity_id,
  1966. UserID requester_node_id)
  1967. {
  1968. UINT temp_registry_handle;
  1969. if (m_fTopProvider)
  1970. {
  1971. if ((number_of_handles > 0) &&
  1972. (number_of_handles <= MAXIMUM_ALLOWABLE_ALLOCATED_HANDLES))
  1973. {
  1974. temp_registry_handle = m_nRegHandle + number_of_handles;
  1975. if (temp_registry_handle > m_nRegHandle)
  1976. {
  1977. m_pMCSUserObject->RegistryAllocateHandleResponse(
  1978. number_of_handles,
  1979. m_nRegHandle,
  1980. requester_entity_id,
  1981. requester_node_id,
  1982. GCC_RESULT_SUCCESSFUL);
  1983. m_nRegHandle = temp_registry_handle;
  1984. }
  1985. else
  1986. {
  1987. m_pMCSUserObject->RegistryAllocateHandleResponse(
  1988. number_of_handles,
  1989. 0,
  1990. requester_entity_id,
  1991. requester_node_id,
  1992. GCC_RESULT_NO_HANDLES_AVAILABLE);
  1993. }
  1994. }
  1995. else
  1996. {
  1997. m_pMCSUserObject->RegistryAllocateHandleResponse(
  1998. number_of_handles,
  1999. 0,
  2000. requester_entity_id,
  2001. requester_node_id,
  2002. GCC_RESULT_INVALID_NUMBER_OF_HANDLES);
  2003. }
  2004. }
  2005. }
  2006. /*
  2007. * void ProcessAllocateHandleResponsePDU ()
  2008. *
  2009. * Public Function Description
  2010. * This routine is used by a node other than the top provider node to
  2011. * process an allocate handle response. It is responsible for generating
  2012. * any local messages associated with this response.
  2013. */
  2014. void CRegistry::ProcessAllocateHandleResponsePDU (
  2015. UINT number_of_handles,
  2016. UINT first_handle,
  2017. EntityID eidRequester,
  2018. GCCResult result)
  2019. {
  2020. CAppSap *pAppSap;
  2021. if (NULL != (pAppSap = m_AppSapEidList2.Find(eidRequester)))
  2022. {
  2023. pAppSap->RegistryAllocateHandleConfirm(m_nConfID,
  2024. number_of_handles,
  2025. first_handle,
  2026. result);
  2027. }
  2028. }
  2029. /*
  2030. * void RemoveNodeOwnership ()
  2031. *
  2032. * Public Function Description
  2033. * This routine removes ownership of all the registry entries associated
  2034. * with the specified node ID. These entries become unowned. This request
  2035. * should only be made from the top provider node. This is a local
  2036. * operation.
  2037. */
  2038. void CRegistry::RemoveNodeOwnership (
  2039. UserID node_id )
  2040. {
  2041. if (m_fTopProvider)
  2042. {
  2043. REG_ENTRY *lpRegEntry;
  2044. m_RegEntryList.Reset();
  2045. while (NULL != (lpRegEntry = m_RegEntryList.Iterate()))
  2046. {
  2047. if (lpRegEntry->owner_id == node_id)
  2048. {
  2049. lpRegEntry->owner_id = 0;
  2050. lpRegEntry->entity_id = 0;
  2051. // Send Monitor Indication if necessary
  2052. if (lpRegEntry->monitoring_state == ON)
  2053. {
  2054. /*
  2055. ** Deliver the monitor indication to the Top
  2056. ** Provider's Node Controller if necessary.
  2057. */
  2058. SendMonitorEntryIndicationMessage (lpRegEntry);
  2059. m_pMCSUserObject->RegistryMonitorEntryIndication(
  2060. lpRegEntry->registry_key,
  2061. lpRegEntry->entry_item,
  2062. lpRegEntry->owner_id,
  2063. lpRegEntry->entity_id,
  2064. lpRegEntry->modification_rights);
  2065. }
  2066. }
  2067. }
  2068. }
  2069. }
  2070. /*
  2071. * void RemoveEntityOwnership ()
  2072. *
  2073. * Public Function Description
  2074. * This routine removes ownership of all the registry entries associated
  2075. * with the specified APE. These entries become unowned. This request
  2076. * should only be made from the top provider node. This is a local
  2077. * operation.
  2078. */
  2079. void CRegistry::RemoveEntityOwnership (
  2080. UserID node_id,
  2081. EntityID entity_id )
  2082. {
  2083. if (m_fTopProvider)
  2084. {
  2085. REG_ENTRY *lpRegEntry;
  2086. m_RegEntryList.Reset();
  2087. while (NULL != (lpRegEntry = m_RegEntryList.Iterate()))
  2088. {
  2089. if ((lpRegEntry->owner_id == node_id) &&
  2090. (lpRegEntry->entity_id == entity_id))
  2091. {
  2092. lpRegEntry->owner_id = 0;
  2093. lpRegEntry->entity_id = 0;
  2094. // Send Monitor Indication if necessary
  2095. if (lpRegEntry->monitoring_state == ON)
  2096. {
  2097. /*
  2098. ** Deliver the monitor indication to the Top
  2099. ** Provider's Node Controller if necessary.
  2100. */
  2101. SendMonitorEntryIndicationMessage(lpRegEntry);
  2102. m_pMCSUserObject->RegistryMonitorEntryIndication(
  2103. lpRegEntry->registry_key,
  2104. lpRegEntry->entry_item,
  2105. lpRegEntry->owner_id,
  2106. lpRegEntry->entity_id,
  2107. lpRegEntry->modification_rights);
  2108. }
  2109. }
  2110. }
  2111. }
  2112. }
  2113. /*
  2114. * void RemoveSessionKeyReference ()
  2115. *
  2116. * Public Function Description
  2117. * This routine removes all registry entries associated with the
  2118. * specified session. This is a local operation.
  2119. */
  2120. void CRegistry::RemoveSessionKeyReference(CSessKeyContainer *session_key)
  2121. {
  2122. BOOL keys_match;
  2123. CRegKeyContainer *registry_key_data;
  2124. if (m_fTopProvider)
  2125. {
  2126. /*
  2127. ** This outer loop is to handle resetting the rogue wave iterator.
  2128. ** You can not delete a list entry while in the iterator with out
  2129. ** resetting it.
  2130. */
  2131. while (1)
  2132. {
  2133. REG_ENTRY *lpRegEntry;
  2134. keys_match = FALSE;
  2135. m_RegEntryList.Reset();
  2136. while (NULL != (lpRegEntry= m_RegEntryList.Iterate()))
  2137. {
  2138. registry_key_data = lpRegEntry->registry_key;
  2139. if (registry_key_data->IsThisYourSessionKey (session_key))
  2140. keys_match = TRUE;
  2141. if (keys_match)
  2142. {
  2143. /*
  2144. ** First convert this to a non-entry incase it needs to
  2145. ** be included in a monitor indication. We first delete
  2146. ** the old entry item and replace it with an Emtpy item.
  2147. */
  2148. if (NULL != lpRegEntry->entry_item)
  2149. {
  2150. lpRegEntry->entry_item->Release();
  2151. }
  2152. lpRegEntry->entry_item = m_pEmptyRegItem;
  2153. lpRegEntry->owner_id = 0;
  2154. lpRegEntry->entity_id = 0;
  2155. lpRegEntry->modification_rights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
  2156. // Send Monitor Indication if necessary
  2157. if (lpRegEntry->monitoring_state == ON)
  2158. {
  2159. /*
  2160. ** Deliver the monitor indication to the Top
  2161. ** Provider's Node Controller if necessary.
  2162. */
  2163. SendMonitorEntryIndicationMessage(lpRegEntry);
  2164. /*
  2165. ** Broadcast a monitor entry indication to all
  2166. ** nodes in the conference.
  2167. */
  2168. m_pMCSUserObject->RegistryMonitorEntryIndication(
  2169. lpRegEntry->registry_key,
  2170. lpRegEntry->entry_item,
  2171. lpRegEntry->owner_id,
  2172. lpRegEntry->entity_id,
  2173. lpRegEntry->modification_rights);
  2174. }
  2175. if (NULL != lpRegEntry->registry_key)
  2176. {
  2177. lpRegEntry->registry_key->Release();
  2178. }
  2179. m_RegEntryList.Remove(lpRegEntry);
  2180. delete lpRegEntry;
  2181. break;
  2182. }
  2183. }
  2184. if (keys_match == FALSE)
  2185. break;
  2186. }
  2187. }
  2188. }
  2189. /*
  2190. * REG_ENTRY *GetRegistryEntry ()
  2191. *
  2192. * Private Function Description
  2193. * This routine is responsible for searching the registry list for
  2194. * the registry entry specified by the passed in registry key. NULL
  2195. * is returned if the entry can not be found.
  2196. *
  2197. * Formal Parameters:
  2198. * registry_key_data - (i) Registry key associated with entry to get.
  2199. *
  2200. * Return Value
  2201. * Pointer to the registry item assoicated with the specified registry
  2202. * key. NULL if it does not exists.
  2203. *
  2204. * Side Effects
  2205. * None.
  2206. *
  2207. * Caveats
  2208. * None.
  2209. */
  2210. REG_ENTRY *CRegistry::GetRegistryEntry(CRegKeyContainer *registry_key_data)
  2211. {
  2212. REG_ENTRY *registry_entry = NULL;
  2213. REG_ENTRY *lpRegEntry;
  2214. m_RegEntryList.Reset();
  2215. while (NULL != (lpRegEntry = m_RegEntryList.Iterate()))
  2216. {
  2217. if (*lpRegEntry->registry_key == *registry_key_data)
  2218. {
  2219. registry_entry = lpRegEntry;
  2220. break;
  2221. }
  2222. }
  2223. return (registry_entry);
  2224. }
  2225. /*
  2226. * TokenID GetUnusedToken ()
  2227. *
  2228. * Private Function Description
  2229. * This routine is responsible for generating an unused token. The routine
  2230. * will return a token ID of zero if all are used up (this is very
  2231. * unlikely).
  2232. *
  2233. * Formal Parameters:
  2234. * None.
  2235. *
  2236. * Return Value
  2237. * The generated token ID. Zero if no token IDs are available.
  2238. *
  2239. * Side Effects
  2240. * None.
  2241. *
  2242. * Caveats
  2243. * None.
  2244. */
  2245. TokenID CRegistry::GetUnusedToken ()
  2246. {
  2247. TokenID token_id = 0;
  2248. CRegItem *registry_item_data;
  2249. REG_ENTRY *lpRegEntry;
  2250. while (token_id == 0)
  2251. {
  2252. token_id = m_nCurrentTokenID;
  2253. m_nCurrentTokenID++;
  2254. if (m_nCurrentTokenID == (TokenID)0xffff)
  2255. {
  2256. m_nCurrentTokenID = (TokenID)16384;
  2257. }
  2258. m_RegEntryList.Reset();
  2259. while (NULL != (lpRegEntry = m_RegEntryList.Iterate()))
  2260. {
  2261. registry_item_data = lpRegEntry->entry_item;
  2262. if (registry_item_data->IsThisYourTokenID(token_id))
  2263. {
  2264. token_id = 0;
  2265. break;
  2266. }
  2267. }
  2268. }
  2269. return (token_id);
  2270. }
  2271. /*
  2272. * GCCError AddAPEToMonitoringList ()
  2273. *
  2274. * Private Function Description
  2275. * This routine is used to add a new APE to the monitoring list.
  2276. *
  2277. * Formal Parameters:
  2278. * registry_key_data - (i) Registry key associated with entry being
  2279. * monitored.
  2280. * entity_id - (i) Entity ID associated with the APE that is
  2281. * doing the monitoring.
  2282. * requester_sap - (i) Pointer to the command target associated
  2283. * with APE making the request.
  2284. *
  2285. * Return Value
  2286. * GCC_NO_ERROR - No error occured.
  2287. * GCC_ALLOCATION_FAILURE - A resource error occured.
  2288. *
  2289. * Side Effects
  2290. * None.
  2291. *
  2292. * Caveats
  2293. * None.
  2294. */
  2295. GCCError CRegistry::AddAPEToMonitoringList(
  2296. CRegKeyContainer *registry_key_data,
  2297. EntityID entity_id,
  2298. CAppSap *requester_sap)
  2299. {
  2300. GCCError rc = GCC_NO_ERROR;
  2301. REG_ENTRY *registry_entry;
  2302. BOOL entry_does_exists;
  2303. GCCRegistryItem registry_item;
  2304. registry_entry = GetRegistryEntry (registry_key_data);
  2305. /*
  2306. ** If the registry does not exists we go ahead and create an empty
  2307. ** entry here.
  2308. */
  2309. if (registry_entry == NULL)
  2310. {
  2311. DBG_SAVE_FILE_LINE
  2312. registry_entry = new REG_ENTRY;
  2313. if (registry_entry != NULL)
  2314. {
  2315. // First allocate an empty registry item
  2316. registry_item.item_type = GCC_REGISTRY_NONE;
  2317. DBG_SAVE_FILE_LINE
  2318. registry_entry->entry_item = new CRegItem(&registry_item, &rc);
  2319. if ((registry_entry->entry_item != NULL) && (rc == GCC_NO_ERROR))
  2320. {
  2321. // Next allocate the registry key
  2322. DBG_SAVE_FILE_LINE
  2323. registry_entry->registry_key = new CRegKeyContainer(registry_key_data, &rc);
  2324. if ((registry_entry->registry_key != NULL) && (rc == GCC_NO_ERROR))
  2325. {
  2326. /*
  2327. ** If everything is OK up to here we go ahead and add the
  2328. ** registry entry to the local entry list.
  2329. */
  2330. m_RegEntryList.Append(registry_entry);
  2331. }
  2332. else if (registry_entry->registry_key == NULL)
  2333. {
  2334. rc = GCC_ALLOCATION_FAILURE;
  2335. registry_entry->entry_item->Release();
  2336. }
  2337. else
  2338. {
  2339. registry_entry->registry_key->Release();
  2340. registry_entry->entry_item->Release();
  2341. }
  2342. }
  2343. else if (registry_entry->entry_item == NULL)
  2344. {
  2345. rc = GCC_ALLOCATION_FAILURE;
  2346. }
  2347. else
  2348. {
  2349. registry_entry->entry_item->Release();
  2350. }
  2351. if (rc != GCC_NO_ERROR)
  2352. {
  2353. delete registry_entry;
  2354. }
  2355. }
  2356. else
  2357. {
  2358. rc = GCC_ALLOCATION_FAILURE;
  2359. }
  2360. }
  2361. if (rc == GCC_NO_ERROR)
  2362. {
  2363. m_AppSapEidList2.Append(entity_id, requester_sap);
  2364. /*
  2365. ** Make sure that this entry does not already exists in the
  2366. ** monitoring list.
  2367. */
  2368. EntityID eid;
  2369. registry_entry->monitoring_list.Reset();
  2370. entry_does_exists = FALSE;
  2371. while (GCC_INVALID_EID != (eid = registry_entry->monitoring_list.Iterate()))
  2372. {
  2373. if (eid == entity_id)
  2374. {
  2375. entry_does_exists = TRUE;
  2376. break;
  2377. }
  2378. }
  2379. if (entry_does_exists == FALSE)
  2380. {
  2381. registry_entry->monitoring_list.Append(entity_id);
  2382. }
  2383. }
  2384. return rc;
  2385. }
  2386. /*
  2387. * void RemoveAPEFromMonitoringList ()
  2388. *
  2389. * Private Function Description
  2390. * This routine is used to remove an APE from the monitoring list.
  2391. *
  2392. * Formal Parameters:
  2393. * registry_key_data - (i) Registry key associated with entry being
  2394. * monitored.
  2395. * entity_id - (i) Entity ID associated with the APE that is
  2396. * being removed from the monitoring list.
  2397. *
  2398. * Return Value
  2399. * None.
  2400. *
  2401. * Side Effects
  2402. * None.
  2403. *
  2404. * Caveats
  2405. * None.
  2406. */
  2407. void CRegistry::RemoveAPEFromMonitoringList(
  2408. CRegKeyContainer *registry_key_data,
  2409. EntityID entity_id)
  2410. {
  2411. REG_ENTRY *registry_entry;
  2412. registry_entry = GetRegistryEntry (registry_key_data);
  2413. if (registry_entry != NULL)
  2414. {
  2415. /*
  2416. ** Make sure that this entry does not already exists in the
  2417. ** monitoring list.
  2418. */
  2419. registry_entry->monitoring_list.Remove(entity_id);
  2420. }
  2421. }
  2422. /*
  2423. * void SendMonitorEntryIndicationMessage ()
  2424. *
  2425. * Private Function Description
  2426. * This routine is used to generate a monitor indication to all the
  2427. * APEs that are currently monitoring the specified registry entry.
  2428. *
  2429. * Formal Parameters:
  2430. * registry_entry - (i) Pointer to the registry entry being monitored.
  2431. *
  2432. * Return Value
  2433. * None.
  2434. *
  2435. * Side Effects
  2436. * None.
  2437. *
  2438. * Caveats
  2439. * None.
  2440. */
  2441. void CRegistry::SendMonitorEntryIndicationMessage(REG_ENTRY *registry_entry)
  2442. {
  2443. EntityID eid;
  2444. CAppSap *pAppSap;
  2445. registry_entry->monitoring_list.Reset();
  2446. while (GCC_INVALID_EID != (eid = registry_entry->monitoring_list.Iterate()))
  2447. {
  2448. if (NULL != (pAppSap = m_AppSapEidList2.Find(eid)))
  2449. {
  2450. pAppSap->RegistryMonitorIndication(
  2451. m_nConfID,
  2452. registry_entry->registry_key,
  2453. registry_entry->entry_item,
  2454. registry_entry->modification_rights,
  2455. registry_entry->owner_id,
  2456. registry_entry->entity_id);
  2457. }
  2458. }
  2459. }