Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1110 lines
28 KiB

/*==========================================================================
*
* Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
*
* File: creg.cpp
* Content:
* This module contains the implementation of the CRegistry class.
* For a class description, see creg.h
*
* History:
* Date By Reason
* ==== == ======
* 07/16/99 rodtoll Created
* 08/18/99 rodtoll Added Register/UnRegister that can be used to
* allow COM objects to register themselves.
* 08/25/99 rodtoll Updated to provide read/write of binary (blob) data
* 10/05/99 rodtoll Added DPF_MODNAMEs
* 10/07/99 rodtoll Updated to work in Unicode
* 10/08/99 rodtoll Fixes to DeleteKey / Reg/UnReg for Win9X
* 10/15/99 rodtoll Plugged some memory leaks
* 10/27/99 pnewson added Open() call that takes a GUID
* 03/07/2001 rodtoll WINBUG #228288 - PREFIX bug
***************************************************************************/
#include "stdafx.h"
#include "creg.h"
#include "dndbg.h"
//#include "OSInd.h"
#include "dvosal.h"
#include "guidutil.h"
#define MODULE_ID CREGISTRY
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::CRegistry"
// CRegistry Constructor
//
// This is the default constructor for the registry class. It
// is used to construct a registry object which has not yet
// opened a handle to the registry. Open must be called before
// this object can be used.
//
// Parameters:
// N/A
//
// Returns:
// N/A
//
CRegistry::CRegistry( ): m_isOpen(FALSE)
{
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::CRegistry"
// CRegistry Copy Constructor
//
// This is the copy constructor for the class which attempts to
// open a new registry handle at the same point in the registry
// as the registry parameter. You must check the IsOpen function
// to see if the object was succesfully initialized.
//
// Parameters:
// const CRegistry &registry - The registry object to set this
// object to
//
// Returns:
// N/A
//
/*
CRegistry::CRegistry( const CRegistry &registry ): m_isOpen(FALSE)
{
Open( registry.GetBaseHandle(), FALSE );
}
*/
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::CRegistry"
// CRegistry Constructor
//
// This constructor attempts to open a registry connection using
// the given parameters. This is equivalent to calling the default
// constructor and then Open with the equivalent parameters.
//
// After using this constructor you should call IsOpen to see if
// the open succeeded.
//
// Parameters:
// HKEY branch - Identifies the branch of the registry to open
// a connect to. E.g. HKEY_LOCAL_MACHINE
// This can also be an HKEY which points to another
// open portion of the registry
// const TCHAR *pathName - A string specifiying the registry path
// to open within the key. NO leading
// slash is required and path is relative
// from the patch represented by the branch
// parameter.
// BOOL create - Set to TRUE to create the given path if it doesn't
// exist, FALSE otherwise.
//
// Returns:
// N/A
//
CRegistry::CRegistry( HKEY branch, LPWSTR pathName, BOOL create ): m_isOpen(FALSE) {
Open( branch, pathName, create );
}
// CRegistry Destructor
//
// This is the destructor for the class, and will close the connection
// to the registry if this object has one open.
//
// Parameters:
// N/A
//
// Returns:
// N/A
//
CRegistry::~CRegistry() {
if( m_isOpen ) {
Close();
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::DeleteSubKey"
// DeleteSubKey
//
// This function causes the key specified by the keyname parameter
// to be deleted from the point in the registry this object is rooted
// at, if the key exists. If the object does not have an open connection
// to the registry, or the keyName is not specified
//
// Parmaters:
// const TCHAR *keyName - key name to delete
//
// Returns:
// BOOL - returns TRUE on success, FALSE on failure
//
BOOL CRegistry::DeleteSubKey( const LPCWSTR keyName ) {
if( keyName == NULL || !IsOpen() ) return FALSE;
LONG retValue;
if( OSAL_IsUnicodePlatform() )
{
retValue = RegDeleteKeyW( m_regHandle, keyName );
}
else
{
LPSTR lpstrKeyName;
if( FAILED( OSAL_AllocAndConvertToANSI( &lpstrKeyName, keyName ) ) )
{
return FALSE;
}
else
{
retValue = RegDeleteKeyA( m_regHandle, lpstrKeyName );
delete [] lpstrKeyName;
}
}
return (retValue == ERROR_SUCCESS);
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::Open"
// Open
//
// This function opens a connection to the registry in the branch
// specified by branch with the path specified by pathName. If
// the path doesn't exist in the registry it will be created if
// the create parameters is set to true, otherwise the call will
// fail.
//
// If this object already has an open connection to the registry
// the previous connection will be closed before this one is
// attempted.
//
// Parameters:
// HKEY branch - A handle to a registry location where the open
// will be rooted. E.g. HKEY_LOCAL_MACHINE
// const TCHAR *path - The path relative to the root specified by
// branch where the registry connection will
// be opened.
// BOOL create - Settings this parameter conrols how this function
// handles opens on paths which don't exists. If set
// to TRUE the path will be created, if set to FALSE
// the function will fail if the path doesn't exist.
//
// Returns:
// BOOL - TRUE on success, FALSE on failure.
//
BOOL CRegistry::Open( HKEY branch, const LPCWSTR pathName, BOOL create ) {
DWORD dwResult; // Temp used in call to RegXXXX
LONG result; // used to store results
DNASSERT( pathName != NULL );
// Prefix found this. Ref Manbugs 29337
// There are some code paths where the pathName can legitimately be NULL,
// returning FALSE indicates a failure to open the registry key.
if( pathName == NULL )
{
return FALSE;
}
// If there is an open connection, close it.
if( m_isOpen ) {
Close();
}
if( OSAL_IsUnicodePlatform() )
{
// Create or open the key based on create parameter
if( create ) {
result = RegCreateKeyExW( branch, pathName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
NULL, &m_regHandle, &dwResult );
} else {
result = RegOpenKeyExW( branch, pathName, 0, KEY_ALL_ACCESS, &m_regHandle );
}
}
else
{
LPSTR lpszKeyName;
if( OSAL_AllocAndConvertToANSI( &lpszKeyName, pathName ) == S_OK )
{
if( create ) {
result = RegCreateKeyExA( branch, lpszKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
NULL, &m_regHandle, &dwResult );
} else {
result = RegOpenKeyExA( branch, lpszKeyName, 0, KEY_ALL_ACCESS, &m_regHandle );
}
delete [] lpszKeyName;
}
else
{
return FALSE;
}
}
// If succesful, initialize object, otherwise set it to
// not open state.
if( result == ERROR_SUCCESS ) {
m_isOpen = TRUE;
m_baseHandle = branch;
return TRUE;
} else {
m_isOpen = FALSE;
return FALSE;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::Open"
// Open
//
// This function opens a connection to the registry in the branch
// specified by branch with the path specified by pathName. If
// the path doesn't exist in the registry it will be created if
// the create parameters is set to true, otherwise the call will
// fail.
//
// In this version of the function, the path is specified as
// a guid instead of a string. The function will attempt to open
// a key with a name in the form "{CB4961DB-D2FA-43f3-942A-991D9294DDBB}"
// that corresponds to the guid as you would expect.
//
// If this object already has an open connection to the registry
// the previous connection will be closed before this one is
// attempted.
//
// Parameters:
// HKEY branch - A handle to a registry location where the open
// will be rooted. E.g. HKEY_LOCAL_MACHINE
// const LPGUID lpguid - The path relative to the root specified by
// branch where the registry connection will
// be opened. See comment above.
// BOOL create - Settings this parameter controls how this function
// handles opens on paths which don't exist. If set
// to TRUE the path will be created, if set to FALSE
// the function will fail if the path doesn't exist.
//
// Returns:
// BOOL - TRUE on success, FALSE on failure.
//
BOOL CRegistry::Open( HKEY branch, const GUID* lpguid, BOOL create )
{
WCHAR wszGuidString[GUID_STRING_LEN];
HRESULT hr;
DNASSERT( lpguid != NULL );
// If there is an open connection, close it.
if( m_isOpen ) {
Close();
}
// convert the guid to a string
hr = DVStringFromGUID(lpguid, wszGuidString, GUID_STRING_LEN);
if (FAILED(hr))
{
DPF(DVF_ERRORLEVEL, "DVStringFromGUID failed");
return FALSE;
}
return Open(branch, wszGuidString, create);
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::Close"
// Close
//
// This function will close an open connection to the registry
// if this object has one. Otherwise it does nothing.
//
// Parameters:
// N/A
//
// Returns:
// BOOL - Returns TRUE on success, FALSE on failure. If the object
// is not open it will return TRUE.
//
BOOL CRegistry::Close() {
LONG retValue;
if( m_isOpen ) {
retValue = RegCloseKey( m_regHandle );
if( retValue == ERROR_SUCCESS )
{
m_isOpen = FALSE;
return TRUE;
}
else
{
return FALSE;
}
} else {
return TRUE;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::EnumKeys"
// EnumKeys
//
// This function can be used to enumerate the keys at the point
// in the registry rooted at the root this object was opened
// with, at the path specified when opening the object.
//
// To properly enumerate the keys you should pass 0 as the index on
// the first call, and increment the index parameter by one on each
// call. You can stop enumerating when the function returns FALSE.
//
// Parameters:
// BFC_STRING &name - The current key in the enumeration will be returned
// in this string. Unless the enumeration fails or
// ended at which case this parameter won't be touched.
//
// DWORD index - The current enum index. See above for details.
//
// Returns:
// BOOL - FALSE when enumeration is done or on error, TRUE otherwise.
//
BOOL CRegistry::EnumKeys( LPWSTR lpwStrName, LPDWORD lpdwStringLen, DWORD index )
{
if( OSAL_IsUnicodePlatform() )
{
wchar_t buffer[MAX_REGISTRY_STRING_SIZE];
DWORD bufferSize = MAX_REGISTRY_STRING_SIZE;
FILETIME tmpTime;
if( RegEnumKeyExW( m_regHandle, index, buffer, &bufferSize, NULL, NULL, NULL, &tmpTime ) != ERROR_SUCCESS )
{
return FALSE;
}
else
{
if( bufferSize+1 > *lpdwStringLen )
{
*lpdwStringLen = bufferSize+1;
return FALSE;
}
lstrcpyW( lpwStrName, buffer );
*lpdwStringLen = bufferSize+1;
return TRUE;
}
}
else
{
char buffer[MAX_REGISTRY_STRING_SIZE];
DWORD bufferSize = MAX_REGISTRY_STRING_SIZE;
FILETIME tmpTime;
if( RegEnumKeyExA( m_regHandle, index, buffer, &bufferSize, NULL, NULL, NULL, &tmpTime ) != ERROR_SUCCESS )
{
return FALSE;
}
else
{
if( bufferSize+1 > *lpdwStringLen )
{
*lpdwStringLen = bufferSize+1;
return FALSE;
}
if( OSAL_AnsiToWide( lpwStrName, buffer, *lpdwStringLen ) == 0 )
{
return FALSE;
}
else
{
*lpdwStringLen = bufferSize+1;
return TRUE;
}
}
}
}
// This comment documents ALL of the Read<Data Type> functions which
// follow.
//
// CRegistry Read<Data Type> Functions
//
// The set of ReadXXXXX functions for the CRegistry class are
// responsible for reading <data type> type data from the registry.
// The object must have an open connection to the registry before
// any of these functions may be used. A connection to the registry
// can be made with the Open call or the constructors.
//
// Parameters:
// const TCHAR *keyName - The keyname of the data you wish to read
// <datatype> & - A reference to the specific data type where
// the data will be placed on a succesful read.
// This parameter will be unaffected if the read
// fails.
//
// Returns:
// BOOL - Returns TRUE on success, FALSE on failure.
//
// This comment documents ALL of the Write<Data Type> functions which
// follow.
//
// CRegistry Write<Data Type> Functions
//
// The set of Write<Data Type> functions for the CRegistry class are
// responsible for writing <data type> type data to the registry.
// The object must have an open connection to the registry before
// any of these functions may be used. A connection to the registry
// can be made with the Open call or the constructors.
//
// Parameters:
// const TCHAR *keyName - The keyname of the data you wish to write
// <datatype> & - A reference to the specific data type which
// contains the data to be written to the registry.
//
// Returns:
// BOOL - Returns TRUE on success, FALSE on failure.
//
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::WriteString"
// WriteString
//
// Writes Strings's to the registry, see block comment above
// for details.
//
BOOL CRegistry::WriteString( LPCWSTR keyName, const LPCWSTR lpwstrValue )
{
LONG retValue;
// Found by PREFIX: Millen Bug #129154, ManBugs:29338
// lpwstrValue could conceivably be NULL and the
if( keyName == NULL || !IsOpen() || lpwstrValue == NULL ) return FALSE;
if( OSAL_IsUnicodePlatform() )
{
retValue = RegSetValueExW( m_regHandle, keyName, 0, REG_SZ, (const unsigned char *) lpwstrValue, (lstrlenW( lpwstrValue )+1)*sizeof(wchar_t) );
}
else
{
LPSTR lpstrKeyName;
LPSTR lpstrValue;
if( FAILED( OSAL_AllocAndConvertToANSI( &lpstrKeyName, keyName ) ) )
{
return FALSE;
}
if( FAILED( OSAL_AllocAndConvertToANSI( &lpstrValue, lpwstrValue ) ) )
{
delete [] lpstrKeyName;
return FALSE;
}
retValue = RegSetValueExA( m_regHandle, lpstrKeyName, 0, REG_SZ, (const unsigned char *) lpstrValue, lstrlenA( lpstrValue )+1 );
delete [] lpstrKeyName;
delete [] lpstrValue;
}
return (retValue == ERROR_SUCCESS);
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::ReadString"
// ReadString
//
// Reads CString's from the registry, see block comment above
// for details.
//
BOOL CRegistry::ReadString( const LPCWSTR keyName, LPWSTR lpwstrValue, LPDWORD lpdwLength )
{
if( keyName == NULL || !IsOpen() ) return FALSE;
LONG retValue;
DWORD tmpSize;;
DWORD tmpType;
if( OSAL_IsUnicodePlatform() )
{
wchar_t buffer[MAX_REGISTRY_STRING_SIZE];
tmpSize = MAX_REGISTRY_STRING_SIZE*sizeof(wchar_t);
retValue = RegQueryValueExW( m_regHandle, keyName, 0, &tmpType, (unsigned char *) &buffer[0], &tmpSize );
if( retValue != ERROR_SUCCESS )
{
return FALSE;
}
if( (tmpSize/2) > *lpdwLength )
{
*lpdwLength = (tmpSize/2);
return FALSE;
}
lstrcpyW( lpwstrValue, buffer );
*lpdwLength = (tmpSize/2);
return TRUE;
}
else
{
LPSTR lpstrKeyName;
char buffer[MAX_REGISTRY_STRING_SIZE];
tmpSize = MAX_REGISTRY_STRING_SIZE;
if( FAILED( OSAL_AllocAndConvertToANSI( &lpstrKeyName, keyName ) ) )
return FALSE;
retValue = RegQueryValueExA( m_regHandle, lpstrKeyName, 0, &tmpType, (unsigned char *) &buffer[0], &tmpSize );
delete [] lpstrKeyName;
if( retValue != ERROR_SUCCESS )
{
return FALSE;
}
if( tmpSize > *lpdwLength )
{
*lpdwLength = tmpSize;
return FALSE;
}
if( OSAL_AnsiToWide( lpwstrValue, buffer, *lpdwLength ) == 0 )
return FALSE;
*lpdwLength = tmpSize;
}
if( retValue == ERROR_SUCCESS && tmpType == REG_SZ ) {
return TRUE;
} else {
return FALSE;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::WriteGUID"
// WriteGUID
//
// Writes GUID's to the registry, see block comment above
// for details. The GUID is written in the format it is usually
// displayed. (But without the '{''s).
//
BOOL CRegistry::WriteGUID( LPCWSTR keyName, const GUID &guid )
{
LONG retValue;
WCHAR wszGuidString[GUID_STRING_LEN];
HRESULT hr;
hr = DVStringFromGUID(&guid, wszGuidString, GUID_STRING_LEN);
if (FAILED(hr))
{
DPF(DVF_ERRORLEVEL, "DVStringFromGUID failed, code: %i", hr);
return FALSE;
}
if( OSAL_IsUnicodePlatform() )
{
retValue = RegSetValueExW( m_regHandle, keyName, 0, REG_SZ, (const unsigned char *) wszGuidString, (lstrlenW( wszGuidString )+1)*sizeof(wchar_t) );
}
else
{
LPSTR lpstrKeyName;
LPSTR lpstrKeyValue;
hr = OSAL_AllocAndConvertToANSI( &lpstrKeyName, keyName );
if (FAILED(hr))
{
DPF(DVF_ERRORLEVEL, "DVStringFromGUID failed, code: %i", hr);
return FALSE;
}
hr = OSAL_AllocAndConvertToANSI( &lpstrKeyValue, wszGuidString );
if (FAILED(hr))
{
DPF(DVF_ERRORLEVEL, "DVStringFromGUID failed, code: %i", hr);
delete [] lpstrKeyName;
return FALSE;
}
retValue = RegSetValueExA( m_regHandle, lpstrKeyName, 0, REG_SZ, (const unsigned char *) lpstrKeyValue, lstrlenA( lpstrKeyValue )+1);
delete [] lpstrKeyName;
delete [] lpstrKeyValue;
}
if( retValue == ERROR_SUCCESS )
return TRUE;
else
return FALSE;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::ReadGUID"
// ReadGUID
//
// Reads GUID's from the registry, see block comment above
// for details. The GUID must be stored in the format written by
// the WriteGUID function or it will not be read correctly.
//
BOOL CRegistry::ReadGUID( LPCWSTR keyName, GUID &guid )
{
wchar_t buffer[MAX_REGISTRY_STRING_SIZE];
DWORD dwLength = MAX_REGISTRY_STRING_SIZE;
HRESULT hr;
if( !ReadString( keyName, buffer, &dwLength ) )
{
return FALSE;
}
else
{
hr = DVGUIDFromString(buffer, &guid);
if (FAILED(hr))
{
DPF(DVF_ERRORLEVEL, "DVGUIDFromString failed, code: %i", hr);
return FALSE;
}
return TRUE;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::WriteDWORD"
// WriteDWORD
//
// Writes DWORDS to the registry, see block comment above
// for details.
//
BOOL CRegistry::WriteDWORD( LPCWSTR keyName, DWORD value ) {
LONG retValue;
if( keyName == NULL || !IsOpen() ) return FALSE;
if( OSAL_IsUnicodePlatform() )
{
retValue = RegSetValueExW( m_regHandle, keyName, 0, REG_DWORD, (const unsigned char *) &value, sizeof( DWORD ) );
}
else
{
LPSTR lpszKeyName;
if( FAILED( OSAL_AllocAndConvertToANSI( &lpszKeyName, keyName ) ) )
return FALSE;
retValue = RegSetValueExA( m_regHandle, lpszKeyName, 0, REG_DWORD, (const unsigned char *) &value, sizeof( DWORD ) );
delete [] lpszKeyName;
}
return (retValue == ERROR_SUCCESS);
}
#undef DPF_MODNAME
#define DPF_MODNAME "Cregistry::ReadBOOL"
BOOL CRegistry::ReadBOOL( LPCWSTR keyName, BOOL &result )
{
DWORD tmpResult;
if( ReadDWORD( keyName, tmpResult ) )
{
result = (BOOL) tmpResult;
return TRUE;
}
else
{
return FALSE;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::WriteBOOL"
BOOL CRegistry::WriteBOOL( LPCWSTR keyName, BOOL value )
{
DWORD tmpValue = (DWORD) value;
return WriteDWORD( keyName, tmpValue );
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::ReadDWORD"
// ReadDWORD
//
// Reads DWORDS from the registry, see block comment above
// for details.
//
BOOL CRegistry::ReadDWORD( LPCWSTR keyName, DWORD &result ) {
if( keyName == NULL || !IsOpen() ) return FALSE;
LONG retValue;
DWORD tmpValue;
DWORD tmpType;
DWORD tmpSize;
tmpSize = sizeof( DWORD );
if( OSAL_IsUnicodePlatform() )
{
retValue = RegQueryValueExW( m_regHandle, keyName, 0, &tmpType, (unsigned char *) &tmpValue, &tmpSize );
}
else
{
LPSTR lpszKeyName;
if( FAILED( OSAL_AllocAndConvertToANSI( &lpszKeyName, keyName ) ) )
return FALSE;
retValue = RegQueryValueExA( m_regHandle, lpszKeyName, 0, &tmpType, (unsigned char *) &tmpValue, &tmpSize );
delete [] lpszKeyName;
}
if( retValue == ERROR_SUCCESS && tmpType == REG_DWORD ) {
result = tmpValue;
return TRUE;
} else {
return FALSE;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::Register"
BOOL CRegistry::Register( LPCWSTR lpszProgID, const LPCWSTR lpszDesc, const LPCWSTR lpszProgName, GUID guidCLSID, LPCWSTR lpszVerIndProgID )
{
CRegistry core;
DNASSERT( lpszDesc != NULL );
DNASSERT( lpszProgID != NULL );
// Build a string representation of the GUID from the GUID
wchar_t lpszGUID[MAX_REGISTRY_STRING_SIZE];
wchar_t lpszKeyName[_MAX_PATH];
swprintf( lpszGUID, L"{%-08.8X-%-04.4X-%-04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}", guidCLSID.Data1, guidCLSID.Data2, guidCLSID.Data3,
guidCLSID.Data4[0], guidCLSID.Data4[1], guidCLSID.Data4[2], guidCLSID.Data4[3],
guidCLSID.Data4[4], guidCLSID.Data4[5], guidCLSID.Data4[6], guidCLSID.Data4[7] );
// Write the HKEY_CLASSES_ROOT\CLSID\{GUID} section
swprintf( lpszKeyName, L"CLSID\\%s", lpszGUID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create registry key %s", lpszKeyName );
return FALSE;
}
core.WriteString( L"", lpszDesc );
core.Close();
// Write the HKEY_CLASSES_ROOT\CLSID\{GUID}\InProcServer32 section
swprintf( lpszKeyName, L"CLSID\\%s\\InProcServer32", lpszGUID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create registry key %s", lpszKeyName );
return FALSE;
}
core.WriteString( L"", lpszProgName );
core.WriteString( L"ThreadingModel", L"Both" );
core.Close();
// Write the HKEY_CLASSES_ROOT\CLSID\{GUID}\VersionIndependentProgID section
if( lpszVerIndProgID != NULL )
{
swprintf( lpszKeyName, L"CLSID\\%s\\VersionIndependentProgID", lpszGUID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create verind registry key %s", lpszKeyName );
return FALSE;
}
core.WriteString( L"", lpszVerIndProgID );
core.Close();
}
// Write the HKEY_CLASSES_ROOT\CLSID\{GUID}\ProgID section
swprintf( lpszKeyName, L"CLSID\\%s\\ProgID", lpszGUID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create verind registry key %s", lpszKeyName );
return FALSE;
}
core.WriteString( L"", lpszProgID );
core.Close();
// Write The VersionIND ProgID
if( lpszVerIndProgID != NULL )
{
if( !core.Open( HKEY_CLASSES_ROOT, lpszVerIndProgID ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create reg key %s", lpszVerIndProgID );
}
else
{
core.WriteString( L"", lpszDesc );
core.Close();
}
swprintf( lpszKeyName, L"%s\\CLSID", lpszVerIndProgID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create reg key %s", lpszKeyName );
}
else
{
core.WriteString( L"", lpszGUID );
core.Close();
}
swprintf( lpszKeyName, L"%s\\CurVer", lpszVerIndProgID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create reg key %s", lpszKeyName );
}
else
{
core.WriteString( L"", lpszProgID );
core.Close();
}
}
if( !core.Open( HKEY_CLASSES_ROOT, lpszProgID ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create reg key %s", lpszKeyName );
}
else
{
core.WriteString( L"", lpszDesc );
core.Close();
}
swprintf( lpszKeyName, L"%s\\CLSID", lpszProgID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open/create reg key %s", lpszKeyName );
}
else
{
core.WriteString( L"", lpszGUID );
core.Close();
}
return TRUE;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::UnRegister"
BOOL CRegistry::UnRegister( GUID guidCLSID )
{
CRegistry core, cregClasses, cregSub;
// Build a string representation of the GUID from the GUID
wchar_t lpszGUID[MAX_REGISTRY_STRING_SIZE];
wchar_t lpszKeyName[_MAX_PATH];
wchar_t szProgID[MAX_REGISTRY_STRING_SIZE];
wchar_t szVerIndProgID[MAX_REGISTRY_STRING_SIZE];
DWORD dwSize = MAX_REGISTRY_STRING_SIZE;
swprintf( lpszGUID, L"{%-08.8X-%-04.4X-%-04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}", guidCLSID.Data1, guidCLSID.Data2, guidCLSID.Data3,
guidCLSID.Data4[0], guidCLSID.Data4[1], guidCLSID.Data4[2], guidCLSID.Data4[3],
guidCLSID.Data4[4], guidCLSID.Data4[5], guidCLSID.Data4[6], guidCLSID.Data4[7] );
if( !cregClasses.Open( HKEY_CLASSES_ROOT, L"" ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open HKEY_CLASSES_ROOT" );
return FALSE;
}
// Write the HKEY_CLASSES_ROOT\CLSID\{GUID} section
swprintf( lpszKeyName, L"CLSID\\%s\\ProgID", lpszGUID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open %s", lpszKeyName );
return FALSE;
}
dwSize = MAX_REGISTRY_STRING_SIZE;
if( core.ReadString( L"", szProgID, &dwSize ) )
{
swprintf( lpszKeyName, L"%s\\CLSID", szProgID );
if( !cregClasses.DeleteSubKey( lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete %s", lpszKeyName );
return FALSE;
}
if( !cregClasses.DeleteSubKey( szProgID ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete HKEY_CLASSES_ROOT/ProgID" );
return FALSE;
}
}
core.Close();
swprintf( lpszKeyName, L"CLSID\\%s\\VersionIndependentProgID", lpszGUID );
if( !core.Open( HKEY_CLASSES_ROOT, lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to open %s", lpszKeyName );
return FALSE;
}
dwSize = MAX_REGISTRY_STRING_SIZE;
if( core.ReadString( L"", szVerIndProgID, &dwSize ) )
{
swprintf( lpszKeyName, L"%s\\CLSID", szVerIndProgID );
if( !cregClasses.DeleteSubKey( lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete %s", lpszKeyName );
return FALSE;
}
swprintf( lpszKeyName, L"%s\\CurVer", szVerIndProgID );
if( !cregClasses.DeleteSubKey( lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete %s", lpszKeyName );
return FALSE;
}
if( !cregClasses.DeleteSubKey( szVerIndProgID ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete HKEY_CLASSES_ROOT/%s", szVerIndProgID);
return FALSE;
}
}
core.Close();
swprintf( lpszKeyName, L"CLSID\\%s\\InprocServer32", lpszGUID );
if( !cregClasses.DeleteSubKey( lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete %s", lpszKeyName );
return FALSE;
}
swprintf( lpszKeyName, L"CLSID\\%s\\ProgID", lpszGUID );
if( !cregClasses.DeleteSubKey( lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete %s", lpszKeyName );
return FALSE;
}
swprintf( lpszKeyName, L"CLSID\\%s\\VersionIndependentProgID", lpszGUID );
if( !cregClasses.DeleteSubKey( lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete %s", lpszKeyName );
return FALSE;
}
swprintf( lpszKeyName, L"CLSID\\%s", lpszGUID );
if( !cregClasses.DeleteSubKey( lpszKeyName ) )
{
DPF( DVF_ERRORLEVEL, "Unable to delete %s", lpszKeyName );
return FALSE;
}
return TRUE;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::ReadBlob"
BOOL CRegistry::ReadBlob( LPCWSTR keyName, LPBYTE lpbBuffer, LPDWORD lpdwSize )
{
if( keyName == NULL || !IsOpen() ) return FALSE;
LONG retValue;
DWORD tmpType;
if( OSAL_IsUnicodePlatform() )
{
retValue = RegQueryValueExW( m_regHandle, keyName, 0, &tmpType, lpbBuffer, lpdwSize );
}
else
{
LPSTR lpszKeyName;
if( FAILED( OSAL_AllocAndConvertToANSI( &lpszKeyName, keyName ) ) )
return FALSE;
retValue = RegQueryValueExA( m_regHandle, lpszKeyName, 0, &tmpType, lpbBuffer, lpdwSize );
delete [] lpszKeyName;
}
if( retValue == ERROR_SUCCESS && tmpType == REG_BINARY ) {
return TRUE;
} else {
return FALSE;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CRegistry::WriteBlob"
BOOL CRegistry::WriteBlob( LPCWSTR keyName, LPBYTE lpbBuffer, DWORD dwSize )
{
LONG retValue;
if( keyName == NULL || !IsOpen() ) return FALSE;
if( OSAL_IsUnicodePlatform() )
{
retValue = RegSetValueExW( m_regHandle, keyName, 0, REG_BINARY, lpbBuffer, dwSize );
}
else
{
LPSTR lpszKeyName;
if( FAILED( OSAL_AllocAndConvertToANSI( &lpszKeyName, keyName ) ) )
return FALSE;
retValue = RegSetValueExA( m_regHandle, lpszKeyName, 0, REG_BINARY, lpbBuffer, dwSize );
delete [] lpszKeyName;
}
return (retValue == ERROR_SUCCESS);
}