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.
2546 lines
61 KiB
2546 lines
61 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
OutRoute.cpp
|
|
|
|
Abstract:
|
|
|
|
This file provides implementation of the service
|
|
outbound routing.
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS) Nov, 1999
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "faxsvc.h"
|
|
|
|
BOOL
|
|
EnumOutboundRoutingGroupsCB(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID pContext
|
|
);
|
|
|
|
|
|
inline
|
|
BOOL
|
|
IsDeviceInstalled (DWORD dwDeviceId)
|
|
{
|
|
// Make sure to lock g_CsLine
|
|
return (GetTapiLineFromDeviceId (dwDeviceId, FALSE)) ? TRUE : FALSE;
|
|
}
|
|
|
|
/************************************
|
|
* *
|
|
* Globals *
|
|
* *
|
|
************************************/
|
|
|
|
COutboundRoutingGroupsMap* g_pGroupsMap; // Map of group name to list of device IDs
|
|
|
|
|
|
/***********************************
|
|
* *
|
|
* COutboundRoutingGroup Methodes *
|
|
* *
|
|
***********************************/
|
|
DWORD
|
|
COutboundRoutingGroup::Load(HKEY hGroupKey, LPCWSTR lpcwstrGroupName)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::Load
|
|
|
|
Routine description:
|
|
|
|
Loads an outboundrouting group's settings from the registry
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hGroupKey [in] - Handle to the opened registry key
|
|
lpcwstrGroupName [in] - Group name
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
LPBYTE lpBuffer = NULL;
|
|
DWORD dwRes;
|
|
DWORD dwType;
|
|
DWORD dwSize=0;
|
|
DWORD i;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::Load"));
|
|
|
|
Assert (hGroupKey);
|
|
|
|
dwRes = RegQueryValueEx(
|
|
hGroupKey,
|
|
REGVAL_ROUTING_GROUP_DEVICES,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwSize
|
|
);
|
|
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegQueryValueEx failed with %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
if (REG_BINARY != dwType)
|
|
{
|
|
//
|
|
// We expect only binary data here
|
|
//
|
|
//
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Error reading devices list, not a binary type"));
|
|
dwRes = ERROR_BADDB; // The configuration registry database is corrupt.
|
|
goto exit;
|
|
}
|
|
|
|
if (0 != dwSize)
|
|
{
|
|
//
|
|
// Allocate required buffer
|
|
//
|
|
lpBuffer = (LPBYTE) MemAlloc( dwSize );
|
|
if (!lpBuffer)
|
|
{
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to allocate group devices buffer"));
|
|
goto exit;
|
|
}
|
|
//
|
|
// Read the data
|
|
//
|
|
dwRes = RegQueryValueEx(
|
|
hGroupKey,
|
|
REGVAL_ROUTING_GROUP_DEVICES,
|
|
NULL,
|
|
&dwType,
|
|
lpBuffer,
|
|
&dwSize
|
|
);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegQueryValueEx failed with %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
LPDWORD lpdwDevices = (LPDWORD)lpBuffer;
|
|
DWORD dwNumDevices = dwSize/sizeof(DWORD);
|
|
BOOL fDeviceInstalled = TRUE;
|
|
|
|
for (i = 0; i < dwNumDevices; i++)
|
|
{
|
|
if (IsDeviceInstalled(lpdwDevices[i]))
|
|
{
|
|
//
|
|
// Add the device only if it is installed
|
|
//
|
|
dwRes = AddDevice (lpdwDevices[i]);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::AddDevice failed with %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fDeviceInstalled = FALSE;
|
|
}
|
|
}
|
|
|
|
if (FALSE == fDeviceInstalled)
|
|
{
|
|
//
|
|
// Save the new configuration
|
|
//
|
|
DWORD ec = Save(hGroupKey);
|
|
if (ERROR_SUCCESS != ec)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::Save failed with %ld"),
|
|
ec);
|
|
}
|
|
|
|
FaxLog(
|
|
FAXLOG_CATEGORY_INIT,
|
|
FAXLOG_LEVEL_MED,
|
|
1,
|
|
MSG_BAD_OUTBOUND_ROUTING_GROUP_CONFIGURATION,
|
|
lpcwstrGroupName
|
|
);
|
|
}
|
|
}
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
MemFree (lpBuffer);
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::GetStatus (FAX_ENUM_GROUP_STATUS* lpStatus) const
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::GetStatus
|
|
|
|
Routine description:
|
|
|
|
Retrieves the group status. Caller must lock g_CsConfig
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpStatus [out] - Pointer to a FAX_ENUM_GROUP_STATUS to recieve the group status
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::GetStatus"));
|
|
DWORD dwNumDevices;
|
|
|
|
Assert (lpStatus);
|
|
|
|
try
|
|
{
|
|
if ((dwNumDevices = m_DeviceList.size()) == 0)
|
|
{
|
|
//
|
|
// Empty group
|
|
//
|
|
*lpStatus = FAX_GROUP_STATUS_EMPTY;
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We remove invalid devices from groups - All devices are valid.
|
|
//
|
|
*lpStatus = FAX_GROUP_STATUS_ALL_DEV_VALID;
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
return ERROR_GEN_FAILURE;
|
|
}
|
|
} // GetStatus
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::Save(HKEY hGroupKey) const
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::Save
|
|
|
|
Routine description:
|
|
|
|
Saves an outbound routing group to the registry
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hGroupKey [in] - Handle to the opened group registry key
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::Save"));
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
LPDWORD lpdwDevices = NULL;
|
|
DWORD dwNumDevices = 0;
|
|
|
|
Assert (hGroupKey);
|
|
|
|
dwRes = SerializeDevices (&lpdwDevices, &dwNumDevices);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::EnumDevices failed , ec %ld"), dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (!SetRegistryBinary( hGroupKey,
|
|
REGVAL_ROUTING_GROUP_DEVICES,
|
|
(LPBYTE) lpdwDevices,
|
|
dwNumDevices * sizeof(DWORD)))
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("SetRegistryBinary failed , ec %ld"), dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (dwRes == ERROR_SUCCESS);
|
|
|
|
exit:
|
|
MemFree (lpdwDevices);
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::SerializeDevices (LPDWORD* lppDevices, LPDWORD lpdwNumDevices, BOOL bAllocate) const
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::SerializeDevices
|
|
|
|
Routine description:
|
|
|
|
Serializes all group devices to an array. The caller must call MemFree to deallocate memory if bAllocate is TRUE.
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lppDevices [out] - Pointer to recieve the pointer to the allocated devices buffer.
|
|
If this parameter is NULL, lpdwNumDevices will return the numner of devices in the list.
|
|
lpdwNumDevices [out] - Pointer to a DWORD to recieve the number of devices in the buffer
|
|
bAllocate [in] - Flag to indicate if the function should allocate the memory.
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::SerializeDevices"));
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
GROUP_DEVICES::iterator it;
|
|
DWORD dwCount = 0;
|
|
|
|
Assert (lpdwNumDevices);
|
|
|
|
if (NULL == lppDevices )
|
|
{
|
|
try
|
|
{
|
|
*lpdwNumDevices = m_DeviceList.size();
|
|
return ERROR_SUCCESS;
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
return ERROR_GEN_FAILURE;
|
|
}
|
|
}
|
|
|
|
if (bAllocate == TRUE)
|
|
{
|
|
*lppDevices = NULL;
|
|
}
|
|
|
|
try
|
|
{
|
|
dwCount = m_DeviceList.size();
|
|
if (0 == dwCount)
|
|
{
|
|
*lppDevices = NULL;
|
|
*lpdwNumDevices = 0;
|
|
return dwRes;
|
|
}
|
|
|
|
if (TRUE == bAllocate)
|
|
{
|
|
*lppDevices = (LPDWORD) MemAlloc(dwCount * sizeof(DWORD));
|
|
if (*lppDevices == NULL)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Cannot allocate devices buffer"));
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
dwCount = 0;
|
|
for (it = m_DeviceList.begin(); it != m_DeviceList.end(); it++)
|
|
{
|
|
(*lppDevices)[dwCount++] = *it;
|
|
}
|
|
|
|
if (0 == dwCount)
|
|
{
|
|
*lppDevices = NULL;
|
|
}
|
|
*lpdwNumDevices = dwCount;
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
dwRes = ERROR_GEN_FAILURE;
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
if (bAllocate == TRUE)
|
|
{
|
|
MemFree (*lppDevices);
|
|
}
|
|
*lppDevices = NULL;
|
|
*lpdwNumDevices = 0;
|
|
}
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
BOOL
|
|
COutboundRoutingGroup::IsDeviceInGroup (DWORD dwDevice) const
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::IsDeviceInGroup
|
|
|
|
Routine description:
|
|
|
|
Check if device is in the group
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDevice [in] - Permanent device ID
|
|
|
|
Return Value:
|
|
|
|
BOOL. If the function fails, Call GetLastError for detailed info.
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::IsDeviceInGroup"));
|
|
GROUP_DEVICES::iterator location;
|
|
BOOL bFound = FALSE;
|
|
|
|
Assert (dwDevice);
|
|
|
|
try
|
|
{
|
|
location = find(m_DeviceList.begin(), m_DeviceList.end(), dwDevice);
|
|
if (location != m_DeviceList.end())
|
|
{
|
|
bFound = TRUE;
|
|
}
|
|
SetLastError (ERROR_SUCCESS);
|
|
return bFound;
|
|
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
SetLastError (ERROR_GEN_FAILURE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::AddDevice (DWORD dwDevice)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::AddDevice
|
|
|
|
Routine description:
|
|
|
|
Adds a new device to group
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDevice [in ] - Permanent device ID
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::AddDevice"));
|
|
GROUP_DEVICES::iterator it;
|
|
DWORD dwRes;
|
|
|
|
Assert (dwDevice);
|
|
|
|
if (IsDeviceInGroup(dwDevice))
|
|
{
|
|
return ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
dwRes = GetLastError();
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::IsDeviceInList failed, error %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Device not in list - Add it
|
|
//
|
|
try
|
|
{
|
|
if (!IsDeviceInstalled(dwDevice))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Device id: %ld is not installed."),
|
|
dwDevice);
|
|
return ERROR_BAD_UNIT;
|
|
}
|
|
m_DeviceList.push_back (dwDevice);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
return ERROR_GEN_FAILURE;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::DelDevice (DWORD dwDevice)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::DelDevice
|
|
|
|
Routine description:
|
|
|
|
Deletes a device from the group
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDevice [in ] - Permanent device ID
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::DelDevice"));
|
|
GROUP_DEVICES::iterator location;
|
|
BOOL bFound = FALSE;
|
|
|
|
Assert (dwDevice);
|
|
|
|
try
|
|
{
|
|
location = find(m_DeviceList.begin(), m_DeviceList.end(), dwDevice);
|
|
if (location == m_DeviceList.end())
|
|
{
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
m_DeviceList.erase (location);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
return ERROR_GEN_FAILURE;
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::SetDevices (LPDWORD lpdwDevices, DWORD dwNumDevices, BOOL fAllDevicesGroup)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::SetDevices
|
|
|
|
Routine description:
|
|
|
|
Sets a new device list to the group
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpdwDevices [in] - Pointer to a list of devices
|
|
dwNumDevices [in] - Number of devices in the list
|
|
fAllDevicesGroup [in] - TRUE if <All Devices> group.
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::SetDevices"));
|
|
|
|
dwRes = ValidateDevices( lpdwDevices, dwNumDevices, fAllDevicesGroup);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::ValidateDevices failed , ec %ld"), dwRes);
|
|
return dwRes;
|
|
}
|
|
|
|
try
|
|
{
|
|
m_DeviceList.erase (m_DeviceList.begin(), m_DeviceList.end());
|
|
|
|
for (DWORD i = 0; i < dwNumDevices; i++)
|
|
{
|
|
m_DeviceList.push_back (lpdwDevices[i]);
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
dwRes = ERROR_GEN_FAILURE;
|
|
}
|
|
|
|
return dwRes;
|
|
}
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::ValidateDevices (const LPDWORD lpdwDevices, DWORD dwNumDevices, BOOL fAllDevicesGroup) const
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::ValidateDevices
|
|
|
|
Routine description:
|
|
|
|
Validates a list of devices (No duplicates, All devices installed)
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpdwDevices [in ] - Pointer to alist of devices
|
|
dwNumDevices [in ] - Number of devices in the list
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
set<DWORD> ValidationSet;
|
|
pair < set<DWORD>::iterator, bool> p;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::ValidateDevices"));
|
|
|
|
try
|
|
{
|
|
if (TRUE == fAllDevicesGroup)
|
|
{
|
|
//
|
|
// <All Devices> group - validate that we do not miss or add a device.
|
|
//
|
|
if (m_DeviceList.size() != dwNumDevices)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("<All Devices> group contains diffrent number of devices, (old group - %ld, new group - %ld)"),
|
|
m_DeviceList.size(),
|
|
dwNumDevices);
|
|
return FAX_ERR_BAD_GROUP_CONFIGURATION;
|
|
}
|
|
}
|
|
|
|
for (DWORD i = 0; i < dwNumDevices; i++)
|
|
{
|
|
p = ValidationSet.insert(lpdwDevices[i]);
|
|
if (p.second == FALSE)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Duplicate device IDs, ID = %ld"),
|
|
lpdwDevices[i]);
|
|
return FAX_ERR_BAD_GROUP_CONFIGURATION;
|
|
}
|
|
|
|
|
|
if (!IsDeviceInstalled (lpdwDevices[i]))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Device ID %ld, is not installed"),
|
|
lpdwDevices[i]);
|
|
return ERROR_BAD_UNIT;
|
|
}
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("set caused exception (%S)"),
|
|
ex.what());
|
|
return ERROR_GEN_FAILURE;
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
#if DBG
|
|
void COutboundRoutingGroup::Dump () const
|
|
{
|
|
GROUP_DEVICES::iterator it;
|
|
WCHAR Buffer[128] = {0};
|
|
DWORD dwBufferSize = sizeof (Buffer)/ sizeof (Buffer[0]);
|
|
|
|
for (it = m_DeviceList.begin(); it != m_DeviceList.end(); it++)
|
|
{
|
|
_snwprintf (Buffer, dwBufferSize - 1, TEXT("\tDevice ID = %ld \n"), *it);
|
|
OutputDebugString (Buffer);
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroup::SetDeviceOrder (DWORD dwDevice, DWORD dwOrder)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroup::SetDeviceOrder
|
|
|
|
Routine description:
|
|
|
|
Sest the order of a single device in a group of outbound routing devices.
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
dwDevice [in] - The device ID to be set
|
|
dwOrder [in] - The device new order
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroup::SetDeviceOrder"));
|
|
GROUP_DEVICES::iterator it;
|
|
DWORD i = 1;
|
|
|
|
Assert (dwDevice);
|
|
|
|
try
|
|
{
|
|
// Check if dwOrder is bigger than number of devices in the list
|
|
if (dwOrder > m_DeviceList.size())
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Device ID %ld, is not found in group"),
|
|
dwDevice);
|
|
return FAX_ERR_BAD_GROUP_CONFIGURATION;
|
|
}
|
|
|
|
it = find(m_DeviceList.begin(), m_DeviceList.end(), dwDevice);
|
|
if (it == m_DeviceList.end())
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Device ID %ld, is not found in group"),
|
|
dwDevice);
|
|
return FAX_ERR_BAD_GROUP_CONFIGURATION;
|
|
}
|
|
|
|
m_DeviceList.erase (it);
|
|
|
|
for (i = 1, it = m_DeviceList.begin(); i < dwOrder; i++, it++)
|
|
{
|
|
;
|
|
}
|
|
|
|
m_DeviceList.insert (it, dwDevice);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("list caused exception (%S)"),
|
|
ex.what());
|
|
return ERROR_GEN_FAILURE;
|
|
}
|
|
|
|
}
|
|
|
|
/****************************************
|
|
* *
|
|
* COutboundRoutingGroupsMap Methodes *
|
|
* *
|
|
****************************************/
|
|
|
|
DWORD
|
|
COutboundRoutingGroupsMap::Load ()
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroupsMap::Load
|
|
|
|
Routine description:
|
|
|
|
Loads all outbound routing groups from the registry
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::Load"));
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hGroupskey = NULL;
|
|
DWORD dwCount = 0;
|
|
|
|
hGroupskey = OpenRegistryKey( HKEY_LOCAL_MACHINE,
|
|
REGKEY_FAX_OUTBOUND_ROUTING,
|
|
FALSE,
|
|
KEY_READ | KEY_WRITE );
|
|
if (NULL == hGroupskey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey, error %ld"),
|
|
dwRes);
|
|
return dwRes;
|
|
}
|
|
|
|
dwCount = EnumerateRegistryKeys( hGroupskey,
|
|
REGKEY_OUTBOUND_ROUTING_GROUPS,
|
|
TRUE, // We might want to change values
|
|
EnumOutboundRoutingGroupsCB,
|
|
&dwRes
|
|
);
|
|
|
|
if (dwRes != ERROR_SUCCESS)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("EnumerateRegistryKeys failed, error %ld"),
|
|
dwRes);
|
|
}
|
|
|
|
RegCloseKey (hGroupskey);
|
|
return dwRes;
|
|
}
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroupsMap::AddGroup (LPCWSTR lpcwstrGroupName, PCGROUP pCGroup)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroupsMap::AddGroup
|
|
|
|
Routine description:
|
|
|
|
Add a new group to the global groups map
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpcwstrGroupName [ ] - Group name
|
|
pCGroup [ ] - Pointer to a group object
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
--*/
|
|
{
|
|
GROUPS_MAP::iterator it;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::AddGroup"));
|
|
pair <GROUPS_MAP::iterator, bool> p;
|
|
|
|
Assert (pCGroup && lpcwstrGroupName);
|
|
|
|
try
|
|
{
|
|
wstring wstrGroupName(lpcwstrGroupName);
|
|
|
|
//
|
|
// Add new map entry
|
|
//
|
|
p = m_GroupsMap.insert (GROUPS_MAP::value_type(wstrGroupName, *pCGroup));
|
|
|
|
//
|
|
// See if entry exists in map
|
|
//
|
|
if (p.second == FALSE)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Group %S is allready in the group map"), lpcwstrGroupName);
|
|
dwRes = ERROR_DUP_NAME;
|
|
goto exit;
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("map or wstring caused exception (%S)"),
|
|
ex.what());
|
|
dwRes = ERROR_GEN_FAILURE;
|
|
}
|
|
|
|
exit:
|
|
return dwRes;
|
|
|
|
}
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroupsMap::DelGroup (LPCWSTR lpcwstrGroupName)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroupsMap::DelGroup
|
|
|
|
Routine description:
|
|
|
|
Deletes a group from the global groups map
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpcwstrGroupName [ ] - The group name
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
GROUPS_MAP::iterator it;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::DelGroup"));
|
|
|
|
try
|
|
{
|
|
wstring wstrGroupName(lpcwstrGroupName);
|
|
|
|
//
|
|
// See if entry exists in map
|
|
//
|
|
if((it = m_GroupsMap.find(wstrGroupName)) == m_GroupsMap.end())
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Group %S not is not in the group map"), lpcwstrGroupName);
|
|
dwRes = FAX_ERR_GROUP_NOT_FOUND;
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Delete the map entry
|
|
//
|
|
m_GroupsMap.erase (it);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("map or wstring caused exception (%S)"),
|
|
ex.what());
|
|
dwRes = ERROR_GEN_FAILURE;
|
|
goto exit;
|
|
}
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
return dwRes;
|
|
}
|
|
|
|
PCGROUP
|
|
COutboundRoutingGroupsMap::FindGroup ( LPCWSTR lpcwstrGroupName ) const
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroupsMap::FindGroup
|
|
|
|
Routine description:
|
|
|
|
Returns a pointer to a group object specified by its name
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
lpcwstrGroupName [in ] - The group name
|
|
|
|
Return Value:
|
|
|
|
Pointer to the found group object. If it is null the group was not found
|
|
|
|
--*/
|
|
{
|
|
GROUPS_MAP::iterator it;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::FindGroup"));
|
|
|
|
try
|
|
{
|
|
wstring wstrGroupName(lpcwstrGroupName);
|
|
|
|
//
|
|
// See if entry exists in map
|
|
//
|
|
if((it = m_GroupsMap.find(wstrGroupName)) == m_GroupsMap.end())
|
|
{
|
|
SetLastError (FAX_ERR_GROUP_NOT_FOUND);
|
|
return NULL;
|
|
}
|
|
return &((*it).second);
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("map or wstring caused exception (%S)"),
|
|
ex.what());
|
|
SetLastError (ERROR_GEN_FAILURE);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
void COutboundRoutingGroupsMap::Dump () const
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::Dump"));
|
|
GROUPS_MAP::iterator it;
|
|
WCHAR Buffer [512] = {0};
|
|
DWORD dwBufferSize = sizeof (Buffer)/ sizeof (Buffer[0]);
|
|
|
|
try
|
|
{ _snwprintf (Buffer, dwBufferSize - 1, TEXT("DUMP - Outbound routing groups\n"));
|
|
OutputDebugString (Buffer);
|
|
|
|
for (it = m_GroupsMap.begin(); it != m_GroupsMap.end(); it++)
|
|
{
|
|
_snwprintf (Buffer, dwBufferSize - 1, TEXT("Group Name - %s\n"), ((*it).first).c_str());
|
|
OutputDebugString (Buffer);
|
|
((*it).second).Dump();
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("map or wstring caused exception (%S)"),
|
|
ex.what());
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroupsMap::SerializeGroups (
|
|
PFAX_OUTBOUND_ROUTING_GROUPW* ppGroups,
|
|
LPDWORD lpdwNumGroups,
|
|
LPDWORD lpdwBufferSize) const
|
|
{
|
|
GROUPS_MAP::iterator it;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::SerializeGroups"));
|
|
DWORD dwSize = 0;
|
|
DWORD dwNumDevices;
|
|
DWORD dwCount = 0;
|
|
LPCWSTR lpcwstrGroupName;
|
|
PCGROUP pCGroup;
|
|
|
|
Assert (ppGroups && lpdwNumGroups && lpdwBufferSize);
|
|
|
|
*ppGroups = NULL;
|
|
*lpdwNumGroups = 0;
|
|
|
|
try
|
|
{
|
|
// Calculate buffer size
|
|
for (it = m_GroupsMap.begin(); it != m_GroupsMap.end(); it++)
|
|
{
|
|
lpcwstrGroupName = ((*it).first).c_str();
|
|
pCGroup = &((*it).second);
|
|
|
|
dwSize += sizeof (FAX_OUTBOUND_ROUTING_GROUPW);
|
|
dwSize += StringSizeW(lpcwstrGroupName);
|
|
dwRes = pCGroup->SerializeDevices(NULL, &dwNumDevices);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::SerializeDevices failed, error %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
dwSize += dwNumDevices * sizeof(DWORD);
|
|
dwCount ++;
|
|
}
|
|
|
|
// Allocate buffer
|
|
*ppGroups = (PFAX_OUTBOUND_ROUTING_GROUPW) MemAlloc (dwSize);
|
|
if (NULL == *ppGroups)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Cannot allocate groups buffer"));
|
|
dwRes = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
DWORD_PTR dwOffset = dwCount * sizeof (FAX_OUTBOUND_ROUTING_GROUPW);
|
|
dwCount = 0;
|
|
|
|
// Fill buffer with serialized info
|
|
for (it = m_GroupsMap.begin(); it != m_GroupsMap.end(); it++)
|
|
{
|
|
lpcwstrGroupName = ((*it).first).c_str();
|
|
pCGroup = &((*it).second);
|
|
LPDWORD lpdwDevices;
|
|
|
|
(*ppGroups)[dwCount].dwSizeOfStruct = sizeof (FAX_OUTBOUND_ROUTING_GROUPW);
|
|
dwRes = pCGroup->GetStatus(&(*ppGroups)[dwCount].Status);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::GetStatus failed, error %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
StoreString (lpcwstrGroupName,
|
|
(PULONG_PTR)&(*ppGroups)[dwCount].lpctstrGroupName,
|
|
(LPBYTE)*ppGroups,
|
|
&dwOffset,
|
|
dwSize);
|
|
|
|
lpdwDevices = (LPDWORD)((LPBYTE)*ppGroups + dwOffset);
|
|
|
|
dwRes = pCGroup->SerializeDevices(&lpdwDevices,
|
|
&dwNumDevices,
|
|
FALSE); // Do not allocate
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::SerializeDevices failed, error %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (dwNumDevices != 0)
|
|
{
|
|
(*ppGroups)[dwCount].lpdwDevices = (LPDWORD)dwOffset;
|
|
dwOffset += dwNumDevices * sizeof(DWORD);
|
|
}
|
|
else
|
|
{
|
|
(*ppGroups)[dwCount].lpdwDevices = NULL;
|
|
}
|
|
|
|
(*ppGroups)[dwCount].dwNumDevices = dwNumDevices;
|
|
dwCount++;
|
|
}
|
|
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("map or wstring caused exception (%S)"),
|
|
ex.what());
|
|
dwRes = ERROR_GEN_FAILURE;
|
|
goto exit;
|
|
}
|
|
|
|
*lpdwNumGroups = dwCount;
|
|
*lpdwBufferSize = dwSize;
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
MemFree (*ppGroups);
|
|
}
|
|
return dwRes;
|
|
}
|
|
|
|
BOOL
|
|
COutboundRoutingGroupsMap::UpdateAllDevicesGroup (void)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroupsMap::UpdateAllDevicesGroup
|
|
|
|
Routine description:
|
|
|
|
Updates <All devices> group with installed devices
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
PLIST_ENTRY Next;
|
|
PLINE_INFO pLineInfo;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::UpdateAllDevicesGroup"));
|
|
HKEY hGroupKey = NULL;
|
|
LPDWORD lpdwDevices = NULL;
|
|
DWORD dwNumDevices = 0;
|
|
DWORD i;
|
|
PCGROUP pCGroup;
|
|
|
|
pCGroup = FindGroup (ROUTING_GROUP_ALL_DEVICESW);
|
|
if (NULL == pCGroup)
|
|
{
|
|
dwRes = GetLastError();
|
|
if (FAX_ERR_GROUP_NOT_FOUND != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::FindGroup failed , ec %ld"), dwRes);
|
|
return FALSE;
|
|
}
|
|
|
|
COutboundRoutingGroup CGroup;
|
|
dwRes = AddGroup (ROUTING_GROUP_ALL_DEVICESW, &CGroup);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::AddGroup failed , ec %ld"), dwRes);
|
|
SetLastError (dwRes);
|
|
return FALSE;
|
|
}
|
|
|
|
pCGroup = FindGroup (ROUTING_GROUP_ALL_DEVICESW);
|
|
if (NULL == pCGroup)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::FindGroup failed , ec %ld"), dwRes);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
dwRes = pCGroup->SerializeDevices (&lpdwDevices, &dwNumDevices);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::EnumDevices failed , ec %ld"), dwRes);
|
|
SetLastError (dwRes);
|
|
return FALSE;
|
|
}
|
|
|
|
EnterCriticalSection( &g_CsLine );
|
|
Next = g_TapiLinesListHead.Flink;
|
|
Assert (Next);
|
|
|
|
//
|
|
// Remove unavailable devices from the group
|
|
//
|
|
for (i = 0; i < dwNumDevices; i++)
|
|
{
|
|
if (IsDeviceInstalled (lpdwDevices[i]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Device is not installed - remove it
|
|
//
|
|
dwRes = pCGroup->DelDevice (lpdwDevices[i]);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::DelDevice failed , ec %ld"), dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add missing devices from TapiLinesList list
|
|
//
|
|
Next = g_TapiLinesListHead.Flink;
|
|
while ((ULONG_PTR)Next != (ULONG_PTR)&g_TapiLinesListHead)
|
|
{
|
|
pLineInfo = CONTAINING_RECORD( Next, LINE_INFO, ListEntry );
|
|
Next = pLineInfo->ListEntry.Flink;
|
|
Assert (Next && pLineInfo->PermanentLineID);
|
|
|
|
dwRes = pCGroup->AddDevice (pLineInfo->PermanentLineID);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::AddDevice failed, error %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save changes
|
|
//
|
|
hGroupKey = OpenOutboundGroupKey( ROUTING_GROUP_ALL_DEVICESW, TRUE, KEY_READ | KEY_WRITE );
|
|
if (NULL == hGroupKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create group key, OpenRegistryKey failed : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = pCGroup->Save (hGroupKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::Save failed, Group name - %s, failed with %ld"),
|
|
ROUTING_GROUP_ALL_DEVICES,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
MemFree (lpdwDevices);
|
|
if (NULL != hGroupKey)
|
|
{
|
|
RegCloseKey (hGroupKey);
|
|
}
|
|
|
|
LeaveCriticalSection( &g_CsLine );
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
SetLastError (dwRes);
|
|
}
|
|
return (ERROR_SUCCESS == dwRes);
|
|
}
|
|
|
|
|
|
DWORD
|
|
COutboundRoutingGroupsMap::RemoveDevice (DWORD dwDeviceId)
|
|
/*++
|
|
|
|
Routine name : COutboundRoutingGroupsMap::RemoveDevice
|
|
|
|
Routine description:
|
|
|
|
Deletes a device from all of the groups in the map
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Sep, 2000
|
|
|
|
Arguments:
|
|
|
|
dwDeviceId [in ] - The device id to remove
|
|
|
|
Return Value:
|
|
|
|
Standard Win32 error code
|
|
|
|
--*/
|
|
{
|
|
GROUPS_MAP::iterator it;
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
HKEY hGroupKey = NULL;
|
|
DEBUG_FUNCTION_NAME(TEXT("COutboundRoutingGroupsMap::RemoveDevice"));
|
|
|
|
Assert (dwDeviceId);
|
|
|
|
try
|
|
{
|
|
//
|
|
// Delete the device from each group
|
|
//
|
|
for (it = m_GroupsMap.begin(); it != m_GroupsMap.end(); it++)
|
|
{
|
|
PCGROUP pCGroup = &((*it).second);
|
|
LPCWSTR lpcwstrGroupName = ((*it).first).c_str();
|
|
|
|
//
|
|
// Open the group registry key
|
|
//
|
|
hGroupKey = OpenOutboundGroupKey( lpcwstrGroupName, FALSE, KEY_READ | KEY_WRITE );
|
|
if (NULL == hGroupKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open group key, OpenOutboundGroupKey failed : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = pCGroup->DelDevice (dwDeviceId);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::DelDevice failed : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = pCGroup->Save(hGroupKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::Save failed : %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
RegCloseKey (hGroupKey);
|
|
hGroupKey = NULL;
|
|
}
|
|
}
|
|
catch (exception &ex)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("map or wstring caused exception (%S)"),
|
|
ex.what());
|
|
dwRes = ERROR_GEN_FAILURE;
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
|
|
if (NULL != hGroupKey)
|
|
{
|
|
RegCloseKey (hGroupKey);
|
|
}
|
|
return dwRes;
|
|
} // RemoveDevice
|
|
|
|
|
|
|
|
/************************************
|
|
* *
|
|
* Registry *
|
|
* *
|
|
************************************/
|
|
BOOL
|
|
EnumOutboundRoutingGroupsCB(
|
|
HKEY hSubKey,
|
|
LPWSTR SubKeyName,
|
|
DWORD Index,
|
|
LPVOID pContext
|
|
)
|
|
{
|
|
DEBUG_FUNCTION_NAME(TEXT("EnumOutboundRoutingGroupsCB"));
|
|
DWORD dwRes;
|
|
COutboundRoutingGroup CGroup;
|
|
BOOL bGroupDeleted = FALSE;
|
|
|
|
if (!SubKeyName)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if ((_wcsicmp (SubKeyName, ROUTING_GROUP_ALL_DEVICESW) != 0) &&
|
|
IsDesktopSKU())
|
|
{
|
|
//
|
|
// We do not support outbound routing on desktop SKUs. Do not load group information.
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Add group
|
|
//
|
|
dwRes = CGroup.Load (hSubKey, SubKeyName);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::Load failed, group name - %s, error %ld"),
|
|
SubKeyName,
|
|
dwRes);
|
|
|
|
// Open Outbound Routing\Groups key
|
|
HKEY hGroupsKey = OpenRegistryKey( HKEY_LOCAL_MACHINE,
|
|
REGKEY_FAX_OUTBOUND_ROUTING_GROUPS,
|
|
FALSE,
|
|
KEY_READ | KEY_WRITE | DELETE);
|
|
if (NULL == hGroupsKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey, error %ld"),
|
|
dwRes);
|
|
}
|
|
else
|
|
{
|
|
DWORD dwRetVal = RegDeleteKey (hGroupsKey, SubKeyName);
|
|
if (ERROR_SUCCESS != dwRetVal)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegDeleteKey failed, Group name - %s, error %ld"),
|
|
SubKeyName,
|
|
dwRetVal);
|
|
}
|
|
else
|
|
{
|
|
bGroupDeleted = TRUE;
|
|
}
|
|
}
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = g_pGroupsMap->AddGroup (SubKeyName, &CGroup);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::AddGroup failed, group name - %s, error %ld"),
|
|
SubKeyName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
if (bGroupDeleted == FALSE)
|
|
{
|
|
FaxLog(
|
|
FAXLOG_CATEGORY_INIT,
|
|
FAXLOG_LEVEL_MIN,
|
|
1,
|
|
MSG_OUTBOUND_ROUTING_GROUP_NOT_ADDED,
|
|
SubKeyName
|
|
);
|
|
}
|
|
else
|
|
{
|
|
FaxLog(
|
|
FAXLOG_CATEGORY_INIT,
|
|
FAXLOG_LEVEL_MIN,
|
|
1,
|
|
MSG_OUTBOUND_ROUTING_GROUP_NOT_LOADED,
|
|
SubKeyName
|
|
);
|
|
}
|
|
}
|
|
*(LPDWORD)pContext = ERROR_SUCCESS; // Let the service start
|
|
return TRUE; // Let the service start
|
|
}
|
|
|
|
/************************************
|
|
* *
|
|
* RPC handlers *
|
|
* *
|
|
************************************/
|
|
|
|
extern "C"
|
|
error_status_t
|
|
FAX_AddOutboundGroup (
|
|
IN handle_t hFaxHandle,
|
|
IN LPCWSTR lpwstrGroupName
|
|
)
|
|
/*++
|
|
|
|
Routine name : FAX_AddOutboundGroup
|
|
|
|
Routine description:
|
|
|
|
Adds a new Outbound routing group to the fax server
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in ] - FaxServer handle
|
|
lpwstrGroupName [in ] - The new group name
|
|
|
|
Return Value:
|
|
|
|
error_status_t
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_AddOutboundGroup"));
|
|
HKEY hGroupKey = NULL;
|
|
COutboundRoutingGroup CGroup;
|
|
DWORD rVal;
|
|
BOOL fAccess;
|
|
|
|
Assert (lpwstrGroupName);
|
|
|
|
if (_wcsicmp (lpwstrGroupName, ROUTING_GROUP_ALL_DEVICESW) == 0)
|
|
{
|
|
return ERROR_DUP_NAME;
|
|
}
|
|
|
|
if (TRUE == IsDesktopSKU())
|
|
{
|
|
//
|
|
// We do not support outbound routing on desktop SKUs.
|
|
//
|
|
if (FAX_API_VERSION_1 > FindClientAPIVersion (hFaxHandle))
|
|
{
|
|
//
|
|
// API version 0 clients don't know about FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU
|
|
//
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
return FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU;
|
|
}
|
|
}
|
|
|
|
if (wcslen (lpwstrGroupName) >= MAX_ROUTING_GROUP_NAME)
|
|
{
|
|
return ERROR_BUFFER_OVERFLOW;
|
|
}
|
|
|
|
//
|
|
// Access check
|
|
//
|
|
dwRes = FaxSvcAccessCheck (FAX_ACCESS_MANAGE_CONFIG, &fAccess, NULL);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
|
|
dwRes);
|
|
return GetServerErrorCode(dwRes);
|
|
}
|
|
|
|
if (FALSE == fAccess)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("The user does not have the FAX_ACCESS_MANAGE_CONFIG right"));
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
|
|
EnterCriticalSection (&g_CsConfig); // Empty group, no need to lock g_CsLine
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -before change"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
hGroupKey = OpenOutboundGroupKey( lpwstrGroupName, TRUE, KEY_READ | KEY_WRITE );
|
|
if (NULL == hGroupKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create group key, OpenRegistryKey failed : %ld"),
|
|
dwRes);
|
|
dwRes = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = g_pGroupsMap->AddGroup (lpwstrGroupName, &CGroup);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::AddGroup failed, Group name - %s, error %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = CGroup.Save (hGroupKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::Save failed, Group name - %s, failed with %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
g_pGroupsMap->DelGroup (lpwstrGroupName);
|
|
dwRes = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
rVal = CreateConfigEvent (FAX_CONFIG_TYPE_OUT_GROUPS);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CreateConfigEvent(FAX_CONFIG_TYPE_OUT_GROUPS) (ec: %lc)"),
|
|
rVal);
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -before change"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
exit:
|
|
if (NULL != hGroupKey)
|
|
{
|
|
RegCloseKey (hGroupKey);
|
|
}
|
|
LeaveCriticalSection (&g_CsConfig);
|
|
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
return GetServerErrorCode(dwRes);
|
|
}
|
|
|
|
|
|
extern "C"
|
|
error_status_t
|
|
FAX_SetOutboundGroup (
|
|
IN handle_t hFaxHandle,
|
|
IN PRPC_FAX_OUTBOUND_ROUTING_GROUPW pGroup
|
|
)
|
|
/*++
|
|
|
|
Routine name : FAX_SetOutboundGroup
|
|
|
|
Routine description:
|
|
|
|
Sets a new device list to an existing group
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Fax server handle
|
|
pGroup [in] - Pointer to a PRPC_FAX_OUTBOUND_ROUTING_GROUPW contaning group info
|
|
|
|
Return Value:
|
|
|
|
error_status_t
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_SetOutboundGroup"));
|
|
HKEY hGroupKey = NULL;
|
|
PCGROUP pCGroup = NULL;
|
|
COutboundRoutingGroup OldGroup;
|
|
DWORD rVal;
|
|
BOOL fAccess;
|
|
BOOL fAllDevicesGroup = FALSE;
|
|
|
|
Assert (pGroup);
|
|
|
|
if (sizeof (FAX_OUTBOUND_ROUTING_GROUPW) != pGroup->dwSizeOfStruct)
|
|
{
|
|
//
|
|
// Size mismatch
|
|
//
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!pGroup->lpwstrGroupName)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (wcslen (pGroup->lpwstrGroupName) >= MAX_ROUTING_GROUP_NAME)
|
|
{
|
|
return ERROR_BUFFER_OVERFLOW;
|
|
}
|
|
|
|
|
|
if (!pGroup->lpdwDevices && pGroup->dwNumDevices)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (TRUE == IsDesktopSKU())
|
|
{
|
|
//
|
|
// We do not support outbound routing on desktop SKUs.
|
|
//
|
|
if (FAX_API_VERSION_1 > FindClientAPIVersion (hFaxHandle))
|
|
{
|
|
//
|
|
// API version 0 clients don't know about FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU
|
|
//
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
return FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Access check
|
|
//
|
|
dwRes = FaxSvcAccessCheck (FAX_ACCESS_MANAGE_CONFIG, &fAccess, NULL);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
|
|
dwRes);
|
|
return GetServerErrorCode(dwRes);
|
|
}
|
|
|
|
if (FALSE == fAccess)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("The user does not have the FAX_ACCESS_MANAGE_CONFIG right"));
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
|
|
if (_wcsicmp (pGroup->lpwstrGroupName, ROUTING_GROUP_ALL_DEVICESW) == 0)
|
|
{
|
|
//
|
|
// If it is <All Devices> group we should validate that no device is missing,
|
|
// and that the new group contains all installed devices.
|
|
//
|
|
fAllDevicesGroup = TRUE;
|
|
}
|
|
|
|
EnterCriticalSection (&g_CsLine);
|
|
EnterCriticalSection (&g_CsConfig);
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -before change"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
pCGroup = g_pGroupsMap->FindGroup (pGroup->lpwstrGroupName);
|
|
if (!pCGroup)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::SetGroup failed, Group name - %s, error %ld"),
|
|
pGroup->lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
hGroupKey = OpenOutboundGroupKey( pGroup->lpwstrGroupName, FALSE, KEY_READ | KEY_WRITE );
|
|
if (NULL == hGroupKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't create group key, OpenRegistryKey failed : %ld"),
|
|
dwRes);
|
|
dwRes = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
OldGroup = *pCGroup;
|
|
|
|
dwRes = pCGroup->SetDevices (pGroup->lpdwDevices, pGroup->dwNumDevices, fAllDevicesGroup);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::SetDevices failed, Group name - %s, failed with %ld"),
|
|
pGroup->lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
dwRes = pCGroup->Save (hGroupKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::Save failed, Group name - %s, failed with %ld"),
|
|
pGroup->lpwstrGroupName,
|
|
dwRes);
|
|
*pCGroup = OldGroup;
|
|
dwRes = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
rVal = CreateConfigEvent (FAX_CONFIG_TYPE_OUT_GROUPS);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CreateConfigEvent(FAX_CONFIG_TYPE_OUT_GROUPS) (ec: %lc)"),
|
|
rVal);
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -before change"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
exit:
|
|
if (NULL != hGroupKey)
|
|
{
|
|
RegCloseKey (hGroupKey);
|
|
}
|
|
LeaveCriticalSection (&g_CsConfig);
|
|
LeaveCriticalSection (&g_CsLine);
|
|
|
|
if (ERROR_SUCCESS == dwRes)
|
|
{
|
|
//
|
|
// We might find a line for a pending job. Wake up JobQueueThread
|
|
//
|
|
if (!SetEvent( g_hJobQueueEvent ))
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Failed to set g_hJobQueueEvent. (ec: %ld)"),
|
|
GetLastError());
|
|
|
|
EnterCriticalSection (&g_CsQueue);
|
|
g_ScanQueueAfterTimeout = TRUE;
|
|
LeaveCriticalSection (&g_CsQueue);
|
|
}
|
|
}
|
|
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
return GetServerErrorCode(dwRes);
|
|
}
|
|
|
|
|
|
extern "C"
|
|
error_status_t
|
|
FAX_RemoveOutboundGroup (
|
|
IN handle_t hFaxHandle,
|
|
IN LPCWSTR lpwstrGroupName
|
|
)
|
|
/*++
|
|
|
|
Routine name : FAX_RemoveOutboundGroup
|
|
|
|
Routine description:
|
|
|
|
Removes an existing Outbound routing group from the fax server
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in ] - FaxServer handle
|
|
lpwstrGroupName [in ] - The group name
|
|
|
|
Return Value:
|
|
|
|
error_status_t
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_RemoveOutboundGroup"));
|
|
HKEY hGroupsKey = NULL;
|
|
DWORD rVal;
|
|
BOOL fAccess;
|
|
PCGROUP pCGroup = NULL;
|
|
|
|
Assert (lpwstrGroupName);
|
|
|
|
if (_wcsicmp (lpwstrGroupName, ROUTING_GROUP_ALL_DEVICESW) == 0)
|
|
{
|
|
return ERROR_INVALID_OPERATION;
|
|
}
|
|
|
|
if (TRUE == IsDesktopSKU())
|
|
{
|
|
//
|
|
// We do not support outbound routing on desktop SKUs.
|
|
//
|
|
if (FAX_API_VERSION_1 > FindClientAPIVersion (hFaxHandle))
|
|
{
|
|
//
|
|
// API version 0 clients don't know about FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU
|
|
//
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
return FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU;
|
|
}
|
|
}
|
|
|
|
if (wcslen (lpwstrGroupName) >= MAX_ROUTING_GROUP_NAME)
|
|
{
|
|
return ERROR_BUFFER_OVERFLOW;
|
|
}
|
|
|
|
//
|
|
// Access check
|
|
//
|
|
dwRes = FaxSvcAccessCheck (FAX_ACCESS_MANAGE_CONFIG, &fAccess, NULL);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
|
|
dwRes);
|
|
return GetServerErrorCode(dwRes);
|
|
}
|
|
|
|
if (FALSE == fAccess)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("The user does not have the FAX_ACCESS_MANAGE_CONFIG right"));
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
|
|
EnterCriticalSection (&g_CsConfig);
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -before delete"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
BOOL bGroupInRule;
|
|
dwRes = g_pRulesMap->IsGroupInRuleDest(lpwstrGroupName, &bGroupInRule);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::IsGroupInRuleDest failed, Group name - %s, error %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
if (TRUE == bGroupInRule)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Group is a rule destination, Can not be deleted, Group name - %s"),
|
|
lpwstrGroupName);
|
|
dwRes = FAX_ERR_GROUP_IN_USE;
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// See if the group exists in the map
|
|
//
|
|
pCGroup = g_pGroupsMap->FindGroup (lpwstrGroupName);
|
|
if (!pCGroup)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::SetGroup failed, Group name - %s, error %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
// Open Outbound Routing\Groups key
|
|
hGroupsKey = OpenRegistryKey( HKEY_LOCAL_MACHINE,
|
|
REGKEY_FAX_OUTBOUND_ROUTING_GROUPS,
|
|
FALSE,
|
|
KEY_READ | KEY_WRITE | DELETE);
|
|
if (NULL == hGroupsKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("OpenRegistryKey, error %ld"),
|
|
dwRes);
|
|
dwRes = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
|
|
// Delete the specified group key
|
|
dwRes = RegDeleteKey (hGroupsKey, lpwstrGroupName);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("RegDeleteKey failed, Group name - %s, error %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
// Delete the group from the memory
|
|
dwRes = g_pGroupsMap->DelGroup (lpwstrGroupName);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::DelGroup failed, Group name - %s, error %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
rVal = CreateConfigEvent (FAX_CONFIG_TYPE_OUT_GROUPS);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CreateConfigEvent(FAX_CONFIG_TYPE_OUT_GROUPS) (ec: %lc)"),
|
|
rVal);
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -after delete"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
exit:
|
|
if (NULL != hGroupsKey)
|
|
{
|
|
RegCloseKey (hGroupsKey);
|
|
}
|
|
LeaveCriticalSection (&g_CsConfig);
|
|
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
return GetServerErrorCode(dwRes);
|
|
} //FAX_RemoveOutboundGroup
|
|
|
|
|
|
|
|
error_status_t
|
|
FAX_EnumOutboundGroups (
|
|
handle_t hFaxHandle,
|
|
LPBYTE* ppBuffer,
|
|
LPDWORD lpdwBufferSize,
|
|
LPDWORD lpdwNumGroups
|
|
)
|
|
/*++
|
|
|
|
Routine name : FAX_EnumOutboundGroups
|
|
|
|
Routine description:
|
|
|
|
Enumurates all outbound routing groups
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in ] - Fax server handle
|
|
ppBuffer [out ] - Adress of a pointer to a buffer to be filled with info
|
|
lpdwBufferSize [in/out] - The buffer size
|
|
lpdwNumGroups [out ] - Number of groups returned
|
|
|
|
Return Value:
|
|
|
|
error_status_t
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_EnumOutboundGroups"));
|
|
BOOL fAccess;
|
|
|
|
Assert (lpdwNumGroups && lpdwNumGroups); // ref pointer in idl
|
|
if (!ppBuffer) // unique pointer in idl
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (TRUE == IsDesktopSKU())
|
|
{
|
|
//
|
|
// We do not support outbound routing on desktop SKUs.
|
|
//
|
|
if (FAX_API_VERSION_1 > FindClientAPIVersion (hFaxHandle))
|
|
{
|
|
//
|
|
// API version 0 clients don't know about FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU
|
|
//
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
return FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Access check
|
|
//
|
|
dwRes = FaxSvcAccessCheck (FAX_ACCESS_QUERY_CONFIG, &fAccess, NULL);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
|
|
dwRes);
|
|
return GetServerErrorCode(dwRes);
|
|
}
|
|
|
|
if (FALSE == fAccess)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("The user does not have the FAX_ACCESS_QUERY_CONFIG right"));
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
|
|
*ppBuffer = NULL;
|
|
*lpdwNumGroups = 0;
|
|
|
|
|
|
EnterCriticalSection (&g_CsConfig);
|
|
|
|
dwRes = g_pGroupsMap->SerializeGroups ((PFAX_OUTBOUND_ROUTING_GROUPW*)ppBuffer,
|
|
lpdwNumGroups,
|
|
lpdwBufferSize);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::SerializeGroups failed, error %ld"),
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
exit:
|
|
LeaveCriticalSection (&g_CsConfig);
|
|
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
return GetServerErrorCode(dwRes);
|
|
|
|
} //FAX_EnumOutboundGroups
|
|
|
|
error_status_t
|
|
FAX_SetDeviceOrderInGroup (
|
|
handle_t hFaxHandle,
|
|
LPCWSTR lpwstrGroupName,
|
|
DWORD dwDeviceId,
|
|
DWORD dwNewOrder
|
|
)
|
|
/*++
|
|
|
|
Routine name : FAX_SetDeviceOrderInGroup
|
|
|
|
Routine description:
|
|
|
|
Sets the order of the specified device in the group
|
|
|
|
Author:
|
|
|
|
Oded Sacher (OdedS), Dec, 1999
|
|
|
|
Arguments:
|
|
|
|
hFaxHandle [in] - Fax server handle
|
|
lpwstrGroupName [in] - The group name
|
|
dwDeviceId [in] - The device permanent ID
|
|
dwNewOrder [in] - The device new order
|
|
|
|
Return Value:
|
|
|
|
error_status_t
|
|
|
|
--*/
|
|
{
|
|
DWORD dwRes = ERROR_SUCCESS;
|
|
DEBUG_FUNCTION_NAME(TEXT("FAX_SetDeviceOrderInGroup"));
|
|
HKEY hGroupKey = NULL;
|
|
PCGROUP pCGroup = NULL;
|
|
COutboundRoutingGroup OldGroup;
|
|
DWORD rVal;
|
|
BOOL fAccess;
|
|
|
|
Assert (lpwstrGroupName);
|
|
|
|
if (!dwDeviceId || !dwNewOrder)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
if (wcslen (lpwstrGroupName) >= MAX_ROUTING_GROUP_NAME)
|
|
{
|
|
SetLastError(ERROR_BUFFER_OVERFLOW);
|
|
return FALSE;
|
|
}
|
|
|
|
if (TRUE == IsDesktopSKU())
|
|
{
|
|
//
|
|
// We do not support outbound routing on desktop SKUs.
|
|
//
|
|
if (FAX_API_VERSION_1 > FindClientAPIVersion (hFaxHandle))
|
|
{
|
|
//
|
|
// API version 0 clients don't know about FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU
|
|
//
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
return FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Access check
|
|
//
|
|
dwRes = FaxSvcAccessCheck (FAX_ACCESS_MANAGE_CONFIG, &fAccess, NULL);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
|
|
dwRes);
|
|
return GetServerErrorCode(dwRes);
|
|
}
|
|
|
|
if (FALSE == fAccess)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,
|
|
TEXT("The user does not have the FAX_ACCESS_MANAGE_CONFIG right"));
|
|
return ERROR_ACCESS_DENIED;
|
|
}
|
|
|
|
EnterCriticalSection (&g_CsConfig);
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -before changing order"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
// Find the group in memory
|
|
pCGroup = g_pGroupsMap->FindGroup (lpwstrGroupName);
|
|
if (!pCGroup)
|
|
{
|
|
dwRes = GetLastError();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::FindGroup failed, Group name - %s, error %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
// Open the group registry key
|
|
hGroupKey = OpenOutboundGroupKey( lpwstrGroupName, FALSE, KEY_READ | KEY_WRITE );
|
|
if (NULL == hGroupKey)
|
|
{
|
|
dwRes = GetLastError ();
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("Can't open group key, OpenOutboundGroupKey failed : %ld"),
|
|
dwRes);
|
|
dwRes = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
// Save a copy of the old group
|
|
OldGroup = *pCGroup;
|
|
|
|
// Cahnge the device order in the group
|
|
dwRes = pCGroup->SetDeviceOrder(dwDeviceId, dwNewOrder);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroupsMap::SetDeviceOrder failed, Group name - %s,\
|
|
Device Id %ld, new order %ld, error %ld"),
|
|
lpwstrGroupName,
|
|
dwDeviceId,
|
|
dwNewOrder,
|
|
dwRes);
|
|
goto exit;
|
|
}
|
|
|
|
// save changes to the registry
|
|
dwRes = pCGroup->Save (hGroupKey);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("COutboundRoutingGroup::Save failed, Group name - %s, failed with %ld"),
|
|
lpwstrGroupName,
|
|
dwRes);
|
|
// Rollback memory
|
|
*pCGroup = OldGroup;
|
|
dwRes = ERROR_REGISTRY_CORRUPT;
|
|
goto exit;
|
|
}
|
|
|
|
rVal = CreateConfigEvent (FAX_CONFIG_TYPE_OUT_GROUPS);
|
|
if (ERROR_SUCCESS != dwRes)
|
|
{
|
|
DebugPrintEx(
|
|
DEBUG_ERR,
|
|
TEXT("CreateConfigEvent(FAX_CONFIG_TYPE_OUT_GROUPS) (ec: %lc)"),
|
|
rVal);
|
|
}
|
|
|
|
Assert (ERROR_SUCCESS == dwRes);
|
|
|
|
#if DBG
|
|
DebugPrintEx(
|
|
DEBUG_MSG,
|
|
TEXT("Dump outbound routing groups -after change"));
|
|
g_pGroupsMap->Dump();
|
|
#endif
|
|
|
|
exit:
|
|
if (NULL != hGroupKey)
|
|
{
|
|
RegCloseKey (hGroupKey);
|
|
}
|
|
LeaveCriticalSection (&g_CsConfig);
|
|
|
|
UNREFERENCED_PARAMETER (hFaxHandle);
|
|
return GetServerErrorCode(dwRes);
|
|
|
|
}// FAX_SetDeviceOrderInGroup
|
|
|
|
|
|
|