Leaked source code of windows server 2003
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.
 
 
 
 
 
 

531 lines
12 KiB

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1997
//
// File: common.cxx
//
// Contents: Microsoft ADs IIS Common routines
//
// History: 28-Feb-97 SophiaC Created.
//
//----------------------------------------------------------------------------
#include "iisext.hxx"
extern SERVER_CACHE * g_pServerCache;
extern WIN32_CRITSEC * g_pGlobalLock;
#pragma hdrstop
#define DEFAULT_TIMEOUT_VALUE 30000
//+------------------------------------------------------------------------
//
// Class: Common
//
// Purpose: Contains Winnt routines and properties that are common to
// all Winnt objects. Winnt objects get the routines and
// properties through C++ inheritance.
//
//-------------------------------------------------------------------------
HRESULT
MakeVariantFromStringArray(
LPWSTR pszList,
VARIANT *pvVariant
)
{
HRESULT hr = S_OK;
SAFEARRAY *aList = NULL;
SAFEARRAYBOUND aBound;
LPWSTR pszStrList;
WCHAR wchPath[MAX_PATH];
if (pszList != NULL)
{
long nCount = 0;
long i = 0;
pszStrList = pszList;
if (*pszStrList == L'\0') {
nCount = 1;
pszStrList++;
}
while (*pszStrList != L'\0') {
while (*pszStrList != L'\0') {
pszStrList++;
}
nCount++;
pszStrList++;
}
aBound.lLbound = 0;
aBound.cElements = nCount;
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
if ( aList == NULL )
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
pszStrList = pszList;
for (i = 0; i < nCount; i++ )
{
VARIANT v;
VariantInit(&v);
V_VT(&v) = VT_BSTR;
hr = ADsAllocString( pszStrList, &(V_BSTR(&v)));
BAIL_ON_FAILURE(hr);
hr = SafeArrayPutElement( aList, &i, &v );
VariantClear(&v);
BAIL_ON_FAILURE(hr);
pszStrList += wcslen(pszStrList) + 1;
}
VariantInit( pvVariant );
V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
V_ARRAY(pvVariant) = aList;
}
else
{
aBound.lLbound = 0;
aBound.cElements = 0;
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
if ( aList == NULL )
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
VariantInit( pvVariant );
V_VT(pvVariant) = VT_ARRAY | VT_VARIANT;
V_ARRAY(pvVariant) = aList;
}
return S_OK;
error:
if ( aList )
SafeArrayDestroy( aList );
return hr;
}
HRESULT
ReCacheAdminBase(
IN LPWSTR pszServerName,
IN OUT IMSAdminBase **ppAdminBase
)
{
HRESULT hr = S_OK;
SERVER_CACHE_ITEM * item = NULL;
DWORD dwThreadId;
IMSAdminBase * pAdminBase = *ppAdminBase;
IMSAdminBase * pOldAdminBase = *ppAdminBase;
// RPC error caused this function to be called, so try to
// recover the connection
hr = InitAdminBase(pszServerName, &pAdminBase);
BAIL_ON_FAILURE(hr);
// we will return this one, so save it in the OUT param
*ppAdminBase = pAdminBase;
// update the cache
dwThreadId = GetCurrentThreadId();
item = g_pServerCache->Find(pszServerName, dwThreadId);
if (item != NULL)
{
UninitAdminBase(pOldAdminBase);
item->UpdateAdminBase(pAdminBase, dwThreadId);
}
error :
RRETURN(hr);
}
HRESULT
OpenAdminBaseKey(
IN LPWSTR pszServerName,
IN LPWSTR pszPathName,
IN DWORD dwAccessType,
IN OUT IMSAdminBase **ppAdminBase,
OUT METADATA_HANDLE *phHandle
)
{
HRESULT hr;
IMSAdminBase *pAdminBase = *ppAdminBase;
METADATA_HANDLE RootHandle = NULL;
DWORD dwThreadId;
hr = pAdminBase->OpenKey(
METADATA_MASTER_ROOT_HANDLE,
pszPathName,
dwAccessType,
DEFAULT_TIMEOUT_VALUE,
&RootHandle
);
if (FAILED(hr)) {
if ((HRESULT_CODE(hr) == RPC_S_SERVER_UNAVAILABLE) ||
((HRESULT_CODE(hr) >= RPC_S_NO_CALL_ACTIVE) &&
(HRESULT_CODE(hr) <= RPC_S_CALL_FAILED_DNE)) ||
hr == RPC_E_DISCONNECTED) {
hr = ReCacheAdminBase(pszServerName, &pAdminBase);
BAIL_ON_FAILURE(hr);
*ppAdminBase = pAdminBase;
hr = pAdminBase->OpenKey(
METADATA_MASTER_ROOT_HANDLE,
pszPathName,
dwAccessType,
DEFAULT_TIMEOUT_VALUE,
&RootHandle
);
BAIL_ON_FAILURE(hr);
}
}
error :
if (FAILED(hr)) {
if (pAdminBase && RootHandle) {
pAdminBase->CloseKey(RootHandle);
}
}
else {
*phHandle = RootHandle;
}
RRETURN(hr);
}
VOID
CloseAdminBaseKey(
IN IMSAdminBase *pAdminBase,
IN METADATA_HANDLE hHandle
)
{
HRESULT hr;
if (pAdminBase) {
hr = pAdminBase->CloseKey(hHandle);
}
return;
}
HRESULT
InitAdminBase(
IN LPWSTR pszServerName,
OUT IMSAdminBase **ppAdminBase
)
{
HRESULT hr = S_OK;
COSERVERINFO csiName;
COSERVERINFO *pcsiParam = &csiName;
IClassFactory * pcsfFactory = NULL;
IMSAdminBase * pAdminBase = NULL;
IMSAdminBase * pAdminBaseT = NULL;
memset(pcsiParam, 0, sizeof(COSERVERINFO));
//
// special case to handle "localhost" to work-around ole32 bug
//
if (pszServerName == NULL || _wcsicmp(pszServerName,L"localhost") == 0) {
pcsiParam->pwszName = NULL;
}
else {
pcsiParam->pwszName = pszServerName;
}
csiName.pAuthInfo = NULL;
pcsiParam = &csiName;
hr = CoGetClassObject(
CLSID_MSAdminBase,
CLSCTX_SERVER,
pcsiParam,
IID_IClassFactory,
(void**) &pcsfFactory
);
BAIL_ON_FAILURE(hr);
hr = pcsfFactory->CreateInstance(
NULL,
IID_IMSAdminBase,
(void **) &pAdminBaseT
);
BAIL_ON_FAILURE(hr);
hr = pAdminBaseT->UnmarshalInterface((IMSAdminBaseW **)&pAdminBase);
pAdminBaseT->Release();
pAdminBaseT = NULL;
BAIL_ON_FAILURE(hr);
*ppAdminBase = pAdminBase;
error:
if (pcsfFactory) {
pcsfFactory->Release();
}
RRETURN(hr);
}
VOID
UninitAdminBase(
IN IMSAdminBase * pAdminBase
)
{
if (pAdminBase != NULL) {
pAdminBase->Release();
}
}
HRESULT
InitServerInfo(
IN LPWSTR pszServerName,
OUT IMSAdminBase ** ppObject
)
{
HRESULT hr = S_OK;
IMSAdminBase * pAdminBase = NULL;
SERVER_CACHE_ITEM * item;
BOOL Success;
DWORD dwThreadId;
ASSERT(g_pServerCache != NULL);
//
// We'll return the localhost machine config to the users if
// pszServerName == NULL, e.g. IIS:
//
if (pszServerName == NULL) {
pszServerName = L"Localhost";
}
dwThreadId = GetCurrentThreadId();
if ((item = g_pServerCache->Find(pszServerName, dwThreadId)) == NULL) {
//
// get pAdminBase
//
hr = InitAdminBase(pszServerName, &pAdminBase);
BAIL_ON_FAILURE(hr);
item = new SERVER_CACHE_ITEM(pszServerName,
pAdminBase,
dwThreadId,
Success);
if (item == NULL || !Success) {
if (item != NULL) {
UninitAdminBase(pAdminBase);
delete item;
}
RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
}
if (g_pServerCache->Insert(item) == FALSE) {
UninitAdminBase(pAdminBase);
delete item;
RRETURN(E_OUTOFMEMORY); // OUT_OF_MEMORY;
}
}
*ppObject = item->pAdminBase;
error :
RRETURN(hr);
}
HRESULT
InitWamAdmin(
IN LPWSTR pszServerName,
OUT IWamAdmin2 **ppWamAdmin
)
{
HRESULT hr = S_OK;
COSERVERINFO csiName;
COSERVERINFO *pcsiParam = &csiName;
IClassFactory * pcsfFactory = NULL;
IWamAdmin2 * pWamAdmin = NULL;
memset(pcsiParam, 0, sizeof(COSERVERINFO));
//
// special case to handle "localhost" to work-around ole32 bug
//
if (pszServerName == NULL || _wcsicmp(pszServerName,L"localhost") == 0) {
pcsiParam->pwszName = NULL;
}
else {
pcsiParam->pwszName = pszServerName;
}
csiName.pAuthInfo = NULL;
pcsiParam = &csiName;
hr = CoGetClassObject(
CLSID_WamAdmin,
CLSCTX_SERVER,
pcsiParam,
IID_IClassFactory,
(void**) &pcsfFactory
);
BAIL_ON_FAILURE(hr);
hr = pcsfFactory->CreateInstance(
NULL,
IID_IWamAdmin2,
(void **) &pWamAdmin
);
BAIL_ON_FAILURE(hr);
*ppWamAdmin = pWamAdmin;
error:
if (pcsfFactory) {
pcsfFactory->Release();
}
RRETURN(hr);
}
VOID
UninitWamAdmin(
IN IWamAdmin2 *pWamAdmin
)
{
if (pWamAdmin != NULL) {
pWamAdmin->Release();
}
}
HRESULT
BuildIISPathFromADsPath(
POBJECTINFO pObjectInfo,
LPWSTR pszIISPathName
)
{
DWORD dwNumComponents = 0;
DWORD i = 0;
dwNumComponents = pObjectInfo->NumComponents;
//
// wcscat "LM" to IIS Metabase path
//
wcscat(pszIISPathName, L"/LM/");
if (dwNumComponents) {
for (i = 0; i < dwNumComponents; i++) {
if (wcscmp(pObjectInfo->ComponentArray[i].szComponent, L"[Root]")){
wcscat(pszIISPathName, pObjectInfo->ComponentArray[i].szComponent);
}
else {
if( i == dwNumComponents -1 ) {
wcscat(pszIISPathName, L"/");
}
}
if( i < dwNumComponents -1 ) {
wcscat(pszIISPathName,L"/");
}
}
}
RRETURN(S_OK);
}
VOID
FreeObjectInfo(
POBJECTINFO pObjectInfo
)
{
if ( !pObjectInfo )
return;
if (pObjectInfo->ProviderName)
{
FreeADsStr( pObjectInfo->ProviderName );
}
if (pObjectInfo->TreeName)
{
FreeADsStr( pObjectInfo->TreeName );
}
if ((pObjectInfo->ComponentArray) && (pObjectInfo->NumComponents))
{
for ( DWORD i = 0; i < pObjectInfo->NumComponents; i++ ) {
if (pObjectInfo->ComponentArray[i].szComponent) {
FreeADsStr( pObjectInfo->ComponentArray[i].szComponent );
}
if (pObjectInfo->ComponentArray[i].szValue) {
FreeADsStr( pObjectInfo->ComponentArray[i].szValue );
}
}
}
if (pObjectInfo->ComponentArray) {
FreeADsMem(pObjectInfo->ComponentArray);
}
// We don't need to free pObjectInfo since the object is always a static
// variable on the stack.
}