You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2050 lines
56 KiB
2050 lines
56 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 1999--2001 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// CAlertEmailConsumer.cpp
|
|
//
|
|
// Description:
|
|
// Implementation of CAlertEmailConsumer class methods
|
|
//
|
|
// [Header File:]
|
|
// CAlertEmailConsumer.h
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include <cdosys_i.c>
|
|
#include <wbemcli.h>
|
|
#include <wbemprov.h>
|
|
#include <wbemidl.h>
|
|
#include <appsrvcs.h>
|
|
#include <appmgrobjs.h>
|
|
#include <iads.h>
|
|
#include <Adshlp.h>
|
|
|
|
|
|
#include "alertemailmsg.h"
|
|
|
|
#include "CAlertEmailConsumer.h"
|
|
|
|
|
|
|
|
//
|
|
// Name of WBEM class
|
|
//
|
|
const WCHAR PROPERTY_CLASS_NAME [] = L"__CLASS";
|
|
|
|
//
|
|
// Key name of alert email's settings.
|
|
//
|
|
const WCHAR SA_ALERTEMAIL_KEYPATH [] =
|
|
L"SOFTWARE\\Microsoft\\ServerAppliance\\AlertEmail";
|
|
//
|
|
// Delimiter
|
|
//
|
|
const WCHAR DELIMITER[] = L"\\";
|
|
|
|
const WCHAR ENTER[] = L"\n";
|
|
|
|
const WCHAR COLON = L':';
|
|
|
|
const WCHAR ENDCODE = L'\0';
|
|
|
|
//
|
|
// HTTP header
|
|
//
|
|
const WCHAR HTTPHEADER[] = L"http://";
|
|
|
|
//
|
|
// SMTP Meta path
|
|
//
|
|
const WCHAR SMTP_META_PATH[] = L"IIS://LOCALHOST/SMTPSVC/1";
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// Value name of alert email's settings.
|
|
//
|
|
const WCHAR ENABLEALERTEAMIL[] = L"EnableAlertEmail";
|
|
|
|
const WCHAR SENDEMAILTYPE[] = L"SendEmailType";
|
|
|
|
const WCHAR RECEIVEREMAILADDRESS[] = L"ReceiverEmailAddress";
|
|
|
|
//
|
|
// The setting value of alert->email disabled.
|
|
//
|
|
const DWORD ALERTEMAILDISABLED = 0;
|
|
|
|
//
|
|
// Name of caption ID in alertdefinitions.
|
|
//
|
|
const WCHAR ALERTDEFINITIONCAPTIONID [] = L"CaptionRID";
|
|
|
|
//
|
|
// Name of description ID in alertdefinitions.
|
|
//
|
|
const WCHAR ALERTDEFINITIONDESCRIPTIONRID [] = L"DescriptionRID";
|
|
|
|
//
|
|
// Name of resource file in alertdefintions.
|
|
//
|
|
const WCHAR ALERTDEFINITIONSOURCE [] = L"Source";
|
|
|
|
//
|
|
// Name of alert email resource
|
|
//
|
|
const WCHAR ALERTEMAILRESOURCE[] = L"AlertEmailMsg.dll";
|
|
|
|
//
|
|
// Max value of Appliance Name
|
|
//
|
|
const DWORD MAXAPPLIANCEDNSNAME = 1024;
|
|
|
|
//
|
|
// WBEM namespace to connection to
|
|
//
|
|
const WCHAR DEFAULT_NAMESPACE[] = L"root\\MicrosoftIISv1";
|
|
|
|
//
|
|
// Query Language to use for WBEM
|
|
//
|
|
const WCHAR QUERY_LANGUAGE [] = L"WQL";
|
|
|
|
//
|
|
// WBEM query which specifies the IIS server settings we're interest in.
|
|
//
|
|
const WCHAR QUERY_STRING [] =
|
|
L"select * from IIS_WebServerSetting where servercomment=\"Administration\"";
|
|
|
|
const WCHAR SERVERBINDINGSPROP[] = L"ServerBindings";
|
|
|
|
//
|
|
// PROGID of the Element Manager
|
|
//
|
|
const WCHAR ELEMENT_RETRIEVER [] = L"Elementmgr.ElementRetriever";
|
|
|
|
//
|
|
// PROGID of the Localization Manager
|
|
//
|
|
const WCHAR LOCALIZATION_MANAGER [] = L"ServerAppliance.LocalizationManager";
|
|
|
|
//
|
|
// Type name of alert resource information.
|
|
//
|
|
const WCHAR ALERTDEFINITIONS [] = L"AlertDefinitions";
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::CAlertEmailConsumer
|
|
//
|
|
// Description:
|
|
// Class constructor.
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CAlertEmailConsumer::CAlertEmailConsumer()
|
|
{
|
|
m_cRef = 0L;
|
|
m_lCurAlertType = 0;
|
|
m_lAlertEmailDisabled = ALERTEMAILDISABLED;
|
|
|
|
m_pLocInfo = NULL;
|
|
m_pcdoIMessage = NULL;
|
|
m_pElementEnum = NULL;
|
|
|
|
m_hAlertKey = NULL;
|
|
m_hThread = NULL;
|
|
m_hCloseThreadEvent = NULL;
|
|
m_pstrFullyQualifiedDomainName = NULL;
|
|
|
|
m_pstrNetBIOSName = NULL;
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::~CAlertEmailConsumer
|
|
//
|
|
// Description:
|
|
// Class deconstructor.
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CAlertEmailConsumer::~CAlertEmailConsumer()
|
|
{
|
|
if( m_hAlertKey != NULL )
|
|
{
|
|
::RegCloseKey( m_hAlertKey );
|
|
}
|
|
|
|
if( m_pLocInfo != NULL )
|
|
{
|
|
m_pLocInfo->Release();
|
|
}
|
|
|
|
if( m_pElementEnum != NULL )
|
|
{
|
|
m_pElementEnum->Release();
|
|
}
|
|
|
|
if( m_pcdoIMessage != NULL )
|
|
{
|
|
m_pcdoIMessage->Release();
|
|
}
|
|
|
|
if( m_pstrFullyQualifiedDomainName != NULL )
|
|
{
|
|
::free( m_pstrFullyQualifiedDomainName );
|
|
}
|
|
|
|
if( m_pstrNetBIOSName != NULL )
|
|
{
|
|
::free( m_pstrNetBIOSName );
|
|
}
|
|
|
|
if( m_hThread != NULL )
|
|
{
|
|
::CloseHandle( m_hThread );
|
|
}
|
|
|
|
if( m_hCloseThreadEvent != NULL )
|
|
{
|
|
::CloseHandle( m_hCloseThreadEvent );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::QueryInterface
|
|
//
|
|
// Description:
|
|
// An method implement of IUnkown interface.
|
|
//
|
|
// Arguments:
|
|
// [in] riid Identifier of the requested interface
|
|
// [out] ppv Address of output variable that receives the
|
|
// interface pointer requested in iid
|
|
//
|
|
// Returns:
|
|
// NOERROR if the interface is supported
|
|
// E_NOINTERFACE if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CAlertEmailConsumer::QueryInterface(
|
|
IN REFIID riid,
|
|
OUT LPVOID FAR *ppv
|
|
)
|
|
{
|
|
*ppv=NULL;
|
|
|
|
if (riid == IID_IUnknown || riid == IID_IWbemUnboundObjectSink)
|
|
{
|
|
*ppv = (IWbemUnboundObjectSink *) this;
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::AddRef
|
|
//
|
|
// Description:
|
|
// increments the reference count for an interface on an object
|
|
//
|
|
// Returns:
|
|
// The new reference count.
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CAlertEmailConsumer::AddRef(void)
|
|
{
|
|
InterlockedIncrement( &m_cRef );
|
|
return m_cRef;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::Release
|
|
//
|
|
// Description:
|
|
// decrements the reference count for an interface on an object.
|
|
//
|
|
// Returns:
|
|
// The new reference count.
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CAlertEmailConsumer::Release(void)
|
|
{
|
|
InterlockedDecrement( &m_cRef );
|
|
if (0 != m_cRef)
|
|
{
|
|
return m_cRef;
|
|
}
|
|
|
|
// delete this;
|
|
BOOL bReturn;
|
|
bReturn = ::SetEvent( m_hCloseThreadEvent );
|
|
if( !bReturn )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:Release setevent error!!!"
|
|
);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::IndicateToConsumer
|
|
//
|
|
// Description:
|
|
// An method implement of IWbemUnboundObjectSink interface.
|
|
//
|
|
// Arguments:
|
|
// [in] pLogicalConsumer Pointer to the logical consumer object for
|
|
// which this set of objects is delivered.
|
|
// [in] lObjectCount Number of objects delivered in the array that
|
|
// follows.
|
|
// [in] ppObjArray Pointer to an array of IWbemClassObject
|
|
// instances which represent the events delivered.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CAlertEmailConsumer::IndicateToConsumer(
|
|
IN IWbemClassObject *pLogicalConsumer,
|
|
IN long lObjectCount,
|
|
IN IWbemClassObject **ppObjArray
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
if( m_lAlertEmailDisabled == ALERTEMAILDISABLED )
|
|
{
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
try
|
|
{
|
|
for (LONG lCount = 0; lCount < lObjectCount; lCount++)
|
|
{
|
|
|
|
|
|
//
|
|
// get the event type
|
|
//
|
|
CComVariant vtName;
|
|
hr = ppObjArray[lCount]->Get (
|
|
PROPERTY_CLASS_NAME,
|
|
0, //reserved
|
|
&vtName,
|
|
NULL, // type
|
|
NULL // flavor
|
|
);
|
|
|
|
if (FAILED (hr))
|
|
{
|
|
SATraceString(
|
|
"AlertEmail: IndicateToConsumer Get Class name failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// check if we support the event received
|
|
//
|
|
if (0 == _wcsicmp (CLASS_WBEM_RAISE_ALERT, V_BSTR (&vtName)))
|
|
{
|
|
//
|
|
// handle a raise alert event
|
|
//
|
|
hr = RaiseAlert ( ppObjArray[lCount] );
|
|
if ( FAILED (hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail: IndicateToConsumer RaiseAlert failed"
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
else if (0 == _wcsicmp (CLASS_WBEM_CLEAR_ALERT, V_BSTR (&vtName)))
|
|
{
|
|
//
|
|
// handle a clear alert
|
|
//
|
|
hr = ClearAlert ( ppObjArray[lCount] );
|
|
if ( FAILED (hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail: IndicateToConsumer ClearAlert failed"
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
} // for loop
|
|
}
|
|
catch (...)
|
|
{
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::ClearAlert
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method
|
|
// which is NOT used now.
|
|
//
|
|
// Arguments:
|
|
// [in] pObject Pointer to an IWbemClassObject instances which
|
|
// represent ClearAlert events delivered.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CAlertEmailConsumer::ClearAlert(
|
|
IN IWbemClassObject *pObject
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::RaiseAlert
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method
|
|
// which is used to send email with the alert information
|
|
// by local SMTP server.
|
|
//
|
|
// Arguments:
|
|
// [in] pObject Pointer to an IWbemClassObject instances which
|
|
// represent RaiseAlert events delivered.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CAlertEmailConsumer::RaiseAlert(
|
|
IN IWbemClassObject *pObject
|
|
)
|
|
{
|
|
LONG lAlertType;
|
|
CComVariant vtProperty;
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
//
|
|
// Get alert type.
|
|
//
|
|
hr = pObject->Get (
|
|
PROPERTY_ALERT_TYPE,
|
|
0, //reserved
|
|
&vtProperty,
|
|
NULL, // type
|
|
NULL // flavor
|
|
);
|
|
if( FAILED (hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RaiseAlert get alert type failed"
|
|
);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// Map to bitmap type definition
|
|
//
|
|
lAlertType = 1 << V_I4( &vtProperty );
|
|
|
|
if( lAlertType & m_lCurAlertType )
|
|
{
|
|
//
|
|
// It's the type user set to send mail.
|
|
//
|
|
do
|
|
{
|
|
//
|
|
// Get name of alert resource dll.
|
|
//
|
|
CComVariant vtAlertLog;
|
|
hr = pObject->Get (
|
|
PROPERTY_ALERT_LOG,
|
|
0, //reserved
|
|
&vtAlertLog,
|
|
NULL, // type
|
|
NULL // flavor
|
|
);
|
|
|
|
if( FAILED (hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RaiseAlert get alert source failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get alert ID.
|
|
//
|
|
CComVariant vtAlertID;
|
|
hr = pObject->Get (
|
|
PROPERTY_ALERT_ID,
|
|
0, //reserved
|
|
&vtAlertID,
|
|
NULL, // type
|
|
NULL // flavor
|
|
);
|
|
if( FAILED (hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RaiseAlert get alert ID failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get replace strings.
|
|
//
|
|
CComVariant vtReplaceStr;
|
|
hr = pObject->Get (
|
|
PROPERTY_ALERT_STRINGS,
|
|
0, //reserved
|
|
&vtReplaceStr,
|
|
NULL, // type
|
|
NULL // flavor
|
|
);
|
|
|
|
if( FAILED (hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RaiseAlert get alert replace string failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// We got all neccessary info,it's time to send email.
|
|
//
|
|
hr = SendMailFromResource(
|
|
V_BSTR( &vtAlertLog ),
|
|
V_I4( &vtAlertID ),
|
|
&vtReplaceStr
|
|
);
|
|
|
|
if( FAILED (hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RaiseAlert call SendMailFromResource failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
} //do
|
|
while ( FALSE );
|
|
|
|
} // if( lAlertType & m_lCurAlertType )
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::SendMailFromResource
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to get useful message about the alert from Local Manager and send
|
|
// mail with the messages.
|
|
//
|
|
// Arguments:
|
|
// [in] lpszSource Point to the name of alert resource.
|
|
// [in] lSourceID Alert ID.
|
|
// [in] pvtReplaceStr Point to array of replace strings.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CAlertEmailConsumer::SendMailFromResource(
|
|
LPWSTR lpszSource,
|
|
LONG lSourceID,
|
|
VARIANT* pvtReplaceStr
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
WCHAR wstrAlertItem[MAX_PATH];
|
|
IWebElement* pWebElement;
|
|
IDispatch* pDispatch;
|
|
|
|
//
|
|
// Format the alert item name:
|
|
// Name = AlertDefinitions<AlertLog><AlertID>
|
|
//
|
|
::wsprintf( wstrAlertItem, L"AlertDefinitions%s%lX", lpszSource,lSourceID );
|
|
//int cchWritten = _snwprintf( wstrAlertItem, MAX_PATH, L"AlertDefinitions%s%lX",
|
|
// lpszSource, lSourceID );
|
|
//if ( cchWritten >= MAX_PATH || cchWritten < 0 )
|
|
//{
|
|
// return E_INVALIDARG;
|
|
//}
|
|
|
|
|
|
do
|
|
{
|
|
//
|
|
// Get the element of alert definition from element manager.
|
|
//
|
|
hr = m_pElementEnum->Item(
|
|
&CComVariant( wstrAlertItem ),
|
|
&pDispatch
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource find alert item failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
hr = pDispatch->QueryInterface(
|
|
__uuidof (IWebElement),
|
|
reinterpret_cast <PVOID*> (&pWebElement)
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource queryinterface failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// allocate BSTR for alertdefintion source
|
|
//
|
|
CComBSTR bstrAlertDefinitionSourceName (ALERTDEFINITIONSOURCE);
|
|
if (NULL == bstrAlertDefinitionSourceName.m_str)
|
|
{
|
|
SATraceString ("AlertEmail::SendMailFromResouce failed on SysAllocString (ALERTDEFINTIONSOURCE)");
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
//Get name of alert's resource dll.
|
|
// AlertLog != AlertSource now! -- 2001/02/07 i-xingj
|
|
//
|
|
CComVariant vtAlertSource;
|
|
hr = pWebElement->GetProperty (
|
|
bstrAlertDefinitionSourceName,
|
|
&vtAlertSource
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource get Alert source failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// allocate BSTR for DesinitionCaptionID string
|
|
//
|
|
CComBSTR bstrAlertDefinitionCaptionIDName (ALERTDEFINITIONCAPTIONID);
|
|
if (NULL == bstrAlertDefinitionCaptionIDName.m_str)
|
|
{
|
|
SATraceString ("AlertEmail::SendMailFromResouce failed on SysAllocString (ALERTDEFINTIONCAPTIONID)");
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get caption ID string
|
|
//
|
|
CComVariant vtCaptionID;
|
|
hr = pWebElement->GetProperty (
|
|
bstrAlertDefinitionCaptionIDName,
|
|
&vtCaptionID
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource find alert captionID failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// allocate BSTR for AlertDescription RID
|
|
//
|
|
CComBSTR bstrAlertDefinitionDescriptionRIDName (ALERTDEFINITIONDESCRIPTIONRID);
|
|
if (NULL == bstrAlertDefinitionDescriptionRIDName.m_str)
|
|
{
|
|
SATraceString ("AlertEmail::SendMailFromResouce failed on SysAllocString (ALERTDEFINITIONDESCRIPTIONRID)");
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get description ID string
|
|
//
|
|
CComVariant vtDescriptionID;
|
|
hr = pWebElement->GetProperty (
|
|
bstrAlertDefinitionDescriptionRIDName,
|
|
&vtDescriptionID
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource get alert descriptionID failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
|
|
LONG lAlertCaptionID;
|
|
LONG lAlertDescriptionID;
|
|
|
|
//
|
|
// Change type from string to long.
|
|
//
|
|
if ( EOF == ::swscanf( V_BSTR( &vtCaptionID ), L"%X", &lAlertCaptionID ))
|
|
{
|
|
SATraceString( "AlertEmail:SendMailFromResource get caption invalid" );
|
|
break;
|
|
}
|
|
if ( EOF == ::swscanf( V_BSTR( &vtDescriptionID ), L"%X", &lAlertDescriptionID ))
|
|
{
|
|
SATraceString( "AlertEmail:SendMailFromResource get description invalid" );
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get caption string from resource as email's subject.
|
|
//
|
|
CComBSTR pszSubject;
|
|
hr = m_pLocInfo->GetString(
|
|
V_BSTR( &vtAlertSource ),
|
|
lAlertCaptionID,
|
|
pvtReplaceStr,
|
|
&pszSubject
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource get subjuct failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get description string from resource as email's message.
|
|
//
|
|
CComBSTR pszMessage;
|
|
hr = m_pLocInfo->GetString(
|
|
V_BSTR( &vtAlertSource ),
|
|
lAlertDescriptionID,
|
|
pvtReplaceStr,
|
|
&pszMessage
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource get message failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// allocate BSTR for email source
|
|
//
|
|
CComBSTR bstrAlertEmailResourceName (ALERTEMAILRESOURCE);
|
|
if (NULL == bstrAlertEmailResourceName.m_str)
|
|
{
|
|
SATraceString ("AlertEmail::SendMailFromResouce failed on SysAllocString (ALERTEMAILRESOURCE)");
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get alert email defined message.
|
|
//
|
|
CComBSTR pszConstantMessage;
|
|
hr = m_pLocInfo->GetString(
|
|
bstrAlertEmailResourceName,
|
|
SA_ALERTEMAIL_SETTINGS_EMAIL_CONTENT,
|
|
NULL,
|
|
&pszConstantMessage
|
|
);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMailFromResource get constantMsg failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
pszMessage += CComBSTR( ENTER );
|
|
pszMessage += CComBSTR( ENTER );
|
|
pszMessage += pszConstantMessage;
|
|
|
|
//
|
|
// Send mail use local SMTP server.
|
|
//
|
|
hr = SendMail( pszSubject, pszMessage );
|
|
|
|
} //do
|
|
while( FALSE );
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::Initialize
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class public method call by
|
|
// CAlertEmailConsumerProvider to initialize useful parameters.
|
|
//
|
|
// Returns:
|
|
// S_OK if successful
|
|
// E_FAIL if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CAlertEmailConsumer::Initialize()
|
|
{
|
|
ULONG ulReturn;
|
|
HRESULT hr = S_OK;
|
|
DWORD dwThreadID;
|
|
|
|
//
|
|
// Initialize Element Manager.
|
|
//
|
|
hr = InitializeElementManager();
|
|
if (FAILED (hr))
|
|
{
|
|
SATraceString(
|
|
"AlertEmailProvider:Initialize InitializeElementManager failed"
|
|
);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
//
|
|
// Initialize Local Manager
|
|
//
|
|
hr = InitializeLocalManager();
|
|
if (FAILED (hr))
|
|
{
|
|
SATraceString(
|
|
"AlertEmailProvider:Initialize InitializeLocalManager failed"
|
|
);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
//
|
|
// Initialize a CDO IMessage interface.
|
|
//
|
|
hr = InitializeCDOMessage();
|
|
if (FAILED (hr))
|
|
{
|
|
SATraceString(
|
|
"AlertEmailProvider:Initialize InitializeCDOMessage failed"
|
|
);
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
//
|
|
// Open registry key of alertemail settings.
|
|
//
|
|
ulReturn = ::RegOpenKey(
|
|
HKEY_LOCAL_MACHINE,
|
|
SA_ALERTEMAIL_KEYPATH,
|
|
&m_hAlertKey
|
|
);
|
|
if( ulReturn != ERROR_SUCCESS )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:Initialize OpenKey failed"
|
|
);
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Get alert email settings from registry.
|
|
//
|
|
if( FALSE == RetrieveRegInfo() )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:Initialize RetrieveRegInfo failed"
|
|
);
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Get server name fully qualified domain anem.
|
|
//
|
|
if( FALSE == GetComputerName( &m_pstrFullyQualifiedDomainName, ComputerNameDnsFullyQualified ) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:Initialize GetComputerName ComputerNameDnsFullyQualified failed"
|
|
);
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Get server name.
|
|
//
|
|
if( FALSE == GetComputerName( &m_pstrNetBIOSName, ComputerNameNetBIOS ) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:Initialize GetComputerName ComputerNameNetBIOS failed"
|
|
);
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
//
|
|
// Event for notify thread exit.
|
|
//
|
|
m_hCloseThreadEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
|
|
if( m_hCloseThreadEvent == NULL )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:Initialize CreateEvent failed"
|
|
);
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Thread used to monitor registy change.
|
|
//
|
|
m_hThread = ::CreateThread( 0,
|
|
0,
|
|
CAlertEmailConsumer::RegThreadProc,
|
|
this,
|
|
0,
|
|
&dwThreadID );
|
|
if( m_hThread == NULL )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:Initialize CreateThread failed"
|
|
);
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::GetSMTPFromDomainName
|
|
//
|
|
// Description:
|
|
// Get the value of "Full Qualified Domain Name" entry in SMTP Delivery tab in MMC.
|
|
//
|
|
// Arguments:
|
|
// [out] bstrDomainName returns domain name that is found in Metabase.
|
|
//
|
|
// Returns:
|
|
// hr
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CAlertEmailConsumer::GetSMTPFromDomainName( BSTR* bstrDomainName )
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IADs> pADs;
|
|
|
|
//
|
|
// Initialize for return
|
|
//
|
|
*bstrDomainName = NULL;
|
|
|
|
CComBSTR bstrADSPath( SMTP_META_PATH );
|
|
if (NULL == bstrADSPath.m_str)
|
|
{
|
|
SATraceString ("CAlertEmailConsumer::GetSMTPFromDomainName failed to allocate memory for bstrADsPath");
|
|
return (E_OUTOFMEMORY);
|
|
}
|
|
|
|
hr = ADsGetObject( bstrADSPath, IID_IADs, (void**) &pADs );
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
CComVariant varValue;
|
|
CComBSTR bstrFullyQualifiedDomainName (L"FullyQualifiedDomainName" );
|
|
if (NULL == bstrFullyQualifiedDomainName.m_str)
|
|
{
|
|
SATraceString ("CAlertEmailConsumer::GetSMTPFromDomainName failed to allocate memory for bstrFullyQualifiedDomainName");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
// Getting the FullyQualifiedDomainName property
|
|
hr = pADs->Get(bstrFullyQualifiedDomainName, &varValue );
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
*bstrDomainName = SysAllocString( V_BSTR( &varValue ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::SendMail
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to send mail through local SMTP server.
|
|
//
|
|
// Arguments:
|
|
// [in] bstrSubject Subject string.
|
|
// [in] bstrMessage Message string.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CAlertEmailConsumer::SendMail(
|
|
BSTR bstrSubject,
|
|
BSTR bstrMessage
|
|
)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
WCHAR* pstrPort = NULL;
|
|
do
|
|
{
|
|
|
|
|
|
//
|
|
// The algorithm is
|
|
// Look at the value of "Full Qualified Domain Name" entry in SMTP Delivery tab in MMC.
|
|
// 1) If the value is empty then the e-mail From Address is same as fully qualified domain name
|
|
// 2) IF there is value and that value is different from Full Qualified Computer Name then use
|
|
// 3) the following as From address.
|
|
// 4) Use the From Address as appliance_name@"Full Qualified Domain Name"
|
|
//
|
|
//
|
|
|
|
//
|
|
// allocate memory for BSTR
|
|
//
|
|
CComBSTR bstrFullyQualifiedDomainName( m_pstrFullyQualifiedDomainName );
|
|
if (NULL == bstrFullyQualifiedDomainName.m_str)
|
|
{
|
|
SATraceString("AlertEmail:SendMail failed to allocate memory for bstrFullyQualifiedDomainName" );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
CComBSTR bstrFromAddress( m_pstrNetBIOSName );
|
|
if (NULL == bstrFromAddress.m_str)
|
|
{
|
|
SATraceString("AlertEmail:SendMail failed to allocate memory for bstrFromAddress" );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
BSTR bstrDomainName = NULL;
|
|
|
|
//
|
|
// Read SMTP "Full Qualified Domain Name" from Metabase
|
|
hr = GetSMTPFromDomainName( &bstrDomainName );
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail GetSMTPFromDomainName failed"
|
|
);
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
if ( bstrDomainName )
|
|
{
|
|
if ( _wcsicmp( bstrFullyQualifiedDomainName, bstrDomainName ) != 0 )
|
|
{
|
|
bstrFromAddress += CComBSTR( L"@" );
|
|
bstrFromAddress += bstrDomainName ;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Set bstrFromAddress that is formed using the above algorithm
|
|
// as mail sender.
|
|
//
|
|
hr = m_pcdoIMessage->put_From( bstrFromAddress );
|
|
|
|
//
|
|
// Free BSTR
|
|
//
|
|
if ( bstrDomainName )
|
|
{
|
|
SysFreeString( bstrDomainName );
|
|
}
|
|
|
|
CComBSTR bstrMailAddress (m_pstrMailAddress );
|
|
if (NULL == bstrMailAddress.m_str)
|
|
{
|
|
SATraceString("AlertEmail:SendMail failed to allocate memory for bstrMailAddress" );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set mail address.
|
|
//
|
|
hr = m_pcdoIMessage->put_To( bstrMailAddress);
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail put_To failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set mail subject.
|
|
//
|
|
hr = m_pcdoIMessage->put_Subject( bstrSubject );
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail put_Subject failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get text bodypart from the message object.
|
|
//
|
|
CComPtr<IBodyPart> pMsgBodyPart;
|
|
hr = m_pcdoIMessage->get_BodyPart( &pMsgBodyPart );
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail get_TextBodyPart failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get current char set from localize manager.
|
|
//
|
|
CComBSTR bstrCharSet;
|
|
hr = m_pLocInfo->get_CurrentCharSet( &bstrCharSet );
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail get_CurrentCharSet failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set char set to text bodypart with current char set.
|
|
//
|
|
// TMARSH: Hardcode charset to UTF-8.
|
|
hr = pMsgBodyPart->put_Charset( CComBSTR(L"utf-8") );
|
|
// hr = pMsgBodyPart->put_Charset( bstrCharSet );
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail put_CharSet failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
CComBSTR bstrExtendMessage;
|
|
bstrExtendMessage.AppendBSTR( bstrMessage );
|
|
/* bstrExtendMessage += CComBSTR( ENTER );
|
|
bstrExtendMessage += CComBSTR( HTTPHEADER );
|
|
bstrExtendMessage += CComBSTR( m_pstrApplianceName );
|
|
|
|
hr = GetAppliancePort( &pstrPort );
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
bstrExtendMessage += CComBSTR( pstrPort );
|
|
}
|
|
else
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail GetAppliancePort failed"
|
|
);
|
|
}
|
|
*/
|
|
//
|
|
// Set mail message.
|
|
//
|
|
hr = m_pcdoIMessage->put_TextBody( bstrExtendMessage );
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:SendMail put_TextBody failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Send it.
|
|
//
|
|
hr = m_pcdoIMessage->Send();
|
|
|
|
}while( FALSE );
|
|
|
|
if( pstrPort!= NULL )
|
|
{
|
|
::free( pstrPort );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::GetFullyQualifiedDomainName
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to get local appliance name in DNS format.
|
|
//
|
|
// Arguments:
|
|
// [in,out] pstrComputerName Pointer of computer name string.
|
|
//
|
|
// Returns:
|
|
// TRUE if successful
|
|
// FALSE if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
CAlertEmailConsumer::GetComputerName(
|
|
LPWSTR* pstrComputerName,
|
|
COMPUTER_NAME_FORMAT nametype
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
DWORD dwSize = 0;
|
|
DWORD dwCount = 1;
|
|
|
|
do
|
|
{
|
|
if( *pstrComputerName != NULL )
|
|
{
|
|
::free( *pstrComputerName );
|
|
}
|
|
|
|
dwSize = MAXAPPLIANCEDNSNAME * dwCount;
|
|
|
|
*pstrComputerName = ( LPWSTR ) ::malloc( sizeof(WCHAR) * dwSize );
|
|
if( *pstrComputerName == NULL )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetApplianceName malloc failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get local computer name.
|
|
//
|
|
bReturn = ::GetComputerNameEx(
|
|
nametype,
|
|
*pstrComputerName,
|
|
&dwSize
|
|
);
|
|
|
|
dwCount <<= 1;
|
|
}
|
|
while( !bReturn &&
|
|
ERROR_MORE_DATA == ::GetLastError() &&
|
|
dwCount < 32
|
|
);
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::GetAppliancePort
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to get local appliance port.
|
|
//
|
|
// Arguments:
|
|
// [in,out] pstrPort Pointer of server port string.
|
|
//
|
|
// Returns:
|
|
// TRUE if successful
|
|
// FALSE if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CAlertEmailConsumer::GetAppliancePort(
|
|
LPWSTR* pstrPort
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try
|
|
{
|
|
do
|
|
{
|
|
|
|
CComPtr <IWbemLocator> pWbemLocator;
|
|
CComPtr <IWbemServices> pWbemServices;
|
|
CComPtr <IEnumWbemClassObject> pEnumServices;
|
|
|
|
//
|
|
// create the WBEM locator object
|
|
//
|
|
hr = ::CoCreateInstance (
|
|
CLSID_WbemLocator,
|
|
0, //aggregation pointer
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemLocator,
|
|
(PVOID*) &pWbemLocator
|
|
);
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort CoCreateInstance failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// allocate memory for BSTR
|
|
//
|
|
CComBSTR bstrDefaultNameSpace (DEFAULT_NAMESPACE);
|
|
if (NULL == bstrDefaultNameSpace.m_str)
|
|
{
|
|
SATraceString("AlertEmail:GetAppliancePort failed to allocate memory for DEFAULT_NAMESPACE" );
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// connect to WMI
|
|
//
|
|
hr = pWbemLocator->ConnectServer (
|
|
bstrDefaultNameSpace,
|
|
NULL, //user-name
|
|
NULL, //password
|
|
0, //current-locale
|
|
0, //reserved
|
|
NULL, //authority
|
|
NULL, //context
|
|
&pWbemServices
|
|
);
|
|
if( hr != WBEM_S_NO_ERROR )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort ConnectServer failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Query Web server instance.
|
|
//
|
|
hr = pWbemServices->ExecQuery(
|
|
CComBSTR( QUERY_LANGUAGE ),
|
|
CComBSTR( QUERY_STRING ),
|
|
0,
|
|
NULL,
|
|
&pEnumServices
|
|
);
|
|
if( hr != WBEM_S_NO_ERROR )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort ExecQuery failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
CComPtr <IWbemClassObject> pService;
|
|
ULONG uReturned;
|
|
|
|
//
|
|
// Now,we only care for the first match.
|
|
//
|
|
hr = pEnumServices->Next(
|
|
WBEM_NO_WAIT,
|
|
1,
|
|
&pService,
|
|
&uReturned
|
|
);
|
|
if( hr != WBEM_S_NO_ERROR )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort nothing found"
|
|
);
|
|
break;
|
|
}
|
|
|
|
CComVariant vtServerBindings;
|
|
|
|
//
|
|
// Get the "ServerBindings" property.
|
|
//
|
|
hr = pService->Get(
|
|
CComBSTR( SERVERBINDINGSPROP ),
|
|
0,
|
|
&vtServerBindings,
|
|
0,
|
|
0
|
|
);
|
|
if ( FAILED(hr) || !V_ISARRAY( &vtServerBindings ) )
|
|
{
|
|
hr = E_FAIL;
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort get serverbindings failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
SAFEARRAY* psa;
|
|
BSTR HUGEP *pbstr;
|
|
|
|
//
|
|
// The property type is VT_ARRAY | VT_BSTR.
|
|
//
|
|
psa = V_ARRAY( &vtServerBindings );
|
|
if( psa->cDims <= 0 )
|
|
{
|
|
hr = E_FAIL;
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort array dim error"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Access array data directly,it's a faster way.
|
|
//
|
|
hr = ::SafeArrayAccessData( psa, ( void HUGEP** )&pbstr );
|
|
if (FAILED(hr))
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort SafeArrayAccessData failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Now we can alloc the port string.
|
|
//
|
|
*pstrPort = ( LPWSTR )malloc( sizeof(WCHAR) * MAX_COMPUTERNAME_LENGTH );
|
|
if( *pstrPort == NULL )
|
|
{
|
|
hr = E_FAIL;
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort malloc failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
WCHAR* pszTemp1;
|
|
WCHAR* pszTemp2;
|
|
|
|
pszTemp1 = ::wcschr( pbstr[0], COLON );
|
|
pszTemp2 = ::wcsrchr( pbstr[0], COLON );
|
|
|
|
if( pszTemp2 != NULL && pszTemp1 != NULL )
|
|
{
|
|
pszTemp2[0] = ENDCODE;
|
|
::wcscpy( *pstrPort, pszTemp1 );
|
|
}
|
|
else
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort string formate error"
|
|
);
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
::SafeArrayUnaccessData( psa );
|
|
}
|
|
while( false );
|
|
}
|
|
catch (...)
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:GetAppliancePort unkown exception"
|
|
);
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::RetrieveRegInfo
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to retrieve alert email settings from registry.
|
|
//
|
|
// Returns:
|
|
// TRUE if successful
|
|
// FALSE if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
CAlertEmailConsumer::RetrieveRegInfo()
|
|
{
|
|
BOOL bReturn = TRUE;
|
|
LONG lReturn;
|
|
DWORD dwDataSize;
|
|
|
|
//
|
|
// Get the email address will be send to.
|
|
//
|
|
dwDataSize = sizeof(m_pstrMailAddress);
|
|
lReturn = ::RegQueryValueEx(
|
|
m_hAlertKey,
|
|
RECEIVEREMAILADDRESS,
|
|
NULL,
|
|
NULL,
|
|
reinterpret_cast<PBYTE>(m_pstrMailAddress),
|
|
&dwDataSize );
|
|
if( lReturn != ERROR_SUCCESS)
|
|
{
|
|
m_pstrMailAddress[0] = L'\0'; // RegQueryValueEx doesn't guarantee
|
|
// a desirable value, so clear the string.
|
|
SATraceString(
|
|
"AlertEmail:RetrieveRegInfo query address failed"
|
|
);
|
|
bReturn = FALSE;
|
|
}
|
|
else
|
|
{
|
|
_ASSERT(dwDataSize <= sizeof(m_pstrMailAddress));
|
|
|
|
//
|
|
// Validate the e-mail address length.
|
|
//
|
|
LONG lLastCharacter;
|
|
if( sizeof( m_pstrMailAddress[0] ) > dwDataSize )
|
|
{
|
|
lLastCharacter = 0;
|
|
}
|
|
else
|
|
{
|
|
lLastCharacter = dwDataSize / sizeof( m_pstrMailAddress[0] ) - 1;
|
|
}
|
|
|
|
if( sizeof(m_pstrMailAddress) == dwDataSize &&
|
|
L'\0' != m_pstrMailAddress[lLastCharacter] )
|
|
{
|
|
SATraceString( "AlertEmail:RetrieveRegInfo address too long" );
|
|
bReturn = FALSE;
|
|
}
|
|
m_pstrMailAddress[lLastCharacter] = L'\0';
|
|
}
|
|
|
|
//
|
|
// Get alert enable setting.
|
|
//
|
|
dwDataSize = sizeof( LONG );
|
|
lReturn = ::RegQueryValueEx(
|
|
m_hAlertKey,
|
|
ENABLEALERTEAMIL,
|
|
NULL,
|
|
NULL,
|
|
reinterpret_cast<PBYTE>(&m_lAlertEmailDisabled),
|
|
&dwDataSize
|
|
);
|
|
if( lReturn != ERROR_SUCCESS)
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RetrieveRegInfo query enablealertemail failed"
|
|
);
|
|
bReturn = FALSE;
|
|
}
|
|
|
|
//
|
|
// Get alert type setting.
|
|
//
|
|
dwDataSize = sizeof( LONG );
|
|
lReturn = ::RegQueryValueEx(
|
|
m_hAlertKey,
|
|
SENDEMAILTYPE,
|
|
NULL,
|
|
NULL,
|
|
reinterpret_cast<PBYTE>(&m_lCurAlertType),
|
|
&dwDataSize
|
|
);
|
|
if( lReturn != ERROR_SUCCESS)
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RetrieveRegInfo query enablealertemail failed"
|
|
);
|
|
bReturn = FALSE;
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::RegThreadProc
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class static method which is used
|
|
// as worker thread entry.
|
|
//
|
|
// Arguments:
|
|
// [in] pIn Point to an instance of CAlertEmailConsumer class.
|
|
//
|
|
// Returns:
|
|
// 0 if successful
|
|
// -1 if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD WINAPI
|
|
CAlertEmailConsumer::RegThreadProc(
|
|
PVOID pIn
|
|
)
|
|
{
|
|
//
|
|
// Make transition to the per-instance method.
|
|
//
|
|
( (CAlertEmailConsumer *) pIn )->RegThread();
|
|
return 0;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::RegThread
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class public method which is real
|
|
// worker thread process.
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
CAlertEmailConsumer::RegThread()
|
|
{
|
|
HANDLE hHandleArray[2];
|
|
DWORD dwEventCount;
|
|
DWORD dwReturn;
|
|
|
|
SATraceString(
|
|
"AlertEmail:RegThread enter"
|
|
);
|
|
|
|
//
|
|
// Handle list used by WaitForMultipleObjects
|
|
//
|
|
hHandleArray[0] = m_hCloseThreadEvent;
|
|
|
|
//
|
|
// Event for RegNotifyChangeKeyValue.
|
|
//
|
|
hHandleArray[1] = ::CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
|
|
if( hHandleArray[1] != NULL )
|
|
{
|
|
dwEventCount = 2;
|
|
|
|
//
|
|
// Monitor key change action.
|
|
//
|
|
::RegNotifyChangeKeyValue( m_hAlertKey, //AlertEmail key
|
|
FALSE, //No subkey
|
|
REG_NOTIFY_CHANGE_LAST_SET, //Value change
|
|
hHandleArray[1], //Event handle
|
|
TRUE ); //APC
|
|
}
|
|
else
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RegThread CreateEvent failed"
|
|
);
|
|
dwEventCount = 1;
|
|
}
|
|
|
|
while( TRUE )
|
|
{
|
|
//
|
|
// Wait for both close and regchange event.
|
|
//
|
|
dwReturn = ::WaitForMultipleObjects( dwEventCount,
|
|
hHandleArray,
|
|
FALSE,
|
|
INFINITE );
|
|
switch( dwReturn )
|
|
{
|
|
case WAIT_OBJECT_0:
|
|
{
|
|
//
|
|
// Close thread event set in release method.
|
|
//
|
|
SATraceString(
|
|
"AlertEmail:RegThread get close event"
|
|
);
|
|
|
|
if( hHandleArray[1] != NULL )
|
|
{
|
|
::CloseHandle( hHandleArray[1] );
|
|
}
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
delete this;
|
|
return;
|
|
} //case WAIT_OBJECT_0:
|
|
|
|
case WAIT_OBJECT_0 + 1:
|
|
{
|
|
//
|
|
// Registry changed event.
|
|
//
|
|
SATraceString(
|
|
"AlertEmail:RegThread get reg event"
|
|
);
|
|
|
|
BOOL bReturn;
|
|
|
|
//
|
|
// Refresh alert email settings.
|
|
//
|
|
bReturn = RetrieveRegInfo();
|
|
if( bReturn == FALSE )
|
|
{
|
|
SATraceString(
|
|
"AlertEmail:RegThread RetrieveRegInfo failed"
|
|
);
|
|
}
|
|
break;
|
|
} //case WAIT_OBJECT_0 + 1:
|
|
|
|
default:
|
|
{
|
|
//
|
|
// Wait error ocupied.
|
|
//
|
|
SATraceString(
|
|
"AlertEmail:RegThread waitevent error"
|
|
);
|
|
break;
|
|
} //default:
|
|
|
|
} //switch(dwReturn)
|
|
|
|
} // While( TRUE )
|
|
|
|
return;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::InitializeLocalManager
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to get object of Local Manager.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAlertEmailConsumer::InitializeLocalManager()
|
|
{
|
|
CLSID clsidLocMgr;
|
|
HRESULT hr;
|
|
|
|
hr = ::CLSIDFromProgID (
|
|
LOCALIZATION_MANAGER,
|
|
&clsidLocMgr
|
|
);
|
|
if (SUCCEEDED (hr))
|
|
{
|
|
//
|
|
// create the Localization Manager COM object
|
|
//
|
|
hr = ::CoCreateInstance (
|
|
clsidLocMgr,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
__uuidof (ISALocInfo),
|
|
(PVOID*) &m_pLocInfo
|
|
);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::InitializeElementManager
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to get object of elements enum interface from Element manager.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CAlertEmailConsumer::InitializeElementManager()
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
IDispatch *pDispatch = NULL;
|
|
|
|
IWebElementRetriever *pWebElementRetriever = NULL;
|
|
|
|
do
|
|
{
|
|
//
|
|
// Get Element Manager's CLSID.
|
|
//
|
|
CLSID clsid;
|
|
hr = ::CLSIDFromProgID (
|
|
ELEMENT_RETRIEVER,
|
|
&clsid
|
|
);
|
|
if (FAILED (hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// create the WebElementRetriever now
|
|
//
|
|
hr = ::CoCreateInstance (
|
|
clsid,
|
|
NULL,
|
|
CLSCTX_LOCAL_SERVER,
|
|
IID_IWebElementRetriever,
|
|
(PVOID*) &pWebElementRetriever
|
|
);
|
|
if (FAILED (hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// allocate memory for BSTR(alert definitions)
|
|
//
|
|
CComBSTR bstrAlertDefinitions (ALERTDEFINITIONS);
|
|
if (NULL == bstrAlertDefinitions.m_str)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Initial now
|
|
//
|
|
hr = pWebElementRetriever->GetElements (
|
|
WEB_ELEMENT_TYPE_DEFINITION,
|
|
bstrAlertDefinitions,
|
|
&pDispatch
|
|
);
|
|
if (FAILED (hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// get the enum variant
|
|
//
|
|
hr = pDispatch->QueryInterface (
|
|
IID_IWebElementEnum,
|
|
reinterpret_cast <PVOID*> (&m_pElementEnum)
|
|
);
|
|
|
|
}while( FALSE );
|
|
|
|
if( pDispatch != NULL )
|
|
{
|
|
pDispatch->Release();
|
|
}
|
|
|
|
if( pWebElementRetriever != NULL )
|
|
{
|
|
pWebElementRetriever->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAlertEmailConsumer::InitializeCDOMessage
|
|
//
|
|
// Description:
|
|
// This is the CAlertEmailConsumer class private method which is used
|
|
// to get object of CDO::IMessage and set the configuration as using
|
|
// local SMTP server.
|
|
//
|
|
// Returns:
|
|
// WBEM_S_NO_ERROR if successful
|
|
// WBEM_E_FAILED if not
|
|
//
|
|
// History:
|
|
// Xing Jin (i-xingj) 23-Dec-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAlertEmailConsumer::InitializeCDOMessage()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr <IConfiguration> pConfig;
|
|
|
|
do
|
|
{
|
|
//
|
|
// Get an object of IMessage
|
|
//
|
|
hr = CoCreateInstance(
|
|
CLSID_Message,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IMessage,
|
|
(PVOID*) &m_pcdoIMessage
|
|
);
|
|
|
|
if (FAILED (hr))
|
|
{
|
|
SATraceString(
|
|
"AlertEmail: InitializeCDOMessage CoCreateInstance failed"
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get the configuration in this message object.
|
|
//
|
|
hr = m_pcdoIMessage->get_Configuration(&pConfig);
|
|
if (FAILED (hr))
|
|
{
|
|
SATraceString(
|
|
"AlertEmail: InitializeCDOMessage get_Configuration failed"
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set the configuration as default setting of local
|
|
// SMTP server.
|
|
//
|
|
hr = pConfig->Load( cdoIIS, NULL );
|
|
|
|
}
|
|
while( FALSE );
|
|
|
|
return hr;
|
|
}
|