windows-nt/Source/XPSP1/NT/printscan/fax/activefax/faxport.cpp
2020-09-26 16:20:57 +08:00

761 lines
13 KiB
C++

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
faxport.cpp
Abstract:
This module implements the port interface/object.
Author:
Wesley Witt (wesw) 20-May-1997
Revision History:
--*/
#include "stdafx.h"
#include "faxport.h"
#include "faxroute.h"
#include "status.h"
CFaxPort::CFaxPort()
{
m_pFaxServer = NULL;
m_FaxPortHandle = NULL;
m_LastFaxError = NO_ERROR;
m_DeviceId = 0;
m_Rings = 0;
m_Send = FALSE;
m_Receive = FALSE;
m_Name = NULL;
m_Csid = NULL;
m_Tsid = NULL;
m_Modify = FALSE;
}
CFaxPort::~CFaxPort()
{
if (m_FaxPortHandle) {
FaxClose( m_FaxPortHandle );
}
if (m_pFaxServer) {
m_pFaxServer->Release();
}
if (m_Name) {
SysFreeString( m_Name );
}
if (m_Csid) {
SysFreeString( m_Csid );
}
if (m_Tsid) {
SysFreeString( m_Tsid );
}
}
BOOL
CFaxPort::Initialize(
CFaxServer *i_pFaxServer,
DWORD i_DeviceId,
DWORD i_Rings,
DWORD i_Priority,
DWORD i_Flags,
LPCWSTR i_Csid,
LPCWSTR i_Tsid,
LPCWSTR i_DeviceName
)
{
HRESULT hr;
m_pFaxServer = i_pFaxServer;
m_DeviceId = i_DeviceId;
m_Rings = i_Rings;
m_Priority = i_Priority;
m_Csid = SysAllocString( i_Csid);
m_Tsid = SysAllocString( i_Tsid);
m_Name = SysAllocString( i_DeviceName );
m_Send = i_Flags & FPF_SEND;
m_Receive = i_Flags & FPF_RECEIVE;
if ((!m_Csid && i_Csid) ||
(!m_Tsid && i_Tsid) ||
(!m_Name && i_DeviceName)) {
SysFreeString( m_Csid );
SysFreeString( m_Tsid );
SysFreeString( m_Name );
return FALSE;
}
if (!m_pFaxServer) {
return FALSE;
}
hr = m_pFaxServer->AddRef();
if (FAILED(hr)) {
m_pFaxServer = NULL;
return FALSE;
}
if (!FaxOpenPort( m_pFaxServer->GetFaxHandle(), m_DeviceId, PORT_OPEN_MODIFY | PORT_OPEN_QUERY, &m_FaxPortHandle )) {
if (GetLastError() == ERROR_ACCESS_DENIED) {
if (!FaxOpenPort( m_pFaxServer->GetFaxHandle(), m_DeviceId, PORT_OPEN_QUERY, &m_FaxPortHandle )) {
m_LastFaxError = GetLastError();
return FALSE;
}
} else {
m_LastFaxError = GetLastError();
return FALSE;
}
} else {
m_Modify = TRUE;
}
return TRUE;
}
STDMETHODIMP CFaxPort::get_CanModify(BOOL * pVal)
{
if (!pVal) {
return E_POINTER;
}
__try {
*pVal = m_Modify;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
BOOL CFaxPort::ChangePort()
{
if (!m_Modify) {
return FALSE;
}
//
// get the current port configuration
//
PFAX_PORT_INFOW PortInfo = NULL;
DWORD PortInfoSize = 0;
if (!FaxGetPort( m_FaxPortHandle, &PortInfo )) {
m_LastFaxError = GetLastError();
return FALSE;
}
//
// set the values
//
PortInfo->Rings = m_Rings;
PortInfo->Priority = m_Priority;
PortInfo->Flags = (PortInfo->Flags &~ (FPF_SEND | FPF_RECEIVE)) | (m_Send ? FPF_SEND : 0) | (m_Receive ? FPF_RECEIVE : 0);
PortInfo->Csid = m_Csid;
PortInfo->Tsid = m_Tsid;
//
// change the server's port configuration
//
if (!FaxSetPort( m_FaxPortHandle, PortInfo )) {
m_LastFaxError = GetLastError();
FaxFreeBuffer( PortInfo );
return FALSE;
}
//
// clean up and bail
//
FaxFreeBuffer( PortInfo );
return TRUE;
}
STDMETHODIMP CFaxPort::get_Name(BSTR *pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy = SysAllocString(m_Name);
if (!Copy && m_Name) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString(Copy);
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::get_DeviceId(long * pVal)
{
if (!pVal) {
return E_POINTER;
}
__try {
*pVal = m_DeviceId;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::get_Rings(long * pVal)
{
if (!pVal) {
return E_POINTER;
}
__try {
*pVal = m_Rings;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::put_Rings(long newVal)
{
long old = m_Rings;
if (!m_Modify) {
return E_ACCESSDENIED;
}
m_Rings = newVal;
if (!ChangePort()) {
m_Rings = old;
return HRESULT_FROM_WIN32(m_LastFaxError);
}
return S_OK;
}
STDMETHODIMP CFaxPort::get_Csid(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy = SysAllocString(m_Csid);
if (!Copy && m_Csid) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString(Copy);
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::put_Csid(BSTR newVal)
{
BSTR old = m_Csid;
if (!m_Modify) {
return E_ACCESSDENIED;
}
BSTR tmp = SysAllocString(newVal);
if (!tmp && newVal) {
return E_OUTOFMEMORY;
}
m_Csid = tmp;
if (!ChangePort()) {
m_Csid = old;
SysFreeString(tmp);
return HRESULT_FROM_WIN32(m_LastFaxError);
}
SysFreeString(old);
return S_OK;
}
STDMETHODIMP CFaxPort::get_Tsid(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy = SysAllocString(m_Tsid);
if (!Copy && m_Tsid) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( m_Csid );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::put_Tsid(BSTR newVal)
{
BSTR old = m_Tsid;
if (!m_Modify) {
return E_ACCESSDENIED;
}
BSTR tmp = SysAllocString(newVal);
if (!tmp && newVal) {
return E_OUTOFMEMORY;
}
m_Tsid = tmp;
if (!ChangePort()) {
m_Tsid = old;
SysFreeString(tmp);
return HRESULT_FROM_WIN32(m_LastFaxError);
}
SysFreeString(old);
return S_OK;
}
STDMETHODIMP CFaxPort::get_Send(BOOL * pVal)
{
if (!pVal) {
return E_POINTER;
}
__try {
*pVal = m_Send;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::put_Send(BOOL newVal)
{
BOOL old = m_Send;
if (!m_Modify) {
return E_ACCESSDENIED;
}
m_Send = newVal;
if (!ChangePort()) {
m_Send = old;
return HRESULT_FROM_WIN32(m_LastFaxError);
}
return S_OK;
}
STDMETHODIMP CFaxPort::get_Receive(BOOL * pVal)
{
if (!pVal) {
return E_POINTER;
}
__try {
*pVal = m_Receive;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::put_Receive(BOOL newVal)
{
BOOL old = m_Receive;
if (!m_Modify) {
return E_ACCESSDENIED;
}
m_Receive = newVal;
if (!ChangePort()) {
m_Receive = old;
return HRESULT_FROM_WIN32(m_LastFaxError);
}
return S_OK;
}
STDMETHODIMP CFaxPort::get_Priority(long * pVal)
{
if (!pVal) {
return E_POINTER;
}
__try {
*pVal = m_Priority;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::put_Priority(long newVal)
{
long old = m_Priority;
if (!m_Modify) {
return E_ACCESSDENIED;
}
m_Priority = newVal;
if (!ChangePort()) {
m_Priority = old;
return HRESULT_FROM_WIN32(m_LastFaxError);
}
return S_OK;
}
STDMETHODIMP CFaxPort::GetRoutingMethods(VARIANT * retval)
{
HRESULT hr;
if (!retval) {
return E_POINTER;
}
CComObject<CFaxRoutingMethods>* p = new CComObject<CFaxRoutingMethods>;
if (!p) {
return E_OUTOFMEMORY;
}
if (!p->Init(this)) {
delete p;
return E_FAIL;
}
IDispatch* pDisp;
hr = p->QueryInterface(IID_IDispatch, (void**)&pDisp);
if (FAILED(hr)) {
delete p;
return hr;
}
__try {
VariantInit(retval);
retval->vt = VT_DISPATCH;
retval->pdispVal = pDisp;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
pDisp->Release();
delete p;
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPort::GetStatus(VARIANT * retval)
{
HRESULT hr;
if (!retval) {
return E_POINTER;
}
CComObject<CFaxStatus>* p = new CComObject<CFaxStatus>;
if (!p) {
return E_OUTOFMEMORY;
}
if (!p->Init(this)) {
delete p;
return E_FAIL;
}
IDispatch* pDisp;
hr = p->QueryInterface(IID_IDispatch, (void**)&pDisp);
if (FAILED(hr)) {
delete p;
return hr;
}
__try {
VariantInit(retval);
retval->vt = VT_DISPATCH;
retval->pdispVal = pDisp;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
pDisp->Release();
delete p;
return E_UNEXPECTED;
}
CFaxPorts::CFaxPorts()
{
m_pFaxServer = NULL;
m_LastFaxError = 0;
m_PortCount = 0;
m_VarVect = NULL;
}
CFaxPorts::~CFaxPorts()
{
if (m_pFaxServer) {
m_pFaxServer->Release();
}
if (m_VarVect) {
delete [] m_VarVect;
}
}
BOOL CFaxPorts::Init(CFaxServer *pFaxServer)
{
PFAX_PORT_INFOW PortInfo = NULL;
DWORD PortInfoSize = 0;
HRESULT hr;
//
// get the ports from the server
//
if (!pFaxServer) {
return FALSE;
}
m_pFaxServer = pFaxServer;
hr = m_pFaxServer->AddRef();
if (FAILED(hr)) {
m_pFaxServer = NULL;
return FALSE;
}
if (!FaxEnumPortsW( m_pFaxServer->GetFaxHandle(), &PortInfo, &m_PortCount )) {
m_LastFaxError = GetLastError();
return FALSE;
}
//
// enumerate the ports
//
m_VarVect = new CComVariant[m_PortCount];
if (!m_VarVect) {
m_LastFaxError = ERROR_OUTOFMEMORY;
FaxFreeBuffer( PortInfo );
return FALSE;
}
for (DWORD i=0; i<m_PortCount; i++) {
//
// create the object
//
CComObject<CFaxPort> *pFaxPort;
HRESULT hr = CComObject<CFaxPort>::CreateInstance( &pFaxPort );
if (FAILED(hr)) {
delete [] m_VarVect;
m_VarVect = NULL;
m_LastFaxError = hr;
FaxFreeBuffer( PortInfo );
return FALSE;
}
if (!pFaxPort->Initialize(
pFaxServer,
PortInfo[i].DeviceId,
PortInfo[i].Rings,
PortInfo[i].Priority,
PortInfo[i].Flags,
PortInfo[i].Csid,
PortInfo[i].Tsid,
PortInfo[i].DeviceName
))
{
delete [] m_VarVect;
m_VarVect = NULL;
m_LastFaxError = GetLastError();
FaxFreeBuffer( PortInfo );
return FALSE;
}
//
// get IDispatch pointer
//
LPDISPATCH lpDisp = NULL;
hr = pFaxPort->QueryInterface( IID_IDispatch, (void**)&lpDisp );
if (FAILED(hr)) {
delete [] m_VarVect;
m_VarVect = NULL;
m_LastFaxError = hr;
FaxFreeBuffer( PortInfo );
return FALSE;
}
//
// create a variant and add it to the collection
//
__try {
CComVariant &var = m_VarVect[i];
var.vt = VT_DISPATCH;
var.pdispVal = lpDisp;
hr = S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
hr = E_UNEXPECTED;
}
if (FAILED(hr)) {
delete [] m_VarVect;
m_VarVect = NULL;
m_LastFaxError = hr;
FaxFreeBuffer( PortInfo );
return FALSE;
}
}
FaxFreeBuffer( PortInfo );
return TRUE;
}
STDMETHODIMP CFaxPorts::get_Count(long * pVal)
{
if (!pVal) {
return E_POINTER;
}
__try {
*pVal = m_PortCount;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxPorts::get_Item(long Index, VARIANT *retval)
{
if (!retval) {
return E_POINTER;
}
if ((Index < 1) || (Index > (long) m_PortCount)) {
return E_INVALIDARG;
}
__try {
VariantInit( retval );
retval->vt = VT_UNKNOWN;
retval->punkVal = NULL;
//
// use 1-based index, VB like
//
return VariantCopy( retval, &m_VarVect[Index-1] );
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}