Leaked source code of windows server 2003
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.
 
 
 
 
 
 

691 lines
20 KiB

//////////////////////////////////////////////////////////////////////////////
//
// File Name: fxocReg.cpp
//
// Abstract: This provides the registry routines used in the FaxOCM
// code base.
//
// Environment: Windows XP / User Mode
//
// Copyright (c) 2000 Microsoft Corporation
//
// Revision History:
//
// Date: Developer: Comments:
// ----- ---------- ---------
// 21-Mar-2000 Oren Rosenbloom (orenr) Created
//////////////////////////////////////////////////////////////////////////////
#include "faxocm.h"
#pragma hdrstop
#include <Loadperf.h>
//////////////////////// Static Function Prototypes ////////////////////////
static DWORD prv_InstallDynamicRegistry(const TCHAR *pszSection);
static DWORD prv_UninstallDynamicRegistry(const TCHAR *pszSection);
static DWORD prv_CreatePerformanceCounters(void);
static DWORD prv_DeletePerformanceCounters(void);
void prv_AddSecurityPrefix(void);
///////////////////////////////
// fxocReg_Init
//
// Initialize registry handling
// subsystem
//
// Params:
// - void
// Returns:
// - NO_ERROR on success
// - error code otherwise
//
DWORD fxocReg_Init(void)
{
DWORD dwRes = NO_ERROR;
DBG_ENTER(_T("Init Registry Module"),dwRes);
return dwRes;
}
///////////////////////////////
// fxocReg_Term
//
// Terminate the registry handling
// subsystem
//
// Params:
// - void
// Returns:
// - NO_ERROR on success
// - error code otherwise
//
DWORD fxocReg_Term(void)
{
DWORD dwRes = NO_ERROR;
DBG_ENTER(_T("Term Registry Module"),dwRes);
return dwRes;
}
///////////////////////////////
// fxocReg_Install
//
// Create registry settings as
// specified in INF file, as well
// as dynamic settings that can only
// be done at run time (such as
// performance counter setup, etc).
//
// Params:
// - pszSubcomponentId
// - pszInstallSection
// Returns:
// - NO_ERROR on success
// - error code otherwise
//
DWORD fxocReg_Install(const TCHAR *pszSubcomponentId,
const TCHAR *pszInstallSection)
{
DWORD dwReturn = NO_ERROR;
DWORD dwNumDevices = 0;
HINF hInf = faxocm_GetComponentInf();
DBG_ENTER( _T("fxocReg_Install"),
dwReturn,
_T("%s - %s"),
pszSubcomponentId,
pszInstallSection);
if (pszInstallSection == NULL)
{
return ERROR_INVALID_PARAMETER;
}
// Set up the static registry data found in the INF file
// This will perform all necessary install steps as specified
// by the SPINST_* flags below. Since we already queued up our
// files to be copied, we are using this API only to setup our
// registry settings as specified in the FAX install section in
// the INF file.
// Notice that this function works both for installing and uninstalling.
// It determines whether to install or uninstall based on the "pszSection"
// parameter passed in from the INF file. The INF file will be structured
// such that the install sections will have 'AddReg', etc, while the
// uninstall sections will have 'DelReg', etc.
// Lastly, notice the SPINST_* flags specified. We tell it to install
// everything (via SPINST_ALL) with the exception of FILES since they
// were copied over by the QUEUE_OPS operation before, and with the
// exception of PROFILEITEMS (shortcut link creation) because we want
// to do that only after we have confirmed everything has succeeded.
// Shortcut links are explictely created/deleted in faxocm.cpp (via
// fxocLink_Install/fxocLink_Uninstall functions)
dwReturn = fxocUtil_DoSetup(
hInf,
pszInstallSection,
TRUE,
SPINST_ALL & ~(SPINST_FILES | SPINST_PROFILEITEMS),
_T("fxocReg_Install"));
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,
_T("Successfully installed static registry ")
_T("settings as specified in INF file"));
// Place any dynamic registry data you need to create on the fly
// here.
//
dwReturn = prv_InstallDynamicRegistry(pszInstallSection);
}
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,
_T("Registry Install, installing performance ")
_T("counters..."));
// first delete any performance counters we have before
prv_DeletePerformanceCounters();
// install performance counters
prv_CreatePerformanceCounters();
}
// now do RegSvr for platform dependent DLLs
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,_T("Registry Install, Doing REGSVR"));
dwReturn = fxocUtil_SearchAndExecute(pszInstallSection,INF_KEYWORD_REGISTER_DLL_PLATFORM,SPINST_REGSVR,NULL);
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,
_T("Successfully Registered Fax DLLs - platform dependent")
_T("from INF file, section '%s'"),
pszInstallSection);
}
else
{
VERBOSE(SETUP_ERR,
_T("Failed to Registered Fax DLLs - platform dependent")
_T("from INF file, section '%s', dwReturn = 0x%lx"),
pszInstallSection,
dwReturn);
}
}
// now do AddReg for platform dependent registry settings
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,_T("Registry Install, Doing AddReg_Platform"));
dwReturn = fxocUtil_SearchAndExecute(pszInstallSection,INF_KEYWORD_ADDREG_PLATFORM,SPINST_REGISTRY,NULL);
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,
_T("Successfully Installed Registry- platform dependent")
_T("from INF file, section '%s'"),
pszInstallSection);
}
else
{
VERBOSE(SETUP_ERR,
_T("Failed to Install Registry- platform dependent")
_T("from INF file, section '%s', dwReturn = 0x%lx"),
pszInstallSection,
dwReturn);
}
}
// When upgrading from SB3 to >=RC1, need to pre-pend FAX_REG_SECURITY_PREFIX
// to all encripted data
if (dwReturn == NO_ERROR &&
fxState_IsUpgrade() == FXSTATE_UPGRADE_TYPE_XP_DOT_NET)
{
prv_AddSecurityPrefix();
}
// now write the version and SKU into the registry
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,_T("Registry Install, Doing SKU and Version"));
HKEY hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE,REGKEY_FAX_SETUP,FALSE,KEY_WRITE);
if (hKey==NULL)
{
dwReturn = GetLastError();
VERBOSE(SETUP_ERR,
_T("Failed to open fax setup registry, dwReturn = 0x%lx"),
dwReturn);
return dwReturn;
}
// write the SKU into the registry
if (!SetRegistryDword(hKey,REGVAL_PRODUCT_SKU,GetProductSKU()))
{
dwReturn = GetLastError();
VERBOSE(SETUP_ERR,
_T("SetRegistryDword REGVAL_PRODUCT_SKU failed , dwReturn = 0x%lx"),
dwReturn);
}
// write the fax version into the registry
if (!SetRegistryDword(hKey,REGVAL_PRODUCT_BUILD,GetProductBuild()))
{
dwReturn = GetLastError();
VERBOSE(SETUP_ERR,
_T("SetRegistryDword REGVAL_PRODUCT_VERSION failed , dwReturn = 0x%lx"),
dwReturn);
}
RegCloseKey(hKey);
}
return dwReturn;
}
///////////////////////////////
// fxocReg_Uninstall
//
// Delete registry settings as
// specified in INF file, as well
// as dynamic settings that can only
// be done at run time (such as
// performance counter setup, etc).
//
// Params:
// - pszSubcomponentId
// - pszUninstallSection
// Returns:
// - NO_ERROR on success
// - error code otherwise
//
DWORD fxocReg_Uninstall(const TCHAR *pszSubcomponentId,
const TCHAR *pszUninstallSection)
{
DWORD dwReturn = NO_ERROR;
HINF hInf = faxocm_GetComponentInf();
DBG_ENTER( _T("fxocReg_Uninstall"),
dwReturn,
_T("%s - %s"),
pszSubcomponentId,
pszUninstallSection);
if (pszUninstallSection == NULL)
{
return ERROR_INVALID_PARAMETER;
}
// try to cleanup regardless of the return value.
prv_UninstallDynamicRegistry(pszUninstallSection);
// remove any performance counters related to fax.
prv_DeletePerformanceCounters();
// remove the static registry settings specified in the INF file
fxocUtil_DoSetup(hInf,
pszUninstallSection,
FALSE,
SPINST_ALL & ~(SPINST_FILES | SPINST_PROFILEITEMS),
_T("fxocReg_Uninstall"));
return dwReturn;
}
///////////////////////////////
// prv_InstallDynamicRegistry
//
// Installs dynamic registry
// settings that can only be
// done at run time (as opposed
// to via the faxsetup.inf file)
//
// Params:
// - pszSection -
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
static DWORD prv_InstallDynamicRegistry(const TCHAR *pszSection)
{
DWORD dwReturn = NO_ERROR;
LONG lResult = ERROR_SUCCESS;
HKEY hKey = NULL;
BOOL bIsServerInstall = FALSE;
DWORD dwProductType = 0;
DBG_ENTER( _T("prv_InstallDynamicRegistry"),
dwReturn,
_T("%s"),
pszSection);
if (pszSection == NULL)
{
return ERROR_INVALID_PARAMETER;
}
// open the install type registry key.
lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
REGKEY_FAX_SETUP,
0,
KEY_ALL_ACCESS,
&hKey);
if (lResult == ERROR_SUCCESS)
{
bIsServerInstall = fxState_IsOsServerBeingInstalled();
if (bIsServerInstall)
{
dwProductType = FAX_INSTALL_SERVER;
}
else
{
dwProductType = FAX_INSTALL_WORKSTATION;
}
lResult = ::RegSetValueEx(hKey,
REGVAL_FAXINSTALL_TYPE,
0,
REG_DWORD,
(BYTE*) &dwProductType,
sizeof(dwProductType));
if (lResult != ERROR_SUCCESS)
{
dwReturn = (DWORD) lResult;
VERBOSE(SETUP_ERR,
_T("Failed to set InstallType, ")
_T("rc = 0x%lx"),
lResult);
}
}
if (hKey)
{
::RegCloseKey(hKey);
hKey = NULL;
}
if (dwReturn == NO_ERROR)
{
VERBOSE(DBG_MSG,
_T("Successfully installed dynamic Registry ")
_T("settings from INF file, section '%s'"),
pszSection);
}
else
{
VERBOSE(SETUP_ERR,
_T("Failed to install dynamic Registry ")
_T("settings from INF file, section '%s', ")
_T("rc = 0x%lx"),
pszSection,
dwReturn);
}
return dwReturn;
}
///////////////////////////////
// prv_UninstallDynamicRegistry
//
// Uninstall dynamic registry.
//
// Params:
// - pszSection.
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
static DWORD prv_UninstallDynamicRegistry(const TCHAR *pszSection)
{
DWORD dwRes = NO_ERROR;
DBG_ENTER( _T("prv_InstallDynamicRegistry"),
dwRes,
_T("%s"),
pszSection);
return dwRes;
}
///////////////////////////////
// CreatePerformanceCounters
//
// Create the performance counters
// for fax in the registry.
//
// Params:
// - void
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
// Author: Mooly Beery (MoolyB) 17-Aug-2000
//
static DWORD prv_CreatePerformanceCounters()
{
DWORD dwRet = ERROR_SUCCESS;
TCHAR szInstallDir[MAX_PATH] = {0};
TCHAR szInstallCmdLine[MAX_PATH+20] = {0};
DBG_ENTER(_T("CreatePerformanceCounters"),dwRet);
// get the install location of fxsperf.dll from Windows Installer
if (!GetSystemDirectory(szInstallDir,ARR_SIZE(szInstallDir)))
{
dwRet = GetLastError();
VERBOSE (GENERAL_ERR,_T("GetSystemDirectory failed (ec: %ld)."),dwRet);
goto exit;
}
_sntprintf(szInstallCmdLine,ARR_SIZE(szInstallCmdLine)-1,_T("x \"%s%s\""),szInstallDir,FAX_FILENAME_FAXPERF_INI);
VERBOSE(DBG_MSG,_T("Calling LoadPerfCounterTextStrings with %s "),szInstallCmdLine);
dwRet = LoadPerfCounterTextStrings(szInstallCmdLine,TRUE);
if (dwRet==ERROR_SUCCESS)
{
VERBOSE(DBG_MSG,_T("LoadPerfCounterTextStrings success"));
}
else
{
VERBOSE(GENERAL_ERR,_T("LoadPerfCounterTextStrings failed (ec=%d)"),dwRet);
}
exit:
return dwRet;
}
///////////////////////////////
// DeletePerformanceCounters
//
// Delete the performance counters
// for fax in the registry.
//
// Params:
// - void
// Returns:
// - NO_ERROR on success.
// - error code otherwise.
//
// Author: Mooly Beery (MoolyB) 17-Aug-2000
//
static DWORD prv_DeletePerformanceCounters()
{
DWORD dwRet = ERROR_SUCCESS;
DBG_ENTER(_T("DeletePerformanceCounters"));
dwRet = UnloadPerfCounterTextStrings(_T("x ") FAX_SERVICE_NAME,TRUE);
if (dwRet==ERROR_SUCCESS)
{
VERBOSE(DBG_MSG,_T("UnloadPerfCounterTextStrings success"));
}
else
{
VERBOSE(GENERAL_ERR,_T("UnloadPerfCounterTextStrings failed (ec=%d)"),dwRet);
}
return dwRet;
}
/*++
Routine description:
Pre-pends FAX_REG_SECURITY_PREFIX to a value
Arguments:
hKey [in] - handle of a key
lpszValueName [in] - name of value to work on
Return Value: none
Note: This function is sometimes used as a callback of EnumerateRegistryKeys(),
therefore its signature must be compatible with PREGENUMCALLBACK
--*/
void prv_AddSecurityPrefixToValue(HKEY hKey, LPCTSTR lpszValueName)
{
LPBYTE pData = NULL;
DWORD dwSize = 0;
DWORD dwPrefixSize = sizeof (TCHAR) * wcslen (FAX_REG_SECURITY_PREFIX);
DBG_ENTER(_T("prv_AddSecurityPrefixToValue"), _T("%s"), lpszValueName);
pData = GetRegistryBinary(hKey, lpszValueName, &dwSize);
if (pData)
{
if (dwSize <=1)
{
VERBOSE(DBG_MSG, _T("Size=%d, not real data"), dwSize);
}
else if ((dwSize>dwPrefixSize) && (memcmp(pData, FAX_REG_SECURITY_PREFIX, dwPrefixSize)==0))
{
VERBOSE(DBG_MSG, _T("Size=%d, data already has prefix"), dwSize);
}
else
{
LPBYTE pNewData = NULL;
VERBOSE(DBG_MSG, _T("Size=%d, adding prefix..."), dwSize);
pNewData = (LPBYTE)MemAlloc(dwSize+dwPrefixSize);
if (pNewData)
{
memcpy(pNewData, FAX_REG_SECURITY_PREFIX, dwPrefixSize);
memcpy(&(pNewData[dwPrefixSize]), pData, dwSize);
if (!SetRegistryBinary(hKey, lpszValueName, pNewData, dwSize+dwPrefixSize))
{
VERBOSE(DBG_WARNING, _T("SetRegistryBinary failed, ec=%x"), GetLastError());
}
MemFree(pNewData);
}
}
MemFree(pData);
}
}
/*++
Routine description:
Pre-pends FAX_REG_SECURITY_PREFIX to all binary values in a specified key
Arguments:
hKey [in] - handle of a key
lpszKeyName [in] - If NULL, the function does nothing
(DWORD) - unused
lpContextData [in] - (LPTSTR) name of subkey under hKey in which to work
if NULL, function will work on hKey itself
Return Value: Always returns true
Note: This function is sometimes used as a callback of EnumerateRegistryKeys(),
therefore its signature must be compatible with PREGENUMCALLBACK
--*/
BOOL prv_AddSecurityPrefixToKey(
HKEY hKey, LPWSTR lpszKeyName, DWORD, LPVOID lpContextData)
{
LPTSTR lpszSubkey = (LPTSTR) lpContextData;
HKEY hSubKey = NULL;
int i;
DWORD dwRet = NO_ERROR;
DWORD dwType;
DWORD dwValueNameSize;
TCHAR szValueName[256] = {_T('\0')};
DBG_ENTER(_T("prv_AddSecurityPrefixToKey"), _T("%s \\ %s"),
lpszKeyName ? lpszKeyName : _T(""),
lpContextData ? lpContextData : _T(""));
// EnumerateRegistryKeys calls here once with the subkey - don't need that
if (!lpszKeyName)
{
return TRUE;
}
if (lpContextData)
{
hSubKey = OpenRegistryKey(hKey, lpszSubkey, FALSE, KEY_READ | KEY_WRITE);
if (!hSubKey)
{
return TRUE;
}
}
for (i=0; ; i++)
{
dwValueNameSize = ARR_SIZE(szValueName);
dwRet = RegEnumValue(
lpContextData ? hSubKey : hKey,
i,
szValueName,
&dwValueNameSize,
NULL, // reserved
&dwType,
NULL, // data buffer
NULL); // size of data buffer
if (dwRet == ERROR_NO_MORE_ITEMS)
{
break;
}
else if (dwRet != ERROR_SUCCESS)
{
VERBOSE(SETUP_ERR, _T("RegEnumValue failed, ec=%x"), dwRet);
break;
}
if (dwType == REG_BINARY)
{
prv_AddSecurityPrefixToValue(lpContextData ? hSubKey : hKey, szValueName);
}
}
if (hSubKey)
{
RegCloseKey(hSubKey);
}
return TRUE;
}
/*++
Routine description:
Pre-pends FAX_REG_SECURITY_PREFIX to all encrypted registry values.
Arguments: none
Return Value: none
Note: Encrypted registry values are located at:
Fax\TAPIDevices\<deviceID>
Fax\Devices Cache\<deviceID>\TAPI Data
Fax\Devices\UnassociatedExtensionData
Fax\Receipts (Password value only)
--*/
void prv_AddSecurityPrefix(void)
{
HKEY hKey = NULL;
DBG_ENTER(_T("prv_AddSecurityPrefix"));
// Add prefixes to all values under TAPIDevices\<deviceID>
EnumerateRegistryKeys(
HKEY_LOCAL_MACHINE,
REGKEY_TAPIDEVICES,
TRUE,
prv_AddSecurityPrefixToKey,
NULL);
// EnumerateRegistryKeys returns the number of enumerated subkeys - we don't care about it
// Add prefixes to all values under Devices Cache\<deviceID>\TAPI Data
EnumerateRegistryKeys(
HKEY_LOCAL_MACHINE,
REGKEY_FAX_DEVICES_CACHE,
TRUE,
prv_AddSecurityPrefixToKey,
(LPVOID)REGKEY_TAPI_DATA);
// EnumerateRegistryKeys returns the number of enumerated subkeys - we don't care about it
// Add prefixes to all values under Devices\UnassociatedExtensionData
prv_AddSecurityPrefixToKey(HKEY_LOCAL_MACHINE, _T(""), 0, REGKEY_FAX_UNASS_DATA);
// Add prefix to Receipts\Password
hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, REGKEY_FAX_RECEIPTS, FALSE, KEY_READ | KEY_WRITE);
if (hKey)
{
prv_AddSecurityPrefixToValue(hKey, REGVAL_RECEIPTS_PASSWORD);
RegCloseKey(hKey);
}
}