mirror of https://github.com/tongzx/nt5src
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.
581 lines
15 KiB
581 lines
15 KiB
#include "precomp.h"
|
|
DEBUG_FILEZONE(ZONE_T120_UTILITY);
|
|
/*
|
|
* regkey.cpp
|
|
*
|
|
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
|
|
*
|
|
* Abstract:
|
|
* This is the implementation file for the class CRegKeyContainer. This
|
|
* class manages the data associated with a Registry Key. Registry Key's
|
|
* are used to identify resources held in the application registry and
|
|
* consist of a Session Key and a resource ID octet string. The
|
|
* CRegKeyContainer class uses a CSessKeyContainer container to maintain the
|
|
* session key data internally. A Rogue Wave string object is used to
|
|
* hold the resource ID octet string.
|
|
*
|
|
* Protected Instance Variables:
|
|
* m_InternalRegKey
|
|
* Structure used to hold the registry key data internally.
|
|
* m_RegKeyPDU
|
|
* Storage for the "PDU" form of the registry key.
|
|
* m_fValidRegKeyPDU
|
|
* Flag indicating that memory has been allocated to hold the internal
|
|
* "PDU" registry key.
|
|
* m_cbDataSize
|
|
* Variable holding the size of the memory which will be required to
|
|
* hold any data referenced by the "API" GCCRegistryKey structure.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*
|
|
* Author:
|
|
* jbo
|
|
*/
|
|
|
|
#include "regkey.h"
|
|
|
|
|
|
/*
|
|
* This macro is used to ensure that the Resource ID contained in the Registry
|
|
* Key does not violate the imposed ASN.1 constraint.
|
|
*/
|
|
#define MAXIMUM_RESOURCE_ID_LENGTH 64
|
|
|
|
|
|
/*
|
|
* CRegKeyContainer()
|
|
*
|
|
* Public Function Description:
|
|
* This constructor is used to create a CRegKeyContainer object from
|
|
* an "API" GCCRegistryKey.
|
|
*/
|
|
CRegKeyContainer::
|
|
CRegKeyContainer(PGCCRegistryKey registry_key, PGCCError pRetCode)
|
|
:
|
|
CRefCount(MAKE_STAMP_ID('R','e','g','K')),
|
|
m_fValidRegKeyPDU(FALSE),
|
|
m_cbDataSize(0)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
/*
|
|
* Initialize instance variables.
|
|
*/
|
|
::ZeroMemory(&m_InternalRegKey, sizeof(m_InternalRegKey));
|
|
::ZeroMemory(&m_RegKeyPDU, sizeof(m_RegKeyPDU));
|
|
|
|
/*
|
|
* Check to make sure the resource ID string does not violate the imposed
|
|
* ASN.1 constraint.
|
|
*/
|
|
if (registry_key->resource_id.length > MAXIMUM_RESOURCE_ID_LENGTH)
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CRegKeyContainer: Error: resource ID exceeds allowable length"));
|
|
rc = GCC_BAD_REGISTRY_KEY;
|
|
goto MyExit;
|
|
}
|
|
|
|
/*
|
|
* Save the Session Key portion of the Registry Key in the internal
|
|
* structure by creating a new CSessKeyContainer object. Check to make
|
|
* sure the object is successfully created.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
m_InternalRegKey.session_key = new CSessKeyContainer(®istry_key->session_key, &rc);
|
|
if (m_InternalRegKey.session_key == NULL)
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CRegKeyContainer: Error creating new CSessKeyContainer"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
goto MyExit;
|
|
}
|
|
else if (rc == GCC_BAD_SESSION_KEY)
|
|
{
|
|
rc = GCC_BAD_REGISTRY_KEY;
|
|
goto MyExit;
|
|
}
|
|
|
|
/*
|
|
* Save the resource ID if the CSessKeyContainer was successfully created.
|
|
*/
|
|
if (NULL == (m_InternalRegKey.poszResourceID = ::My_strdupO2(
|
|
registry_key->resource_id.value,
|
|
registry_key->resource_id.length)))
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CRegKeyContainer: Error creating resource id"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
// goto MyExit;
|
|
}
|
|
|
|
MyExit:
|
|
|
|
*pRetCode = rc;
|
|
}
|
|
|
|
|
|
/*
|
|
* CRegKeyContainer()
|
|
*
|
|
* Public Function Description:
|
|
* This constructor is used to create a CRegKeyContainer object from
|
|
* a "PDU" RegistryKey.
|
|
*/
|
|
CRegKeyContainer::
|
|
CRegKeyContainer(PRegistryKey registry_key, PGCCError pRetCode)
|
|
:
|
|
CRefCount(MAKE_STAMP_ID('R','e','g','K')),
|
|
m_fValidRegKeyPDU(FALSE),
|
|
m_cbDataSize(0)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
/*
|
|
* Initialize instance variables.
|
|
*/
|
|
::ZeroMemory(&m_InternalRegKey, sizeof(m_InternalRegKey));
|
|
::ZeroMemory(&m_RegKeyPDU, sizeof(m_RegKeyPDU));
|
|
|
|
/*
|
|
* Save the Session Key portion of the Registry Key in the internal
|
|
* structure by creating a new CSessKeyContainer object. Check to make sure
|
|
* the object is successfully created.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
m_InternalRegKey.session_key = new CSessKeyContainer(®istry_key->session_key, &rc);
|
|
if ((m_InternalRegKey.session_key == NULL) || (rc != GCC_NO_ERROR))
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CRegKeyContainer: Error creating new CSessKeyContainer"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
goto MyExit;
|
|
}
|
|
|
|
/*
|
|
* Save the resource ID if the CSessKeyContainer was successfully created.
|
|
*/
|
|
if (NULL == (m_InternalRegKey.poszResourceID = ::My_strdupO2(
|
|
registry_key->resource_id.value,
|
|
registry_key->resource_id.length)))
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CRegKeyContainer: Error creating resource id"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
// goto MyExit;
|
|
}
|
|
|
|
MyExit:
|
|
|
|
*pRetCode = rc;
|
|
}
|
|
|
|
|
|
/*
|
|
* CRegKeyContainer()
|
|
*
|
|
* Public Function Description:
|
|
* This copy constructor is used to create a new CRegKeyContainer object
|
|
* from another CRegKeyContainer object.
|
|
*/
|
|
CRegKeyContainer::
|
|
CRegKeyContainer(CRegKeyContainer *registry_key, PGCCError pRetCode)
|
|
:
|
|
CRefCount(MAKE_STAMP_ID('R','e','g','K')),
|
|
m_fValidRegKeyPDU(FALSE),
|
|
m_cbDataSize(0)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
/*
|
|
* Initialize instance variables.
|
|
*/
|
|
::ZeroMemory(&m_InternalRegKey, sizeof(m_InternalRegKey));
|
|
::ZeroMemory(&m_RegKeyPDU, sizeof(m_RegKeyPDU));
|
|
|
|
/*
|
|
* Copy the Session Key portion of the Registry Key using the copy
|
|
* constructor of the CSessKeyContainer class. Check to make sure the
|
|
* CSessKeyContainer object is successfully created.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
m_InternalRegKey.session_key = new CSessKeyContainer(registry_key->m_InternalRegKey.session_key, &rc);
|
|
if ((m_InternalRegKey.session_key == NULL) || (rc != GCC_NO_ERROR))
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CRegKeyContainer: Error creating new CSessKeyContainer"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
goto MyExit;
|
|
}
|
|
|
|
/*
|
|
* Save the resource ID if the CSessKeyContainer was saved correctly.
|
|
* Store the resource ID in a Rogue Wave string container.
|
|
*/
|
|
if (NULL == (m_InternalRegKey.poszResourceID = ::My_strdupO(
|
|
registry_key->m_InternalRegKey.poszResourceID)))
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CRegKeyContainer: Error creating new resource id"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
// goto MyExit;
|
|
}
|
|
|
|
MyExit:
|
|
|
|
*pRetCode = rc;
|
|
}
|
|
|
|
|
|
/*
|
|
* ~CRegKeyContainer()
|
|
*
|
|
* Public Function Description
|
|
* The CRegKeyContainer destructor is responsible for freeing any memory
|
|
* allocated to hold the registry key data.
|
|
*
|
|
*/
|
|
CRegKeyContainer::
|
|
~CRegKeyContainer(void)
|
|
{
|
|
/*
|
|
* If "PDU" data has been allocated for this object, free it now.
|
|
*/
|
|
if (m_fValidRegKeyPDU)
|
|
{
|
|
FreeRegistryKeyDataPDU();
|
|
}
|
|
|
|
/*
|
|
* Delete any registry key data held internally.
|
|
*/
|
|
if (NULL != m_InternalRegKey.session_key)
|
|
{
|
|
m_InternalRegKey.session_key->Release();
|
|
}
|
|
delete m_InternalRegKey.poszResourceID;
|
|
}
|
|
|
|
|
|
/*
|
|
* LockRegistryKeyData ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine locks the registry key data and determines the amount of
|
|
* memory referenced by the "API" registry key structure.
|
|
*/
|
|
UINT CRegKeyContainer::
|
|
LockRegistryKeyData(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 registry key
|
|
* structure. Otherwise, just increment the lock count.
|
|
*/
|
|
if (Lock() == 1)
|
|
{
|
|
/*
|
|
* Lock the data for the session key by using the "Lock" routine of
|
|
* the internal CSessKeyContainer object. Determine the amount of memory
|
|
* necessary to hold the data referenced by the "API" registry key
|
|
* structure. The referenced data consists of data for the object key
|
|
* as well as data for the resource ID octet string. The sizes for
|
|
* both of these memory blocks are rounded to occupy an even multiple
|
|
* of four-byte blocks, with the session key block being rounded at a
|
|
* lower level. The pointers to the internal objects were validated in
|
|
* the constructor.
|
|
*/
|
|
m_cbDataSize = m_InternalRegKey.session_key->LockSessionKeyData();
|
|
m_cbDataSize += m_InternalRegKey.poszResourceID->length;
|
|
m_cbDataSize = ROUNDTOBOUNDARY(m_cbDataSize);
|
|
}
|
|
|
|
return m_cbDataSize;
|
|
}
|
|
|
|
|
|
/*
|
|
* GetGCCRegistryKeyData ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine retrieves registry key data in the form of an "API"
|
|
* GCCRegistryKey. This routine is called after "locking" the registry
|
|
* key data.
|
|
*/
|
|
UINT CRegKeyContainer::
|
|
GetGCCRegistryKeyData(PGCCRegistryKey registry_key, LPBYTE memory)
|
|
{
|
|
UINT cbDataSizeToRet = 0;
|
|
|
|
/*
|
|
* If the registry key data has been locked, fill in the output structure
|
|
* and the data referenced by the structure. Call the "Get" routine for the
|
|
* SessionKey to fill in the session key data.
|
|
*/
|
|
if (GetLockCount() > 0)
|
|
{
|
|
UINT session_key_data_length;
|
|
LPBYTE data_memory = memory;
|
|
|
|
/*
|
|
* Fill in the output parameter which indicates the amount of memory
|
|
* used to hold all of the data associated with the registry key.
|
|
*/
|
|
cbDataSizeToRet = m_cbDataSize;
|
|
|
|
session_key_data_length = m_InternalRegKey.session_key->
|
|
GetGCCSessionKeyData(®istry_key->session_key, data_memory);
|
|
data_memory += session_key_data_length;
|
|
|
|
/*
|
|
* Move the memory pointer past the session key data. The length of
|
|
* the session key data is rounded to a four-byte boundary by the
|
|
* lower level routines. Set the resource ID octet string length
|
|
* and pointer and copy the octet string data into the memory block
|
|
* from the internal Rogue Wave string.
|
|
*/
|
|
registry_key->resource_id.value = data_memory;
|
|
registry_key->resource_id.length = m_InternalRegKey.poszResourceID->length;
|
|
|
|
::CopyMemory(data_memory, m_InternalRegKey.poszResourceID->value,
|
|
m_InternalRegKey.poszResourceID->length);
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::GetGCCRegistryKeyData Error Data Not Locked"));
|
|
}
|
|
|
|
return cbDataSizeToRet;
|
|
}
|
|
|
|
|
|
/*
|
|
* UnlockRegistryKeyData ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine decrements the lock count and frees the memory associated
|
|
* with the "API" registry key once the lock count reaches zero.
|
|
*/
|
|
void CRegKeyContainer::
|
|
UnLockRegistryKeyData(void)
|
|
{
|
|
if (Unlock(FALSE) == 0)
|
|
{
|
|
/*
|
|
* Unlock the data associated with the internal CSessKeyContainer.
|
|
*/
|
|
if (m_InternalRegKey.session_key != NULL)
|
|
{
|
|
m_InternalRegKey.session_key->UnLockSessionKeyData();
|
|
}
|
|
}
|
|
|
|
// we have to call Release() because we used Unlock(FALSE)
|
|
Release();
|
|
}
|
|
|
|
|
|
/*
|
|
* GetRegistryKeyDataPDU ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine converts the registry key from it's internal form of a
|
|
* REG_KEY structure into the "PDU" form which can be passed in
|
|
* to the ASN.1 encoder. A pointer to a "PDU" "RegistryKey" structure is
|
|
* returned.
|
|
*/
|
|
GCCError CRegKeyContainer::
|
|
GetRegistryKeyDataPDU(PRegistryKey registry_key)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
/*
|
|
* 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_fValidRegKeyPDU == FALSE)
|
|
{
|
|
m_fValidRegKeyPDU = TRUE;
|
|
|
|
/*
|
|
* Fill in the "PDU" registry key from the internal structure.
|
|
*/
|
|
if (m_InternalRegKey.session_key != NULL)
|
|
{
|
|
/*
|
|
* Fill in the session key portion of the registry key by using the
|
|
* "Get" routine of the internal CSessKeyContainer object.
|
|
*/
|
|
rc = m_InternalRegKey.session_key->GetSessionKeyDataPDU(&m_RegKeyPDU.session_key);
|
|
}
|
|
else
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
}
|
|
|
|
if (rc == GCC_NO_ERROR)
|
|
{
|
|
/*
|
|
* Fill in the "PDU" resource ID if no error has occurred.
|
|
*/
|
|
::CopyMemory(m_RegKeyPDU.resource_id.value,
|
|
m_InternalRegKey.poszResourceID->value,
|
|
m_InternalRegKey.poszResourceID->length);
|
|
|
|
m_RegKeyPDU.resource_id.length = m_InternalRegKey.poszResourceID->length;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Copy the internal PDU structure into the structure pointed to by the
|
|
* output parameter.
|
|
*/
|
|
*registry_key = m_RegKeyPDU;
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
* FreeRegistryKeyDataPDU ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine is used to free the registry key data held internally in
|
|
* the "PDU" form of a "RegistryKey".
|
|
*/
|
|
void CRegKeyContainer::
|
|
FreeRegistryKeyDataPDU(void)
|
|
{
|
|
if (m_fValidRegKeyPDU)
|
|
{
|
|
/*
|
|
* Set the flag indicating that PDU registry key data is no longer
|
|
* allocated.
|
|
*/
|
|
m_fValidRegKeyPDU = FALSE;
|
|
|
|
if (m_InternalRegKey.session_key != NULL)
|
|
{
|
|
m_InternalRegKey.session_key->FreeSessionKeyDataPDU();
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::FreeRegistryKeyDataPDU: Bad internal pointer"));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
GCCError CRegKeyContainer::
|
|
CreateRegistryKeyData(PGCCRegistryKey *ppRegKey)
|
|
{
|
|
GCCError rc;
|
|
|
|
DebugEntry(CRegKeyContainer::CreateRegistryKeyData);
|
|
|
|
/*
|
|
** Here we calculate the length of the bulk data. This
|
|
** includes the registry key and registry item. These objects are
|
|
** "locked" in order to determine how much bulk memory they will
|
|
** occupy.
|
|
*/
|
|
UINT cbKeySize = ROUNDTOBOUNDARY(sizeof(GCCRegistryKey));
|
|
UINT cbDataSize = LockRegistryKeyData() + cbKeySize;
|
|
LPBYTE pData;
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
if (NULL != (pData = new BYTE[cbDataSize]))
|
|
{
|
|
*ppRegKey = (PGCCRegistryKey) pData;
|
|
::ZeroMemory(pData, cbKeySize);
|
|
|
|
pData += cbKeySize;
|
|
GetGCCRegistryKeyData(*ppRegKey, pData);
|
|
|
|
rc = GCC_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::CreateRegistryKeyData: can't create GCCRegistryKey"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
}
|
|
|
|
// UnLock the registry key since it is no longer needed
|
|
UnLockRegistryKeyData();
|
|
|
|
DebugExitINT(CRegKeyContainer::CreateRegistryKeyData, rc);
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
* IsThisYourSessionKey ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine determines whether this registry key holds the specified
|
|
* session key.
|
|
*/
|
|
BOOL CRegKeyContainer::
|
|
IsThisYourSessionKey(CSessKeyContainer *session_key)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
CSessKeyContainer *session_key_data;
|
|
GCCError rc2;
|
|
|
|
DBG_SAVE_FILE_LINE
|
|
session_key_data = new CSessKeyContainer(session_key, &rc2);
|
|
if ((session_key_data != NULL) && (rc2 == GCC_NO_ERROR))
|
|
{
|
|
if (*session_key_data == *m_InternalRegKey.session_key)
|
|
{
|
|
fRet = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CRegKeyContainer::IsThisYourSessionKey: Error creating new CSessKeyContainer"));
|
|
}
|
|
|
|
if (NULL != session_key_data)
|
|
{
|
|
session_key_data->Release();
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
|
|
/*
|
|
* GetSessionKey ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine is used to retrieve the session key which is held within
|
|
* this registry key. The session key is returned in the form of a
|
|
* CSessKeyContainer container object.
|
|
*/
|
|
|
|
|
|
/*
|
|
* operator== ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine is used to determine whether or not two registry keys are
|
|
* equal in value.
|
|
*/
|
|
BOOL operator==(const CRegKeyContainer& registry_key_1, const CRegKeyContainer& registry_key_2)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
if ((registry_key_1.m_InternalRegKey.session_key != NULL) &&
|
|
(registry_key_2.m_InternalRegKey.session_key != NULL))
|
|
{
|
|
if (*registry_key_1.m_InternalRegKey.session_key ==
|
|
*registry_key_2.m_InternalRegKey.session_key)
|
|
{
|
|
if (0 == My_strcmpO(registry_key_1.m_InternalRegKey.poszResourceID,
|
|
registry_key_2.m_InternalRegKey.poszResourceID))
|
|
{
|
|
fRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return fRet;
|
|
}
|