You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
409 lines
14 KiB
409 lines
14 KiB
|
|
/**********************************************************************/
|
|
/** 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 <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
}
|
|
#include <dbgutil.h>
|
|
#include <apiutil.h>
|
|
#include <loadadm.hxx>
|
|
#include <ole2.h>
|
|
#include <inetsvcs.h>
|
|
#include <ntsec.h>
|
|
#include <string.hxx>
|
|
#pragma warning(push, 3)
|
|
#include <stringau.hxx>
|
|
#pragma warning(pop)
|
|
#include <iadmext.h>
|
|
#include <admsub.hxx>
|
|
#include <imd.h>
|
|
#include <iiscnfg.h>
|
|
#include <initguid.h>
|
|
|
|
// IVANPASH
|
|
// It is just imposible to include the headers files defining the CLSID of the
|
|
// service extensions here. So I have to copy the definition.
|
|
|
|
// CLSID_WmRgSrv = {763A6C86-F30F-11D0-9953-00C04FD919C1}
|
|
// defined in iis\svcs\wam\wamreg\wmrgsv.idl
|
|
DEFINE_GUID(CLSID_WmRgSrv, 0X763A6C86, 0XF30F, 0X11D0, 0X99, 0X53, 0X00, 0XC0, 0X4F, 0XD9, 0X19, 0XC1);
|
|
|
|
// CLSID_ADMEXT = {C4376B00-F87B-11D0-A6A6-00A0C922E752}
|
|
// defined in iis\svcs\admex\secex\bootimp.hxx
|
|
// The extension is removed from IIS6/IIS5.1
|
|
// DEFINE_GUID(CLSID_ADMEXT, 0XC4376B00, 0XF87B, 0X11D0, 0XA6, 0XA6, 0X0, 0XA0, 0XC9, 0X22, 0XE7, 0X52);
|
|
|
|
// CLSID_W3EXTEND = {FCC764A0-2A38-11D1-B9C6-00A0C922E750}
|
|
// defined in iis\svcs\infocomm\extend\coimp.hxx
|
|
DEFINE_GUID(CLSID_W3EXTEND, 0XFCC764A0, 0X2A38, 0X11D1, 0XB9, 0XC6, 0X0, 0XA0, 0XC9, 0X22, 0XE7, 0X50);
|
|
|
|
|
|
static const CLSID *g_rgpclsidExtension[]=
|
|
{
|
|
&CLSID_W3EXTEND,
|
|
&CLSID_WmRgSrv
|
|
};
|
|
static const DWORD g_cExtensions = sizeof(g_rgpclsidExtension)/sizeof(*g_rgpclsidExtension);
|
|
|
|
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;
|
|
}
|
|
|
|
HRESULT
|
|
StartServiceExtension(
|
|
const CLSID *pclsidExtension)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IADMEXT *piaeExtension = NULL;
|
|
|
|
// Check args
|
|
if ( pclsidExtension == NULL )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
|
|
// Create the extension
|
|
hr = CoCreateInstance( *pclsidExtension,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IADMEXT,
|
|
(void**) &piaeExtension );
|
|
if ( FAILED(hr) )
|
|
{
|
|
// IVANPASH
|
|
// Not all service extensions are always registered.
|
|
// For example wamreg is registered when w3svc is installed.
|
|
// So if we cannot create a service extension, because the
|
|
// it is not registered yet, just ignore the error.
|
|
if ( hr == REGDB_E_CLASSNOTREG )
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
goto exit;
|
|
}
|
|
|
|
// Initialize the extension
|
|
hr = piaeExtension->Initialize();
|
|
if ( FAILED(hr) )
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
// Add the extension to the list of the running extensions
|
|
hr = AddServiceExtension(piaeExtension);
|
|
if ( FAILED(hr) )
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
// Do not clear the extension
|
|
piaeExtension = NULL;
|
|
|
|
exit:
|
|
DBG_ASSERT( SUCCEEDED(hr) );
|
|
|
|
// Cleanup
|
|
if ( piaeExtension != NULL )
|
|
{
|
|
StopServiceExtension( piaeExtension );
|
|
piaeExtension = NULL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
StartServiceExtensions()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwIndex;
|
|
|
|
DBG_ASSERT(g_piaecHead == NULL);
|
|
|
|
for ( dwIndex = 0; dwIndex < g_cExtensions; dwIndex++ )
|
|
{
|
|
hr = StartServiceExtension( g_rgpclsidExtension[dwIndex] );
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
DBG_ASSERT( SUCCEEDED(hr) );
|
|
|
|
// If failed
|
|
if ( FAILED(hr) )
|
|
{
|
|
// Stop all service extenstions
|
|
StopServiceExtensions();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
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_INPROC_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)) {
|
|
|
|
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;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
BOOL fNeedToWrite = TRUE;
|
|
|
|
// If we failed to deal with the buffer above then we won't
|
|
// be trying to write new clsids below, but we will need to delete
|
|
// the old clsids.
|
|
if ( SUCCEEDED (hresBufferError) )
|
|
{
|
|
// Figure out if the clsids have changed.
|
|
|
|
BUFFER MbBuffer;
|
|
DWORD dwBufferRequiredSize = 0;
|
|
|
|
if (MbBuffer.Resize( (dwMLSZLen + 1) * sizeof(WCHAR) ) )
|
|
{
|
|
|
|
METADATA_RECORD mdrDataRetrieve;
|
|
|
|
mdrDataRetrieve.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdrDataRetrieve.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdrDataRetrieve.dwMDDataType = MULTISZ_METADATA;
|
|
mdrDataRetrieve.dwMDDataLen = (dwMLSZLen + 1) * sizeof(WCHAR);
|
|
mdrDataRetrieve.pbMDData = (PBYTE)MbBuffer.QueryPtr();
|
|
mdrDataRetrieve.dwMDIdentifier = IISADMIN_EXTENSIONS_CLSID_MD_ID;
|
|
|
|
hresMDError = pcCom->ComMDGetMetaDataW( mdhExtension,
|
|
NULL,
|
|
&mdrDataRetrieve,
|
|
&dwBufferRequiredSize );
|
|
|
|
//
|
|
// if we succeeded in getting info then check if the info
|
|
// is of the right size and matches the data we all ready have.
|
|
//
|
|
if ( SUCCEEDED ( hresMDError ) )
|
|
{
|
|
// if we succeeded then we had enough space, so we can
|
|
// check the full size that we thought should match.
|
|
// then check the content of the data
|
|
if ( memcmp ( MbBuffer.QueryPtr(), bufCLSIDs.QueryPtr(), (dwMLSZLen + 1) * sizeof(WCHAR) ) == 0 )
|
|
{
|
|
fNeedToWrite = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( fNeedToWrite )
|
|
{
|
|
//
|
|
// We need to remove the old clsids.
|
|
//
|
|
pcCom->ComMDDeleteMetaData(
|
|
mdhExtension,
|
|
NULL,
|
|
MD_IISADMIN_EXTENSIONS,
|
|
MULTISZ_METADATA);
|
|
|
|
//
|
|
// Now we decide if we want to write the
|
|
// new clsids.
|
|
//
|
|
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);
|
|
|
|
} // end of writting because we had to.
|
|
} // end of clsids
|
|
} // end of needing to write
|
|
pcCom->ComMDCloseMetaObject(mdhExtension);
|
|
}
|
|
pcCom->ComMDTerminate(TRUE);
|
|
}
|
|
pcCom->Release();
|
|
}
|
|
if (pmallocOle != NULL) {
|
|
pmallocOle->Release();
|
|
}
|
|
}
|
|
}
|