Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

793 lines
17 KiB

/////////////////////////////////////////////////////////////////////////////
// FILE : FaxServer.cpp //
// //
// DESCRIPTION : CFaxServer that contains the //
// Connect / Disconnect functionality to the Fax Server //
// //
// //
// AUTHOR : yossg //
// //
// HISTORY : //
// Nov 25 1999 yossg Init . //
// Aug 3 2000 yossg Add notification window //
// //
// Copyright (C) 1999 - 2000 Microsoft Corporation All Rights Reserved //
/////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "FaxServer.h"
#include "Devices.h"
#include "GeneralNotifyWnd.h"
#include <FaxReg.h>
/*
- CFaxServer::GetFaxServerHandle
-
* Purpose:
* If Handle does not exist re-connect.
* Retreives the Fax Server handle.
*
* Arguments:
*
* Return:
* Fax Server handle, if failed to connect
* retrieves NULL
*/
HANDLE CFaxServer::GetFaxServerHandle()
{
if (!m_hFaxHandle)
{
ATLASSERT (!m_hDevicesStatusNotification);
HRESULT hRc = Connect();
if ( FAILED(hRc))
{
// DebugPrintEx(DEBUG_ERR)
// should been already given by
// this function caller.
}
}
return m_hFaxHandle;
}
/*
- CFaxServer::Connect
-
* Purpose:
* Connect to the Fax Server.
*
* Arguments:
*
* Return:
*
*/
HRESULT CFaxServer::Connect()
{
DEBUG_FUNCTION_NAME(TEXT("CFaxServer::Connect"));
DWORD ec = ERROR_SUCCESS;
ATLASSERT(!m_hFaxHandle);
//
// Connect to server
//
if (!FaxConnectFaxServer (m_bstrServerName, &m_hFaxHandle))
{
ec= GetLastError();
DebugPrintEx(
DEBUG_ERR,
_T("FaxConnectFaxServer() Failed to %ws. (ec: %ld)"),
((!m_bstrServerName) || (m_bstrServerName == L""))? L"local machine" : m_bstrServerName.m_str,
ec);
m_hFaxHandle = NULL;
return HRESULT_FROM_WIN32(ec);
}
ATLASSERT(m_hFaxHandle);
//
// Check Server API Version
//
if(!FaxGetReportedServerAPIVersion(m_hFaxHandle, &m_dwServerAPIVersion))
{
//
// Cannot retrieve version info
//
ec= GetLastError();
DebugPrintEx(DEBUG_ERR, _T("FaxGetReportedServerAPIVersion() failed with %ld)"), ec);
Disconnect();
return HRESULT_FROM_WIN32(ec);
}
if(m_dwServerAPIVersion > CURRENT_FAX_API_VERSION)
{
//
// Cannot manage later version of fax
//
Disconnect();
return HRESULT_FROM_WIN32(ERROR_RMODE_APP);
}
PRODUCT_SKU_TYPE ServerSKU = PRODUCT_SKU_UNKNOWN;
if(!FaxGetServerSKU(m_hFaxHandle, &ServerSKU))
{
ec = GetLastError();
DebugPrintEx(DEBUG_ERR, _T("FaxGetServerSKU() failed with %ld)"), ec);
Disconnect();
return HRESULT_FROM_WIN32(ec);
}
if(IsDesktopSKUFromSKU(ServerSKU))
{
//
// We are connected to WinXP Desktop SKU
// It cannot be managed remotely
//
m_bDesktopSKUConnection = TRUE;
Disconnect();
return HRESULT_FROM_WIN32(ERROR_RMODE_APP);
}
//
// Verify or re-establish (if needed) notification setup
//
if (m_pDevicesNode)
{
HRESULT hRc = InternalRegisterForDeviceNotifications();
if (S_OK != hRc)
{
DebugPrintEx(
DEBUG_ERR,
_T("InternalRegisterForDeviceNotifications Failed. (hRc: %08X)"),
hRc);
}
}
DebugPrintEx(
DEBUG_MSG,
_T("FaxConnectFaxServer() succeeded. Handle: %08X"),
m_hFaxHandle);
return S_OK;
}
/*
- CFaxServer::Disconnect
-
* Purpose:
* Disconnect from the Fax Server.
*
* Arguments:
*
* Return:
*
*/
HRESULT CFaxServer::Disconnect()
{
DEBUG_FUNCTION_NAME(TEXT("CFaxServer::Disconnect"));
HRESULT hRc = S_OK;
DWORD ec;
if (NULL == m_hFaxHandle)
{
hRc = E_FAIL;
DebugPrintEx(
DEBUG_MSG,
_T("No connection handle exists. (m_hFaxHandle is NULL)\n Connection may not started or disconnected before.\n "));
return hRc;
}
hRc = UnRegisterForNotifications();
if (S_OK != hRc)
{
DebugPrintEx(
DEBUG_ERR,
_T("UnRegisterForNotifications() failed. (hRc: %0X8)"),
hRc);
// continue!!!
}
if (!FaxClose (m_hFaxHandle))
{
ec= GetLastError();
DebugPrintEx(
DEBUG_ERR,
_T("FaxClose() failed. (ec: %ld)"),
ec);
hRc = HRESULT_FROM_WIN32(ec);
goto Cleanup;
}
DebugPrintEx( DEBUG_MSG,
_T("Succeeded to close connection to Fax. ServerHandle: %08X"),
m_hFaxHandle);
Cleanup:
m_hFaxHandle = NULL;
return hRc;
}
/*
- CFaxServer::SetServerName
-
* Purpose:
* Set the Server machine name
*
* Arguments:
*
* Return:
* OLE error code
*/
HRESULT CFaxServer::SetServerName(BSTR bstrServerName)
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::SetServerName"));
HRESULT hRc = S_OK;
m_bstrServerName = bstrServerName;
if (!m_bstrServerName)
{
hRc = E_OUTOFMEMORY;
DebugPrintEx(
DEBUG_ERR,
_T("Failed to allocate string - out of memory"));
m_bstrServerName = L"";
}
return hRc;
}
/*
- CFaxServer::GetServerName
-
* Purpose:
* Set the Server machine name
*
* Arguments:
*
* Return:
* OLE error code
*/
const CComBSTR& CFaxServer::GetServerName()
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::GetServerName"));
return m_bstrServerName;
}
/*
+
+
* CFaxServer::IsServerRunningFaxService
*
* Purpose:
* Contacts the machine and determines if Fax Server Service is running.
*
* Arguments:
*
* Return:
* boolean value Running or notruning
-
-
*/
BOOL CFaxServer::IsServerRunningFaxService ( )
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::IsServerRunningFaxService"));
SC_HANDLE SCMHandle = NULL;
SC_HANDLE FXSHandle = NULL;
SERVICE_STATUS SStatus;
BOOL bRun = FALSE;
if (
(SCMHandle = OpenSCManager(m_bstrServerName, NULL, GENERIC_READ))
&&
(FXSHandle = OpenService(SCMHandle, FAX_SERVICE_NAME, SERVICE_QUERY_STATUS))
&&
QueryServiceStatus(FXSHandle, &SStatus)
&&
(SERVICE_RUNNING == SStatus.dwCurrentState)
)
{
bRun = TRUE;
}
if (FXSHandle)
{
CloseServiceHandle(FXSHandle);
}
else // FXSHandle == NULL
{
DebugPrintEx(
DEBUG_ERR,
_T("Fail to Open Fax Server Service. (ec: %ld)"),
GetLastError());
}
if (SCMHandle)
{
CloseServiceHandle(SCMHandle);
}
else // SCMHandle == NULL
{
DebugPrintEx(
DEBUG_ERR,
_T("Fail to OpenSCManager. (ec: %ld)"),
GetLastError());
}
return bRun;
}
/*
+
+
* CFaxServer::IsServerFaxServiceStopped
*
* Purpose:
* Contacts the machine and determines if Fax Server Service is already stopped.
*
* Arguments:
* [in] bstrServerName - the server name
*
* Return:
* boolean value Running or notruning
-
-
*/
BOOL CFaxServer::IsServerFaxServiceStopped( )
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::IsServerFaxServiceStopped"));
SC_HANDLE SCMHandle = NULL;
SC_HANDLE FXSHandle = NULL;
SERVICE_STATUS SStatus;
BOOL bRun = FALSE;
if (
(SCMHandle = OpenSCManager(m_bstrServerName, NULL, GENERIC_READ))
&&
(FXSHandle = OpenService(SCMHandle, FAX_SERVICE_NAME, SERVICE_QUERY_STATUS))
&&
QueryServiceStatus(FXSHandle, &SStatus)
&&
(SERVICE_STOPPED == SStatus.dwCurrentState)
)
{
bRun = TRUE;
}
if (FXSHandle)
{
CloseServiceHandle(FXSHandle);
}
else // FXSHandle == NULL
{
DebugPrintEx(
DEBUG_ERR,
_T("Fail to Open Fax Server Service. (ec: %ld)"),
GetLastError());
}
if (SCMHandle)
{
CloseServiceHandle(SCMHandle);
}
else // SCMHandle == NULL
{
DebugPrintEx(
DEBUG_ERR,
_T("Fail to OpenSCManager. (ec: %ld)"),
GetLastError());
}
return bRun;
}
/*
+
+
* CFaxServer::CreateNotifyWindow
*
* Purpose:
* Init notification window
*
* Arguments:
*
* Return:
* OLE error code
-
-
*/
DWORD CFaxServer::CreateNotifyWindow( )
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::CreateNotifyWindow"));
DWORD ec = ERROR_SUCCESS;
RECT rcRect;
ZeroMemory(&rcRect, sizeof(rcRect));
HWND hDevicesNotifyHandle;
ATLASSERT(!m_pNotifyWin);
m_pNotifyWin = new CFaxGeneralNotifyWnd(this);
if (!m_pNotifyWin)
{
ec = ERROR_NOT_ENOUGH_MEMORY;
SetLastError(ec);
DebugPrintEx(
DEBUG_ERR,
TEXT("Fail to create CFaxGeneralNotifyWnd - Out of memory."));
goto Exit;
}
hDevicesNotifyHandle = m_pNotifyWin->Create(NULL,
rcRect,
NULL, //LPCTSTR szWindowName
WS_POPUP, //DWORD dwStyle
0x0,
0);
ATLASSERT(m_pNotifyWin->m_hWnd == m_hDevicesNotifyHandle);
if (!(::IsWindow(hDevicesNotifyHandle)))
{
ec = ERROR_INVALID_HANDLE;
DebugPrintEx(
DEBUG_ERR,
_T("Failed to create window."));
hDevicesNotifyHandle = NULL;
delete m_pNotifyWin;
m_pNotifyWin = NULL;
goto Exit;
}
ATLASSERT(ERROR_SUCCESS == ec);
goto Exit;
Exit:
return ec;
}
/*
+
+
* CFaxServer::UnRegisterForNotifications
*
* Purpose:
* UnRegisterFor Server Event Notifications
*
* Arguments:
*
* Return:
* OLE error code
-
-
*/
HRESULT CFaxServer::UnRegisterForNotifications()
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::UnRegisterForNotifications"));
DWORD ec = ERROR_SUCCESS;
if (m_hDevicesStatusNotification)
{
//
// Unregister server notifications
//
if (!FaxUnregisterForServerEvents (m_hDevicesStatusNotification))
{
ec = GetLastError ();
DebugPrintEx(
DEBUG_ERR,
_T("Fail to Unregister For Device status Server Events. (ec: %ld)"),
ec);
m_hDevicesStatusNotification = NULL;
goto Exit;
}
}
Exit:
return HRESULT_FROM_WIN32(ec);
}
/*
+
+
* CFaxServer::RegisterForNotification
*
* Purpose:
* RegisterFor Server Event Notifications
*
* Arguments:
*
* Return:
* OLE error code
-
-
*/
DWORD CFaxServer::RegisterForNotifications()
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::RegisterForNotifications"));
DWORD ec = ERROR_SUCCESS;
//
// Register for device status notification
//
ATLASSERT(!m_hDevicesStatusNotification);
ATLASSERT(m_pNotifyWin);
ATLASSERT(m_pNotifyWin->IsWindow());
if (!FaxRegisterForServerEvents (
m_hFaxHandle,
FAX_EVENT_TYPE_DEVICE_STATUS,
NULL,
0,
m_pNotifyWin->m_hWnd,
WM_GENERAL_EVENT_NOTIFICATION,
&m_hDevicesStatusNotification
)
)
{
ec = GetLastError();
DebugPrintEx(
DEBUG_ERR,
_T("Fail to Register For Device Status Server Events (ec: %ld)"), ec);
m_hDevicesStatusNotification = NULL;
goto Exit;
}
ATLASSERT(m_hDevicesStatusNotification);
Exit:
return ec;
}
/*
+
+
* CFaxServer::InternalRegisterForDeviceNotifications
*
* Purpose:
* Call the members to create window and register for device notifications
*
* Arguments:
* non.
*
* Return:
* HRESULT
-
-
*/
HRESULT CFaxServer::InternalRegisterForDeviceNotifications()
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::InternalRegisterForDeviceNotifications"));
DWORD ec = ERROR_SUCCESS;
ATLASSERT (m_pDevicesNode);
//
// Check/Create notification window
//
if (!m_pNotifyWin)
{
ATLASSERT(!m_hDevicesStatusNotification);
ec = CreateNotifyWindow();
if ( ERROR_SUCCESS != ec)
{
DebugPrintEx(
DEBUG_MSG,
_T("Fail to CreateNotifyWindow(). (ec: %ld)"),
ec);
return HRESULT_FROM_WIN32(ec);
}
}
ATLASSERT(m_pNotifyWin);
//
// Check/register to event notification
//
if (!m_hDevicesStatusNotification)
{
ec = RegisterForNotifications();
if (ERROR_SUCCESS != ec)
{
DebugPrintEx(
DEBUG_ERR,
_T("Fail to RegisterForNotification()"),
ec);
ATLASSERT(!m_hDevicesStatusNotification);
//
// Keep the notification window alive.
// Try next time to register only.
//
return HRESULT_FROM_WIN32(ec);
}
ATLASSERT(m_hDevicesStatusNotification);
}
return S_OK;
}
/*
+
+
* CFaxServer::OnNewEvent
*
* Purpose:
* Called when new registered event reaches window
*
* Arguments:
* pFaxEvent [in] - PFAX_EVENT_EX structure pointer
*
* Return:
* OLE error code
-
-
*/
HRESULT CFaxServer::OnNewEvent(PFAX_EVENT_EX pFaxEvent)
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::OnNewEvent"));
HRESULT hRc = S_OK;
//
// Update "Devices" Node
//
if ( FAX_EVENT_TYPE_DEVICE_STATUS == pFaxEvent->EventType )
{
ATLASSERT( m_pDevicesNode);
hRc = m_pDevicesNode->UpdateDeviceStatusChange(
pFaxEvent->EventInfo.DeviceStatus.dwDeviceId,
pFaxEvent->EventInfo.DeviceStatus.dwNewStatus);
if (S_OK != hRc)
{
DebugPrintEx(
DEBUG_ERR,
_T("Failed to UpdateDeviceStatusChange()"));
goto Exit;
}
}
else
{
ATLASSERT(FALSE); //Unsupported EVENT
}
Exit:
return hRc;
}
/*
+
+
* CFaxServer::RegisterForDeviceNotifications
*
* Purpose:
* Init Devices notification window
*
* Arguments:
* pDevices [in] - pointer to "devices" node
*
* Return:
* OLE error code
-
-
*/
HRESULT CFaxServer::RegisterForDeviceNotifications(CFaxDevicesNode * pDevices)
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::RegisterForDeviceNotifications"));
HRESULT hRc = S_OK;
//
// Set pointer to Devices node
//
m_pDevicesNode = pDevices;
ATLASSERT (m_pDevicesNode);
//
// Now try to do the stages needed for this registration to happen
//
hRc = InternalRegisterForDeviceNotifications();
if (S_OK != hRc)
{
DebugPrintEx(
DEBUG_ERR,
_T("InternalRegisterForDeviceNotifications Failed. (hRc: %08X)"),
hRc);
}
return hRc;
}
/*
+
+
* CFaxServer::DestroyNotifyWindow
*
* Purpose:
* DestroyNotifyWindow
*
* Arguments:
*
* Return:
* VOID
-
-
*/
VOID CFaxServer::DestroyNotifyWindow()
{
DEBUG_FUNCTION_NAME( _T("CFaxServer::DestroyNotifyWindow"));
//
// Destroy Notification Window
//
if (NULL != m_pNotifyWin)
{
if (m_pNotifyWin->IsWindow())
{
m_pNotifyWin->DestroyWindow();
}
delete m_pNotifyWin;
m_pNotifyWin = NULL;
}
return;
}