📄 registry.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//+---------------------------------------------------------------------------------
//
//
// File:
// registry.cpp
//
// Contents:
//
// Contains the implementation for the actual change code of the registry.
//
//----------------------------------------------------------------------------------
// Includes ------------------------------------------------------------------
#ifdef UNDER_CE
#include "WinCEUtils.h"
#endif
#include "headers.h"
#ifndef UNDER_CE
#include <crtdbg.h>
#endif
static void _UnregisterLevel(
const REGENTRY * rRegEntry,
const int iCount,
const HKEY hkeyParent,
int & iPos);
#ifdef CE_NO_EXCEPTIONS
static HRESULT _RegisterCurrentLevel(
#else
static void _RegisterCurrentLevel(
#endif
const REGENTRY * rRegEntry,
const int iCount,
const char * strFileName,
const char ** astrAlternateFileNames,
const HKEY hkeyParent,
int & iPos);
static void _RemoveHKEYSubkeys(
const HKEY hkey);
static void _SkipChildEntries(
const REGENTRY * rRegEntry,
const int ciCount,
const int ciCurrentLevel,
int & iPos);
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: void RegisterRegEntry
//
// parameters:
//
// description:
// Called on DLLRegisterServer to add our keys to the registry.
// This function is parameter array driven, so all action can be
// defined in the rRegEntry case
//
// In case of an error the function will throw and it is possible
// that only parts of the rRegEntry array have been processed.
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef CE_NO_EXCEPTIONS
HRESULT RegisterRegEntry(
#else
void RegisterRegEntry(
#endif
const REGENTRY * rRegEntry, // @parm The array of registry entries
// to process
const int iCount, // @parm The number of elements in the
// registry array rRegEntry
const char * strFileName, // @parm The name of the DLL to be
// registered
const char ** astrAlternates, // @parm array of alternate file names
HKEY hkey // @parm The parent key to start the
// opening from
)
{
ASSERT (iCount > 0);
ASSERT (rRegEntry);
ASSERT (rRegEntry[0].iLevel == REG_ROOT);
int iPos = 0; // will point to the current position in the array,
// so inital we start at 0
#ifdef CE_NO_EXCEPTIONS
HRESULT hr = S_OK;
#endif
// loop over all entries
while (iPos < iCount)
{
#ifndef UNDER_CE
_RPT1(_CRT_WARN,"::RegisterRegEntry iPos:%i\n",iPos);
#endif
// Call the subfunction to register all the entries which share
// level 1
#ifdef CE_NO_EXCEPTIONS
hr = _RegisterCurrentLevel(
#else
_RegisterCurrentLevel(
#endif
rRegEntry, // the array
iCount, // maximum number of arguments
strFileName, // filename of the DLL
astrAlternates,
hkey, // this is the parent key, in this
// special case it is the root
iPos // the current position is passed
// as a reference parameter, it will
// change with the calls.
);
#ifdef CE_NO_EXCEPTIONS
if(FAILED(hr))
return hr;
#endif
// When we return to this point, we got iPos pointing
// - beyond elements in rRegEntry
// - at an entry in level 1
}
#ifdef CE_NO_EXCEPTIONS
return hr;
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: void UnregisterRegEntry
//
// parameters:
//
// description:
// Called on DLLUnregisterServer to remove keys from the registry.
// This function is parameter array driven, so all action can be
// defined in the rRegEntry case
//
// The function will try to proceed independent from erros, no error
// code is returned,
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void UnregisterRegEntry(
const REGENTRY * rRegEntry, // The array of registry entries
// to process
const int iCount, // The number of elements in the
// registry array rRegEntry
HKEY hkey // The parent key to start from
)
{
ASSERT (iCount > 0);
ASSERT (rRegEntry);
ASSERT (rRegEntry[0].iLevel == REG_ROOT);
int iPos = 0; // will point to the current position in the array,
// so inital we start at 0
// loop over all entries
while (iPos < iCount)
{
// Call the subfunction to unregister all the entries which share
// level 1
#ifndef UNDER_CE
_RPT1(_CRT_WARN,"::UnregisterRegEntry iPos:%i\n",iPos);
#endif
_UnregisterLevel(
rRegEntry, // the array
iCount, // maximum number of arguments
hkey, // this is the parent key, in this
// special case it is the root
iPos // the current position is passed
// as a reference parameter, it will
// change with the calls.
);
// When we return to this point, we got iPos pointing
// - beyond elements in rRegEntry
// - at an entry in level 1
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: static void _UnregisterLevel
//
// parameters:
//
// description:
// Called on DLLUnregisterServer and will remove all entries in
// rRegEntry which are on the same level and have the same parentkey.
//
// The function will try to proceed independent from erros, no error code is returned
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
static void _UnregisterLevel(
const REGENTRY * rRegEntry, // The array of registry entries
// to process
const int iCount, // The number of elements in the
// registry array rRegEntry
const HKEY hkeyParent, // The parent key for the current
// key
int & iPos // The current position in
// rRegEntry. A reference parameter!
)
{
ASSERT (iCount > 0);
ASSERT (rRegEntry);
ASSERT (iPos < iCount);
// The current level we will handle in this function
const int ciCurrentLevel = rRegEntry[iPos].iLevel;
// lets set the outer boundary
while (iPos < iCount)
{
if (ciCurrentLevel > rRegEntry[iPos].iLevel)
{
// oops ... we just moved into a parent level, we better
// return to the parent level !
return;
}
if (rRegEntry[iPos].iAction & UNREG_IGNORE)
{
// we will ignore the current key and all child levels
// of this key
_SkipChildEntries(rRegEntry, iCount, ciCurrentLevel, iPos);
// Either iPos is greater than ciCount or we returned to
// our level or a parent level of it
continue;
}
// now let's open the key we got here ....
long stat;
CHkey hkey;
#ifndef UNDER_CE
_RPT3(_CRT_WARN,"::_UnregisterLevel iLevel: %i iPos:%i key: %s\n", ciCurrentLevel, iPos, rRegEntry[iPos].strRegKey);
#endif
// Use lower security setting if we are only opening this key, not removing!
REGSAM regsam;
regsam = (rRegEntry[iPos].iAction & UNREG_OPEN) ?
KEY_ENUMERATE_SUB_KEYS : KEY_ALL_ACCESS;
stat = RegOpenKeyExA(
hkeyParent, // handle of open key
rRegEntry[iPos].strRegKey, // subkey to open
NULL, // reserved
regsam, // security access mask
&hkey.hkey // address of handle of open key
);
// Any action makes only sense if we could open the key at all !
if (stat != ERROR_SUCCESS)
{
// we couldn't open this thing, so lets forget about the sublevels
// we will ignore the current key and all child levels
// of this key
_SkipChildEntries(rRegEntry, iCount, ciCurrentLevel, iPos);
// Either iPos is greater than ciCount or we returned to
// our level or a parent level of it
continue;
}
if (rRegEntry[iPos].iAction & UNREG_REMOVE_AND_SUBKEYS)
{
// we are going to remove the current key and subkeys
_RemoveHKEYSubkeys(hkey.hkey);
// Lets close the current key ...
hkey.Close();
// ... and finaly delete the key
RegDeleteKeyA(hkeyParent, rRegEntry[iPos].strRegKey);
// we will ignore the current key and all child levels
// of this key
_SkipChildEntries(rRegEntry, iCount, ciCurrentLevel, iPos);
// Either iPos is greater than ciCount or we returned to
// our level or a parent level of it
continue;
}
if (rRegEntry[iPos].iAction & UNREG_OPEN)
{
// In this case we are asked to keep browsing into the subkeys
// This key will not be deleted!
// A requirement is that the next entry in the array is
// exactly one level deeper ! This will only be asserted, not
// verified in debug builds.
ASSERT(iPos + 1 < iCount);
ASSERT(ciCurrentLevel + 1 == rRegEntry[iPos+1].iLevel);
iPos ++;
_UnregisterLevel(
rRegEntry, // the array
iCount, // and it's size
hkey.hkey, // the parent key for the next level
iPos // the current position
// A reference parameter!
);
// At this point we are finished whith hkey as the current
// entry. Either iPos is greater than ciCount or we returned to
// our level or a parent level of it
continue;
}
if (rRegEntry[iPos].iAction & UNREG_REMOVE)
{
// In this case we are asked to remove the subkey. First we have
// to process all possible subkeys of it!
// This key will then be deleted!
// we need this to remove the key later
const char * pcRegString = rRegEntry[iPos].strRegKey;
iPos ++;
if (iPos < iCount)
{
// additional entries are available, are those child-levels
if (ciCurrentLevel + 1 == rRegEntry[iPos].iLevel)
{
// yes, so process those child-levels first
_UnregisterLevel(
rRegEntry, // the array
iCount, // and it's size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -