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.
4680 lines
126 KiB
4680 lines
126 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
faxreg.c
|
|
|
|
Abstract:
|
|
|
|
This module wraps all of the registry access
|
|
for the fax server.
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 9-June-1996
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <tchar.h>
|
|
#include <objbase.h>
|
|
#include <wincrypt.h>
|
|
#include <Shlwapi.h.>
|
|
|
|
#include "fxsapip.h"
|
|
#include "faxutil.h"
|
|
#include "faxext.h"
|
|
#include "faxreg.h"
|
|
#include "faxsvcrg.h"
|
|
|
|
#define FAX_CATEGORY_COUNT 4
|
|
|
|
#define BAD_FOLDER_STRING TEXT("\\\\\\")
|
|
|
|
static BYTE const gsc_baEntropy [] = {0x46, 0x41, 0x58, 0x43, 0x4F, 0x56, 0x45, 0x52, 0x2D, 0x56, 0x45, 0x52,
|
|
0x30, 0x30, 0x35, 0x77, 0x87, 0x00, 0x00, 0x00};
|
|
|
|
static
|
|
BOOL
|
|
SetRegistrySecureBinary (
|
|
HKEY hKey,
|
|
LPCTSTR lpctstrValueName,
|
|
LPBYTE lpbValue,
|
|
DWORD dwValueSize,
|
|
BOOL bOptionallyNonSecure
|
|
)
|
|
/*++
|
|
|
|
Routine name : SetRegistrySecureBinary
|
|
|
|
Routine description:
|
|
|
|
Stores a binary blob in the registry with encryption
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Sep, 2001
|
|
|
|
Arguments:
|
|
|
|
hKey [in] - Handle to registry key (open)
|
|
lpctstrValueName [in] - Name of value
|
|
lpbValue [in] - Blob to store
|
|
dwValueSize [in] - Size of data blob
|
|
bOptionallyNonSecure [in] - Do we allow the registry entry to be non-secure?
|
|
If FALSE, the data will always be written encrypted.
|
|
If TRUE, the data will be written encrypted but prefixed with
|
|
a string (FAX_REG_SECURITY_PREFIX).
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, FALSE otherwise.
|
|
|
|
Remarks:
|
|
|
|
Data is stored in REG_BINARY format.
|
|
|
|
Encryption has no UI
|
|
|
|
Encryption is machine based (if you change the account under which the server is running, it will
|
|
still be able to read and decrypt the encrypted data).
|
|
|
|
--*/
|
|
{
|
|
BOOL bRes = FALSE;
|
|
DEBUG_FUNCTION_NAME(TEXT("SetRegistrySecureBinary"));
|
|
|
|
Assert (hKey && lpbValue && dwValueSize);
|
|
//
|
|
// Start by encrypting the value
|
|
//
|
|
DATA_BLOB DataIn;
|
|
DATA_BLOB DataOut = {0};
|
|
DataIn.pbData = lpbValue;
|
|
DataIn.cbData = dwValueSize;
|
|
DATA_BLOB DataEntropy;
|
|
DataEntropy.pbData = (BYTE*)gsc_baEntropy;
|
|
DataEntropy.cbData = sizeof (gsc_baEntropy);
|
|
|
|
if (!CryptProtectData(
|
|
&DataIn,
|
|
TEXT("Description"), // No description sting.
|
|
&DataEntropy, // We're using the cover page signature as an additional entropy
|
|
NULL, // Reserved.
|
|
NULL, // No user prompt
|
|
CRYPTPROTECT_UI_FORBIDDEN, // Presenting a user interface (UI) is not an option.
|
|
&DataOut))
|
|
{
|
|
DWORD dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CryptProtectData failed with %ld"),
|
|
dwRes);
|
|
return bRes;
|
|
}
|
|
if (bOptionallyNonSecure)
|
|
{
|
|
//
|
|
// Need to prefix the data with FAX_REG_SECURITY_PREFIX.
|
|
// This is done so that the matching reading function can handle secure and non-secure data
|
|
// correctly.
|
|
//
|
|
DWORD dwPrefixSize = sizeof (TCHAR) * wcslen (FAX_REG_SECURITY_PREFIX);
|
|
DWORD dwSize = dwPrefixSize + DataOut.cbData;
|
|
BYTE *pPrefixedData = (BYTE*)LocalAlloc (LPTR, dwSize);
|
|
if (!pPrefixedData)
|
|
{
|
|
DWORD dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("LocalAlloc failed with %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
memcpy (pPrefixedData, FAX_REG_SECURITY_PREFIX, dwPrefixSize);
|
|
memcpy (&pPrefixedData[dwPrefixSize], DataOut.pbData, DataOut.cbData);
|
|
LocalFree (DataOut.pbData);
|
|
DataOut.pbData = pPrefixedData;
|
|
DataOut.cbData = dwSize;
|
|
}
|
|
//
|
|
// Store the data in the registry (as binary)
|
|
//
|
|
if (!SetRegistryBinary(
|
|
hKey,
|
|
lpctstrValueName,
|
|
DataOut.pbData,
|
|
DataOut.cbData))
|
|
{
|
|
DWORD dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SetRegistryBinary failed with %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
bRes = TRUE;
|
|
|
|
exit:
|
|
|
|
LocalFree (DataOut.pbData);
|
|
return bRes;
|
|
} // SetRegistrySecureBinary
|
|
|
|
|
|
BOOL
|
|
SetRegistrySecureString (
|
|
HKEY hKey,
|
|
LPCTSTR lpctstrValueName,
|
|
LPCTSTR lpctstrValue,
|
|
BOOL bOptionallyNonSecure
|
|
)
|
|
/*++
|
|
|
|
Routine name : SetRegistrySecureString
|
|
|
|
Routine description:
|
|
|
|
Stores a string in the registry with encryption
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Jul, 2000
|
|
|
|
Arguments:
|
|
|
|
hKey [in] - Handle to registry key (open)
|
|
lpctstrValueName [in] - Name of value
|
|
lpctstrValue [in] - String to store
|
|
bOptionallyNonSecure [in] - Do we allow the registry entry to be non-secure?
|
|
If FALSE, the data will always be written encrypted.
|
|
If TRUE, the data will be written encrypted but prefixed with
|
|
a string (FAX_REG_SECURITY_PREFIX).
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, FALSE otherwise.
|
|
|
|
Remarks:
|
|
|
|
String is stored in REG_BINARY format.
|
|
|
|
Encryption has no UI
|
|
|
|
Encryption is machine based (if you change the account under which the server is running, it will
|
|
still be able to read and decrypt the encrypted data).
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("SetRegistrySecureString"));
|
|
|
|
return SetRegistrySecureBinary (hKey,
|
|
lpctstrValueName,
|
|
(LPBYTE)lpctstrValue,
|
|
(lstrlen(lpctstrValue) + 1) * sizeof (TCHAR),
|
|
bOptionallyNonSecure);
|
|
} // SetRegistrySecureString
|
|
|
|
|
|
static
|
|
DWORD
|
|
GetRegistrySecureBinary(
|
|
HKEY hKey,
|
|
LPCTSTR lpctstrValueName,
|
|
LPBYTE *ppData,
|
|
LPDWORD lpdwSize,
|
|
BOOL bOptionallyNonSecure,
|
|
FAX_ENUM_DATA_ENCRYPTION* pDataDecrypted
|
|
)
|
|
/*++
|
|
|
|
Routine name : GetRegistrySecureBinary
|
|
|
|
Routine description:
|
|
|
|
Reads an decrypts a secure registry string
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Jul, 2000
|
|
|
|
Arguments:
|
|
|
|
hKey [in] - Handle to registry key (open)
|
|
lpctstrValueName [in] - Name of value
|
|
ppData [out] - Allocated return buffer
|
|
lpdwSize [out] - Allocated return buffer size (in bytes)
|
|
bOptionallyNonSecure [in] - Do we allow the registry entry to be non-secure?
|
|
If FALSE, the data will always be read and decrypted.
|
|
If TRUE, the data will be read and checked for a prefix
|
|
string (FAX_REG_SECURITY_PREFIX) before it is decrypted.
|
|
If the prefix string is not there, the data will not be
|
|
decrypted and will be returned as-is.
|
|
pDataDecrypted [out] - Points to a FAX_ENUM_DATA_ENCRYPTION that on return is FAX_DATA_ENCRYPTED if the data was decrypted,
|
|
and FAX_DATA_NOT_ENCRYPTED if the data was not decrypted and was returned as is.
|
|
FAX_NO_DATA means that this information is not available.
|
|
Ignored if NULL;
|
|
|
|
Return Value:
|
|
|
|
Win32 error code
|
|
|
|
Remarks:
|
|
|
|
String is stored in REG_BINARY format.
|
|
|
|
String was stored by calling SetRegistrySecureBinary().
|
|
|
|
Caller should MemFree return value.
|
|
|
|
--*/
|
|
{
|
|
DATA_BLOB DataIn;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DATA_BLOB DataOut = {0};
|
|
DATA_BLOB DataEntropy;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("GetRegistrySecureBinary"));
|
|
|
|
Assert (hKey && ppData && lpdwSize);
|
|
if (NULL != pDataDecrypted)
|
|
{
|
|
*pDataDecrypted = FAX_NO_DATA;
|
|
}
|
|
//
|
|
// Get the registry data first
|
|
//
|
|
DataIn.pbData = GetRegistryBinary(
|
|
hKey,
|
|
lpctstrValueName,
|
|
&DataIn.cbData);
|
|
if (!DataIn.pbData)
|
|
{
|
|
//
|
|
// Couldn't read data
|
|
//
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("GetRegistryBinary failed with %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
if (1 == DataIn.cbData)
|
|
{
|
|
//
|
|
// Data wasn't found in the registry.
|
|
// Current implementation of GetRegistryBinary returns a 1-byte buffer of 0 in that case.
|
|
// We know for sure that data encrypted with CryptProtectData must be longer than 10 bytes.
|
|
//
|
|
MemFree (DataIn.pbData);
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("GetRegistryBinary found no data for %s"),
|
|
lpctstrValueName);
|
|
return ERROR_FILE_NOT_FOUND;
|
|
}
|
|
//
|
|
// We got the data - decrypt it
|
|
//
|
|
DataEntropy.pbData = (BYTE*)gsc_baEntropy;
|
|
DataEntropy.cbData = sizeof (gsc_baEntropy);
|
|
|
|
if (bOptionallyNonSecure)
|
|
{
|
|
//
|
|
// Data is allowed to be non-secure
|
|
//
|
|
DWORD dwPrefixSize = sizeof (TCHAR) * wcslen (FAX_REG_SECURITY_PREFIX);
|
|
if ((DataIn.cbData <= dwPrefixSize) ||
|
|
memcmp (DataIn.pbData, FAX_REG_SECURITY_PREFIX, dwPrefixSize))
|
|
{
|
|
//
|
|
// Data length is too short or data does not start with encryption signature.
|
|
// The data we're reading is non-secure. Just return it as is.
|
|
//
|
|
*lpdwSize = DataIn.cbData;
|
|
*ppData = DataIn.pbData;
|
|
if (pDataDecrypted)
|
|
{
|
|
*pDataDecrypted = FAX_DATA_NOT_ENCRYPTED;
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The data starts with encryption signature.
|
|
// Actual encrypted data follows signature.
|
|
//
|
|
BYTE *pRealData;
|
|
|
|
if (pDataDecrypted)
|
|
{
|
|
*pDataDecrypted = FAX_DATA_ENCRYPTED;
|
|
}
|
|
DataIn.cbData -= dwPrefixSize;
|
|
pRealData = (LPBYTE)MemAlloc (DataIn.cbData);
|
|
if (!pRealData)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("MemAlloc failed with %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
memcpy (pRealData, &(DataIn.pbData[dwPrefixSize]), DataIn.cbData);
|
|
MemFree (DataIn.pbData);
|
|
DataIn.pbData = pRealData;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The data is always encrypted
|
|
//
|
|
if (pDataDecrypted)
|
|
{
|
|
*pDataDecrypted = FAX_DATA_ENCRYPTED;
|
|
}
|
|
}
|
|
if (!CryptUnprotectData(
|
|
&DataIn, // Data to decrypt
|
|
NULL, // Not interested in description
|
|
&DataEntropy, // Entropy in use
|
|
NULL, // Reserved
|
|
NULL, // No prompt
|
|
CRYPTPROTECT_UI_FORBIDDEN, // Presenting a user interface (UI) is not an option.
|
|
&DataOut)) // Out data
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CryptUnprotectData failed with %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
//
|
|
// Use our own memory allocation
|
|
//
|
|
*lpdwSize = DataOut.cbData;
|
|
*ppData = (LPBYTE)MemAlloc (DataOut.cbData);
|
|
if (!(*ppData))
|
|
{
|
|
dwRes = GetLastError ();
|
|
goto exit;
|
|
}
|
|
memcpy (*ppData, DataOut.pbData, DataOut.cbData);
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (DataOut.pbData)
|
|
{
|
|
SecureZeroMemory(DataOut.pbData, DataOut.cbData);
|
|
LocalFree (DataOut.pbData);
|
|
}
|
|
MemFree (DataIn.pbData);
|
|
return dwRes;
|
|
} // GetRegistrySecureBinary
|
|
|
|
|
|
LPTSTR
|
|
GetRegistrySecureString(
|
|
HKEY hKey,
|
|
LPCTSTR lpctstrValueName,
|
|
LPCTSTR lpctstrDefaultValue,
|
|
BOOL bOptionallyNonSecure,
|
|
FAX_ENUM_DATA_ENCRYPTION* pDataDecrypted
|
|
)
|
|
/*++
|
|
|
|
Routine name : GetRegistrySecureString
|
|
|
|
Routine description:
|
|
|
|
Reads an decrypts a secure registry string
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Jul, 2000
|
|
|
|
Arguments:
|
|
|
|
hKey [in] - Handle to registry key (open)
|
|
lpctstrValueName [in] - Name of value
|
|
lpctstrDefaultValue [in] - Default value
|
|
bOptionallyNonSecure [in] - Do we allow the registry entry to be non-secure?
|
|
If FALSE, the data will always be read and decrypted.
|
|
If TRUE, the data will be read and checked for a prefix
|
|
string (FAX_REG_SECURITY_PREFIX) before it is decrypted.
|
|
If the prefix string is not there, the data will not be
|
|
decrypted and will be returned as-is.
|
|
pDataDecrypted [out] - Points to a FAX_ENUM_DATA_ENCRYPTION that on return is FAX_DATA_ENCRYPTED if the data was decrypted,
|
|
and FAX_DATA_NOT_ENCRYPTED if the data was not decrypted and was returned as is.
|
|
FAX_NO_DATA means that this information is not available.
|
|
Ignored if NULL;
|
|
|
|
Return Value:
|
|
|
|
String read or NULL on error
|
|
|
|
Remarks:
|
|
|
|
String is stored in REG_BINARY format.
|
|
|
|
String was stored by calling SetRegistrySecureString().
|
|
|
|
Caller should MemFree return value.
|
|
|
|
--*/
|
|
{
|
|
LPTSTR lptstrResult = NULL;
|
|
DWORD dwRes;
|
|
DWORD dwSize;
|
|
DEBUG_FUNCTION_NAME(TEXT("GetRegistrySecureString"));
|
|
|
|
dwRes = GetRegistrySecureBinary (hKey,
|
|
lpctstrValueName,
|
|
(LPBYTE*)&lptstrResult,
|
|
&dwSize,
|
|
bOptionallyNonSecure,
|
|
pDataDecrypted);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
//
|
|
// Error reading or decrypting data - return default
|
|
//
|
|
return StringDup (lpctstrDefaultValue);
|
|
}
|
|
//
|
|
// Assert the read binary blob is indeed a string by checing for EOSTR at the end.
|
|
//
|
|
Assert (lptstrResult[dwSize / sizeof (TCHAR) - 1] == TEXT('\0'));
|
|
return lptstrResult;
|
|
} // GetRegistrySecureString
|
|
|
|
static
|
|
DWORD
|
|
OpenExtensionKey (
|
|
DWORD dwDeviceId,
|
|
FAX_ENUM_DEVICE_ID_SOURCE DevIdSrc,
|
|
PHKEY lphKey
|
|
);
|
|
|
|
BOOL
|
|
EnumDeviceProviders(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
DEBUG_FUNCTION_NAME(TEXT("EnumDeviceProviders"));
|
|
|
|
if (SubKeyName == NULL) {
|
|
//
|
|
// The enumeration function has called us with the parent key.
|
|
// Index should contain the number of subkeys. In this case this is the number of
|
|
// providers subkeys.
|
|
//
|
|
if (Index) {
|
|
FaxReg->DeviceProviders = (PREG_DEVICE_PROVIDER) MemAlloc( Index * sizeof(REG_DEVICE_PROVIDER) );
|
|
if (!FaxReg->DeviceProviders) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
if (FaxReg == NULL || FaxReg->DeviceProviders == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
memset(&FaxReg->DeviceProviders[Index],0,sizeof(REG_DEVICE_PROVIDER));
|
|
|
|
//
|
|
// Check the APIVersion and see if this is an EFSP
|
|
//
|
|
FaxReg->DeviceProviders[Index].dwAPIVersion = GetRegistryDword(hSubKey, REGVAL_PROVIDER_API_VERSION);
|
|
|
|
if (FSPI_API_VERSION_1 == FaxReg->DeviceProviders[Index].dwAPIVersion ||
|
|
0 == FaxReg->DeviceProviders[Index].dwAPIVersion)
|
|
{
|
|
LPTSTR lptstrGUID;
|
|
//
|
|
// This is a legacy FSP
|
|
//
|
|
FaxReg->DeviceProviders[Index].FriendlyName = GetRegistryString( hSubKey, REGVAL_FRIENDLY_NAME, EMPTY_STRING );
|
|
FaxReg->DeviceProviders[Index].ImageName = GetRegistryStringExpand( hSubKey, REGVAL_IMAGE_NAME, EMPTY_STRING );
|
|
FaxReg->DeviceProviders[Index].ProviderName = GetRegistryString( hSubKey, REGVAL_PROVIDER_NAME,EMPTY_STRING );
|
|
FaxReg->DeviceProviders[Index].dwAPIVersion = FSPI_API_VERSION_1;
|
|
|
|
lptstrGUID = GetRegistryString( hSubKey, REGVAL_PROVIDER_GUID,EMPTY_STRING );
|
|
if ( (NULL == lptstrGUID) || (0 == _tcscmp(lptstrGUID , EMPTY_STRING)) )
|
|
{
|
|
//
|
|
// This FSP was registerd using the legacy registration API
|
|
// Use the provider unique name as a "GUID"
|
|
//
|
|
MemFree (lptstrGUID);
|
|
lptstrGUID = StringDup(SubKeyName);
|
|
}
|
|
FaxReg->DeviceProviders[Index].lptstrGUID = lptstrGUID;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// API_VERSION we do not support
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Unknown API version : 0x%08X"),
|
|
FaxReg->DeviceProviders[Index].dwAPIVersion);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumDeviceProvidersChange(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
if (SubKeyName == NULL) {
|
|
//
|
|
// called once for the subkey
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
if (FaxReg == NULL || FaxReg->DeviceProviders == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
SetRegistryString( hSubKey, REGVAL_FRIENDLY_NAME, FaxReg->DeviceProviders[Index].FriendlyName );
|
|
SetRegistryStringExpand( hSubKey, REGVAL_IMAGE_NAME, FaxReg->DeviceProviders[Index].ImageName );
|
|
SetRegistryString( hSubKey, REGVAL_PROVIDER_NAME, FaxReg->DeviceProviders[Index].ProviderName );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumRoutingMethods(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID pvRoutingExtension
|
|
)
|
|
{
|
|
|
|
PREG_ROUTING_EXTENSION RoutingExtension = (PREG_ROUTING_EXTENSION) pvRoutingExtension;
|
|
if (SubKeyName == NULL) {
|
|
if (Index) {
|
|
RoutingExtension->RoutingMethods = (PREG_ROUTING_METHOD) MemAlloc( Index * sizeof(REG_ROUTING_METHOD) );
|
|
if (!RoutingExtension->RoutingMethods) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
if (RoutingExtension == NULL || RoutingExtension->RoutingMethods == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
RoutingExtension->RoutingMethods[Index].InternalName = StringDup( SubKeyName );
|
|
RoutingExtension->RoutingMethods[Index].FriendlyName = GetRegistryString( hSubKey, REGVAL_FRIENDLY_NAME, EMPTY_STRING );
|
|
RoutingExtension->RoutingMethods[Index].FunctionName = GetRegistryString( hSubKey, REGVAL_FUNCTION_NAME, EMPTY_STRING );
|
|
RoutingExtension->RoutingMethods[Index].Guid = GetRegistryString( hSubKey, REGVAL_GUID, EMPTY_STRING );
|
|
RoutingExtension->RoutingMethods[Index].Priority = GetRegistryDword( hSubKey, REGVAL_ROUTING_PRIORITY );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumRoutingMethodsChange(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpRoutingExtension
|
|
)
|
|
{
|
|
PREG_ROUTING_EXTENSION RoutingExtension = (PREG_ROUTING_EXTENSION) lpRoutingExtension;
|
|
if (SubKeyName == NULL) {
|
|
//
|
|
// called once for the subkey
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
if (RoutingExtension == NULL || RoutingExtension->RoutingMethods) {
|
|
return FALSE;
|
|
}
|
|
|
|
SetRegistryString( hSubKey, REGVAL_FRIENDLY_NAME, RoutingExtension->RoutingMethods[Index].FriendlyName );
|
|
SetRegistryString( hSubKey, REGVAL_FUNCTION_NAME, RoutingExtension->RoutingMethods[Index].FunctionName );
|
|
SetRegistryString( hSubKey, REGVAL_GUID, RoutingExtension->RoutingMethods[Index].Guid );
|
|
SetRegistryDword ( hSubKey, REGVAL_ROUTING_PRIORITY, RoutingExtension->RoutingMethods[Index].Priority );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumRoutingExtensions(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
if (SubKeyName == NULL) {
|
|
if (Index) {
|
|
FaxReg->RoutingExtensions = (PREG_ROUTING_EXTENSION) MemAlloc( Index * sizeof(REG_ROUTING_EXTENSION) );
|
|
if (!FaxReg->RoutingExtensions) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
if (FaxReg == NULL || FaxReg->RoutingExtensions == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
FaxReg->RoutingExtensions[Index].InternalName = StringDup( SubKeyName );
|
|
FaxReg->RoutingExtensions[Index].FriendlyName = GetRegistryString( hSubKey, REGVAL_FRIENDLY_NAME, EMPTY_STRING );
|
|
FaxReg->RoutingExtensions[Index].ImageName = GetRegistryStringExpand( hSubKey, REGVAL_IMAGE_NAME, EMPTY_STRING );
|
|
|
|
//
|
|
// load the routing methods for this extension
|
|
//
|
|
|
|
FaxReg->RoutingExtensions[Index].RoutingMethodsCount = EnumerateRegistryKeys(
|
|
hSubKey,
|
|
REGKEY_ROUTING_METHODS,
|
|
FALSE,
|
|
EnumRoutingMethods,
|
|
&FaxReg->RoutingExtensions[Index]
|
|
);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumRoutingExtensionsChange(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
if (SubKeyName == NULL) {
|
|
//
|
|
// called once for the subkey
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
if (FaxReg == NULL || FaxReg->RoutingExtensions == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
SetRegistryString( hSubKey, REGVAL_FRIENDLY_NAME, FaxReg->RoutingExtensions[Index].FriendlyName );
|
|
SetRegistryStringExpand( hSubKey, REGVAL_IMAGE_NAME, FaxReg->RoutingExtensions[Index].ImageName );
|
|
|
|
//
|
|
// load the routing methods for this extension
|
|
//
|
|
|
|
EnumerateRegistryKeys(
|
|
hSubKey,
|
|
REGKEY_ROUTING_METHODS,
|
|
TRUE,
|
|
EnumRoutingMethodsChange,
|
|
&FaxReg->RoutingExtensions[Index]
|
|
);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumDevices(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
HKEY hNewSubKey = NULL;
|
|
|
|
if (SubKeyName == NULL) {
|
|
if (Index) {
|
|
FaxReg->Devices = (PREG_DEVICE) MemAlloc( Index * sizeof(REG_DEVICE) );
|
|
if (!FaxReg->Devices) {
|
|
return FALSE;
|
|
}
|
|
ZeroMemory(FaxReg->Devices, Index * sizeof(REG_DEVICE));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
if (FaxReg == NULL || FaxReg->Devices == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
FaxReg->Devices[Index].PermanentLineId = GetRegistryDword( hSubKey, REGVAL_PERMANENT_LINEID);
|
|
|
|
hNewSubKey = OpenRegistryKey( hSubKey, REGKEY_FAXSVC_DEVICE_GUID, FALSE, NULL );
|
|
if(hNewSubKey)
|
|
{
|
|
DWORDLONG *pTemp;
|
|
DWORD dwDataSize = sizeof(DWORDLONG);
|
|
|
|
FaxReg->Devices[Index].bValidDevice = TRUE;
|
|
FaxReg->Devices[Index].Flags = GetRegistryDword( hNewSubKey, REGVAL_FLAGS );
|
|
FaxReg->Devices[Index].Rings = GetRegistryDword( hNewSubKey, REGVAL_RINGS );
|
|
FaxReg->Devices[Index].Name = GetRegistryString( hNewSubKey, REGVAL_DEVICE_NAME, EMPTY_STRING );
|
|
FaxReg->Devices[Index].Csid = GetRegistryString( hNewSubKey, REGVAL_ROUTING_CSID, EMPTY_STRING );
|
|
FaxReg->Devices[Index].Tsid = GetRegistryString( hNewSubKey, REGVAL_ROUTING_TSID, EMPTY_STRING );
|
|
FaxReg->Devices[Index].TapiPermanentLineID = GetRegistryDword( hNewSubKey, REGVAL_TAPI_PERMANENT_LINEID );
|
|
FaxReg->Devices[Index].lptstrDeviceName = GetRegistryString( hNewSubKey, REGVAL_DEVICE_NAME, EMPTY_STRING);
|
|
FaxReg->Devices[Index].lptstrDescription = GetRegistryString( hNewSubKey, REGVAL_DEVICE_DESCRIPTION, EMPTY_STRING);
|
|
FaxReg->Devices[Index].lptstrProviderGuid = GetRegistryString( hNewSubKey, REGVAL_PROVIDER_GUID, EMPTY_STRING );
|
|
|
|
pTemp = (DWORDLONG *)GetRegistryBinary(hNewSubKey, REGVAL_LAST_DETECTED_TIME, &dwDataSize);
|
|
if(pTemp && dwDataSize == sizeof(DWORDLONG))
|
|
{
|
|
FaxReg->Devices[Index].dwlLastDetected = *pTemp;
|
|
MemFree(pTemp);
|
|
}
|
|
|
|
RegCloseKey(hNewSubKey);
|
|
}
|
|
else
|
|
{
|
|
FaxReg->Devices[Index].bValidDevice = FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
SetDevicesValues(
|
|
HKEY hSubKey,
|
|
DWORD dwPermanentLineId,
|
|
DWORD TapiPermanentLineID,
|
|
DWORD Flags,
|
|
DWORD Rings,
|
|
LPCTSTR DeviceName,
|
|
LPCTSTR ProviderGuid,
|
|
LPCTSTR Csid,
|
|
LPCTSTR Tsid
|
|
)
|
|
{
|
|
HKEY hNewSubKey = NULL;
|
|
|
|
SetRegistryDword( hSubKey, REGVAL_PERMANENT_LINEID, dwPermanentLineId );
|
|
|
|
|
|
hNewSubKey = OpenRegistryKey( hSubKey, REGKEY_FAXSVC_DEVICE_GUID, TRUE, NULL );
|
|
if(hNewSubKey)
|
|
{
|
|
SetRegistryDword( hNewSubKey, REGVAL_TAPI_PERMANENT_LINEID, TapiPermanentLineID );
|
|
SetRegistryDword( hNewSubKey, REGVAL_FLAGS, Flags );
|
|
SetRegistryDword( hNewSubKey, REGVAL_RINGS, Rings );
|
|
if (DeviceName)
|
|
{
|
|
SetRegistryString( hNewSubKey, REGVAL_DEVICE_NAME, DeviceName );
|
|
}
|
|
if (ProviderGuid)
|
|
{
|
|
if (ProviderGuid[0])
|
|
{
|
|
SetRegistryString( hNewSubKey, REGVAL_PROVIDER_GUID, ProviderGuid );
|
|
}
|
|
}
|
|
SetRegistryString( hNewSubKey, REGVAL_ROUTING_CSID, Csid );
|
|
SetRegistryString( hNewSubKey, REGVAL_ROUTING_TSID, Tsid );
|
|
|
|
RegCloseKey(hNewSubKey);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumDevicesChange(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
if (SubKeyName == NULL) {
|
|
//
|
|
// called once for the subkey
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
if (FaxReg == NULL || FaxReg->Devices == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
SetDevicesValues(
|
|
hSubKey,
|
|
FaxReg->Devices[Index].PermanentLineId,
|
|
FaxReg->Devices[Index].TapiPermanentLineID,
|
|
FaxReg->Devices[Index].Flags,
|
|
FaxReg->Devices[Index].Rings,
|
|
FaxReg->Devices[Index].Name,
|
|
FaxReg->Devices[Index].lptstrProviderGuid,
|
|
FaxReg->Devices[Index].Csid,
|
|
FaxReg->Devices[Index].Tsid
|
|
);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumLogging(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
if (SubKeyName == NULL)
|
|
{
|
|
if (Index)
|
|
{
|
|
FaxReg->Logging = (PREG_CATEGORY) MemAlloc( Index * sizeof(REG_CATEGORY) );
|
|
if (!FaxReg->Logging)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
if (FaxReg->Logging == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
FaxReg->Logging[Index].CategoryName = GetRegistryString( hSubKey, REGVAL_CATEGORY_NAME, EMPTY_STRING );
|
|
FaxReg->Logging[Index].Level = GetRegistryDword( hSubKey, REGVAL_CATEGORY_LEVEL );
|
|
FaxReg->Logging[Index].Number = GetRegistryDword( hSubKey, REGVAL_CATEGORY_NUMBER );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnumLoggingChange(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID lpFaxReg
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg = (PREG_FAX_SERVICE) lpFaxReg;
|
|
if (SubKeyName == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
SetRegistryString( hSubKey, REGVAL_CATEGORY_NAME, FaxReg->Logging[Index].CategoryName );
|
|
SetRegistryDword( hSubKey, REGVAL_CATEGORY_LEVEL, FaxReg->Logging[Index].Level );
|
|
SetRegistryDword( hSubKey, REGVAL_CATEGORY_NUMBER, FaxReg->Logging[Index].Number );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetFaxRegistry(
|
|
PREG_FAX_SERVICE* ppFaxReg
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
DWORD Tmp;
|
|
DWORD ec;
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_READ );
|
|
if (!hKey)
|
|
{
|
|
ec = GetLastError();
|
|
return ec;
|
|
}
|
|
|
|
if (NULL == *ppFaxReg)
|
|
{
|
|
//
|
|
// First call - Allocate FaxReg and read only what is needed for event log
|
|
//
|
|
*ppFaxReg = (PREG_FAX_SERVICE) MemAlloc( sizeof(REG_FAX_SERVICE) );
|
|
if (!*ppFaxReg)
|
|
{
|
|
RegCloseKey( hKey );
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
ZeroMemory (*ppFaxReg, sizeof(REG_FAX_SERVICE));
|
|
|
|
//
|
|
// load the logging categories
|
|
//
|
|
(*ppFaxReg)->LoggingCount = EnumerateRegistryKeys(
|
|
hKey,
|
|
REGKEY_LOGGING,
|
|
FALSE,
|
|
EnumLogging,
|
|
*ppFaxReg
|
|
);
|
|
|
|
RegCloseKey( hKey );
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// load the fax service values
|
|
//
|
|
(*ppFaxReg)->Retries = GetRegistryDword( hKey, REGVAL_RETRIES );
|
|
(*ppFaxReg)->RetryDelay = GetRegistryDword( hKey, REGVAL_RETRYDELAY );
|
|
(*ppFaxReg)->DirtyDays = GetRegistryDword( hKey, REGVAL_DIRTYDAYS );
|
|
(*ppFaxReg)->dwQueueState = GetRegistryDword (hKey, REGVAL_QUEUE_STATE);
|
|
(*ppFaxReg)->NextJobNumber = GetRegistryDword( hKey, REGVAL_JOB_NUMBER );
|
|
(*ppFaxReg)->Branding = GetRegistryDword( hKey, REGVAL_BRANDING );
|
|
(*ppFaxReg)->UseDeviceTsid = GetRegistryDword( hKey, REGVAL_USE_DEVICE_TSID );
|
|
(*ppFaxReg)->ServerCp = GetRegistryDword( hKey, REGVAL_SERVERCP );
|
|
Tmp = GetRegistryDword( hKey, REGVAL_STARTCHEAP );
|
|
(*ppFaxReg)->StartCheapTime.Hour = LOWORD(Tmp);
|
|
(*ppFaxReg)->StartCheapTime.Minute = HIWORD(Tmp);
|
|
Tmp = GetRegistryDword( hKey, REGVAL_STOPCHEAP );
|
|
(*ppFaxReg)->StopCheapTime.Hour = LOWORD(Tmp);
|
|
(*ppFaxReg)->StopCheapTime.Minute = HIWORD(Tmp);
|
|
|
|
(*ppFaxReg)->dwLastUniqueLineId = GetRegistryDword( hKey, REGVAL_LAST_UNIQUE_LINE_ID );
|
|
(*ppFaxReg)->dwMaxLineCloseTime = GetRegistryDword( hKey, REGVAL_MAX_LINE_CLOSE_TIME );
|
|
(*ppFaxReg)->lptstrQueueDir = GetRegistryString( hKey, REGVAL_QUEUE_DIRECTORY, NULL );
|
|
(*ppFaxReg)->dwRecipientsLimit = GetRegistryDword( hKey, REGVAL_RECIPIENTS_LIMIT );
|
|
(*ppFaxReg)->dwAllowRemote = GetRegistryDword( hKey, REGVAL_ALLOW_REMOTE );
|
|
//
|
|
// load the device providers
|
|
//
|
|
|
|
(*ppFaxReg)->DeviceProviderCount = EnumerateRegistryKeys(
|
|
hKey,
|
|
REGKEY_DEVICE_PROVIDERS,
|
|
FALSE,
|
|
EnumDeviceProviders,
|
|
*ppFaxReg
|
|
);
|
|
|
|
//
|
|
// load the routing extensions
|
|
//
|
|
|
|
(*ppFaxReg)->RoutingExtensionsCount = EnumerateRegistryKeys(
|
|
hKey,
|
|
REGKEY_ROUTING_EXTENSIONS,
|
|
FALSE,
|
|
EnumRoutingExtensions,
|
|
*ppFaxReg
|
|
);
|
|
|
|
//
|
|
// load the devices
|
|
//
|
|
|
|
(*ppFaxReg)->DeviceCount = EnumerateRegistryKeys(
|
|
hKey,
|
|
REGKEY_DEVICES,
|
|
FALSE,
|
|
EnumDevices,
|
|
*ppFaxReg
|
|
);
|
|
|
|
RegCloseKey( hKey );
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
FreeFaxRegistry(
|
|
PREG_FAX_SERVICE FaxReg
|
|
)
|
|
{
|
|
DWORD i,j;
|
|
|
|
|
|
if (!FaxReg) {
|
|
return;
|
|
}
|
|
|
|
for (i=0; i<FaxReg->DeviceProviderCount; i++) {
|
|
MemFree( FaxReg->DeviceProviders[i].FriendlyName );
|
|
MemFree( FaxReg->DeviceProviders[i].ImageName );
|
|
MemFree( FaxReg->DeviceProviders[i].ProviderName );
|
|
}
|
|
|
|
for (i=0; i<FaxReg->RoutingExtensionsCount; i++) {
|
|
MemFree( FaxReg->RoutingExtensions[i].FriendlyName );
|
|
MemFree( FaxReg->RoutingExtensions[i].ImageName );
|
|
for (j=0; j<FaxReg->RoutingExtensions[i].RoutingMethodsCount; j++) {
|
|
MemFree( FaxReg->RoutingExtensions[i].RoutingMethods[j].FriendlyName );
|
|
MemFree( FaxReg->RoutingExtensions[i].RoutingMethods[j].FunctionName );
|
|
MemFree( FaxReg->RoutingExtensions[i].RoutingMethods[j].Guid );
|
|
}
|
|
MemFree( FaxReg->RoutingExtensions[i].RoutingMethods );
|
|
}
|
|
|
|
MemFree( FaxReg->DeviceProviders );
|
|
MemFree( FaxReg->RoutingExtensions );
|
|
|
|
for (i=0; i<FaxReg->DeviceCount; i++) {
|
|
MemFree( FaxReg->Devices[i].Name );
|
|
}
|
|
|
|
MemFree( FaxReg->Devices );
|
|
|
|
|
|
for (i=0; i<FaxReg->LoggingCount; i++) {
|
|
MemFree( FaxReg->Logging[i].CategoryName );
|
|
}
|
|
|
|
MemFree( FaxReg->Logging );
|
|
MemFree( FaxReg->lptstrQueueDir );
|
|
|
|
MemFree( FaxReg );
|
|
}
|
|
|
|
|
|
//
|
|
// This functions is provided to support the legacy FaxSetConfiguration API call.
|
|
//
|
|
BOOL
|
|
SetFaxGlobalsRegistry(
|
|
PFAX_CONFIGURATION FaxConfig,
|
|
DWORD dwQueueState
|
|
)
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("SetFaxGlobalsRegistry"));
|
|
DWORD dwRes = SaveQueueState (dwQueueState);
|
|
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
SetLastError (dwRes);
|
|
return FALSE;
|
|
}
|
|
|
|
HKEY hKey;
|
|
HKEY hSentItemsArchiveKey;
|
|
HKEY hReceiptsKey;
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE,
|
|
REGKEY_SOFTWARE,
|
|
TRUE,
|
|
KEY_WRITE );
|
|
if (!hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open server's registry key : %ld"),
|
|
dwRes);
|
|
return FALSE;
|
|
}
|
|
hSentItemsArchiveKey = OpenRegistryKey( hKey,
|
|
REGKEY_ARCHIVE_SENTITEMS_CONFIG,
|
|
TRUE,
|
|
KEY_WRITE );
|
|
if (!hSentItemsArchiveKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open server's sent items archive registry key : %ld"),
|
|
dwRes);
|
|
RegCloseKey( hKey );
|
|
return FALSE;
|
|
}
|
|
|
|
hReceiptsKey = OpenRegistryKey( hKey,
|
|
REGKEY_RECEIPTS_CONFIG,
|
|
TRUE,
|
|
KEY_WRITE );
|
|
if (!hReceiptsKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open server's Receipts registry key : %ld"),
|
|
dwRes);
|
|
RegCloseKey( hKey );
|
|
RegCloseKey( hSentItemsArchiveKey );
|
|
return FALSE;
|
|
}
|
|
SetRegistryDword( hKey, REGVAL_RETRIES, FaxConfig->Retries );
|
|
SetRegistryDword( hKey, REGVAL_RETRYDELAY, FaxConfig->RetryDelay );
|
|
SetRegistryDword( hKey, REGVAL_DIRTYDAYS, FaxConfig->DirtyDays );
|
|
SetRegistryDword( hKey, REGVAL_BRANDING, FaxConfig->Branding );
|
|
SetRegistryDword( hKey, REGVAL_USE_DEVICE_TSID, FaxConfig->UseDeviceTsid );
|
|
SetRegistryDword( hKey, REGVAL_SERVERCP, FaxConfig->ServerCp );
|
|
SetRegistryDword( hKey, REGVAL_STARTCHEAP, MAKELONG( FaxConfig->StartCheapTime.Hour, FaxConfig->StartCheapTime.Minute ) );
|
|
SetRegistryDword( hKey, REGVAL_STOPCHEAP, MAKELONG( FaxConfig->StopCheapTime.Hour, FaxConfig->StopCheapTime.Minute ) );
|
|
SetRegistryDword( hSentItemsArchiveKey,
|
|
REGVAL_ARCHIVE_USE,
|
|
FaxConfig->ArchiveOutgoingFaxes);
|
|
SetRegistryString( hSentItemsArchiveKey,
|
|
REGVAL_ARCHIVE_FOLDER,
|
|
FaxConfig->ArchiveDirectory );
|
|
RegCloseKey( hReceiptsKey );
|
|
RegCloseKey( hSentItemsArchiveKey );
|
|
RegCloseKey( hKey );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* Name: SetFaxJobNumberRegistry
|
|
* Author:
|
|
*******************************************************************************
|
|
DESCRIPTION:
|
|
Saves the value of the next job id to the registry at the
|
|
REGKEY_FAXSERVER\NextJobId value.
|
|
PARAMETERS:
|
|
NextJobNumber
|
|
A DWORD value of the next job id.
|
|
RETURN VALUE:
|
|
TRUE if no error occured.
|
|
FALSE otherwise.
|
|
REMARKS:
|
|
NONE.
|
|
*******************************************************************************/
|
|
|
|
BOOL
|
|
SetFaxJobNumberRegistry(
|
|
DWORD NextJobNumber
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, TRUE, KEY_WRITE );
|
|
if (!hKey) {
|
|
return FALSE;
|
|
}
|
|
|
|
SetRegistryDword( hKey, REGVAL_JOB_NUMBER, NextJobNumber );
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetLoggingCategoriesRegistry(
|
|
PREG_FAX_LOGGING FaxRegLogging
|
|
)
|
|
{
|
|
REG_FAX_SERVICE FaxReg = {0};
|
|
HKEY hKey;
|
|
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_READ );
|
|
if (!hKey) {
|
|
return FALSE;
|
|
}
|
|
|
|
FaxRegLogging->LoggingCount = EnumerateRegistryKeys(
|
|
hKey,
|
|
REGKEY_LOGGING,
|
|
FALSE,
|
|
EnumLogging,
|
|
&FaxReg
|
|
);
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
FaxRegLogging->Logging = FaxReg.Logging;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SetLoggingCategoriesRegistry(
|
|
PREG_FAX_LOGGING FaxRegLogging
|
|
)
|
|
{
|
|
REG_FAX_SERVICE FaxReg = {0};
|
|
HKEY hKey;
|
|
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, TRUE, KEY_READ | KEY_WRITE );
|
|
if (!hKey) {
|
|
return FALSE;
|
|
}
|
|
|
|
FaxReg.Logging = FaxRegLogging->Logging;
|
|
FaxReg.LoggingCount = FaxRegLogging->LoggingCount;
|
|
|
|
EnumerateRegistryKeys(
|
|
hKey,
|
|
REGKEY_LOGGING,
|
|
TRUE,
|
|
EnumLoggingChange,
|
|
&FaxReg
|
|
);
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
PREG_FAX_DEVICES
|
|
GetFaxDevicesRegistry(
|
|
VOID
|
|
)
|
|
{
|
|
PREG_FAX_SERVICE FaxReg;
|
|
PREG_FAX_DEVICES FaxRegDevices;
|
|
HKEY hKey;
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_READ );
|
|
if (!hKey) {
|
|
return NULL;
|
|
}
|
|
|
|
FaxReg = (PREG_FAX_SERVICE) MemAlloc( sizeof(REG_FAX_SERVICE) );
|
|
if (!FaxReg) {
|
|
RegCloseKey( hKey );
|
|
return NULL;
|
|
}
|
|
|
|
FaxRegDevices = (PREG_FAX_DEVICES) MemAlloc( sizeof(REG_FAX_DEVICES) );
|
|
if (!FaxRegDevices) {
|
|
MemFree( FaxReg );
|
|
RegCloseKey( hKey );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// load the devices
|
|
//
|
|
|
|
FaxReg->DeviceCount = EnumerateRegistryKeys(
|
|
hKey,
|
|
REGKEY_DEVICES,
|
|
FALSE,
|
|
EnumDevices,
|
|
FaxReg
|
|
);
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
FaxRegDevices->Devices = FaxReg->Devices;
|
|
FaxRegDevices->DeviceCount = FaxReg->DeviceCount;
|
|
|
|
MemFree( FaxReg );
|
|
|
|
return FaxRegDevices;
|
|
}
|
|
|
|
|
|
//
|
|
// Note: This function requires mutual execlusion. Use CsLine to sync access to it.
|
|
//
|
|
DWORD
|
|
RegAddNewFaxDevice(
|
|
LPDWORD lpdwLastUniqueLineId,
|
|
LPDWORD lpdwPermanentLineId,
|
|
LPTSTR DeviceName,
|
|
LPTSTR ProviderName,
|
|
LPTSTR ProviderGuid,
|
|
LPTSTR Csid,
|
|
LPTSTR Tsid,
|
|
DWORD TapiPermanentLineID,
|
|
DWORD Flags,
|
|
DWORD Rings
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
TCHAR SubKeyName[128];
|
|
DWORD dwNewUniqueLineId;
|
|
DWORD dwAttempt = 0;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("RegAddNewFaxDevice"));
|
|
|
|
Assert( lpdwLastUniqueLineId);
|
|
Assert( lpdwPermanentLineId);
|
|
|
|
|
|
if (0 == *(lpdwPermanentLineId))
|
|
{
|
|
if( ERROR_SUCCESS != GetNewServiceDeviceID(lpdwLastUniqueLineId,lpdwPermanentLineId) )
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to generate next uniqueu line id."));
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// The caller provider the unique line id. This is an update operation.
|
|
//
|
|
dwNewUniqueLineId = *lpdwPermanentLineId;
|
|
|
|
//
|
|
// create the device's registry key
|
|
//
|
|
_stprintf( SubKeyName, TEXT("%s\\%010d"), REGKEY_FAX_DEVICES, dwNewUniqueLineId );
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, SubKeyName, TRUE, KEY_WRITE );
|
|
if (!hKey) {
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey failed for [%s] (ec: %ld)"),
|
|
SubKeyName,
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
|
|
SetDevicesValues(
|
|
hKey,
|
|
*lpdwPermanentLineId,
|
|
TapiPermanentLineID,
|
|
Flags,
|
|
Rings,
|
|
DeviceName,
|
|
ProviderGuid,
|
|
Csid,
|
|
Tsid
|
|
);
|
|
|
|
RegCloseKey( hKey );
|
|
//
|
|
// close the handles and leave
|
|
//
|
|
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
DWORD
|
|
RegSetFaxDeviceFlags(
|
|
DWORD dwPermanentLineID,
|
|
DWORD dwFlags
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
TCHAR SubKeyName[256] = {0};
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("RegSetFaxDeviceFlags"));
|
|
|
|
//
|
|
// Open the device's registry key
|
|
//
|
|
_sntprintf( SubKeyName,
|
|
ARR_SIZE(SubKeyName) - 1,
|
|
TEXT("%s\\%010d\\%s"),
|
|
REGKEY_FAX_DEVICES,
|
|
dwPermanentLineID,
|
|
REGKEY_FAXSVC_DEVICE_GUID);
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, SubKeyName, FALSE, KEY_WRITE );
|
|
if (NULL == hKey)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey failed for [%s] (ec: %ld)"),
|
|
SubKeyName,
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
|
|
if (!SetRegistryDword(hKey, REGVAL_FLAGS, dwFlags))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SetRegistryDword failed (ec: %ld)"),
|
|
dwRes);
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
//
|
|
// close the handles and leave
|
|
//
|
|
return dwRes;
|
|
}
|
|
|
|
BOOL
|
|
SetFaxRoutingInfo(
|
|
LPTSTR ExtensionName,
|
|
LPTSTR MethodName,
|
|
LPTSTR Guid,
|
|
DWORD Priority,
|
|
LPTSTR FunctionName,
|
|
LPTSTR FriendlyName
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
LPTSTR KeyName = NULL;
|
|
|
|
// calculate string size and allocate memory.
|
|
// the string sizes includes the terminating NULL which is replaced with '\\' and terminating NULL of the KeyName String
|
|
KeyName = (LPTSTR) MemAlloc( StringSize(REGKEY_ROUTING_EXTENSION_KEY) +
|
|
StringSize(ExtensionName) +
|
|
StringSize(REGKEY_ROUTING_METHODS) +
|
|
StringSize(MethodName)
|
|
);
|
|
|
|
if ( !KeyName )
|
|
return FALSE;
|
|
|
|
wsprintf( KeyName, L"%s\\%s\\%s\\%s", REGKEY_ROUTING_EXTENSION_KEY, ExtensionName,REGKEY_ROUTING_METHODS, MethodName );
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, KeyName, FALSE, KEY_WRITE );
|
|
if (!hKey) {
|
|
MemFree( KeyName );
|
|
return FALSE;
|
|
}
|
|
|
|
MemFree ( KeyName );
|
|
|
|
SetRegistryString( hKey, REGVAL_FRIENDLY_NAME, FriendlyName );
|
|
SetRegistryString( hKey, REGVAL_FUNCTION_NAME, FunctionName );
|
|
SetRegistryString( hKey, REGVAL_GUID, Guid );
|
|
SetRegistryDword ( hKey, REGVAL_ROUTING_PRIORITY, Priority );
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
DeleteFaxDevice(
|
|
DWORD PermanentLineID,
|
|
DWORD TapiPermanentLineID
|
|
)
|
|
{
|
|
BOOL success = TRUE;
|
|
TCHAR SubKey[512];
|
|
|
|
// delete any extension configuration data
|
|
_stprintf( SubKey, TEXT("%s\\%08x"), REGKEY_TAPIDEVICES, TapiPermanentLineID );
|
|
if(!DeleteRegistryKey( HKEY_LOCAL_MACHINE, SubKey ))
|
|
success = FALSE;
|
|
|
|
// delete any device data
|
|
_stprintf( SubKey, TEXT("%s\\%s\\%010d"), REGKEY_SOFTWARE, REGKEY_DEVICES, PermanentLineID);
|
|
if(!DeleteRegistryKey( HKEY_LOCAL_MACHINE, SubKey ))
|
|
success = FALSE;
|
|
|
|
return success;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
FreeFaxDevicesRegistry(
|
|
PREG_FAX_DEVICES FaxReg
|
|
)
|
|
{
|
|
DWORD i;
|
|
|
|
|
|
if (!FaxReg) {
|
|
return;
|
|
}
|
|
|
|
for (i=0; i<FaxReg->DeviceCount; i++) {
|
|
MemFree( FaxReg->Devices[i].Name );
|
|
}
|
|
|
|
MemFree( FaxReg->Devices );
|
|
|
|
MemFree( FaxReg );
|
|
}
|
|
|
|
|
|
BOOL
|
|
CreateFaxEventSource(
|
|
PREG_FAX_SERVICE FaxReg,
|
|
PFAX_LOG_CATEGORY DefaultCategories,
|
|
int DefaultCategoryCount
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
HKEY hKeyLogging;
|
|
DWORD i;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("CreateFaxEventSource"));
|
|
|
|
if (FaxReg->LoggingCount == 0)
|
|
{
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAX_LOGGING, TRUE, KEY_WRITE );
|
|
if (!hKey)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey failed with %ld."),
|
|
GetLastError ());
|
|
return FALSE;
|
|
}
|
|
|
|
FaxReg->Logging = (PREG_CATEGORY) MemAlloc(DefaultCategoryCount * sizeof(REG_CATEGORY) );
|
|
if (!FaxReg->Logging)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("MemAlloc (%ld) failed."),
|
|
DefaultCategoryCount * sizeof(REG_CATEGORY));
|
|
RegCloseKey( hKey );
|
|
return FALSE;
|
|
}
|
|
|
|
for (i=0; i< (DWORD) DefaultCategoryCount; i++)
|
|
{
|
|
TCHAR szKeyName[16] = {0};
|
|
_itot(i+1,szKeyName,10);
|
|
hKeyLogging = OpenRegistryKey( hKey, szKeyName, TRUE, KEY_WRITE );
|
|
if (hKeyLogging)
|
|
{
|
|
SetRegistryString( hKeyLogging, REGVAL_CATEGORY_NAME, DefaultCategories[i].Name );
|
|
FaxReg->Logging[i].CategoryName = StringDup( DefaultCategories[i].Name);
|
|
|
|
SetRegistryDword( hKeyLogging, REGVAL_CATEGORY_LEVEL, DefaultCategories[i].Level );
|
|
FaxReg->Logging[i].Level = DefaultCategories[i].Level;
|
|
|
|
SetRegistryDword( hKeyLogging, REGVAL_CATEGORY_NUMBER, DefaultCategories[i].Category );
|
|
FaxReg->Logging[i].Number = DefaultCategories[i].Category;
|
|
|
|
RegCloseKey( hKeyLogging );
|
|
}
|
|
}
|
|
|
|
FaxReg->LoggingCount = DefaultCategoryCount;
|
|
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetInstallationInfo(
|
|
LPDWORD Installed,
|
|
LPDWORD InstallType,
|
|
LPDWORD InstalledPlatforms,
|
|
LPDWORD ProductType
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
LONG rVal;
|
|
DWORD RegType;
|
|
DWORD RegSize;
|
|
TCHAR ProductTypeStr[32];
|
|
DWORD Bytes;
|
|
DWORD Type;
|
|
|
|
|
|
if (Installed == NULL || InstallType == NULL || InstalledPlatforms == NULL || ProductType == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
rVal = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_FAX_SETUP,
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
);
|
|
if (rVal != ERROR_SUCCESS) {
|
|
DebugPrint(( TEXT("Could not open setup registry key, ec=0x%08x"), rVal ));
|
|
return FALSE;
|
|
}
|
|
|
|
RegSize = sizeof(DWORD);
|
|
|
|
rVal = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_FAXINSTALLED,
|
|
0,
|
|
&RegType,
|
|
(LPBYTE) Installed,
|
|
&RegSize
|
|
);
|
|
if (rVal != ERROR_SUCCESS) {
|
|
DebugPrint(( TEXT("Could not query installed registry value, ec=0x%08x"), rVal ));
|
|
*Installed = 0;
|
|
}
|
|
|
|
rVal = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_FAXINSTALL_TYPE,
|
|
0,
|
|
&RegType,
|
|
(LPBYTE) InstallType,
|
|
&RegSize
|
|
);
|
|
if (rVal != ERROR_SUCCESS) {
|
|
DebugPrint(( TEXT("Could not query install type registry value, ec=0x%08x"), rVal ));
|
|
*InstallType = 0;
|
|
}
|
|
|
|
rVal = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_FAXINSTALLED_PLATFORMS,
|
|
0,
|
|
&RegType,
|
|
(LPBYTE) InstalledPlatforms,
|
|
&RegSize
|
|
);
|
|
if (rVal != ERROR_SUCCESS) {
|
|
DebugPrint(( TEXT("Could not query install platforms mask registry value, ec=0x%08x"), rVal ));
|
|
*InstalledPlatforms = 0;
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
//
|
|
// get the product type
|
|
//
|
|
|
|
*ProductType = PRODUCT_TYPE_WINNT;
|
|
|
|
rVal = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
TEXT("System\\CurrentControlSet\\Control\\ProductOptions"),
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
);
|
|
if (rVal == ERROR_SUCCESS) {
|
|
Bytes = sizeof(ProductTypeStr);
|
|
|
|
rVal = RegQueryValueEx(
|
|
hKey,
|
|
TEXT("ProductType"),
|
|
NULL,
|
|
&Type,
|
|
(LPBYTE) ProductTypeStr,
|
|
&Bytes
|
|
);
|
|
if (rVal == ERROR_SUCCESS) {
|
|
if ((_tcsicmp( ProductTypeStr, TEXT("SERVERNT") ) == 0) ||
|
|
(_tcsicmp( ProductTypeStr, TEXT("LANMANNT") ) == 0)) {
|
|
*ProductType = PRODUCT_TYPE_SERVER;
|
|
}
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsModemClass1(
|
|
LPSTR SubKey,
|
|
LPBOOL Class1Fax
|
|
)
|
|
{
|
|
BOOL rVal = TRUE;
|
|
LONG Rslt;
|
|
HKEY hKey;
|
|
DWORD Type;
|
|
DWORD Size;
|
|
|
|
|
|
*Class1Fax = 0;
|
|
|
|
Rslt = RegOpenKeyExA(
|
|
HKEY_LOCAL_MACHINE,
|
|
SubKey,
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
);
|
|
if (Rslt == ERROR_SUCCESS) {
|
|
Size = sizeof(DWORD);
|
|
Rslt = RegQueryValueEx(
|
|
hKey,
|
|
TEXT("FaxClass1"),
|
|
0,
|
|
&Type,
|
|
(LPBYTE) Class1Fax,
|
|
&Size
|
|
);
|
|
if (Rslt != ERROR_SUCCESS) {
|
|
rVal = FALSE;
|
|
}
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SaveModemClass(
|
|
LPSTR SubKey,
|
|
BOOL Class1Fax
|
|
)
|
|
{
|
|
BOOL rVal = FALSE;
|
|
LONG Rslt;
|
|
HKEY hKey;
|
|
|
|
|
|
Rslt = RegOpenKeyExA(
|
|
HKEY_LOCAL_MACHINE,
|
|
SubKey,
|
|
0,
|
|
KEY_WRITE,
|
|
&hKey
|
|
);
|
|
if (Rslt == ERROR_SUCCESS) {
|
|
Rslt = RegSetValueEx(
|
|
hKey,
|
|
TEXT("FaxClass1"),
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE) &Class1Fax,
|
|
sizeof(DWORD)
|
|
);
|
|
if (Rslt == ERROR_SUCCESS) {
|
|
rVal = TRUE;
|
|
}
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetOrigSetupData(
|
|
IN DWORD dwPermanentLineId,
|
|
OUT PREG_SETUP RegSetup
|
|
)
|
|
/*++
|
|
|
|
Routine name : GetOrigSetupData
|
|
|
|
Routine description:
|
|
|
|
Read from the Registry Device's data. At upgrades, Setup writes some Devices's data,
|
|
and this function reads this and fills RegSetup.
|
|
Devices are recognized by their Permanent Line Id, which should not change during the
|
|
upgrade. After a specific device information is read, the key is deleted.
|
|
|
|
Author:
|
|
|
|
Iv Garber (IvG), Mar, 2001
|
|
|
|
Arguments:
|
|
|
|
dwPermanentLineId [IN] - Permanent Line Id of the Device
|
|
RegSetup [OUT] - the structure to be returned
|
|
|
|
Return Value:
|
|
|
|
TRUE if succeded, FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
HKEY hKey = NULL;
|
|
BOOL fDeviceKey = TRUE;
|
|
TCHAR tszKeyName[256] = {0};
|
|
DEBUG_FUNCTION_NAME(TEXT("GetOrigSetupData"));
|
|
|
|
|
|
//
|
|
// see if some data is stored for this Permanent Line Id
|
|
//
|
|
_stprintf(tszKeyName, TEXT("%s\\%010d"), REGKEY_FAX_SETUP_ORIG, dwPermanentLineId);
|
|
hKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, tszKeyName, FALSE, KEY_READ);
|
|
if (!hKey)
|
|
{
|
|
//
|
|
// This Permanent Line Id is new, so take default values
|
|
//
|
|
fDeviceKey = FALSE;
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAX_SETUP_ORIG, FALSE, KEY_READ);
|
|
if (!hKey)
|
|
{
|
|
//
|
|
// Registry is corrupted
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Cann't open key SETUP_ORIG, ec = %ld"),
|
|
GetLastError());
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
RegSetup->lptstrDescription = StringDup(EMPTY_STRING);
|
|
RegSetup->Csid = GetRegistryString(hKey, REGVAL_ROUTING_CSID, REGVAL_DEFAULT_CSID);
|
|
RegSetup->Tsid = GetRegistryString(hKey, REGVAL_ROUTING_TSID, REGVAL_DEFAULT_TSID);
|
|
RegSetup->Rings = GetRegistryDword(hKey, REGVAL_RINGS);
|
|
RegSetup->Flags = GetRegistryDword(hKey, REGVAL_FLAGS);
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
//
|
|
// Delete the key if it is a key of a device after upgrade from W2K.
|
|
//
|
|
if (TRUE == fDeviceKey)
|
|
{
|
|
DWORD dwRes = RegDeleteKey (HKEY_LOCAL_MACHINE, tszKeyName);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegDeleteKey failed, error %ld"),
|
|
dwRes);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
FreeOrigSetupData(
|
|
PREG_SETUP RegSetup
|
|
)
|
|
{
|
|
MemFree( RegSetup->Csid );
|
|
MemFree( RegSetup->Tsid );
|
|
MemFree( RegSetup->lptstrDescription );
|
|
}
|
|
|
|
DWORD
|
|
SaveQueueState (
|
|
DWORD dwNewState
|
|
)
|
|
/*++
|
|
|
|
Routine name : SaveQueueState
|
|
|
|
Routine description:
|
|
|
|
Saves the queue state bits to the registry
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
dwNewState [in] - New state to save
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error codes
|
|
|
|
--*/
|
|
{
|
|
HKEY hKey;
|
|
DWORD dwRes;
|
|
DEBUG_FUNCTION_NAME(TEXT("SaveQueueState"));
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_WRITE );
|
|
if (!hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
//
|
|
// Set the fax queue value
|
|
//
|
|
if (!SetRegistryDword( hKey, REGVAL_QUEUE_STATE, dwNewState))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
RegCloseKey( hKey );
|
|
return dwRes;
|
|
}
|
|
RegCloseKey( hKey );
|
|
return ERROR_SUCCESS;
|
|
} // SaveQueueState
|
|
|
|
DWORD
|
|
StoreReceiptsSettings (
|
|
CONST PFAX_RECEIPTS_CONFIG pReceiptsConfig
|
|
)
|
|
/*++
|
|
|
|
Routine name : StoreReceiptsSettings
|
|
|
|
Routine description:
|
|
|
|
Stores Receipts configuration in the registry.
|
|
Create the Receipts subkey if not existent.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
pReceiptsConfig [in] - Receipts configuration to store
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hServerKey = NULL;
|
|
HKEY hReceiptsKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("StoreReceiptsSettings"));
|
|
|
|
hServerKey = OpenRegistryKey( HKEY_LOCAL_MACHINE,
|
|
REGKEY_SOFTWARE,
|
|
FALSE,
|
|
KEY_WRITE );
|
|
if (NULL == hServerKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
dwRes = RegCreateKey (hServerKey, REGKEY_RECEIPTS_CONFIG, &hReceiptsKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create or open key : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (!SetRegistryDword( hReceiptsKey, REGVAL_ISFOR_MSROUTE, pReceiptsConfig->bIsToUseForMSRouteThroughEmailMethod))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (!SetRegistryDword( hReceiptsKey, REGVAL_RECEIPTS_TYPE, pReceiptsConfig->dwAllowedReceipts))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if(
|
|
(pReceiptsConfig->dwAllowedReceipts & DRT_EMAIL)
|
|
||
|
|
pReceiptsConfig->bIsToUseForMSRouteThroughEmailMethod
|
|
)
|
|
{
|
|
if (!SetRegistryDword( hReceiptsKey, REGVAL_RECEIPTS_PORT, pReceiptsConfig->dwSMTPPort))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hReceiptsKey, REGVAL_RECEIPTS_SMTP_AUTH_TYPE, pReceiptsConfig->SMTPAuthOption))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hReceiptsKey,
|
|
REGVAL_RECEIPTS_SERVER,
|
|
pReceiptsConfig->lptstrSMTPServer ?
|
|
pReceiptsConfig->lptstrSMTPServer :
|
|
EMPTY_STRING))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hReceiptsKey,
|
|
REGVAL_RECEIPTS_FROM,
|
|
pReceiptsConfig->lptstrSMTPFrom ?
|
|
pReceiptsConfig->lptstrSMTPFrom : EMPTY_STRING))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hReceiptsKey,
|
|
REGVAL_RECEIPTS_USER,
|
|
pReceiptsConfig->lptstrSMTPUserName ?
|
|
pReceiptsConfig->lptstrSMTPUserName : EMPTY_STRING))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (pReceiptsConfig->lptstrSMTPPassword)
|
|
{
|
|
if (!SetRegistrySecureString(
|
|
hReceiptsKey,
|
|
REGVAL_RECEIPTS_PASSWORD,
|
|
pReceiptsConfig->lptstrSMTPPassword ?
|
|
pReceiptsConfig->lptstrSMTPPassword : EMPTY_STRING,
|
|
TRUE // Optionally non-encrypted
|
|
))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hReceiptsKey)
|
|
{
|
|
RegCloseKey (hReceiptsKey);
|
|
}
|
|
if (NULL != hServerKey)
|
|
{
|
|
RegCloseKey (hServerKey);
|
|
}
|
|
return dwRes;
|
|
} // StoreReceiptsSettings
|
|
|
|
DWORD
|
|
LoadReceiptsSettings (
|
|
PFAX_SERVER_RECEIPTS_CONFIGW pReceiptsConfig
|
|
)
|
|
/*++
|
|
|
|
Routine name : LoadReceiptsSettings
|
|
|
|
Routine description:
|
|
|
|
Reads Receipts configuration from the registry.
|
|
Ovverride destination strings without freeing anything.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
pReceiptsConfig [out] - Receipts configuration to read
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hReceiptsKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("LoadReceiptsSettings"));
|
|
|
|
hReceiptsKey = OpenRegistryKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_SOFTWARE TEXT("\\") REGKEY_RECEIPTS_CONFIG,
|
|
FALSE,
|
|
KEY_READ | KEY_WRITE );
|
|
if (NULL == hReceiptsKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
pReceiptsConfig->dwSMTPPort = GetRegistryDword (hReceiptsKey, REGVAL_RECEIPTS_PORT);
|
|
if (0 == pReceiptsConfig->dwSMTPPort)
|
|
{
|
|
//
|
|
// A zero port is invalid
|
|
//
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SMTPPort invalid value read : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
pReceiptsConfig->bIsToUseForMSRouteThroughEmailMethod =
|
|
GetRegistryDword (hReceiptsKey, REGVAL_ISFOR_MSROUTE);
|
|
|
|
pReceiptsConfig->SMTPAuthOption =
|
|
(FAX_ENUM_SMTP_AUTH_OPTIONS)GetRegistryDword (hReceiptsKey, REGVAL_RECEIPTS_SMTP_AUTH_TYPE);
|
|
if ((FAX_SMTP_AUTH_ANONYMOUS > pReceiptsConfig->SMTPAuthOption) ||
|
|
(FAX_SMTP_AUTH_NTLM < pReceiptsConfig->SMTPAuthOption))
|
|
{
|
|
//
|
|
// Value out of range
|
|
//
|
|
dwRes = ERROR_BADDB;
|
|
SetLastError (dwRes);
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SMTPAuthOption value out of range"));
|
|
goto exit;
|
|
}
|
|
pReceiptsConfig->dwAllowedReceipts =GetRegistryDword (hReceiptsKey, REGVAL_RECEIPTS_TYPE);
|
|
if (pReceiptsConfig->dwAllowedReceipts & ~DRT_ALL)
|
|
{
|
|
//
|
|
// Value out of range
|
|
//
|
|
dwRes = ERROR_BADDB;
|
|
SetLastError (dwRes);
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("AllowedReceipts value out of range"));
|
|
goto exit;
|
|
}
|
|
pReceiptsConfig->lptstrSMTPServer = GetRegistryString (hReceiptsKey, REGVAL_RECEIPTS_SERVER, EMPTY_STRING);
|
|
pReceiptsConfig->lptstrSMTPFrom = GetRegistryString (hReceiptsKey, REGVAL_RECEIPTS_FROM, EMPTY_STRING);
|
|
pReceiptsConfig->lptstrSMTPPassword = NULL; // we do not hold the password in memory - we read it only when we need to
|
|
pReceiptsConfig->lptstrSMTPUserName = GetRegistryString (hReceiptsKey, REGVAL_RECEIPTS_USER, EMPTY_STRING);
|
|
pReceiptsConfig->lptstrReserved = NULL;
|
|
|
|
if (TRUE == IsDesktopSKU())
|
|
{
|
|
//
|
|
// We do not support SMTP receipts on desktop SKUs
|
|
//
|
|
pReceiptsConfig->dwAllowedReceipts &= ~DRT_EMAIL;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hReceiptsKey)
|
|
{
|
|
RegCloseKey (hReceiptsKey);
|
|
}
|
|
return dwRes;
|
|
} // LoadReceiptsSettings
|
|
|
|
DWORD
|
|
StoreOutboxSettings (
|
|
PFAX_OUTBOX_CONFIG pOutboxCfg
|
|
)
|
|
/*++
|
|
|
|
Routine name : StoreOutboxSettings
|
|
|
|
Routine description:
|
|
|
|
Stores Outbox configuration to the registry.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
pOutboxCfg [in] - Outbox configuration to write
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("StoreOutboxSettings"));
|
|
|
|
hKey = OpenRegistryKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_SOFTWARE,
|
|
FALSE,
|
|
KEY_WRITE );
|
|
if (NULL == hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_RETRIES, pOutboxCfg->dwRetries ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_RETRIES) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_RETRYDELAY, pOutboxCfg->dwRetryDelay ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_RETRYDELAY) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_DIRTYDAYS, pOutboxCfg->dwAgeLimit ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_DIRTYDAYS) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_BRANDING, pOutboxCfg->bBranding ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_BRANDING) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_USE_DEVICE_TSID, pOutboxCfg->bUseDeviceTSID ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_USE_DEVICE_TSID) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_SERVERCP, !pOutboxCfg->bAllowPersonalCP ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_SERVERCP) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey,
|
|
REGVAL_STARTCHEAP,
|
|
MAKELONG(pOutboxCfg->dtDiscountStart.Hour,
|
|
pOutboxCfg->dtDiscountStart.Minute) ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_STARTCHEAP) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey,
|
|
REGVAL_STOPCHEAP,
|
|
MAKELONG(pOutboxCfg->dtDiscountEnd.Hour,
|
|
pOutboxCfg->dtDiscountEnd.Minute) ))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't SetRegistryDword(REGVAL_STOPCHEAP) : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
return dwRes;
|
|
|
|
} // StoreOutboxSettings
|
|
|
|
DWORD
|
|
LoadArchiveSettings (
|
|
FAX_ENUM_MESSAGE_FOLDER Folder,
|
|
PFAX_ARCHIVE_CONFIG pCfg
|
|
)
|
|
/*++
|
|
|
|
Routine name : LoadArchiveSettings
|
|
|
|
Routine description:
|
|
|
|
Reads archive configuration from the registry.
|
|
Ovverride destination strings without freeing anything.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
Folder [in ] - Archive folder type
|
|
pCfg [out] - Archive configuration to read
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("LoadArchiveSettings"));
|
|
|
|
Assert (FAX_MESSAGE_FOLDER_INBOX == Folder ||
|
|
FAX_MESSAGE_FOLDER_SENTITEMS == Folder);
|
|
Assert (pCfg);
|
|
|
|
hKey = OpenRegistryKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
FAX_MESSAGE_FOLDER_INBOX == Folder ?
|
|
REGKEY_SOFTWARE TEXT("\\") REGKEY_ARCHIVE_INBOX_CONFIG :
|
|
REGKEY_SOFTWARE TEXT("\\") REGKEY_ARCHIVE_SENTITEMS_CONFIG,
|
|
FALSE,
|
|
KEY_READ | KEY_WRITE );
|
|
if (NULL == hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
pCfg->dwSizeOfStruct = sizeof (FAX_ARCHIVE_CONFIG);
|
|
pCfg->bUseArchive = GetRegistryDword (hKey, REGVAL_ARCHIVE_USE);
|
|
pCfg->bSizeQuotaWarning = GetRegistryDword (hKey, REGVAL_ARCHIVE_SIZE_QUOTA_WARNING);
|
|
pCfg->dwSizeQuotaHighWatermark = GetRegistryDword (hKey, REGVAL_ARCHIVE_HIGH_WATERMARK);
|
|
pCfg->dwSizeQuotaLowWatermark = GetRegistryDword (hKey, REGVAL_ARCHIVE_LOW_WATERMARK);
|
|
pCfg->dwAgeLimit = GetRegistryDword (hKey, REGVAL_ARCHIVE_AGE_LIMIT);
|
|
if (pCfg->bUseArchive &&
|
|
(pCfg->dwSizeQuotaHighWatermark < pCfg->dwSizeQuotaLowWatermark))
|
|
{
|
|
//
|
|
// Invalid value
|
|
//
|
|
DebugPrintEx(DEBUG_ERR, TEXT("Invalid archive watermarks"));
|
|
dwRes = ERROR_INVALID_DATA;
|
|
goto exit;
|
|
}
|
|
|
|
pCfg->lpcstrFolder = GetRegistryString (hKey, REGVAL_ARCHIVE_FOLDER, BAD_FOLDER_STRING);
|
|
if (pCfg->bUseArchive && !lstrcmp (BAD_FOLDER_STRING, pCfg->lpcstrFolder))
|
|
{
|
|
//
|
|
// Invalid value
|
|
//
|
|
DebugPrintEx(DEBUG_ERR, TEXT("Invalid archive folder"));
|
|
dwRes = ERROR_INVALID_DATA;
|
|
MemFree (pCfg->lpcstrFolder);
|
|
pCfg->lpcstrFolder = NULL;
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
return dwRes;
|
|
} // LoadArchiveSettings
|
|
|
|
DWORD
|
|
StoreArchiveSettings (
|
|
FAX_ENUM_MESSAGE_FOLDER Folder,
|
|
PFAX_ARCHIVE_CONFIG pCfg
|
|
)
|
|
/*++
|
|
|
|
Routine name : StoreArchiveSettings
|
|
|
|
Routine description:
|
|
|
|
Writes archive configuration to the registry.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
Folder [in] - Archive folder type
|
|
pCfg [in] - Archive configuration to write
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hServerKey = NULL;
|
|
HKEY hKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("StoreArchiveSettings"));
|
|
|
|
Assert (FAX_MESSAGE_FOLDER_INBOX == Folder ||
|
|
FAX_MESSAGE_FOLDER_SENTITEMS == Folder);
|
|
Assert (pCfg);
|
|
|
|
hServerKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_WRITE );
|
|
if (NULL == hServerKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
dwRes = RegCreateKey ( hServerKey,
|
|
FAX_MESSAGE_FOLDER_INBOX == Folder ?
|
|
REGKEY_ARCHIVE_INBOX_CONFIG :
|
|
REGKEY_ARCHIVE_SENTITEMS_CONFIG,
|
|
&hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create or open key : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (!SetRegistryDword( hKey, REGVAL_ARCHIVE_USE, pCfg->bUseArchive))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_ARCHIVE_SIZE_QUOTA_WARNING, pCfg->bSizeQuotaWarning))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_ARCHIVE_HIGH_WATERMARK, pCfg->dwSizeQuotaHighWatermark))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_ARCHIVE_LOW_WATERMARK, pCfg->dwSizeQuotaLowWatermark))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_ARCHIVE_AGE_LIMIT, pCfg->dwAgeLimit))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hKey,
|
|
REGVAL_ARCHIVE_FOLDER,
|
|
pCfg->lpcstrFolder ? pCfg->lpcstrFolder : EMPTY_STRING))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
if (NULL != hServerKey)
|
|
{
|
|
RegCloseKey (hServerKey);
|
|
}
|
|
return dwRes;
|
|
} // StoreArchiveSettings
|
|
|
|
DWORD
|
|
LoadActivityLoggingSettings (
|
|
PFAX_SERVER_ACTIVITY_LOGGING_CONFIG pLogCfg
|
|
)
|
|
/*++
|
|
|
|
Routine name : LoadActivityLoggingSettings
|
|
|
|
Routine description:
|
|
|
|
Reads activity logging configuration from the registry.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
pLogCfg [in] - Activity logging configuration to read
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("LoadActivityLoggingSettings"));
|
|
|
|
Assert (pLogCfg);
|
|
|
|
hKey = OpenRegistryKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_SOFTWARE TEXT("\\") REGKEY_ACTIVITY_LOG_CONFIG,
|
|
FALSE,
|
|
KEY_READ | KEY_WRITE );
|
|
if (NULL == hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
pLogCfg->dwSizeOfStruct = sizeof (FAX_ACTIVITY_LOGGING_CONFIG);
|
|
pLogCfg->bLogIncoming = GetRegistryDword (hKey, REGVAL_ACTIVITY_LOG_IN);
|
|
pLogCfg->bLogOutgoing = GetRegistryDword (hKey, REGVAL_ACTIVITY_LOG_OUT);
|
|
|
|
|
|
//
|
|
// read Activity log file limit criterions setting
|
|
//
|
|
// Notice: This settings are not configurable through UI nor RPC calls.
|
|
// The only way to configure them is through directly registry settings.
|
|
// Hence StoreActivityLoggingSettings() will not persist this settings back to the registry
|
|
//
|
|
pLogCfg->dwLogLimitCriteria = GetRegistryDword (hKey, REGVAL_ACTIVITY_LOG_LIMIT_CRITERIA);
|
|
pLogCfg->dwLogSizeLimit = GetRegistryDword (hKey, REGVAL_ACTIVITY_LOG_SIZE_LIMIT);
|
|
pLogCfg->dwLogAgeLimit = GetRegistryDword (hKey, REGVAL_ACTIVITY_LOG_AGE_LIMIT);
|
|
pLogCfg->dwLimitReachedAction = GetRegistryDword (hKey, REGVAL_ACTIVITY_LOG_LIMIT_REACHED_ACTION);
|
|
|
|
if ( 0 == pLogCfg->dwLogSizeLimit)
|
|
{
|
|
//
|
|
// Illegal value, set default value
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Illegal value in dwLogSizeLimit. Default value of %ld Mbytes is used."),
|
|
ACTIVITY_LOG_DEFAULT_SIZE_LIMIT);
|
|
|
|
pLogCfg->dwLogSizeLimit = ACTIVITY_LOG_DEFAULT_SIZE_LIMIT;
|
|
}
|
|
|
|
if ( 0 == pLogCfg->dwLogAgeLimit )
|
|
{
|
|
//
|
|
// Illegal value, set default value
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Illegal value in dwLogAgeLimit. Default value of %ld months is used."),
|
|
ACTIVITY_LOG_DEFAULT_AGE_LIMIT);
|
|
|
|
pLogCfg->dwLogAgeLimit = ACTIVITY_LOG_DEFAULT_AGE_LIMIT;
|
|
}
|
|
|
|
if ( ACTIVITY_LOG_LIMIT_CRITERIA_NONE != pLogCfg->dwLogLimitCriteria &&
|
|
ACTIVITY_LOG_LIMIT_CRITERIA_SIZE != pLogCfg->dwLogLimitCriteria &&
|
|
ACTIVITY_LOG_LIMIT_CRITERIA_AGE != pLogCfg->dwLogLimitCriteria )
|
|
{
|
|
//
|
|
// Illegal value, set default value
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Illegal value in dwLogLimitCriteria. Default value (not using logging limit) - is used.")
|
|
);
|
|
|
|
pLogCfg->dwLogLimitCriteria = ACTIVITY_LOG_LIMIT_CRITERIA_NONE;
|
|
|
|
}
|
|
|
|
if ( ACTIVITY_LOG_LIMIT_REACHED_ACTION_COPY != pLogCfg->dwLimitReachedAction &&
|
|
ACTIVITY_LOG_LIMIT_REACHED_ACTION_DELETE != pLogCfg->dwLimitReachedAction )
|
|
{
|
|
//
|
|
// Illegal value, set default value
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Illegal value in dwLogLimitCriteria. Default value (copy log file) is used.")
|
|
);
|
|
|
|
pLogCfg->dwLimitReachedAction = ACTIVITY_LOG_LIMIT_REACHED_ACTION_COPY;
|
|
|
|
}
|
|
|
|
if (pLogCfg->bLogIncoming || pLogCfg->bLogOutgoing)
|
|
{
|
|
pLogCfg->lptstrDBPath = GetRegistryString (hKey, REGVAL_ACTIVITY_LOG_DB, BAD_FOLDER_STRING);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// No logging => DB path is NULL
|
|
//
|
|
pLogCfg->lptstrDBPath = NULL;
|
|
}
|
|
if ((pLogCfg->bLogIncoming || pLogCfg->bLogOutgoing) &&
|
|
!lstrcmp (BAD_FOLDER_STRING, pLogCfg->lptstrDBPath))
|
|
{
|
|
//
|
|
// Invalid value
|
|
//
|
|
DebugPrintEx(DEBUG_ERR, TEXT("Invalid activity logging database"));
|
|
dwRes = ERROR_INVALID_DATA;
|
|
MemFree (pLogCfg->lptstrDBPath);
|
|
pLogCfg->lptstrDBPath = NULL;
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
return dwRes;
|
|
} // LoadActivityLoggingSettings
|
|
|
|
|
|
DWORD
|
|
StoreActivityLoggingSettings (
|
|
PFAX_ACTIVITY_LOGGING_CONFIG pLogCfg
|
|
)
|
|
/*++
|
|
|
|
Routine name : StoreActivityLoggingSettings
|
|
|
|
Routine description:
|
|
|
|
Writes activity logging configuration to the registry.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
pLogCfg [in] - Activity logging configuration to write
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hServerKey = NULL;
|
|
HKEY hKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("StoreActivityLoggingSettings"));
|
|
|
|
Assert (pLogCfg);
|
|
|
|
hServerKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_WRITE );
|
|
if (NULL == hServerKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
dwRes = RegCreateKey ( hServerKey,
|
|
REGKEY_ACTIVITY_LOG_CONFIG,
|
|
&hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create or open key : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (!SetRegistryDword( hKey, REGVAL_ACTIVITY_LOG_IN, pLogCfg->bLogIncoming))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_ACTIVITY_LOG_OUT, pLogCfg->bLogOutgoing))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hKey,
|
|
REGVAL_ACTIVITY_LOG_DB,
|
|
pLogCfg->lptstrDBPath ? pLogCfg->lptstrDBPath : EMPTY_STRING))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
if (NULL != hServerKey)
|
|
{
|
|
RegCloseKey (hServerKey);
|
|
}
|
|
return dwRes;
|
|
} // StoreActivityLoggingSettings
|
|
|
|
|
|
DWORD
|
|
StoreDeviceConfig (
|
|
DWORD dwDeviceId,
|
|
PFAX_PORT_INFO_EX pPortInfo,
|
|
BOOL bVirtualDevice
|
|
)
|
|
/*++
|
|
|
|
Routine name : StoreDeviceConfig
|
|
|
|
Routine description:
|
|
|
|
Writes device configuration to the registry.
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId [in] - Device identifier
|
|
pPortInfo [in] - Configuration bloack to write.
|
|
Writes: Enable send flag
|
|
Enable receive flag
|
|
Rings for answer count
|
|
CSID
|
|
TSID
|
|
Description
|
|
bVirtualDevice [in] - Should we set FPF_VIRTUAL ?
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hKey = NULL;
|
|
TCHAR wszSubKeyName[MAX_PATH];
|
|
DWORD dwFlags = 0;
|
|
DEBUG_FUNCTION_NAME(TEXT("StoreDeviceConfig"));
|
|
|
|
Assert (pPortInfo);
|
|
|
|
_stprintf( wszSubKeyName, TEXT("%s\\%010d\\%s"), REGKEY_FAX_DEVICES, dwDeviceId, REGKEY_FAXSVC_DEVICE_GUID );
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, wszSubKeyName, FALSE, KEY_WRITE );
|
|
if (NULL == hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open device key : %ld"),
|
|
dwRes);
|
|
ASSERT_FALSE; // The device must exist !!!
|
|
return dwRes;
|
|
}
|
|
|
|
if (bVirtualDevice)
|
|
{
|
|
dwFlags |= FPF_VIRTUAL;
|
|
}
|
|
if (FAX_DEVICE_RECEIVE_MODE_AUTO == pPortInfo->ReceiveMode)
|
|
{
|
|
dwFlags |= FPF_RECEIVE;
|
|
}
|
|
if (pPortInfo->bSend)
|
|
{
|
|
dwFlags |= FPF_SEND;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_FLAGS, dwFlags))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_RINGS, pPortInfo->dwRings))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hKey, REGVAL_ROUTING_CSID, pPortInfo->lptstrCsid))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hKey, REGVAL_ROUTING_TSID, pPortInfo->lptstrTsid))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString( hKey, REGVAL_DEVICE_DESCRIPTION, pPortInfo->lptstrDescription))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't write value : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
return dwRes;
|
|
} // StoreDeviceConfig
|
|
|
|
static
|
|
DWORD
|
|
OpenExtensionKey (
|
|
DWORD dwDeviceId,
|
|
FAX_ENUM_DEVICE_ID_SOURCE DevIdSrc,
|
|
PHKEY lphKey
|
|
)
|
|
/*++
|
|
|
|
Routine name : OpenExtensionKey
|
|
|
|
Routine description:
|
|
|
|
Opens the extension's configuration key according to the device id
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId [in ] - Device identifier
|
|
DevIdSrc [in ] - Class of device id (Fax / TAPI)
|
|
lphKey [out] - Registry handle to open key
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
TCHAR wszSubKeyName[MAX_PATH];
|
|
DEBUG_FUNCTION_NAME(TEXT("OpenExtensionKey"));
|
|
|
|
Assert (lphKey);
|
|
|
|
if (0 == dwDeviceId)
|
|
{
|
|
//
|
|
// Non-associated data is always written under the fax devices key
|
|
//
|
|
DevIdSrc = DEV_ID_SRC_FAX;
|
|
}
|
|
switch (DevIdSrc)
|
|
{
|
|
case DEV_ID_SRC_FAX:
|
|
if (!dwDeviceId)
|
|
{
|
|
//
|
|
// We're dealing with an unassociated device here
|
|
//
|
|
_stprintf( wszSubKeyName,
|
|
TEXT("%s\\%s"),
|
|
REGKEY_FAX_DEVICES,
|
|
REGKEY_UNASSOC_EXTENSION_DATA );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Extension data associated with a device , saved under service GUID !!!
|
|
//
|
|
_stprintf( wszSubKeyName, TEXT("%s\\%010d\\%s"), REGKEY_FAX_DEVICES, dwDeviceId, REGKEY_FAXSVC_DEVICE_GUID );
|
|
}
|
|
break;
|
|
|
|
case DEV_ID_SRC_TAPI:
|
|
Assert (dwDeviceId);
|
|
{
|
|
//
|
|
// Make sure the key of TAPI devices configuration exists - create if needed.
|
|
//
|
|
HKEY hkeyTAPIConfig = OpenRegistryKey (HKEY_LOCAL_MACHINE,
|
|
REGKEY_TAPIDEVICES,
|
|
TRUE,
|
|
KEY_READ);
|
|
if (NULL == hkeyTAPIConfig)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open / create TAPI devices configuration key : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
RegCloseKey (hkeyTAPIConfig);
|
|
}
|
|
_stprintf( wszSubKeyName, TEXT("%s\\%08lx"), REGKEY_TAPIDEVICES, dwDeviceId );
|
|
break;
|
|
|
|
default:
|
|
ASSERT_FALSE;
|
|
return ERROR_GEN_FAILURE;
|
|
}
|
|
//
|
|
// Try to open device key (create if needed)
|
|
//
|
|
*lphKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, wszSubKeyName, TRUE, KEY_READ | KEY_WRITE );
|
|
if (NULL == *lphKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open device (%ld) key : %ld"),
|
|
dwDeviceId,
|
|
dwRes);
|
|
}
|
|
return dwRes;
|
|
} // OpenExtensionKey
|
|
|
|
DWORD
|
|
ReadExtensionData (
|
|
DWORD dwDeviceId,
|
|
FAX_ENUM_DEVICE_ID_SOURCE DevIdSrc,
|
|
LPCWSTR lpcwstrNameGUID,
|
|
LPBYTE *ppData,
|
|
LPDWORD lpdwDataSize
|
|
)
|
|
/*++
|
|
|
|
Routine name : ReadExtensionData
|
|
|
|
Routine description:
|
|
|
|
Reads extesnion configuration data from the registry
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId [in ] - Device identifier
|
|
0 = Data is not associated with any given device
|
|
DevIdSrc [in ] - Class of device id (Fax / TAPI)
|
|
lpcwstrNameGUID [in ] - Name of data (GUID format)
|
|
ppData [out] - Pointer to block that receives the data.
|
|
lpdwDataSize [out] - Points to data size
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("ReadExtensionData"));
|
|
|
|
Assert (ppData);
|
|
Assert (lpdwDataSize);
|
|
|
|
dwRes = OpenExtensionKey (dwDeviceId, DevIdSrc, &hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
return dwRes;
|
|
}
|
|
dwRes = GetRegistrySecureBinary(hKey,
|
|
lpcwstrNameGUID,
|
|
ppData,
|
|
lpdwDataSize,
|
|
TRUE, // Optionally non-ecrypted
|
|
NULL // Dont care if the data was decrypted or not
|
|
);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetRegistrySecureBinary on device %ld and GUID %s failed with %ld"),
|
|
dwDeviceId,
|
|
lpcwstrNameGUID,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
//
|
|
// Success
|
|
//
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
|
|
if (hKey)
|
|
{
|
|
RegCloseKey (hKey);
|
|
}
|
|
return dwRes;
|
|
} // ReadExtensionData
|
|
|
|
DWORD
|
|
WriteExtensionData (
|
|
DWORD dwDeviceId,
|
|
FAX_ENUM_DEVICE_ID_SOURCE DevIdSrc,
|
|
LPCWSTR lpcwstrNameGUID,
|
|
LPBYTE pData,
|
|
DWORD dwDataSize
|
|
)
|
|
/*++
|
|
|
|
Routine name : WriteExtensionData
|
|
|
|
Routine description:
|
|
|
|
Writes extesnion configuration data to the registry
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Nov, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId [in ] - Device identifier
|
|
0 = Data is not associated with any given device
|
|
DevIdSrc [in ] - Class of device id (Fax / TAPI)
|
|
lpcwstrNameGUID [in ] - Name of data (GUID format)
|
|
pData [out] - Pointer to data.
|
|
dwDataSize [out] - Data size
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("WriteExtensionData"));
|
|
|
|
Assert (pData);
|
|
Assert (dwDataSize);
|
|
|
|
dwRes = OpenExtensionKey (dwDeviceId, DevIdSrc, &hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
return dwRes;
|
|
}
|
|
//
|
|
// Write data
|
|
//
|
|
if (!SetRegistrySecureBinary (hKey,
|
|
lpcwstrNameGUID,
|
|
pData,
|
|
dwDataSize,
|
|
TRUE // Optionally non-ecrypted
|
|
))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SetRegistrySecureBinary on device %ld and GUID %s failed with %ld"),
|
|
dwDeviceId,
|
|
lpcwstrNameGUID,
|
|
dwRes);
|
|
}
|
|
RegCloseKey (hKey);
|
|
return dwRes;
|
|
} // WriteExtensionData
|
|
|
|
|
|
//********************************************
|
|
//* Outbound routing
|
|
//********************************************
|
|
|
|
HKEY
|
|
OpenOutboundGroupKey (
|
|
LPCWSTR lpcwstrGroupName,
|
|
BOOL fNewKey,
|
|
REGSAM SamDesired
|
|
)
|
|
/*++
|
|
|
|
Routine name : OpenOutboundGroupKey
|
|
|
|
Routine description:
|
|
|
|
Opens an outbound routing group key
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpcwstrGroupName [in] - The outbound routing group name
|
|
fNewKey [in] - Flag that indicates to create a new key
|
|
SamDesired [in] - Desired access (See OpenRegistryKey)
|
|
|
|
Return Value:
|
|
|
|
Handle to the opened key. If this is NULL call GetLastError() for more info.
|
|
|
|
--*/
|
|
{
|
|
HKEY hGroupkey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("OpenOutboundGroupKey"));
|
|
WCHAR wszSubKeyName[2*MAX_PATH] = {0};
|
|
int Count;
|
|
|
|
Assert (lpcwstrGroupName);
|
|
|
|
Count = _snwprintf ( wszSubKeyName,
|
|
ARR_SIZE(wszSubKeyName) - 1,
|
|
TEXT("%s\\%s"),
|
|
REGKEY_FAX_OUTBOUND_ROUTING_GROUPS,
|
|
lpcwstrGroupName );
|
|
if (Count < 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, TEXT("File Name exceded MAX_PATH"));
|
|
SetLastError (ERROR_BUFFER_OVERFLOW);
|
|
return NULL;
|
|
}
|
|
|
|
hGroupkey = OpenRegistryKey( HKEY_LOCAL_MACHINE, wszSubKeyName, fNewKey, SamDesired );
|
|
if (NULL == hGroupkey)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create group key, OpenRegistryKey failed : %ld"),
|
|
GetLastError());
|
|
}
|
|
return hGroupkey;
|
|
|
|
} //OpenOutboundGroupKey
|
|
|
|
|
|
HKEY
|
|
OpenOutboundRuleKey (
|
|
DWORD dwCountryCode,
|
|
DWORD dwAreaCode,
|
|
BOOL fNewKey,
|
|
REGSAM SamDesired
|
|
)
|
|
/*++
|
|
|
|
Routine name : OpenOutboundRuleKey
|
|
|
|
Routine description:
|
|
|
|
Opens an outbound routing group key
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
dwCountryCode [in] - The outbound routing rule country code
|
|
dwAreaCode [in] - The outbound routing rule area code
|
|
fNewKey [in] - Flag that indicates to create a new key
|
|
SamDesired [in] - Desired access (See OpenRegistryKey)
|
|
|
|
Return Value:
|
|
|
|
Handle to the opened key. If this is NULL call GetLastError() for more info.
|
|
|
|
--*/
|
|
{
|
|
HKEY hRulekey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("OpenOutboundRuleKey"));
|
|
WCHAR wszSubKeyName[2*MAX_PATH] = {0};
|
|
int Count;
|
|
|
|
|
|
Count = _snwprintf ( wszSubKeyName,
|
|
ARR_SIZE(wszSubKeyName) - 1,
|
|
TEXT("%s\\%ld:%ld"),
|
|
REGKEY_FAX_OUTBOUND_ROUTING_RULES,
|
|
dwCountryCode,
|
|
dwAreaCode );
|
|
|
|
if (Count < 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, TEXT("File Name exceded MAX_PATH"));
|
|
SetLastError (ERROR_BUFFER_OVERFLOW);
|
|
return NULL;
|
|
}
|
|
|
|
hRulekey = OpenRegistryKey( HKEY_LOCAL_MACHINE, wszSubKeyName, fNewKey, SamDesired );
|
|
if (NULL == hRulekey)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create rule key, OpenRegistryKey failed : %ld"),
|
|
GetLastError());
|
|
}
|
|
return hRulekey;
|
|
} // OpenOutboundRuleKey
|
|
|
|
|
|
|
|
DWORD
|
|
DeleteOutboundRuleKey (DWORD dwCountryCode, DWORD dwAreaCode)
|
|
/*++
|
|
|
|
Routine name : DeleteOutboundRuleKey
|
|
|
|
Routine description:
|
|
|
|
Deletes an existing outbound routing rule key
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
dwCountryCode [in ] - The rule's country code
|
|
dwAreaCode [in ] - The rule's area code
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
HKEY hRulekey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("DeleteOutboundRuleKey"));
|
|
WCHAR wszSubKeyName[MAX_PATH];
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
int iCount;
|
|
|
|
iCount = _snwprintf ( wszSubKeyName,
|
|
MAX_PATH - 1,
|
|
TEXT("%ld:%ld"),
|
|
dwCountryCode,
|
|
dwAreaCode );
|
|
|
|
if (iCount < 0)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, TEXT("File Name exceded MAX_PATH"));
|
|
return ERROR_BUFFER_OVERFLOW;
|
|
}
|
|
|
|
hRulekey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAX_OUTBOUND_ROUTING_RULES, FALSE, DELETE );
|
|
if (NULL == hRulekey)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open rule key, OpenRegistryKey failed : %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
|
|
dwRes = RegDeleteKey (hRulekey, wszSubKeyName);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegDeleteKey failed, error %ld"),
|
|
dwRes);
|
|
}
|
|
|
|
RegCloseKey (hRulekey);
|
|
return dwRes;
|
|
|
|
} // DeleteOutboundRuleKey
|
|
|
|
|
|
|
|
|
|
DWORD
|
|
AddNewProviderToRegistry (
|
|
LPCWSTR lpctstrGUID,
|
|
LPCWSTR lpctstrFriendlyName,
|
|
LPCWSTR lpctstrImageName,
|
|
LPCWSTR lpctstrTspName,
|
|
DWORD dwFSPIVersion
|
|
)
|
|
/*++
|
|
|
|
Routine name : AddNewProviderToRegistry
|
|
|
|
Routine description:
|
|
|
|
Adds a new FSP entry to the registry
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpctstrGUID [in] - GUID of FSP
|
|
lpctstrFriendlyName [in] - Friendly name of FSP
|
|
lpctstrImageName [in] - Image name of FSP. May contain environment variables
|
|
lpctstrTspName [in] - TSP name of FSP.
|
|
dwFSPIVersion [in] - FSP's API version.
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
HKEY hKey = NULL;
|
|
HKEY hProviderKey = NULL;
|
|
DWORD dwRes;
|
|
DWORD dw;
|
|
DEBUG_FUNCTION_NAME(TEXT("AddNewProviderToRegistry"));
|
|
|
|
//
|
|
// Open providers key
|
|
//
|
|
dwRes = RegOpenKeyEx (HKEY_LOCAL_MACHINE, REGKEY_DEVICE_PROVIDER_KEY, 0, KEY_WRITE, &hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error opening providers key (ec = %ld)"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
//
|
|
// Create key for provider
|
|
//
|
|
dwRes = RegCreateKey (hKey, lpctstrGUID, &hProviderKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error creating provider key (%s) (ec = %ld)"),
|
|
lpctstrFriendlyName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
//
|
|
// Write provider's data into the key
|
|
//
|
|
if (!SetRegistryString (hProviderKey, REGVAL_FRIENDLY_NAME, lpctstrFriendlyName))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error writing string value (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryStringExpand (hProviderKey, REGVAL_IMAGE_NAME, lpctstrImageName))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error writing auto-expand string value (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString (hProviderKey, REGVAL_PROVIDER_NAME, lpctstrTspName))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error writing string value (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryString (hProviderKey, REGVAL_PROVIDER_GUID, lpctstrGUID))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error writing string value (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (!SetRegistryDword (hProviderKey, REGVAL_PROVIDER_API_VERSION, dwFSPIVersion))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error writing DWORD value (ec = %ld)"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Provider %s successfuly added."),
|
|
lpctstrFriendlyName);
|
|
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
|
|
if (ERROR_SUCCESS != dwRes && hKey)
|
|
{
|
|
//
|
|
// Try to remove half-cooked key
|
|
//
|
|
dw = RegDeleteKey (hKey, lpctstrGUID);
|
|
if (ERROR_SUCCESS != dw)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error deleting provider's key (ec = %ld)"),
|
|
dw);
|
|
}
|
|
}
|
|
if (hKey)
|
|
{
|
|
dw = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dw)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error closing providers key (ec = %ld)"),
|
|
dw);
|
|
}
|
|
}
|
|
if (hProviderKey)
|
|
{
|
|
dw = RegCloseKey (hProviderKey);
|
|
if (ERROR_SUCCESS != dw)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error closing provider's key (ec = %ld)"),
|
|
dw);
|
|
}
|
|
}
|
|
return dwRes;
|
|
} // AddNewProviderToRegistry
|
|
|
|
DWORD
|
|
RemoveProviderFromRegistry (
|
|
LPCWSTR lpctstrGUID
|
|
)
|
|
/*++
|
|
|
|
Routine name : RemoveProviderFromRegistry
|
|
|
|
Routine description:
|
|
|
|
Removes an existing FSP entry from the registry
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpctstrGUID [in] - GUID of FSP
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
HKEY hKey = NULL;
|
|
DWORD dwRes;
|
|
DWORD dw;
|
|
DEBUG_FUNCTION_NAME(TEXT("RemoveProviderFromRegistry"));
|
|
|
|
dwRes = RegOpenKeyEx (HKEY_LOCAL_MACHINE, REGKEY_DEVICE_PROVIDER_KEY,0, DELETE, &hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error opening providers key (ec = %ld)"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
dwRes = RegDeleteKey (hKey, lpctstrGUID);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error deleting provider key ( %s ) (ec = %ld)"),
|
|
lpctstrGUID,
|
|
dwRes);
|
|
}
|
|
dw = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dw)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error closing providers key (ec = %ld)"),
|
|
dw);
|
|
}
|
|
return dwRes;
|
|
} // RemoveProviderFromRegistry
|
|
|
|
DWORD
|
|
WriteManualAnswerDeviceId (
|
|
DWORD dwDeviceId
|
|
)
|
|
/*++
|
|
|
|
Routine name : WriteManualAnswerDeviceId
|
|
|
|
Routine description:
|
|
|
|
Write the manual-answer device id to the registry
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 2000
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId [in] - Device id (0 = None)
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
HKEY hKey = NULL;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("WriteManualAnswerDeviceId"));
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_WRITE );
|
|
if (!hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error opening server key (ec = %ld)"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
if (!SetRegistryDword (hKey, REGVAL_MANUAL_ANSWER_DEVICE, dwDeviceId))
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error setting registry value (ec = %ld)"),
|
|
dwRes);
|
|
}
|
|
dwRes = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error closing providers key (ec = %ld)"),
|
|
dwRes);
|
|
}
|
|
return dwRes;
|
|
} // WriteManualAnswerDeviceId
|
|
|
|
DWORD
|
|
ReadManualAnswerDeviceId (
|
|
LPDWORD lpdwDeviceId
|
|
)
|
|
/*++
|
|
|
|
Routine name : ReadManualAnswerDeviceId
|
|
|
|
Routine description:
|
|
|
|
Read the manual-answer device id from the registry
|
|
|
|
Author:
|
|
|
|
Eran Yariv (EranY), Dec, 2000
|
|
|
|
Arguments:
|
|
|
|
lpdwDeviceId [out] - Device id (0 = None)
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
HKEY hKey = NULL;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("ReadManualAnswerDeviceId"));
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_SOFTWARE, FALSE, KEY_READ );
|
|
if (!hKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error opening server key (ec = %ld)"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
*lpdwDeviceId = GetRegistryDword (hKey, REGVAL_MANUAL_ANSWER_DEVICE);
|
|
dwRes = RegCloseKey (hKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error closing providers key (ec = %ld)"),
|
|
dwRes);
|
|
}
|
|
return dwRes;
|
|
} // ReadManualAnswerDeviceId
|
|
|
|
|
|
DWORD
|
|
FaxCopyRegSubkeys(
|
|
LPCTSTR strDestSubKeyName,
|
|
HKEY hKeySrcHive,
|
|
LPCTSTR strSrcSubKeyName
|
|
)
|
|
/*++
|
|
|
|
Routine name : FaxCopyRegSubkeys
|
|
|
|
|
|
Routine description:
|
|
|
|
Copy a content of one registry key into another
|
|
using shell function SHCopyKey
|
|
|
|
Caller must supply the source key handle *AND* a subkey whose subkeys and values are to be copied
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Mar, 2002
|
|
|
|
Arguments:
|
|
|
|
strDestSubKeyName [in] - Destination registry key name
|
|
strSrcSubKeyName [in] - Source registry key name
|
|
hKeySrcHive [in] - Handle to the source key (for example, HKEY_LOCAL_MACHINE).
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS - on succesful move
|
|
|
|
win32 error code on failure
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
HKEY hKeyDest = NULL;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("FaxCopyRegSubkeys"));
|
|
|
|
//
|
|
// Create destination Key
|
|
//
|
|
hKeyDest = OpenRegistryKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
strDestSubKeyName,
|
|
TRUE, // create
|
|
KEY_WRITE);
|
|
if (!hKeyDest)
|
|
{
|
|
dwRet = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey failed [%lu], Can't copy keys."),
|
|
dwRet
|
|
);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// copy subkeys recursively
|
|
//
|
|
dwRet = SHCopyKey(
|
|
hKeySrcHive,
|
|
strSrcSubKeyName,
|
|
hKeyDest,
|
|
0);
|
|
if ( ERROR_SUCCESS != dwRet )
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SHCopyKey failed with [%ld]"),
|
|
dwRet);
|
|
goto exit;
|
|
}
|
|
|
|
Assert(ERROR_SUCCESS == dwRet);
|
|
|
|
exit:
|
|
|
|
if (NULL != hKeyDest)
|
|
{
|
|
if(ERROR_SUCCESS != RegCloseKey(hKeyDest))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("RegCloseKey failed (ec=%iu)"),
|
|
GetLastError());
|
|
}
|
|
}
|
|
|
|
return dwRet;
|
|
} // FaxCopyRegSubkeys
|
|
|
|
/*++
|
|
|
|
Routine name : MoveDeviceRegIntoDeviceCache
|
|
|
|
|
|
Routine description:
|
|
|
|
Move device's service and TAPI data into device cache
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Apr, 2001
|
|
|
|
Arguments:
|
|
|
|
dwServerPermanentID [in] - service device ID
|
|
dwTapiPermanentLineID [in] - tapi devive ID
|
|
fManualAnswer [in] - TRUE if the device was set to manual answer
|
|
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS - on succesful move
|
|
|
|
win32 error code on failure
|
|
|
|
--*/
|
|
DWORD
|
|
MoveDeviceRegIntoDeviceCache(
|
|
DWORD dwServerPermanentID,
|
|
DWORD dwTapiPermanentLineID,
|
|
BOOL fManualAnswer
|
|
)
|
|
{
|
|
DWORD ec = ERROR_SUCCESS; // LastError for this function.
|
|
HKEY hKey = NULL;
|
|
TCHAR strSrcSubKeyName [MAX_PATH];
|
|
TCHAR strDestSubKeyName[MAX_PATH];
|
|
|
|
DWORDLONG dwlTimeNow;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("MoveDeviceRegIntoDeviceCache"));
|
|
|
|
//
|
|
// open/create - "fax\Device Cache\GUID" Registry Key
|
|
// and create new key for the device using the dwTapiPermanentLineID as a key
|
|
// server data is stored under service GUID
|
|
//
|
|
_stprintf( strDestSubKeyName, TEXT("%s\\%08lx\\%s"), REGKEY_FAX_DEVICES_CACHE, dwTapiPermanentLineID, REGKEY_FAXSVC_DEVICE_GUID );
|
|
|
|
//
|
|
// open - "fax\Devices" Registry Key
|
|
//
|
|
_stprintf( strSrcSubKeyName, TEXT("%s\\%010lu\\%s"), REGKEY_FAX_DEVICES, dwServerPermanentID, REGKEY_FAXSVC_DEVICE_GUID );
|
|
|
|
ec = FaxCopyRegSubkeys(strDestSubKeyName,HKEY_LOCAL_MACHINE,strSrcSubKeyName);
|
|
if ( ERROR_SUCCESS != ec )
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("FaxCopyRegSubkeys of service data failed with [%ld] for tapi ID [%lu]. abort movement"),
|
|
ec,
|
|
dwTapiPermanentLineID
|
|
);
|
|
return ec;
|
|
}
|
|
|
|
//
|
|
// If the device was a manual answer device, set it in the registry
|
|
// open - "fax\Device Cache\dwTapiPermanentLineID" Registry Key
|
|
//
|
|
_stprintf( strDestSubKeyName, TEXT("%s\\%08lx"), REGKEY_FAX_DEVICES_CACHE, dwTapiPermanentLineID);
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, strDestSubKeyName, FALSE, KEY_WRITE );
|
|
if (hKey)
|
|
{
|
|
SetRegistryDword( hKey, REGVAL_MANUAL_ANSWER, fManualAnswer );
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
TEXT("OpenRegistryKey failed with [%lu] for [%s]."),
|
|
GetLastError(),
|
|
strDestSubKeyName);
|
|
}
|
|
|
|
ec = DeleteDeviceEntry(dwServerPermanentID);
|
|
if ( ERROR_SUCCESS != ec )
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("DeleteDeviceEntry of service data failed with [%ld] for tapi ID [%lu]. continue movement"),
|
|
ec,
|
|
dwTapiPermanentLineID
|
|
);
|
|
}
|
|
|
|
//
|
|
// open/create - "fax\Device Cache\TAPI Data" Registry Key
|
|
// and create new key for the device using the dwTapiPermanentLineID as a key
|
|
//
|
|
_stprintf( strDestSubKeyName, TEXT("%s\\%08lx\\%s"), REGKEY_FAX_DEVICES_CACHE, dwTapiPermanentLineID, REGKEY_TAPI_DATA );
|
|
|
|
//
|
|
// open - "fax\TAPIDevices" Registry Key
|
|
//
|
|
_stprintf( strSrcSubKeyName, TEXT("%s\\%08lx"), REGKEY_TAPIDEVICES, dwTapiPermanentLineID );
|
|
|
|
ec = FaxCopyRegSubkeys(strDestSubKeyName,HKEY_LOCAL_MACHINE,strSrcSubKeyName);
|
|
if ( ERROR_SUCCESS != ec )
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("FaxCopyRegSubkeys of TAPI data failed with [%ld] for tapi ID [%lu]."),
|
|
ec,
|
|
dwTapiPermanentLineID
|
|
);
|
|
}
|
|
|
|
|
|
ec = DeleteTapiEntry(dwTapiPermanentLineID);
|
|
|
|
if ( ERROR_SUCCESS != ec )
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("DeleteTapiEntry of service data failed with [%ld] for tapi ID [%lu]."),
|
|
ec,
|
|
dwTapiPermanentLineID
|
|
);
|
|
}
|
|
|
|
//
|
|
// Mark cache entry creation time
|
|
//
|
|
GetSystemTimeAsFileTime((FILETIME *)&dwlTimeNow);
|
|
|
|
if ( FALSE == UpdateLastDetectedTime(dwTapiPermanentLineID,dwlTimeNow) )
|
|
{
|
|
// the entry will be delete in the next service startup
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("UpdateLastDetectedTime failed for device cache ID no. [%lu]."),
|
|
dwTapiPermanentLineID
|
|
);
|
|
}
|
|
|
|
// service device data has been moved
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine name : RestoreDeviceRegFromDeviceCache
|
|
|
|
|
|
Routine description:
|
|
|
|
restore a device data from device cache, into devices
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Apr, 2001
|
|
|
|
Arguments:
|
|
|
|
dwServerPermanentID [in] - service device ID
|
|
dwTapiPermanentLineID [in] - tapi devive ID
|
|
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS - on succesful move
|
|
|
|
win32 error code on failure
|
|
|
|
--*/
|
|
DWORD
|
|
RestoreDeviceRegFromDeviceCache(DWORD dwServerPermanentID,DWORD dwTapiPermanentLineID)
|
|
{
|
|
DWORD ec = ERROR_SUCCESS; // LastError for this function.
|
|
|
|
HKEY hKey = NULL;
|
|
HKEY hKeySrc = NULL;
|
|
TCHAR strSrcSubKeyName [MAX_PATH];
|
|
TCHAR strDestSubKeyName[MAX_PATH];
|
|
BOOL fFaxDevicesKeyCreated = FALSE;
|
|
DEBUG_FUNCTION_NAME(TEXT("RestoreDeviceRegFromDeviceCache"));
|
|
|
|
//
|
|
// Restore Service date
|
|
//
|
|
|
|
//
|
|
// "fax\Device Cache\dwTapiPermanentLineID\REGKEY_FAXSVC_DEVICE_GUID" Registry Key
|
|
//
|
|
_stprintf( strSrcSubKeyName, TEXT("%s\\%08lx\\%s"), REGKEY_FAX_DEVICES_CACHE, dwTapiPermanentLineID, REGKEY_FAXSVC_DEVICE_GUID );
|
|
|
|
//
|
|
// "fax\Devices\dwServerPermanentID\REGKEY_FAXSVC_DEVICE_GUID" Registry Key
|
|
//
|
|
_stprintf( strDestSubKeyName, TEXT("%s\\%010lu\\%s"), REGKEY_FAX_DEVICES, dwServerPermanentID, REGKEY_FAXSVC_DEVICE_GUID );
|
|
|
|
ec = FaxCopyRegSubkeys(strDestSubKeyName,HKEY_LOCAL_MACHINE,strSrcSubKeyName);
|
|
if ( ERROR_SUCCESS != ec )
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("FaxCopyRegSubkeys of service data failed with [%lu] for tapi ID [%lu]. abort movement"),
|
|
ec,
|
|
dwTapiPermanentLineID
|
|
);
|
|
goto Exit;
|
|
}
|
|
fFaxDevicesKeyCreated = TRUE;
|
|
|
|
//
|
|
// open - "fax\Devices\dwServerPermanentID" Registry Key
|
|
//
|
|
_stprintf( strSrcSubKeyName, TEXT("%s\\%010lu"), REGKEY_FAX_DEVICES, dwServerPermanentID);
|
|
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, strSrcSubKeyName, FALSE, KEY_WRITE);
|
|
if (!hKey)
|
|
{
|
|
ec = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey failed with [%lu] for [%s]. abort movement"),
|
|
ec,
|
|
strSrcSubKeyName
|
|
);
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
//
|
|
// store "Permanent Lineid" value
|
|
//
|
|
if ( FALSE == SetRegistryDword(hKey, REGVAL_PERMANENT_LINEID, dwServerPermanentID) )
|
|
{
|
|
ec = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SetRegistryDword failed for [%s]. abort movement"),
|
|
REGVAL_PERMANENT_LINEID
|
|
);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Restore TAPI data
|
|
//
|
|
|
|
//
|
|
// open - "fax\Device Cache\dwTapiPermanentLineID\TAPI Data" Registry Key
|
|
//
|
|
_stprintf( strSrcSubKeyName, TEXT("%s\\%08lx\\%s"), REGKEY_FAX_DEVICES_CACHE, dwTapiPermanentLineID, REGKEY_TAPI_DATA );
|
|
|
|
//
|
|
// open/create - "fax\TAPIDevices\dwTapiPermanentLineID" Registry Key
|
|
//
|
|
_stprintf( strDestSubKeyName, TEXT("%s\\%08lx"), REGKEY_TAPIDEVICES, dwTapiPermanentLineID );
|
|
|
|
//
|
|
// See if fax\Device Cache\dwTapiPermanentLineID\TAPI Data exists
|
|
//
|
|
hKeySrc = OpenRegistryKey( HKEY_LOCAL_MACHINE, strSrcSubKeyName, FALSE, KEY_READ );
|
|
if (!hKeySrc)
|
|
{
|
|
//
|
|
// This data does not have to be there
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("OpenRegistryKey failed with [%lu], Can't copy keys."),
|
|
GetLastError());
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// fax\Device Cache\dwTapiPermanentLineID\TAPI Data exists, try to copy data
|
|
//
|
|
RegCloseKey(hKeySrc);
|
|
ec = FaxCopyRegSubkeys(strDestSubKeyName,HKEY_LOCAL_MACHINE, strSrcSubKeyName);
|
|
if ( ERROR_SUCCESS != ec)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_WRN,
|
|
TEXT("FaxCopyRegSubkeys of TAPI data failed with [%lu] for tapi ID [%lu]."),
|
|
ec,
|
|
dwTapiPermanentLineID
|
|
);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == ec);
|
|
|
|
Exit:
|
|
if (NULL != hKey)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
if (ERROR_SUCCESS != ec &&
|
|
TRUE == fFaxDevicesKeyCreated)
|
|
{
|
|
//
|
|
// Delete the registry entry fax\Devices\dwServerPermanentID
|
|
//
|
|
DWORD dwRes = DeleteDeviceEntry(dwServerPermanentID);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("DeleteDeviceEntry failed with [%lu] for server ID [%lu]."),
|
|
dwRes,
|
|
dwServerPermanentID
|
|
);
|
|
}
|
|
}
|
|
DeleteCacheEntry(dwTapiPermanentLineID);
|
|
return ec;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine name : FindServiceDeviceByTapiPermanentLineID
|
|
|
|
Routine description:
|
|
|
|
Search for a device configuration in the registry with a given "Tapi Permanent Line ID"
|
|
and the device's name. and return it's service ID and REG_SETUP data
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Mar, 2001
|
|
|
|
Updated:
|
|
|
|
Apr, 2001 - Device cache re-implementation
|
|
|
|
|
|
Arguments:
|
|
|
|
dwTapiPermanentLineID [in] - Tapi Permanent Line ID to search
|
|
strDeviceName [in] - Device name
|
|
pRegSetup [out] - Parameter, for returning registry stored Csid, Tsid, Flags, Rings
|
|
pInputFaxReg [in] - Devices list (from GetFaxDevicesRegistry() )
|
|
|
|
|
|
Return Value:
|
|
|
|
Permanent Line ID (server's ID) or 0 if not found
|
|
|
|
--*/
|
|
DWORD
|
|
FindServiceDeviceByTapiPermanentLineID(
|
|
DWORD dwTapiPermanentLineID,
|
|
LPCTSTR strDeviceName,
|
|
PREG_SETUP pRegSetup,
|
|
const PREG_FAX_DEVICES pInputFaxReg
|
|
)
|
|
{
|
|
DWORD dwDevice;
|
|
DWORD dwServiceID = 0;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("FindServiceDeviceByTapiPermanentLineID"));
|
|
|
|
Assert( pRegSetup );
|
|
Assert( pInputFaxReg );
|
|
|
|
|
|
// iterate through all devices and try to find the device with the given TapiPermanentLineID and name
|
|
for ( dwDevice = 0 ; dwDevice < pInputFaxReg->DeviceCount ; ++dwDevice )
|
|
{
|
|
PREG_DEVICE pRegDevice = &(pInputFaxReg->Devices[dwDevice]);
|
|
|
|
if(!pRegDevice->bValidDevice)
|
|
{
|
|
// the device's registry record is not valid
|
|
continue;
|
|
}
|
|
|
|
// it's the same device if permanent Tapi line ID and the device name are equal.
|
|
if ( pRegDevice->TapiPermanentLineID == dwTapiPermanentLineID &&
|
|
(0 == _tcscmp(strDeviceName,pRegDevice->lptstrDeviceName)) )
|
|
{
|
|
// update REG_SETUP record with the registry values
|
|
LPTSTR strTemp = NULL;
|
|
if ( NULL != (strTemp = StringDup(pRegDevice->Csid) ) )
|
|
{
|
|
MemFree(pRegSetup->Csid);
|
|
pRegSetup->Csid = strTemp;
|
|
}
|
|
|
|
if ( NULL != (strTemp = StringDup(pRegDevice->Tsid) ) )
|
|
{
|
|
MemFree(pRegSetup->Tsid);
|
|
pRegSetup->Tsid = strTemp;
|
|
}
|
|
|
|
if ( NULL != (strTemp = StringDup(pRegDevice->lptstrDescription) ) )
|
|
{
|
|
MemFree(pRegSetup->lptstrDescription);
|
|
pRegSetup->lptstrDescription = strTemp;
|
|
}
|
|
|
|
pRegSetup->Flags = pRegDevice->Flags;
|
|
pRegSetup->Rings = pRegDevice->Rings;
|
|
|
|
|
|
dwServiceID = pRegDevice->PermanentLineId; // server's line ID (also the key of the device in the registry)
|
|
|
|
pRegDevice->DeviceInstalled = TRUE; // mark as installed, will be needed later for registry clean-up
|
|
|
|
break; // found it no need to continue
|
|
}
|
|
}
|
|
|
|
return dwServiceID;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine name : FindCacheEntryByTapiPermanentLineID
|
|
|
|
Routine description:
|
|
|
|
Search for a device configuration in the registry Device cache with a given "Tapi Permanent Line ID"
|
|
and the device's name.
|
|
|
|
Author:
|
|
|
|
Caliv Nir (t-nicali), Apr, 2001
|
|
|
|
|
|
Arguments:
|
|
|
|
dwTapiPermanentLineID [in] - Tapi Permanent Line ID to search
|
|
strDeviceName [in] - Device name
|
|
pRegSetup [out] - Parameter, for returning registry stored Csid, Tsid, Flags, Rings
|
|
lpdwLastUniqueLineId [in] - last unique Server device ID (from registry), for assigning the device with new ID
|
|
pfManualAnswer [out] - TRUE if the device was wet to manual answer when moved to the cache
|
|
|
|
Return Value:
|
|
|
|
Permanent Line ID (server's ID) or 0 if not found
|
|
|
|
--*/
|
|
DWORD
|
|
FindCacheEntryByTapiPermanentLineID(
|
|
DWORD dwTapiPermanentLineID,
|
|
LPCTSTR strDeviceName,
|
|
PREG_SETUP pRegSetup,
|
|
LPDWORD lpdwLastUniqueLineId,
|
|
BOOL* pfManualAnswer
|
|
)
|
|
{
|
|
DWORD dwNewServiceID = 0;
|
|
HKEY hKey = NULL;
|
|
TCHAR SubKeyName[MAX_PATH];
|
|
LPTSTR strDeviceNameFromCache=NULL;
|
|
BOOL fManualAnswer = FALSE;
|
|
DEBUG_FUNCTION_NAME(TEXT("FindCacheEntryByTapiPermanentLineID"));
|
|
|
|
//
|
|
// open - "fax\Device Cache\dwTapiPermanentLineID\REGKEY_FAXSVC_DEVICE_GUID" Registry Key
|
|
//
|
|
_stprintf( SubKeyName, TEXT("%s\\%08lx\\%s"), REGKEY_FAX_DEVICES_CACHE, dwTapiPermanentLineID, REGKEY_FAXSVC_DEVICE_GUID );
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, SubKeyName, FALSE, KEY_READ );
|
|
if (!hKey)
|
|
{
|
|
return dwNewServiceID;
|
|
}
|
|
|
|
//
|
|
// found the dwTapiPermanentLineID inside the cache now check the device's name
|
|
//
|
|
Assert(strDeviceName);
|
|
|
|
strDeviceNameFromCache=GetRegistryString(hKey,REGVAL_DEVICE_NAME,NULL);
|
|
if ( (NULL != strDeviceNameFromCache) &&
|
|
(0 == _tcscmp(strDeviceName,strDeviceNameFromCache)) )
|
|
{
|
|
//
|
|
// found the device entry in cache
|
|
//
|
|
if ( ERROR_SUCCESS != GetNewServiceDeviceID(lpdwLastUniqueLineId, &dwNewServiceID))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("GetNewServiceDeviceID failed and couldn't assign new Service ID")
|
|
);
|
|
dwNewServiceID = 0;
|
|
}
|
|
}
|
|
|
|
if (hKey)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
MemFree(strDeviceNameFromCache);
|
|
|
|
if ( dwNewServiceID )
|
|
{
|
|
//
|
|
// Chcek if the device was set to manual answer
|
|
// open - "fax\Device Cache\dwTapiPermanentLineID" Registry Key
|
|
//
|
|
_stprintf( SubKeyName, TEXT("%s\\%08lx"), REGKEY_FAX_DEVICES_CACHE, dwTapiPermanentLineID);
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, SubKeyName, FALSE, KEY_READ );
|
|
if (hKey)
|
|
{
|
|
fManualAnswer = GetRegistryDword( hKey, REGVAL_MANUAL_ANSWER );
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
|
*pfManualAnswer = fManualAnswer;
|
|
|
|
//
|
|
// move the cahce entry into devices
|
|
//
|
|
if ( ERROR_SUCCESS == RestoreDeviceRegFromDeviceCache(dwNewServiceID,dwTapiPermanentLineID) )
|
|
{
|
|
//
|
|
// update REG_SETUP record with the registry values
|
|
//
|
|
Assert( pRegSetup );
|
|
|
|
_stprintf( SubKeyName, TEXT("%s\\%010lu\\%s"), REGKEY_FAX_DEVICES, dwNewServiceID, REGKEY_FAXSVC_DEVICE_GUID );
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, SubKeyName, FALSE, KEY_READ );
|
|
|
|
if (!hKey) {
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey failed for [%s]. REG_SETUP was not updated."),
|
|
SubKeyName
|
|
);
|
|
|
|
//
|
|
// return the new service ID but REG_SETUP will contains it's default values
|
|
//
|
|
return dwNewServiceID;
|
|
}
|
|
|
|
|
|
LPTSTR strTemp = NULL;
|
|
|
|
if ( NULL != (strTemp = GetRegistryString( hKey, REGVAL_ROUTING_CSID, REGVAL_DEFAULT_CSID )) )
|
|
{
|
|
MemFree(pRegSetup->Csid);
|
|
pRegSetup->Csid = strTemp;
|
|
}
|
|
|
|
if ( NULL != (strTemp = GetRegistryString( hKey, REGVAL_ROUTING_TSID, REGVAL_DEFAULT_TSID )) )
|
|
{
|
|
MemFree(pRegSetup->Tsid);
|
|
pRegSetup->Tsid = strTemp;
|
|
}
|
|
|
|
if ( NULL != (strTemp = GetRegistryString( hKey, REGVAL_DEVICE_DESCRIPTION, EMPTY_STRING )) )
|
|
{
|
|
MemFree(pRegSetup->lptstrDescription);
|
|
pRegSetup->lptstrDescription = strTemp;
|
|
}
|
|
|
|
pRegSetup->Flags = GetRegistryDword( hKey, REGVAL_FLAGS );
|
|
pRegSetup->Rings = GetRegistryDword( hKey, REGVAL_RINGS );
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// couldn't restore the device cache entry
|
|
//
|
|
dwNewServiceID = 0;
|
|
}
|
|
|
|
}
|
|
|
|
return dwNewServiceID;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine name : GetNewServiceDeviceID
|
|
|
|
|
|
Routine description:
|
|
|
|
The routine search and return new Service device ID.
|
|
The routine also update this new ID in registry
|
|
|
|
ReImplemented By:
|
|
|
|
Caliv Nir (t-nicali), Apr, 2001
|
|
|
|
Arguments:
|
|
|
|
lpdwLastUniqueLineId [in/out] - last ID given to service device (from registry)
|
|
lpdwPermanentLineId [out] - on success will contain the new ID
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS - when ID was successfully assigned
|
|
|
|
on failue - win32 error code
|
|
|
|
--*/
|
|
DWORD
|
|
GetNewServiceDeviceID(
|
|
LPDWORD lpdwLastUniqueLineId,
|
|
LPDWORD lpdwPermanentLineId
|
|
)
|
|
{
|
|
//
|
|
// Create a new UniqueLineInd.
|
|
// A fax unique line id is always below the base of the FSP line ids.
|
|
//
|
|
DWORD dwUniqueDeviceIdsSpace = DEFAULT_REGVAL_PROVIDER_DEVICE_ID_PREFIX_BASE - DEFAULT_REGVAL_FAX_UNIQUE_DEVICE_ID_BASE;
|
|
DWORD bGeneratedId = FALSE;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
TCHAR SubKeyName[MAX_PATH];
|
|
HKEY hKey = NULL;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("GetNewServiceDeviceID"));
|
|
|
|
//
|
|
// Scan through all available space
|
|
//
|
|
if (*lpdwLastUniqueLineId < DEFAULT_REGVAL_FAX_UNIQUE_DEVICE_ID_BASE)
|
|
{
|
|
//
|
|
// Set to minimum. May happen only in first attempt.
|
|
//
|
|
*lpdwLastUniqueLineId = DEFAULT_REGVAL_FAX_UNIQUE_DEVICE_ID_BASE;
|
|
}
|
|
|
|
|
|
DWORD dwAttempt;
|
|
|
|
for (dwAttempt = 0; dwAttempt< dwUniqueDeviceIdsSpace; dwAttempt++)
|
|
{
|
|
(*lpdwLastUniqueLineId)++;
|
|
if (*lpdwLastUniqueLineId >= DEFAULT_REGVAL_PROVIDER_DEVICE_ID_PREFIX_BASE)
|
|
{
|
|
//
|
|
// Reached space height limit, loop back to lower limit.
|
|
//
|
|
*lpdwLastUniqueLineId = DEFAULT_REGVAL_FAX_UNIQUE_DEVICE_ID_BASE;
|
|
continue;
|
|
}
|
|
Assert(*lpdwLastUniqueLineId != 0);
|
|
Assert(*lpdwLastUniqueLineId < DEFAULT_REGVAL_PROVIDER_DEVICE_ID_PREFIX_BASE);
|
|
Assert(*lpdwLastUniqueLineId >= DEFAULT_REGVAL_FAX_UNIQUE_DEVICE_ID_BASE);
|
|
|
|
_stprintf( SubKeyName, TEXT("%s\\%010d"), REGKEY_FAX_DEVICES, *lpdwLastUniqueLineId );
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, SubKeyName, FALSE, KEY_READ );
|
|
if (!hKey)
|
|
{
|
|
bGeneratedId = TRUE;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
}
|
|
|
|
if (hKey)
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
if (!bGeneratedId)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to generate next uniqueu line id."));
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Persiste the new line id
|
|
//
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAXSERVER, TRUE, KEY_WRITE );
|
|
if (!hKey)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey Failed for %s while persisting new unique line id (%010d) (ec: %ld)"),
|
|
REGKEY_FAX_DEVICES,
|
|
*lpdwLastUniqueLineId,
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
if (!SetRegistryDword( hKey, REGVAL_LAST_UNIQUE_LINE_ID, *lpdwLastUniqueLineId))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SetRegistryDword to value [%s] failed while writing new unique line id (%010d) (ec: %ld)"),
|
|
REGVAL_LAST_UNIQUE_LINE_ID,
|
|
*lpdwLastUniqueLineId,
|
|
dwRes );
|
|
RegCloseKey (hKey);
|
|
return dwRes;
|
|
}
|
|
|
|
RegCloseKey (hKey);
|
|
|
|
*lpdwPermanentLineId = *lpdwLastUniqueLineId;
|
|
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Routine name : UpdateLastDetectedTime
|
|
|
|
|
|
Routine description:
|
|
|
|
Write creation time of a cache entry for a given TAPI line ID
|
|
|
|
ReImplemented By:
|
|
|
|
Caliv Nir (t-nicali), Apr, 2001
|
|
|
|
Arguments:
|
|
|
|
dwPermanentTapiLineID [in] - Permanent Tapi Line ID to update in cache
|
|
dwlTimeNow [in] - Current time in UTC
|
|
|
|
Return Value:
|
|
TRUE - on success update.
|
|
FALSE - on failure
|
|
|
|
--*/
|
|
BOOL
|
|
UpdateLastDetectedTime(
|
|
DWORD dwPermanentTapiLineID,
|
|
DWORDLONG dwlTimeNow
|
|
)
|
|
{
|
|
BOOL success = FALSE;
|
|
TCHAR SubKey[MAX_PATH];
|
|
HKEY hKey;
|
|
|
|
DEBUG_FUNCTION_NAME(TEXT("UpdateLastDetectedTime"));
|
|
|
|
_stprintf( SubKey, TEXT("%s\\%08lx"),
|
|
REGKEY_FAX_DEVICES_CACHE,
|
|
dwPermanentTapiLineID);
|
|
|
|
// open the device cache entry
|
|
hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, SubKey, FALSE, KEY_WRITE );
|
|
if(hKey)
|
|
{
|
|
// try to update the creation time
|
|
success = SetRegistryBinary(hKey, REGVAL_LAST_DETECTED_TIME, (BYTE *)&dwlTimeNow, sizeof(dwlTimeNow));
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|