2025-11-28 00:35:46 +09:00

505 lines
17 KiB
C++

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
#include "stdafx.h"
#include "AppInfo.h"
#include "ComSpyCtl.h"
#include "ComSpyAudit.h"
#include "CComSpy.h"
#include <algorithm>
#include "SysLCESub.h" // Includes for all the event consumers.
#include "AppSub.h" // Implement App Events
#include "InstanceSub.h" // Implement Instance Events
#include "EvtStoreSub.h" // Implement COM+ Event System Events
#include "TxSub.h" // Implement Transaction Events
#include "ObjSub.h" // Implement Object Events
#include "MethodSub.h" // Implement Method Events
#include "ResourceSub.h" // Implement Resource Events
#include "SecuritySub.h" // Implement Security Events
#include "ThreadSub.h" // Implement Thread Events
#include "UserSub.h" // Implement User Defined Events
#include "ObjConstSub.h" // Implement Object Construction Events
#include "ObjPoolSub.h" // Implement Object Pool Events
#include "ObjPool2Sub.h" // Implement more Object Pool Events
#include "ActivitySub.h" // Implement Activity Events
#include "IdentitySub.h" // Implement Identity Events
#include "QCSub.h" // Implement Queued Components Events
#include "ExceptionSub.h" // Implement Exception Events
#include "crmsub.h" // Implement CRM Events
#include "lbsub.h" // Implement COM+ Load Balancing Events
// -----------------------------------------------------------------------------
// Method: CAppInfo::Initialze(...)
// Params: pSpy: Pointer to a CComSpy object.
// Returns: (None)
// Purpose: Initialize the class and create the Event Subscriber MAP.
// -----------------------------------------------------------------------------
void CAppInfo::Initialze(CComSpy * pSpy)
{
m_EventMap = new SUBSCRIBERMAP;
m_bReadyForDelete = false;
m_pSpy = pSpy;
};
// -----------------------------------------------------------------------------
// Method: CAppInfo::CAppInfo(...)
// Params: pwszAppName: A string representing 'All Applications'
// pSpy: Pointer to a CComSpy object.
// Returns: (None)
// Purpose: Constructor for the special, NoFilter instance of this class.
// -----------------------------------------------------------------------------
CAppInfo::CAppInfo(LPCWSTR pwszAppName, CComSpy * pSpy)
{
Initialze(pSpy);
m_sAppName = pwszAppName;
m_FilterType = NoFilter;
m_sAppID = L"";
m_PID = 0;
};
// -----------------------------------------------------------------------------
// Method: CAppInfo::CAppInfo(...)
// Params: pwszAppName: A string representing 'All Applications'
// pSpy: Pointer to a CComSpy object.
// nPID: ProcessID for this running app.
// Returns: (None)
// Purpose: Constructor for the Running Application version of this object.
// -----------------------------------------------------------------------------
CAppInfo::CAppInfo(LPCWSTR pwszAppName, CComSpy * pSpy, long nPID)
{
Initialze(pSpy);
m_sAppName = pwszAppName;
m_FilterType = ProcessID;
m_sAppID = L"";
m_PID = nPID;
};
// -----------------------------------------------------------------------------
// Method: CAppInfo::CAppInfo(...)
// Params: pwszAppName: String representing the AppName.
// pSpy: Pointer to a CComSpy object.
// pwszAppID: String representing AppID (a formatted GUID)
// Returns: (None)
// Purpose: Constructor for the standard case of filtering by AppID.
// Note that the COM+ Filtering does not want a Application Name, but
// instead wants an Application ID as a GUID.
// -----------------------------------------------------------------------------
CAppInfo::CAppInfo(LPCWSTR pwszAppName, CComSpy * pSpy, LPCWSTR pwszAppID)
{
Initialze(pSpy);
m_sAppName = pwszAppName;
m_FilterType = AppID;
m_sAppID = pwszAppID;
m_PID = 0;
};
// -----------------------------------------------------------------------------
// Method: CAppInfo::~CAppInfo()
// Params: (None)
// Returns: (None)
// Purpose: Destructor for the CAppInfo class. Remove All Subscriptions.
// and delete the map.
// ToDo: Do we need to empty this Map first?
// -----------------------------------------------------------------------------
CAppInfo::~CAppInfo()
{
bool bResult = RemoveAllSubscriptions();
delete m_EventMap;
m_EventMap = NULL;
}
// -----------------------------------------------------------------------------
// Method: CAppInfo::RemoveAllSubscriptions()
// Params: (None)
// Returns: True always
// Purpose: Remove all subscriptions held by this Application object. Iterate
// through the event map and free each.
// Note: We must call Release() because these are COM objects.
// -----------------------------------------------------------------------------
bool CAppInfo::RemoveAllSubscriptions()
{
SUBSCRIBERMAP::iterator item;
ICOMSysLCE* pSubscriber = NULL;
// Iterate through the list of Events to delete them all.
item = m_EventMap->begin();
while (item != m_EventMap->end())
{
pSubscriber = (*item).second;
if (pSubscriber)
{
pSubscriber->Uninstall();
pSubscriber->Release();
pSubscriber = NULL;
}
item = m_EventMap->erase(item);
};
return true;
}
// -----------------------------------------------------------------------------
// Method: CAppInfo::AddSubscription(...)
// Params: e: The EventEnum that we want to subscribe to. (eg. Method)
// Returns: true if the subscription was added successfully.
// Purpose: To create an Interface pointer to the appropriate Subscription
// type within COM+. These all derive from IComSysLCE, so we use
// the polymorphism to do this. Once we have the specific interface
// required, we then determine which filter (if any) to use and we
// Install the filter.
// -----------------------------------------------------------------------------
bool CAppInfo::AddSubscription(EventEnum e)
{
HRESULT hr;
ICOMSysLCE* pSubscriber = NULL;
if (IsSubscribed(e))
return false;
switch (e)
{
// Note: The QI will do our AddRef
case Application:
{
CComObject <CAppSub> * pSub;
hr = CComObject<CAppSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Thread:
{
CComObject <CThreadSub> * pSub;
hr = CComObject<CThreadSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Instance:
{
CComObject <CInstanceSub> * pSub;
hr = CComObject<CInstanceSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Transaction:
{
CComObject <CTxSub> * pSub;
hr = CComObject<CTxSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Method:
{
CComObject <CMethodSub> * pSub;
hr = CComObject<CMethodSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Object:
{
CComObject <CObjSub> * pSub;
hr = CComObject<CObjSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Resource:
{
CComObject <CResourceSub> * pSub;
hr = CComObject<CResourceSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case User:
{
CComObject <CUserSub> * pSub;
hr = CComObject<CUserSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Security:
{
CComObject <CSecuritySub> * pSub;
hr = CComObject<CSecuritySub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case ObjectConstruction:
{
CComObject <CObjConstSub> * pSub;
hr = CComObject<CObjConstSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case ObjectPool:
{
CComObject <CObjPoolSub> * pSub;
hr = CComObject<CObjPoolSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case ObjectPool2:
{
CComObject <CObjPool2Sub> * pSub;
hr = CComObject<CObjPool2Sub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Activity:
{
CComObject <CActivitySub> * pSub;
hr = CComObject<CActivitySub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Identity:
{
CComObject <CIdentitySub> * pSub;
hr = CComObject<CIdentitySub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case QC:
{
CComObject <CQCSub> * pSub;
hr = CComObject<CQCSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case Exception:
{
CComObject <CExceptionSub> * pSub;
hr = CComObject<CExceptionSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case CRM:
{
CComObject <CCRMSub> * pSub;
hr = CComObject<CCRMSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
//Events generated by system process
case EventStore:
{
CComObject <CEvtStoreSub> * pSub;
hr = CComObject<CEvtStoreSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
case LoadBalancing:
{
CComObject <CLBSub> * pSub;
hr = CComObject<CLBSub>::CreateInstance(&pSub);
if (FAILED(hr))
return false;
_ASSERTE(pSub);
pSub->SetSpyObj(m_pSpy);
pSub->QueryInterface(IID_PPV_ARGS(&pSubscriber));
break;
}
default:
ATLTRACE(L"Object type not implemented yet\n");
_ASSERTE(0);
break;
}
// We've successfully created the Subscriber interface.
if (pSubscriber)
{
CComBSTR bstrPropertyName;
CComVariant vPropertyValue;
BSTR* pbstrPropertyName = NULL;
// Set the filter strings according to the object type.
switch (m_FilterType)
{
case ProcessID:
vPropertyValue = m_PID;
bstrPropertyName = L"ProcessId";
pbstrPropertyName = (BSTR*)&bstrPropertyName;
break;
case AppID:
bstrPropertyName = L"AppId";
vPropertyValue = m_sAppID;
pbstrPropertyName = (BSTR*)&bstrPropertyName;
break;
case NoFilter:
// If this is a filtertype of All Apps, then pass NULL.
pbstrPropertyName = NULL;
vPropertyValue = L"";
break;
default:
_ASSERTE(0);
};
// Register the subscription.
pSubscriber->Install(pbstrPropertyName, vPropertyValue);
// Add the event Subscription to the MAP.
(*m_EventMap)[e] = pSubscriber;
};
return true;
};
// -----------------------------------------------------------------------------
// Method: CAppInfo::RemoveAllSubscriptions()
// Params: e: The EventEnum to remove the subscription for.
// Returns: true if the subscrioption was removed.
// Purpose: Remove the Event Subscription for a given EventEnum.
// Note: We must call Release() because these are COM objects.
// -----------------------------------------------------------------------------
bool CAppInfo::RemoveSubscription(EventEnum e)
{
ICOMSysLCE* pSubscriber = NULL;
if (!IsSubscribed(e))
return false;
// Get the Subscriber interface pointer.
pSubscriber = (*m_EventMap)[e];
if (pSubscriber)
{
pSubscriber->Uninstall();
pSubscriber->Release();
pSubscriber = NULL;
m_EventMap->erase(e);
return true;
};
return false;
}
// -----------------------------------------------------------------------------
// Method: CAppInfo::IsSubscribed(...)
// Params: e: the EventEnum to check
// Returns: True if the given Event is currently subscribed to, otherwise False.
// Purpose: Check whether or not this Application is subscribed to an event.
// -----------------------------------------------------------------------------
bool CAppInfo::IsSubscribed(EventEnum e)
{
ICOMSysLCE* pSubscriber = NULL;
pSubscriber = (*m_EventMap)[e];
bool bResult = pSubscriber ? true : false;
pSubscriber = NULL;
return bResult;
};
// -----------------------------------------------------------------------------
// Method: CAppInfo::IsSubscribedToAny()
// Params: (None)
// Returns: True if any Event is currently subscribed to, otherwise False.
// Purpose: Check whether or not this Application is subscribed to any events.
// -----------------------------------------------------------------------------
bool CAppInfo::IsSubscribedToAny()
{
long nSubs = 0;
SUBSCRIBERMAP::iterator item;
ICOMSysLCE* pSubscriber = NULL;
for (item = m_EventMap->begin(); item != m_EventMap->end(); ++item)
{
pSubscriber = (*item).second;
if (pSubscriber)
nSubs++;
};
return (nSubs > 0) ? true : false;
};