|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
FaxServer.cpp
Abstract:
Implementation of CFaxServer
Author:
Iv Garber (IvG) Apr, 2000
Revision History:
--*/
#include "stdafx.h"
#include "FaxComEx.h"
#include "FaxServer.h"
#include "FaxDevices.h"
#include "FaxDeviceProviders.h"
#include <new>
//
//================== GET API VERSION ==============================
//
STDMETHODIMP CFaxServer::get_APIVersion( /*[out, retval]*/ FAX_SERVER_APIVERSION_ENUM *pAPIVersion ) /*++
Routine name : CFaxServer::get_APIVersion
Routine description:
Return API Version of the Fax Server.
Author:
Iv Garber (IvG), May, 2001
Arguments:
pAPIVersion [out] - ptr to the place to put the API Version of the Fax Server
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::get_APIVersion"), hr);
if (!m_bVersionValid) { //
// get Version of the Server
//
hr = GetVersion(); if (FAILED(hr)) { return hr; } }
//
// Check the pointer we have got
//
if (::IsBadWritePtr(pAPIVersion, sizeof(FAX_SERVER_APIVERSION_ENUM))) { //
// Got a bad return pointer
//
hr = E_POINTER; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr); return hr; }
*pAPIVersion = m_APIVersion; return hr; }
//
//====================== CLEAR NOTIFY WINDOW ============================
//
void CFaxServer::ClearNotifyWindow(void) /*++
Routine name : CFaxServer::ClearNotifyWindow
Routine description:
Clear Notify Window.
Author:
Iv Garber (IvG), Jul, 2000
Arguments:
None.
Return Value:
None.
--*/ { if (m_pNotifyWindow && ::IsWindow(m_pNotifyWindow->m_hWnd)) { m_pNotifyWindow->DestroyWindow(); }
if (m_pNotifyWindow) { delete m_pNotifyWindow; m_pNotifyWindow = NULL; } return; }
//
//====================== PROCESS JOB NOTIFICATION =======================
//
HRESULT CFaxServer::ProcessJobNotification( /*[in]*/ DWORDLONG dwlJobId, /*[in]*/ FAX_ENUM_JOB_EVENT_TYPE eventType, /*[in]*/ LOCATION place, /*[in]*/ FAX_JOB_STATUS *pJobStatus ) /*++
Routine name : CFaxServer::ProcessJobNotification
Routine description:
Call appropriate Fire Method, for Jobs/Messages in Queues/Archives.
Author:
Iv Garber (IvG), Jul, 2000
Arguments:
dwlJobId [in] - Id of the Job/Message eventType [in] - Type of the Event place [in] - Where the Job/Message sits pJobStatus [in] - FAX_JOB_STATUS structure
Return Value:
Standard HRESULT value.
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::ProcessJobNotification"), hr, _T("JOBID=%ld EVENTTYPE=%ld PLACE=%d"), dwlJobId, eventType, place);
//
// Convert JobId from DWORDLONG into BSTR
//
CComBSTR bstrJobId; hr = GetBstrFromDwordlong(dwlJobId, &bstrJobId); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("GetBstrFromDwordlong(dwlJobId, &bstrJobId)"), hr); return hr; }
//
// Check Type of the Event that happened
//
switch (eventType) { case FAX_JOB_EVENT_TYPE_ADDED:
switch (place) { case IN_QUEUE: hr = Fire_OnIncomingJobAdded(this, bstrJobId); break; case OUT_QUEUE: hr = Fire_OnOutgoingJobAdded(this, bstrJobId); break; case IN_ARCHIVE: hr = Fire_OnIncomingMessageAdded(this, bstrJobId); break; case OUT_ARCHIVE: hr = Fire_OnOutgoingMessageAdded(this, bstrJobId); break; default: //
// assert (FALSE)
//
ATLASSERT(place == IN_QUEUE); hr = E_FAIL; return hr; }
if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_On In/Out Job/Message Added(this, bstrJobId)"), hr); return hr; } break; case FAX_JOB_EVENT_TYPE_REMOVED:
switch (place) { case IN_QUEUE: hr = Fire_OnIncomingJobRemoved(this, bstrJobId); break; case OUT_QUEUE: hr = Fire_OnOutgoingJobRemoved(this, bstrJobId); break; case IN_ARCHIVE: hr = Fire_OnIncomingMessageRemoved(this, bstrJobId); break; case OUT_ARCHIVE: hr = Fire_OnOutgoingMessageRemoved(this, bstrJobId); break; default: //
// assert (FALSE)
//
ATLASSERT(place == IN_QUEUE); hr = E_FAIL; return hr; }
if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_On In/Out Job/Message Removed(this, bstrJobId)"), hr); return hr; } break; case FAX_JOB_EVENT_TYPE_STATUS: { if (!pJobStatus) { ATLASSERT(pJobStatus); hr = E_FAIL; return hr; }
//
// Create Job Status Object to pass to the Events
//
CComObject<CFaxJobStatus> *pJobStatusClass = NULL; pJobStatusClass = new (std::nothrow) CComObject<CFaxJobStatus>; if (!pJobStatusClass) { //
// Out of Memory
//
CALL_FAIL(MEM_ERR, _T("new CComObject<CFaxJobStatus>"), hr); return hr; }
//
// Init the Object
//
hr = pJobStatusClass->Init(pJobStatus); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("pJobStatusClass->Init(pJobStatus)"), hr); delete pJobStatusClass; return hr; }
//
// Query the Interface from the Object
//
CComPtr<IFaxJobStatus> pFaxJobStatus = NULL; hr = pJobStatusClass->QueryInterface(IID_IFaxJobStatus, (void **) &pFaxJobStatus); if (FAILED(hr) || !pFaxJobStatus) { CALL_FAIL(GENERAL_ERR, _T("pJobStatusClass->QueryInterface(pFaxJobStatus)"), hr); delete pJobStatusClass; return hr; }
switch (place) { case IN_QUEUE: hr = Fire_OnIncomingJobChanged(this, bstrJobId, pFaxJobStatus); break; case OUT_QUEUE: hr = Fire_OnOutgoingJobChanged(this, bstrJobId, pFaxJobStatus); break; default: //
// assert (FALSE)
//
ATLASSERT(place == IN_QUEUE); hr = E_FAIL; return hr; }
if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_On In/Out JobChanged(this, bstrJobId)"), hr); return hr; } } break;
default: //
// assert (FALSE)
//
ATLASSERT(eventType == FAX_JOB_EVENT_TYPE_STATUS); hr = E_FAIL; return hr; }
return hr; }
//
//================= PROCESS MESSAGE ============================================
//
HRESULT CFaxServer::ProcessMessage( FAX_EVENT_EX *pFaxEventInfo ) /*++
Routine name : CFaxServer::ProcessMessage
Routine description:
Fire appropriate Message
Author:
Iv Garber (IvG), Jul, 2000
Arguments:
pFaxEventInfo [TBD] - Information about current Event
Return Value:
None.
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::ProcessMessage"), hr);
if (!m_faxHandle) { //
// Fax Server already disconnected
//
VERBOSE(DBG_WARNING, _T("FaxServer already disconnected.")); return hr; }
switch (pFaxEventInfo->EventType) { case FAX_EVENT_TYPE_IN_QUEUE:
ProcessJobNotification(pFaxEventInfo->EventInfo.JobInfo.dwlMessageId, pFaxEventInfo->EventInfo.JobInfo.Type, IN_QUEUE, pFaxEventInfo->EventInfo.JobInfo.pJobData); break;
case FAX_EVENT_TYPE_OUT_QUEUE:
ProcessJobNotification(pFaxEventInfo->EventInfo.JobInfo.dwlMessageId, pFaxEventInfo->EventInfo.JobInfo.Type, OUT_QUEUE, pFaxEventInfo->EventInfo.JobInfo.pJobData); break;
case FAX_EVENT_TYPE_IN_ARCHIVE:
ProcessJobNotification(pFaxEventInfo->EventInfo.JobInfo.dwlMessageId, pFaxEventInfo->EventInfo.JobInfo.Type, IN_ARCHIVE); break;
case FAX_EVENT_TYPE_OUT_ARCHIVE:
ProcessJobNotification(pFaxEventInfo->EventInfo.JobInfo.dwlMessageId, pFaxEventInfo->EventInfo.JobInfo.Type, OUT_ARCHIVE); break;
case FAX_EVENT_TYPE_CONFIG:
switch (pFaxEventInfo->EventInfo.ConfigType) { case FAX_CONFIG_TYPE_RECEIPTS: hr = Fire_OnReceiptOptionsChange(this); break; case FAX_CONFIG_TYPE_ACTIVITY_LOGGING: hr = Fire_OnActivityLoggingConfigChange(this); break; case FAX_CONFIG_TYPE_OUTBOX: hr = Fire_OnOutgoingQueueConfigChange(this); break; case FAX_CONFIG_TYPE_SENTITEMS: hr = Fire_OnOutgoingArchiveConfigChange(this); break; case FAX_CONFIG_TYPE_INBOX: hr = Fire_OnIncomingArchiveConfigChange(this); break; case FAX_CONFIG_TYPE_SECURITY: hr = Fire_OnSecurityConfigChange(this); break; case FAX_CONFIG_TYPE_EVENTLOGS: hr = Fire_OnEventLoggingConfigChange(this); break; case FAX_CONFIG_TYPE_DEVICES: hr = Fire_OnDevicesConfigChange(this); break; case FAX_CONFIG_TYPE_OUT_GROUPS: hr = Fire_OnOutboundRoutingGroupsConfigChange(this); break; case FAX_CONFIG_TYPE_OUT_RULES: hr = Fire_OnOutboundRoutingRulesConfigChange(this); break; default: //
// assert (FALSE)
//
ATLASSERT(pFaxEventInfo->EventInfo.ConfigType == FAX_CONFIG_TYPE_OUT_RULES); hr = E_FAIL; return hr; }
if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_On <...> ConfigChange(this)"), hr); return hr; } break;
case FAX_EVENT_TYPE_ACTIVITY:
hr = Fire_OnServerActivityChange(this, pFaxEventInfo->EventInfo.ActivityInfo.dwIncomingMessages, pFaxEventInfo->EventInfo.ActivityInfo.dwRoutingMessages, pFaxEventInfo->EventInfo.ActivityInfo.dwOutgoingMessages, pFaxEventInfo->EventInfo.ActivityInfo.dwQueuedMessages); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_OnServerActivityChange(this, ...)"), hr); return hr; } break;
case FAX_EVENT_TYPE_QUEUE_STATE:
hr = Fire_OnQueuesStatusChange(this, bool2VARIANT_BOOL(pFaxEventInfo->EventInfo.dwQueueStates & FAX_OUTBOX_BLOCKED), bool2VARIANT_BOOL(pFaxEventInfo->EventInfo.dwQueueStates & FAX_OUTBOX_PAUSED), bool2VARIANT_BOOL(pFaxEventInfo->EventInfo.dwQueueStates & FAX_INCOMING_BLOCKED)); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_OnQueueStatusChange(this, ...)"), hr); return hr; } break;
case FAX_EVENT_TYPE_NEW_CALL: { CComBSTR bstrCallerId = pFaxEventInfo->EventInfo.NewCall.lptstrCallerId; if (pFaxEventInfo->EventInfo.NewCall.lptstrCallerId && !bstrCallerId) { CALL_FAIL(MEM_ERR, _T("CComBSTR::operator=()"), E_OUTOFMEMORY); return hr; }
hr = Fire_OnNewCall(this, pFaxEventInfo->EventInfo.NewCall.hCall, pFaxEventInfo->EventInfo.NewCall.dwDeviceId, bstrCallerId); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_OnNewCall(this, ...)"), hr); return hr; } } break;
case FAX_EVENT_TYPE_FXSSVC_ENDED:
hr = Fire_OnServerShutDown(this); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_OnServerShutDown(this)"), hr); return hr; } break;
case FAX_EVENT_TYPE_DEVICE_STATUS:
hr = Fire_OnDeviceStatusChange(this, pFaxEventInfo->EventInfo.DeviceStatus.dwDeviceId, bool2VARIANT_BOOL(pFaxEventInfo->EventInfo.DeviceStatus.dwNewStatus & FAX_DEVICE_STATUS_POWERED_OFF), bool2VARIANT_BOOL(pFaxEventInfo->EventInfo.DeviceStatus.dwNewStatus & FAX_DEVICE_STATUS_SENDING), bool2VARIANT_BOOL(pFaxEventInfo->EventInfo.DeviceStatus.dwNewStatus & FAX_DEVICE_STATUS_RECEIVING), bool2VARIANT_BOOL(pFaxEventInfo->EventInfo.DeviceStatus.dwNewStatus & FAX_DEVICE_STATUS_RINGING)); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("Fire_OnDeviceStatusChange(this, dwDeviceId, ...)"), hr); return hr; } break;
default: //
// assert (FALSE)
//
ATLASSERT(pFaxEventInfo->EventType == FAX_EVENT_TYPE_FXSSVC_ENDED); hr = E_FAIL; return hr; }
return hr; }
//
//========== MESSAGE HANDLER FUNCTION ======================================
//
LRESULT CNotifyWindow::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) /*++
Routine name : CNotifyWindow::OnMessage
Routine description:
Get the Message and call Server's ProcessMessage.
Author:
Iv Garber (IvG), Jul, 2000
Arguments:
uMsg [in] - Msg Id wParam [in] - wParam lParam [in] - LParam bHandled [in,out] - bHandled
Return Value:
Standard result code
--*/ { DBG_ENTER(_T("CNotifyWindow::OnMessage"));
//
// Check that lParam is valid
//
if (!lParam) { CALL_FAIL(GENERAL_ERR, _T("(!lParam)"), E_FAIL); return 0; }
if (::IsBadReadPtr((FAX_EVENT_EX *)lParam, sizeof(FAX_EVENT_EX))) { CALL_FAIL(GENERAL_ERR, _T("(::IsBadReadPtr((FAX_EVENT_EX *)lParam, sizeof(FAX_EVENT_EX))"), E_FAIL); return 0; }
if (((FAX_EVENT_EX *)lParam)->dwSizeOfStruct != sizeof(FAX_EVENT_EX)) { CALL_FAIL(GENERAL_ERR, _T("(((FAX_EVENT_EX *)lParam)->dwSizeOfStruct != sizeof(FAX_EVENT_EX))"), E_FAIL); return 0; }
//
// Call Server to Process the Message
//
if (m_pServer) { HRESULT hr = S_OK; hr = m_pServer->ProcessMessage((FAX_EVENT_EX *)lParam); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("m_pServer->ProcessMessage()"), hr); } }
//
// Free the Buffer
//
FaxFreeBuffer((void *)lParam); return 0; }
//
//================ GET METHOD DATA ================================================
//
void CFaxServer::GetMethodData( /*[in]*/ BSTR bstrAllString, /*[out]*/ LPWSTR strWhereToPut ) /*++
Routine name : CFaxServer::GetMethodData
Routine description:
Read from bstrAllString data upto DELIMITER and store it in strWhereToPut. Used in GetRegisteredData for Extension Method Registration.
Author:
Iv Garber (IvG), Jul, 2000
Arguments:
bstrAllString [TBD] - in subsequent calls strWhereToPut [TBD] - where to put the value that was readed from the bstrAllString.
--*/ { BOOL bRes = TRUE; DBG_ENTER(_T("CFaxServer::GetMethodData()"));
//
// Find Method Name
//
BSTR bstrTmp; bstrTmp = _tcstok(bstrAllString, DELIMITER); if (!bstrTmp) { CALL_FAIL(MEM_ERR, _T("_tcstok(bstrAllString, DELIMITER))"), bRes); RaiseException(EXCEPTION_INVALID_METHOD_DATA, 0, 0, 0); }
//
// Check that length of the readen data
//
if (_tcslen(bstrTmp) > 100) { //
// Error : exceeds the limit
//
CALL_FAIL(GENERAL_ERR, _T("(_tcslen(bstrTmp) > 100)"), E_FAIL); RaiseException(EXCEPTION_INVALID_METHOD_DATA, 0, 0, 0); }
memcpy(strWhereToPut, bstrTmp, (sizeof(TCHAR) * (_tcslen(bstrTmp) + 1))); return; }
//
//============= GET REGISTERED DATA =========================================
//
BOOL CFaxServer::GetRegisteredData( /*[out]*/ LPWSTR MethodName, /*[out]*/ LPWSTR FriendlyName, /*[out]*/ LPWSTR FunctionName, /*[out]*/ LPWSTR Guid ) /*++
Routine name : CFaxServer::GetRegisteredData
Routine description:
Return data about specific Method being registered.
Author:
Iv Garber (IvG), Jul, 2000
Arguments:
MethodName [TBD] - Name of the Method FriendlyName [TBD] - Friendly Name of the Method FunctionName [TBD] - Function Name of the Method Guid [TBD] - GUID of the Method
Return Value:
TRUE if Method Data is filled ok, FALSE if all the methods already registered.
Notes:
The function raises an exception when any error happens.
--*/ { BOOL bRes = TRUE; DBG_ENTER(_T("CFaxServer::GetRegisteredData"), bRes);
//
// Check if we already finished the array
//
if (m_pRegMethods->rgsabound[0].cElements == m_lLastRegisteredMethod) { bRes = FALSE; CALL_FAIL(GENERAL_ERR, _T("We have reached the End of the Array"), bRes); return bRes; }
CComBSTR bstrMethodData; HRESULT hr = SafeArrayGetElement(m_pRegMethods, &m_lLastRegisteredMethod, &bstrMethodData); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("SafeArrayGetElement(m_pRegMethods, ...)"), hr); RaiseException(EXCEPTION_INVALID_METHOD_DATA, 0, 0, 0); }
GetMethodData(bstrMethodData, MethodName); GetMethodData(NULL, FriendlyName); GetMethodData(NULL, FunctionName); GetMethodData(NULL, Guid);
//
// Increase the Index of the SafeArray
//
m_lLastRegisteredMethod++; return bRes; }
//
//=================== REGISTER METHOD CALLBACK ===============================
//
BOOL CALLBACK RegisterMethodCallback( /*[in]*/ HANDLE FaxHandle, /*[in]*/ LPVOID Context, /*[out]*/ LPWSTR MethodName, /*[out]*/ LPWSTR FriendlyName, /*[out]*/ LPWSTR FunctionName, /*[out]*/ LPWSTR Guid ) { BOOL bRes = TRUE; DBG_ENTER(_T("RegisterMethodCallback"), bRes);
bRes = ((CFaxServer *)Context)->GetRegisteredData(MethodName, FriendlyName, FunctionName, Guid); return bRes; }
//
//=================== LISTEN TO SERVER EVENTS ===============================
//
STDMETHODIMP CFaxServer::ListenToServerEvents( /*[in]*/ FAX_SERVER_EVENTS_TYPE_ENUM EventTypes ) /*++
Routine name : CFaxServer::ListenToServerEvents
Routine description:
Starts or stops listening to Server Events.
Author:
Iv Garber (IvG), Jul, 2000
Arguments:
EventTypes [in] - Events to listen to.
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::ListenToServerEvents"), hr, _T("Events=%ld"), EventTypes);
//
// Check Fax Handle
//
if (m_faxHandle == NULL) { //
// Server not Connected
//
hr = E_HANDLE; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_FaxHandle == NULL"), hr); return hr; }
HANDLE hEvent = NULL; if (EventTypes > fsetNONE) { if (!m_pNotifyWindow) { //
// Create new Window
//
m_pNotifyWindow = new (std::nothrow) CNotifyWindow(this); if (!m_pNotifyWindow) { //
// Out of Memory
//
hr = E_OUTOFMEMORY; Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxServer, hr); CALL_FAIL(MEM_ERR, _T("new CNotifyWindow(this)"), hr); return hr; }
RECT rcRect; ZeroMemory(&rcRect, sizeof(rcRect));
m_pNotifyWindow->Create(NULL, rcRect, NULL, WS_POPUP, 0x0, 0); if (!::IsWindow(m_pNotifyWindow->m_hWnd)) { //
// Failed to Create Window
//
hr = E_FAIL; CALL_FAIL(GENERAL_ERR, _T("m_pNotifyWindow->Create(NULL, rcRect)"), hr); ClearNotifyWindow(); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; } }
//
// Register for new Set of Events
//
if (!FaxRegisterForServerEvents(m_faxHandle, EventTypes, NULL, 0, m_pNotifyWindow->m_hWnd, m_pNotifyWindow->GetMessageId(), &hEvent)) { //
// Failed to Register given Set of Events
//
hr = Fax_HRESULT_FROM_WIN32(GetLastError()); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxRegisterForServerEvents(m_faxHandle, lEventTypes, ...)"), hr); ClearNotifyWindow(); return hr; } }
//
// Unregister from the previous set of Events, if there was one
//
if (m_hEvent) { if (!FaxUnregisterForServerEvents(m_hEvent)) { //
// Failed to Unregister given Set of Events
//
hr = Fax_HRESULT_FROM_WIN32(GetLastError()); CALL_FAIL(GENERAL_ERR, _T("FaxUnregisterForServerEvents(m_hEvent)"), hr);
//
// Return Error only when Caller specially wanted to Unregister.
// Otherwise, debug Warning is enough.
//
if (EventTypes == fsetNONE) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); } } } //
// store the new Listening HANDLE for future UNRegistration
//
m_hEvent = hEvent; if (m_hEvent == NULL) { //
// We're not listening to any events - dismiss the hidden window
//
ClearNotifyWindow(); } m_EventTypes = EventTypes; return hr; }
//
//=================== GET REGISTERED EVENTS ===============================
//
STDMETHODIMP CFaxServer::get_RegisteredEvents( /*[out, retval]*/ FAX_SERVER_EVENTS_TYPE_ENUM *pEventTypes ) /*++
Routine name : CFaxServer::get_RegisteredEvents
Routine description:
Return Bit-Wise Combination of Events the Fax Server is Listening to
Author:
Iv Garber (IvG), Dec, 2000
Arguments:
pEventTypes [out] - the Event Types to return
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK;
DBG_ENTER(_T("CFaxServer::get_RegisteredEvents"), hr);
//
// Check the Fax Service Handle
//
if (m_faxHandle == NULL) { //
// Server not Connected
//
hr = E_HANDLE; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_FaxHandle == NULL"), hr); return hr; }
//
// Check the pointer we have got
//
if (::IsBadWritePtr(pEventTypes, sizeof(FAX_SERVER_EVENTS_TYPE_ENUM))) { //
// Got a bad return pointer
//
hr = E_POINTER; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr); return hr; }
*pEventTypes = m_EventTypes; return hr; }
//
//=================== REGISTER DEVICE PROVIDER ===============================
//
STDMETHODIMP CFaxServer::RegisterDeviceProvider( /*[in]*/ BSTR bstrGUID, /*[in]*/ BSTR bstrFriendlyName, /*[in]*/ BSTR bstrImageName, /*[in]*/ BSTR bstrTspName, /*[in]*/ long lFSPIVersion ) /*++
Routine name : CFaxServer::RegisterDeviceProvider
Routine description:
Register the FSP
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
bstrGUID [in] - GUID of the FSP bstrFriendlyName [in] - Frienly Name of the FSP bstrImageName [in] - Image Name of the FSP TspName [in] - TspName of the FSP FSPIVersion [in] - Version of the FSP interface
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::RegisterDeviceProvider"), hr, _T("GUID=%s FriendlyName=%s ImageName=%s TspNameName=%s Version=%d"), bstrGUID, bstrFriendlyName, bstrImageName, bstrTspName, lFSPIVersion);
if (m_faxHandle == NULL) { //
// Server not Connected
//
hr = E_HANDLE; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_FaxHandle == NULL"), hr); return hr; }
//
// Check if GUID is valid
//
hr = IsValidGUID(bstrGUID); if (FAILED(hr)) { CALL_FAIL(GENERAL_ERR, _T("IsValidGUID(bstrGUID)"), hr); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
//
// Register the FSP
//
if (!FaxRegisterServiceProviderEx(m_faxHandle, bstrGUID, bstrFriendlyName, bstrImageName, bstrTspName, lFSPIVersion, 0)) // capabilities
{ hr = Fax_HRESULT_FROM_WIN32(GetLastError()); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxRegisterServiceProviderEx(m_faxHandle, bstrUniqueName, ...)"), hr); return hr; }
return hr; }
//
//================= REGISTER INBOUND ROUTING EXTENSION ================================
//
STDMETHODIMP CFaxServer::RegisterInboundRoutingExtension( /*[in]*/ BSTR bstrExtensionName, /*[in]*/ BSTR bstrFriendlyName, /*[in]*/ BSTR bstrImageName, /*[in]*/ VARIANT vMethods ) /*++
Routine name : CFaxServer::RegisterInboundRoutingExtension
Routine description:
Register Inbound Routing Extension.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
bstrExtensionName [in] - Extension Name bstrFriendlyName [in] - Friendly Name bstrImageName [in] - Image Name vMethods [in] - SafeArray of the Methods Data
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::RegisterInboundRoutingExtension"), hr, _T("Name=%s Friendly=%s Image=%s"),bstrExtensionName, bstrFriendlyName, bstrImageName);
if (m_faxHandle == NULL) { //
// Server not Connected
//
hr = E_HANDLE; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_FaxHandle == NULL"), hr); return hr; }
//
// Check the Validity of the SafeArray
//
if (vMethods.vt != (VT_ARRAY | VT_BSTR)) { hr = E_INVALIDARG; Error(IDS_ERROR_METHODSNOTARRAY, IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("(vMethods.vt != VT_ARRAY | VT_BSTR)"), hr); return hr; }
m_pRegMethods = vMethods.parray; if (!m_pRegMethods) { hr = E_INVALIDARG; CALL_FAIL(GENERAL_ERR, _T("!m_pRegMethods ( = vMethods.parray )"), hr); Error(IDS_ERROR_METHODSNOTARRAY, IID_IFaxServer, hr); return hr; }
if (SafeArrayGetDim(m_pRegMethods) != 1) { hr = E_INVALIDARG; CALL_FAIL(GENERAL_ERR, _T("SafeArrayGetDim(m_pRegMethods) != 1"), hr); Error(IDS_ERROR_METHODSNOTARRAY, IID_IFaxServer, hr); return hr; }
if (m_pRegMethods->rgsabound[0].lLbound != 0) { hr = E_INVALIDARG; Error(IDS_ERROR_METHODSNOTARRAY, IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_pRegMethods->rgsabound[0].lLbound != 0"), hr); return hr; }
//
// Register the IR Extension
//
m_lLastRegisteredMethod = 0; if (!FaxRegisterRoutingExtension(m_faxHandle, bstrExtensionName, bstrFriendlyName, bstrImageName, RegisterMethodCallback, this)) { hr = Fax_HRESULT_FROM_WIN32(GetLastError()); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxRegisterRoutingExtension(m_faxHandle, bstrExtensionName, ...)"), hr); return hr; }
return hr; }
//
//========== UNREGISTER INBOUND ROUTING EXTENSION ==============================================
//
STDMETHODIMP CFaxServer::UnregisterInboundRoutingExtension( /*[in]*/ BSTR bstrExtensionUniqueName ) /*++
Routine name : CFaxServer::UnregisterExtensionUniqueName
Routine description:
Unregister the Inbound Routing Extension
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
bstrExtensionUniqueName - Unique Name of the IR Extension to Unregister
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::UnregisterInboundRoutingExtension"), hr, _T("Unique Name =%s"), bstrExtensionUniqueName);
if (m_faxHandle == NULL) { //
// Server not Connected
//
hr = E_HANDLE; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_FaxHandle == NULL"), hr); return hr; }
//
// Unregister the given Routing Extension
//
if (!FaxUnregisterRoutingExtension(m_faxHandle, bstrExtensionUniqueName)) { hr = Fax_HRESULT_FROM_WIN32(GetLastError()); CALL_FAIL(GENERAL_ERR, _T("FaxUnregisterRoutingExtension(m_faxHandle, bstrExtensionUniqueName)"), hr); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//========== UNREGISTER DEVICE PROVIDER ==============================================
//
STDMETHODIMP CFaxServer::UnregisterDeviceProvider( /*[in]*/ BSTR bstrUniqueName ) /*++
Routine name : CFaxServer::UnregisterDeviceProvider
Routine description:
Unregister the Device Provider
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
bstrUniqueName [in] - UniqueName of the Device Provider to Unregister
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::UnregisterDeviceProvider"), hr, _T("UniqueName=%s"), bstrUniqueName);
if (m_faxHandle == NULL) { //
// Server not Connected
//
hr = E_HANDLE; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_FaxHandle == NULL"), hr); return hr; }
//
// Unregister the given Device Provider
//
if (!FaxUnregisterServiceProviderEx(m_faxHandle, bstrUniqueName)) { hr = Fax_HRESULT_FROM_WIN32(GetLastError()); CALL_FAIL(GENERAL_ERR, _T("FaxUnregisterServiceProviderEx(m_faxHandle, bstrUniqueName)"), hr); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//===================== GET EXTENSION PROPERTY ===============================================
//
STDMETHODIMP CFaxServer::GetExtensionProperty( /*[in]*/ BSTR bstrGUID, /*[out, retval]*/ VARIANT *pvProperty ) /*++
Routine name : CFaxServer::GetExtensionProperty
Routine description:
Retrieves the global Extension Data from the Server.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
bstrGUID [in] -- Extension's Data GUID pvProperty [out] -- Variant with the Blob to Return
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::GetExtensionProperty()"), hr, _T("GUID=%s"), bstrGUID);
hr = ::GetExtensionProperty(this, 0, bstrGUID, pvProperty); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; };
//
//============= SET EXTENSION PROPERTY =============================
//
STDMETHODIMP CFaxServer::SetExtensionProperty( /*[in]*/ BSTR bstrGUID, /*[in]*/ VARIANT vProperty ) /*++
Routine name : CFaxServer::SetExtensionProperty
Routine description:
Stores Extension Configuration Property at Server level.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
bstrGUID [in] - GUID of the Property vProperty [in] - the Property to Store : SafeArray of Bytes
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::SetExtensionProperty()"), hr, _T("GUID=%s"), bstrGUID);
hr = ::SetExtensionProperty(this, 0, bstrGUID, vProperty); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr;
}
//
//================== GET DEBUG ==============================
//
STDMETHODIMP CFaxServer::get_Debug( /*[out, retval]*/ VARIANT_BOOL *pbDebug ) /*++
Routine name : CFaxServer::get_Debug
Routine description:
Return Whether Server is in Debug Mode.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
pbDebug [out] - the result
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::get_Debug"), hr);
if (!m_bVersionValid) { //
// get Version of the Server
//
hr = GetVersion(); if (FAILED(hr)) { return hr; } }
//
// Return the Value
//
hr = GetVariantBool(pbDebug, bool2VARIANT_BOOL((m_Version.dwFlags & FAX_VER_FLAG_CHECKED) ? true : false)); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET MINOR BUILD ==============================
//
STDMETHODIMP CFaxServer::get_MinorBuild( /*[out, retval]*/ long *plMinorBuild ) /*++
Routine name : CFaxServer::get_MinorBuild
Routine description:
Return Minor Build of the Server.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
plMinorBuild [out] - the result
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::get_MinorBuild"), hr);
if (!m_bVersionValid) { //
// get Version of the Server
//
hr = GetVersion(); if (FAILED(hr)) { return hr; } }
//
// Return the Value
//
hr = GetLong(plMinorBuild, m_Version.wMinorBuildNumber); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET MAJOR BUILD ==============================
//
STDMETHODIMP CFaxServer::get_MajorBuild( /*[out, retval]*/ long *plMajorBuild ) /*++
Routine name : CFaxServer::get_MajorBuild
Routine description:
Return Major Build of the Server.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
plMajorBuild [out] - the result
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::get_MajorBuild"), hr);
if (!m_bVersionValid) { //
// get Version of the Server
//
hr = GetVersion(); if (FAILED(hr)) { return hr; } }
//
// Return the Value
//
hr = GetLong(plMajorBuild, m_Version.wMajorBuildNumber); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET MINOR VERSION ==============================
//
STDMETHODIMP CFaxServer::get_MinorVersion( /*[out, retval]*/ long *plMinorVersion ) /*++
Routine name : CFaxServer::get_MinorVersion
Routine description:
Return Minor Version of the Server.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
plMinorVersion [out] - the result
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::get_MinorVersion"), hr);
if (!m_bVersionValid) { //
// get Version of the Server
//
hr = GetVersion(); if (FAILED(hr)) { return hr; } }
//
// Return the Value
//
hr = GetLong(plMinorVersion, m_Version.wMinorVersion); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET VERSION ==============================
//
STDMETHODIMP CFaxServer::GetVersion() { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::GetVersion"), hr);
if (m_faxHandle == NULL) { //
// Server not Connected
//
hr = E_HANDLE; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_FaxHandle == NULL"), hr); return hr; }
//
// Get Version from the Fax Server
//
ZeroMemory(&m_Version, sizeof(FAX_VERSION)); m_Version.dwSizeOfStruct = sizeof(FAX_VERSION); if (!FaxGetVersion(m_faxHandle, &m_Version)) { hr = Fax_HRESULT_FROM_WIN32(GetLastError()); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxGetVersion(m_faxHandle, &m_Version))"), hr); return hr; }
//
// Check that we have got good Version struct
//
if (m_Version.dwSizeOfStruct != sizeof(FAX_VERSION)) { hr = E_FAIL; Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("m_Version.dwSizeOfStruct != sizeof(FAX_VERSION)"), hr); return hr; } ATLASSERT(m_Version.bValid);
//
// Get API Version from the Fax Server
//
if (!FaxGetReportedServerAPIVersion(m_faxHandle, LPDWORD(&m_APIVersion))) { hr = HRESULT_FROM_WIN32(GetLastError()); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxGetReportedServerAPIVersion(m_faxHandle, &m_APIVersion))"), hr); return hr; }
//
// m_Version & m_APIVersion are valid and OK
//
m_bVersionValid = true; return hr; }
//
//================== GET MAJOR VERSION ==============================
//
STDMETHODIMP CFaxServer::get_MajorVersion( /*[out, retval]*/ long *plMajorVersion ) /*++
Routine name : CFaxServer::get_MajorVersion
Routine description:
Return Major Version of the Server.
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
plMajorVersion [out] - the result
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::get_MajorVersion"), hr);
if (!m_bVersionValid) { //
// get Version of the Server
//
hr = GetVersion(); if (FAILED(hr)) { return hr; } }
//
// Return the Value
//
hr = GetLong(plMajorVersion, m_Version.wMajorVersion); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET OUTBOUND ROUTING OBJECT ==============================
//
STDMETHODIMP CFaxServer::get_OutboundRouting( IFaxOutboundRouting **ppOutboundRouting ) /*++
Routine name : CFaxServer::get_OutboundRouting
Routine description:
Return Outbound Routing Shortcut Object
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
ppOutboundRouting [out] - the Outbound Routing Object
Return Value:
Standard HRESULT code
Notes:
FaxOutboundRouting is Contained Object, because of : a) It needs Ptr to Fax Server, to create Groups/Rules Collections each time it is asked to. b) Fax Server caches it, to allow fast dot notation ( Server.OutboundRouting.<...> )
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_OutboundRouting"), hr);
CObjectHandler<CFaxOutboundRouting, IFaxOutboundRouting> ObjectCreator; hr = ObjectCreator.GetContainedObject(ppOutboundRouting, &m_pOutboundRouting, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET DEVICES OBJECT ==============================
//
STDMETHODIMP CFaxServer::GetDevices( IFaxDevices **ppDevices ) /*++
Routine name : CFaxServer::get_Devices
Routine description:
Return Devices Collection Object
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
ppDevices [out] - the Devices Collection Object
Return Value:
Standard HRESULT code
Notes: Devices is a collection. It is not cached by the Server. Each time the function is called, the new collection is created. This enables the user to refresh the collection.
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_Devices"), hr);
CObjectHandler<CFaxDevices, IFaxDevices> ObjectCreator; hr = ObjectCreator.GetObject(ppDevices, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET DEVICE PROVIDERS OBJECT ==============================
//
STDMETHODIMP CFaxServer::GetDeviceProviders( IFaxDeviceProviders **ppDeviceProviders ) /*++
Routine name : CFaxServer::get_DeviceProviders
Routine description:
Return Device Providers Collection Object
Author:
Iv Garber (IvG), Jun, 2000
Arguments:
ppDeviceProviders [out] - the Device Providers Collection Object
Return Value:
Standard HRESULT code
Notes: Device Providers is a collection. It is not cached by the Server. Each time the function is called, the new collection is created. This enables the user to refresh the collection.
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_DeviceProviders"), hr);
CObjectHandler<CFaxDeviceProviders, IFaxDeviceProviders> ObjectCreator; hr = ObjectCreator.GetObject(ppDeviceProviders, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET INBOUND ROUTING OBJECT ==============================
//
STDMETHODIMP CFaxServer::get_InboundRouting( IFaxInboundRouting **ppInboundRouting ) /*++
Routine name : CFaxServer::get_InboundRouting
Routine description:
Return Inbound Routing Shortcut Object
Author:
Iv Garber (IvG), June, 2000
Arguments:
ppInboundRouting [out] - the Inbound Routing Object
Return Value:
Standard HRESULT code
Notes:
FaxInboundRouting is Contained Object, because of : a) It needs Ptr to Fax Server, to create Extensions/Methods Collections each time it is asked to. b) Fax Server caches it, to allow fast dot notation ( Server.InboundRouting.<...> )
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_InboundRouting"), hr);
CObjectHandler<CFaxInboundRouting, IFaxInboundRouting> ObjectCreator; hr = ObjectCreator.GetContainedObject(ppInboundRouting, &m_pInboundRouting, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET SECURITY OBJECT ==============================
//
STDMETHODIMP CFaxServer::get_Security( IFaxSecurity **ppSecurity ) /*++
Routine name : CFaxServer::get_Security
Routine description:
Return Security Object
Author:
Iv Garber (IvG), June, 2000
Arguments:
ppSecurity [out] - the Security Object
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_Security"), hr);
CObjectHandler<CFaxSecurity, IFaxSecurity> ObjectCreator; hr = ObjectCreator.GetContainedObject(ppSecurity, &m_pSecurity, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET ACTIVITY OBJECT ==============================
//
STDMETHODIMP CFaxServer::get_Activity( IFaxActivity **ppActivity ) /*++
Routine name : CFaxServer::get_Activity
Routine description:
Return Activity Object
Author:
Iv Garber (IvG), June, 2000
Arguments:
ppActivity [out] - the Activity Object
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_Activity"), hr);
CObjectHandler<CFaxActivity, IFaxActivity> ObjectCreator; hr = ObjectCreator.GetContainedObject(ppActivity, &m_pActivity, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== GET LOGGING OPTIONS OBJECT ==============================
//
STDMETHODIMP CFaxServer::get_LoggingOptions( IFaxLoggingOptions **ppLoggingOptions ) /*++
Routine name : CFaxServer::get_LoggingOptions
Routine description:
Return Logging Options Object
Author:
Iv Garber (IvG), June, 2000
Arguments:
ppLoggingOptions [out] - the Logging Options Object
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_LoggingOptions"), hr);
CObjectHandler<CFaxLoggingOptions, IFaxLoggingOptions> ObjectCreator; hr = ObjectCreator.GetContainedObject(ppLoggingOptions, &m_pLoggingOptions, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//==================== GET HANDLE =====================================
//
STDMETHODIMP CFaxServer::GetHandle( /*[out, retval]*/ HANDLE* pFaxHandle ) /*++
Routine name : CFaxServer::GetHandle
Routine description:
Return Handle to the Fax Server, if possible
Author:
Iv Garber (IvG), Apr, 2000
Arguments:
seqId [in] - the seqId of the Caller
Return Value:
HANDLE to the Fax Server
--*/ { HRESULT hr = S_OK;
DBG_ENTER (_T("CFaxServer::GetHandle"), hr);
if (::IsBadWritePtr(pFaxHandle, sizeof(HANDLE *))) { //
// Got a bad return pointer
//
hr = E_POINTER; CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr); return hr; }
*pFaxHandle = m_faxHandle; return hr;
} // CFaxServer::GetHandle
//
//==================== INTERFACE SUPPORT ERROR INFO =====================
//
STDMETHODIMP CFaxServer::InterfaceSupportsErrorInfo( REFIID riid ) /*++
Routine name : CFaxServer::InterfaceSupportsErrorInfo
Routine description:
ATL's implementation of Support Error Info
Author:
Iv Garber (IvG), Apr, 2000
Arguments:
riid [in] - Reference to the Interface
Return Value:
Standard HRESULT code
--*/ { static const IID* arr[] = { &IID_IFaxServer, &IID_IFaxFolders, // Contained object
&IID_IFaxActivity, // Contained object
&IID_IFaxSecurity, // Contained object
&IID_IFaxReceiptOptions, // Contained object
&IID_IFaxLoggingOptions, // Contained object
&IID_IFaxInboundRouting, // Contained object
&IID_IFaxOutboundRouting // Contained object
}; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE; }
//
//================== GET FOLDERS OBJECT ==============================
//
STDMETHODIMP CFaxServer::get_Folders( IFaxFolders **ppFolders ) /*++
Routine name : CFaxServer::get_Folders
Routine description:
Return Folders Shortcut Object
Author:
Iv Garber (IvG), Apr, 2000
Arguments:
pFaxFolders [out] - Fax Folders Object
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_Folders"), hr);
CObjectHandler<CFaxFolders, IFaxFolders> ObjectCreator; hr = ObjectCreator.GetContainedObject(ppFolders, &m_pFolders, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
//
//================== DISCONNECT =============================================
// {CR}
STDMETHODIMP CFaxServer::Disconnect() { HRESULT hr = S_OK;
DBG_ENTER (_T("CFaxServer::Disconnect"), hr);
if (!m_faxHandle) { return hr; }
//
// first UnListen, while we still connected
//
hr = ListenToServerEvents(fsetNONE); if (FAILED(hr)) { //
// Show the error, but continue
//
CALL_FAIL(GENERAL_ERR, _T("ListenToServerEvents(fsetNONE)"), hr); }
if (!FaxClose(m_faxHandle)) { hr = Fax_HRESULT_FROM_WIN32(GetLastError()); Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxClose()"), hr); return hr; }
m_faxHandle = NULL; m_bstrServerName.Empty(); return hr; }
//
//=================== CONNECT =======================================
//{CR}
STDMETHODIMP CFaxServer::Connect( BSTR bstrServerName ) /*++
Routine name : CFaxServer::Connect
Routine description:
Connect to the given Fax Server
Author:
Iv Garber (IvG), May, 2000
Arguments:
bstrServerName [in] - Name of the Fax Server to Connect to
Return Value:
Standard HRESULT code
--*/ { HANDLE h_tmpFaxHandle; DWORD dwServerAPIVersion; HRESULT hr = S_OK;
DBG_ENTER (_T("CFaxServer::Connect"), hr, _T("%s"), bstrServerName);
if (!FaxConnectFaxServer(m_bstrServerName, &h_tmpFaxHandle)) { //
// Failed to Connect to the Server
//
hr = Fax_HRESULT_FROM_WIN32(GetLastError()); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxConnectFaxServer()"), hr); return hr; } ATLASSERT(h_tmpFaxHandle);
//
// Get API Version from the Fax Server
//
if (!FaxGetReportedServerAPIVersion(h_tmpFaxHandle, &dwServerAPIVersion)) { hr = Fax_HRESULT_FROM_WIN32(GetLastError()); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("FaxGetReportedServerAPIVersion(h_tmpFaxHandle, &dwServerAPIVersion))"), hr); FaxClose(h_tmpFaxHandle); return hr; }
//
// Block Whistler clients from connection to BOS servers
//
if (FAX_API_VERSION_1 > dwServerAPIVersion) { hr = Fax_HRESULT_FROM_WIN32(FAX_ERR_VERSION_MISMATCH); Error(GetErrorMsgId(hr), IID_IFaxServer, hr); CALL_FAIL(GENERAL_ERR, _T("Mismatch client and server versions"), hr); FaxClose(h_tmpFaxHandle); return hr; }
if (m_faxHandle) { //
// Reconnect
//
hr = Disconnect(); if (FAILED(hr)) { //
// Failed to DisConnect from the Previous Server
//
CALL_FAIL(DBG_MSG, _T("Disconnect()"), hr); } }
m_faxHandle = h_tmpFaxHandle; m_bstrServerName = bstrServerName; return hr; }
//
//============== GET & PUT PROPERTIES ===============================
//
STDMETHODIMP CFaxServer::get_ServerName( BSTR *pbstrServerName ) /*++
Routine name : CFaxServer::get_ServerName
Routine description:
Return Name of the Server
Author:
Iv Garber (IvG), May, 2000
Arguments:
pbstrServerName [out] - Name of the Server to Return
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER(_T("CFaxServer::get_ServerName"), hr);
hr = GetBstr(pbstrServerName, m_bstrServerName); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; } return hr; }
//
//============== MAIL OPTIONS OBJECT =========================================
//
STDMETHODIMP CFaxServer::get_ReceiptOptions( IFaxReceiptOptions **ppReceiptOptions ) /*++
Routine name : CFaxServer::get_ReceiptOptions
Routine description:
Return Mail Options Object.
Author:
Iv Garber (IvG), May, 2000
Arguments:
ppReceiptOptions [out, retval] - Ptr to the place to put the object.
Return Value:
Standard HRESULT code
--*/ { HRESULT hr = S_OK; DBG_ENTER (_T("CFaxServer::get_ReceiptOptions"), hr);
CObjectHandler<CFaxReceiptOptions, IFaxReceiptOptions> ObjectCreator; hr = ObjectCreator.GetContainedObject(ppReceiptOptions, &m_pReceiptOptions, this); if (FAILED(hr)) { Error(GetErrorMsgId(hr), IID_IFaxServer, hr); return hr; }
return hr; }
|