254 lines
6.7 KiB
C++
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);
|
|
}
|
|
}
|