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.
 
 
 
 
 
 

2519 lines
89 KiB

// ImportUI.cpp : Implementation of CImportUI
#include "stdafx.h"
#include "IISUIObj.h"
#include "ImportExportConfig.h"
#include "ExportUI.h"
#include "ImportUI.h"
#include "Defaults.h"
#include "util.h"
#include "ddxv.h"
#include <strsafe.h>
#define HIDD_IISUIOBJ_IMPORT 0x50401
#define LAST_USED_IMPORT_FILE _T("LastImportFile")
LPTSTR GimmiePointerToLastPart(LPCTSTR lpszMDPath)
{
LPTSTR lpszReturn = NULL;
ASSERT_PTR(lpszMDPath);
if (!lpszMDPath || !*lpszMDPath)
{
return NULL;
}
LPCTSTR lp = lpszMDPath + _tcslen(lpszMDPath) - 1;
//
// Skip trailing separator
//
if (*lp == SZ_MBN_SEP_CHAR)
{
--lp;
}
while (*lp && *lp != SZ_MBN_SEP_CHAR)
{
lpszReturn = (LPTSTR) (lp--);
}
return lpszReturn;
}
void InitListView(HWND hList)
{
LV_COLUMN lvCol;
RECT rect;
LONG width;
ZeroMemory(&rect, sizeof(rect));
GetWindowRect(hList, &rect);
width = rect.right - rect.left - 4; // -4 to prevent the horizontal scrollbar from appearing
ZeroMemory(&lvCol, sizeof(lvCol));
lvCol.mask = LVCF_TEXT | LVCF_WIDTH;
lvCol.fmt = LVCFMT_LEFT;
lvCol.cx = width;
ListView_InsertColumn(hList, 0, &lvCol);
return;
}
HRESULT DoImportConfigFromFile(PCONNECTION_INFO pConnectionInfo,BSTR bstrFileNameAndPath,BSTR bstrMetabaseSourcePath,BSTR bstrMetabaseDestinationPath,BSTR bstrPassword,DWORD dwImportFlags)
{
HRESULT hr = E_FAIL;
IMSAdminBase *pIMSAdminBase = NULL;
IMSAdminBase2 *pIMSAdminBase2 = NULL;
LPWSTR lpwstrTempPassword = NULL;
if (!pConnectionInfo)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
}
if (pConnectionInfo->pszUserPasswordEncrypted)
{
if (FAILED(DecryptMemoryPassword((LPWSTR) pConnectionInfo->pszUserPasswordEncrypted,&lpwstrTempPassword,pConnectionInfo->cbUserPasswordEncrypted)))
{
return HRESULT_FROM_WIN32(ERROR_DECRYPTION_FAILED);
}
}
CComAuthInfo auth(pConnectionInfo->pszMachineName,pConnectionInfo->pszUserName,lpwstrTempPassword);
if (!bstrFileNameAndPath)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
}
// Bufferfer overflow paranoia, make sure it's less than 255 characters long
if (wcslen(bstrFileNameAndPath) > (_MAX_PATH)){return RPC_S_STRING_TOO_LONG;}
if (wcslen(bstrMetabaseSourcePath) > (_MAX_PATH * 3)){return RPC_S_STRING_TOO_LONG;}
if (wcslen(bstrMetabaseDestinationPath) > (_MAX_PATH * 3)){return RPC_S_STRING_TOO_LONG;}
if (bstrPassword)
{
if (wcslen(bstrPassword) > (_MAX_PATH)){return RPC_S_STRING_TOO_LONG;}
}
if(FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
if(FAILED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{
return hr;
}
}
// RPC_C_AUTHN_LEVEL_DEFAULT 0
// RPC_C_AUTHN_LEVEL_NONE 1
// RPC_C_AUTHN_LEVEL_CONNECT 2
// RPC_C_AUTHN_LEVEL_CALL 3
// RPC_C_AUTHN_LEVEL_PKT 4
// RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 5
// RPC_C_AUTHN_LEVEL_PKT_PRIVACY 6
COSERVERINFO * pcsiName = auth.CreateServerInfoStruct(RPC_C_AUTHN_LEVEL_DEFAULT);
MULTI_QI res[1] =
{
{&IID_IMSAdminBase, NULL, 0}
};
if (FAILED(hr = CoCreateInstanceEx(CLSID_MSAdminBase,NULL,CLSCTX_ALL,pcsiName,1,res)))
{
goto DoImportConfigFromFile_Exit;
}
pIMSAdminBase = (IMSAdminBase *)res[0].pItf;
if (auth.UsesImpersonation())
{
if (FAILED(hr = auth.ApplyProxyBlanket(pIMSAdminBase)))
{
goto DoImportConfigFromFile_Exit;
}
// There is a remote IUnknown interface that lurks behind IUnknown.
// If that is not set, then the Release call can return access denied.
IUnknown * pUnk = NULL;
hr = pIMSAdminBase->QueryInterface(IID_IUnknown, (void **)&pUnk);
if(FAILED(hr))
{
return hr;
}
if (FAILED(hr = auth.ApplyProxyBlanket(pUnk)))
{
goto DoImportConfigFromFile_Exit;
}
pUnk->Release();pUnk = NULL;
}
if (FAILED(hr = pIMSAdminBase->QueryInterface(IID_IMSAdminBase2, (void **)&pIMSAdminBase2)))
{
goto DoImportConfigFromFile_Exit;
}
if (auth.UsesImpersonation())
{
if (FAILED(hr = auth.ApplyProxyBlanket(pIMSAdminBase2)))
{
goto DoImportConfigFromFile_Exit;
}
}
else
{
// the local call needs min RPC_C_IMP_LEVEL_IMPERSONATE
// for the pIMSAdminBase2 objects Import/Export functions!
if (FAILED(hr = SetBlanket(pIMSAdminBase2)))
{
//goto DoImportConfigFromFile_Exit;
}
}
//#define MD_IMPORT_INHERITED 0x00000001
//#define MD_IMPORT_NODE_ONLY 0x00000002
//#define MD_IMPORT_MERGE 0x00000004
IISDebugOutput(_T("Import:MetabasePathSource=%s,MetabasePathDestination=%s\r\n"),bstrMetabaseSourcePath,bstrMetabaseDestinationPath);
hr = pIMSAdminBase2->Import(bstrPassword,bstrFileNameAndPath,bstrMetabaseSourcePath,bstrMetabaseDestinationPath,dwImportFlags);
DoImportConfigFromFile_Exit:
IISDebugOutput(_T("Import:ret=0x%x\r\n"),hr);
if (lpwstrTempPassword)
{
// security percaution:Make sure to zero out memory that temporary password was used for.
SecureZeroMemory(lpwstrTempPassword,pConnectionInfo->cbUserPasswordEncrypted);
LocalFree(lpwstrTempPassword);
lpwstrTempPassword = NULL;
}
if (pIMSAdminBase2)
{
pIMSAdminBase2->Release();
pIMSAdminBase2 = NULL;
}
if (pIMSAdminBase)
{
pIMSAdminBase->Release();
pIMSAdminBase = NULL;
}
CoUninitialize();
return hr;
}
INT_PTR CALLBACK ShowSiteExistsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
EnableWindow(GetDlgItem(hDlg, IDC_RADIO1), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_RADIO2), TRUE);
CheckDlgButton(hDlg,IDC_RADIO1,BST_CHECKED);
CheckDlgButton(hDlg,IDC_RADIO2,BST_UNCHECKED);
CenterWindow(GetParent(hDlg), hDlg);
UpdateWindow(hDlg);
break;
case WM_CLOSE:
EndDialog(hDlg, IDCANCEL);
return FALSE;
break;
case WM_COMMAND:
switch (wParam)
{
case IDCANCEL:
EndDialog(hDlg, (int) wParam);
return FALSE;
case IDOK:
if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO1))
{
EndDialog(hDlg, (int) IDC_RADIO1);
}
else if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO2))
{
EndDialog(hDlg, (int) IDC_RADIO2);
}
return TRUE;
}
break;
}
return FALSE;
}
INT_PTR CALLBACK ShowVDirExistsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static LPTSTR szReturnString = NULL;
switch (msg)
{
case WM_INITDIALOG:
szReturnString = (LPTSTR) lParam;
EnableWindow(GetDlgItem(hDlg, IDC_RADIO1), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_RADIO2), TRUE);
CheckDlgButton(hDlg,IDC_RADIO1,BST_CHECKED);
CheckDlgButton(hDlg,IDC_RADIO2,BST_UNCHECKED);
SendDlgItemMessage(hDlg, IDC_EDIT_NEW_NAME, EM_LIMITTEXT, _MAX_PATH, 0);
EnableWindow(GetDlgItem(hDlg,IDC_EDIT_NEW_NAME), TRUE);
SetDlgItemText(hDlg, IDC_EDIT_NEW_NAME, _T(""));
CenterWindow(GetParent(hDlg), hDlg);
UpdateWindow(hDlg);
break;
case WM_CLOSE:
EndDialog(hDlg, IDCANCEL);
return FALSE;
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_EDIT_NEW_NAME:
{
switch (HIWORD(wParam))
{
case EN_CHANGE:
EditHideBalloon();
// If the contents of the edit control have changed,
if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO1))
{
EnableWindow(GetDlgItem(hDlg, IDOK),(SendMessage(GetDlgItem(hDlg,LOWORD(wParam)),EM_LINELENGTH,(WPARAM) -1, 0) != 0));
}
break;
case EN_MAXTEXT:
case EN_ERRSPACE:
// If the control is out of space, honk
MessageBeep (0);
break;
default:
break;
}
return TRUE;
}
case IDC_RADIO1:
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_NEW_NAME), TRUE);
EnableWindow(GetDlgItem(hDlg, IDOK),(SendMessage(GetDlgItem(hDlg,IDC_EDIT_NEW_NAME),EM_LINELENGTH,(WPARAM) -1, 0) != 0));
SetFocus(GetDlgItem(hDlg, IDC_EDIT_NEW_NAME));
return TRUE;
case IDC_RADIO2:
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_NEW_NAME), FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK),TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, (int) wParam);
return FALSE;
case IDOK:
TCHAR szEditString[_MAX_PATH + 1];
ZeroMemory(szEditString, sizeof(szEditString));
GetDlgItemText(hDlg, IDC_EDIT_NEW_NAME, szEditString, _MAX_PATH);
// sizeof szReturnString = _MAX_PATH + 1
StringCbCopy(szReturnString,_MAX_PATH + 1, szEditString);
if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO1))
{
EndDialog(hDlg, (int) IDC_RADIO1);
}
else if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO2))
{
EndDialog(hDlg, (int) IDC_RADIO2);
}
return TRUE;
}
break;
}
return FALSE;
}
INT_PTR CALLBACK
ShowAppPoolExistsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static LPTSTR szReturnString = NULL;
switch (msg)
{
case WM_INITDIALOG:
szReturnString = (LPTSTR) lParam;
EnableWindow(GetDlgItem(hDlg, IDC_RADIO1), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_RADIO2), TRUE);
CheckDlgButton(hDlg,IDC_RADIO1,BST_CHECKED);
CheckDlgButton(hDlg,IDC_RADIO2,BST_UNCHECKED);
SendDlgItemMessage(hDlg, IDC_EDIT_NEW_NAME, EM_LIMITTEXT, _MAX_PATH, 0);
EnableWindow(GetDlgItem(hDlg,IDC_EDIT_NEW_NAME), TRUE);
SetDlgItemText(hDlg, IDC_EDIT_NEW_NAME, _T(""));
CenterWindow(GetParent(hDlg), hDlg);
UpdateWindow(hDlg);
break;
case WM_CLOSE:
EndDialog(hDlg, IDCANCEL);
return FALSE;
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_EDIT_NEW_NAME:
{
switch (HIWORD(wParam))
{
case EN_CHANGE:
EditHideBalloon();
// If the contents of the edit control have changed,
if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO1))
{
EnableWindow(GetDlgItem(hDlg, IDOK),(SendMessage(GetDlgItem(hDlg,LOWORD(wParam)),EM_LINELENGTH,(WPARAM) -1, 0) != 0));
}
break;
case EN_MAXTEXT:
case EN_ERRSPACE:
// If the control is out of space, honk
MessageBeep (0);
break;
default:
break;
}
return TRUE;
}
case IDC_RADIO1:
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_NEW_NAME), TRUE);
EnableWindow(GetDlgItem(hDlg, IDOK),(SendMessage(GetDlgItem(hDlg,IDC_EDIT_NEW_NAME),EM_LINELENGTH,(WPARAM) -1, 0) != 0));
SetFocus(GetDlgItem(hDlg, IDC_EDIT_NEW_NAME));
return TRUE;
case IDC_RADIO2:
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_NEW_NAME), FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK),TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, (int) wParam);
return FALSE;
case IDOK:
TCHAR szEditString[_MAX_PATH + 1];
ZeroMemory(szEditString, sizeof(szEditString));
if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO1))
{
GetDlgItemText(hDlg, IDC_EDIT_NEW_NAME, szEditString, _MAX_PATH);
// check for invalid entry
TCHAR bad_chars[] = _T("\\/");
if (_tcslen(szEditString) != _tcscspn(szEditString, bad_chars))
{
CString strCaption;
CString strMsg;
strCaption.LoadString(_Module.GetResourceInstance(), IDS_MSGBOX_CAPTION);
strMsg.LoadString(_Module.GetResourceInstance(), IDS_INVALID_ENTRY);
MessageBox(hDlg,strMsg,strCaption,MB_ICONEXCLAMATION | MB_OK);
*szReturnString = 0;
}
else
{
// sizeof szReturnString = _MAX_PATH + 1
StringCbCopy(szReturnString,_MAX_PATH + 1, szEditString);
EndDialog(hDlg, (int) IDC_RADIO1);
}
}
else if (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_RADIO2))
{
*szReturnString = 0;
EndDialog(hDlg, (int) IDC_RADIO2);
}
}
break;
}
return FALSE;
}
INT_PTR CALLBACK ShowPasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static LPTSTR szReturnString = NULL;
switch (msg)
{
case WM_INITDIALOG:
szReturnString = (LPTSTR) lParam;
SendDlgItemMessage(hDlg, IDC_EDIT_GET_PASSWORD, EM_LIMITTEXT, PWLEN, 0);
SendDlgItemMessage(hDlg, IDC_EDIT_GET_PASSWORD, EM_SETPASSWORDCHAR, WPARAM('*'), 0);
EnableWindow(GetDlgItem(hDlg,IDC_EDIT_GET_PASSWORD), TRUE);
SetDlgItemText(hDlg, IDC_EDIT_GET_PASSWORD, _T(""));
UpdateWindow(hDlg);
break;
case WM_CLOSE:
EndDialog(hDlg, IDCANCEL);
return FALSE;
break;
case WM_COMMAND:
switch (wParam)
{
case IDCANCEL:
EndDialog(hDlg,(int)wParam);
return FALSE;
case IDOK:
{
TCHAR szPassword[PWLEN + 1];
SecureZeroMemory(szPassword, sizeof(szPassword));
GetDlgItemText(hDlg, IDC_EDIT_GET_PASSWORD, szPassword, PWLEN);
// sizeof szReturnString = _MAX_PATH + 1
StringCbCopy(szReturnString,_MAX_PATH + 1, szPassword);
// security percaution:Make sure to zero out memory that temporary password was used for.
SecureZeroMemory(szPassword, sizeof(szPassword));
EndDialog(hDlg,(int)wParam);
return TRUE;
}
}
break;
}
return FALSE;
}
HRESULT FillListBoxWithMultiSzData(HWND hList,LPCTSTR szKeyType,WCHAR * pszBuffer)
{
HRESULT hr = E_FAIL;
WCHAR szBuffer[_MAX_PATH + 1];
WCHAR * pszBufferTemp1 = NULL;
WCHAR * pszBufferTemp2 = NULL;
LVITEM ItemIndex;
LV_COLUMN lvcol;
INT iIndex = 0;
DWORD dwCount = 0;
BOOL bMultiSzIsPaired = FALSE;
BOOL bPleaseAddItem = TRUE;
BOOL bPleaseFilterThisSitesList = FALSE;
if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_SERVER_W) || 0 == _tcscmp(szKeyType,IIS_CLASS_FTP_SERVER_W) )
{
bPleaseFilterThisSitesList = TRUE;
}
pszBufferTemp1 = pszBuffer;
// forget this, it's always paired.
//bMultiSzIsPaired = IsMultiSzPaired(pszBufferTemp1);
bMultiSzIsPaired = TRUE;
// Erase existing data in list box...
ListView_DeleteAllItems(hList);
// Delete all of the columns.
for (int i=0;i <= ListView_GetItemCount(hList);i++)
{ListView_DeleteColumn(hList,i);}
//
// Decide on the column widths
//
RECT rect;
GetClientRect(hList, &rect);
LONG lWidth;
if (dwCount > (DWORD)ListView_GetCountPerPage(hList))
{
lWidth = (rect.right - rect.left) - GetSystemMetrics(SM_CYHSCROLL);
}
else
{
lWidth = rect.right - rect.left;
}
//
// Insert the component name column
//
memset(&lvcol, 0, sizeof(lvcol));
// zero memory
ZeroMemory(szBuffer, sizeof(szBuffer));
lvcol.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
lvcol.fmt = LVCFMT_LEFT;
lvcol.pszText = szBuffer;
lvcol.cx = lWidth;
LoadString(_Module.m_hInst, IDS_COL_LOCATION, szBuffer, ARRAYSIZE(szBuffer));
ListView_InsertColumn(hList, 0, &lvcol);
SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE,(WPARAM) 0, LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
if (!pszBufferTemp1)
{
return ERROR_SUCCESS;
}
while (1)
{
if (pszBufferTemp1)
{
hr = ERROR_SUCCESS;
ZeroMemory (&ItemIndex, sizeof(ItemIndex));
if (bMultiSzIsPaired)
{
bPleaseAddItem = TRUE;
// -----------
// paired list
// value1a value1b
// value2a value2b
// ...
// -----------
// make a copy of this baby
pszBufferTemp2 = pszBufferTemp1;
// then increment until we hit another null.
// to get value #2 -- which is the description
while (*pszBufferTemp1)
{
pszBufferTemp1++;
}
// check for the ending \0\0
if ( *(pszBufferTemp1+1) == NULL)
{
break;
}
else
{
pszBufferTemp1++;
}
// Check if pszBufferTemp1 is an empty string
// if it is then display something else.
//IISDebugOutput(_T("key=%s,friendly=%s\r\n"),pszBufferTemp2,pszBufferTemp1);
if (IsSpaces(pszBufferTemp1))
{
ItemIndex.pszText = pszBufferTemp2;
ItemIndex.pszText = GimmiePointerToLastPart(pszBufferTemp2);
}
else
{
ItemIndex.pszText = pszBufferTemp1;
}
if (bPleaseFilterThisSitesList)
{
// Check if it is a true site node -- like
// /LM/W3SVC/1
// /LM/MSFTPSVC/1
// and not /LM/W3SVC/SOMETHINGELSE
//
DWORD dwInstanceNum = CMetabasePath::GetInstanceNumber(pszBufferTemp2);
if (dwInstanceNum == 0 || dwInstanceNum == 0xffffffff)
{
// this is not a valid site path
bPleaseAddItem = FALSE;
}
}
if (bPleaseAddItem)
{
ItemIndex.mask = LVIF_TEXT | LVIF_PARAM;
ItemIndex.iItem = iIndex;
ItemIndex.lParam = (LPARAM) pszBufferTemp2;
iIndex = ListView_InsertItem (hList, &ItemIndex);
}
// then increment until we hit another null.
// to get value #2
while (*pszBufferTemp1)
{
pszBufferTemp1++;
}
// check for the ending \0\0
if ( *(pszBufferTemp1+1) == NULL)
{
break;
}
else
{
pszBufferTemp1++;
}
}
else
{
// -----------
// single list
// value1a
// value2a
// ...
// -----------
ItemIndex.mask = LVIF_TEXT | LVIF_PARAM;
ItemIndex.iItem = iIndex;
ItemIndex.pszText = pszBufferTemp1;
ItemIndex.lParam = (LPARAM) pszBufferTemp1;
iIndex = ListView_InsertItem (hList, &ItemIndex);
// then increment until we hit another null.
// to get value #2
while (*pszBufferTemp1)
{
pszBufferTemp1++;
}
}
// check for the ending \0\0
if ( *(pszBufferTemp1+1) == NULL)
{
break;
}
else
{
pszBufferTemp1++;
}
iIndex++;
}
}
return hr;
}
HRESULT DoEnumDataFromFile(PCONNECTION_INFO pConnectionInfo,BSTR bstrFileNameAndPath,BSTR bstrPathType,WCHAR ** pszMetabaseMultiszList)
{
HRESULT hr = E_FAIL;
IMSAdminBase *pIMSAdminBase = NULL;
IMSImpExpHelp * pIMSImpExpHelp = NULL;
WCHAR * pszBuffer = NULL;
DWORD dwBufferSize = 1;
LPWSTR lpwstrTempPassword = NULL;
if (!pConnectionInfo)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
}
if (pConnectionInfo->pszUserPasswordEncrypted)
{
if (FAILED(DecryptMemoryPassword((LPWSTR) pConnectionInfo->pszUserPasswordEncrypted,&lpwstrTempPassword,pConnectionInfo->cbUserPasswordEncrypted)))
{
return HRESULT_FROM_WIN32(ERROR_DECRYPTION_FAILED);
}
}
CComAuthInfo auth(pConnectionInfo->pszMachineName,pConnectionInfo->pszUserName,lpwstrTempPassword);
if (!bstrFileNameAndPath)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
}
if (!bstrPathType)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
}
// Buffer overflow paranoia, make sure it's less than 255 characters long
if (wcslen(bstrFileNameAndPath) > (_MAX_PATH)){return RPC_S_STRING_TOO_LONG;}
if (wcslen(bstrPathType) > (_MAX_PATH)){return RPC_S_STRING_TOO_LONG;}
if(FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
if(FAILED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{
return hr;
}
}
// RPC_C_AUTHN_LEVEL_DEFAULT 0
// RPC_C_AUTHN_LEVEL_NONE 1
// RPC_C_AUTHN_LEVEL_CONNECT 2
// RPC_C_AUTHN_LEVEL_CALL 3
// RPC_C_AUTHN_LEVEL_PKT 4
// RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 5
// RPC_C_AUTHN_LEVEL_PKT_PRIVACY 6
COSERVERINFO * pcsiName = auth.CreateServerInfoStruct(RPC_C_AUTHN_LEVEL_DEFAULT);
MULTI_QI res[1] =
{
{&IID_IMSAdminBase, NULL, 0}
};
if (FAILED(hr = CoCreateInstanceEx(CLSID_MSAdminBase,NULL,CLSCTX_ALL,pcsiName,1,res)))
{
goto DoEnumDataFromFile_Exit;
}
pIMSAdminBase = (IMSAdminBase *)res[0].pItf;
if (auth.UsesImpersonation())
{
if (FAILED(hr = auth.ApplyProxyBlanket(pIMSAdminBase)))
{
goto DoEnumDataFromFile_Exit;
}
// There is a remote IUnknown interface that lurks behind IUnknown.
// If that is not set, then the Release call can return access denied.
IUnknown * pUnk = NULL;
hr = pIMSAdminBase->QueryInterface(IID_IUnknown, (void **)&pUnk);
if(FAILED(hr))
{
return hr;
}
if (FAILED(hr = auth.ApplyProxyBlanket(pUnk)))
{
goto DoEnumDataFromFile_Exit;
}
pUnk->Release();pUnk = NULL;
}
if (FAILED(hr = pIMSAdminBase->QueryInterface(IID_IMSImpExpHelp, (void **)&pIMSImpExpHelp)))
{
goto DoEnumDataFromFile_Exit;
}
if (auth.UsesImpersonation())
{
if (FAILED(hr = auth.ApplyProxyBlanket(pIMSImpExpHelp)))
{
goto DoEnumDataFromFile_Exit;
}
}
else
{
// the local call needs min RPC_C_IMP_LEVEL_IMPERSONATE
// for the pIMSAdminBase2 objects Import/Export functions!
if (FAILED(hr = SetBlanket(pIMSImpExpHelp)))
{
//goto DoEnumDataFromFile_Exit;
}
}
IISDebugOutput(_T("EnumeratePathsInFile:FileName=%s,PathType=%s\r\n"),bstrFileNameAndPath,bstrPathType);
if (FAILED(hr = pIMSImpExpHelp->EnumeratePathsInFile(bstrFileNameAndPath, bstrPathType, dwBufferSize, pszBuffer, &dwBufferSize)))
{
goto DoEnumDataFromFile_Exit;
}
pszBuffer = (WCHAR *) ::CoTaskMemAlloc(dwBufferSize * sizeof(WCHAR));
if (NULL == pszBuffer)
{
hr = E_OUTOFMEMORY;
goto DoEnumDataFromFile_Exit;
}
if (FAILED(hr = pIMSImpExpHelp->EnumeratePathsInFile(bstrFileNameAndPath, bstrPathType, dwBufferSize, pszBuffer, &dwBufferSize)))
{
// free existing amount of space we asked for
if (pszBuffer)
{
::CoTaskMemFree(pszBuffer);
pszBuffer = NULL;
}
goto DoEnumDataFromFile_Exit;
}
if (!pszBuffer || dwBufferSize <= 0)
{
goto DoEnumDataFromFile_Exit;
}
// see if returned an empty list...
if (0 == _tcscmp(pszBuffer,_T("")))
{
goto DoEnumDataFromFile_Exit;
}
*pszMetabaseMultiszList = pszBuffer;
DoEnumDataFromFile_Exit:
IISDebugOutput(_T("EnumeratePathsInFile:ret=0x%x\r\n"),hr);
if (lpwstrTempPassword)
{
// security percaution:Make sure to zero out memory that temporary password was used for.
SecureZeroMemory(lpwstrTempPassword,pConnectionInfo->cbUserPasswordEncrypted);
LocalFree(lpwstrTempPassword);
lpwstrTempPassword = NULL;
}
if (pIMSImpExpHelp)
{
pIMSImpExpHelp->Release();
pIMSImpExpHelp = NULL;
}
if (pIMSAdminBase)
{
pIMSAdminBase->Release();
pIMSAdminBase = NULL;
}
CoUninitialize();
return hr;
}
void ImportDlgEnableButtons(HWND hDlg,PCOMMONDLGPARAM pcdParams,LPCTSTR lpszCurrentEnumedFileName)
{
BOOL fEnableListControl = FALSE;
BOOL fEnableOK = FALSE;
BOOL fEnableBrowse = FALSE;
BOOL fEnableEnum = FALSE;
TCHAR szFullFileName[_MAX_PATH + 1];
ZeroMemory(szFullFileName, sizeof(szFullFileName));
GetDlgItemText(hDlg, IDC_EDIT_FILE, szFullFileName, _MAX_PATH);
HWND hList = GetDlgItem(hDlg, IDC_LIST_OBJECT);
int ItemIndex = ListView_GetNextItem(hList, -1, LVNI_ALL);
if (ItemIndex < 0)
{
// no items in listview,disable what we need to
fEnableListControl = FALSE;
fEnableOK = FALSE;
}
else
{
fEnableListControl = TRUE;
// Check if something is selected
ItemIndex = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
if (ItemIndex < 0)
{
fEnableOK = FALSE;
}
else
{
fEnableOK = TRUE;
}
}
// Check if we should enable the listcontrol at all...
// see if the filename is the same
if (0 != _tcsicmp(_T(""),lpszCurrentEnumedFileName))
{
// check for % characters
// if there are any, expand them.
LPTSTR pch = _tcschr( (LPTSTR) szFullFileName, _T('%'));
if (pch && pcdParams->ConnectionInfo.IsLocal)
{
TCHAR szValue[_MAX_PATH + 1];
TCHAR szValue2[_MAX_PATH + 1];
StringCbCopy(szValue, sizeof(szValue), szFullFileName);
StringCbCopy(szValue2, sizeof(szValue2), lpszCurrentEnumedFileName);
if (!ExpandEnvironmentStrings( (LPCTSTR)szFullFileName, szValue, sizeof(szValue)/sizeof(TCHAR)))
{StringCbCopy(szValue, sizeof(szValue), szFullFileName);}
if (!ExpandEnvironmentStrings( (LPCTSTR)lpszCurrentEnumedFileName, szValue2, sizeof(szValue2)/sizeof(TCHAR)))
{StringCbCopy(szValue2, sizeof(szValue2), lpszCurrentEnumedFileName);}
if (0 != _tcsicmp(szValue,szValue2))
{
// it's not the same file
// so let's erase and disable the info in the list box.
fEnableListControl = FALSE;
}
}
else
{
if (0 != _tcsicmp(szFullFileName,lpszCurrentEnumedFileName))
{
// it's not the same file
// so let's erase and disable the info in the list box.
fEnableListControl = FALSE;
}
}
}
EnableWindow(hList, fEnableListControl);
if (FALSE == IsWindowEnabled(hList))
{
fEnableOK = FALSE;
}
// Set focus on listbox
//if (fEnableListControl){SetFocus(GetDlgItem(hDlg, IDC_LIST_OBJECT));}
fEnableEnum = (SendMessage(GetDlgItem(hDlg,IDC_EDIT_FILE),EM_LINELENGTH,(WPARAM) -1, 0) != 0);
// no browse button for remote case
if (pcdParams)
{
if (pcdParams->ConnectionInfo.IsLocal)
{fEnableBrowse = TRUE;}
}
// enable enum button
EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_ENUM_FILE),fEnableEnum);
// enable browse button
EnableWindow(GetDlgItem(hDlg,IDC_BUTTON_BROWSE), fEnableBrowse);
// enable OK button
EnableWindow(GetDlgItem(hDlg, IDOK), fEnableOK);
UpdateWindow(hDlg);
}
INT_PTR CALLBACK ShowImportDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static PCOMMONDLGPARAM pcdParams;
static TCHAR * pszMetabaseMultiszList = NULL;
static CString strCurrentFileNameEnum;
switch (msg)
{
case WM_INITDIALOG:
pcdParams = (PCOMMONDLGPARAM)lParam;
pszMetabaseMultiszList = NULL;
TCHAR szFullFileName1[_MAX_PATH + 1];
ZeroMemory(szFullFileName1, sizeof(szFullFileName1));
if (DefaultValueSettingsLoad(pcdParams->ConnectionInfo.pszMachineName,LAST_USED_IMPORT_FILE,szFullFileName1))
{
if (0 != _tcscmp(szFullFileName1, _T("")))
{
SetDlgItemText(hDlg, IDC_EDIT_FILE, szFullFileName1);
}
}
strCurrentFileNameEnum = _T("");
InitListView(GetDlgItem(hDlg, IDC_LIST_OBJECT));
CenterWindow(GetParent(hDlg), hDlg);
SetFocus(GetDlgItem(hDlg, IDC_EDIT_FILE));
ImportDlgEnableButtons(hDlg,pcdParams,strCurrentFileNameEnum);
EnableWindow(GetDlgItem(hDlg, IDC_LIST_OBJECT), FALSE);
break;
/*
case WM_ACTIVATE:
if (wParam == 0)
{
}
break;
*/
case WM_NOTIFY:
{
if((int)((LPNMHDR)lParam)->idFrom == IDC_LIST_OBJECT)
{
switch (((LPNMHDR)lParam)->code)
{
case LVN_ITEMCHANGED:
ImportDlgEnableButtons(hDlg,pcdParams,strCurrentFileNameEnum);
break;
case NM_CLICK:
ImportDlgEnableButtons(hDlg,pcdParams,strCurrentFileNameEnum);
break;
case NM_DBLCLK:
if((int)((LPNMHDR)lParam)->idFrom == IDC_LIST_OBJECT)
{
PostMessage(hDlg,WM_COMMAND,IDOK,NULL);
}
break;
default:
break;
}
}
return FALSE;
break;
}
case WM_CLOSE:
ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_LIST_OBJECT));
EndDialog(hDlg, IDCANCEL);
return FALSE;
break;
case WM_HELP:
LaunchHelp(hDlg,HIDD_IISUIOBJ_IMPORT);
return TRUE;
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_EDIT_FILE:
{
switch (HIWORD(wParam))
{
case EN_CHANGE:
EditHideBalloon();
{
// If the contents of the edit control have changed,
// check if it's the same as the file that is currently enumed...
HWND hList = GetDlgItem(hDlg, IDC_LIST_OBJECT);
if (ListView_GetItemCount(hList) > 0)
{
TCHAR szFullFileName3[_MAX_PATH + 1];
ZeroMemory(szFullFileName3, sizeof(szFullFileName3));
GetDlgItemText(hDlg, IDC_EDIT_FILE, szFullFileName3, _MAX_PATH);
// see if the filename is the same as this one!
if (!strCurrentFileNameEnum.IsEmpty())
{
if (0 != _tcsicmp(szFullFileName3,strCurrentFileNameEnum))
{
// it's not the same file
// so let's erase and disable the info in the list box.
EnableWindow(hList, FALSE);
}
}
}
ImportDlgEnableButtons(hDlg,pcdParams,strCurrentFileNameEnum);
break;
}
case EN_MAXTEXT:
case EN_ERRSPACE:
// If the control is out of space, honk
MessageBeep (0);
break;
default:
break;
}
return TRUE;
break;
}
case IDC_BUTTON_BROWSE:
{
TCHAR szOldFilePath[_MAX_PATH + 1];
GetDlgItemText(hDlg, IDC_EDIT_FILE, szOldFilePath, _MAX_PATH);
TCHAR szNewFilePath[_MAX_PATH + 1];
ZeroMemory(szNewFilePath, sizeof(szNewFilePath));
if (BrowseForFile(szOldFilePath,szNewFilePath,sizeof(szNewFilePath)))
{
if (0 != _tcsicmp(szNewFilePath, _T("")))
{
SetDlgItemText(hDlg, IDC_EDIT_FILE, szNewFilePath);
UpdateWindow(hDlg);
}
}
ImportDlgEnableButtons(hDlg,pcdParams,strCurrentFileNameEnum);
return FALSE;
break;
}
case IDC_BUTTON_ENUM_FILE:
{
BOOL bThingsAreKool = TRUE;
TCHAR szFullFileName2[_MAX_PATH + 1];
ZeroMemory(szFullFileName2, sizeof(szFullFileName2));
GetDlgItemText(hDlg, IDC_EDIT_FILE, szFullFileName2, _MAX_PATH);
// check for % characters
// if there are any, expand them.
LPTSTR pch = _tcschr( (LPTSTR) szFullFileName2, _T('%'));
if (pch)
{
if (pcdParams->ConnectionInfo.IsLocal)
{
TCHAR szValue[_MAX_PATH + 1];
StringCbCopy(szValue, sizeof(szValue), szFullFileName2);
if (!ExpandEnvironmentStrings( (LPCTSTR)szFullFileName2, szValue, sizeof(szValue)/sizeof(TCHAR)))
{
StringCbCopy(szValue, sizeof(szValue), szFullFileName2);
}
StringCbCopy(szFullFileName2, sizeof(szFullFileName2), szValue);
bThingsAreKool = TRUE;
}
else
{
// we don't support % characters on remote systems.
EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_FILE),_Module.GetResourceInstance(),IDS_FILENAME_NOREMOTE_EXPAND);
bThingsAreKool = FALSE;
}
}
if (bThingsAreKool)
{
if (pcdParams->ConnectionInfo.IsLocal)
{
if (!IsFileExist(szFullFileName2))
{
bThingsAreKool = FALSE;
EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_FILE),_Module.GetResourceInstance(),IDS_FILE_NOT_FOUND);
}
}
}
if (bThingsAreKool)
{
TCHAR szNodeType[50];
ZeroMemory(szNodeType, sizeof(szNodeType));
if (pcdParams->pszKeyType)
{
HRESULT hr = ERROR_SUCCESS;
StringCbCopy(szNodeType, sizeof(szNodeType), pcdParams->pszKeyType);
if (0 != _tcsicmp(szNodeType,_T("")))
{
HWND hList = GetDlgItem(hDlg, IDC_LIST_OBJECT);
// Erase existing data in list box...
ListView_DeleteAllItems(hList);
// free up the preiously used pointer if we already have memory freed
if (pszMetabaseMultiszList)
{
::CoTaskMemFree(pszMetabaseMultiszList);
pszMetabaseMultiszList = NULL;
}
if (SUCCEEDED(hr = DoEnumDataFromFile(&pcdParams->ConnectionInfo,szFullFileName2,szNodeType,&pszMetabaseMultiszList)))
{
strCurrentFileNameEnum = szFullFileName2;
if (pszMetabaseMultiszList)
{
// filter out stuff we don't want the user to see...
hr = FillListBoxWithMultiSzData(hList,szNodeType,pszMetabaseMultiszList);
//DumpStrInMultiStr(pszMetabaseMultiszList);
if (SUCCEEDED(hr))
{
if (0 != _tcscmp(szFullFileName2, _T("")))
{
DefaultValueSettingsSave(pcdParams->ConnectionInfo.pszMachineName,LAST_USED_IMPORT_FILE,szFullFileName2);
}
}
}
else
{
// check if there was anything returned...
// if there was then we got something back
// which doesn't have the objects we asked for
CString strMsg;
CString strFormat;
CString strObjectType;
BOOL bFound = FALSE;
//IIS_CLASS_WEB_SERVER_W
//IIS_CLASS_FTP_SERVER_W
//IIS_CLASS_WEB_VDIR_W
//IIS_CLASS_FTP_VDIR_W
//IIsApplicationPool
if (0 == _tcscmp(szNodeType,IIS_CLASS_WEB_SERVER_W))
{
strObjectType = IIS_CLASS_WEB_SERVER_W;
strObjectType.LoadString(_Module.GetResourceInstance(), IDS_STRING_WEB_SERVER);
bFound = TRUE;
}
else if (0 == _tcscmp(szNodeType,IIS_CLASS_FTP_SERVER_W))
{
strObjectType = IIS_CLASS_FTP_SERVER_W;
strObjectType.LoadString(_Module.GetResourceInstance(), IDS_STRING_FTP_SERVER);
bFound = TRUE;
}
else if (0 == _tcscmp(szNodeType,IIS_CLASS_WEB_VDIR_W))
{
strObjectType = IIS_CLASS_WEB_VDIR_W;
strObjectType.LoadString(_Module.GetResourceInstance(), IDS_STRING_WEB_VDIR);
bFound = TRUE;
}
else if (0 == _tcscmp(szNodeType,IIS_CLASS_FTP_VDIR_W))
{
strObjectType = IIS_CLASS_FTP_VDIR_W;
strObjectType.LoadString(_Module.GetResourceInstance(), IDS_STRING_FTP_VDIR);
bFound = TRUE;
}
else if (0 == _tcscmp(szNodeType,_T("IIsApplicationPool")))
{
strObjectType = _T("IIsApplicationPool");
strObjectType.LoadString(_Module.GetResourceInstance(), IDS_STRING_APP_POOL);
bFound = TRUE;
}
if (bFound)
{
strFormat.LoadString(_Module.GetResourceInstance(), IDS_IMPORT_MISMATCH);
strMsg.FormatMessage((LPCTSTR) strFormat,(LPCTSTR) strObjectType,(LPCTSTR) strObjectType,(LPCTSTR) strObjectType);
EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_FILE),(LPCTSTR) strMsg);
}
}
}
else
{
if (HRESULTTOWIN32(hr) == ERROR_FILE_NOT_FOUND)
{
EditShowBalloon(
GetDlgItem(hDlg, IDC_EDIT_FILE),
_Module.GetResourceInstance(),IDS_FILE_NOT_FOUND);
}
}
}
}
}
ImportDlgEnableButtons(hDlg,pcdParams,strCurrentFileNameEnum);
return FALSE;
break;
}
case IDC_LIST_OBJECT:
{
ImportDlgEnableButtons(hDlg,pcdParams,strCurrentFileNameEnum);
return FALSE;
break;
}
case IDHELP:
LaunchHelp(hDlg,HIDD_IISUIOBJ_IMPORT);
return TRUE;
case IDCANCEL:
{
ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_LIST_OBJECT));
// free up memory we may have allocated...
if (pszMetabaseMultiszList)
{
::CoTaskMemFree(pszMetabaseMultiszList);
pszMetabaseMultiszList = NULL;
}
EndDialog(hDlg,(int)wParam);
return FALSE;
break;
}
case IDOK:
if (TRUE == OnImportOK(hDlg,&pcdParams->ConnectionInfo,pcdParams->pszKeyType,pcdParams->pszMetabasePath,pcdParams->dwImportFlags))
{
TCHAR szFullFileName3[_MAX_PATH + 1];
ZeroMemory(szFullFileName3, sizeof(szFullFileName3));
GetDlgItemText(hDlg, IDC_EDIT_FILE, szFullFileName3, _MAX_PATH);
ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_LIST_OBJECT));
// free up memory we may have allocated...
if (pszMetabaseMultiszList)
{
::CoTaskMemFree(pszMetabaseMultiszList);
pszMetabaseMultiszList = NULL;
}
return TRUE;
}
else
{
return FALSE;
}
break;
}
break;
}
return FALSE;
}
BOOL OnImportOK(HWND hDlg,PCONNECTION_INFO pConnectionInfo,LPCTSTR szKeyType,LPCTSTR szCurrentMetabasePath,DWORD dwImportFlags)
{
BOOL bPleaseProceed = FALSE;
HRESULT hr = ERROR_SUCCESS;
INT iReturnedFlag = 0;
TCHAR szFullFileName[_MAX_PATH + 1];
TCHAR szNewPassword[PWLEN + 1];
LPTSTR pszSourcePath = NULL;
LPTSTR pszDestinationPathMungeAble = NULL;
DWORD dwDestinationPathMungeAble = 0;
LPTSTR pszSaveSafeCopy = NULL;
int ItemIndex = 0;
LVITEM lviGet;
memset(&lviGet, 0, sizeof(lviGet));
// Get the filepath which this tree was created from.
// could have changed since user edited edit box...
// so get the one that the tree was created from...
GetDlgItemText(hDlg, IDC_EDIT_FILE, szFullFileName, _MAX_PATH);
SecureZeroMemory(szNewPassword, sizeof(szNewPassword));
if (ListView_GetSelectedCount(GetDlgItem(hDlg, IDC_LIST_OBJECT)) <= 0)
{
goto OnImportOK_Exit;
}
// Get the metabase path the user selected..
ItemIndex = ListView_GetNextItem(GetDlgItem(hDlg, IDC_LIST_OBJECT), -1, LVNI_SELECTED);
if (-1 == ItemIndex)
{
goto OnImportOK_Exit;
}
ZeroMemory(&lviGet, sizeof(LVITEM));
lviGet.iItem = ItemIndex;
lviGet.iSubItem = 0;
lviGet.mask = LVIF_PARAM;
lviGet.lParam = NULL;
if (FALSE == ListView_GetItem(GetDlgItem(hDlg, IDC_LIST_OBJECT), &lviGet))
{
goto OnImportOK_Exit;
}
if (lviGet.lParam)
{
// figure out how big of a buffer do we need...
int iLen = _tcslen((LPTSTR) lviGet.lParam) + 1;
pszSourcePath = (LPTSTR) LocalAlloc(LPTR, iLen * sizeof(TCHAR));
if (!pszSourcePath)
{
goto OnImportOK_Exit;
}
StringCbCopy(pszSourcePath,(iLen * sizeof(TCHAR)), (WCHAR *) lviGet.lParam);
dwDestinationPathMungeAble = iLen * sizeof(TCHAR);
pszDestinationPathMungeAble = (LPTSTR) LocalAlloc(LPTR, dwDestinationPathMungeAble);
if (!pszDestinationPathMungeAble)
{
goto OnImportOK_Exit;
}
// make the destination path the same as what we got from the file!
StringCbCopy(pszDestinationPathMungeAble,dwDestinationPathMungeAble,pszSourcePath);
}
// Clean the metabase to work with Import...
// we have something like this in the list
// LM/W3SVC/1/ROOT/MyDir
// -----------------------------------
// Check to see if the destination path already exists!!!!
// if it already does, then popup a msg box to get another from the user!
// -----------------------------------
do
{
iReturnedFlag = 0;
IISDebugOutput(_T("CleanDestinationPathForVdirs:before:KeyType=%s,CurPath=%s,MetabasePathDestination=%s\r\n"),szKeyType,szCurrentMetabasePath,pszDestinationPathMungeAble);
if (FAILED(hr = CleanDestinationPathForVdirs(szKeyType,szCurrentMetabasePath,&pszDestinationPathMungeAble,&dwDestinationPathMungeAble)))
{
// something failed, let's just stay on this dialog
bPleaseProceed = FALSE;
goto OnImportOK_Exit;
}
IISDebugOutput(_T("CleanDestinationPathForVdirs:after :KeyType=%s,CurPath=%s,MetabasePathDestination=%s\r\n"),szKeyType,szCurrentMetabasePath,pszDestinationPathMungeAble);
// allocate the new space
int cbSafeCopy = (_tcslen(pszDestinationPathMungeAble)+ 1) * sizeof(TCHAR);
if (pszSaveSafeCopy)
{LocalFree(pszSaveSafeCopy);pszSaveSafeCopy=NULL;}
pszSaveSafeCopy = (LPTSTR) LocalAlloc(LPTR, cbSafeCopy);
if (!pszSaveSafeCopy)
{
bPleaseProceed = FALSE;
goto OnImportOK_Exit;
}
// copy the data to the new buffer
StringCbCopy(pszSaveSafeCopy,cbSafeCopy,pszDestinationPathMungeAble);
if (FALSE == GetNewDestinationPathIfEntryExists(hDlg,pConnectionInfo,szKeyType,&pszDestinationPathMungeAble,&dwDestinationPathMungeAble,&iReturnedFlag))
{
// cancelled, so let's just stay on this dialog
bPleaseProceed = FALSE;
goto OnImportOK_Exit;
}
else
{
if (1 == iReturnedFlag)
{
// The destination path already exists and we should overwrite
// we should overwrite
// Get the original destination path
// since it could already have been munged...
StringCbCopy(pszDestinationPathMungeAble,dwDestinationPathMungeAble,pszSaveSafeCopy);
break;
}
else if (2 == iReturnedFlag)
{
// the path didn't already exists so we can write it out now...
break;
}
else
{
// we got a new pszDestinationPathMungeAble
// go thru the loop again.
}
}
} while (TRUE);
// if we get down here
// it's because we have a pszDestinationPathMungeAble that we
// can write to or overwrite...
// we will never get here is the user cancelled...
do
{
// Perform the action...
// if it fails then ask for a password...
if (FAILED(hr = DoImportConfigFromFile(pConnectionInfo,szFullFileName,pszSourcePath,pszDestinationPathMungeAble,szNewPassword,dwImportFlags)))
{
// Check if it failed because the site/vdir/app pool already exists...
// if that's the error, then ask the user for a new path...
// If it failed because of bad password, then say so
if (0x8007052B == hr)
{
// See if the user wants to try again.
// if they do, then try it with the new password...
if (IDCANCEL == DialogBoxParam((HINSTANCE) _Module.m_hInst, MAKEINTRESOURCE(IDD_DIALOG_GET_PASSWORD), hDlg, ShowPasswordDlgProc, (LPARAM) szNewPassword))
{
// the user cancelled...
// so we should just stay on this page...
// cancelled, so let's just stay on this dialog
bPleaseProceed = FALSE;
break;
}
else
{
// try it again with the new password...
}
}
else if (HRESULTTOWIN32(hr) == ERROR_NO_MATCH)
{
bPleaseProceed = FALSE;
break;
}
else
{
// if it failed or some reason
// then get out of loop
// hr holds the error
CError err(hr);
err.MessageBox();
bPleaseProceed = FALSE;
break;
}
}
else
{
// Succeeded to import the config from the file
// let's get out
bPleaseProceed = TRUE;
ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_LIST_OBJECT));
//
// If we imported then, we need to do some fixup....
//
// make sure to append on the "root" stuff...
if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_SERVER_W))
{
// figure out how big of a buffer do we need...
int iLen = _tcslen((LPTSTR) pszSourcePath) + _tcslen(_T("/ROOT")) + 1;
LPTSTR pszNewPath = (LPTSTR) LocalAlloc(LPTR, iLen * sizeof(TCHAR));
if (pszNewPath)
{
StringCbCopy(pszNewPath,(iLen * sizeof(TCHAR)), (TCHAR *) pszSourcePath);
StringCbCat(pszNewPath,(iLen * sizeof(TCHAR)), (TCHAR *) _T("/ROOT"));
// figure out how big of a buffer do we need...
iLen = _tcslen((LPTSTR) pszDestinationPathMungeAble) + _tcslen(_T("/ROOT")) + 1;
LPTSTR pszNewPath2 = (LPTSTR) LocalAlloc(LPTR, iLen * sizeof(TCHAR));
if (pszNewPath2)
{
StringCbCopy(pszNewPath2,(iLen * sizeof(TCHAR)), (TCHAR *) pszDestinationPathMungeAble);
StringCbCat(pszNewPath2,(iLen * sizeof(TCHAR)), (TCHAR *) _T("/ROOT"));
hr = FixupImportAppRoot(pConnectionInfo,pszNewPath,pszNewPath2);
}
}
}
else if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_VDIR_W))
{
hr = FixupImportAppRoot(pConnectionInfo,pszSourcePath,pszDestinationPathMungeAble);
}
EndDialog(hDlg, IDOK);
break;
}
} while (FAILED(hr));
OnImportOK_Exit:
if (pszSourcePath)
{
LocalFree(pszSourcePath);pszSourcePath=NULL;
}
if (pszDestinationPathMungeAble)
{
LocalFree(pszDestinationPathMungeAble);pszDestinationPathMungeAble=NULL;
}
if (pszSaveSafeCopy)
{
LocalFree(pszSaveSafeCopy);pszSaveSafeCopy=NULL;
}
// make sure this doesn't hang around in memory
SecureZeroMemory(szNewPassword, sizeof(szNewPassword));
return bPleaseProceed;
}
// IIsWebServer
// IIsWebVirtualDir
// IIsFtpServer
// IIsFtpVirtualDir
// IIsApplicationPool
BOOL GetNewDestinationPathIfEntryExists(HWND hDlg,PCONNECTION_INFO pConnectionInfo,LPCTSTR szKeyType,LPTSTR * pszDestinationPathMungeAble,DWORD * pcbDestinationPathMungeAble,INT * iReturnedFlag)
{
BOOL bPleaseProceed = FALSE;
// IF iReturnedFlag = 0 then don't overwrite and don't use the new path
// IF iReturnedFlag = 1 then overwrite the existing entry
// IF iReturnedFlag = 2 then use the newly created path
*iReturnedFlag = 0;
if (!pConnectionInfo)
{
goto GetNewDestinationPathIfEntryExists_Exit;
}
BOOL bEntryAlreadyThere = IsMetabaseWebSiteKeyExistAuth(pConnectionInfo,*pszDestinationPathMungeAble);
if (FALSE == bEntryAlreadyThere)
{
bPleaseProceed = TRUE;
*iReturnedFlag = 2;
goto GetNewDestinationPathIfEntryExists_Exit;
}
// at this point
// the destination path already exists in the metabase
// Popup a dialog to get the user to pick a different DestinationPath
// figure out which one of the dialogs we need to display and get another path from the user...
if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_SERVER_W) || 0 == _tcscmp(szKeyType,IIS_CLASS_FTP_SERVER_W) )
{
INT_PTR iRet = DialogBox((HINSTANCE) _Module.m_hInst, MAKEINTRESOURCE(IDD_DIALOG_EXISTS_SITE), hDlg, ShowSiteExistsDlgProc);
switch(iRet)
{
case IDCANCEL:
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
break;
case IDC_RADIO1: // create new site...
{
bPleaseProceed = TRUE;
*iReturnedFlag = 0;
// Get the new size that we're going to need...
LPTSTR pNewPointer = NULL;
INT iNewSize = 0;
if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_SERVER_W))
{
iNewSize = _tcslen(SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_WEB SZ_MBN_SEP_STR) + 10 + 1;
}
else
{
iNewSize = _tcslen(SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_FTP SZ_MBN_SEP_STR) + 10 + 1;
}
pNewPointer = (LPTSTR) LocalAlloc(LPTR, iNewSize * sizeof(TCHAR));
if (!pNewPointer)
{
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
goto GetNewDestinationPathIfEntryExists_Exit;
}
// Generate a new site ID
if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_SERVER_W))
{
StringCbPrintf(pNewPointer,(iNewSize * sizeof(TCHAR)),SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_WEB SZ_MBN_SEP_STR _T("%d"), GetUniqueSite(SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_WEB));
}
else
{
StringCbPrintf(pNewPointer,(iNewSize * sizeof(TCHAR)),SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_FTP SZ_MBN_SEP_STR _T("%d"), GetUniqueSite(SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_FTP));
}
LocalFree((LPTSTR) *pszDestinationPathMungeAble);*pszDestinationPathMungeAble=NULL;
*pszDestinationPathMungeAble = pNewPointer;
*pcbDestinationPathMungeAble = (iNewSize * sizeof(TCHAR));
//IISDebugOutput(_T("Create new site:[%s]\r\n"),*pszDestinationPathMungeAble);
break;
}
case IDC_RADIO2: // replace existing..
bPleaseProceed = TRUE;
*iReturnedFlag = 1;
break;
default:
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
break;
}
}
else if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_VDIR_W) || 0 == _tcscmp(szKeyType,IIS_CLASS_FTP_VDIR_W))
{
TCHAR szMetabaseVDir[_MAX_PATH + 1];
ZeroMemory(szMetabaseVDir, sizeof(szMetabaseVDir));
INT_PTR iRet = DialogBoxParam((HINSTANCE) _Module.m_hInst, MAKEINTRESOURCE(IDD_DIALOG_EXISTS_VDIR), hDlg, ShowVDirExistsDlgProc, (LPARAM) szMetabaseVDir);
switch(iRet)
{
case IDCANCEL:
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
break;
case IDC_RADIO1: // create new site...
{
bPleaseProceed = TRUE;
*iReturnedFlag = 0;
// Get VDir Name that the user input on that screeen...
// Generate a VDir Name
CString strOriginalDestPath = *pszDestinationPathMungeAble;
CString strNewPath, strRemainder;
// Is this the root??
LPCTSTR lpPath1 = CMetabasePath::GetRootPath(strOriginalDestPath, strNewPath, &strRemainder);
if (lpPath1)
{
// Allocate enough space for the new path...
LPTSTR pNewPointer = NULL;
DWORD iNewSize = 0;
iNewSize = _tcslen(lpPath1) + _tcslen(szMetabaseVDir) + 2;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, iNewSize * sizeof(TCHAR));
if (!pNewPointer)
{
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
goto GetNewDestinationPathIfEntryExists_Exit;
}
// if this is the root dir...
StringCbCopy(pNewPointer,iNewSize * sizeof(TCHAR),lpPath1);
AddEndingMetabaseSlashIfNeedTo(pNewPointer,iNewSize * sizeof(TCHAR));
StringCbCat(pNewPointer,iNewSize * sizeof(TCHAR),szMetabaseVDir);
LocalFree((LPTSTR) *pszDestinationPathMungeAble);*pszDestinationPathMungeAble=NULL;
*pszDestinationPathMungeAble = pNewPointer;
*pcbDestinationPathMungeAble = (iNewSize * sizeof(TCHAR));
//IISDebugOutput(_T("Create new vdir:[%s]\r\n"),*pszDestinationPathMungeAble);
}
break;
}
case IDC_RADIO2: // replace existing...
bPleaseProceed = TRUE;
*iReturnedFlag = 1;
break;
default:
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
break;
}
}
else if (0 == _tcscmp(szKeyType,L"IIsApplicationPool"))
{
TCHAR szMetabaseAppPool[_MAX_PATH + 1];
ZeroMemory(szMetabaseAppPool,sizeof(szMetabaseAppPool));
INT_PTR iRet = DialogBoxParam((HINSTANCE) _Module.m_hInst, MAKEINTRESOURCE(IDD_DIALOG_EXISTS_APP_POOL), hDlg, ShowAppPoolExistsDlgProc, (LPARAM) szMetabaseAppPool);
switch(iRet)
{
case IDCANCEL:
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
break;
case IDC_RADIO1: // create new site...
{
bPleaseProceed = TRUE;
*iReturnedFlag = 0;
// Allocate enough space for the new path...
LPTSTR pNewPointer = NULL;
INT iNewSize = 0;
iNewSize = _tcslen(SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_WEB SZ_MBN_SEP_STR SZ_MBN_APP_POOLS SZ_MBN_SEP_STR) +
_tcslen(szMetabaseAppPool) + 1;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, iNewSize * sizeof(TCHAR));
if (!pNewPointer)
{
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
goto GetNewDestinationPathIfEntryExists_Exit;
}
// Get The New AppPool Name that the user input on that screeen...
StringCbPrintf(pNewPointer,(iNewSize * sizeof(TCHAR)),SZ_MBN_MACHINE SZ_MBN_SEP_STR SZ_MBN_WEB SZ_MBN_SEP_STR SZ_MBN_APP_POOLS SZ_MBN_SEP_STR _T("%s"),szMetabaseAppPool);
LocalFree((LPTSTR) *pszDestinationPathMungeAble);*pszDestinationPathMungeAble=NULL;
*pszDestinationPathMungeAble = pNewPointer;
*pcbDestinationPathMungeAble = (iNewSize * sizeof(TCHAR));
//IISDebugOutput(_T("Create new AppPool:[%s]\r\n"),*pszDestinationPathMungeAble);
break;
}
case IDC_RADIO2: // replace existing...
bPleaseProceed = TRUE;
*iReturnedFlag = 1;
break;
default:
bPleaseProceed = FALSE;
*iReturnedFlag = 0;
break;
}
}
else
{
// nothing matches, get out
bPleaseProceed = FALSE;
}
GetNewDestinationPathIfEntryExists_Exit:
return bPleaseProceed;
}
HRESULT CleanDestinationPathForVdirs(LPCTSTR szKeyType,LPCTSTR szCurrentMetabasePath,LPTSTR * pszDestinationPathMungeMe,DWORD * pcbDestinationPathMungeMe)
{
HRESULT hReturn = E_FAIL;
BOOL bCreateAFirstLevelVdir = FALSE;
LPTSTR pszLastPart = NULL;
LPTSTR pszLastPartNew = NULL;
int iLastPartNewSize = 0;
INT iChars = 0;
DWORD cbNewPointer = 0;
LPTSTR pNewPointer = NULL;
if (!CleanMetaPath(pszDestinationPathMungeMe,pcbDestinationPathMungeMe))
{
hReturn = E_POINTER;
}
if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_SERVER_W) || 0 == _tcscmp(szKeyType,IIS_CLASS_FTP_SERVER_W) )
{
hReturn = S_OK;
}
else if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_VDIR_W) || 0 == _tcscmp(szKeyType,IIS_CLASS_FTP_VDIR_W))
{
hReturn = E_FAIL;
// szCurrentMetabasePath probably looks like:
// lm/w3svc/500/ROOT/CurrentSite
// lm/w3svc/500/ROOT
// lm/w3svc/500
// *pszDestinationPathMungeMe probably looks like:
// lm/w3svc/23/ROOT/MyOldSite
// lm/w3svc/23/ROOT
//
// make *pszDestinationPathMungeMe look like lm/w3svc/500/ROOT/MyOldSite
//
// Get the lm/w3svc/sitenum part of szCurrentMetabasePath
//
if (0 == _tcscmp(szKeyType,IIS_CLASS_WEB_VDIR_W))
{
//IISDebugOutput(_T("CleanDestinationPathForVdirs:KeyType=%s,CurPath=%s,MetabasePathDestination=%s\r\n"),szKeyType,szCurrentMetabasePath,*pszDestinationPathMungeMe);
// Get Vdir we want to append...
// should look like "ROOT/MyVdir"
CString strSiteNode, strRemainder_WithRoot;
LPCTSTR lpPath1 = CMetabasePath::TruncatePath(3, *pszDestinationPathMungeMe, strSiteNode, &strRemainder_WithRoot);
if (lpPath1){}
if (strRemainder_WithRoot.IsEmpty())
{
hReturn = E_INVALIDARG;
goto CleanDestinationPathForVdirs_Exit;
}
if (IsWebSitePath(szCurrentMetabasePath))
{
// if our current metabase path is already a site node, then add them together
// /LM/W3SVC/1 + / + ROOT/MyVdir
// figure out how much space we need.
iChars = _tcslen(szCurrentMetabasePath) + _tcslen(strRemainder_WithRoot) + 2; // includes extra slash
cbNewPointer = iChars * sizeof(TCHAR);
// allocate the new space
pNewPointer = NULL;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, cbNewPointer);
if (!pNewPointer)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
// copy the data to the new buffer
StringCbCopy(pNewPointer,cbNewPointer,szCurrentMetabasePath);
AddEndingMetabaseSlashIfNeedTo(pNewPointer,cbNewPointer);
StringCbCat(pNewPointer,cbNewPointer,(LPCTSTR) strRemainder_WithRoot);
// Free the old one.
LocalFree(*pszDestinationPathMungeMe);*pszDestinationPathMungeMe=NULL;
// point to the new buffer
*pszDestinationPathMungeMe = pNewPointer;
*pcbDestinationPathMungeMe = cbNewPointer;
hReturn = S_OK;
}
else if (IsWebSiteVDirPath(szCurrentMetabasePath,FALSE))
{
// we failed to get farther, just treat it as a new vdir
bCreateAFirstLevelVdir = TRUE;
// if our current metabase path is already a vdir/physical path dir...then do some funky magic
pszLastPart = NULL;
pszLastPartNew = NULL;
iLastPartNewSize = 0;
BOOL bIsRootVdir = IsRootVDir(*pszDestinationPathMungeMe);
pszLastPart = GimmiePointerToLastPart(*pszDestinationPathMungeMe);
if (pszLastPart)
{
bCreateAFirstLevelVdir = FALSE;
iLastPartNewSize = _tcslen(pszLastPart) + 1;
pszLastPartNew = (LPTSTR) LocalAlloc(LPTR, iLastPartNewSize * sizeof(TCHAR));
if (!pszLastPartNew)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
StringCbCopy(pszLastPartNew, iLastPartNewSize * sizeof(TCHAR),pszLastPart);
}
// check if the site that the user is currently on, is a vdir or physical dir...
if (bCreateAFirstLevelVdir)
{
// /LM/W3SVC/1 + / + ROOT/MyNewVdir
CString strRemainder_Temp;
LPCTSTR lpPath2 = CMetabasePath::TruncatePath(3, szCurrentMetabasePath, strSiteNode, &strRemainder_Temp);
if (lpPath2){}
if (strSiteNode.IsEmpty())
{
hReturn = E_INVALIDARG;
goto CleanDestinationPathForVdirs_Exit;
}
// figure out how much space we need.
iChars = _tcslen(strSiteNode) + _tcslen(strRemainder_WithRoot) + 2; // includes extra slash
cbNewPointer = iChars * sizeof(TCHAR);
// allocate it
pNewPointer = NULL;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, cbNewPointer);
if (!pNewPointer)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
// Copy to new buffer
StringCbCopy(pNewPointer,cbNewPointer,strSiteNode);
AddEndingMetabaseSlashIfNeedTo(pNewPointer,cbNewPointer);
StringCbCat(pNewPointer,cbNewPointer,(LPCTSTR) strRemainder_WithRoot);
// Free the old one.
LocalFree(*pszDestinationPathMungeMe);*pszDestinationPathMungeMe=NULL;
// point to the new buffer
*pszDestinationPathMungeMe = pNewPointer;
*pcbDestinationPathMungeMe = cbNewPointer;
}
else
{
// /LM/W3SVC/1/ROOT/MyOldVdirThatIwantToKeep + / + MyNewVdir
// figure out how much space we need.
iChars = _tcslen(szCurrentMetabasePath) + 2; // includes extra slash
if (pszLastPartNew)
{
iChars = iChars + _tcslen(pszLastPartNew);
}
cbNewPointer = iChars * sizeof(TCHAR);
// allocate the new amt of space
pNewPointer = NULL;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, cbNewPointer);
if (!pNewPointer)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
// Copy to new buffer
StringCbCopy(pNewPointer,cbNewPointer,szCurrentMetabasePath);
if (pszLastPartNew)
{
// Don't copy over if the end of this part is root
// and the part we want to copy over is "root"
if (!bIsRootVdir)
{
AddEndingMetabaseSlashIfNeedTo(pNewPointer,cbNewPointer);
StringCbCat(pNewPointer,cbNewPointer,pszLastPartNew);
}
}
// Free the old one.
LocalFree(*pszDestinationPathMungeMe);*pszDestinationPathMungeMe=NULL;
// point to the new buffer
*pszDestinationPathMungeMe = pNewPointer;
*pcbDestinationPathMungeMe = cbNewPointer;
}
hReturn = S_OK;
}
else
{
hReturn = E_INVALIDARG;
goto CleanDestinationPathForVdirs_Exit;
}
}
else
{
// Get Vdir we want to append...
CString strSiteNode, strRemainder_WithRoot;
LPCTSTR lpPath3 = CMetabasePath::TruncatePath(3, *pszDestinationPathMungeMe, strSiteNode, &strRemainder_WithRoot);
if (lpPath3){}
if (strRemainder_WithRoot.IsEmpty())
{
hReturn = E_INVALIDARG;
goto CleanDestinationPathForVdirs_Exit;
}
if (IsFTPSitePath(szCurrentMetabasePath))
{
// if our current metabase path is already a site node, then add them together
// /LM/MSFTPSVC/1 + / + ROOT/MyVdir
// figure out how much space we need.
iChars = _tcslen(szCurrentMetabasePath) + _tcslen(strRemainder_WithRoot) + 2;
cbNewPointer = iChars * sizeof(TCHAR);
// allocate the new amt of space
pNewPointer = NULL;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, cbNewPointer);
if (!pNewPointer)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
// Copy to new buffer
StringCbCopy(pNewPointer,cbNewPointer,szCurrentMetabasePath);
AddEndingMetabaseSlashIfNeedTo(pNewPointer,cbNewPointer);
StringCbCat(pNewPointer,cbNewPointer,(LPCTSTR) strRemainder_WithRoot);
// Free the old one.
LocalFree(*pszDestinationPathMungeMe);*pszDestinationPathMungeMe=NULL;
// point to the new buffer
*pszDestinationPathMungeMe = pNewPointer;
*pcbDestinationPathMungeMe = cbNewPointer;
hReturn = S_OK;
}
else if (IsFTPSiteVDirPath(szCurrentMetabasePath,FALSE))
{
// we failed to get farther, just treat it as a new vdir
bCreateAFirstLevelVdir = TRUE;
// if our current metabase path is already a vdir/physical path dir...then do some funky magic
pszLastPart = NULL;
pszLastPartNew = NULL;
iLastPartNewSize = 0;
BOOL bIsRootVdir = IsRootVDir(*pszDestinationPathMungeMe);
pszLastPart = GimmiePointerToLastPart(*pszDestinationPathMungeMe);
if (pszLastPart)
{
bCreateAFirstLevelVdir = FALSE;
iLastPartNewSize = _tcslen(pszLastPart) + 1;
pszLastPartNew = (LPTSTR) LocalAlloc(LPTR, iLastPartNewSize * sizeof(TCHAR));
if (!pszLastPartNew)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
StringCbCopy(pszLastPartNew, iLastPartNewSize * sizeof(TCHAR),pszLastPart);
}
// check if the site that the user is currently on, is a vdir or physical dir...
if (bCreateAFirstLevelVdir)
{
CString strRemainder_Temp;
LPCTSTR lpPath4 = CMetabasePath::TruncatePath(3, szCurrentMetabasePath, strSiteNode, &strRemainder_Temp);
if (lpPath4){}
if (strSiteNode.IsEmpty())
{
hReturn = E_INVALIDARG;
goto CleanDestinationPathForVdirs_Exit;
}
// figure out how much space we need.
iChars = _tcslen(szCurrentMetabasePath) + _tcslen(strRemainder_WithRoot) + 2;
cbNewPointer = iChars * sizeof(TCHAR);
// allocate the new amt of space
pNewPointer = NULL;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, cbNewPointer);
if (!pNewPointer)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
// Copy to new buffer
StringCbCopy(pNewPointer,cbNewPointer,strSiteNode);
AddEndingMetabaseSlashIfNeedTo(pNewPointer,cbNewPointer);
StringCbCat(pNewPointer,cbNewPointer,(LPCTSTR) strRemainder_WithRoot);
// Free the old one.
LocalFree(*pszDestinationPathMungeMe);*pszDestinationPathMungeMe=NULL;
// point to the new buffer
*pszDestinationPathMungeMe = pNewPointer;
*pcbDestinationPathMungeMe = cbNewPointer;
}
else
{
// /LM/MSFTPSVC/1/ROOT/MyOldVdirThatIwantToKeep + / + MyNewVdir
// figure out how much space we need.
iChars = _tcslen(szCurrentMetabasePath) + 2;
if (pszLastPartNew)
{
iChars = iChars + _tcslen(pszLastPartNew);
}
cbNewPointer = iChars * sizeof(TCHAR);
// allocate the new amt of space
pNewPointer = NULL;
pNewPointer = (LPTSTR) LocalAlloc(LPTR, cbNewPointer);
if (!pNewPointer)
{
hReturn = E_OUTOFMEMORY;
goto CleanDestinationPathForVdirs_Exit;
}
// Copy to new buffer
StringCbCopy(pNewPointer,cbNewPointer,szCurrentMetabasePath);
if (pszLastPartNew)
{
// Don't copy over if the end of this part is root
// and the part we want to copy over is "root"
if (!bIsRootVdir)
{
AddEndingMetabaseSlashIfNeedTo(pNewPointer,cbNewPointer);
StringCbCat(pNewPointer,cbNewPointer,pszLastPartNew);
}
}
// Free the old one.
LocalFree(*pszDestinationPathMungeMe);*pszDestinationPathMungeMe=NULL;
// point to the new buffer
*pszDestinationPathMungeMe = pNewPointer;
*pcbDestinationPathMungeMe = cbNewPointer;
}
hReturn = S_OK;
}
else
{
hReturn = E_INVALIDARG;
goto CleanDestinationPathForVdirs_Exit;
}
}
}
else if (0 == _tcscmp(szKeyType,L"IIsApplicationPool"))
{
hReturn = S_OK;
}
else
{
// nothing matches, get out
hReturn = E_INVALIDARG;
}
CleanDestinationPathForVdirs_Exit:
if (pszLastPartNew)
{
LocalFree(pszLastPartNew);pszLastPartNew=NULL;
}
return hReturn;
}
#define DEFAULT_TIMEOUT_VALUE 30000
HRESULT FixupImportAppRoot(PCONNECTION_INFO pConnectionInfo,LPCWSTR pszSourcePath,LPCWSTR pszDestPath)
{
HRESULT hr = S_OK;
IMSAdminBase *pIMSAdminBase = NULL;
IMSAdminBase2 *pIMSAdminBase2 = NULL;
METADATA_HANDLE hObjHandle = NULL;
DWORD dwMDMetaID = MD_APP_ROOT;
DWORD dwBufferSize = 0;
DWORD dwReqdBufferSize = 0;
WCHAR *pBuffer = NULL;
DWORD dwRecBufSize = 0;
WCHAR *pRecBuf = NULL;
METADATA_RECORD mdrMDData;
const WCHAR c_slash = L'/';
WCHAR *pSourcePath = NULL;
DWORD dwSLen = 0;
WCHAR *pFoundStr = NULL;
WCHAR *pOrigBuffer = NULL;
WCHAR *pNewAppRoot = NULL;
BOOL bCoInitCalled = FALSE;
LPWSTR lpwstrTempPassword = NULL;
if ((!pszSourcePath)||(!pszDestPath))
{
return RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
}
if (!pConnectionInfo)
{
return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
}
if (pConnectionInfo->pszUserPasswordEncrypted)
{
if (FAILED(DecryptMemoryPassword((LPWSTR) pConnectionInfo->pszUserPasswordEncrypted,&lpwstrTempPassword,pConnectionInfo->cbUserPasswordEncrypted)))
{
return HRESULT_FROM_WIN32(ERROR_DECRYPTION_FAILED);
}
}
CComAuthInfo auth(pConnectionInfo->pszMachineName,pConnectionInfo->pszUserName,lpwstrTempPassword);
_wcsupr((WCHAR*)pszSourcePath);
_wcsupr((WCHAR*)pszDestPath);
// Make sure that pSourcePath has a trailing slash.
dwSLen = (DWORD)wcslen(pszSourcePath);
if (c_slash == pszSourcePath[dwSLen - 1])
{
pSourcePath = new WCHAR[dwSLen+ 1];
if (!pSourcePath)
{
hr = E_OUTOFMEMORY;
goto done;
}
StringCbCopyW(pSourcePath,((dwSLen+1) * sizeof(WCHAR)), pszSourcePath);
}
else
{
pSourcePath = new WCHAR[dwSLen + 2];
if (!pSourcePath)
{
hr = E_OUTOFMEMORY;
goto done;
}
StringCbCopyW(pSourcePath,((dwSLen+2) * sizeof(WCHAR)), pszSourcePath);
pSourcePath[dwSLen] = c_slash;
pSourcePath[dwSLen+1] = 0;
}
if(FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
if(FAILED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{
goto done;
}
}
bCoInitCalled = TRUE;
// RPC_C_AUTHN_LEVEL_DEFAULT 0
// RPC_C_AUTHN_LEVEL_NONE 1
// RPC_C_AUTHN_LEVEL_CONNECT 2
// RPC_C_AUTHN_LEVEL_CALL 3
// RPC_C_AUTHN_LEVEL_PKT 4
// RPC_C_AUTHN_LEVEL_PKT_INTEGRITY 5
// RPC_C_AUTHN_LEVEL_PKT_PRIVACY 6
COSERVERINFO * pcsiName = auth.CreateServerInfoStruct(RPC_C_AUTHN_LEVEL_DEFAULT);
MULTI_QI res[1] =
{
{&IID_IMSAdminBase, NULL, 0}
};
if (FAILED(hr = CoCreateInstanceEx(CLSID_MSAdminBase,NULL,CLSCTX_ALL,pcsiName,1,res)))
{
goto done;
}
pIMSAdminBase = (IMSAdminBase *)res[0].pItf;
if (auth.UsesImpersonation())
{
if (FAILED(hr = auth.ApplyProxyBlanket(pIMSAdminBase)))
{
goto done;
}
// There is a remote IUnknown interface that lurks behind IUnknown.
// If that is not set, then the Release call can return access denied.
IUnknown * pUnk = NULL;
hr = pIMSAdminBase->QueryInterface(IID_IUnknown, (void **)&pUnk);
if(FAILED(hr))
{
goto done;
}
if (FAILED(hr = auth.ApplyProxyBlanket(pUnk)))
{
goto done;
}
pUnk->Release();pUnk = NULL;
}
if (FAILED(hr = pIMSAdminBase->QueryInterface(IID_IMSAdminBase2, (void **)&pIMSAdminBase2)))
{
goto done;
}
if (auth.UsesImpersonation())
{
if (FAILED(hr = auth.ApplyProxyBlanket(pIMSAdminBase2)))
{
goto done;
}
}
else
{
// the local call needs min RPC_C_IMP_LEVEL_IMPERSONATE
// for the pIMSAdminBase2 objects Import/Export functions!
if (FAILED(hr = SetBlanket(pIMSAdminBase2)))
{
//goto done;
}
}
hr = pIMSAdminBase2->OpenKey( METADATA_MASTER_ROOT_HANDLE,
(LPWSTR)L"",
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
DEFAULT_TIMEOUT_VALUE,
&hObjHandle
);
if (FAILED(hr))
{
goto done;
}
hr = pIMSAdminBase2->GetDataPaths(
hObjHandle,
pszDestPath,
dwMDMetaID,
ALL_METADATA,
dwBufferSize,
(LPWSTR)L"",
&dwReqdBufferSize
);
if (FAILED(hr))
{
if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
{
goto done;
}
}
pBuffer = new WCHAR[dwReqdBufferSize];
if (!pBuffer)
{
hr = E_OUTOFMEMORY;
goto done;
}
dwBufferSize = dwReqdBufferSize;
hr = pIMSAdminBase2->GetDataPaths(
hObjHandle,
pszDestPath,
dwMDMetaID,
ALL_METADATA,
dwBufferSize,
(LPWSTR)pBuffer,
&dwReqdBufferSize
);
pOrigBuffer = pBuffer;
if (FAILED(hr))
{
goto done;
}
// look at AppRoot at each path
while (*pBuffer)
{
// Create the new AppRoot for this record...
int iNewAppRootLen = wcslen(pBuffer) + 1;
pNewAppRoot = new WCHAR[iNewAppRootLen];
if (!pNewAppRoot)
{
hr = E_OUTOFMEMORY;
goto done;
}
StringCbCopy(pNewAppRoot,iNewAppRootLen * sizeof(WCHAR),pBuffer);
_wcsupr((WCHAR*)pNewAppRoot);
// make sure it doesn't end with a slash...
if (_T('/') == pNewAppRoot[iNewAppRootLen - 2])
{
// cut if off if it's there
pNewAppRoot[iNewAppRootLen - 2] = '\0';
}
MD_SET_DATA_RECORD(&mdrMDData,
dwMDMetaID,
METADATA_INHERIT,
IIS_MD_UT_FILE,
STRING_METADATA,
dwRecBufSize,
pRecBuf);
hr = pIMSAdminBase2->GetData(
hObjHandle,
pBuffer,
&mdrMDData,
&dwRecBufSize
);
if (FAILED(hr))
{
if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
{
goto done;
}
}
pRecBuf = new WCHAR[dwRecBufSize + 1]; // for extra slash if we need it
if (!pRecBuf)
{
hr = E_OUTOFMEMORY;
goto done;
}
MD_SET_DATA_RECORD(&mdrMDData,
dwMDMetaID,
METADATA_INHERIT,
IIS_MD_UT_FILE,
STRING_METADATA,
dwRecBufSize,
pRecBuf);
hr = pIMSAdminBase2->GetData(
hObjHandle,
pBuffer,
&mdrMDData,
&dwRecBufSize
);
if (FAILED(hr))
{
goto done;
}
_wcsupr(pRecBuf);
// Make sure that pRecBuf has a trailing slash.
dwSLen = (DWORD)wcslen(pRecBuf);
if (c_slash != pRecBuf[dwSLen - 1])
{
pRecBuf[dwSLen] = c_slash;
pRecBuf[dwSLen+1] = 0;
}
pFoundStr = wcsstr(pRecBuf,pSourcePath);
if (pFoundStr)
{
if (pNewAppRoot)
{
// now set the new AppRoot
MD_SET_DATA_RECORD(&mdrMDData,
dwMDMetaID,
METADATA_INHERIT,
IIS_MD_UT_FILE,
STRING_METADATA,
(DWORD)((wcslen(pNewAppRoot)+1)*sizeof(WCHAR)),
(PBYTE)pNewAppRoot);
hr = pIMSAdminBase2->SetData(
hObjHandle,
pBuffer,
&mdrMDData
);
IISDebugOutput(_T("FixupImportAppRoot:NewAppRoot=%s\r\n"),(LPCTSTR) pNewAppRoot);
}
else
{
hr = E_OUTOFMEMORY;
}
if (FAILED(hr))
{
goto done;
}
if (pNewAppRoot)
{
delete[] pNewAppRoot;
pNewAppRoot = NULL;
}
}
if (pRecBuf)
{
delete [] pRecBuf;
pRecBuf = NULL;
}
pBuffer += wcslen(pBuffer) + 1;
}
done:
if (lpwstrTempPassword)
{
// security percaution:Make sure to zero out memory that temporary password was used for.
SecureZeroMemory(lpwstrTempPassword,pConnectionInfo->cbUserPasswordEncrypted);
LocalFree(lpwstrTempPassword);
lpwstrTempPassword = NULL;
}
if (hObjHandle)
{
pIMSAdminBase2->CloseKey(hObjHandle);
}
if (pIMSAdminBase2)
{
pIMSAdminBase2->Release();
pIMSAdminBase2 = NULL;
}
if (pIMSAdminBase)
{
pIMSAdminBase->Release();
pIMSAdminBase = NULL;
}
if (pRecBuf)
{
delete[] pRecBuf;
pRecBuf = NULL;
}
if (pNewAppRoot)
{
delete[] pNewAppRoot;
pNewAppRoot = NULL;
}
if (pOrigBuffer)
{
// pOrigBuffer is pBuffer before we moved through it.
delete pOrigBuffer;
pOrigBuffer = NULL;
pBuffer = NULL;
}
if (pSourcePath)
{
delete[] pSourcePath;
pSourcePath = NULL;
}
if (bCoInitCalled)
{
CoUninitialize();
}
return hr;
}