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.
677 lines
14 KiB
677 lines
14 KiB
/*++
|
|
|
|
Copyright (c) 1998-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
appladmin.cpp
|
|
|
|
Abstract:
|
|
|
|
This file contains implementation of:
|
|
CAppPoolMethod, CWebAppMethod
|
|
|
|
Author:
|
|
|
|
???
|
|
|
|
Revision History:
|
|
|
|
Mohit Srivastava 21-Jan-01
|
|
|
|
--*/
|
|
|
|
|
|
#include "iisprov.h"
|
|
#include "appladmin.h"
|
|
#include "MultiSzHelper.h"
|
|
#include "iiswmimsg.h"
|
|
|
|
//
|
|
// CApplAdmin
|
|
//
|
|
|
|
CAppPoolMethod::CAppPoolMethod()
|
|
{
|
|
m_pIABase = (IMSAdminBase2*)metabase;
|
|
|
|
HRESULT hr = CoCreateInstance(
|
|
CLSID_WamAdmin,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IIISApplicationAdmin,
|
|
(void**)&m_spAppAdmin);
|
|
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
|
|
CAppPoolMethod::~CAppPoolMethod()
|
|
{
|
|
}
|
|
|
|
void CAppPoolMethod::GetCurrentMode(
|
|
VARIANT* io_pvtServerMode)
|
|
/*++
|
|
|
|
Synopsis:
|
|
This method, unlike the others, is actually on the IIsWebService node.
|
|
|
|
Arguments: [io_pvtServerMode] -
|
|
|
|
--*/
|
|
{
|
|
DBG_ASSERT(io_pvtServerMode != NULL);
|
|
|
|
DWORD dwServerMode = 0;
|
|
VariantInit(io_pvtServerMode);
|
|
|
|
HRESULT hr = m_spAppAdmin->GetProcessMode(&dwServerMode);
|
|
THROW_ON_ERROR(hr);
|
|
|
|
io_pvtServerMode->vt = VT_I4;
|
|
io_pvtServerMode->lVal = dwServerMode;
|
|
}
|
|
|
|
void CAppPoolMethod::Start(
|
|
LPCWSTR i_wszMbPath)
|
|
{
|
|
DBG_ASSERT(i_wszMbPath != NULL);
|
|
|
|
m_wszPath = i_wszMbPath;
|
|
|
|
HRESULT hr = ExecMethod(MD_APPPOOL_COMMAND_START);
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
|
|
void CAppPoolMethod::Stop(
|
|
LPCWSTR i_wszMbPath)
|
|
{
|
|
DBG_ASSERT(i_wszMbPath != NULL);
|
|
|
|
m_wszPath = i_wszMbPath;
|
|
|
|
HRESULT hr = ExecMethod(MD_APPPOOL_COMMAND_STOP);
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
|
|
void CAppPoolMethod::RecycleAppPool(
|
|
LPCWSTR i_wszMbPath)
|
|
{
|
|
DBG_ASSERT(i_wszMbPath != NULL);
|
|
|
|
LPCWSTR wszAppPool = NULL;
|
|
GetPtrToAppPool(i_wszMbPath, &wszAppPool);
|
|
|
|
HRESULT hr = m_spAppAdmin->RecycleApplicationPool(wszAppPool);
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
|
|
void CAppPoolMethod::EnumAppsInPool(
|
|
LPCWSTR i_wszMbPath,
|
|
VARIANT* io_pvtApps)
|
|
/*++
|
|
|
|
Synopsis:
|
|
|
|
Arguments: [i_wszMbPath] -
|
|
[io_pvtApps] - Will be an array of strings
|
|
|
|
--*/
|
|
{
|
|
DBG_ASSERT(i_wszMbPath != NULL);
|
|
DBG_ASSERT(io_pvtApps != NULL);
|
|
|
|
CComBSTR sbstrApps = NULL;
|
|
VariantInit(io_pvtApps);
|
|
|
|
LPCWSTR wszAppPool = NULL;
|
|
GetPtrToAppPool(i_wszMbPath, &wszAppPool);
|
|
|
|
HRESULT hr = m_spAppAdmin->EnumerateApplicationsInPool(
|
|
wszAppPool,
|
|
&sbstrApps);
|
|
THROW_ON_ERROR(hr);
|
|
|
|
CMultiSz MultiSz;
|
|
|
|
hr = MultiSz.ToWmiForm(
|
|
sbstrApps,
|
|
io_pvtApps);
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
|
|
void CAppPoolMethod::DeleteAppPool(
|
|
LPCWSTR i_wszMbPath)
|
|
{
|
|
DBG_ASSERT(i_wszMbPath);
|
|
|
|
LPCWSTR wszAppPool = NULL;
|
|
GetPtrToAppPool(i_wszMbPath, &wszAppPool);
|
|
|
|
HRESULT hr = m_spAppAdmin->DeleteApplicationPool(wszAppPool);
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
|
|
//
|
|
// CAppPoolMethod - private methods
|
|
//
|
|
|
|
void CAppPoolMethod::GetPtrToAppPool(
|
|
LPCWSTR i_wszMbPath,
|
|
LPCWSTR* o_pwszAppPool)
|
|
/*++
|
|
|
|
Synopsis:
|
|
|
|
Arguments: [i_wszMbPath] -
|
|
[o_wszAppPool] - This is a ptr to i_wszMbPath. Does not need to be
|
|
freed by caller.
|
|
|
|
--*/
|
|
{
|
|
DBG_ASSERT(i_wszMbPath);
|
|
DBG_ASSERT(o_pwszAppPool);
|
|
DBG_ASSERT(*o_pwszAppPool == NULL);
|
|
|
|
DBG_ASSERT(i_wszMbPath[0] == L'/');
|
|
DBG_ASSERT(i_wszMbPath[1] != L'\0');
|
|
|
|
LPWSTR wszAppPool = (LPWSTR)wcsrchr(i_wszMbPath, L'/');
|
|
|
|
if (NULL == wszAppPool)
|
|
{
|
|
CIIsProvException e;
|
|
e.SetMC(WBEM_E_FAILED, IISWMI_INVALID_APPPOOL_CONTAINER, i_wszMbPath);
|
|
throw e;
|
|
}
|
|
|
|
*wszAppPool = L'\0';
|
|
if(_wcsicmp(i_wszMbPath, L"/LM/w3svc/AppPools") != 0)
|
|
{
|
|
*wszAppPool = L'/';
|
|
CIIsProvException e;
|
|
e.SetMC(WBEM_E_FAILED, IISWMI_INVALID_APPPOOL_CONTAINER, i_wszMbPath);
|
|
throw e;
|
|
}
|
|
|
|
*wszAppPool = L'/';
|
|
|
|
//
|
|
// Set out params on success
|
|
//
|
|
*o_pwszAppPool = wszAppPool + 1;
|
|
}
|
|
|
|
HRESULT
|
|
CAppPoolMethod::IISGetAppPoolState(
|
|
METADATA_HANDLE hObjHandle,
|
|
PDWORD pdwState
|
|
)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwBufferSize = sizeof(DWORD);
|
|
METADATA_RECORD mdrMDData;
|
|
LPBYTE pBuffer = (LPBYTE)pdwState;
|
|
|
|
MD_SET_DATA_RECORD(&mdrMDData,
|
|
MD_APPPOOL_STATE, // server state
|
|
METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,
|
|
DWORD_METADATA,
|
|
dwBufferSize,
|
|
pBuffer);
|
|
|
|
hr = m_pIABase->GetData(
|
|
hObjHandle,
|
|
m_wszPath,
|
|
&mdrMDData,
|
|
&dwBufferSize
|
|
);
|
|
|
|
if( hr == MD_ERROR_DATA_NOT_FOUND )
|
|
{
|
|
//
|
|
// If the data is not there, but the path exists, then the
|
|
// most likely cause is that the app pool is not running and
|
|
// this object was just created.
|
|
//
|
|
// Since MD_APPPOOL_STATE would be set as stopped if the
|
|
// app pool were running when the key is added, we'll just
|
|
// say that it's stopped.
|
|
//
|
|
*pdwState = MD_APPPOOL_STATE_STOPPED;
|
|
hr = S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
error:
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT
|
|
CAppPoolMethod::IISGetAppPoolWin32Error(
|
|
METADATA_HANDLE hObjHandle,
|
|
HRESULT* phrError)
|
|
{
|
|
DBG_ASSERT(phrError != NULL);
|
|
|
|
long lWin32Error = 0;
|
|
DWORD dwLen;
|
|
|
|
METADATA_RECORD mr = {
|
|
MD_WIN32_ERROR,
|
|
METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,
|
|
DWORD_METADATA,
|
|
sizeof(DWORD),
|
|
(unsigned char*)&lWin32Error,
|
|
0
|
|
};
|
|
|
|
HRESULT hr = m_pIABase->GetData(
|
|
hObjHandle,
|
|
m_wszPath,
|
|
&mr,
|
|
&dwLen);
|
|
if(hr == MD_ERROR_DATA_NOT_FOUND)
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
//
|
|
// Set out param
|
|
//
|
|
*phrError = HRESULT_FROM_WIN32(lWin32Error);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CAppPoolMethod::ExecMethod(
|
|
DWORD dwControl)
|
|
{
|
|
DWORD dwTargetState;
|
|
DWORD dwState = 0;
|
|
DWORD dwSleepTotal = 0L;
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrMbNode = S_OK;
|
|
METADATA_HANDLE hKey = 0;
|
|
|
|
switch(dwControl)
|
|
{
|
|
case MD_APPPOOL_COMMAND_STOP:
|
|
dwTargetState = MD_APPPOOL_STATE_STOPPED;
|
|
break;
|
|
|
|
case MD_APPPOOL_COMMAND_START:
|
|
dwTargetState = MD_APPPOOL_STATE_STARTED;
|
|
break;
|
|
|
|
default:
|
|
hr = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
hr = IISGetAppPoolState(METADATA_MASTER_ROOT_HANDLE, &dwState);
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
if (dwState == dwTargetState)
|
|
{
|
|
return (hr);
|
|
}
|
|
|
|
//
|
|
// Write the command to the metabase
|
|
//
|
|
hr = m_pIABase->OpenKey(
|
|
METADATA_MASTER_ROOT_HANDLE,
|
|
m_wszPath,
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
|
|
DEFAULT_TIMEOUT_VALUE, // 30 seconds
|
|
&hKey);
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hr = IISSetDword(hKey, MD_WIN32_ERROR, 0);
|
|
if(FAILED(hr))
|
|
{
|
|
m_pIABase->CloseKey(hKey);
|
|
goto error;
|
|
}
|
|
hr = IISSetDword(hKey, MD_APPPOOL_COMMAND, dwControl);
|
|
if(FAILED(hr))
|
|
{
|
|
m_pIABase->CloseKey(hKey);
|
|
goto error;
|
|
}
|
|
m_pIABase->CloseKey(hKey);
|
|
|
|
while (dwSleepTotal < MAX_SLEEP_INST)
|
|
{
|
|
hr = IISGetAppPoolState(METADATA_MASTER_ROOT_HANDLE, &dwState);
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
hrMbNode = 0;
|
|
hr = IISGetAppPoolWin32Error(METADATA_MASTER_ROOT_HANDLE, &hrMbNode);
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
//
|
|
// Done one way or another
|
|
//
|
|
if (dwState == dwTargetState)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If we haven't check the Win32 Error from the metabase
|
|
//
|
|
if(FAILED(hrMbNode))
|
|
{
|
|
hr = hrMbNode;
|
|
goto error;
|
|
}
|
|
|
|
//
|
|
// Still pending...
|
|
//
|
|
::Sleep(SLEEP_INTERVAL);
|
|
|
|
dwSleepTotal += SLEEP_INTERVAL;
|
|
}
|
|
|
|
if (dwSleepTotal >= MAX_SLEEP_INST)
|
|
{
|
|
//
|
|
// Timed out. If there is a real error in the metabase
|
|
// use it, otherwise use a generic timeout error
|
|
//
|
|
|
|
hr = HRESULT_FROM_WIN32(ERROR_SERVICE_REQUEST_TIMEOUT);
|
|
}
|
|
|
|
error :
|
|
|
|
return (hr);
|
|
}
|
|
|
|
HRESULT
|
|
CAppPoolMethod::IISSetDword(
|
|
METADATA_HANDLE hKey,
|
|
DWORD dwPropId,
|
|
DWORD dwValue
|
|
)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwBufferSize = sizeof(DWORD);
|
|
METADATA_RECORD mdrMDData;
|
|
LPBYTE pBuffer = (LPBYTE)&dwValue;
|
|
|
|
if (MD_WIN32_ERROR == dwPropId) {
|
|
MD_SET_DATA_RECORD(&mdrMDData,
|
|
dwPropId,
|
|
METADATA_VOLATILE,
|
|
IIS_MD_UT_SERVER,
|
|
DWORD_METADATA,
|
|
dwBufferSize,
|
|
pBuffer);
|
|
|
|
}
|
|
else {
|
|
MD_SET_DATA_RECORD(&mdrMDData,
|
|
dwPropId,
|
|
METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,
|
|
DWORD_METADATA,
|
|
dwBufferSize,
|
|
pBuffer);
|
|
}
|
|
|
|
hr = m_pIABase->SetData(
|
|
hKey,
|
|
L"",
|
|
&mdrMDData
|
|
);
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
error:
|
|
|
|
return(hr);
|
|
|
|
}
|
|
|
|
//
|
|
// CWebAppMethod
|
|
//
|
|
|
|
CWebAppMethod::CWebAppMethod()
|
|
{
|
|
HRESULT hr = CoCreateInstance(
|
|
CLSID_WamAdmin,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IIISApplicationAdmin,
|
|
(void**)&m_pAppAdmin
|
|
);
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_WamAdmin,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IWamAdmin2,
|
|
(void**)&m_pWamAdmin2
|
|
);
|
|
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
|
|
CWebAppMethod::~CWebAppMethod()
|
|
{
|
|
if(m_pAppAdmin)
|
|
m_pAppAdmin->Release();
|
|
|
|
if(m_pWamAdmin2)
|
|
m_pWamAdmin2->Release();
|
|
}
|
|
|
|
|
|
HRESULT CWebAppMethod::AppCreate(
|
|
LPCWSTR szMetaBasePath,
|
|
bool bInProcFlag
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
LPWSTR szActualName = NULL;
|
|
BOOL bActualCreation = FALSE;
|
|
|
|
hr = m_pAppAdmin->CreateApplication(
|
|
szMetaBasePath,
|
|
bInProcFlag ? 0 : 1, // 0 for InProc, 1 for Out of Proc
|
|
szActualName,
|
|
bActualCreation // Don't create - DefaultAppPool should already be there
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AppCreate2(
|
|
LPCWSTR szMetaBasePath,
|
|
long lAppMode
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
LPWSTR szActualName = NULL;
|
|
BOOL bActualCreation = FALSE;
|
|
|
|
hr = m_pAppAdmin->CreateApplication(
|
|
szMetaBasePath,
|
|
lAppMode,
|
|
szActualName,
|
|
bActualCreation // Don't create - DefaultAppPool should already be there
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AppCreate3(
|
|
LPCWSTR szMetaBasePath,
|
|
long lAppMode,
|
|
LPCWSTR szAppPoolName,
|
|
bool bCreatePool
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
LPWSTR szActualName;
|
|
BOOL bActualCreation = FALSE;
|
|
|
|
if (szAppPoolName) {
|
|
szActualName = (LPWSTR)szAppPoolName;
|
|
}
|
|
else {
|
|
szActualName = NULL;
|
|
}
|
|
|
|
if (bCreatePool != true) {
|
|
bActualCreation = FALSE;
|
|
}
|
|
else {
|
|
bActualCreation = TRUE;
|
|
}
|
|
|
|
hr = m_pAppAdmin->CreateApplication(
|
|
szMetaBasePath,
|
|
lAppMode,
|
|
szActualName,
|
|
bActualCreation // Don't create - DefaultAppPool should already be there
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AppDelete(
|
|
LPCWSTR szMetaBasePath,
|
|
bool bRecursive
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
hr = m_pAppAdmin->DeleteApplication(
|
|
szMetaBasePath,
|
|
bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AppUnLoad(
|
|
LPCWSTR szMetaBasePath,
|
|
bool bRecursive
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
hr = m_pWamAdmin2->AppUnLoad(
|
|
szMetaBasePath,
|
|
bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AppDisable(
|
|
LPCWSTR szMetaBasePath,
|
|
bool bRecursive
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
hr = m_pWamAdmin2->AppDeleteRecoverable(
|
|
szMetaBasePath,
|
|
bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AppEnable(
|
|
LPCWSTR szMetaBasePath,
|
|
bool bRecursive
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
hr = m_pWamAdmin2->AppRecover(
|
|
szMetaBasePath,
|
|
bRecursive ? TRUE : FALSE // Don't mix bool w/ BOOL
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AppGetStatus(
|
|
LPCWSTR szMetaBasePath,
|
|
DWORD* pdwStatus
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
hr = m_pWamAdmin2->AppGetStatus(
|
|
szMetaBasePath,
|
|
pdwStatus);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebAppMethod::AspAppRestart(
|
|
LPCWSTR a_szMetaBasePath
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwState = 0;
|
|
METADATA_HANDLE t_hKey = NULL;
|
|
CMetabase t_mb;
|
|
|
|
// open key
|
|
t_hKey = t_mb.OpenKey(a_szMetaBasePath, true);
|
|
|
|
// check app
|
|
hr = t_mb.WebAppCheck(t_hKey);
|
|
THROW_ON_ERROR(hr);
|
|
|
|
// get state
|
|
hr = t_mb.WebAppGetStatus(t_hKey, &dwState);
|
|
THROW_ON_ERROR(hr);
|
|
|
|
// change state value
|
|
dwState = dwState ? 0 : 1;
|
|
hr = t_mb.WebAppSetStatus(t_hKey, dwState);
|
|
THROW_ON_ERROR(hr);
|
|
|
|
// re-set back state value
|
|
dwState = dwState ? 0 : 1;
|
|
hr = t_mb.WebAppSetStatus(t_hKey, dwState);
|
|
THROW_ON_ERROR(hr);
|
|
|
|
t_mb.CloseKey(t_hKey);
|
|
|
|
return hr;
|
|
}
|