windows-nt/Source/XPSP1/NT/termsrv/remdsk/rds/t120/common/appcap.cpp

403 lines
9.9 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "precomp.h"
#include "fsdiag.h"
DEBUG_FILEZONE(ZONE_T120_UTILITY);
/*
* appcap.cpp
*
* Copyright (c) 1994 by DataBeam Corporation, Lexington, KY
*
* Abstract:
* This is the implementation file for the class CAppCap.
*
* Caveats:
* None.
*
* Author:
* jbo
*/
#include "appcap.h"
#include "clists.h"
/*
* CAppCap ()
*
* Public Function Description:
* This constructor is used to create a AppCapabilityData object
* from an "API" GCCApplicationCapability list.
*/
CAppCap::CAppCap(UINT number_of_capabilities,
PGCCApplicationCapability * capabilities_list,
PGCCError pRetCode)
:
CRefCount(MAKE_STAMP_ID('A','C','a','p')),
m_AppCapItemList(DESIRED_MAX_CAPS),
m_cbDataSize(0)
{
APP_CAP_ITEM *pAppCapItem;
UINT i;
GCCError rc;
rc = GCC_NO_ERROR;
for (i = 0; i < number_of_capabilities; i++)
{
DBG_SAVE_FILE_LINE
pAppCapItem = new APP_CAP_ITEM((GCCCapabilityType) capabilities_list[i]->capability_class.eType);
if (pAppCapItem != NULL)
{
DBG_SAVE_FILE_LINE
pAppCapItem->pCapID = new CCapIDContainer(
&capabilities_list[i]->capability_id,
&rc);
if ((pAppCapItem->pCapID != NULL) && (rc == GCC_NO_ERROR))
{
if (capabilities_list[i]->capability_class.eType ==
GCC_UNSIGNED_MINIMUM_CAPABILITY)
{
pAppCapItem->nUnsignedMinimum =
capabilities_list[i]->capability_class.nMinOrMax;
}
else if (capabilities_list[i]->capability_class.eType
== GCC_UNSIGNED_MAXIMUM_CAPABILITY)
{
pAppCapItem->nUnsignedMaximum =
capabilities_list[i]->capability_class.nMinOrMax;
}
pAppCapItem->cEntries = 1;
/*
* Add this capability to the list.
*/
m_AppCapItemList.Append(pAppCapItem);
}
else if (pAppCapItem->pCapID == NULL)
{
rc = GCC_ALLOCATION_FAILURE;
}
else
{
delete pAppCapItem;
}
}
else
{
rc = GCC_ALLOCATION_FAILURE;
}
if (rc != GCC_NO_ERROR)
break;
}
*pRetCode = rc;
}
/*
* ~CAppCap()
*
* Public Function Description
* The CAppCap destructor is responsible for freeing
* any memory allocated to hold the capability data.
*
*/
CAppCap::~CAppCap(void)
{
m_AppCapItemList.DeleteList();
}
/*
* LockCapabilityData ()
*
* Public Function Description:
* This routine locks the capability data and determines the amount of
* memory referenced by the "API" non-collapsing capability data structure.
*/
UINT CAppCap::LockCapabilityData(void)
{
/*
* If this is the first time this routine is called, determine the size of
* the memory required to hold the data referenced by the list of
* capabilities. Otherwise, just increment the lock count.
*/
if (Lock() == 1)
{
APP_CAP_ITEM *pAppCapItem;
/*
* Add the amount of memory necessary to hold the string data associated
* with each capability ID.
*/
m_AppCapItemList.Reset();
/*
* Lock the data for each capability ID. The lock call returns the
* length of the data referenced by each capability ID rounded to occupy
* an even multiple of four-bytes.
*/
while (NULL != (pAppCapItem = m_AppCapItemList.Iterate()))
{
m_cbDataSize += pAppCapItem->pCapID->LockCapabilityIdentifierData();
}
/*
* Add the memory to hold the application capability pointers
* and structures.
*/
m_cbDataSize += m_AppCapItemList.GetCount() *
(sizeof (PGCCApplicationCapability) +
ROUNDTOBOUNDARY( sizeof(GCCApplicationCapability)) );
}
return m_cbDataSize;
}
/*
* GetGCCApplicationCapabilityList ()
*
* Public Function Description:
* This routine retrieves the application capabilities list in the form of
* a list of PGCCApplicationCapability's. This routine is called after
* "locking" the capability data.
*/
UINT CAppCap::GetGCCApplicationCapabilityList(
PUShort number_of_capabilities,
PGCCApplicationCapability * * capabilities_list,
LPBYTE memory)
{
UINT cbDataSizeToRet = 0;
/*
* If the capability data has been locked, fill in the output structure and
* the data referenced by the structure.
*/
if (GetLockCount() > 0)
{
UINT data_length = 0;
UINT capability_id_data_length = 0;
USHORT capability_count;
PGCCApplicationCapability gcc_capability;
PGCCApplicationCapability * gcc_capability_list;
APP_CAP_ITEM *pAppCapItem;
/*
* Fill in the output length parameter which indicates how much data
* referenced outside the structure will be written.
*/
cbDataSizeToRet = m_cbDataSize;
/*
* Retrieve the number of capabilities and fill in any that are present.
*/
*number_of_capabilities = (USHORT) m_AppCapItemList.GetCount();
if (*number_of_capabilities != 0)
{
/*
* Fill in the pointer to the list of application capability
* pointers. The pointer list will begin at the memory location
* passed into this routine. Save the list pointer in a local
* variable for convenience.
*/
*capabilities_list = (PGCCApplicationCapability *)memory;
gcc_capability_list = *capabilities_list;
/*
* Move the memory pointer past the list of capability pointers.
* This is where the first application capability structure will be
* written.
*/
memory += (*number_of_capabilities * sizeof(PGCCApplicationCapability));
/*
* Add to the data length the amount of memory necessary to hold the
* application capability pointers. Go ahead and add the amount of
* memory necessary to hold all of the GCCApplicationCapability
* structures.
*/
data_length += *number_of_capabilities *
(sizeof(PGCCApplicationCapability) +
ROUNDTOBOUNDARY ( sizeof(GCCApplicationCapability)) );
/*
* Iterate through the capabilities list, building an "API"
* capability for each capability in the list.
*/
capability_count = 0;
m_AppCapItemList.Reset();
while (NULL != (pAppCapItem = m_AppCapItemList.Iterate()))
{
/*
* Set the application capability pointer equal to the
* location in memory where it will be written.
*/
gcc_capability = (PGCCApplicationCapability)memory;
/*
* Save the pointer to the application capability in the
* list of application capability pointers.
*/
gcc_capability_list[capability_count] = gcc_capability;
/*
* Advance the memory pointer past the application capability
* structure. This is where the string data for the capability
* ID will be written. Ensure that the memory pointer falls on
* an even four-byte boundary.
*/
memory += ROUNDTOBOUNDARY(sizeof(GCCApplicationCapability));
/*
* Retrieve the capability ID information from the internal
* CapabilityIDData object. The length returned by this call
* will have already been rounded to an even multiple of four
* bytes.
*/
capability_id_data_length = pAppCapItem->pCapID->
GetGCCCapabilityIDData(&gcc_capability->capability_id, memory);
/*
* Advance the memory pointer past the string data written into
* memory by the capability ID object. Add the length of the
* string data to the overall capability length.
*/
memory += capability_id_data_length;
data_length += capability_id_data_length;
/*
* Now fill in the rest of the capability.
*/
gcc_capability->capability_class.eType = pAppCapItem->eCapType;
if (gcc_capability->capability_class.eType ==
GCC_UNSIGNED_MINIMUM_CAPABILITY)
{
gcc_capability->capability_class.nMinOrMax =
pAppCapItem->nUnsignedMinimum;
}
else if (gcc_capability->capability_class.eType ==
GCC_UNSIGNED_MAXIMUM_CAPABILITY)
{
gcc_capability->capability_class.nMinOrMax =
pAppCapItem->nUnsignedMaximum;
}
gcc_capability->number_of_entities = pAppCapItem->cEntries;
/*
* Increment the capability array counter.
*/
capability_count++;
}
}
else
{
cbDataSizeToRet = 0;
capabilities_list = NULL;
}
}
else
{
ERROR_OUT(("CAppCap::GetData: Error: data not locked"));
}
return (cbDataSizeToRet);
}
/*
* UnLockCapabilityData ()
*
* Public Function Description:
* This routine decrements the lock count and frees the memory associated
* with the "API" capability once the lock count reaches zero.
*/
void CAppCap::UnLockCapabilityData(void)
{
if (Unlock(FALSE) == 0)
{
APP_CAP_ITEM *pAppCapItem;
/*
* Iterate through the list of collapsed capabilities, unlocking the
* data for each CapabilityIDData object associated with each
* capability.
*/
m_AppCapItemList.Reset();
while (NULL != (pAppCapItem = m_AppCapItemList.Iterate()))
{
pAppCapItem->pCapID->UnLockCapabilityIdentifierData();
}
}
// we have to call Release() because we used Unlock(FALSE)
Release();
}
APP_CAP_ITEM::APP_CAP_ITEM(GCCCapabilityType eCapType)
:
pCapID(NULL),
eCapType(eCapType),
cEntries(0),
poszAppData(NULL)
{
}
APP_CAP_ITEM::APP_CAP_ITEM(APP_CAP_ITEM *p, PGCCError pError)
: poszAppData(NULL)
{
// First set up the capability id
DBG_SAVE_FILE_LINE
pCapID = new CCapIDContainer(p->pCapID, pError);
if (NULL != pCapID)
{
// Initialize the new capability to default values.
eCapType = p->eCapType;
if (p->eCapType == GCC_UNSIGNED_MINIMUM_CAPABILITY)
{
nUnsignedMinimum = (UINT) -1;
}
else if (p->eCapType == GCC_UNSIGNED_MAXIMUM_CAPABILITY)
{
nUnsignedMaximum = 0;
}
cEntries = p->cEntries;
//
// LONCHANC: We do not copy the entries in application data???
//
*pError = GCC_NO_ERROR;
}
else
{
*pError = GCC_ALLOCATION_FAILURE;
}
}
APP_CAP_ITEM::~APP_CAP_ITEM(void)
{
if (NULL != pCapID)
{
pCapID->Release();
}
delete poszAppData;
}
void CAppCapItemList::DeleteList(void)
{
APP_CAP_ITEM *pAppCapItem;
while (NULL != (pAppCapItem = Get()))
{
delete pAppCapItem;
}
}