|
|
#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; }
|