/*++ 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 #ifndef _NO_TRACING_ DECLARE_DEBUG_PRINTS_OBJECT(); #include 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); } }