|
|
/*++
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 ); } }
|