windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/infocomm/extend/extcom.cxx
2020-09-26 16:20:57 +08:00

254 lines
6.7 KiB
C++

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
extcom.cxx
Abstract:
IIS Services IISADMIN Extension
Main COM interface.
Class CadmExt
CLSID = CLSID_W3EXTEND
IID = IID_IADMEXT
Author:
Michael W. Thomas 16-Sep-97
--*/
#include <cominc.hxx>
#ifndef _NO_TRACING_
DECLARE_DEBUG_PRINTS_OBJECT();
#include <initguid.h>
DEFINE_GUID(IisExtComGuid,
0x784d8925, 0xaa8c, 0x11d2, 0x92, 0x5e, 0x00, 0xc0, 0x4f, 0x72, 0xd9, 0x0e);
#endif
CAdmExt::CAdmExt():
m_dwRefCount(0),
m_pcCom(NULL),
m_dwSinkCookie(0),
m_pConnPoint(NULL)
{
}
CAdmExt::~CAdmExt()
{
#ifndef _NO_TRACING_
DELETE_DEBUG_PRINT_OBJECT();
#endif
}
HRESULT
CAdmExt::QueryInterface(REFIID riid, void **ppObject) {
if (riid==IID_IUnknown || riid==IID_IADMEXT) {
*ppObject = (IADMEXT *) this;
}
else {
return E_NOINTERFACE;
}
AddRef();
return NO_ERROR;
}
ULONG
CAdmExt::AddRef()
{
DWORD dwRefCount;
InterlockedIncrement((long *)&g_dwRefCount);
dwRefCount = InterlockedIncrement((long *)&m_dwRefCount);
return dwRefCount;
}
ULONG
CAdmExt::Release()
{
DWORD dwRefCount;
InterlockedDecrement((long *)&g_dwRefCount);
dwRefCount = InterlockedDecrement((long *)&m_dwRefCount);
//
// This is now a member of class factory.
// It is not dynamically allocated, so don't delete it.
//
/*
if (dwRefCount == 0) {
delete this;
return 0;
}
*/
return dwRefCount;
}
HRESULT STDMETHODCALLTYPE
CAdmExt::Initialize(void)
{
HRESULT hresReturn;
#ifdef _NO_TRACING_
CREATE_DEBUG_PRINT_OBJECT( "SVCEXT" );
#else
CREATE_DEBUG_PRINT_OBJECT("SVCEXT", IisExtComGuid);
#endif
hresReturn = CoCreateInstance(CLSID_MDCOM,
NULL,
CLSCTX_SERVER,
IID_IMDCOM,
(void**) &m_pcCom);
if (SUCCEEDED(hresReturn)) {
//
// First, set the state of all servers to Stopped.
//
SetServerState(L"/LM/W3SVC");
SetServerState(L"/LM/MSFTPSVC");
//
// Set up a sink for special processing.
//
IConnectionPointContainer* pConnPointContainer = NULL;
BOOL bSinkConnected = FALSE;
CSvcExtImpIMDCOMSINK *pEventSink = new CSvcExtImpIMDCOMSINK(m_pcCom);
if (pEventSink != NULL) {
// First query the object for its Connection Point Container. This
// essentially asks the object in the server if it is connectable.
hresReturn = m_pcCom->QueryInterface(
IID_IConnectionPointContainer,
(PVOID *)&pConnPointContainer);
if SUCCEEDED(hresReturn)
{
// Find the requested Connection Point. This AddRef's the
// returned pointer.
hresReturn = pConnPointContainer->FindConnectionPoint(IID_IMDCOMSINK_W, &m_pConnPoint);
if (SUCCEEDED(hresReturn)) {
hresReturn = m_pConnPoint->Advise((IUnknown *)pEventSink, &m_dwSinkCookie);
}
pConnPointContainer->Release();
}
pEventSink->Release();
}
else {
hresReturn = E_OUTOFMEMORY;
}
}
UpdateUsers();
return hresReturn;
}
HRESULT STDMETHODCALLTYPE
CAdmExt::EnumDcomCLSIDs(
/* [size_is][out] */ CLSID *pclsidDcom,
/* [in] */ DWORD dwEnumIndex)
{
return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
}
HRESULT STDMETHODCALLTYPE
CAdmExt::Terminate(void)
{
if (m_pcCom != NULL) {
if (m_pConnPoint != NULL) {
if (m_dwSinkCookie != 0) {
m_pConnPoint->Unadvise(m_dwSinkCookie);
}
m_pConnPoint->Release();
}
m_pcCom->Release();
}
return S_OK;
}
VOID
CAdmExt::SetServerState(
LPWSTR pszPath)
{
HRESULT hresReturn, hresTempReturn;
TCHAR pszNameBuf[METADATA_MAX_NAME_LEN];
int i;
METADATA_RECORD mdrData;
DWORD dwData;
DWORD dwRequiredDataLen;
METADATA_HANDLE mdhCurrent;
hresReturn = m_pcCom->ComMDOpenMetaObject(METADATA_MASTER_ROOT_HANDLE,
pszPath,
METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
OPEN_TIMEOUT_VALUE,
&mdhCurrent);
if (SUCCEEDED(hresReturn)) {
for (i=0;hresReturn == ERROR_SUCCESS;i++) {
//
// enumerate children
//
hresReturn = m_pcCom->ComMDEnumMetaObjects(mdhCurrent,
TEXT(""),
pszNameBuf,
i);
if (SUCCEEDED(hresReturn)) {
MD_SET_DATA_RECORD_EXT(&mdrData,
MD_SERVER_STATE,
METADATA_NO_ATTRIBUTES,
0,
DWORD_METADATA,
sizeof(DWORD),
(PBYTE)&dwData)
//
// See if Server State exists at this node,
// and pick up the current attributes, etc.
//
hresTempReturn = m_pcCom->ComMDGetMetaData(mdhCurrent,
pszNameBuf,
&mdrData,
&dwRequiredDataLen);
//
// PREFIX
// ComMDGetMetaData should not return success without setting the data
// value pointed to by dwData. I'm not sure if PREFIX is incapable of
// recognizing the extra level of indirection or if there is some path
// that I missed in reviewing ComMDGetMetaData. I'm going to shut down
// this warning, but I'll open an issue with the PREFIX guys.
//
/* INTRINSA suppress = uninitialized */
if ((SUCCEEDED(hresTempReturn)) && (dwData != MD_SERVER_STATE_STOPPED)) {
//
// Set the new data
//
dwData = MD_SERVER_STATE_STOPPED;
hresTempReturn = m_pcCom->ComMDSetMetaData(mdhCurrent,
pszNameBuf,
&mdrData);
}
}
}
hresReturn = m_pcCom->ComMDCloseMetaObject(mdhCurrent);
}
}