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.
436 lines
13 KiB
436 lines
13 KiB
#define _WIN32_DCOM
|
|
|
|
#include <atlbase.h>
|
|
#include <atlconv.h>
|
|
|
|
#include <initguid.h>
|
|
#include <comdef.h>
|
|
|
|
#include <stdio.h>
|
|
#include <iadmw.h> // COM Interface header file.
|
|
#include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
|
|
|
|
#include <conio.h>
|
|
|
|
#include <shlobj.h>
|
|
#include <Shlwapi.h>
|
|
|
|
#include "util.h"
|
|
#include "auth.h"
|
|
#include "filecopy.h"
|
|
#include "mbase.h"
|
|
|
|
#define ORIGINAL_BUFFER_SIZE 256
|
|
#define KEYTYPE_NAME_BUFFER 32
|
|
|
|
#pragma comment(lib,"Shlwapi.lib")
|
|
|
|
|
|
|
|
HRESULT CreateAndCopyKey(
|
|
IMSAdminBase* pIMetaSource,
|
|
METADATA_HANDLE hMDSourceHandle, //metabase handle to the source key.
|
|
wchar_t* pszMDSourcePath, //path of the source relative to hMDSourceHandle.
|
|
IMSAdminBase* pIMetaTarget,
|
|
METADATA_HANDLE hMDDestHandle, //metabase handle to the destination.
|
|
wchar_t* pszMDDestPath, //path of the destination, relative to hMDDestHandle.
|
|
BOOL bMDCopySubKeys //whether to copy all subkey data
|
|
)
|
|
{
|
|
|
|
HRESULT hRes = S_OK;
|
|
|
|
DWORD indx = 0;
|
|
WCHAR SubKeyName[MAX_PATH*2];
|
|
_bstr_t bstrTargetSubKeyPath;
|
|
_bstr_t bstrSourceSubKeyPath;
|
|
|
|
ATLASSERT(pIMetaSource != NULL);
|
|
ATLASSERT(pIMetaTarget != NULL);
|
|
ATLASSERT(pszMDSourcePath);
|
|
ATLASSERT(pszMDDestPath);
|
|
|
|
|
|
// first this will create the destination key.
|
|
pIMetaTarget->AddKey(hMDDestHandle,pszMDDestPath);
|
|
|
|
while (SUCCEEDED(hRes))
|
|
{
|
|
hRes = pIMetaSource->EnumKeys(hMDSourceHandle, pszMDSourcePath, SubKeyName, indx);
|
|
if(SUCCEEDED(hRes)) {
|
|
|
|
bstrTargetSubKeyPath = pszMDDestPath;
|
|
bstrTargetSubKeyPath += L"/";
|
|
bstrTargetSubKeyPath += SubKeyName;
|
|
|
|
bstrSourceSubKeyPath = pszMDSourcePath;
|
|
bstrSourceSubKeyPath += L"/";
|
|
bstrSourceSubKeyPath += SubKeyName;
|
|
|
|
//wprintf(L"%s %s\n",SubKeyName,KeyType);
|
|
CreateAndCopyKey (pIMetaSource,hMDSourceHandle,bstrSourceSubKeyPath,pIMetaTarget,
|
|
hMDDestHandle,bstrTargetSubKeyPath, bMDCopySubKeys);
|
|
|
|
}
|
|
indx++;
|
|
|
|
} //while (SUCCEEDED(hRes))
|
|
|
|
hRes = EnumProperties(pIMetaSource,hMDSourceHandle,pszMDSourcePath,pIMetaTarget,hMDDestHandle,pszMDDestPath);
|
|
|
|
return hRes;
|
|
}
|
|
|
|
|
|
|
|
HRESULT EnumProperties(IMSAdminBase* pIMetaSource, METADATA_HANDLE hKeySource, wchar_t* SourceMDPath,
|
|
IMSAdminBase* pIMetaTarget, METADATA_HANDLE hKeyTarget, wchar_t* TargetMDPath )
|
|
{
|
|
|
|
HRESULT hRes = 0;
|
|
METADATA_RECORD mRec;
|
|
DWORD indx = 0;
|
|
DWORD dwReqBufLen = 0;
|
|
DWORD dwBufLen = ORIGINAL_BUFFER_SIZE;
|
|
PBYTE pbBuffer = new BYTE[dwBufLen];
|
|
wchar_t *ptemp = 0;
|
|
|
|
|
|
while (SUCCEEDED(hRes)){
|
|
|
|
mRec.dwMDAttributes = METADATA_ISINHERITED;
|
|
mRec.dwMDUserType = ALL_METADATA; //IIS_MD_UT_FILE ;
|
|
mRec.dwMDDataType = ALL_METADATA;
|
|
mRec.dwMDDataLen = dwBufLen;
|
|
mRec.pbMDData = pbBuffer;
|
|
|
|
hRes = pIMetaSource->EnumData(hKeySource, SourceMDPath, &mRec, indx, &dwReqBufLen);
|
|
if (hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER)) {
|
|
delete [] (pbBuffer);
|
|
pbBuffer = new BYTE[dwReqBufLen];
|
|
dwBufLen = dwReqBufLen;
|
|
mRec.dwMDDataLen = dwReqBufLen;
|
|
mRec.pbMDData = pbBuffer;
|
|
hRes = pIMetaSource->EnumData(hKeySource, SourceMDPath, &mRec, indx, &dwReqBufLen);
|
|
}
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
|
|
// write the property to the target
|
|
if( mRec.dwMDIdentifier == MD_APP_ROOT )
|
|
{
|
|
// mRec.pbMDData = new WCHAR[MAX_PATH];
|
|
wcscpy((LPWSTR)mRec.pbMDData, _bstr_t(L"/LM") + _bstr_t(TargetMDPath) );
|
|
mRec.dwMDDataLen = (DWORD)(wcslen((LPWSTR)mRec.pbMDData)+1)*2;
|
|
|
|
}
|
|
hRes = pIMetaTarget->SetData(hKeyTarget,TargetMDPath,&mRec);
|
|
if( !SUCCEEDED(hRes) )
|
|
return hRes;
|
|
}
|
|
// Increment the index.
|
|
indx++;
|
|
} // End while.
|
|
|
|
delete pbBuffer;
|
|
//wprintf(L"Done numerating properties set at: %s ...\n",SourceMDPath);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// INPUT canonicalized source path node in relation to the root key "/LM" ex: /w3svc/1
|
|
HRESULT CopyIISConfig(COSERVERINFO *pCoServerInfoSource, COSERVERINFO *pCoServerInfoTarget,
|
|
WCHAR *pwszSourceKey, _bstr_t &bstrTargetKey)
|
|
{
|
|
|
|
HRESULT hRes;
|
|
METADATA_HANDLE hKeySource;
|
|
METADATA_HANDLE hKeyTarget;
|
|
CComPtr <IMSAdminBase> pIMetaSource = 0L;
|
|
CComPtr <IMSAdminBase> pIMetaTarget = 0L;
|
|
BOOL bIsLocal;
|
|
_bstr_t bstrRootKey = L"/LM";
|
|
_bstr_t bstrTargetNode;
|
|
|
|
long lTargetSiteID;
|
|
|
|
|
|
// Declare a MULTI_QI for remote usage
|
|
MULTI_QI rgmqi[1] = { &IID_IMSAdminBase,0,0 };
|
|
|
|
|
|
ATLASSERT(pCoServerInfoSource);
|
|
ATLASSERT(pCoServerInfoTarget);
|
|
|
|
bIsLocal = IsServerLocal( (char*)_bstr_t(pCoServerInfoSource->pwszName) );
|
|
|
|
hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL, CLSCTX_ALL, pCoServerInfoSource,
|
|
1, rgmqi);
|
|
|
|
if(SUCCEEDED(hRes))
|
|
pIMetaSource = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
|
|
else
|
|
{
|
|
wprintf( L"error creating IMSAdminbase on machine: %s. HRESULT=%x\n", pCoServerInfoSource->pwszName, hRes);
|
|
return hRes;
|
|
}
|
|
|
|
if( pCoServerInfoSource->pAuthInfo->pAuthIdentityData->User )
|
|
{
|
|
//hRes = SetBlanket(pIMetaSource);
|
|
if (!SUCCEEDED(SetBlanket(pIMetaSource,pCoServerInfoSource->pAuthInfo->pAuthIdentityData->User,
|
|
pCoServerInfoSource->pAuthInfo->pAuthIdentityData->Domain,
|
|
pCoServerInfoSource->pAuthInfo->pAuthIdentityData->Password) ) )
|
|
{
|
|
_tprintf(_T("error setting COM impersonation: HRESULT=%x\n"), hRes);
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
if(bIsLocal)
|
|
//hRes = pIMetaSource->QueryInterface(IID_IMSAdminBase,(void**)&pIMetaTarget);
|
|
pIMetaTarget = pIMetaSource;
|
|
else
|
|
{
|
|
// Create the IMSAdminBase object on the target server
|
|
rgmqi[0].pItf = 0L;
|
|
rgmqi[0].hr = 0L;
|
|
|
|
hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL, CLSCTX_ALL, pCoServerInfoTarget,
|
|
1, rgmqi);
|
|
|
|
if(SUCCEEDED(hRes))
|
|
pIMetaTarget = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
|
|
else
|
|
{
|
|
_tprintf(_T("error creating IMSAdminbase on this machine: %s. HRESULT=%x\n"),
|
|
(char*)_bstr_t(pCoServerInfoTarget->pwszName), hRes);
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
// Open the metabase on the source and target
|
|
if( bIsLocal )
|
|
|
|
{
|
|
if( !SUCCEEDED( hRes = pIMetaSource->OpenKey(METADATA_MASTER_ROOT_HANDLE, bstrRootKey,
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10000, &hKeySource) ) )
|
|
{
|
|
_tprintf( _T("OpenKey() failed on the root key %s on server: %s, hr = %x\n"),
|
|
(char*)bstrRootKey, (char*)_bstr_t(pCoServerInfoSource->pwszName), hRes );
|
|
return hRes;
|
|
}
|
|
hKeyTarget = hKeySource;
|
|
}
|
|
else
|
|
{
|
|
|
|
// Get a handle to the Root key of the Source machine
|
|
if( !SUCCEEDED( hRes = pIMetaSource->OpenKey(METADATA_MASTER_ROOT_HANDLE, bstrRootKey,
|
|
METADATA_PERMISSION_READ , 10000, &hKeySource) ))
|
|
{
|
|
_tprintf( _T("OpenKey() failed on the root key %s on server: %s, hr = %x\n"),
|
|
(char*)bstrRootKey, (char*)_bstr_t(pCoServerInfoSource->pwszName), hRes );
|
|
return hRes;
|
|
}
|
|
|
|
// Get a handle to the Root key of the Target machine
|
|
if( !SUCCEEDED( hRes = pIMetaTarget->OpenKey(METADATA_MASTER_ROOT_HANDLE, bstrRootKey,
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, 10000, &hKeyTarget) ))
|
|
{
|
|
_tprintf( _T("OpenKey() failed on the root key %s on server: %s, hr = %x\n"),
|
|
(char*)bstrRootKey, (char*)_bstr_t(pCoServerInfoTarget->pwszName), hRes );
|
|
|
|
pIMetaSource->CloseKey(hKeySource);
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
if( bstrTargetKey.length() == 0 )
|
|
{
|
|
lTargetSiteID = GetAvailableSiteID(pIMetaTarget,hKeyTarget);
|
|
bstrTargetNode = L"/W3SVC/";
|
|
bstrTargetNode += _bstr_t(lTargetSiteID);
|
|
bstrTargetKey = bstrTargetNode;
|
|
}
|
|
else
|
|
bstrTargetNode = bstrTargetKey;
|
|
|
|
// replicate the metabase node
|
|
fwprintf(stderr, L"replicating IIS metabase properties set at: %s ...\n",pwszSourceKey);
|
|
hRes = CreateAndCopyKey(pIMetaSource,hKeySource, pwszSourceKey,
|
|
pIMetaTarget, hKeyTarget,bstrTargetNode, true );
|
|
|
|
|
|
if( !SUCCEEDED(hRes) )
|
|
{
|
|
_tprintf( _T("Error encountered in metabase copy operation\n") );
|
|
}
|
|
|
|
|
|
pIMetaSource->CloseKey(hKeySource);
|
|
if( !bIsLocal )
|
|
pIMetaTarget->CloseKey( hKeyTarget );
|
|
|
|
pIMetaSource = 0;
|
|
pIMetaTarget = 0;
|
|
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT ApplyMBFixUp(COSERVERINFO *pCoServerInfo, WCHAR * pwszKey, WCHAR * pwszAppPoolID,
|
|
PXCOPYTASKITEM pXCOPYList, WCHAR * pwszServerBinding, BOOL bApplyFPSE)
|
|
{
|
|
HRESULT hRes;
|
|
METADATA_HANDLE hKey;
|
|
CComPtr <IMSAdminBase> pIMeta = 0L;
|
|
MULTI_QI rgmqi[1] = { &IID_IMSAdminBase,0,0 };
|
|
WCHAR DataBuf[MAX_PATH];
|
|
memset (DataBuf,0,sizeof(DataBuf) );
|
|
PXCOPYTASKITEM pList = pXCOPYList;
|
|
bstr_t bstrRealTargetPath;
|
|
WCHAR *pTemp = NULL;
|
|
DWORD dwFPSEBOOL;
|
|
DWORD dwSize = sizeof(DWORD);
|
|
_bstr_t bstrCommandline;
|
|
TCHAR szOwsAdmPath[MAX_PATH];
|
|
|
|
ZeroMemory(szOwsAdmPath,sizeof(szOwsAdmPath));
|
|
|
|
ATLASSERT(pwszKey);
|
|
|
|
if( !pCoServerInfo )
|
|
return E_UNEXPECTED;
|
|
|
|
if( SUCCEEDED(hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL,
|
|
CLSCTX_ALL, pCoServerInfo,1, rgmqi) ) )
|
|
pIMeta = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
|
|
else
|
|
{
|
|
fwprintf( stderr, L"error creating IMSAdminbase on machine: %s. HRESULT=%x\n",
|
|
pCoServerInfo->pwszName, hRes);
|
|
return hRes;
|
|
}
|
|
|
|
if( UsesImpersonation(pCoServerInfo) )
|
|
{
|
|
if (!SUCCEEDED(hRes = SetBlanket(pIMeta,pCoServerInfo->pAuthInfo->pAuthIdentityData->User,
|
|
pCoServerInfo->pAuthInfo->pAuthIdentityData->Domain,
|
|
pCoServerInfo->pAuthInfo->pAuthIdentityData->Password) ) )
|
|
{
|
|
fwprintf( stderr, L"error setting CoSetProxyBlanket on machine: %s for user: %s HRESULT=%x\n",
|
|
pCoServerInfo->pwszName,pCoServerInfo->pAuthInfo->pAuthIdentityData->User, hRes);
|
|
pIMeta = 0;
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
if( !SUCCEEDED( hRes = pIMeta->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM",
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE , 10000, &hKey) ) )
|
|
{
|
|
fwprintf( stderr, L"Error opening key: %s on computer: %s. HRESULT=%x\n",
|
|
L"/LM", pCoServerInfo->pwszName, hRes);
|
|
pIMeta = 0;
|
|
return hRes;
|
|
}
|
|
|
|
if( !SUCCEEDED( hRes = CreateAppPool(pIMeta,hKey,pwszAppPoolID) ) )
|
|
{
|
|
return hRes;
|
|
}
|
|
|
|
|
|
// Now set the AppPoolID property of the Key
|
|
// wcscpy((LPWSTR)DataBuf, pwszAppPoolID);
|
|
|
|
hRes = SetPropertyData(pIMeta,hKey,_bstr_t(pwszKey) + _bstr_t(L"/root"), MD_APP_APPPOOL_ID, METADATA_INHERIT,
|
|
IIS_MD_UT_SERVER,STRING_METADATA, (PBYTE)pwszAppPoolID, (wcslen(pwszAppPoolID) + 1) * sizeof(WCHAR) );
|
|
|
|
// Loope thought the list and reset any Path direcrories
|
|
if( pList )
|
|
{
|
|
ATLASSERT(pList->pwszMBPath);
|
|
ATLASSERT(pList->pwszDestPath);
|
|
|
|
pTemp = wcsstr(_wcslwr(pList->pwszMBPath),L"/root");
|
|
bstrRealTargetPath = _bstr_t(pwszKey) + _bstr_t(pTemp);
|
|
|
|
|
|
hRes = SetPropertyData(pIMeta,hKey,bstrRealTargetPath, MD_VR_PATH, METADATA_INHERIT,
|
|
IIS_MD_UT_FILE,STRING_METADATA, pList->pwszDestPath, (wcslen(pList->pwszDestPath) + 1) * sizeof(WCHAR) );
|
|
|
|
while( pList->pNextItem )
|
|
{
|
|
pList = pList->pNextItem;
|
|
pTemp = wcsstr(_wcslwr(pList->pwszMBPath),L"/root");
|
|
bstrRealTargetPath = _bstr_t(pwszKey) + _bstr_t(pTemp);
|
|
hRes = SetPropertyData(pIMeta,hKey,bstrRealTargetPath, MD_VR_PATH, METADATA_INHERIT,
|
|
IIS_MD_UT_FILE,STRING_METADATA, pList->pwszDestPath, (wcslen(pList->pwszDestPath) + 1) * sizeof(WCHAR) );
|
|
}
|
|
}
|
|
|
|
// Set the serverbinding string if present
|
|
if( pwszServerBinding )
|
|
{
|
|
|
|
hRes = SetPropertyData(pIMeta,hKey,pwszKey, MD_SERVER_BINDINGS, METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,MULTISZ_METADATA, pwszServerBinding, (wcslen(pwszServerBinding) + 1) * sizeof(WCHAR) + 1 * sizeof(WCHAR));
|
|
}
|
|
|
|
if (bApplyFPSE)
|
|
{
|
|
// Check to see if the web is front page extended
|
|
bstrCommandline = "-o install -p /lm";
|
|
bstrCommandline += _bstr_t(pwszKey);
|
|
hRes = GetPropertyData(pIMeta,hKey,pwszKey,MD_FRONTPAGE_WEB,METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER, DWORD_METADATA, &dwFPSEBOOL, &dwSize );
|
|
|
|
if( SUCCEEDED(hRes) )
|
|
{
|
|
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMON , NULL, SHGFP_TYPE_CURRENT, szOwsAdmPath)) )
|
|
{
|
|
PathAppend(szOwsAdmPath, TEXT("Microsoft Shared\\Web Server Extensions\\50\\bin\\owsadm.exe") );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !SUCCEEDED(hRes = pIMeta->CloseKey(hKey) ) )
|
|
{
|
|
fwprintf( stderr, L"Error closing key: /LM/W3SVC on computer: %s. HRESULT=%x\n",
|
|
pCoServerInfo->pwszName, hRes);
|
|
}
|
|
|
|
pIMeta = 0;
|
|
|
|
if( bApplyFPSE )
|
|
{
|
|
fwprintf(stderr,L"reconfiguring FPSE settings...\n" );
|
|
MyCreateProcess(szOwsAdmPath,bstrCommandline,CREATE_NEW_PROCESS_GROUP,360000);
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT CreateAppPool(IMSAdminBase* pIMeta,METADATA_HANDLE hKey,WCHAR *pAppPoolID)
|
|
{
|
|
HRESULT hRes;
|
|
|
|
_bstr_t bstrAppPoolPath(L"/w3svc/AppPools/");
|
|
WCHAR DataBuf[MAX_PATH];
|
|
memset (DataBuf,0,sizeof(DataBuf) );
|
|
|
|
|
|
bstrAppPoolPath += pAppPoolID;
|
|
|
|
hRes = pIMeta->AddKey(hKey,bstrAppPoolPath);
|
|
|
|
// Set the KeyType property of the AppPool
|
|
// hRes = SetKeyType( pIMeta, hKey, bstrAppPoolPath, L"IIsApplicationPool" );
|
|
hRes = SetPropertyData(pIMeta,hKey,bstrAppPoolPath,MD_KEY_TYPE,METADATA_NO_ATTRIBUTES,
|
|
IIS_MD_UT_SERVER,STRING_METADATA,L"IIsApplicationPool",(wcslen(L"IIsApplicationPool") + 1) * sizeof(WCHAR) );
|
|
|
|
|
|
return hRes;
|
|
}
|