/**********************************************************************/ /** Microsoft Windows NT **/ /** Copyright(c) Microsoft Corp., 1997 **/ /**********************************************************************/ /* admsub.cxx This module contains IISADMIN subroutines. FILE HISTORY: 7/7/97 michth created */ #define INITGUID extern "C" { #include #include #include } #include #include #include #include #include #include #include #include #include #include #include #include #include #include PIADMEXT_CONTAINER g_piaecHead = NULL; HRESULT AddServiceExtension(IADMEXT *piaeExtension) { HRESULT hresReturn = ERROR_SUCCESS; PIADMEXT_CONTAINER piaecExtension = new IADMEXT_CONTAINER; if (piaecExtension == NULL) { hresReturn = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } else { piaecExtension->piaeInstance = piaeExtension; piaecExtension->NextPtr = g_piaecHead; g_piaecHead = piaecExtension; } return hresReturn; } VOID StartServiceExtension(LPTSTR pszExtension) { HRESULT hresError; CLSID clsidExtension; IADMEXT *piaeExtension; STRAU strauCLSID(pszExtension); if (strauCLSID.IsValid() && (strauCLSID.QueryStrW() != NULL)) { hresError = CLSIDFromString(strauCLSID.QueryStrW(), &clsidExtension); if (SUCCEEDED(hresError)) { hresError = CoCreateInstance(clsidExtension, NULL, CLSCTX_SERVER, IID_IADMEXT, (void**) &piaeExtension); if (SUCCEEDED(hresError)) { hresError = piaeExtension->Initialize(); if (SUCCEEDED(hresError)) { hresError = AddServiceExtension(piaeExtension); if (FAILED(hresError)) { piaeExtension->Terminate(); } } if (FAILED(hresError)) { piaeExtension->Release(); } } } } } VOID StartServiceExtensions() { DBG_ASSERT(g_piaecHead == NULL); MDRegKey mdrkMain(HKEY_LOCAL_MACHINE, IISADMIN_EXTENSIONS_REG_KEY); if (GetLastError() == ERROR_SUCCESS) { MDRegKeyIter *pmdrkiCLSID = new MDRegKeyIter(mdrkMain); if ((pmdrkiCLSID != NULL) && (GetLastError() == ERROR_SUCCESS)) { LPTSTR pszExtension; for (DWORD dwIndex = 0; pmdrkiCLSID->Next(&pszExtension, NULL, dwIndex) == ERROR_SUCCESS; dwIndex++) { StartServiceExtension(pszExtension); } } delete (pmdrkiCLSID); } } BOOL RemoveServiceExtension(IADMEXT **ppiaeExtension) { BOOL bReturn = FALSE; if (g_piaecHead != NULL) { PIADMEXT_CONTAINER piaecExtension = g_piaecHead; *ppiaeExtension = g_piaecHead->piaeInstance; g_piaecHead = g_piaecHead->NextPtr; delete piaecExtension; bReturn = TRUE; } return bReturn; } VOID StopServiceExtension(IADMEXT *piaeExtension) { piaeExtension->Terminate(); piaeExtension->Release(); } VOID StopServiceExtensions() { IADMEXT *piaeExtension; while (RemoveServiceExtension(&piaeExtension)) { StopServiceExtension(piaeExtension); } DBG_ASSERT(g_piaecHead == NULL); } HRESULT AddClsidToBuffer(CLSID clsidDcomExtension, BUFFER *pbufCLSIDs, DWORD *pdwMLSZLen, LPMALLOC pmallocOle) { HRESULT hresReturn = S_OK; LPWSTR pszCLSID; if (!pbufCLSIDs->Resize((*pdwMLSZLen + CLSID_LEN) * sizeof(WCHAR))) { hresReturn = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } else { if (SUCCEEDED(StringFromCLSID(clsidDcomExtension, &pszCLSID))) { DBG_ASSERT(wcslen(pszCLSID) + 1 == CLSID_LEN); memcpy(((LPWSTR)pbufCLSIDs->QueryPtr()) + *pdwMLSZLen, pszCLSID, CLSID_LEN * sizeof(WCHAR)); (*pdwMLSZLen) += CLSID_LEN; if (pmallocOle != NULL) { pmallocOle->Free(pszCLSID); } } } return hresReturn; } VOID RegisterServiceExtensionCLSIDs() { HRESULT hresMDError; HRESULT hresExtensionError; HRESULT hresBufferError; HRESULT hresCom; CLSID clsidDcomExtension; DWORD i; IMDCOM * pcCom = NULL; METADATA_HANDLE mdhRoot; METADATA_HANDLE mdhExtension; METADATA_RECORD mdrData; PIADMEXT_CONTAINER piaecExtension; BUFFER bufCLSIDs; DWORD dwMLSZLen = 0; BOOL bAreCLSIDs = FALSE; LPMALLOC pmallocOle = NULL; hresCom = CoGetMalloc(1, &pmallocOle); if( SUCCEEDED(hresCom) ) { hresMDError = CoCreateInstance(CLSID_MDCOM, NULL, CLSCTX_SERVER, IID_IMDCOM, (void**) &pcCom); if (SUCCEEDED(hresMDError)) { hresMDError = pcCom->ComMDInitialize(); if (SUCCEEDED(hresMDError)) { hresMDError = pcCom->ComMDOpenMetaObject( METADATA_MASTER_ROOT_HANDLE, (PBYTE)IISADMIN_EXTENSIONS_CLSID_MD_KEY, METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ, MD_OPEN_DEFAULT_TIMEOUT_VALUE, &mdhExtension); if (hresMDError == RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND)) { hresMDError = pcCom->ComMDOpenMetaObject( METADATA_MASTER_ROOT_HANDLE, NULL, METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ, MD_OPEN_DEFAULT_TIMEOUT_VALUE, &mdhRoot); if (SUCCEEDED(hresMDError)) { hresMDError = pcCom->ComMDAddMetaObject( mdhRoot, (PBYTE)IISADMIN_EXTENSIONS_CLSID_MD_KEY); pcCom->ComMDCloseMetaObject(mdhRoot); if (SUCCEEDED(hresMDError)) { hresMDError = pcCom->ComMDOpenMetaObject( METADATA_MASTER_ROOT_HANDLE, (PBYTE)IISADMIN_EXTENSIONS_CLSID_MD_KEY, METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ, MD_OPEN_DEFAULT_TIMEOUT_VALUE, &mdhExtension); } } } if (SUCCEEDED(hresMDError)) { pcCom->ComMDDeleteMetaData( mdhExtension, NULL, MD_IISADMIN_EXTENSIONS, MULTISZ_METADATA); for (piaecExtension = g_piaecHead, hresBufferError = S_OK; (piaecExtension != NULL) && (SUCCEEDED(hresBufferError)); piaecExtension = piaecExtension->NextPtr) { hresMDError = ERROR_SUCCESS; for (i = 0; SUCCEEDED(hresExtensionError = piaecExtension->piaeInstance->EnumDcomCLSIDs(&clsidDcomExtension, i)); i++) { bAreCLSIDs = TRUE; hresBufferError = AddClsidToBuffer(clsidDcomExtension, &bufCLSIDs, &dwMLSZLen, pmallocOle); if (FAILED(hresBufferError)) { break; } } } if (bAreCLSIDs && SUCCEEDED(hresBufferError)) { if (bufCLSIDs.Resize((dwMLSZLen + 1) * sizeof(WCHAR))) { *(((LPWSTR)bufCLSIDs.QueryPtr()) + dwMLSZLen) = (WCHAR)'\0'; mdrData.dwMDAttributes = METADATA_NO_ATTRIBUTES; mdrData.dwMDUserType = IIS_MD_UT_SERVER; mdrData.dwMDDataType = MULTISZ_METADATA; mdrData.dwMDDataLen = (dwMLSZLen + 1) * sizeof(WCHAR); mdrData.pbMDData = (PBYTE)bufCLSIDs.QueryPtr(); mdrData.dwMDIdentifier = IISADMIN_EXTENSIONS_CLSID_MD_ID; hresMDError = pcCom->ComMDSetMetaDataW( mdhExtension, NULL, &mdrData); } } pcCom->ComMDCloseMetaObject(mdhExtension); } pcCom->ComMDTerminate(TRUE); } pcCom->Release(); } if (pmallocOle != NULL) { pmallocOle->Release(); } } }