|
|
/////////////////////////////////////////////////////////////////////////////
// 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; }
|