windows-nt/Source/XPSP1/NT/printscan/fax/admin/faxadmin/idevice.cpp

1149 lines
32 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
ilogcat.cpp
Abstract:
Internal implementation for a logging category item.
Environment:
WIN32 User Mode
Author:
Darwin Ouyang (t-darouy) 30-Sept-1997
--*/
#include "StdAfx.h"
#include "inode.h" // base class
#include "iroot.h" // root item
#include "idevice.h" // device item
#include "idevices.h" // devices folder
#include "faxcompd.h" // CFaxComponentData
#include "faxcomp.h" // CFaxComponent
#include "faxdataobj.h" // dataobject
#include "faxstrt.h" // string table
#include "ddevmain.h" // device settings
#include "droutpri.h" // route extension priority
#include "faxreg.h"
#pragma hdrstop
extern CStringTable * GlobalStringTable;
CRITICAL_SECTION CInternalDevice::csDeviceLock = {0};
// defines for context menu command ids
#define SEND_CONTEXT_ITEM 11
#define RECV_CONTEXT_ITEM 12
// defines for toolbar button command ids
#define CMD_PRI_UP 123
#define CMD_PRI_DOWN 124
// Generated with uuidgen. Each node must have a GUID associated with it.
// This one is for the main root node.
const GUID GUID_DeviceNode = /* de58ae00-4c0f-11d1-9083-00a0c90ab504 */
{
0xde58ae00,
0x4c0f,
0x11d1,
{0x90, 0x83, 0x00, 0xa0, 0xc9, 0x0a, 0xb5, 0x04}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Constructor and destructor
//
//
CInternalDevice::CInternalDevice(
IN CInternalNode * pParent,
IN CFaxComponentData * pCompData,
IN HANDLE faxHandle,
IN DWORD devID )
: CInternalNode( pParent, pCompData ),
dwDeviceId( devID ),
hFaxServer( faxHandle ),
pDeviceInfo( NULL ),
myToolBar( NULL )
/*++
Routine Description:
Constructor
Arguments:
pParent - pointer to parent node, in this case unused
pCompData - pointer to IComponentData implementation for snapin global data
Return Value:
None.
--*/
{
RetrieveNewInfo();
DebugPrint(( TEXT("CInternalDevice Created") ));
}
CInternalDevice::~CInternalDevice()
/*++
Routine Description:
Destructor
Arguments:
None.
Return Value:
None.
--*/
{
if( myToolBar != NULL ) {
myToolBar->Release();
myToolBar = NULL ;
}
DebugPrint(( TEXT("CInternalDevice Destroyed") ));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Custom Clipboard Format handlers.
//
//
// clipboard format
UINT CInternalDevice::s_cfFaxDevice = 0;
UINT CInternalDevice::s_cfFaxServerDown = 0;
#define CCF_FAX_DEVICE L"CF_FAX_DEVICE"
#define CCF_FAX_SERVER_DOWN L"CF_FAX_SERVER_DOWN"
// clipboard methods
HRESULT
CInternalDevice::DataObjectRegisterFormats()
/*++
Routine Description:
Registers the custom clipboard formats for the device node.
Arguments:
None.
Return Value:
HRESULT which indicates SUCCEEDED() or FAILED()
--*/
{
s_cfFaxDevice = RegisterClipboardFormat(CCF_FAX_DEVICE);
s_cfFaxServerDown = RegisterClipboardFormat(CCF_FAX_SERVER_DOWN);
return S_OK;
}
HRESULT
CInternalDevice::DataObjectGetDataHere(
IN FORMATETC __RPC_FAR *pFormatEtc,
IN IStream * pstm )
/*++
Routine Description:
Handles GetDataHere for custom clipboard formats specific to this
particular node.
The default implementation asserts since there should be no unhandled
formats.
Arguments:
pFormatEtc - the FORMATETC struction indicating where and what the
client is requesting
pstm - the stream to write the data to.
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
const CLIPFORMAT cf = pFormatEtc->cfFormat;
HANDLE faxHandle = ((CInternalDevices *)m_pParentINode)->faxHandle;
HRESULT hr = S_OK;
LPTSTR tstr;
BOOL temp;
assert( faxHandle != NULL );
assert( pDeviceInfo != NULL );
if( cf == s_cfFaxDevice ) {
// handle the device clipboard format
pstm->Write( &(faxHandle), sizeof(HANDLE), NULL );
pstm->Write( &(pDeviceInfo->DeviceId), sizeof(DWORD), NULL );
tstr = m_pCompData->globalRoot->GetMachine();
if( tstr != NULL ) {
pstm->Write( tstr, (MAX_COMPUTERNAME_LENGTH+1) * sizeof( TCHAR ), NULL );
} else {
pstm->Write( &tstr, sizeof( NULL ), NULL );
}
} else if( cf == s_cfFaxServerDown ) {
// handle the query server down format
temp = m_pCompData->QueryRpcError();
pstm->Write( &temp, sizeof( BOOL ), NULL );
} else {
hr = DV_E_FORMATETC;
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Mandatory CInternalNode implementations.
//
//
const GUID *
CInternalDevice::GetNodeGUID()
/*++
Routine Description:
Returns the node's associated GUID.
Arguments:
None.
Return Value:
A const pointer to a binary GUID.
--*/
{
// DebugPrint(( TEXT("Trace: CInternalDevice::GetNodeGUID") ));
return &GUID_DeviceNode;
}
const LPTSTR
CInternalDevice::GetNodeDisplayName()
/*++
Routine Description:
Returns a const TSTR pointer to the node's display name.
Arguments:
None.
Return Value:
A const pointer to a TSTR.
--*/
{
// DebugPrint(( TEXT("Trace: CInternalDevice::GetNodeDisplayName") ));
return (LPTSTR)pDeviceInfo->DeviceName;
}
const LONG_PTR
CInternalDevice::GetCookie()
/*++
Routine Description:
Returns the cookie for this node.
Arguments:
None.
Return Value:
A const long containing the cookie for the pointer,
in this case, (long)this.
--*/
{
// DebugPrint(( TEXT("Trace: CInternalDevice::GetCookie") ));
DebugPrint(( TEXT("Device Node Cookie: 0x%p"), this ));
return (LONG_PTR)this; // device node's cookie is the this pointer.
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// IComponent over-rides
//
//
HRESULT STDMETHODCALLTYPE CInternalDevice::ResultGetDisplayInfo(
IN CFaxComponent * pComp,
IN OUT RESULTDATAITEM __RPC_FAR *pResultDataItem)
/*++
Routine Description:
This routine dispatches result pane GetDisplayInfo requests to the appropriate handlers
in the mandatory implementations of the node, as well as handling special case data requests.
Arguments:
pComp - a pointer to the IComponent associated with this node.
pResultDataItem - a pointer to the RESULTDATAITEM struct which needs to be filled in.
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
// DebugPrint(( TEXT("Trace: CInternalDevice::ResultGetDisplayInfo") ));
TCHAR buffer[ 20 ];
HRESULT hr = S_OK;
ZeroMemory( (PVOID)buffer, 20 * sizeof( TCHAR ) );
assert(pResultDataItem != NULL);
do {
if( m_pCompData->QueryRpcError() == TRUE ) {
// notify the parent of the failure
((CInternalDevices *)m_pParentINode)->NotifyFailure( pComp );
hr = E_UNEXPECTED;
break;
}
if( pResultDataItem->mask & RDI_STR ) {
if( pResultDataItem->nCol == 0 ) {
hr = RetrieveNewInfo();
if( FAILED( hr ) ) {
assert( FALSE );
break;
}
pResultDataItem->str = GetNodeDisplayName();
}
if( pResultDataItem->nCol == 1 ) {
if( pDeviceInfo->Flags & FPF_SEND ) {
pResultDataItem->str = ::GlobalStringTable->GetString( IDS_YES );
} else {
pResultDataItem->str = ::GlobalStringTable->GetString( IDS_NO );
}
}
if( pResultDataItem->nCol == 2 ) {
if( pDeviceInfo->Flags & FPF_RECEIVE ) {
pResultDataItem->str = ::GlobalStringTable->GetString( IDS_YES );
} else {
pResultDataItem->str = ::GlobalStringTable->GetString( IDS_NO );
}
}
if( pResultDataItem->nCol == 3 ) {
pResultDataItem->str = (LPTSTR)pDeviceInfo->Tsid;
}
if( pResultDataItem->nCol == 4 ) {
pResultDataItem->str = (LPTSTR)pDeviceInfo->Csid;
}
if( pResultDataItem->nCol == 5 ) {
pResultDataItem->str = GetStatusString( pDeviceInfo->State );
}
if( pResultDataItem->nCol == 6 ) {
pResultDataItem->str = _itot( pDeviceInfo->Priority, buffer, 10 );
}
if( pResultDataItem->mask & RDI_IMAGE ) {
pResultDataItem->nImage = GetNodeDisplayImage();
}
}
} while( 0 );
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// IExtendContextMenu event handlers
//
//
HRESULT
STDMETHODCALLTYPE
CInternalDevice::ComponentContextMenuAddMenuItems(
IN CFaxComponent * pComp,
IN CFaxDataObject * piDataObject,
IN LPCONTEXTMENUCALLBACK piCallback,
IN OUT long __RPC_FAR *pInsertionAllowed)
/*++
Routine Description:
Adds items to the context menu.
Arguments:
pComp - a pointer to the IComponent associated with this node.
piDataObject - pointer to the dataobject associated with this node
piCallback - a pointer to the IContextMenuCallback used to insert pages
pInsertionAllowed - a set of flag indicating whether insertion is allowed.
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("Trace: CInternalDevice::ComponentContextMenuAddMenuItems") ));
CONTEXTMENUITEM menuItem;
HRESULT hr = S_OK;
if( !( *pInsertionAllowed | CCM_INSERTIONALLOWED_TOP ) ) {
assert( FALSE );
return S_OK;
}
// build the submenu items
ZeroMemory( ( void* )&menuItem, sizeof( menuItem ) );
menuItem.strName = ::GlobalStringTable->GetString( IDS_DEVICE_SEND_EN );
menuItem.strStatusBarText = ::GlobalStringTable->GetString( IDS_DEVICE_SEND_EN_DESC );
menuItem.lCommandID = SEND_CONTEXT_ITEM;
menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
if( pDeviceInfo->Flags & FPF_SEND ) {
menuItem.fFlags = MF_ENABLED | MF_CHECKED;
} else {
menuItem.fFlags = MF_ENABLED;
}
menuItem.fSpecialFlags = 0;
hr = piCallback->AddItem( &menuItem );
if( FAILED(hr) ) {
assert(FALSE);
return hr;
}
ZeroMemory( ( void* )&menuItem, sizeof( menuItem ) );
menuItem.strName = ::GlobalStringTable->GetString( IDS_DEVICE_RECV_EN );
menuItem.strStatusBarText = ::GlobalStringTable->GetString( IDS_DEVICE_RECV_EN_DESC );
menuItem.lCommandID = RECV_CONTEXT_ITEM;
menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
if( pDeviceInfo->Flags & FPF_RECEIVE ) {
menuItem.fFlags = MF_ENABLED | MF_CHECKED;
} else {
menuItem.fFlags = MF_ENABLED;
}
menuItem.fSpecialFlags = 0;
hr = piCallback->AddItem( &menuItem );
if( FAILED(hr) ) {
assert(FALSE);
return hr;
}
return hr;
}
HRESULT
STDMETHODCALLTYPE
CInternalDevice::ComponentContextMenuCommand(
IN CFaxComponent * pComp,
IN long lCommandID,
IN CFaxDataObject * piDataObject)
/*++
Routine Description:
Context menu event handler.
Arguments:
pComp - a pointer to the IComponent associated with this node.
lCommandID - the command ID
piDataObject - pointer to the dataobject associated with this node
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("Trace: CInternalDevice::ComponentContextMenuCommand") ));
HRESULT hr = S_OK;
assert( hFaxServer != NULL );
do {
// retrieve data
hr = RetrieveNewInfo();
if( FAILED( hr ) ) {
assert( FALSE );
break;
}
switch( lCommandID ) {
case SEND_CONTEXT_ITEM:
if( pDeviceInfo->Flags & FPF_SEND ) {
pDeviceInfo->Flags = pDeviceInfo->Flags & (~FPF_SEND);
} else {
pDeviceInfo->Flags = pDeviceInfo->Flags | FPF_SEND;
}
break;
case RECV_CONTEXT_ITEM:
if( pDeviceInfo->Flags & FPF_RECEIVE ) {
pDeviceInfo->Flags = pDeviceInfo->Flags & (~FPF_RECEIVE);
} else {
pDeviceInfo->Flags = pDeviceInfo->Flags | FPF_RECEIVE;
}
break;
default:
assert(FALSE);
break;
}
// commit new settings
hr = CommitNewInfo();
if( FAILED( hr ) ) {
break;
}
// fixup the service startup state
((CInternalDevices*)m_pParentINode)->CorrectServiceState();
} while( 0 );
// notify update
pComp->m_pResultData->UpdateItem( hItemID );
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// IExtendPropertySheet event handlers
//
//
HRESULT
STDMETHODCALLTYPE
CInternalDevice::ComponentPropertySheetCreatePropertyPages(
IN CFaxComponent * pComp,
IN LPPROPERTYSHEETCALLBACK lpProvider,
IN LONG_PTR handle,
IN CFaxDataObject * lpIDataObject)
/*++
Routine Description:
This routine adds device pages to the property sheet.
Arguments:
pComp - a pointer to the IComponent associated with this node.
lpProvider - a pointer to the IPropertySheetCallback used to insert pages
handle - a handle to route messages with
lpIDataobject - pointer to the dataobject associated with this node
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("Trace: CInternalDevice::ComponentPropertySheetCreatePropertyPages") ));
assert( lpIDataObject != NULL );
assert( lpProvider != NULL );
HRESULT hr;
if( lpIDataObject == NULL || lpProvider == NULL ) {
assert(FALSE);
return E_POINTER;
}
pMyPropSheet = new CFaxDeviceSettingsPropSheet( ::GlobalStringTable->GetInstance(), handle, this, pComp );
if (!pMyPropSheet) {
return(E_OUTOFMEMORY);
}
hr = lpProvider->AddPage( pMyPropSheet->GetHandle() );
return hr;
}
HRESULT
STDMETHODCALLTYPE
CInternalDevice::ComponentPropertySheetQueryPagesFor(
IN CFaxComponent * pComp,
IN CFaxDataObject * lpDataObject)
/*++
Routine Description:
The implementation of this routine returns S_OK to indicate there are
property pages to be added to the property sheet.
Arguments:
pComp - a pointer to the IComponent associated with this node.
lpDataobject - pointer to the dataobject associated with this node
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("Trace: CInternalDevice::ComponentPropertySheetQueryPagesFor") ));
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Internal Event Handlers
//
//
HRESULT
CInternalDevice::ResultOnSelect(
IN CFaxComponent* pComp,
IN CFaxDataObject * lpDataObject,
IN LPARAM arg,
IN LPARAM param)
/*++
Routine Description:
Event handler for the MMCN_SELECT message for the device node.
Arguments:
pComp - a pointer to the instance of IComponentData which this root node is associated with.
lpDataObject - a pointer to the data object containing context information for this node.
arg, param - the arguements of the message
Return Value:
HRESULT which indicates SUCCEEDED() or FAILED()
--*/
{
BOOL bScope = LOWORD( arg );
BOOL bSelect = HIWORD( arg );
if( bSelect == TRUE ) {
DebugPrint(( TEXT("++++++++++++++++++++++++++++ Device SELECT") ));
pComp->m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE );
pComp->m_pConsoleVerb->SetDefaultVerb( MMC_VERB_PROPERTIES );
} else {
DebugPrint(( TEXT("---------------------------- Device DESELECT") ));
// if the toolbar has not already been released
if( pComp->m_pControlbar != NULL ) {
pComp->m_pControlbar->Detach( myToolBar );
}
}
return S_OK;
}
HRESULT
CInternalDevice::ResultOnPropertyChange(
IN CFaxComponent* pComp,
IN CFaxDataObject * lpDataObject,
IN LPARAM arg,
IN LPARAM param)
/*++
Routine Description:
Event handler for the MMCN_PROPERTY_CHANGE message for the device node.
Arguments:
pComp - a pointer to the instance of IComponentData which this root node is associated with.
lpDataObject - a pointer to the data object containing context information for this node.
arg, param - the arguements of the message
Return Value:
HRESULT which indicates SUCCEEDED() or FAILED()
--*/
{
HRESULT hr = S_OK;
do {
hr = pComp->m_pResultData->UpdateItem( hItemID );
if( FAILED( hr ) ) {
break;
}
} while( 0 );
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// IExtendControlbar - default implementations
//
//
HRESULT
CInternalDevice::ControlBarOnBtnClick(
IN CFaxComponent* pComp,
IN CFaxDataObject * lpDataObject,
IN LPARAM param )
/*++
Routine Description:
Handles a click on a toolbar button.
Arguments:
pComp - a pointer to the IComponent associated with this node.
lpDataObject - pointer to the dataobject associated with this node
param - the parameter for the message
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("Trace: CInternalDevice::ControlBarOnBtnClick") ));
HRESULT hr = S_OK;
assert( hFaxServer != NULL );
do {
hr = RetrieveNewInfo();
if( FAILED( hr ) ) {
break;
}
switch( param ) {
case CMD_PRI_UP:
DebugPrint(( TEXT(" ******************** Increase priority") ));
if( pDeviceInfo->Priority > 1 ) {
pDeviceInfo->Priority--;
hr = CommitNewInfo();
if( FAILED( hr ) ) {
pDeviceInfo->Priority++;
break;
}
}
break;
case CMD_PRI_DOWN:
DebugPrint(( TEXT(" ******************** Decrease priority") ));
if( pDeviceInfo->Priority < 1000 ) {
pDeviceInfo->Priority++;
hr = CommitNewInfo();
if( FAILED( hr ) ) {
pDeviceInfo->Priority--;
break;
}
}
break;
}
// BUGBUG for some reason, I need to do this twice for the sort to be correctly
// done!!!! If I only do it one, the MMC sorts in reverse order for some reason?
//
// Ultimate kludge! Yuck.
//
pComp->m_pResultData->UpdateItem( hItemID );
pComp->m_pResultData->Sort( 6, 0, NULL );
pComp->m_pResultData->UpdateItem( hItemID );
pComp->m_pResultData->Sort( 6, 0, NULL );
} while( 0 );
return hr;
}
HRESULT
CInternalDevice::ControlBarOnSelect(
IN CFaxComponent* pComp,
IN LPARAM arg,
IN CFaxDataObject * lpDataObject )
/*++
Routine Description:
Adds and removes the toolbar when the node is clicked.
Arguments:
pComp - a pointer to the IComponent associated with this node.
arg - the parameter for the message
lpDataObject - pointer to the dataobject associated with this node
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
DebugPrint(( TEXT("CInternalDevice::ControlBarOnSelect") ));
BOOL bScope = (BOOL) LOWORD( arg );
BOOL bSelect = (BOOL) HIWORD( arg );
LPUNKNOWN lpUnk;
HRESULT hr = S_OK;
if( pComp == NULL ) {
assert( FALSE );
return E_POINTER;
}
MMCBUTTON buttons[] =
{
{
0,
CMD_PRI_UP,
TBSTATE_ENABLED,
TBSTYLE_BUTTON,
::GlobalStringTable->GetString( IDS_BTN_RAISE_PRI ),
::GlobalStringTable->GetString( IDS_BTN_RAISE_PRI_TOOLTIP )
},
{
1,
CMD_PRI_DOWN,
TBSTATE_ENABLED,
TBSTYLE_BUTTON,
::GlobalStringTable->GetString( IDS_BTN_LOWER_PRI ),
::GlobalStringTable->GetString( IDS_BTN_LOWER_PRI_TOOLTIP )
}
};
if( bSelect == TRUE ) {
DebugPrint(( TEXT("++++++++++++++++++++++++++++ Device Controlbar SELECT") ));
// if the controlbar hasn't already been created, create it
if( myToolBar == NULL ) {
hr = pComp->m_pControlbar->Create( TOOLBAR, pComp, &lpUnk );
if( FAILED( hr ) ) {
assert( FALSE );
return E_UNEXPECTED;
}
hr = lpUnk->QueryInterface( IID_IToolbar, (void **)&myToolBar );
if( FAILED( hr ) ) {
assert( FALSE );
return E_UNEXPECTED;
}
lpUnk->Release();
HBITMAP hbUp = LoadBitmap( ::GlobalStringTable->GetInstance(),
MAKEINTRESOURCE( IDB_UP ) );
assert( hbUp != NULL );
HBITMAP hbDown = LoadBitmap( ::GlobalStringTable->GetInstance(),
MAKEINTRESOURCE( IDB_DOWN ) );
assert( hbDown != NULL );
hr = myToolBar->AddBitmap( 1, hbUp, 16, 16, 0x00ff00ff );
if( FAILED( hr ) ) {
assert( FALSE );
return hr;
}
hr = myToolBar->AddBitmap( 1, hbDown, 16, 16, 0x00ff00ff );
if( FAILED( hr ) ) {
assert( FALSE );
return hr;
}
hr = myToolBar->AddButtons( 2, buttons );
if( FAILED( hr ) ) {
assert( FALSE );
return hr;
}
}
hr = pComp->m_pControlbar->Attach( TOOLBAR, myToolBar );
} else {
DebugPrint(( TEXT("--------------------------- Device Controlbar DESELECT") ));
// detach the toolbar
hr = pComp->m_pControlbar->Detach( myToolBar );
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Internal Functions
//
//
HRESULT
CInternalDevice::RetrieveNewInfo()
/*++
Routine Description:
Retrieves new device info.
Arguments:
None.
Return Value:
HRESULT which indicates SUCCEEDED() or FAILED()
--*/
{
HANDLE portHandle = NULL;
HRESULT hr = S_OK;
EnterCriticalSection( &csDeviceLock );
assert( hFaxServer != NULL );
try {
do {
if( m_pCompData->QueryRpcError() ) {
hr = E_UNEXPECTED;
break;
}
// open the port
if( !FaxOpenPort( hFaxServer, dwDeviceId, PORT_OPEN_QUERY, &portHandle ) ) {
if (GetLastError() != ERROR_ACCESS_DENIED) {
m_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
}
::GlobalStringTable->SystemErrorMsg( GetLastError() );
hr = E_UNEXPECTED;
break;
}
// free the existing buffer
if( pDeviceInfo != NULL ) {
FaxFreeBuffer( (PVOID) pDeviceInfo );
pDeviceInfo = NULL;
}
// get data
if( !FaxGetPort( portHandle, &pDeviceInfo ) ) {
if (GetLastError() != ERROR_ACCESS_DENIED) {
m_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
}
::GlobalStringTable->SystemErrorMsg( GetLastError() );
hr = E_UNEXPECTED;
break;
}
} while( 0 );
} catch( ... ) {
m_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
::GlobalStringTable->SystemErrorMsg( GetLastError() );
hr = E_UNEXPECTED;
}
// close port
if( portHandle != NULL ) {
FaxClose( portHandle );
}
LeaveCriticalSection( &csDeviceLock );
return hr;
}
HRESULT
CInternalDevice::CommitNewInfo()
/*++
Routine Description:
Writes out the current device state to the fax service.
Arguments:
None.
Return Value:
HRESULT which indicates SUCCEEDED() or FAILED()
--*/
{
HANDLE portHandle = NULL;
HRESULT hr = S_OK;
DWORD ec = ERROR_SUCCESS;
EnterCriticalSection( &csDeviceLock );
assert( hFaxServer != NULL );
try {
do {
if( m_pCompData->QueryRpcError() ) {
hr = E_UNEXPECTED;
break;
}
// open the port
if( !FaxOpenPort( hFaxServer, dwDeviceId, PORT_OPEN_MODIFY, &portHandle ) ) {
if (GetLastError() != ERROR_ACCESS_DENIED) {
m_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
}
::GlobalStringTable->SystemErrorMsg( GetLastError() );
hr = E_UNEXPECTED;
break;
}
// set data
if( !FaxSetPort( portHandle, pDeviceInfo ) ) {
ec = GetLastError();
if (ec != ERROR_ACCESS_DENIED && ec != ERROR_DEVICE_IN_USE) {
m_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
}
if (ec == ERROR_DEVICE_IN_USE)
::GlobalStringTable->PopUpMsg( NULL , IDS_DEVICE_INUSE, TRUE, 0 );
else
::GlobalStringTable->SystemErrorMsg( ec );
hr = E_UNEXPECTED;
break;
}
FaxClose( portHandle );
portHandle = NULL;
// See if faxstat is running
HWND hWndFaxStat = FindWindow(FAXSTAT_WINCLASS, NULL);
if (hWndFaxStat) {
if (SendMessage(hWndFaxStat, WM_FAXSTAT_MMC, (WPARAM) dwDeviceId, 0)) {
::GlobalStringTable->PopUpMsg( NULL, IDS_DEVICE_MANUALANSWER, FALSE, 0 );
}
}
} while( 0 );
} catch( ... ) {
m_pCompData->NotifyRpcError( TRUE );
assert(FALSE);
::GlobalStringTable->SystemErrorMsg( GetLastError() );
hr = E_UNEXPECTED;
}
// close port
if( portHandle != NULL ) {
FaxClose( portHandle );
}
LeaveCriticalSection( &csDeviceLock );
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Utility Functions
//
//
LPTSTR
CInternalDevice::GetStatusString(
DWORD state )
/*++
Routine Description:
Returns the correct status description given a device state.
Arguments:
state - the state of the device
Return Value:
A LPTSTR to a buffer containing the description of the state. Do not free this string.
--*/
{
int i;
int j = 1;
// this will break if the defines ever change!!
for( i = 1; i <= 25; i++ ) {
if( j & state ) {
break;
}
j = j << 1; // shift left
}
if( i <= 24 && i > 0 ) {
return ::GlobalStringTable->GetString( IDS_DEVICE_STATUS + i );
} else {
assert( FALSE );
return ::GlobalStringTable->GetString( IDS_DEVICE_STATUS_UNKNOWN );
}
}