Leaked source code of windows server 2003
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.
 
 
 
 
 
 

774 lines
25 KiB

/********************************************************************
Copyright (c) 1999 Microsoft Corporation
Module Name:
Channel.cpp
Abstract:
This is implementation of IChannel object
Revision History:
Steve Shih created 07/15/99
Davide Massarenti rewrote 12/05/2000
********************************************************************/
#include "stdafx.h"
////////////////////////////////////////////////////////////////////////////////
CSAFChannelRecord::CSAFChannelRecord()
{
}
HRESULT CSAFChannelRecord::GetField( /*[in]*/ SAFREG_Field field, /*[out]*/ BSTR *pVal )
{
LPCWSTR szText;
WCHAR rgLCID[64];
switch(field)
{
case SAFREG_SKU : szText = m_ths.GetSKU (); break;
case SAFREG_Language : szText = rgLCID; _ltow( m_ths.GetLanguage(), rgLCID, 10 ); break;
case SAFREG_VendorID : szText = m_bstrVendorID; break;
case SAFREG_ProductID : szText = m_bstrProductID; break;
case SAFREG_VendorName : szText = m_bstrVendorName; break;
case SAFREG_ProductName : szText = m_bstrProductName; break;
case SAFREG_ProductDescription: szText = m_bstrDescription; break;
case SAFREG_VendorIcon : szText = m_bstrIcon; break;
case SAFREG_SupportUrl : szText = m_bstrURL; break;
break;
case SAFREG_PublicKey : szText = m_bstrPublicKey; break;
case SAFREG_UserAccount : szText = m_bstrUserAccount; break;
case SAFREG_Security : szText = m_bstrSecurity; break;
case SAFREG_Notification : szText = m_bstrNotification; break;
default: return E_INVALIDARG;
}
return MPC::GetBSTR( szText, pVal );
}
HRESULT CSAFChannelRecord::SetField( /*[in]*/ SAFREG_Field field, /*[in]*/ BSTR newVal )
{
CComBSTR* pbstr = NULL;
SANITIZEWSTR( newVal );
switch(field)
{
case SAFREG_SKU : m_ths.m_strSKU = newVal ; break;
case SAFREG_Language : m_ths.m_lLCID = _wtol( newVal ) ; break;
case SAFREG_VendorID : pbstr = (CComBSTR*)&m_bstrVendorID ; break;
case SAFREG_ProductID : pbstr = (CComBSTR*)&m_bstrProductID ; break;
case SAFREG_VendorName : pbstr = (CComBSTR*)&m_bstrVendorName ; break;
case SAFREG_ProductName : pbstr = (CComBSTR*)&m_bstrProductName ; break;
case SAFREG_ProductDescription: pbstr = (CComBSTR*)&m_bstrDescription ; break;
case SAFREG_VendorIcon : pbstr = (CComBSTR*)&m_bstrIcon ; break;
case SAFREG_SupportUrl : pbstr = (CComBSTR*)&m_bstrURL ; break;
case SAFREG_PublicKey : pbstr = (CComBSTR*)&m_bstrPublicKey ; break;
case SAFREG_UserAccount : pbstr = (CComBSTR*)&m_bstrUserAccount ; break;
case SAFREG_Security : pbstr = (CComBSTR*)&m_bstrSecurity ; break;
case SAFREG_Notification : pbstr = (CComBSTR*)&m_bstrNotification; break;
default: return E_INVALIDARG;
}
return pbstr ? MPC::PutBSTR( *pbstr, newVal ) : S_OK;
}
////////////////////////////////////////////////////////////////////////////////
CSAFChannel::CSAFChannel()
{
__HCP_FUNC_ENTRY( "CSAFChannel::CSAFChannel" );
// CSAFChannelRecord m_data;
// CComPtr<IPCHSecurityDescriptor> m_Security;
// List m_lstIncidentItems;
}
void CSAFChannel::FinalRelease()
{
__HCP_FUNC_ENTRY( "CSAFChannel::FinalRelease" );
Passivate();
}
void CSAFChannel::Passivate()
{
__HCP_FUNC_ENTRY( "CSAFChannel::Passivate" );
m_Security.Release();
MPC::ReleaseAll( m_lstIncidentItems );
}
/////////////////////////////////////////////////////////////////////////////
HRESULT CSAFChannel::OpenIncidentStore( /*[out]*/ CIncidentStore*& pIStore )
{
__HCP_FUNC_ENTRY( "CSAFChannel::OpenIncidentStore" );
HRESULT hr;
__MPC_EXIT_IF_ALLOC_FAILS(hr, pIStore, new CIncidentStore());
__MPC_EXIT_IF_METHOD_FAILS(hr, pIStore->Load());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT CSAFChannel::CloseIncidentStore( /*[out]*/ CIncidentStore*& pIStore )
{
__HCP_FUNC_ENTRY( "CSAFChannel::CloseIncidentStore" );
HRESULT hr;
if(pIStore)
{
(void)pIStore->Save();
delete pIStore; pIStore = NULL;
}
hr = S_OK;
__HCP_FUNC_EXIT(hr);
}
/////////////////////////////////////////////////////////////////////////////
HRESULT CSAFChannel::Init( /*[in]*/ const CSAFChannelRecord& cr )
{
__HCP_FUNC_ENTRY( "CSAFChannel::Init" );
HRESULT hr;
CIncidentStore* pIStore = NULL;
m_data = cr;
__MPC_EXIT_IF_METHOD_FAILS(hr, OpenIncidentStore( pIStore ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pIStore->OpenChannel( this ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
(void)CloseIncidentStore( pIStore );
__HCP_FUNC_EXIT(hr);
}
HRESULT CSAFChannel::Import( /*[in]*/ const CSAFIncidentRecord& increc ,
/*[out]*/ CSAFIncidentItem* *ppItem )
{
__HCP_FUNC_ENTRY( "CSAFChannel::Import" );
HRESULT hr;
CComObject<CSAFIncidentItem>* pItem = NULL;
__MPC_EXIT_IF_METHOD_FAILS(hr, CreateChild( this, &pItem ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pItem->Import( increc ));
if(ppItem)
{
(*ppItem = pItem)->AddRef();
}
m_lstIncidentItems.push_back( pItem ); pItem = NULL;
hr = S_OK;
__HCP_FUNC_CLEANUP;
MPC::Release( pItem );
__HCP_FUNC_EXIT(hr);
}
HRESULT CSAFChannel::Create( /*[in]*/ BSTR bstrDesc ,
/*[in]*/ BSTR bstrURL ,
/*[in]*/ BSTR bstrProgress ,
/*[in]*/ BSTR bstrXMLDataFile ,
/*[in]*/ BSTR bstrXMLBlob ,
/*[out]*/ CSAFIncidentItem* *pVal )
{
__HCP_FUNC_ENTRY( "CSAFChannel::Create" );
HRESULT hr;
CIncidentStore* pIStore = NULL;
CComBSTR bstrOwner;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
__MPC_PARAMCHECK_END();
__MPC_EXIT_IF_METHOD_FAILS(hr, OpenIncidentStore( pIStore ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetCallerPrincipal( /*fImpersonate*/true, bstrOwner ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pIStore->AddRec( this, bstrOwner, bstrDesc, bstrURL, bstrProgress, bstrXMLDataFile, bstrXMLBlob, pVal ));
// Fire an event to the Notification Object (onIncidentAdded)
__MPC_EXIT_IF_METHOD_FAILS(hr, Fire_NotificationEvent( EVENT_INCIDENTADDED, GetSizeIncidentList(), this, *pVal, 0 ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
(void)CloseIncidentStore( pIStore );
__HCP_FUNC_EXIT(hr);
}
CSAFChannel::IterConst CSAFChannel::Find( /*[in]*/ BSTR bstrURL )
{
IterConst it;
//
// Release all the items.
//
for(it = m_lstIncidentItems.begin(); it != m_lstIncidentItems.end(); it++)
{
if((*it)->GetURL() == bstrURL) break;
}
return it;
}
CSAFChannel::IterConst CSAFChannel::Find( /*[in]*/ DWORD dwIndex )
{
IterConst it;
//
// Release all the items.
//
for(it = m_lstIncidentItems.begin(); it != m_lstIncidentItems.end(); it++)
{
if((*it)->GetRecIndex() == dwIndex) break;
}
return it;
}
/////////////////////////////////////////////////////////////////////////////
// Custom interfaces
STDMETHODIMP CSAFChannel::get_VendorID( /*[out, retval]*/ BSTR *pVal )
{
MPC::SmartLock<_ThreadModel> lock( this );
return m_data.GetField( CSAFChannelRecord::SAFREG_VendorID, pVal );
}
STDMETHODIMP CSAFChannel::get_ProductID( /*[out, retval]*/ BSTR *pVal )
{
MPC::SmartLock<_ThreadModel> lock( this );
return m_data.GetField( CSAFChannelRecord::SAFREG_ProductID, pVal );
}
STDMETHODIMP CSAFChannel::get_VendorName( /*[out, retval]*/ BSTR *pVal )
{
MPC::SmartLock<_ThreadModel> lock( this );
return m_data.GetField( CSAFChannelRecord::SAFREG_VendorName, pVal );
}
STDMETHODIMP CSAFChannel::get_ProductName( /*[out, retval]*/ BSTR *pVal )
{
MPC::SmartLock<_ThreadModel> lock( this );
return m_data.GetField( CSAFChannelRecord::SAFREG_ProductName, pVal );
}
STDMETHODIMP CSAFChannel::get_Description( /*[out, retval]*/ BSTR *pVal )
{
MPC::SmartLock<_ThreadModel> lock( this );
return m_data.GetField( CSAFChannelRecord::SAFREG_ProductDescription, pVal );
}
STDMETHODIMP CSAFChannel::get_VendorDirectory( /*[out, retval]*/ BSTR *pVal )
{
__HCP_FUNC_ENTRY( "CSAFChannel::get_VendorDirectory" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
MPC::wstring strRoot;
Taxonomy::LockingHandle handle;
Taxonomy::InstalledInstanceIter it;
bool fFound;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
__MPC_PARAMCHECK_END();
if(m_data.m_bstrVendorID.Length() == 0)
{
__MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::InstalledInstanceStore::s_GLOBAL->GrabControl( handle ));
__MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::InstalledInstanceStore::s_GLOBAL->SKU_Find ( m_data.m_ths, fFound, it ));
if(!fFound)
{
__MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
}
strRoot = it->m_inst.m_strSystem;
strRoot += HC_HELPSET_SUB_VENDORS L"\\"; MPC::SubstituteEnvVariables( strRoot );
strRoot += m_data.m_bstrVendorID;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetBSTR( strRoot.c_str(), pVal ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSAFChannel::get_Security( /*[out, retval]*/ IPCHSecurityDescriptor* *pVal )
{
__HCP_FUNC_ENTRY( "CSAFChannel::get_Security" );
HRESULT hr;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
__MPC_PARAMCHECK_END();
if(m_data.m_bstrSecurity.Length())
{
if(m_Security == NULL)
{
CPCHSecurityDescriptorDirect sdd;
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertFromString( m_data.m_bstrSecurity ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CPCHSecurity::s_GLOBAL->CreateObject_SecurityDescriptor( &m_Security ));
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertSDToCOM( m_Security ));
}
__MPC_EXIT_IF_METHOD_FAILS(hr, m_Security.CopyTo( pVal ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
STDMETHODIMP CSAFChannel::put_Security( /*[in]*/ IPCHSecurityDescriptor* newVal )
{
__HCP_FUNC_ENTRY( "CSAFChannel::put_Security" );
HRESULT hr;
m_data.m_bstrSecurity.Empty ();
m_Security .Release();
if(newVal)
{
CPCHSecurityDescriptorDirect sdd;
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertSDFromCOM( newVal ));
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.ConvertToString( &m_data.m_bstrSecurity ));
}
//
// Update the SAF store...
//
__MPC_EXIT_IF_METHOD_FAILS(hr, CSAFReg::s_GLOBAL->UpdateField( m_data, CSAFChannelRecord::SAFREG_Security ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSAFChannel::get_Notification( /*[out, retval]*/ BSTR *pVal )
{
MPC::SmartLock<_ThreadModel> lock( this );
return m_data.GetField( CSAFChannelRecord::SAFREG_Notification, pVal );
}
STDMETHODIMP CSAFChannel::put_Notification( /*[in]*/ BSTR newVal )
{
__HCP_FUNC_ENTRY( "CSAFChannel::get_Notification" );
HRESULT hr;
CLSID clsID;
MPC::SmartLock<_ThreadModel> lock( this );
// Lets see if the CLSID is valid, if not return error
if(FAILED(hr = ::CLSIDFromString( newVal, &clsID )))
{
DebugLog(L"Not a valid GUID!\r\n");
__MPC_FUNC_LEAVE;
}
// Set the CSAFChannel object member
m_data.m_bstrNotification = newVal;
// Place the Notification GUID into the XML SAFReg
__MPC_EXIT_IF_METHOD_FAILS(hr, CSAFReg::s_GLOBAL->UpdateField( m_data, CSAFChannelRecord::SAFREG_Notification ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSAFChannel::Incidents( /*[in]*/ IncidentCollectionOptionEnum opt ,
/*[out, retval]*/ IPCHCollection* *ppC )
{
__HCP_FUNC_ENTRY( "CSAFChannel::get_Incidents" );
HRESULT hr;
IterConst it;
CComPtr<CPCHCollection> pColl;
MPC::SmartLock<_ThreadModel> lock( this );
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(ppC,NULL);
__MPC_PARAMCHECK_END();
// Check the value of "opt" if other than 0,1,2 flag an error
switch(opt)
{
case pchAllIncidents : break;
case pchOpenIncidents : break;
case pchClosedIncidents: break;
default : __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);// Not a valid Option. Set the error.
}
//
// Create the Enumerator and fill it with items.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pColl ));
for(it = m_lstIncidentItems.begin(); it != m_lstIncidentItems.end(); it++)
{
CSAFIncidentItem* item = *it;
if(item->MatchEnumOption( opt ))
{
__MPC_EXIT_IF_METHOD_FAILS(hr, pColl->AddItem( item ));
}
}
__MPC_EXIT_IF_METHOD_FAILS(hr, pColl.QueryInterface( ppC ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
// The following method needs to be in the IncidentItem ideally.
// First take it out from here.
STDMETHODIMP CSAFChannel::RecordIncident( /*[in]*/ BSTR bstrDisplay ,
/*[in]*/ BSTR bstrURL ,
/*[in]*/ VARIANT vProgress ,
/*[in]*/ VARIANT vXMLDataFile ,
/*[in]*/ VARIANT vXMLBlob ,
/*[out]*/ ISAFIncidentItem* *pVal )
{
__HCP_FUNC_ENTRY( "CSAFChannel::RecordIncident" );
HRESULT hr;
CComPtr<CSAFIncidentItem> pItem;
MPC::SmartLock<_ThreadModel> lock( this );
BSTR bstrProgress = (vProgress.vt == VT_BSTR ? vProgress .bstrVal : NULL);
BSTR bstrXMLDataFile = (vXMLDataFile.vt == VT_BSTR ? vXMLDataFile.bstrVal : NULL);
BSTR bstrXMLBlob = (vXMLBlob.vt == VT_BSTR ? vXMLBlob .bstrVal : NULL);
__MPC_EXIT_IF_METHOD_FAILS(hr, Create( bstrDisplay, bstrURL, bstrProgress, bstrXMLDataFile, bstrXMLBlob, &pItem ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pItem.QueryInterface( pVal ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT CSAFChannel::RemoveIncidentFromList( /*[in]*/ CSAFIncidentItem* pVal )
{
__HCP_FUNC_ENTRY( "CSAFChannel::RemoveIncidentFromList" );
HRESULT hr;
IterConst it;
MPC::SmartLock<_ThreadModel> lock( this );
// Fire an event to the Notification Object (onIncidentAdded)
__MPC_EXIT_IF_METHOD_FAILS(hr, Fire_NotificationEvent( EVENT_INCIDENTREMOVED, GetSizeIncidentList(), this, pVal, 0 ));
it = Find( pVal->GetRecIndex() );
if(it != m_lstIncidentItems.end())
{
(*it)->Release();
m_lstIncidentItems.erase( it );
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
/*
Function CSAFChannel::Fire_Notification
Description
This function is used to fire a notification event on the registered notification object.
If there is no notification object, this will do nothing.
Parameters:
Depending on the type of Event you want to fire, different parameters must be filled out.
The following table shows which are the valid parameters for the call. If a parameter
is not valid, it MUST be set to NULL.
iEventType - EVENT_INCIDENTADDED
Valid parameters:
- iCountIncidentInChannel
- pC
- pI
- EVENT_INCIDENTREMOVED
Valid parameters:
- iCountIncidentInChannel
- pC
- pI
- EVENT_INCIDENTUPDATED
Valid parameters:
- iCountIncidentInChannel
- pC
- pI
- EVENT_CHANNELUPDATED
Valid parameters:
- iCountIncidentInChannel
- pC
- dwCode
*/
HRESULT CSAFChannel::Fire_NotificationEvent( int iEventType ,
int iCountIncidentInChannel ,
ISAFChannel* pC ,
ISAFIncidentItem* pI ,
DWORD dwCode )
{
__HCP_FUNC_ENTRY( "CSAFChannel::Fire_NotificationEvent" );
HRESULT hr;
PWTS_SESSION_INFO pSessionInfo = NULL;
DWORD dwSessions = 0;
DWORD dwValidSessions = 0;
DWORD dwRetSize = 0;
WINSTATIONINFORMATIONW WSInfo;
CComBSTR bstrCaller;
PSID pSID = NULL;
LPCWSTR szDomain = NULL;
LPCWSTR szLogin = NULL;
CLSID clsID;
ULONG ulRet;
// Check to see if we have a registered Notification Object
if(!m_data.m_bstrNotification || FAILED(::CLSIDFromString( m_data.m_bstrNotification, &clsID )))
{
__MPC_SET_ERROR_AND_EXIT(hr, S_OK);
}
//
// First lets get the callers Domain and Name by impersonating the caller and grabbing them
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::GetCallerPrincipal( true, bstrCaller ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::ConvertPrincipalToSID( bstrCaller, pSID ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SecurityDescriptor::ConvertSIDToPrincipal( pSID, &szLogin, &szDomain ));
// Enumerate all sessions on this machine
// -------------------------------------------
// Use WTSEnumerateSessions
// Then find active ones
// Then make the calls to ISAFChannelNotifyIncident
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::WTSEnumerateSessions( WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwSessions ))
// Find the active ones and mark them only if they are the correct user
for(DWORD i = 0; i < dwSessions; i++)
{
if(pSessionInfo[i].State == WTSActive) // Got an active session
{
CComPtr<IPCHSlaveProcess> sp;
CComPtr<IUnknown> unk;
CComPtr<ISAFChannelNotifyIncident> chNot;
// Now mark it if the Username and Domain match that of the user
// we are calling for.
memset( &WSInfo, 0, sizeof(WSInfo) );
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::WinStationQueryInformationW( SERVERNAME_CURRENT ,
pSessionInfo[i].SessionId ,
WinStationInformation ,
&WSInfo ,
sizeof(WSInfo) ,
&dwRetSize ));
// Now we can fish the userid and domain out of the WSInfo.Domain and WSInfo.UserName
// Now we are ready to compare the domain and username
if((wcscmp( WSInfo.Domain , szDomain ) == 0) &&
(wcscmp( WSInfo.UserName, szLogin ) == 0) )
{
WINSTATIONUSERTOKEN WsUserToken;
// We found the correct sessions, make the calls to ISAFChannelNotifyIncident
WsUserToken.ProcessId = LongToHandle( GetCurrentProcessId() );
WsUserToken.ThreadId = LongToHandle( GetCurrentThreadId () );
// Grab token from SessionID
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::WinStationQueryInformationW( WTS_CURRENT_SERVER_HANDLE ,
pSessionInfo[i].SessionId ,
WinStationUserToken ,
&WsUserToken ,
sizeof(WsUserToken) ,
&ulRet ));
// Create the notification object in the session (using the hToken
{
CPCHUserProcess::UserEntry ue;
__MPC_EXIT_IF_METHOD_FAILS(hr, ue.InitializeForImpersonation( WsUserToken.UserToken ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CPCHUserProcess::s_GLOBAL->Connect( ue, &sp ));
}
//
// Discard all the failures from the remote objects.
//
////////////////////////////////////////////////////////////////////////////////
// Use the Slave Process to Create the object which CLSID clsID.
if(FAILED(hr = sp->CreateInstance( clsID, NULL, &unk )))
{
continue;
}
// Grab a pointer to the correct interface
if(FAILED(hr = unk.QueryInterface( &chNot )))
{
continue;
}
// Depending on the type of notification, call the correct event callback
switch(iEventType)
{
case EVENT_INCIDENTADDED : hr = chNot->onIncidentAdded ( pC, pI , iCountIncidentInChannel ); break;
case EVENT_INCIDENTREMOVED: hr = chNot->onIncidentRemoved( pC, pI , iCountIncidentInChannel ); break;
case EVENT_INCIDENTUPDATED: hr = chNot->onIncidentUpdated( pC, pI , iCountIncidentInChannel ); break;
case EVENT_CHANNELUPDATED : hr = chNot->onChannelUpdated ( pC, dwCode, iCountIncidentInChannel ); break;
}
if(FAILED(hr))
{
continue;
}
}
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
MPC::SecurityDescriptor::ReleaseMemory( (void *&)pSID );
MPC::SecurityDescriptor::ReleaseMemory( (void *&)szLogin );
MPC::SecurityDescriptor::ReleaseMemory( (void *&)szDomain );
__HCP_FUNC_EXIT(hr);
}