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.

964 lines
27 KiB

  1. #include "precomp.h"
  2. #include "fsdiag.h"
  3. DEBUG_FILEZONE(ZONE_T120_GCCNC);
  4. /*
  5. * userdata.cpp
  6. *
  7. * Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
  8. *
  9. * Abstract:
  10. * This is the implementation file for the class CUserDataListContainer. CUserDataListContainer
  11. * objects are used to maintain user data elements. A user data element
  12. * consists of an Object Key and an optional octet string. The Object
  13. * Key data is maintained internally by this class by using an
  14. * CObjectKeyContainer container. The optional octet string data is maintained
  15. * internally through the use of a Rogue Wave string container.
  16. *
  17. * Protected Instance Variables:
  18. * m_UserDataItemList
  19. * List of structures used to hold the user data internally.
  20. * m_pSetOfUserDataPDU
  21. * Storage for the "PDU" form of the user data.
  22. * m_cbDataSize
  23. * Variable holding the size of the memory which will be required to
  24. * hold any data referenced by the "API" GCCUserData structure.
  25. *
  26. * Caveats:
  27. * None.
  28. *
  29. * Author:
  30. * jbo
  31. */
  32. #include "userdata.h"
  33. #include "clists.h"
  34. USER_DATA::~USER_DATA(void)
  35. {
  36. if (NULL != key)
  37. {
  38. key->Release();
  39. }
  40. delete poszOctetString;
  41. }
  42. /*
  43. * CUserDataListContainer()
  44. *
  45. * Public Function Description
  46. * This CUserDataListContainer constructor is used to create a CUserDataListContainer object
  47. * from "API" data. The constructor immediately copies the user data
  48. * passed in as a list of "GCCUserData" structures into it's internal form
  49. * where a Rogue Wave container holds the data in the form of
  50. * USER_DATA structures.
  51. */
  52. CUserDataListContainer::
  53. CUserDataListContainer(UINT cMembers, PGCCUserData *user_data_list, PGCCError pRetCode)
  54. :
  55. CRefCount(MAKE_STAMP_ID('U','r','D','L')),
  56. m_UserDataItemList(DESIRED_MAX_USER_DATA_ITEMS),
  57. m_cbDataSize(0),
  58. m_pSetOfUserDataPDU(NULL)
  59. {
  60. /*
  61. * Copy the user data into the internal structures.
  62. */
  63. *pRetCode = CopyUserDataList(cMembers, user_data_list);
  64. }
  65. /*
  66. * CUserDataListContainer()
  67. *
  68. * Public Function Description
  69. * This CUserDataListContainer constructor is used to create a CUserDataListContainer object
  70. * from data passed in as a "PDU" SetOfUserData structure. The user
  71. * data is copied into it's internal form where a Rogue Wave container
  72. * holds the data in the form of USER_DATA structures.
  73. */
  74. CUserDataListContainer::
  75. CUserDataListContainer(PSetOfUserData set_of_user_data, PGCCError pRetCode)
  76. :
  77. CRefCount(MAKE_STAMP_ID('U','r','D','L')),
  78. m_UserDataItemList(DESIRED_MAX_USER_DATA_ITEMS),
  79. m_cbDataSize(0),
  80. m_pSetOfUserDataPDU(NULL)
  81. {
  82. /*
  83. * Copy the user data into the internal structures.
  84. */
  85. *pRetCode = UnPackUserDataFromPDU(set_of_user_data);
  86. }
  87. /*
  88. * CUserDataListContainer()
  89. *
  90. * Public Function Description
  91. * This CUserDataListContainer copy constructor is used to create a CUserDataListContainer
  92. * object from another CUserDataListContainer object. The constructor immediately
  93. * copies the user data passed in into it's internal form where a Rogue
  94. * Wave list holds the data in the form of USER_DATA structures.
  95. */
  96. CUserDataListContainer::
  97. CUserDataListContainer(CUserDataListContainer *user_data_list, PGCCError pRetCode)
  98. :
  99. CRefCount(MAKE_STAMP_ID('U','r','D','L')),
  100. m_UserDataItemList(DESIRED_MAX_USER_DATA_ITEMS),
  101. m_cbDataSize(0),
  102. m_pSetOfUserDataPDU(NULL)
  103. {
  104. GCCError rc;
  105. USER_DATA *user_data_info_ptr;
  106. USER_DATA *lpUsrDataInfo;
  107. /*
  108. * Set up an iterator for the internal list of "info" structures in the
  109. * CUserDataListContainer object to be copied.
  110. */
  111. user_data_list->m_UserDataItemList.Reset();
  112. /*
  113. * Copy each USER_DATA structure contained in the CUserDataListContainer object to
  114. * be copied.
  115. */
  116. while (NULL != (lpUsrDataInfo = user_data_list->m_UserDataItemList.Iterate()))
  117. {
  118. /*
  119. * Create a new USER_DATA structure to hold each element of the new
  120. * CUserDataListContainer object. Report an error if creation of this structure
  121. * fails.
  122. */
  123. DBG_SAVE_FILE_LINE
  124. user_data_info_ptr = new USER_DATA;
  125. if (user_data_info_ptr != NULL)
  126. {
  127. user_data_info_ptr->poszOctetString = NULL;
  128. /*
  129. * Go ahead and insert the pointer to the USER_DATA structure
  130. * into the internal Rogue Wave list.
  131. */
  132. m_UserDataItemList.Append(user_data_info_ptr);
  133. /*
  134. * Create a new CObjectKeyContainer object to hold the "key" using the
  135. * copy constructor for the CObjectKeyContainer class. Check to be sure
  136. * construction of the object is successful. Note that validation
  137. * of the object key data is not done here since this would be done
  138. * when the original CUserDataListContainer object was created.
  139. */
  140. DBG_SAVE_FILE_LINE
  141. user_data_info_ptr->key = new CObjectKeyContainer(lpUsrDataInfo->key, &rc);
  142. if ((NULL != user_data_info_ptr->key) && (GCC_NO_ERROR == rc))
  143. {
  144. /*
  145. * If an octet string exists, create a new Rogue Wave string to hold
  146. * the octet string portion of the "key" and copy the octet string
  147. * from the old CUserDataListContainer object into the new USER_DATA
  148. * structure.
  149. */
  150. if (lpUsrDataInfo->poszOctetString != NULL)
  151. {
  152. if (NULL == (user_data_info_ptr->poszOctetString =
  153. ::My_strdupO(lpUsrDataInfo->poszOctetString)))
  154. {
  155. ERROR_OUT(("UserData::UserData: can't create octet string"));
  156. rc = GCC_ALLOCATION_FAILURE;
  157. goto MyExit;
  158. }
  159. }
  160. else
  161. {
  162. ASSERT(NULL == user_data_info_ptr->poszOctetString);
  163. }
  164. }
  165. else
  166. {
  167. ERROR_OUT(("UserData::UserData: Error creating new ObjectKeyData"));
  168. rc = GCC_ALLOCATION_FAILURE;
  169. goto MyExit;
  170. }
  171. }
  172. else
  173. {
  174. ERROR_OUT(("UserData::UserData: can't create USER_DATA"));
  175. rc = GCC_ALLOCATION_FAILURE;
  176. goto MyExit;
  177. }
  178. }
  179. rc = GCC_NO_ERROR;
  180. MyExit:
  181. *pRetCode = rc;
  182. }
  183. /*
  184. * ~CUserDataListContainer()
  185. *
  186. * Public Function Description
  187. * This is the destructor for the CUserDataListContainer class. It is used to
  188. * clean up any memory allocated during the life of this object.
  189. */
  190. CUserDataListContainer::
  191. ~CUserDataListContainer(void)
  192. {
  193. /*
  194. * Free any PDU data which may have not been freed.
  195. */
  196. if (m_pSetOfUserDataPDU)
  197. {
  198. FreeUserDataListPDU();
  199. }
  200. /*
  201. * Set up an iterator to use for iterating through the internal Rogue
  202. * Wave list of USER_DATA structures.
  203. */
  204. USER_DATA *pUserDataItem;
  205. m_UserDataItemList.Reset();
  206. while (NULL != (pUserDataItem = m_UserDataItemList.Iterate()))
  207. {
  208. /*
  209. * Delete any memory being referenced in the USER_DATA structure.
  210. */
  211. delete pUserDataItem;
  212. }
  213. }
  214. /*
  215. * LockUserDataList ()
  216. *
  217. * Public Function Description:
  218. * This routine locks the user data list and determines the amount of
  219. * memory referenced by the "API" user data list structures.
  220. */
  221. UINT CUserDataListContainer::
  222. LockUserDataList(void)
  223. {
  224. /*
  225. * If this is the first time this routine is called, determine the size of
  226. * the memory required to hold the data. Otherwise, just increment the
  227. * lock count.
  228. */
  229. if (Lock() == 1)
  230. {
  231. USER_DATA *lpUsrDataInfo;
  232. /*
  233. * Set aside memory to hold the pointers to the GCCUserData structures
  234. * as well as the structures themselves. The "sizeof" the structure
  235. * must be rounded to an even four-byte boundary.
  236. */
  237. m_cbDataSize = m_UserDataItemList.GetCount() *
  238. (sizeof(PGCCUserData) + ROUNDTOBOUNDARY(sizeof(GCCUserData)) );
  239. m_UserDataItemList.Reset();
  240. while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
  241. {
  242. /*
  243. * Lock the data for the object keys, adding the amount of memory
  244. * necessary to hold the object key data to the total memory size.
  245. */
  246. m_cbDataSize += lpUsrDataInfo->key->LockObjectKeyData();
  247. /*
  248. * Check to see if this user data element contains the optional
  249. * user data octet string. Add the space to hold it if it exists.
  250. */
  251. if (lpUsrDataInfo->poszOctetString != NULL)
  252. {
  253. /*
  254. * Since the user data structure contains a pointer to a
  255. * OSTR structure, we must add the amount of memory
  256. * needed to hold the structure as well as the string data.
  257. */
  258. m_cbDataSize += ROUNDTOBOUNDARY(sizeof(OSTR));
  259. /*
  260. * The data referenced by the octet string is just the byte
  261. * length of the octet string.
  262. */
  263. m_cbDataSize += ROUNDTOBOUNDARY(lpUsrDataInfo->poszOctetString->length);
  264. }
  265. }
  266. }
  267. return m_cbDataSize;
  268. }
  269. /*
  270. * GetUserDataList ()
  271. *
  272. * Public Function Description:
  273. * This routine retrieves user data elements contained in the user data
  274. * object and returns them in the "API" form of a list of pointers to
  275. * "GCCUserData" structures. The number of user data elements contained
  276. * in this object is also returned.
  277. */
  278. UINT CUserDataListContainer::
  279. GetUserDataList(USHORT *number_of_members, PGCCUserData **user_data_list, LPBYTE memory)
  280. {
  281. UINT cbDataSizeToRet = 0;
  282. UINT data_length = 0;
  283. Int user_data_counter = 0;
  284. PGCCUserData user_data_ptr;
  285. /*
  286. * If the user data has been locked, fill in the output parameters and
  287. * the data referenced by the pointers. Otherwise, report that the object
  288. * has yet to be locked into the "API" form.
  289. */
  290. if (GetLockCount() > 0)
  291. {
  292. USER_DATA *lpUsrDataInfo;
  293. /*
  294. * Fill in the output length parameter which indicates how much data
  295. * referenced outside the structure will be written.
  296. */
  297. cbDataSizeToRet = m_cbDataSize;
  298. /*
  299. * Fill in the number of user data entities and save a pointer to the
  300. * memory location passed in. This is where the pointers to the
  301. * GCCUserData structures will be written. The actual structures will
  302. * be written into memory immediately following the list of pointers.
  303. */
  304. *number_of_members = (USHORT) m_UserDataItemList.GetCount();
  305. *user_data_list = (PGCCUserData *)memory;
  306. /*
  307. * Save the amount of memory needed to hold the list of pointers
  308. * as well as the actual user data structures.
  309. */
  310. data_length = m_UserDataItemList.GetCount() * sizeof(PGCCUserData);
  311. /*
  312. * Move the memory pointer past the list of user data pointers. This
  313. * is where the first user data structure will be written.
  314. */
  315. memory += data_length;
  316. /*
  317. * Iterate through the internal list of USER_DATA structures,
  318. * building "API" GCCUserData structures in memory.
  319. */
  320. m_UserDataItemList.Reset();
  321. while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
  322. {
  323. /*
  324. * Save the pointer to the user data structure in the list
  325. * of pointers.
  326. */
  327. user_data_ptr = (PGCCUserData)memory;
  328. (*user_data_list)[user_data_counter++] = user_data_ptr;
  329. /*
  330. * Move the memory pointer past the user data structure. This is
  331. * where the object key data and octet string data will be written.
  332. */
  333. memory += ROUNDTOBOUNDARY(sizeof(GCCUserData));
  334. /*
  335. * Fill in the user data structure starting with the object key.
  336. */
  337. data_length = lpUsrDataInfo->key->GetGCCObjectKeyData(&user_data_ptr->key, memory);
  338. /*
  339. * Move the memory pointer past the object key data. This is
  340. * where the octet string structure will be written, if it exists.
  341. * If the octet string does exist, save the memory pointer in the
  342. * user data structure's octet string pointer and fill in the
  343. * elements of the octet string structure. Otherwise, set the
  344. * octet string pointer to NULL.
  345. */
  346. memory += data_length;
  347. if (lpUsrDataInfo->poszOctetString == NULL)
  348. {
  349. user_data_ptr->octet_string = NULL;
  350. }
  351. else
  352. {
  353. user_data_ptr->octet_string = (LPOSTR) memory;
  354. /*
  355. * Move the memory pointer past the octet string structure.
  356. * This is where the actual string data for the octet string
  357. * will be written.
  358. */
  359. memory += ROUNDTOBOUNDARY(sizeof(OSTR));
  360. /*
  361. * Write the octet string data into memory and set the octet
  362. * string structure pointer and length.
  363. */
  364. user_data_ptr->octet_string->length =
  365. lpUsrDataInfo->poszOctetString->length;
  366. user_data_ptr->octet_string->value = (LPBYTE)memory;
  367. /*
  368. * Now copy the octet string data from the internal Rogue Wave
  369. * string into the object key structure held in memory.
  370. */
  371. ::CopyMemory(memory, lpUsrDataInfo->poszOctetString->value,
  372. lpUsrDataInfo->poszOctetString->length);
  373. /*
  374. * Move the memory pointer past the octet string data.
  375. */
  376. memory += ROUNDTOBOUNDARY(user_data_ptr->octet_string->length);
  377. }
  378. }
  379. }
  380. else
  381. {
  382. *user_data_list = NULL;
  383. *number_of_members = 0;
  384. ERROR_OUT(("CUserDataListContainer::GetUserDataList: Error Data Not Locked"));
  385. }
  386. return cbDataSizeToRet;
  387. }
  388. /*
  389. * UnLockUserDataList ()
  390. *
  391. * Public Function Description:
  392. * This routine is used to "unlock" the "API" data for this object. This
  393. * results in the lock count for this object being decremented. When the
  394. * lock count transitions from 1 to 0, a check is made to determine
  395. * whether the object has been freed through a call to
  396. * FreeUserDataList. If so, the object will automatically delete
  397. * itself.
  398. */
  399. void CUserDataListContainer::
  400. UnLockUserDataList(void)
  401. {
  402. USER_DATA *user_data_info_ptr;
  403. if (Unlock(FALSE) == 0)
  404. {
  405. /*
  406. * Unlock any memory locked for the CObjectKeyContainer objects in the
  407. * internal USER_DATA structures.
  408. */
  409. m_UserDataItemList.Reset();
  410. while (NULL != (user_data_info_ptr = m_UserDataItemList.Iterate()))
  411. {
  412. /*
  413. * Unlock any CObjectKeyContainer memory being referenced in the
  414. * USER_DATA structure.
  415. */
  416. if (user_data_info_ptr->key != NULL)
  417. {
  418. user_data_info_ptr->key->UnLockObjectKeyData ();
  419. }
  420. }
  421. }
  422. // we have to call Release() because we used Unlock(FALSE)
  423. Release();
  424. }
  425. /*
  426. * GetUserDataPDU ()
  427. *
  428. * Public Function Description:
  429. * This routine converts the user data from it's internal form of a list
  430. * of USER_DATA structures into the "PDU" form which can be passed in
  431. * to the ASN.1 encoder. A pointer to a "PDU" "SetOfUserData" structure is
  432. * returned.
  433. */
  434. GCCError CUserDataListContainer::
  435. GetUserDataPDU(PSetOfUserData *set_of_user_data)
  436. {
  437. GCCError rc = GCC_NO_ERROR;
  438. PSetOfUserData new_pdu_user_data_ptr;
  439. PSetOfUserData old_pdu_user_data_ptr = NULL;
  440. /*
  441. * If this is the first time that PDU data has been requested then we must
  442. * fill in the internal PDU structure and copy it into the structure pointed
  443. * to by the output parameter. On subsequent calls to "GetPDU" we can just
  444. * copy the internal PDU structure into the structure pointed to by the
  445. * output parameter.
  446. */
  447. if (NULL == m_pSetOfUserDataPDU)
  448. {
  449. USER_DATA *lpUsrDataInfo;
  450. /*
  451. * Iterate through the list of USER_DATA structures, converting
  452. * each into "PDU" form and saving the pointers in the linked list of
  453. * "SetsOfUserData".
  454. */
  455. m_UserDataItemList.Reset();
  456. while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
  457. {
  458. DBG_SAVE_FILE_LINE
  459. new_pdu_user_data_ptr = new SetOfUserData;
  460. /*
  461. * If an allocation failure occurs, call the routine which will
  462. * iterate through the list freeing any data which had been
  463. * allocated.
  464. */
  465. if (new_pdu_user_data_ptr == NULL)
  466. {
  467. ERROR_OUT(("CUserDataListContainer::GetUserDataPDU: Allocation error, cleaning up"));
  468. rc = GCC_ALLOCATION_FAILURE;
  469. break;
  470. }
  471. //
  472. // Ensure everything is clean.
  473. //
  474. ::ZeroMemory(new_pdu_user_data_ptr, sizeof(SetOfUserData));
  475. /*
  476. * The first time through, set the PDU structure pointer equal
  477. * to the first SetOfUserData created. On subsequent loops, set
  478. * the structure's "next" pointer equal to the new structure.
  479. */
  480. if (m_pSetOfUserDataPDU == NULL)
  481. {
  482. m_pSetOfUserDataPDU = new_pdu_user_data_ptr;
  483. }
  484. else
  485. {
  486. old_pdu_user_data_ptr->next = new_pdu_user_data_ptr;
  487. }
  488. old_pdu_user_data_ptr = new_pdu_user_data_ptr;
  489. /*
  490. * Initialize the new "next" pointer to NULL and convert the
  491. * user data element.
  492. */
  493. new_pdu_user_data_ptr->next = NULL;
  494. if (ConvertUserDataInfoToPDUUserData(lpUsrDataInfo, new_pdu_user_data_ptr) != GCC_NO_ERROR)
  495. {
  496. ERROR_OUT(("UserData::GetUserDataPDU: can't convert USER_DATA to PDU"));
  497. rc = GCC_ALLOCATION_FAILURE;
  498. break;
  499. }
  500. }
  501. if (GCC_NO_ERROR != rc)
  502. {
  503. FreeUserDataListPDU();
  504. ASSERT(NULL == m_pSetOfUserDataPDU);
  505. }
  506. }
  507. /*
  508. * Copy the internal PDU structure into the structure pointed to by the
  509. * output parameter.
  510. */
  511. *set_of_user_data = m_pSetOfUserDataPDU;
  512. return rc;
  513. }
  514. /*
  515. * FreeUserDataListPDU ()
  516. *
  517. * Public Function Description:
  518. * This routine frees any data which was allocated as a result of a call
  519. * to "GetUserDataPDU" which was called in order to build up a "PDU"
  520. * structure holding the user data.
  521. */
  522. void CUserDataListContainer::
  523. FreeUserDataListPDU(void)
  524. {
  525. PSetOfUserData pdu_user_data_set;
  526. PSetOfUserData next_pdu_user_data_set;
  527. USER_DATA *lpUsrDataInfo;
  528. /*
  529. * Check to make sure "PDU" data has been allocated for this object.
  530. */
  531. if (NULL != m_pSetOfUserDataPDU)
  532. {
  533. pdu_user_data_set = m_pSetOfUserDataPDU;
  534. m_pSetOfUserDataPDU = NULL; // so no one can use it now.
  535. /*
  536. * Loop through the list, freeing the user data associated with
  537. * each structure contained in the list.
  538. */
  539. while (pdu_user_data_set != NULL)
  540. {
  541. next_pdu_user_data_set = pdu_user_data_set->next;
  542. delete pdu_user_data_set;
  543. pdu_user_data_set = next_pdu_user_data_set;
  544. }
  545. }
  546. else
  547. {
  548. TRACE_OUT(("CUserDataListContainer::FreeUserDataListPDU: Error PDU data not allocated"));
  549. }
  550. /*
  551. * Iterate through the internal list, telling each CObjectKeyContainer object
  552. * to free any PDU data which it has allocated.
  553. */
  554. m_UserDataItemList.Reset();
  555. while (NULL != (lpUsrDataInfo = m_UserDataItemList.Iterate()))
  556. {
  557. if (lpUsrDataInfo->key != NULL)
  558. {
  559. lpUsrDataInfo->key->FreeObjectKeyDataPDU();
  560. }
  561. }
  562. }
  563. /*
  564. * GCCError CopyUserDataList ( UINT number_of_members,
  565. * PGCCUserData * user_data_list)
  566. *
  567. * Private member function of CUserDataListContainer.
  568. *
  569. * Function Description:
  570. * This routine copies the user data passed in as "API" data into it's
  571. * internal form where the Rogue Wave m_UserDataItemList holds the data
  572. * in the form of USER_DATA structures.
  573. *
  574. * Formal Parameters:
  575. * number_of_members (i) The number of elements in the user data list.
  576. * user_datalist (i) The list holding the user data to store.
  577. *
  578. * Return Value:
  579. * GCC_NO_ERROR - No error.
  580. * GCC_ALLOCATION_FAILURE - Error creating an object using the
  581. * "new" operator.
  582. * GCC_BAD_USER_DATA - The user data passed in contained
  583. * an invalid object key.
  584. *
  585. * Side Effects:
  586. * None.
  587. *
  588. * Caveats:
  589. * None.
  590. */
  591. GCCError CUserDataListContainer::
  592. CopyUserDataList(UINT number_of_members, PGCCUserData *user_data_list)
  593. {
  594. GCCError rc = GCC_NO_ERROR;
  595. USER_DATA *user_data_info_ptr;
  596. UINT i;
  597. LPOSTR octet_string_ptr;
  598. /*
  599. * Return an error if no user data is passed in.
  600. */
  601. if (number_of_members == 0)
  602. return (GCC_BAD_USER_DATA);
  603. for (i = 0; i < number_of_members; i++)
  604. {
  605. /*
  606. * Create a new "info" structure to hold the user data internally.
  607. */
  608. DBG_SAVE_FILE_LINE
  609. user_data_info_ptr = new USER_DATA;
  610. if (user_data_info_ptr != NULL)
  611. {
  612. user_data_info_ptr->poszOctetString = NULL;
  613. /*
  614. * Create a new CObjectKeyContainer object which will be used to store
  615. * the "key" portion of the object data internally.
  616. */
  617. DBG_SAVE_FILE_LINE
  618. user_data_info_ptr->key = new CObjectKeyContainer(&user_data_list[i]->key, &rc);
  619. if (user_data_info_ptr->key == NULL)
  620. {
  621. ERROR_OUT(("UserData::CopyUserDataList: Error creating new CObjectKeyContainer"));
  622. rc = GCC_ALLOCATION_FAILURE;
  623. goto MyExit;
  624. }
  625. else if (rc != GCC_NO_ERROR)
  626. {
  627. ERROR_OUT(("UserData::CopyUserDataList: Error creating new CObjectKeyContainer - bad data"));
  628. goto MyExit;
  629. }
  630. /*
  631. * Store the optional user data octet string in the list.
  632. */
  633. octet_string_ptr = user_data_list[i]->octet_string;
  634. if ((octet_string_ptr != NULL) && (rc == GCC_NO_ERROR))
  635. {
  636. /*
  637. * Create a new Rogue Wave string container to hold the
  638. * octet string.
  639. */
  640. if (NULL == (user_data_info_ptr->poszOctetString = ::My_strdupO2(
  641. octet_string_ptr->value,
  642. octet_string_ptr->length)))
  643. {
  644. ERROR_OUT(("UserData::CopyUserDataList: can't create octet string"));
  645. rc = GCC_ALLOCATION_FAILURE;
  646. goto MyExit;
  647. }
  648. }
  649. else
  650. {
  651. ASSERT(NULL == user_data_info_ptr->poszOctetString);
  652. }
  653. }
  654. else
  655. {
  656. ERROR_OUT(("UserData::CopyUserDataList: can't create USER_DATA"));
  657. rc = GCC_ALLOCATION_FAILURE;
  658. goto MyExit;
  659. }
  660. /*
  661. * Insert the pointer to the USER_DATA structure into the Rogue Wave list.
  662. */
  663. m_UserDataItemList.Append(user_data_info_ptr);
  664. }
  665. MyExit:
  666. if (GCC_NO_ERROR != rc)
  667. {
  668. delete user_data_info_ptr;
  669. }
  670. return rc;
  671. }
  672. /*
  673. * GCCError UnPackUserDataFromPDU (PSetOfUserData set_of_user_data)
  674. *
  675. * Private member function of CUserDataListContainer.
  676. *
  677. * Function Description:
  678. * This routine unpacks the user data from the "PDU" form into the
  679. * internal form which is maintained as a Rogue Wave list of USER_DATA
  680. * structures.
  681. *
  682. * Formal Parameters:
  683. * set_of_user_data (i) The "PDU" user data list to copy.
  684. *
  685. * Return Value:
  686. * GCC_NO_ERROR - No error.
  687. * GCC_ALLOCATION_FAILURE - Error creating an object using the
  688. * "new" operator.
  689. *
  690. * Side Effects:
  691. * None.
  692. *
  693. * Caveats:
  694. * None.
  695. */
  696. GCCError CUserDataListContainer::
  697. UnPackUserDataFromPDU(PSetOfUserData set_of_user_data)
  698. {
  699. PSetOfUserData pUserData;
  700. GCCError rc = GCC_NO_ERROR;
  701. for (pUserData = set_of_user_data; NULL != pUserData; pUserData = pUserData->next)
  702. {
  703. /*
  704. * Convert the user data elements into the internal format which
  705. * is a USER_DATA structure and insert the pointers to the
  706. * USER_DATA structures into the m_UserDataItemList.
  707. */
  708. if (ConvertPDUDataToInternal(pUserData) != GCC_NO_ERROR)
  709. {
  710. ERROR_OUT(("CUserDataListContainer::UnPackUserDataFromPDU: Error converting PDU data to internal"));
  711. rc = GCC_ALLOCATION_FAILURE;
  712. break;
  713. }
  714. }
  715. return rc;
  716. }
  717. /*
  718. * GCCError ConvertPDUDataToInternal ( PSetOfUserData user_data_ptr)
  719. *
  720. * Private member function of CUserDataListContainer.
  721. *
  722. * Function Description:
  723. * This routine converts an individual user data element from the "PDU"
  724. * structure form into the internal form which is a USER_DATA
  725. * structure.
  726. *
  727. * Formal Parameters:
  728. * user_data_ptr (i) The "PDU" user data list to copy.
  729. *
  730. * Return Value:
  731. * GCC_NO_ERROR - No error.
  732. * GCC_ALLOCATION_FAILURE - Error creating an object using the
  733. * "new" operator.
  734. *
  735. * Side Effects:
  736. * None.
  737. *
  738. * Caveats:
  739. * None.
  740. */
  741. GCCError CUserDataListContainer::
  742. ConvertPDUDataToInternal(PSetOfUserData user_data_ptr)
  743. {
  744. USER_DATA *user_data_info_ptr;
  745. GCCError rc = GCC_NO_ERROR;
  746. DBG_SAVE_FILE_LINE
  747. user_data_info_ptr = new USER_DATA;
  748. if (user_data_info_ptr != NULL)
  749. {
  750. user_data_info_ptr->poszOctetString = NULL;
  751. /*
  752. * Create a new CObjectKeyContainer object which will be used to store the
  753. * "key" portion of the user data internally. If an error occurs
  754. * constructing the key report it. Otherwise, check for any user data
  755. * which may need to be stored. Note that any error in creating the
  756. * CObjectKeyContainer object is reported as an allocation failure. An error
  757. * could occur if a bad object key was received as PDU data but this
  758. * would have originated from some other provider since we validate all
  759. * object keys created locally. We therefore report it as an allocation
  760. * failure.
  761. */
  762. DBG_SAVE_FILE_LINE
  763. user_data_info_ptr->key = new CObjectKeyContainer(&user_data_ptr->user_data_element.key, &rc);
  764. if ((user_data_info_ptr->key == NULL) || (rc != GCC_NO_ERROR))
  765. {
  766. ERROR_OUT(("UserData::ConvertPDUDataToInternal: Error creating new CObjectKeyContainer"));
  767. rc = GCC_ALLOCATION_FAILURE;
  768. goto MyExit;
  769. }
  770. else
  771. {
  772. /*
  773. * The object key was successfully saved so store any actual user
  774. * data in the list if it is present.
  775. */
  776. if (user_data_ptr->user_data_element.bit_mask & USER_DATA_FIELD_PRESENT)
  777. {
  778. if (NULL == (user_data_info_ptr->poszOctetString = ::My_strdupO2(
  779. user_data_ptr->user_data_element.user_data_field.value,
  780. user_data_ptr->user_data_element.user_data_field.length)))
  781. {
  782. ERROR_OUT(("UserData::ConvertPDUDataToInternal: can't create octet string"));
  783. rc = GCC_ALLOCATION_FAILURE;
  784. goto MyExit;
  785. }
  786. }
  787. else
  788. {
  789. ASSERT(NULL == user_data_info_ptr->poszOctetString);
  790. }
  791. }
  792. /*
  793. * Initialize the structure pointers to NULL and insert the pointer
  794. * to the USER_DATA structure into the Rogue Wave list.
  795. */
  796. m_UserDataItemList.Append(user_data_info_ptr);
  797. }
  798. else
  799. {
  800. ERROR_OUT(("UserData::ConvertPDUDataToInternal: can't create USER_DATA"));
  801. rc = GCC_ALLOCATION_FAILURE;
  802. // goto MyExit;
  803. }
  804. MyExit:
  805. if (GCC_NO_ERROR != rc)
  806. {
  807. delete user_data_info_ptr;
  808. }
  809. return rc;
  810. }
  811. /*
  812. * GCCError ConvertUserDataInfoToPDUUserData (
  813. * USER_DATA *user_data_info_ptr,
  814. * PSetOfUserData pdu_user_data_ptr)
  815. *
  816. * Private member function of CUserDataListContainer.
  817. *
  818. * Function Description:
  819. * This routine converts the user data from the internal form which is a
  820. * USER_DATA structure into the "PDU" structure form "SetOfUserData".
  821. *
  822. * Formal Parameters:
  823. * user_data_info_ptr (i) The internal user data structure to convert.
  824. * pdu_user_data_ptr (o) The structure to hold the PDU data after
  825. * conversion.
  826. *
  827. * Return Value:
  828. * GCC_NO_ERROR - No error.
  829. * GCC_ALLOCATION_FAILURE - Error creating an object using the
  830. * "new" operator.
  831. * GCC_INVALID_PARAMETER - The internal key pointer was
  832. * corrupted.
  833. *
  834. * Side Effects:
  835. * None.
  836. *
  837. * Caveats:
  838. * None.
  839. */
  840. GCCError CUserDataListContainer::
  841. ConvertUserDataInfoToPDUUserData(USER_DATA *user_data_info_ptr, PSetOfUserData pdu_user_data_ptr)
  842. {
  843. GCCError rc = GCC_NO_ERROR;
  844. /*
  845. * Initialize the user data bit mask to zero.
  846. */
  847. pdu_user_data_ptr->user_data_element.bit_mask = 0;
  848. /*
  849. * Fill in the octet string pointer and length if the octet string
  850. * exists. Set the bit mask indicating that the string exists.
  851. */
  852. if (user_data_info_ptr->poszOctetString != NULL)
  853. {
  854. pdu_user_data_ptr->user_data_element.user_data_field.value =
  855. user_data_info_ptr->poszOctetString->value;
  856. pdu_user_data_ptr->user_data_element.user_data_field.length =
  857. user_data_info_ptr->poszOctetString->length;
  858. pdu_user_data_ptr->user_data_element.bit_mask |= USER_DATA_FIELD_PRESENT;
  859. }
  860. /*
  861. * Fill in the object key data.
  862. */
  863. if (user_data_info_ptr->key != NULL)
  864. {
  865. /*
  866. * Retrieve the "PDU" object key data from the internal CObjectKeyContainer
  867. * object.
  868. */
  869. if (user_data_info_ptr->key->GetObjectKeyDataPDU (
  870. &pdu_user_data_ptr->user_data_element.key) != GCC_NO_ERROR)
  871. {
  872. rc = GCC_ALLOCATION_FAILURE;
  873. }
  874. }
  875. else
  876. {
  877. ERROR_OUT(("UserData::ConvertUserDataInfoToPDUUserData: no valid UserDataInfo key"));
  878. rc = GCC_INVALID_PARAMETER;
  879. }
  880. return rc;
  881. }