#include "precomp.h" DEBUG_FILEZONE(ZONE_T120_GCCNC); /* * netaddr.cpp * * Copyright (c) 1995 by DataBeam Corporation, Lexington, KY * * Abstract: * This is the implementation file for the CNetAddrListContainer Class. This * class manages the data associated with a network address. Network * addresses can be one of three types: aggregated channel, transport * connection, or non-standard. A variety of structures, objects, and * Rogue Wave containers are used to buffer the network address data * internally. * * Protected Instance Variables: * m_NetAddrItemList * List of structures used to hold the network address data internally. * m_pSetOfNetAddrPDU * Storage for the "PDU" form of the network address list. * m_cbDataSize * Variable holding the size of the memory which will be required to * hold any data referenced by the "API" network address structures. * m_fValidNetAddrPDU * Flag indicating that memory has been allocated to hold the internal * "PDU" network address list. * * Private Member Functions: * StoreNetworkAddressList * This routine is used to store the network address data passed in as * "API" data in the internal structures. * ConvertPDUDataToInternal * This routine is used to store the network address data passed in as * "PDU" data in the internal structures. * ConvertNetworkAddressInfoToPDU * This routine is used to convert the network address info structures * maintained internally into the "PDU" form which is a * SetOfNetworkAddresses. * ConvertTransferModesToInternal * This routine is used to convert the PDU network address transfer * modes structure into the internal form where the structure is saved * as a GCCTranferModes structure. * ConvertHighLayerCompatibilityToInternal * This routine is used to convert the PDU network address high layer * compatibility structure into the internal form where the structure * is saved as a GCCHighLayerCompatibility structure. * ConvertTransferModesToPDU * This routine is used to convert the API network address transfer * modes structure into the PDU form which is a TranferModes structure. * ConvertHighLayerCompatibilityToPDU * This routine is used to convert the API network address high layer * compatibility structure into the PDU form which is a * HighLayerCompatibility structure. * IsDialingStringValid * This routine is used to ensure that the values held within a * dialing string do not violate the imposed ASN.1 constraints. * IsCharacterStringValid * This routine is used to ensure that the values held within a * character string do not violate the imposed ASN.1 constraints. * IsExtraDialingStringValid * This routine is used to ensure that the values held within an * extra dialing string do not violate the imposed ASN.1 constraints. * * Caveats: * This container stores much of the network address information internally * using an "API" GCCNetworkAddress structure. Any data referenced by * pointers in this structure is stored in some other container. * Therefore, the pointers held within the internal "API" structure are * not valid and must not be accessed. * * Author: * blp/jbo */ #include #include "ms_util.h" #include "netaddr.h" /* * These macros are used to define the size constraints of an "nsap" address. */ #define MINIMUM_NSAP_ADDRESS_SIZE 1 #define MAXIMUM_NSAP_ADDRESS_SIZE 20 /* * These macros are used to verify that a network address has a valid number * of network address entities. */ #define MINIMUM_NUMBER_OF_ADDRESSES 1 #define MAXIMUM_NUMBER_OF_ADDRESSES 64 /* * These macros are used to define the size constraints of an extra dialing * string. */ #define MINIMUM_EXTRA_DIALING_STRING_SIZE 1 #define MAXIMUM_EXTRA_DIALING_STRING_SIZE 255 NET_ADDR::NET_ADDR(void) : pszSubAddress(NULL), pwszExtraDialing(NULL), high_layer_compatibility(NULL), poszTransportSelector(NULL), poszNonStandardParam(NULL), object_key(NULL) { } NET_ADDR::~NET_ADDR(void) { switch (network_address.network_address_type) { case GCC_AGGREGATED_CHANNEL_ADDRESS: delete pszSubAddress; delete pwszExtraDialing; delete high_layer_compatibility; break; case GCC_TRANSPORT_CONNECTION_ADDRESS: delete poszTransportSelector; break; case GCC_NONSTANDARD_NETWORK_ADDRESS: delete poszNonStandardParam; if (NULL != object_key) { object_key->Release(); } break; default: ERROR_OUT(("NET_ADDR::~NET_ADDR: unknown addr type=%u", (UINT) network_address.network_address_type)); break; } } /* * CNetAddrListContainer() * * Public Function Description: * This constructor is used when creating a CNetAddrListContainer object with * the "API" form of network address, GCCNetworkAddress. */ CNetAddrListContainer:: CNetAddrListContainer(UINT number_of_network_addresses, PGCCNetworkAddress *network_address_list, PGCCError return_value ) : CRefCount(MAKE_STAMP_ID('N','t','A','L')), m_pSetOfNetAddrPDU(NULL), m_fValidNetAddrPDU(FALSE), m_cbDataSize(0) { /* * Initialize the instance variables. The m_NetAddrItemList which * will hold the network address data internally will be filled in by the * call to StoreNetworkAddressList. */ /* * Check to make sure a valid number of network addresses exist. */ if ((number_of_network_addresses < MINIMUM_NUMBER_OF_ADDRESSES) || (number_of_network_addresses > MAXIMUM_NUMBER_OF_ADDRESSES)) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: ERROR Invalid number of network addresses, %u", (UINT) number_of_network_addresses)); *return_value = GCC_BAD_NETWORK_ADDRESS; } /* * Check to make sure that the list pointer is valid. */ else if (network_address_list == NULL) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: ERROR NULL address list")); *return_value = GCC_BAD_NETWORK_ADDRESS; } /* * Save the network address(es) in the internal structures. */ else { *return_value = StoreNetworkAddressList(number_of_network_addresses, network_address_list); } } /* * CNetAddrListContainer() * * Public Function Description: * This constructor is used when creating a CNetAddrListContainer object with * the "PDU" form of network address, SetOfNetworkAddresses. */ CNetAddrListContainer:: CNetAddrListContainer(PSetOfNetworkAddresses network_address_list, PGCCError return_value ) : CRefCount(MAKE_STAMP_ID('N','t','A','L')), m_pSetOfNetAddrPDU(NULL), m_fValidNetAddrPDU(FALSE), m_cbDataSize(0) { PSetOfNetworkAddresses network_address_ptr; /* * Initialize the instance variables. The m_NetAddrItemList which * will hold the network address data internally will be filled in by the * calls to ConvertPDUDataToInternal. */ *return_value = GCC_NO_ERROR; network_address_ptr = network_address_list; /* * Loop through the set of network addresses, saving each in an internal * NET_ADDR structure and saving those structures in the internal * list. */ if (network_address_list != NULL) { while (1) { /* * Convert each "PDU" network address into the internal form. Note * that object ID validation is not performed on data received as * a PDU. If a bad object ID comes in on the wire, this will be * flagged as an allocation failure. */ if (ConvertPDUDataToInternal (network_address_ptr) != GCC_NO_ERROR) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: Error converting PDU data to internal")); *return_value = GCC_ALLOCATION_FAILURE; break; } else { network_address_ptr = network_address_ptr->next; } if (network_address_ptr == NULL) break; } } } /* * CNetAddrListContainer() * * Public Function Description: * This is the copy constructor used to create a new CNetAddrListContainer * object from an existing CNetAddrListContainer object. */ CNetAddrListContainer:: CNetAddrListContainer(CNetAddrListContainer *address_list, PGCCError pRetCode) : CRefCount(MAKE_STAMP_ID('N','t','A','L')), m_pSetOfNetAddrPDU(NULL), m_fValidNetAddrPDU(FALSE), m_cbDataSize(0) { NET_ADDR *network_address_info; NET_ADDR *lpNetAddrInfo; GCCNetworkAddressType network_address_type; GCCError rc; /* * Set up an iterator for the internal list of network addresses. */ address_list->m_NetAddrItemList.Reset(); /* * Copy each NET_ADDR structure contained in the * CNetAddrListContainer object to be copied. */ while (NULL != (lpNetAddrInfo = address_list->m_NetAddrItemList.Iterate())) { /* * Create a new NET_ADDR structure to hold each element of the * new CNetAddrListContainer object. Report an error if creation of this * structure fails. */ DBG_SAVE_FILE_LINE if (NULL == (network_address_info = new NET_ADDR)) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: can't create NET_ADDR")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } /* * First copy the GCCNetworkAddress structure contained in the * internal NET_ADDR structure. This copies all data * except that referenced by pointers in the structure. */ network_address_info->network_address = lpNetAddrInfo->network_address; /* * Next copy any data embedded in the network address that would * not have been copied in the above operation (typically pointers * to strings). */ /* * This variable is used for abbreviation. */ network_address_type = lpNetAddrInfo->network_address.network_address_type; /* * The network address is the "Aggregated" type. */ switch (network_address_type) { case GCC_AGGREGATED_CHANNEL_ADDRESS: /* * If a sub-address string exists, store it in a Rogue Wave * container. Set the structure pointer to NULL if one does * not exist. */ if (lpNetAddrInfo->pszSubAddress != NULL) { if (NULL == (network_address_info->pszSubAddress = ::My_strdupA(lpNetAddrInfo->pszSubAddress))) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: can't create sub address")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->pszSubAddress = NULL; } /* * If an extra dialing string exists, store it in a Unicode * String object. Set the structure pointer to NULL if one * does not exist. */ if (lpNetAddrInfo->pwszExtraDialing != NULL) { if (NULL == (network_address_info->pwszExtraDialing = ::My_strdupW(lpNetAddrInfo->pwszExtraDialing))) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: can't creating extra dialing string")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->pwszExtraDialing = NULL; } /* * If a higher layer compatibility structure exists, store it * in a GCCHighLayerCompatibility structure. Set the structure * pointer to NULL if one does not exist. */ if (lpNetAddrInfo->high_layer_compatibility != NULL) { DBG_SAVE_FILE_LINE network_address_info->high_layer_compatibility = new GCCHighLayerCompatibility; if (network_address_info->high_layer_compatibility != NULL) { /* * Copy the high layer compatibility data to the * new structure. */ *network_address_info->high_layer_compatibility = *(lpNetAddrInfo->high_layer_compatibility); } else { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: Error creating new GCCHighLayerCompat")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->high_layer_compatibility = NULL; } break; /* * The network address is the "Transport Connection" type. */ case GCC_TRANSPORT_CONNECTION_ADDRESS: /* * If a transport selector exists, store it in a Rogue Wave * container. Otherwise, set the structure pointer to NULL. */ if (lpNetAddrInfo->poszTransportSelector != NULL) { if (NULL == (network_address_info->poszTransportSelector = ::My_strdupO(lpNetAddrInfo->poszTransportSelector))) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: can't create transport selector")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->poszTransportSelector = NULL; } break; /* * The network address is the "Non-Standard" type. */ case GCC_NONSTANDARD_NETWORK_ADDRESS: /* * First store the non-standard parameter data in a Rogue Wave * container. */ if (NULL == (network_address_info->poszNonStandardParam = ::My_strdupO(lpNetAddrInfo->poszNonStandardParam))) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: can't create non-standard param")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } /* * Next store the object key internally in an CObjectKeyContainer * object. Note that there is no need to report the error * "BAD_NETWORK_ADDRESS" here since the object key data * would have been validated when the original network address * was created. */ DBG_SAVE_FILE_LINE network_address_info->object_key = new CObjectKeyContainer(lpNetAddrInfo->object_key, &rc); if ((network_address_info->object_key == NULL) || (rc != GCC_NO_ERROR)) { ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: Error creating new CObjectKeyContainer")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } break; /* * The network address is of unknown type. This should never be * encountered so flag it as an allocation failure. */ default: ERROR_OUT(("CNetAddrListContainer::CNetAddrListContainer: Invalid type received as PDU")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } /* * Go ahead and insert the pointer to the NET_ADDR * structure into the internal Rogue Wave list. */ m_NetAddrItemList.Append(network_address_info); } rc = GCC_NO_ERROR; MyExit: if (GCC_NO_ERROR != rc) { delete network_address_info; } *pRetCode = rc; } /* * ~CNetAddrListContainer() * * Public Function Description: * The destructor is used to free up any memory allocated during the life * of the object. */ CNetAddrListContainer:: ~CNetAddrListContainer(void) { /* * Free any data allocated to hold "PDU" information. */ if (m_fValidNetAddrPDU) { FreeNetworkAddressListPDU(); } /* * Free any data allocated for the internal list of "info" structures. */ NET_ADDR *pNetAddrInfo; m_NetAddrItemList.Reset(); while (NULL != (pNetAddrInfo = m_NetAddrItemList.Iterate())) { delete pNetAddrInfo; } } /* * LockNetworkAddressList () * * Public Function Description: * This routine is called to "Lock" the network address data in "API" form. * The amount of memory required to hold the "API" data which is referenced * by, but not included in the GCCNetworkAddress structure, will be * returned. * */ UINT CNetAddrListContainer:: LockNetworkAddressList(void) { /* * If this is the first time this routine is called, determine the size of * the memory required to hold the data. Otherwise, just increment the * lock count. */ if (Lock() == 1) { PGCCNetworkAddress network_address; NET_ADDR *lpNetAddrInfo; /* * Set aside memory to hold the pointers to the GCCNetworkAddress * structures as well as the structures themselves. The "sizeof" the * structure must be rounded to an even four-byte boundary. */ m_cbDataSize = m_NetAddrItemList.GetCount() * ( sizeof(PGCCNetworkAddress) + ROUNDTOBOUNDARY(sizeof(GCCNetworkAddress)) ); /* * Loop through the list of network addresses, adding up the space * requirements of each address. */ m_NetAddrItemList.Reset(); while (NULL != (lpNetAddrInfo = m_NetAddrItemList.Iterate())) { /* * Use a local variable to keep from having to access the Rogue Wave * iterator repeatedly. */ network_address = &lpNetAddrInfo->network_address; /* * Check to see what type of network address exists. */ switch (network_address->network_address_type) { case GCC_AGGREGATED_CHANNEL_ADDRESS: /* * Add the length of the sub address string if it exists. */ if (lpNetAddrInfo->pszSubAddress != NULL) { m_cbDataSize += ROUNDTOBOUNDARY(::lstrlenA(lpNetAddrInfo->pszSubAddress) + 1); } /* * Add the size of the GCCExtraDialingString structure as well * as the length of the extra dialing string if it exists. */ if (lpNetAddrInfo->pwszExtraDialing != NULL) { m_cbDataSize += ROUNDTOBOUNDARY(sizeof(GCCExtraDialingString)) + ROUNDTOBOUNDARY((::lstrlenW(lpNetAddrInfo->pwszExtraDialing) + 1) * sizeof(WCHAR)); } /* * Add the size of the high layer compatibility structure if * it exists. */ if (lpNetAddrInfo->high_layer_compatibility != NULL) { m_cbDataSize += ROUNDTOBOUNDARY(sizeof(GCCHighLayerCompatibility)); } break; case GCC_TRANSPORT_CONNECTION_ADDRESS: /* * Add the size of the OSTR structure as well as the * length of the octet string if it exists. */ if (lpNetAddrInfo->poszTransportSelector != NULL) { m_cbDataSize += ROUNDTOBOUNDARY(sizeof(OSTR)) + ROUNDTOBOUNDARY(lpNetAddrInfo->poszTransportSelector->length); } break; case GCC_NONSTANDARD_NETWORK_ADDRESS: /* * Lock the object key in the non-standard parameter in order to * determine the amount of memory needed to hold its data. */ m_cbDataSize += lpNetAddrInfo->object_key->LockObjectKeyData (); /* * Add the space needed to hold the octet string data for the * non-standard parameter. */ m_cbDataSize += ROUNDTOBOUNDARY(lpNetAddrInfo->poszNonStandardParam->length); break; } } } return m_cbDataSize; } /* * GetNetworkAddressListAPI () * * Public Function Description: * This routine is used to retrieve the list of network addresses in "API" * form. */ UINT CNetAddrListContainer:: GetNetworkAddressListAPI(UINT * number_of_network_addresses, PGCCNetworkAddress ** network_address_list, LPBYTE memory) { UINT cbDataSizeToRet = 0; UINT data_length = 0; UINT network_address_counter = 0; PGCCNetworkAddress network_address_ptr; NET_ADDR *address_info; PGCCNetworkAddress *address_array; /* * If the user data has been locked, fill in the output parameters and * the data referenced by the pointers. Otherwise, report that the object * has yet to be locked into the "API" form. */ if (GetLockCount() > 0) { // NET_ADDR *lpNetAddrInfo; /* * Fill in the output length parameter which indicates how much data * referenced outside the structure will be written. */ cbDataSizeToRet = m_cbDataSize; /* * Fill in the number of network address entities and save a pointer to * the memory location passed in. This is where the pointers to the * GCCNetworkAddress structures will be written. The actual structures * will be written into memory immediately following the list of * pointers. */ *number_of_network_addresses = (UINT) m_NetAddrItemList.GetCount(); *network_address_list = (PGCCNetworkAddress *)memory; address_array = *network_address_list; /* * Save the amount of memory needed to hold the list of pointers as * well as the actual network address structures. */ data_length = m_NetAddrItemList.GetCount() * sizeof(PGCCNetworkAddress); /* * Move the memory pointer past the list of network address pointers. * This is where the first network address structure will be written. */ memory += data_length; /* * Iterate through the internal list of NET_ADDR structures, * building "API" GCCNetworkAddress structures in memory. */ m_NetAddrItemList.Reset(); while (NULL != (address_info = m_NetAddrItemList.Iterate())) { /* * Save the pointer to the network address structure in the list * of pointers. */ network_address_ptr = (PGCCNetworkAddress)memory; address_array[network_address_counter++] = network_address_ptr; /* * Move the memory pointer past the network address structure. * This is where the network address data will be written. */ memory += ROUNDTOBOUNDARY(sizeof(GCCNetworkAddress)); /* * Check to see what type of network address this is and fill in * the user data structure. Here the address is the aggregated * channel type. */ switch (address_info->network_address.network_address_type) { case GCC_AGGREGATED_CHANNEL_ADDRESS: network_address_ptr->network_address_type = GCC_AGGREGATED_CHANNEL_ADDRESS; /* * Copy the transfer modes. */ network_address_ptr->u.aggregated_channel_address.transfer_modes = address_info->network_address.u.aggregated_channel_address.transfer_modes; /* * Copy the international number. */ ::lstrcpyA(network_address_ptr->u.aggregated_channel_address.international_number, address_info->network_address.u.aggregated_channel_address.international_number); /* * If the sub address string exists, set the sub address string * pointer and write the data into memory. Otherwise, set the * "API" pointer to NULL. */ if (address_info->pszSubAddress != NULL) { network_address_ptr->u.aggregated_channel_address.sub_address_string = (GCCCharacterString)memory; /* * Now copy the sub-address string data from the internal * Rogue Wave string into memory. */ ::lstrcpyA((LPSTR) memory, address_info->pszSubAddress); /* * Move the memory pointer past the sub-address string data. * This is where the GCCExtraDialingString structure will be * written. */ memory += ROUNDTOBOUNDARY(::lstrlenA(address_info->pszSubAddress) + 1); } else { /* * No sub-address was present so set the pointer to NULL. */ network_address_ptr->u.aggregated_channel_address.sub_address_string = NULL; } /* * If the extra dialing string exists, set the extra dialing * string pointer and write the data into memory. Otherwise, * set the "API" pointer to NULL. */ if (address_info->pwszExtraDialing != NULL) { network_address_ptr->u.aggregated_channel_address.extra_dialing_string = (PGCCExtraDialingString)memory; /* * Move the memory pointer past the GCCExtraDialingString * structure. This is where the extra dialing string data * will be written. */ memory += ROUNDTOBOUNDARY(sizeof(GCCExtraDialingString)); UINT cchExtraDialing = ::lstrlenW(address_info->pwszExtraDialing); network_address_ptr->u.aggregated_channel_address.extra_dialing_string->length = (USHORT) cchExtraDialing; network_address_ptr->u.aggregated_channel_address.extra_dialing_string->value = (LPWSTR)memory; /* * Now copy the hex string data from the internal Unicode * String into the allocated memory. */ // // LONCHANC: The size does not include null terminator in the original code. // could this be a bug??? // ::CopyMemory(memory, address_info->pwszExtraDialing, cchExtraDialing * sizeof(WCHAR)); /* * Move the memory pointer past the extra dialing string * data. This is where the high layer compatibility * structure will be written. */ memory += ROUNDTOBOUNDARY(cchExtraDialing * sizeof(WCHAR)); } else { /* * No extra dialing string was present so set the pointer * to NULL. */ network_address_ptr->u.aggregated_channel_address.extra_dialing_string = NULL; } /* * If the high layer compatibility structure exists, set the * pointer and write the data into memory. Otherwise, set * the "API" pointer to NULL. */ if (address_info->high_layer_compatibility != NULL) { network_address_ptr->u.aggregated_channel_address.high_layer_compatibility = (PGCCHighLayerCompatibility)memory; *network_address_ptr->u.aggregated_channel_address.high_layer_compatibility = *(address_info->high_layer_compatibility); /* * Move the memory pointer past the high layer * compatibility structure. */ memory += ROUNDTOBOUNDARY(sizeof(GCCHighLayerCompatibility)); } else { /* * No high layer compatibility structure was present so * set the pointer to NULL. */ network_address_ptr->u.aggregated_channel_address. high_layer_compatibility = NULL; } break; /* * The network address is a transport connection type. */ case GCC_TRANSPORT_CONNECTION_ADDRESS: network_address_ptr->network_address_type = GCC_TRANSPORT_CONNECTION_ADDRESS; /* * Now copy the nsap address. */ ::CopyMemory(network_address_ptr->u.transport_connection_address.nsap_address.value, address_info->network_address.u.transport_connection_address.nsap_address.value, address_info->network_address.u.transport_connection_address.nsap_address.length); network_address_ptr->u.transport_connection_address.nsap_address.length = address_info->network_address.u.transport_connection_address.nsap_address.length; /* * If a transport selector exists, set the transport selector * pointer and write the data into memory. Otherwise, set the * "API" pointer to NULL. */ if (address_info->poszTransportSelector != NULL) { network_address_ptr->u.transport_connection_address.transport_selector = (LPOSTR) memory; /* * Move the memory pointer past the OSTR * structure. This is where the actual string data will * be written. */ memory += ROUNDTOBOUNDARY(sizeof(OSTR)); network_address_ptr->u.transport_connection_address. transport_selector->value = (LPBYTE)memory; network_address_ptr->u.transport_connection_address. transport_selector->length = address_info->poszTransportSelector->length; /* * Now copy the transport selector string data from the * internal Rogue Wave string into memory. */ ::CopyMemory(memory, address_info->poszTransportSelector->value, address_info->poszTransportSelector->length); /* * Move the memory pointer past the transport selector * string data. */ memory += ROUNDTOBOUNDARY(address_info->poszTransportSelector->length); } else { network_address_ptr->u.transport_connection_address.transport_selector = NULL; } break; /* * The network address is a non-standard type. */ case GCC_NONSTANDARD_NETWORK_ADDRESS: network_address_ptr->network_address_type = GCC_NONSTANDARD_NETWORK_ADDRESS; /* * Check to make sure both elements of the non-standard address * exist in the internal structure. */ if ((address_info->poszNonStandardParam == NULL) || (address_info->object_key == NULL)) { ERROR_OUT(("CNetAddrListContainer::GetNetworkAddressListAPI: Bad internal pointer")); cbDataSizeToRet = 0; } else { data_length = address_info->object_key-> GetGCCObjectKeyData( &network_address_ptr->u. non_standard_network_address.object_key, memory); /* * Move the memory pointer past the object key data. This * is where the octet string data will be written. */ memory += data_length; network_address_ptr->u.non_standard_network_address.parameter_data.value = memory; /* * Write the octet string data into memory and set the octet * string structure pointer and length. */ network_address_ptr->u.non_standard_network_address.parameter_data.length = (USHORT) address_info->poszNonStandardParam->length; /* * Now copy the octet string data from the internal Rogue * Wave string into the object key structure held in memory. */ ::CopyMemory(memory, address_info->poszNonStandardParam->value, address_info->poszNonStandardParam->length); /* * Move the memory pointer past the octet string data. */ memory += ROUNDTOBOUNDARY(address_info->poszNonStandardParam->length); } break; default: ERROR_OUT(("CNetAddrListContainer::GetNetworkAddressListAPI: Error Bad type.")); break; } // switch } // while } else { *network_address_list = NULL; *number_of_network_addresses = 0; ERROR_OUT(("CNetAddrListContainer::GetNetworkAddressListAPI: Error Data Not Locked")); } return cbDataSizeToRet; } /* * UnLockNetworkAddressList () * * Public Function Description: * This routine unlocks any memory which has been locked for the "API" * form of the network address list. If the "Free" flag has been set then * the CNetAddrListContainer object will be destroyed. * */ void CNetAddrListContainer:: UnLockNetworkAddressList(void) { /* * If the lock count has reached zero, this object is "unlocked" so do * some cleanup. */ if (Unlock(FALSE) == 0) { /* * Unlock any memory locked for the CObjectKeyContainer objects in the * internal NET_ADDR structures. */ NET_ADDR *pNetAddrInfo; m_NetAddrItemList.Reset(); while (NULL != (pNetAddrInfo = m_NetAddrItemList.Iterate())) { if (pNetAddrInfo->object_key != NULL) { pNetAddrInfo->object_key->UnLockObjectKeyData(); } } } // we have to call Release() because we used Unlock(FALSE) Release(); } /* * GetNetworkAddressListPDU () * * Public Function Description: * This routine is used to retrieve the network address list in "PDU" form. */ GCCError CNetAddrListContainer:: GetNetworkAddressListPDU(PSetOfNetworkAddresses *set_of_network_addresses) { GCCError rc = GCC_NO_ERROR; PSetOfNetworkAddresses new_pdu_network_address_ptr; PSetOfNetworkAddresses old_pdu_network_address_ptr = NULL; /* * If this is the first time that PDU data has been requested then we must * fill in the internal PDU structure and copy it into the structure pointed * to by the output parameter. On subsequent calls to "GetPDU" we can just * copy the internal PDU structure into the structure pointed to by the * output parameter. */ if (m_fValidNetAddrPDU == FALSE) { m_fValidNetAddrPDU = TRUE; /* * Initialize the output parameter to NULL so that the first time * through it will be set equal to the first new set of network address * data created in the iterator loop. */ m_pSetOfNetAddrPDU = NULL; /* * Iterate through the list of NET_ADDR structures, * converting each into "PDU" form and saving the pointers in the * linked list of "SetsOfNetworkAddresses". */ NET_ADDR *pNetAddrInfo; m_NetAddrItemList.Reset(); while (NULL != (pNetAddrInfo = m_NetAddrItemList.Iterate())) { /* * If an allocation failure occurs, call the routine which will * iterate through the list freeing any data which had been * allocated. */ DBG_SAVE_FILE_LINE new_pdu_network_address_ptr = new SetOfNetworkAddresses; if (new_pdu_network_address_ptr == NULL) { ERROR_OUT(("CNetAddrListContainer::GetNetworkAddressListPDU: Allocation error, cleaning up")); rc = GCC_ALLOCATION_FAILURE; FreeNetworkAddressListPDU (); break; } /* * The first time through, set the PDU structure pointer equal * to the first SetOfNetworkAddresses created. On subsequent loops, * set the structure's "next" pointer equal to the new structure. */ if (m_pSetOfNetAddrPDU == NULL) { m_pSetOfNetAddrPDU = new_pdu_network_address_ptr; } else { old_pdu_network_address_ptr->next = new_pdu_network_address_ptr; } old_pdu_network_address_ptr = new_pdu_network_address_ptr; /* * Initialize the new "next" pointer to NULL. */ new_pdu_network_address_ptr->next = NULL; /* * Call the routine to actually convert the network address. */ if (ConvertNetworkAddressInfoToPDU(pNetAddrInfo, new_pdu_network_address_ptr) != GCC_NO_ERROR) { ERROR_OUT(("CNetAddrListContainer::GetNetworkAddressListPDU: can't create NET_ADDR to PDU")); rc = GCC_ALLOCATION_FAILURE; break; } } } /* * Copy the internal PDU structure into the structure pointed to by the * output parameter. */ *set_of_network_addresses = m_pSetOfNetAddrPDU; return rc; } /* * FreeNetworkAddressListPDU () * * Public Function Description: * This routine is used to free the memory allocated for the "PDU" form * of the network address list. */ GCCError CNetAddrListContainer:: FreeNetworkAddressListPDU(void) { GCCError rc = GCC_NO_ERROR; PSetOfNetworkAddresses pdu_network_address_set; PSetOfNetworkAddresses next_pdu_network_address_set; if (m_fValidNetAddrPDU) { m_fValidNetAddrPDU = FALSE; pdu_network_address_set = m_pSetOfNetAddrPDU; /* * Loop through the list, freeing the network address data associated * with each structure contained in the list. The only data allocated * for the PDU which is not held in the internal info structure list * is done by the CObjectKeyContainer object. Those objects are told to free * that data in the iterator loop below. */ while (pdu_network_address_set != NULL) { next_pdu_network_address_set = pdu_network_address_set->next; delete pdu_network_address_set; pdu_network_address_set = next_pdu_network_address_set; } /* * Free any PDU memory allocated by the internal CObjectKeyContainer object. */ NET_ADDR *pNetAddrInfo; m_NetAddrItemList.Reset(); while (NULL != (pNetAddrInfo = m_NetAddrItemList.Iterate())) { if (pNetAddrInfo->object_key != NULL) { pNetAddrInfo->object_key->FreeObjectKeyDataPDU(); } } } else { ERROR_OUT(("NetAddressList::FreeUserDataListPDU: PDU Data not allocated")); rc = GCC_BAD_NETWORK_ADDRESS; } return (rc); } /* * GCCError StoreNetworkAddressList ( * UINT number_of_network_addresses, * PGCCNetworkAddress * local_network_address_list); * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to store the network address data passed in as * "API" data in the internal structures. * * Formal Parameters: * number_of_network_addresses (i) Number of addresses in "API" list. * local_network_address_list (i) List of "API" addresses. * * Return Value: * GCC_NO_ERROR - No error. * GCC_ALLOCATION_FAILURE - Error creating an object using the * "new" operator. * GCC_BAD_NETWORK_ADDRESS - Invalid network address passed in. * GCC_BAD_NETWORK_ADDRESS_TYPE - Bad "choice" field for address * * Side Effects: * None. * * Caveats: * None. */ GCCError CNetAddrListContainer:: StoreNetworkAddressList(UINT number_of_network_addresses, PGCCNetworkAddress * local_network_address_list) { GCCError rc; NET_ADDR *network_address_info; PGCCNetworkAddress network_address; UINT i; /* * For each network address in the list, create a new "info" structure to * buffer the data internally. Fill in the structure and save it in the * Rogue Wave list. */ for (i = 0; i < number_of_network_addresses; i++) { DBG_SAVE_FILE_LINE if (NULL == (network_address_info = new NET_ADDR)) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: can't create NET_ADDR")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } /* * This variable is used for abbreviation. */ network_address = &network_address_info->network_address; /* * Copy all the network address data into the network address * structure that is part of the network address info structure. */ *network_address = *local_network_address_list[i]; /* * This section of the code deals with any data embedded in the * network address that would not have been copied in the above * operation (typically pointers to strings). */ switch (network_address->network_address_type) { case GCC_AGGREGATED_CHANNEL_ADDRESS: /* * Check to make sure the international number dialing string * does not violate the imposed ASN.1 constraints. */ if (! IsDialingStringValid(local_network_address_list[i]->u.aggregated_channel_address.international_number)) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: Invalid international number")); rc = GCC_BAD_NETWORK_ADDRESS; goto MyExit; } /* * If a sub-address string exists, store it in a Rogue Wave * container. Set the structure pointer to NULL if one does * not exist. */ if (local_network_address_list[i]->u.aggregated_channel_address.sub_address_string != NULL) { /* * Check to make sure the sub address string does not * violate the imposed ASN.1 constraints. */ if (! IsCharacterStringValid(local_network_address_list[i]->u.aggregated_channel_address.sub_address_string)) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: Invalid sub address string")); rc = GCC_BAD_NETWORK_ADDRESS; goto MyExit; } /* * Create a string to hold the sub address. */ if (NULL == (network_address_info->pszSubAddress = ::My_strdupA( (LPSTR) local_network_address_list[i]->u.aggregated_channel_address.sub_address_string))) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: can't creating new sub address string")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->pszSubAddress = NULL; } /* * If an extra dialing string exists, store it in a Unicode * String object. Set the structure pointer to NULL if one * does not exist. */ if (local_network_address_list[i]->u.aggregated_channel_address.extra_dialing_string != NULL) { /* * Check to make sure the extra dialing string does not * violate the imposed ASN.1 constraints. */ if (! IsExtraDialingStringValid(local_network_address_list[i]->u.aggregated_channel_address.extra_dialing_string)) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: Invalid extra dialing string")); rc = GCC_BAD_NETWORK_ADDRESS; goto MyExit; } if (NULL == (network_address_info->pwszExtraDialing = ::My_strdupW2( local_network_address_list[i]->u.aggregated_channel_address.extra_dialing_string->length, local_network_address_list[i]->u.aggregated_channel_address.extra_dialing_string->value))) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: Error creating extra dialing string")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->pwszExtraDialing = NULL; } /* * If a higher layer compatibility structure exists, store it * in a GCCHighLayerCompatibility structure. Set the structure * pointer to NULL if one does not exist. */ if (local_network_address_list[i]->u.aggregated_channel_address.high_layer_compatibility != NULL) { DBG_SAVE_FILE_LINE network_address_info->high_layer_compatibility = new GCCHighLayerCompatibility; if (network_address_info->high_layer_compatibility != NULL) { /* * Copy the high layer compatibility data to the * new structure. */ *network_address_info->high_layer_compatibility = *(local_network_address_list[i]->u.aggregated_channel_address.high_layer_compatibility); } else { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: Error creating new GCCHighLayerCompatibility")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->high_layer_compatibility = NULL; } break; case GCC_TRANSPORT_CONNECTION_ADDRESS: /* * Check to make sure the length of the nsap address is within * the allowable range. */ if ((local_network_address_list[i]->u.transport_connection_address.nsap_address.length < MINIMUM_NSAP_ADDRESS_SIZE) || (local_network_address_list[i]->u.transport_connection_address.nsap_address.length > MAXIMUM_NSAP_ADDRESS_SIZE)) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: Invalid nsap address")); rc = GCC_BAD_NETWORK_ADDRESS; goto MyExit; } /* * If a transport selector exists, store it in a Rogue Wave * string. Otherwise, set the structure pointer to NULL. */ if (local_network_address_list[i]->u.transport_connection_address.transport_selector != NULL) { /* * Create a Rogue Wave string to hold the transport * selector string. */ if (NULL == (network_address_info->poszTransportSelector = ::My_strdupO2( local_network_address_list[i]->u.transport_connection_address.transport_selector->value, local_network_address_list[i]->u.transport_connection_address.transport_selector->length))) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: can't create transport selector")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { network_address_info->poszTransportSelector = NULL; } break; case GCC_NONSTANDARD_NETWORK_ADDRESS: /* * Create a Rogue Wave string to hold the non-standard * parameter octet string. */ if (NULL == (network_address_info->poszNonStandardParam = ::My_strdupO2( local_network_address_list[i]->u.non_standard_network_address.parameter_data.value, local_network_address_list[i]->u.non_standard_network_address.parameter_data.length))) { ERROR_OUT(("CNetAddrListContainer::StoreNetworkAddressList: can't create non-standard param")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } /* * Next store the object key internally in an CObjectKeyContainer * object. */ DBG_SAVE_FILE_LINE network_address_info->object_key = new CObjectKeyContainer( &local_network_address_list[i]->u.non_standard_network_address.object_key, &rc); if (network_address_info->object_key == NULL || rc != GCC_NO_ERROR) { ERROR_OUT(("CNetAddrListContainer::StoreNetAddrList: Error creating new CObjectKeyContainer")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } break; default: ERROR_OUT(("CNetAddrListContainer::StoreNetAddrList: bad network address type=%u", (UINT) network_address->network_address_type)); rc = GCC_BAD_NETWORK_ADDRESS_TYPE; goto MyExit; } /* * If all data was properly saved, insert the "info" structure * pointer into the Rogue Wave list. */ m_NetAddrItemList.Append(network_address_info); } // for rc = GCC_NO_ERROR; MyExit: if (GCC_NO_ERROR != rc) { delete network_address_info; } return rc; } /* * GCCError ConvertPDUDataToInternal ( * PSetOfNetworkAddresses network_address_ptr) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to store the network address data passed in as * "PDU" data in the internal structures. * * Formal Parameters: * network_address_ptr (i) "PDU" address list structure. * * Return Value: * GCC_NO_ERROR - No error. * GCC_ALLOCATION_FAILURE - Error creating an object using the * "new" operator. * * Side Effects: * None. * * Caveats: * None. */ GCCError CNetAddrListContainer:: ConvertPDUDataToInternal(PSetOfNetworkAddresses network_address_ptr) { GCCError rc; GCCError error_value; NET_ADDR *network_address_info_ptr; PGCCNetworkAddress copy_network_address; PNetworkAddress pdu_network_address; /* * Create a new info structure to hold the data internally. */ DBG_SAVE_FILE_LINE if (NULL == (network_address_info_ptr = new NET_ADDR)) { ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: can't create NET_ADDR")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } /* * Use these variables for clarity and brevity. */ copy_network_address = &network_address_info_ptr->network_address; pdu_network_address = &network_address_ptr->value; /* * Check to see what type of network address exists and save the data * in the internal structures. */ switch (pdu_network_address->choice) { case AGGREGATED_CHANNEL_CHOSEN: copy_network_address->network_address_type = GCC_AGGREGATED_CHANNEL_ADDRESS; /* * Save the tranfer modes structure. */ ConvertTransferModesToInternal( &pdu_network_address->u.aggregated_channel.transfer_modes, ©_network_address->u.aggregated_channel_address.transfer_modes); /* * Save the international number. */ ::lstrcpyA(copy_network_address->u.aggregated_channel_address.international_number, pdu_network_address->u.aggregated_channel.international_number); /* * Save the sub address string (if it exists) in the Rogue Wave * buffer contained in the network info structure. Otherwise, set * the structure pointer to NULL. */ if (pdu_network_address->u.aggregated_channel.bit_mask & SUB_ADDRESS_PRESENT) { /* * Create a Rogue Wave string to hold the sub address string. */ if (NULL == (network_address_info_ptr->pszSubAddress = ::My_strdupA( pdu_network_address->u.aggregated_channel.sub_address))) { ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: can't create sub address string")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { /* * The sub address string is not present so set the internal * info structure pointer to NULL. */ network_address_info_ptr->pszSubAddress = NULL; } /* * Next save the extra dialing string if one exists. */ if (pdu_network_address->u.aggregated_channel.bit_mask & EXTRA_DIALING_STRING_PRESENT) { if (NULL == (network_address_info_ptr->pwszExtraDialing = ::My_strdupW2( pdu_network_address->u.aggregated_channel.extra_dialing_string.length, pdu_network_address->u.aggregated_channel.extra_dialing_string.value))) { ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: Error creating extra dialing string")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { /* * The extra dialing string is not present so set the internal * info structure pointer to NULL. */ network_address_info_ptr->pwszExtraDialing = NULL; } /* * Save the high layer compatibility structure if it is present. */ if (pdu_network_address->u.aggregated_channel.bit_mask & HIGH_LAYER_COMPATIBILITY_PRESENT) { DBG_SAVE_FILE_LINE network_address_info_ptr->high_layer_compatibility = new GCCHighLayerCompatibility; if (network_address_info_ptr->high_layer_compatibility != NULL) { /* * Copy the high layer compatibility data to the * new structure. */ ConvertHighLayerCompatibilityToInternal( &pdu_network_address->u.aggregated_channel.high_layer_compatibility, network_address_info_ptr->high_layer_compatibility); } else { ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: Error creating new GCCHighLayerCompatibility")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { /* * The high layer compatibility structure is not present so set * the internal info structure pointer to NULL. */ network_address_info_ptr->high_layer_compatibility = NULL; } break; /* * Save the transport connection address. */ case TRANSPORT_CONNECTION_CHOSEN: copy_network_address->network_address_type = GCC_TRANSPORT_CONNECTION_ADDRESS; /* * Save the nsap address by copying the length and then the string. */ copy_network_address->u.transport_connection_address.nsap_address.length = pdu_network_address->u.transport_connection.nsap_address.length; ::lstrcpyA((LPSTR)copy_network_address->u.transport_connection_address.nsap_address.value, (LPSTR)pdu_network_address->u.transport_connection.nsap_address.value); /* * Save the transport selector if one exists. */ if (pdu_network_address->u.transport_connection.bit_mask & TRANSPORT_SELECTOR_PRESENT) { /* * Create a Rogue Wave string to hold the transport * selector string. */ if (NULL == (network_address_info_ptr->poszTransportSelector = ::My_strdupO2( pdu_network_address->u.transport_connection.transport_selector.value, pdu_network_address->u.transport_connection.transport_selector.length))) { ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: can't create transport selector")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } } else { /* * The transport selector is not present so set the internal * info structure pointer to NULL. */ network_address_info_ptr->poszTransportSelector = NULL; } break; /* * Save the non standard address. */ case ADDRESS_NON_STANDARD_CHOSEN: copy_network_address->network_address_type = GCC_NONSTANDARD_NETWORK_ADDRESS; /* * Create a Rogue Wave string to hold the non-standard * parameter octet string. */ if (NULL == (network_address_info_ptr->poszNonStandardParam = ::My_strdupO2( pdu_network_address->u.address_non_standard.data.value, pdu_network_address->u.address_non_standard.data.length))) { ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: can't create non-standard param")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } /* * Next store the object key internally in an CObjectKeyContainer * object. */ DBG_SAVE_FILE_LINE network_address_info_ptr->object_key = new CObjectKeyContainer( &pdu_network_address->u.address_non_standard.key, &error_value); if ((network_address_info_ptr->object_key == NULL) || (error_value != GCC_NO_ERROR)) { ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: Error creating new CObjectKeyContainer")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } break; default: ERROR_OUT(("CNetAddrListContainer::ConvertPDUDataToInternal: Error bad network address type")); rc = GCC_ALLOCATION_FAILURE; goto MyExit; } // switch /* * Go ahead and save the pointer to the info structure in the * internal Rogue Wave list. */ m_NetAddrItemList.Append(network_address_info_ptr); rc = GCC_NO_ERROR; MyExit: if (GCC_NO_ERROR != rc) { delete network_address_info_ptr; } return rc; } /* * GCCError ConvertNetworkAddressInfoToPDU ( * NET_ADDR *network_address_info_ptr, * PSetOfNetworkAddresses network_address_pdu_ptr) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to convert the network address info structures * maintained internally into the "PDU" form which is a * SetOfNetworkAddresses. * * Formal Parameters: * network_address_info_ptr (i) Internal network address structure. * network_address_pdu_ptr (o) PDU network address structure to fill in * * Return Value: * GCC_NO_ERROR - No error. * GCC_ALLOCATION_FAILURE - Error converting the network address * * Side Effects: * None. * * Caveats: * None. */ GCCError CNetAddrListContainer:: ConvertNetworkAddressInfoToPDU(NET_ADDR *network_address_info_ptr, PSetOfNetworkAddresses network_address_pdu_ptr) { GCCError rc = GCC_NO_ERROR; PGCCNetworkAddress api_ptr; PNetworkAddress pdu_ptr; /* * This variable will point to the "API" network address structure held in * the internal info structure. It is used for brevity. */ api_ptr = &network_address_info_ptr->network_address; /* * This variable will point to the "PDU" network address structure held in * the "SetOfNetworkAddresses" structure. It is used for brevity. */ pdu_ptr = &network_address_pdu_ptr->value; /* * Check to see what type of network address exists. Fill in the * appropriate form of the network address PDU structure. */ switch (api_ptr->network_address_type) { case GCC_AGGREGATED_CHANNEL_ADDRESS: /* * Fill in the aggregated channel address PDU structure. */ pdu_ptr->choice = AGGREGATED_CHANNEL_CHOSEN; pdu_ptr->u.aggregated_channel.bit_mask = 0; /* * Convert the structure holding the transfer modes into PDU form. */ ConvertTransferModesToPDU(&api_ptr->u.aggregated_channel_address.transfer_modes, &pdu_ptr->u.aggregated_channel.transfer_modes); /* * Copy the international number string. */ ::lstrcpyA(pdu_ptr->u.aggregated_channel.international_number, api_ptr->u.aggregated_channel_address.international_number); /* * Copy the sub-address string if it is present. Set the bit mask in * the PDU structure indicating that a sub-address string is present. */ if (network_address_info_ptr->pszSubAddress != NULL) { pdu_ptr->u.aggregated_channel.bit_mask |= SUB_ADDRESS_PRESENT; ::lstrcpyA((LPSTR) pdu_ptr->u.aggregated_channel.sub_address, network_address_info_ptr->pszSubAddress); } /* * Copy the extra dialing string if it is present. Set the bit mask in * the PDU structure indicating that an extra dialing string is present. */ if (network_address_info_ptr->pwszExtraDialing != NULL) { pdu_ptr->u.aggregated_channel.bit_mask |= EXTRA_DIALING_STRING_PRESENT; pdu_ptr->u.aggregated_channel.extra_dialing_string.value = network_address_info_ptr->pwszExtraDialing; pdu_ptr->u.aggregated_channel.extra_dialing_string.length = ::lstrlenW(network_address_info_ptr->pwszExtraDialing); } /* * Convert the structure holding the high layer compatibilities into * PDU form, if it is present. Set the bit mask in the PDU structure * indicating that a high layer compatibility structure is present. */ if (network_address_info_ptr->high_layer_compatibility != NULL) { pdu_ptr->u.aggregated_channel.bit_mask |= HIGH_LAYER_COMPATIBILITY_PRESENT; ConvertHighLayerCompatibilityToPDU( network_address_info_ptr->high_layer_compatibility, &pdu_ptr->u.aggregated_channel.high_layer_compatibility); } break; case GCC_TRANSPORT_CONNECTION_ADDRESS: /* * Fill in the transport connection address PDU structure. */ pdu_ptr->choice = TRANSPORT_CONNECTION_CHOSEN; /* * Copy the nsap_address. */ pdu_ptr->u.transport_connection.nsap_address.length = api_ptr->u.transport_connection_address.nsap_address.length; ::lstrcpyA((LPSTR)pdu_ptr->u.transport_connection.nsap_address.value, (LPSTR)api_ptr->u.transport_connection_address.nsap_address.value); /* * Copy the transport selector if it is present. Set the bit mask in * the PDU structure indicating that a transport selector is present. */ if (network_address_info_ptr->poszTransportSelector != NULL) { pdu_ptr->u.transport_connection.bit_mask |= TRANSPORT_SELECTOR_PRESENT; pdu_ptr->u.transport_connection.transport_selector.length = network_address_info_ptr->poszTransportSelector->length; pdu_ptr->u.transport_connection.transport_selector.value = (LPBYTE) network_address_info_ptr->poszTransportSelector->value; } break; case GCC_NONSTANDARD_NETWORK_ADDRESS: /* * Fill in the non-standard network address PDU structure. */ pdu_ptr->choice = ADDRESS_NON_STANDARD_CHOSEN; /* * Fill in the data portion of the non-standard parameter. */ pdu_ptr->u.address_non_standard.data.length = network_address_info_ptr->poszNonStandardParam->length; pdu_ptr->u.address_non_standard.data.value = network_address_info_ptr->poszNonStandardParam->value; /* * Now fill in the object key portion of the non-standard parameter * using the CObjectKeyContainer object stored internally in the network * address info structure. */ rc = network_address_info_ptr->object_key->GetObjectKeyDataPDU(&pdu_ptr->u.address_non_standard.key); if (rc != GCC_NO_ERROR) { ERROR_OUT(("CNetAddrListContainer::ConvertNetworkAddressInfoToPDU: Error getting object key data PDU")); } break; default: /* * The constructors will check to make sure a valid network address * type exists so this should never be encountered. */ ERROR_OUT(("CNetAddrListContainer::ConvertNetworkAddressInfoToPDU: Error bad network address type")); rc = GCC_ALLOCATION_FAILURE; } return rc; } /* * void ConvertTransferModesToInternal ( * PTransferModes source_transfer_modes, * PGCCTransferModes copy_transfer_modes) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to convert the PDU network address transfer modes * structure into the internal form where the structure is saved as a * GCCTranferModes structure. * * Formal Parameters: * source_transfer_modes (i) Structure holding "PDU" transfer modes. * copy_transfer_modes (o) Structure to hold "API" transfer modes. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ void CNetAddrListContainer:: ConvertTransferModesToInternal(PTransferModes source_transfer_modes, PGCCTransferModes copy_transfer_modes) { copy_transfer_modes->speech = (BOOL) source_transfer_modes->speech; copy_transfer_modes->voice_band = (BOOL) source_transfer_modes->voice_band; copy_transfer_modes->digital_56k = (BOOL) source_transfer_modes->digital_56k; copy_transfer_modes->digital_64k = (BOOL) source_transfer_modes->digital_64k; copy_transfer_modes->digital_128k = (BOOL) source_transfer_modes->digital_128k; copy_transfer_modes->digital_192k = (BOOL) source_transfer_modes->digital_192k; copy_transfer_modes->digital_256k = (BOOL) source_transfer_modes->digital_256k; copy_transfer_modes->digital_320k = (BOOL) source_transfer_modes->digital_320k; copy_transfer_modes->digital_384k = (BOOL) source_transfer_modes->digital_384k; copy_transfer_modes->digital_512k = (BOOL) source_transfer_modes->digital_512k; copy_transfer_modes->digital_768k = (BOOL) source_transfer_modes->digital_768k; copy_transfer_modes->digital_1152k = (BOOL) source_transfer_modes->digital_1152k; copy_transfer_modes->digital_1472k = (BOOL) source_transfer_modes->digital_1472k; copy_transfer_modes->digital_1536k = (BOOL) source_transfer_modes->digital_1536k; copy_transfer_modes->digital_1920k = (BOOL) source_transfer_modes->digital_1920k; copy_transfer_modes->packet_mode = (BOOL) source_transfer_modes->packet_mode; copy_transfer_modes->frame_mode = (BOOL) source_transfer_modes->frame_mode; copy_transfer_modes->atm = (BOOL) source_transfer_modes->atm; } /* * void ConvertHighLayerCompatibilityToInternal ( * PHighLayerCompatibility source_structure, * PGCCHighLayerCompatibility copy_structure) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to convert the PDU network address high layer * compatibility structure into the internal form where the structure is * saved as a GCCHighLayerCompatibility structure. * * Formal Parameters: * source_structure (i) Structure holding "PDU" high layer * compatibilities. * copy_structure (o) Structure to hold "API" high layer * compatibilities. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ void CNetAddrListContainer:: ConvertHighLayerCompatibilityToInternal(PHighLayerCompatibility source_structure, PGCCHighLayerCompatibility copy_structure) { copy_structure->telephony3kHz = (BOOL) source_structure->telephony3kHz; copy_structure->telephony7kHz = (BOOL) source_structure->telephony7kHz; copy_structure->videotelephony = (BOOL) source_structure->videotelephony; copy_structure->videoconference = (BOOL) source_structure->videoconference; copy_structure->audiographic = (BOOL) source_structure->audiographic; copy_structure->audiovisual = (BOOL) source_structure->audiovisual; copy_structure->multimedia = (BOOL) source_structure->multimedia; } /* * void ConvertTransferModesToPDU ( * PGCCTransferModes source_transfer_modes, * PTransferModes copy_transfer_modes) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to convert the API network address transfer modes * structure into the PDU form which is a TranferModes structure. * * Formal Parameters: * source_transfer_modes (i) Structure holding "API" transfer modes. * copy_transfer_modes (i) Structure holding "PDU" transfer modes. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ void CNetAddrListContainer:: ConvertTransferModesToPDU(PGCCTransferModes source_transfer_modes, PTransferModes copy_transfer_modes) { copy_transfer_modes->speech = (ASN1bool_t) source_transfer_modes->speech; copy_transfer_modes->voice_band = (ASN1bool_t) source_transfer_modes->voice_band; copy_transfer_modes->digital_56k = (ASN1bool_t) source_transfer_modes->digital_56k; copy_transfer_modes->digital_64k = (ASN1bool_t) source_transfer_modes->digital_64k; copy_transfer_modes->digital_128k = (ASN1bool_t) source_transfer_modes->digital_128k; copy_transfer_modes->digital_192k = (ASN1bool_t) source_transfer_modes->digital_192k; copy_transfer_modes->digital_256k = (ASN1bool_t) source_transfer_modes->digital_256k; copy_transfer_modes->digital_320k = (ASN1bool_t) source_transfer_modes->digital_320k; copy_transfer_modes->digital_384k = (ASN1bool_t) source_transfer_modes->digital_384k; copy_transfer_modes->digital_512k = (ASN1bool_t) source_transfer_modes->digital_512k; copy_transfer_modes->digital_768k = (ASN1bool_t) source_transfer_modes->digital_768k; copy_transfer_modes->digital_1152k = (ASN1bool_t) source_transfer_modes->digital_1152k; copy_transfer_modes->digital_1472k = (ASN1bool_t) source_transfer_modes->digital_1472k; copy_transfer_modes->digital_1536k = (ASN1bool_t) source_transfer_modes->digital_1536k; copy_transfer_modes->digital_1920k = (ASN1bool_t) source_transfer_modes->digital_1920k; copy_transfer_modes->packet_mode = (ASN1bool_t) source_transfer_modes->packet_mode; copy_transfer_modes->frame_mode = (ASN1bool_t) source_transfer_modes->frame_mode; copy_transfer_modes->atm = (ASN1bool_t) source_transfer_modes->atm; } /* * void ConvertHighLayerCompatibilityToPDU ( * PGCCHighLayerCompatibility source_structure, * PHighLayerCompatibility copy_structure) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to convert the API network address high layer * compatibility structure into the PDU form which is a * HighLayerCompatibility structure. * * Formal Parameters: * source_structure (i) Structure holding "API" high layer * compatibilities. * copy_structure (o) Structure to hold "PDU" high layer * compatibilities. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ void CNetAddrListContainer:: ConvertHighLayerCompatibilityToPDU(PGCCHighLayerCompatibility source_structure, PHighLayerCompatibility copy_structure) { copy_structure->telephony3kHz = (ASN1bool_t) source_structure->telephony3kHz; copy_structure->telephony7kHz = (ASN1bool_t) source_structure->telephony7kHz; copy_structure->videotelephony = (ASN1bool_t) source_structure->videotelephony; copy_structure->videoconference = (ASN1bool_t) source_structure->videoconference; copy_structure->audiographic = (ASN1bool_t) source_structure->audiographic; copy_structure->audiovisual = (ASN1bool_t) source_structure->audiovisual; copy_structure->multimedia = (ASN1bool_t) source_structure->multimedia; } /* * BOOL IsDialingStringValid ( GCCDialingString dialing_string) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to ensure that the values held within a * dialing string do not violate the imposed ASN.1 constraints. The * dialing string is constrained to be digits between 0 and 9, inclusive. * * Formal Parameters: * dialing_string (i) Dialing string to validate. * * Return Value: * TRUE - The string is valid. * FALSE - The string violates the ASN.1 constraints. * * Side Effects: * None. * * Caveats: * None. */ BOOL CNetAddrListContainer:: IsDialingStringValid(GCCDialingString dialing_string) { BOOL fRet = TRUE; while (*dialing_string != 0) { if ((*dialing_string < '0') || (*dialing_string > '9')) { fRet = FALSE; break; } dialing_string++; } return fRet; } /* * BOOL IsCharacterStringValid ( * GCCCharacterString character_string) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to ensure that the values held within a * character string do not violate the imposed ASN.1 constraints. The * character string is constrained to be digits between 0 and 9, inclusive. * * Formal Parameters: * character_string (i) Character string to validate. * * Return Value: * TRUE - The string is valid. * FALSE - The string violates the ASN.1 constraints. * * Side Effects: * None. * * Caveats: * None. */ BOOL CNetAddrListContainer:: IsCharacterStringValid(GCCCharacterString character_string) { BOOL fRet = TRUE; while (*character_string != 0) { if ((*character_string < '0') || (*character_string > '9')) { fRet = FALSE; break; } character_string++; } return fRet; } /* * BOOL IsExtraDialingStringValid ( * PGCCExtraDialingString extra_dialing_string) * * Private member function of CNetAddrListContainer. * * Function Description: * This routine is used to ensure that the values held within an * extra dialing string do not violate the imposed ASN.1 constraints. * * Formal Parameters: * extra_dialing_string (i) Dialing string to validate. * * Return Value: * TRUE - The string is valid. * FALSE - The string violates the ASN.1 constraints. * * Side Effects: * None. * * Caveats: * None. */ BOOL CNetAddrListContainer:: IsExtraDialingStringValid(PGCCExtraDialingString extra_dialing_string) { BOOL fRet = TRUE; /* * Check to make sure the length of the string is within the * allowable range. */ if ((extra_dialing_string->length < MINIMUM_EXTRA_DIALING_STRING_SIZE) || (extra_dialing_string->length > MAXIMUM_EXTRA_DIALING_STRING_SIZE)) { fRet = FALSE; } else { /* * If the length is valid, check the string values. */ LPWSTR pwsz = extra_dialing_string->value; for (USHORT i = 0; i < extra_dialing_string->length; i++) { if ((*pwsz != '#') && (*pwsz != '*') && (*pwsz != ',')) { if ((*pwsz < '0') || (*pwsz > '9')) { fRet = FALSE; break; } } pwsz++; } } return fRet; }