Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

870 lines
24 KiB

#include "precomp.h"
DEBUG_FILEZONE(ZONE_T120_GCCNC);
/*
* conflist.cpp
*
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
*
* Abstract:
* This is the implementation file for the class CConfDescriptorListContainer.
* Instances of this class represent the Conference Descriptor list that is
* generated by a call to GCCConferenceQueryRequest. This class hides most
* of the complexity associated with building this list. It also handles
* building the set of conference descriptors used in the
* ConferenceQueryResponse PDU and the conference descriptor list passed
* to the GCC interface. This class is designed so that a CControlSAP
* object can use it to create a GCC_CONFERENCE_QUERY_CONFIRM message by
* requesting a pointer to a list of Conference Descriptor pointers from
* it. Objects of this type only live long enough to service a particular
* query request. After a message callback has returned or a PDU has been
* sent to MCS, the CConfDescriptorListContainer object is deleted.
*
* Protected Instance Variables:
* m_ppGCCConfDescriptorList
* The list holding the conference descriptors in the API form.
* m_pSetOfConfDescriptors
* The list holding the conference descriptors in the PDU form.
* m_cDescriptors
* The number of descriptors in the list.
* m_pDescriptorListMemory
* The memory object used to hold the memory for the API list of
* conference descriptors.
* m_ConfDescriptorList
* The Rogue Wave list used to hold the descriptor data in the
* internal form.
* m_pNetAddrListMemory
* The memory object used to hold the memory for the network address
* list part of the API conference descriptor list.
* m_pNetAddrMemoryPointer
* A pointer used to keep track of where the network addresses for
* the API form of the descriptor list are written.
*
* Private Member Functions:
* GetConferenceDescriptor
* The routine used to fill in an API conference descriptor
* structure from an internal descriptor data structure.
*
* Caveats:
* The set of conference descriptors uses pointers owned by the conferences
* pointed to by the passed in list. Therefore, it is important not to
* use the set of descriptors held by this class after a conference is
* deleted. At this point the set of descriptors is invalid. Ideally,
* the decriptor set built by this class should be used immediately after
* construction.
*
* Author:
* blp
*/
#include "ms_util.h"
#include "conflist.h"
CONF_DESCRIPTOR::CONF_DESCRIPTOR(void)
:
pszNumericConfName(NULL),
pwszTextConfName(NULL),
pszConfModifier(NULL),
pwszConfDescription(NULL),
network_address_list(NULL)
{
}
CONF_DESCRIPTOR::~CONF_DESCRIPTOR(void)
{
delete pszNumericConfName;
delete pwszTextConfName;
delete pszConfModifier;
delete pwszConfDescription;
if (NULL != network_address_list)
{
network_address_list->Release();
}
}
/*
* CConfDescriptorListContainer ()
*
* Public Function Description
* This is a constructor for the CConfDescriptorListContainer class. It
* saves the memory manager which is passed in and initializes instance
* variables.
*/
CConfDescriptorListContainer::CConfDescriptorListContainer(void)
:
CRefCount(MAKE_STAMP_ID('C','D','L','C')),
m_ppGCCConfDescriptorList(NULL),
m_pSetOfConfDescriptors(NULL),
m_pDescriptorListMemory(NULL),
m_pNetAddrListMemory(NULL),
m_pNetAddrMemoryPointer(NULL),
m_cDescriptors(0)
{
}
/*
* CConfDescriptorListContainer ()
*
* Public Function Description
* This constructor builds a List of conference descriptors that can
* be passed on to the GCC interface. This list is built from a set
* of conference descriptors which is part of a query response PDU.
*/
CConfDescriptorListContainer::CConfDescriptorListContainer(
PSetOfConferenceDescriptors conference_list,
PGCCError gcc_error)
:
CRefCount(MAKE_STAMP_ID('C','D','L','C')),
m_ppGCCConfDescriptorList(NULL),
m_pSetOfConfDescriptors(NULL),
m_pDescriptorListMemory(NULL),
m_pNetAddrListMemory(NULL),
m_pNetAddrMemoryPointer(NULL),
m_cDescriptors(0)
{
PSetOfConferenceDescriptors descriptor_pdu;
CONF_DESCRIPTOR *descriptor_data;
GCCError error_value;
/*
* Initialize the return parameter and instance variables.
*/
*gcc_error = GCC_NO_ERROR;
descriptor_pdu = conference_list;
while (descriptor_pdu != NULL)
{
/*
* Allocate the structure used to hold internal data.
*/
DBG_SAVE_FILE_LINE
descriptor_data = new CONF_DESCRIPTOR;
if (descriptor_data == NULL)
{
*gcc_error = GCC_ALLOCATION_FAILURE;
break;
}
/*
* Fill in the descriptor flags.
*/
descriptor_data->conference_is_locked = descriptor_pdu->value.conference_is_locked;
descriptor_data->password_in_the_clear = descriptor_pdu->value.clear_password_required;
/*
* Copy the numeric portion of the conference name.
*/
descriptor_data->pszNumericConfName = ::My_strdupA(descriptor_pdu->value.conference_name.numeric);
/*
* Copy the text portion of the name if it exists.
*/
if (descriptor_pdu->value.conference_name.bit_mask &
CONFERENCE_NAME_TEXT_PRESENT)
{
if (NULL == (descriptor_data->pwszTextConfName = ::My_strdupW2(
descriptor_pdu->value.conference_name.conference_name_text.length,
descriptor_pdu->value.conference_name.conference_name_text.value)))
{
*gcc_error = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->pwszTextConfName);
}
/*
* Next copy the conference name modifier if it exists.
*/
if (descriptor_pdu->value.bit_mask & CONFERENCE_NAME_MODIFIER_PRESENT)
{
if (NULL == (descriptor_data->pszConfModifier = ::My_strdupA(
descriptor_pdu->value.conference_name_modifier)))
{
*gcc_error = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->pszConfModifier);
}
/*
* Next copy the conference description if it exists.
*/
if (descriptor_pdu->value.bit_mask & CONFERENCE_DESCRIPTION_PRESENT)
{
if (NULL == (descriptor_data->pwszConfDescription = ::My_strdupW2(
descriptor_pdu->value.conference_description.length,
descriptor_pdu->value.conference_description.value)))
{
*gcc_error = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->pwszConfDescription);
}
/*
* Next copy the network address list if it exists.
*/
if (descriptor_pdu->value.bit_mask & DESCRIPTOR_NET_ADDRESS_PRESENT)
{
DBG_SAVE_FILE_LINE
descriptor_data->network_address_list = new CNetAddrListContainer(
descriptor_pdu->value.descriptor_net_address,
&error_value);
if ((descriptor_data->network_address_list == NULL) ||
(error_value != GCC_NO_ERROR))
{
*gcc_error = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->network_address_list);
}
/*
* If no error has occurred, set up the next pointer and add the data
* structure to the list of conference descriptor data.
*/
if (*gcc_error == GCC_NO_ERROR)
{
descriptor_pdu = descriptor_pdu->next;
m_ConfDescriptorList.Append(descriptor_data);
}
else
{
delete descriptor_data;
break;
}
}
}
/*
* ~CConfDescriptorListContainer ()
*
* Public Function Description
* This is the destructor for the CConfDescriptorListContainer class. It is
* responsible for freeing up any resources allocated during the life of
* this object.
*/
CConfDescriptorListContainer::~CConfDescriptorListContainer(void)
{
UINT i;
CONF_DESCRIPTOR *lpConfDescData;
if (m_pSetOfConfDescriptors != NULL)
FreeConferenceDescriptorListPDU ();
/*
* Free all resources allocated by this object by iterating through the
* internal list of decriptor data structures.
*/
m_ConfDescriptorList.Reset();
while (NULL != (lpConfDescData = m_ConfDescriptorList.Iterate()))
{
delete lpConfDescData;
}
/*
* Free up any other allocated resources.
*/
if (m_pDescriptorListMemory != NULL)
{
for (i = 0; i < m_cDescriptors; i++)
{
delete m_ppGCCConfDescriptorList[i];
}
delete m_pDescriptorListMemory;
}
delete m_pNetAddrListMemory;
}
/*
* AddConferenceDescriptorToList ()
*
* Public Function Description
* This routine is used to add a single new conference descriptor to the
* list of conference descriptors.
*/
GCCError CConfDescriptorListContainer::AddConferenceDescriptorToList(
LPSTR pszNumericConfName,
LPWSTR pwszConfTextName,
LPSTR pszConfModifier,
BOOL locked_conference,
BOOL password_in_the_clear,
LPWSTR pwszConfDescription,
CNetAddrListContainer *network_address_list)
{
GCCError rc = GCC_NO_ERROR;
CONF_DESCRIPTOR *descriptor_data;
/*
* If PDU data has been allocated, free it so that the next "GetPDU" call
* will result in a rebuild of the PDU data and will therefore include the
* data being added in this routine.
*/
if (m_pSetOfConfDescriptors != NULL)
FreeConferenceDescriptorListPDU ();
/*
* Next allocate the structure used to hold the data internally.
*/
DBG_SAVE_FILE_LINE
descriptor_data = new CONF_DESCRIPTOR;
if (descriptor_data != NULL)
{
/*
* Fill in the descriptor flags.
*/
descriptor_data->conference_is_locked = locked_conference;
descriptor_data->password_in_the_clear = password_in_the_clear;
/*
* Copy the numeric portion of the conference name.
*/
if (pszNumericConfName != NULL)
{
descriptor_data->pszNumericConfName = ::My_strdupA(pszNumericConfName);
}
else
{
ASSERT(NULL == descriptor_data->pszNumericConfName);
rc = GCC_ALLOCATION_FAILURE;
}
/*
* Copy the text portion of the name if it exists
*/
if (pwszConfTextName != NULL)
{
if (NULL == (descriptor_data->pwszTextConfName =
::My_strdupW(pwszConfTextName)))
{
rc = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->pwszTextConfName);
}
/*
* Next copy the conference name modifier if it exists.
*/
if (pszConfModifier != NULL)
{
if (NULL == (descriptor_data->pszConfModifier = ::My_strdupA(pszConfModifier)))
{
rc = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->pszConfModifier);
}
/*
* Next copy the conference description if it exists.
*/
if (pwszConfDescription != NULL)
{
if (NULL == (descriptor_data->pwszConfDescription =
::My_strdupW(pwszConfDescription)))
{
rc = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->pwszConfDescription);
}
/*
* Next copy the network address list if it exists.
*/
if (network_address_list != NULL)
{
DBG_SAVE_FILE_LINE
descriptor_data->network_address_list =
new CNetAddrListContainer(network_address_list, &rc);
if (descriptor_data->network_address_list == NULL)
{
rc = GCC_ALLOCATION_FAILURE;
}
}
else
{
ASSERT(NULL == descriptor_data->network_address_list);
}
}
else
{
rc = GCC_ALLOCATION_FAILURE;
}
if (GCC_NO_ERROR == rc)
{
/*
* Add the structure to the descriptor list.
*/
m_ConfDescriptorList.Append(descriptor_data);
}
else
{
delete descriptor_data;
}
return rc;
}
/*
* GetConferenceDescriptorListPDU ()
*
* Public Function Description
* This routine is used to retrieve the PDU form of the conference
* descriptor list which is a list of "SetOfConferenceDescriptors"
* structures.
*/
GCCError CConfDescriptorListContainer::GetConferenceDescriptorListPDU(
PSetOfConferenceDescriptors * conference_list)
{
GCCError rc = GCC_NO_ERROR;
PSetOfConferenceDescriptors last_descriptor = NULL;
PSetOfConferenceDescriptors new_descriptor;
CONF_DESCRIPTOR *descriptor_data;
if (m_pSetOfConfDescriptors == NULL)
{
m_ConfDescriptorList.Reset();
while (NULL != (descriptor_data = m_ConfDescriptorList.Iterate()))
{
/*
* First allocate the new descriptor.
*/
DBG_SAVE_FILE_LINE
new_descriptor = new SetOfConferenceDescriptors;
if (new_descriptor == NULL)
{
rc = GCC_ALLOCATION_FAILURE;
break;
}
/*
* Next we add the new descriptor to the list..
*/
if (m_pSetOfConfDescriptors == NULL)
m_pSetOfConfDescriptors = new_descriptor;
else
last_descriptor->next = new_descriptor;
/*
* Set up the previous descriptor pointer.
*/
last_descriptor = new_descriptor;
/*
* Now fill in the new descriptor with the passed in parameters.
*/
new_descriptor->next = NULL;
new_descriptor->value.bit_mask = 0;
new_descriptor->value.conference_is_locked =
(ASN1bool_t)descriptor_data->conference_is_locked;
new_descriptor->value.clear_password_required =
(ASN1bool_t)descriptor_data->password_in_the_clear;
/*
* Get the numeric conference name.
*/
new_descriptor->value.conference_name.bit_mask = 0;
::lstrcpyA(new_descriptor->value.conference_name.numeric,
descriptor_data->pszNumericConfName);
/*
* Get the text conference name, if it exists.
*/
if (descriptor_data->pwszTextConfName != NULL)
{
new_descriptor->value.conference_name.bit_mask |= CONFERENCE_NAME_TEXT_PRESENT;
new_descriptor->value.conference_name.conference_name_text.value =
descriptor_data->pwszTextConfName;
new_descriptor->value.conference_name.conference_name_text.length =
::lstrlenW(descriptor_data->pwszTextConfName);
}
/*
* Check for a conference name modifier.
*/
if (descriptor_data->pszConfModifier != NULL)
{
new_descriptor->value.bit_mask |= CONFERENCE_NAME_MODIFIER_PRESENT;
::lstrcpyA(new_descriptor->value.conference_name_modifier,
descriptor_data->pszConfModifier);
}
/*
* Get the conference description if one exists.
*/
if (descriptor_data->pwszConfDescription != NULL)
{
new_descriptor->value.bit_mask |=CONFERENCE_DESCRIPTION_PRESENT;
new_descriptor->value.conference_description.value =
descriptor_data->pwszConfDescription;
new_descriptor->value.conference_description.length =
::lstrlenW(descriptor_data->pwszConfDescription);
}
/*
* Get the Network Address list if it exists.
*/
if (descriptor_data->network_address_list != NULL)
{
new_descriptor->value.bit_mask |=DESCRIPTOR_NET_ADDRESS_PRESENT;
descriptor_data->network_address_list->
GetNetworkAddressListPDU(&new_descriptor->value.
descriptor_net_address);
}
}
}
*conference_list = (rc == GCC_NO_ERROR) ?
m_pSetOfConfDescriptors :
NULL;
return rc;
}
/*
* FreeConferenceDescriptorListPDU ()
*
* Public Function Description
* This routine is used to free up any resources allocated to hold the PDU
* form of the conference descriptor list.
*/
void CConfDescriptorListContainer::FreeConferenceDescriptorListPDU(void)
{
PSetOfConferenceDescriptors pCurr, pNext;
CONF_DESCRIPTOR *lpConfDescData;
/*
* Loop through the list of descriptors, deleting each element.
*/
for (pCurr = m_pSetOfConfDescriptors; NULL != pCurr; pCurr = pNext)
{
pNext = pCurr->next;
delete pCurr;
}
/*
* Free the PDU data for any network address lists which may exist.
*/
m_ConfDescriptorList.Reset();
while (NULL != (lpConfDescData = m_ConfDescriptorList.Iterate()))
{
if (NULL != lpConfDescData->network_address_list)
{
lpConfDescData->network_address_list->FreeNetworkAddressListPDU();
}
}
m_pSetOfConfDescriptors = NULL;
}
/*
* LockConferenceDescriptorList ()
*
* Public Function Description
* This routine is used to "lock" the API form of the conference descriptor
* list. The lock count is incremented and the API form of the list
* created in preparation for a "GetConferenceDescriptorList" call used to
* retrieve the API form of the list. The memory necessary to hold the
* API list is allocated by this routine.
*/
GCCError CConfDescriptorListContainer::LockConferenceDescriptorList(void)
{
GCCError rc = GCC_NO_ERROR;
UINT i;
UINT network_address_data_length = 0;
CONF_DESCRIPTOR *lpConfDescData;
if (Lock() == 1)
{
m_cDescriptors = m_ConfDescriptorList.GetCount();
if (m_cDescriptors != 0)
{
/*
* Allocate space to hold pointers to all descriptors in the
* conference.
*/
DBG_SAVE_FILE_LINE
m_pDescriptorListMemory = new BYTE[m_cDescriptors * sizeof(PGCCConferenceDescriptor)];
if (m_pDescriptorListMemory != NULL)
{
m_ppGCCConfDescriptorList = (PGCCConferenceDescriptor *) m_pDescriptorListMemory;
/*
* Set up an iterator for the internal descriptor list. Iterate
* through the list, locking each network address list object
* and adding up the amount of memory needed to hold all of the
* data for the network address lists. Allocate the necessary
* amount of memory and save a pointer to the memory.
*/
m_ConfDescriptorList.Reset();
while (NULL != (lpConfDescData = m_ConfDescriptorList.Iterate()))
{
if (lpConfDescData->network_address_list != NULL)
{
network_address_data_length += lpConfDescData->network_address_list->LockNetworkAddressList();
}
}
if (network_address_data_length != 0)
{
DBG_SAVE_FILE_LINE
m_pNetAddrListMemory = new BYTE[network_address_data_length];
if (m_pNetAddrListMemory != NULL)
{
m_pNetAddrMemoryPointer = m_pNetAddrListMemory;
}
else
{
rc = GCC_ALLOCATION_FAILURE;
}
}
if (rc == GCC_NO_ERROR)
{
m_ConfDescriptorList.Reset();
for (i = 0; i < m_cDescriptors; i++)
{
lpConfDescData = m_ConfDescriptorList.Iterate();
ASSERT(NULL != lpConfDescData);
/*
* Allocate the API structure used at the interface.
* Call the routine which converts the descriptor data
* from its internal form into API form.
*/
DBG_SAVE_FILE_LINE
m_ppGCCConfDescriptorList[i] = new GCCConferenceDescriptor;
if (m_ppGCCConfDescriptorList[i] != NULL)
{
GetConferenceDescriptor(m_ppGCCConfDescriptorList[i], lpConfDescData);
}
else
{
rc = GCC_ALLOCATION_FAILURE;
}
}
}
}
else
{
rc = GCC_ALLOCATION_FAILURE;
}
}
if (rc != GCC_NO_ERROR)
{
Unlock();
}
}
return rc;
}
/*
* GetConferenceDescriptorList ()
*
* Public Function Description
* This routine is used to retrieve the API form of the conference
* descriptor list.
*/
void CConfDescriptorListContainer::GetConferenceDescriptorList(
PGCCConferenceDescriptor ** conference_list,
UINT * number_of_descriptors)
{
/*
* Check to see if the object has been locked. Fill in the API descriptor
* list if it has, report an error if it has not.
*/
if (GetLockCount() > 0)
{
*conference_list = m_ppGCCConfDescriptorList;
*number_of_descriptors = (USHORT) m_cDescriptors;
}
else
{
ERROR_OUT(("CConfDescriptorListContainer::GetConferenceDescriptorList: Error, data not locked"));
*conference_list = NULL;
*number_of_descriptors = 0;
}
}
/*
* UnLockConferenceDescriptorList ()
*
* Public Function Description
* This routine is used to "unlock" the "API" data for this object. This
* results in the lock count for this object being decremented. When the
* lock count transitions from 1 to 0, a check is made to determine
* whether the object has been freed through a call to
* FreeConferenceDescriptorList. If so, the object will automatically
* delete itself. If not, any resources allocated to hold the API form
* of the decriptor list are freed.
*/
void CConfDescriptorListContainer::UnLockConferenceDescriptorList(void)
{
UINT i;
/*
* If the lock count is zero, delete the object if it is "freed". If the
* lock count is zero but the obect is not "freed", free any resources
* allocated to hold the API data.
*/
if (Unlock(FALSE) == 0)
{
CONF_DESCRIPTOR *lpConfDescData;
if (m_pDescriptorListMemory != NULL)
{
for (i = 0; i < m_cDescriptors; i++)
{
delete m_ppGCCConfDescriptorList[i];
}
delete m_pDescriptorListMemory;
m_pDescriptorListMemory = NULL;
m_ppGCCConfDescriptorList = NULL;
}
/*
* Free the memory for the network address lists if it exists.
* Iterate through the internal descriptor list, unlocking any
* network address list objects which exist.
*/
if (m_pNetAddrListMemory != NULL)
{
delete m_pNetAddrListMemory;
m_pNetAddrListMemory = NULL;
m_pNetAddrMemoryPointer = NULL;
}
m_ConfDescriptorList.Reset();
while (NULL != (lpConfDescData = m_ConfDescriptorList.Iterate()))
{
if (lpConfDescData->network_address_list != NULL)
{
lpConfDescData->network_address_list->UnLockNetworkAddressList ();
}
}
}
// we have to call Release() because we used Unlock(FALSE)
Release();
}
/*
* void GetConferenceDescriptor (
* PGCCConferenceDescriptor gcc_descriptor,
* CONF_DESCRIPTOR *descriptor_data)
*
* Private member function of CConfDescriptorListContainer.
*
* Function Description:
* This routine is used to fill in an API conference descriptor structure
* from an internal descriptor data structure.
*
* Formal Parameters:
* gcc_descriptor (o) The API descriptor structure to fill in.
* descriptor_data (i) The internal structure holding the data which is
* to be copied into the API structure.
*
* Return Value:
* None.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
void CConfDescriptorListContainer::GetConferenceDescriptor(
PGCCConferenceDescriptor gcc_descriptor,
CONF_DESCRIPTOR *descriptor_data)
{
UINT network_address_data_length;
/*
* Fill in the descriptor flags.
*/
gcc_descriptor->conference_is_locked =
descriptor_data->conference_is_locked;
gcc_descriptor->password_in_the_clear_required =
descriptor_data->password_in_the_clear;
/*
* Get the numeric portion of the conference name.
*/
gcc_descriptor->conference_name.numeric_string =
(GCCNumericString) descriptor_data->pszNumericConfName;
/*
* Get the text portion of the conference name, if it exists.
*/
gcc_descriptor->conference_name.text_string = descriptor_data->pwszTextConfName;
/*
* Get the conference modifier.
*/
if (descriptor_data->pszConfModifier != NULL)
{
gcc_descriptor->conference_name_modifier =
(GCCNumericString) descriptor_data->pszConfModifier;
}
else
gcc_descriptor->conference_name_modifier = NULL;
/*
* Get the conference description.
*/
gcc_descriptor->conference_descriptor = descriptor_data->pwszConfDescription;
/*
* Fill in the network address list if it exists. Otherwise, set the
* number of address to zero and the structure pointer to NULL.
*/
if (descriptor_data->network_address_list != NULL)
{
network_address_data_length = descriptor_data->network_address_list->
GetNetworkAddressListAPI(
&gcc_descriptor->number_of_network_addresses,
&gcc_descriptor->network_address_list,
m_pNetAddrMemoryPointer);
/*
* Move the network address list memory pointer past the data written
* into memory by the "Get" call. The data for the next network address
* list will then be written there on subsequent "Get" calls.
*/
m_pNetAddrMemoryPointer += network_address_data_length;
}
else
{
gcc_descriptor->number_of_network_addresses = 0;
gcc_descriptor->network_address_list = NULL;
}
}