757 lines
23 KiB
C++
757 lines
23 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1997 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
idevices.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Internal implementation for the devices subfolder.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
WIN32 User Mode
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Darwin Ouyang (t-darouy) 30-Sept-1997
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "StdAfx.h"
|
||
|
|
||
|
#include "inode.h" // base class
|
||
|
#include "iroot.h" // iroot
|
||
|
#include "idevices.h" // devices folder
|
||
|
#include "idevice.h" // a device
|
||
|
|
||
|
#include "faxsnapin.h" // snapin
|
||
|
#include "faxdataobj.h" // dataobject
|
||
|
#include "faxstrt.h" // string table
|
||
|
|
||
|
#pragma hdrstop
|
||
|
|
||
|
extern CStringTable * GlobalStringTable;
|
||
|
|
||
|
// Generated with uuidgen. Each node must have a GUID associated with it.
|
||
|
// This one is for the devices subfolder.
|
||
|
const GUID GUID_DevicesNode = /* 03a815d8-3e9e-11d1-9075-00a0c90ab504 */
|
||
|
{
|
||
|
0x03a815d8,
|
||
|
0x3e9e,
|
||
|
0x11d1,
|
||
|
{0x90, 0x75, 0x00, 0xa0, 0xc9, 0x0a, 0xb5, 0x04}
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// Constructor and destructor
|
||
|
//
|
||
|
//
|
||
|
|
||
|
CInternalDevices::CInternalDevices(
|
||
|
CInternalNode * pParent,
|
||
|
CFaxComponentData * pCompData )
|
||
|
: CInternalNode( pParent, pCompData ),
|
||
|
pDevicesInfo( 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.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DebugPrint(( TEXT("CInternalDeviceS Created") ));
|
||
|
|
||
|
faxHandle = m_pCompData->m_FaxHandle;
|
||
|
assert( faxHandle != NULL );
|
||
|
}
|
||
|
|
||
|
CInternalDevices::~CInternalDevices( )
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Destructor
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DebugPrint(( TEXT("CInternalDeviceS Destroyed") ));
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// Mandatory CInternalNode implementations.
|
||
|
//
|
||
|
//
|
||
|
|
||
|
const GUID *
|
||
|
CInternalDevices::GetNodeGUID()
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Returns the node's associated GUID.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
A const pointer to a binary GUID.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
// DebugPrint(( TEXT("Trace: CInternalDevices::GetNodeGUID") ));
|
||
|
return &GUID_DevicesNode;
|
||
|
}
|
||
|
|
||
|
const LPTSTR
|
||
|
CInternalDevices::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: CInternalDevices::GetNodeDisplayName") ));
|
||
|
return ::GlobalStringTable->GetString( IDS_DEVICESNODENAME );
|
||
|
}
|
||
|
|
||
|
const LPTSTR
|
||
|
CInternalDevices::GetNodeDescription()
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Returns a const TSTR pointer to the node's display description.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
A const pointer to a TSTR.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
// DebugPrint(( TEXT("Trace: CInternalDevices::GetNodeDisplayName") ));
|
||
|
return ::GlobalStringTable->GetString( IDS_DEVICES_FOLDER_DESC_ROOT );
|
||
|
}
|
||
|
|
||
|
const LONG_PTR
|
||
|
CInternalDevices::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: CInternalDevices::GetCookie") ));
|
||
|
DebugPrint(( TEXT("Devices Node Cookie: 0x%p"), this ));
|
||
|
return (LONG_PTR)this; // status node's cookie is the node id.
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// Internal Event Handlers
|
||
|
//
|
||
|
//
|
||
|
|
||
|
HRESULT
|
||
|
CInternalDevices::ResultOnShow(
|
||
|
IN CFaxComponent* pComp,
|
||
|
IN CFaxDataObject * lpDataObject,
|
||
|
IN LPARAM arg,
|
||
|
IN LPARAM param)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Event handler for the MMCN_SHOW message for the devices 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()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DebugPrint(( TEXT("Trace: CInternalDevices::ResultOnShow") ));
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
unsigned int count;
|
||
|
int iResult;
|
||
|
|
||
|
LPHEADERCTRL pIHeaderCtrl;
|
||
|
|
||
|
if( m_pCompData->QueryRpcError() ) {
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
if( arg == TRUE ) { // need to display result pane
|
||
|
do {
|
||
|
// get resultdata pointer
|
||
|
pIResultData = pComp->m_pResultData;
|
||
|
assert( pIResultData );
|
||
|
if( pIResultData == NULL ) {
|
||
|
hr = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// insert the icons into the image list
|
||
|
hr = pComp->InsertIconsIntoImageList();
|
||
|
assert( SUCCEEDED( hr ) );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// set headers
|
||
|
pIHeaderCtrl = pComp->m_pHeaderCtrl;
|
||
|
|
||
|
hr = pIHeaderCtrl->InsertColumn( 0,
|
||
|
::GlobalStringTable->GetString( IDS_DEVICE_NAME ),
|
||
|
LVCFMT_LEFT,
|
||
|
MMCLV_AUTO );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = pIHeaderCtrl->InsertColumn( 1,
|
||
|
::GlobalStringTable->GetString( IDS_DEVICE_SEND_EN ),
|
||
|
LVCFMT_LEFT,
|
||
|
MMCLV_AUTO );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = pIHeaderCtrl->InsertColumn( 2,
|
||
|
::GlobalStringTable->GetString( IDS_DEVICE_RECV_EN ),
|
||
|
LVCFMT_LEFT,
|
||
|
MMCLV_AUTO );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = pIHeaderCtrl->InsertColumn( 3,
|
||
|
::GlobalStringTable->GetString( IDS_DEVICE_TSID ),
|
||
|
LVCFMT_LEFT,
|
||
|
MMCLV_AUTO );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = pIHeaderCtrl->InsertColumn( 4,
|
||
|
::GlobalStringTable->GetString( IDS_DEVICE_CSID ),
|
||
|
LVCFMT_LEFT,
|
||
|
MMCLV_AUTO );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = pIHeaderCtrl->InsertColumn( 5,
|
||
|
::GlobalStringTable->GetString( IDS_DEVICE_STATUS ),
|
||
|
LVCFMT_LEFT,
|
||
|
MMCLV_AUTO );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = pIHeaderCtrl->InsertColumn( 6,
|
||
|
::GlobalStringTable->GetString( IDS_DEVICE_PRI ),
|
||
|
LVCFMT_LEFT,
|
||
|
MMCLV_AUTO );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// this is the first time initializing the devices node
|
||
|
if( pComp->pDeviceArray == NULL ) {
|
||
|
// get fax info
|
||
|
try {
|
||
|
if( !FaxEnumPorts( faxHandle, &pDevicesInfo, &pComp->numDevices ) ) {
|
||
|
|
||
|
if (GetLastError() == ERROR_ACCESS_DENIED) {
|
||
|
::GlobalStringTable->SystemErrorMsg(ERROR_ACCESS_DENIED);
|
||
|
} else {
|
||
|
m_pCompData->NotifyRpcError( TRUE );
|
||
|
hr = m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_RETR_DEV_FAIL ),
|
||
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
||
|
MB_OK,
|
||
|
&iResult);
|
||
|
}
|
||
|
|
||
|
|
||
|
hr = E_UNEXPECTED;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
} catch( ... ) {
|
||
|
m_pCompData->NotifyRpcError( TRUE );
|
||
|
hr = m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_RETR_DEV_FAIL ),
|
||
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
||
|
MB_OK,
|
||
|
&iResult);
|
||
|
hr = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
assert( pComp->pDeviceArray == NULL );
|
||
|
|
||
|
pComp->pDeviceArray = new pCInternalDevice[pComp->numDevices];
|
||
|
if (!pComp->pDeviceArray) {
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
ZeroMemory( (void *)pComp->pDeviceArray, pComp->numDevices * sizeof( pCInternalDevice ) );
|
||
|
|
||
|
for( count = 0; count < pComp->numDevices; count ++ ) {
|
||
|
pComp->pDeviceArray[count] = new CInternalDevice( this, m_pCompData, faxHandle, pDevicesInfo[count].DeviceId );
|
||
|
if (!pComp->pDeviceArray[count]) {
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// on each display, insert each device into the devices pane
|
||
|
for( count = 0; count < pComp->numDevices; count++ ) {
|
||
|
hr = InsertItem( &pComp->pDeviceArray[count], &(pDevicesInfo[count]) );
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} while( 0 );
|
||
|
if( pDevicesInfo != NULL ) {
|
||
|
FaxFreeBuffer( (PVOID) pDevicesInfo );
|
||
|
pDevicesInfo = NULL;
|
||
|
}
|
||
|
|
||
|
if (FAILED(hr)) {
|
||
|
if (pComp->pDeviceArray) {
|
||
|
for (count = 0; count < pComp->numDevices; count++ ) {
|
||
|
if (pComp->pDeviceArray[count]) {
|
||
|
delete(pComp->pDeviceArray[count]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete(pComp->pDeviceArray);
|
||
|
pComp->pDeviceArray = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CInternalDevices::ResultOnDelete(
|
||
|
IN CFaxComponent* pComp,
|
||
|
IN CFaxDataObject * lpDataObject,
|
||
|
IN LPARAM arg,
|
||
|
IN LPARAM param)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Event handler for the MMCN_DELETE message for the devices 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.
|
||
|
pdo - a pointer to the data object associated with this node
|
||
|
arg, param - the arguements of the message
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
// unneeded because the per result view data will be deleted by destroying the
|
||
|
// CInternalComponent holding the information
|
||
|
#if 0
|
||
|
DebugPrint(( TEXT("Trace: CInternalDevices::ResultOnDelete") ));
|
||
|
|
||
|
unsigned int count;
|
||
|
|
||
|
for( count = 0; count < pComp->numDevices; count++ ) {
|
||
|
if( pComp->pDeviceArray[count] != NULL ) {
|
||
|
delete pComp->pDeviceArray[count];
|
||
|
pComp->pDeviceArray[count] = NULL;
|
||
|
}
|
||
|
}
|
||
|
delete pComp->pDeviceArray;
|
||
|
pComp->pDeviceArray = NULL;
|
||
|
#endif
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// Internal Functions
|
||
|
//
|
||
|
//
|
||
|
|
||
|
HRESULT
|
||
|
CInternalDevices::CorrectServiceState()
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Scans the devices to see if any are enabled for receive, and if so,
|
||
|
resets the service's startup state to automatic from manual. If no
|
||
|
devices are enabled for receive, then the service is set from
|
||
|
automatic to manual.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DWORD i;
|
||
|
PFAX_PORT_INFO pPortInfos = NULL;
|
||
|
DWORD portCount;
|
||
|
int iResult;
|
||
|
BOOL setAuto = FALSE;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
DebugPrint(( TEXT("Trace: CInternalDevices::CorrectServiceState") ));
|
||
|
|
||
|
do {
|
||
|
// get fax info
|
||
|
try {
|
||
|
if( m_pCompData->QueryRpcError() ) {
|
||
|
hr = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if( !FaxEnumPorts( faxHandle, &pPortInfos, &portCount ) ) {
|
||
|
if (GetLastError() == ERROR_ACCESS_DENIED) {
|
||
|
::GlobalStringTable->SystemErrorMsg(ERROR_ACCESS_DENIED);
|
||
|
} else {
|
||
|
m_pCompData->NotifyRpcError( TRUE );
|
||
|
hr = m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_RETR_DEV_FAIL ),
|
||
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
||
|
MB_OK,
|
||
|
&iResult);
|
||
|
}
|
||
|
hr = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
} catch( ... ) {
|
||
|
m_pCompData->NotifyRpcError( TRUE );
|
||
|
hr = m_pCompData->m_pConsole->MessageBox(::GlobalStringTable->GetString( IDS_FAX_RETR_DEV_FAIL ),
|
||
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
||
|
MB_OK,
|
||
|
&iResult);
|
||
|
hr = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
for( i = 0; i < portCount; i++) {
|
||
|
if( pPortInfos[i].Flags & FPF_RECEIVE ) {
|
||
|
setAuto = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetServiceState( setAuto );
|
||
|
|
||
|
} while( 0 );
|
||
|
|
||
|
if( pPortInfos != NULL ) {
|
||
|
FaxFreeBuffer( (PVOID) pPortInfos );
|
||
|
pPortInfos = NULL;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CInternalDevices::SetServiceState(
|
||
|
IN BOOL fAutomatic )
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Opens the Service Manager on the snapin's target machine, and sets
|
||
|
the fax service state according to the fAutomatic parameter.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
fAutomatic - if TRUE, sets the service to start automatically.
|
||
|
if FALSE, sets the service to start manually.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
SC_LOCK sclLock;
|
||
|
LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf;
|
||
|
TCHAR buffer[256];
|
||
|
LPTSTR str;
|
||
|
int iResult;
|
||
|
HRESULT hr = S_OK;
|
||
|
SC_HANDLE schSCManager;
|
||
|
SC_HANDLE schService;
|
||
|
|
||
|
DebugPrint(( TEXT("Trace: CInternalDevices::SetServiceState") ));
|
||
|
|
||
|
DWORD dwBytesNeeded, dwStartType;
|
||
|
|
||
|
ZeroMemory( (PVOID)buffer, sizeof( TCHAR ) * 256 );
|
||
|
|
||
|
schSCManager = OpenSCManager( ((CInternalRoot*)m_pParentINode)->GetMachine(),
|
||
|
NULL,
|
||
|
SC_MANAGER_CONNECT | SC_MANAGER_LOCK
|
||
|
| SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_ENUMERATE_SERVICE );
|
||
|
|
||
|
if( schSCManager == NULL ) {
|
||
|
::GlobalStringTable->PopUpMsg( NULL, IDS_ERR_CONNECT_SCM, TRUE, 0 );
|
||
|
assert( FALSE );
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Need to acquire database lock before reconfiguring.
|
||
|
sclLock = LockServiceDatabase(schSCManager);
|
||
|
// If the database cannot be locked, report the details.
|
||
|
if(sclLock == NULL) {
|
||
|
// Exit if the database is not locked by another process.
|
||
|
if(GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) {
|
||
|
::GlobalStringTable->PopUpMsg( NULL, IDS_ERR_LOCK_SERVICE_DB, TRUE, 0 );
|
||
|
assert( FALSE );
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
// Allocate a buffer to get details about the lock.
|
||
|
lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc( LPTR,
|
||
|
sizeof(QUERY_SERVICE_LOCK_STATUS)+256);
|
||
|
|
||
|
if(lpqslsBuf == NULL) {
|
||
|
::GlobalStringTable->PopUpMsg( NULL, IDS_OUT_OF_MEMORY, TRUE, 0 );
|
||
|
assert( FALSE );
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
do {
|
||
|
// Get and print the lock status information.
|
||
|
if(!QueryServiceLockStatus( schSCManager,
|
||
|
lpqslsBuf,
|
||
|
sizeof(QUERY_SERVICE_LOCK_STATUS)+256,
|
||
|
&dwBytesNeeded) ) {
|
||
|
::GlobalStringTable->PopUpMsg( NULL, IDS_ERR_QUERY_LOCK, TRUE, 0 );
|
||
|
assert( FALSE );
|
||
|
break;
|
||
|
}
|
||
|
if(lpqslsBuf->fIsLocked) {
|
||
|
str = ::GlobalStringTable->GetString( IDS_QUERY_LOCK );
|
||
|
_stprintf( buffer, str, lpqslsBuf->lpLockOwner, lpqslsBuf->dwLockDuration );
|
||
|
m_pCompData->m_pConsole->MessageBox( buffer,
|
||
|
::GlobalStringTable->GetString( IDS_ERR_TITLE ),
|
||
|
MB_OK,
|
||
|
&iResult);
|
||
|
} else {
|
||
|
::GlobalStringTable->PopUpMsg( NULL, IDS_ERR_LOCK_SERVICE_DB, TRUE, 0 );
|
||
|
}
|
||
|
|
||
|
} while( 0 );
|
||
|
|
||
|
LocalFree(lpqslsBuf);
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
do {
|
||
|
|
||
|
// The database is locked, so it is safe to make changes.
|
||
|
// Open a handle to the service.
|
||
|
schService = OpenService( schSCManager, // SCManager database
|
||
|
TEXT("Fax"), // name of service
|
||
|
SERVICE_CHANGE_CONFIG ); // need CHANGE access
|
||
|
if(schService == NULL) {
|
||
|
::GlobalStringTable->PopUpMsg( NULL, IDS_ERR_OPEN_SERVICE, TRUE, 0 );
|
||
|
assert( FALSE );
|
||
|
hr = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
dwStartType = (fAutomatic) ? SERVICE_AUTO_START :
|
||
|
SERVICE_DEMAND_START;
|
||
|
|
||
|
if(! ChangeServiceConfig( schService, // handle of service
|
||
|
SERVICE_NO_CHANGE, // service type: no change
|
||
|
dwStartType, // change service start type
|
||
|
SERVICE_NO_CHANGE, // error control: no change
|
||
|
NULL, // binary path: no change
|
||
|
NULL, // load order group: no change
|
||
|
NULL, // tag ID: no change
|
||
|
NULL, // dependencies: no change
|
||
|
NULL, // account name: no change
|
||
|
NULL, // password: no change
|
||
|
NULL) ) { // display string
|
||
|
::GlobalStringTable->PopUpMsg( NULL, IDS_ERR_CHANGE_SERVICE, TRUE, 0 );
|
||
|
assert( FALSE );
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
// Close the handle to the service.
|
||
|
CloseServiceHandle(schService);
|
||
|
|
||
|
} while( 0 );
|
||
|
|
||
|
// Release the database lock.
|
||
|
UnlockServiceDatabase(sclLock);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CInternalDevices::NotifyFailure(
|
||
|
CFaxComponent * pComp )
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
If there was a failure in a RPC call anywhere in the child nodes, the result
|
||
|
pane should be cleared. This function clears the result pane.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pComp - a pointer to the instance of IComponentData which this root node is associated with.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
assert( pComp != NULL );
|
||
|
assert( pComp->pDeviceArray != NULL );
|
||
|
|
||
|
pComp->m_pResultData->DeleteAllRsltItems();
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// Utility Functions
|
||
|
//
|
||
|
//
|
||
|
|
||
|
HRESULT
|
||
|
CInternalDevices::InsertItem(
|
||
|
IN CInternalDevice ** pDevice,
|
||
|
IN PFAX_PORT_INFO pDeviceInfo )
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Wrapper that inserts an item into the result view pane given some information.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pDevice - the instance of CInternalDevice to insert
|
||
|
pDeviceInfo - the information associated with that log category.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT which indicates SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
RESULTDATAITEM rdi;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
ZeroMemory( &rdi, sizeof( RESULTDATAITEM ) );
|
||
|
rdi.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
|
||
|
rdi.nCol = 0;
|
||
|
rdi.bScopeItem = FALSE;
|
||
|
rdi.lParam = (*pDevice)->GetCookie();
|
||
|
rdi.nImage = (*pDevice)->GetNodeDisplayImage();
|
||
|
rdi.str = MMC_CALLBACK;
|
||
|
|
||
|
hr = pIResultData->InsertItem( &rdi );
|
||
|
assert( SUCCEEDED( hr ) );
|
||
|
|
||
|
(*pDevice)->SetItemID( rdi.itemID );
|
||
|
return hr;
|
||
|
}
|
||
|
|