// ExportUI.cpp : Implementation of CExportUI //#include "stdafx.h" //#include "ExportUI.h" #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 #define HIDD_IISUIOBJ_EXPORT 0x50402 #define LAST_USED_EXPORT_PATH _T("LastExportPath") void SetControlStates(HWND hDlg, UINT msg, WPARAM wParam, PCOMMONDLGPARAM pcdParams) { BOOL bEnAbleOk = FALSE; BOOL bEnAbleBrowse = FALSE; BOOL bAllPasswordsFilled = TRUE; BOOL bFileNameFilled = FALSE; BOOL bFilePathFilled = FALSE; BOOL bUsingPassword = (BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_CHECK_ENCRYPT)); if (bUsingPassword) { bAllPasswordsFilled = FALSE; // check to see if we want to enable okay button if (SendMessage(GetDlgItem(hDlg,IDC_EDIT_PASSWORD1),EM_LINELENGTH,(WPARAM) -1, 0)) { if (SendMessage(GetDlgItem(hDlg,IDC_EDIT_PASSWORD2),EM_LINELENGTH,(WPARAM) -1, 0)) { bAllPasswordsFilled = TRUE; } } } if (SendMessage(GetDlgItem(hDlg,IDC_EDIT_FILENAME),EM_LINELENGTH,(WPARAM) -1, 0)) { bFileNameFilled = TRUE; } if (SendMessage(GetDlgItem(hDlg,IDC_EDIT_PATH),EM_LINELENGTH,(WPARAM) -1, 0)) { bFilePathFilled = TRUE; } if (bFileNameFilled && bFilePathFilled && bAllPasswordsFilled) { bEnAbleOk = TRUE; } // no browse button for remote case if (pcdParams) { if (pcdParams->ConnectionInfo.IsLocal) { bEnAbleBrowse = TRUE; } } EnableWindow(GetDlgItem(hDlg,IDOK), bEnAbleOk); EnableWindow(GetDlgItem(hDlg,IDC_BUTTON_BROWSE), bEnAbleBrowse); UpdateWindow(hDlg); return; } INT_PTR CALLBACK ShowExportDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static PCOMMONDLGPARAM pcdParams; switch (msg) { case WM_INITDIALOG: { TCHAR szPathToInetsrv[_MAX_PATH]; pcdParams = (PCOMMONDLGPARAM)lParam; if (!pcdParams->pszMetabasePath) { EnableWindow(GetDlgItem(hDlg,IDOK), FALSE); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } SendDlgItemMessage(hDlg, IDC_EDIT_FILENAME, EM_LIMITTEXT, _MAX_PATH, 0); SendDlgItemMessage(hDlg, IDC_EDIT_PATH, EM_LIMITTEXT, _MAX_PATH, 0); SendDlgItemMessage(hDlg, IDC_EDIT_PASSWORD1, EM_LIMITTEXT, PWLEN, 0); SendDlgItemMessage(hDlg, IDC_EDIT_PASSWORD2, EM_LIMITTEXT, PWLEN, 0); // Default it with some default values... // Fill a Default filename... SetDlgItemText(hDlg, IDC_EDIT_FILENAME, _T("")); // Fill a default filepath... SetDlgItemText(hDlg, IDC_EDIT_PATH, _T("")); if (DefaultValueSettingsLoad((LPCTSTR) pcdParams->ConnectionInfo.pszMachineName,LAST_USED_EXPORT_PATH,szPathToInetsrv)) { if (0 != _tcscmp(szPathToInetsrv, _T(""))) { SetDlgItemText(hDlg, IDC_EDIT_PATH, szPathToInetsrv); } else { if (GetInetsrvPath(pcdParams->ConnectionInfo.pszMachineName,szPathToInetsrv,sizeof(szPathToInetsrv))) { SetDlgItemText(hDlg, IDC_EDIT_PATH, szPathToInetsrv); } } } else { if (pcdParams->ConnectionInfo.IsLocal) { if (GetInetsrvPath(pcdParams->ConnectionInfo.pszMachineName,szPathToInetsrv,sizeof(szPathToInetsrv))) { SetDlgItemText(hDlg, IDC_EDIT_PATH, szPathToInetsrv); } } else { // forget remote case, since GetInetsrvPath may hang for this reason... } } // Set encryption using password to unchecked. SendDlgItemMessage(hDlg, IDC_CHECK_ENCRYPT, BM_SETCHECK, BST_UNCHECKED, 0L); // Set encryption password1 to blank // make sure it's disabled... SendDlgItemMessage(hDlg, IDC_EDIT_PASSWORD1, EM_SETPASSWORDCHAR, WPARAM('*'), 0); EnableWindow(GetDlgItem(hDlg,IDC_EDIT_PASSWORD1), FALSE); SetDlgItemText(hDlg, IDC_EDIT_PASSWORD1, _T("")); // Set encryption password2 to blank // make sure it's disabled... SendDlgItemMessage(hDlg, IDC_EDIT_PASSWORD2, EM_SETPASSWORDCHAR, WPARAM('*'), 0); EnableWindow(GetDlgItem(hDlg,IDC_EDIT_PASSWORD2), FALSE); SetDlgItemText(hDlg, IDC_EDIT_PASSWORD2, _T("")); EnableWindow(GetDlgItem(hDlg,IDC_STATIC_PASSWORD1), FALSE); EnableWindow(GetDlgItem(hDlg,IDC_STATIC_PASSWORD2), FALSE); CenterWindow(GetForegroundWindow(), hDlg); SetFocus(GetDlgItem(hDlg, IDC_EDIT_FILENAME)); SetControlStates(hDlg,msg,wParam,pcdParams); break; } case WM_NOTIFY: break; case WM_CLOSE: EndDialog(hDlg, IDCANCEL); return FALSE; break; case WM_HELP: LaunchHelp(hDlg,HIDD_IISUIOBJ_EXPORT); return TRUE; break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_BUTTON_BROWSE: { CString strTitle; strTitle.LoadString(_Module.GetResourceInstance(), IDS_BROWSE_SELECT_FOLDER); UINT ulFlags=BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | //BIF_STATUSTEXT | //BIF_DONTGOBELOWDOMAIN | BIF_BROWSEFORCOMPUTER | BIF_SHAREABLE | //BIF_BROWSEINCLUDEFILES | //BIF_USENEWUI | BIF_UAHINT | BIF_VALIDATE; CFolderDialog dlg(hDlg,strTitle,ulFlags); if (IDOK == dlg.DoModal()) { // update the dialog box if (0 != _tcsicmp(dlg.GetFolderPath(), _T(""))) { SetDlgItemText(hDlg, IDC_EDIT_PATH, dlg.GetFolderPath()); UpdateWindow(hDlg); } } return FALSE; } case IDC_EDIT_FILENAME: { switch (HIWORD(wParam)) { case EN_CHANGE: EditHideBalloon(); // If the contents of the edit control have changed, SetControlStates(hDlg,msg,wParam,pcdParams); break; case EN_MAXTEXT: case EN_ERRSPACE: // If the control is out of space, honk MessageBeep (0); break; default: break; } return FALSE; } case IDC_EDIT_PASSWORD1: { switch (HIWORD(wParam)) { case EN_CHANGE: EditHideBalloon(); SetControlStates(hDlg,msg,wParam,pcdParams); break; case EN_MAXTEXT: case EN_ERRSPACE: // If the control is out of space, honk MessageBeep (0); break; default: break; } return FALSE; } case IDC_EDIT_PASSWORD2: { switch (HIWORD(wParam)) { case EN_CHANGE: EditHideBalloon(); SetControlStates(hDlg,msg,wParam,pcdParams); break; case EN_MAXTEXT: case EN_ERRSPACE: // If the control is out of space, honk MessageBeep (0); break; default: break; } return FALSE; } case IDC_EDIT_PATH: { switch (HIWORD(wParam)) { case EN_CHANGE: EditHideBalloon(); // If the contents of the edit control have changed, SetControlStates(hDlg,msg,wParam,pcdParams); break; case EN_MAXTEXT: case EN_ERRSPACE: // If the control is out of space, honk MessageBeep (0); break; default: break; } return FALSE; } case IDHELP: LaunchHelp(hDlg,HIDD_IISUIOBJ_EXPORT); return TRUE; case IDCANCEL: { EndDialog(hDlg, (int)wParam); return FALSE; } case IDOK: { HRESULT hr = ERROR_SUCCESS; TCHAR szFullFileName[_MAX_PATH + 1]; TCHAR szFileName[_MAX_PATH + 1]; TCHAR szNoSpaces[_MAX_PATH + 1]; ZeroMemory(szFullFileName, sizeof(szFullFileName)); ZeroMemory(szFileName, sizeof(szFileName)); GetDlgItemText(hDlg, IDC_EDIT_FILENAME, szFileName, _MAX_PATH); GetDlgItemText(hDlg, IDC_EDIT_PATH, szFullFileName, _MAX_PATH); CString strDefaultExt; strDefaultExt.LoadString(_Module.GetResourceInstance(), IDS_DEFAULT_SAVED_EXT); RemoveSpaces(szNoSpaces, sizeof(szNoSpaces), szFileName); StringCbCopy(szNoSpaces, sizeof(szNoSpaces), szFileName); RemoveSpaces(szNoSpaces, sizeof(szNoSpaces), szFullFileName); StringCbCopy(szFullFileName, sizeof(szFullFileName), szNoSpaces); if (IsSpaces(szFileName)) { // There was no filename specified. EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_FILENAME),_Module.GetResourceInstance(),IDS_FILENAME_MISSING); } else if (0 == _tcsicmp(szFullFileName,_T(""))) { // There was no filename specified. EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_FILENAME),_Module.GetResourceInstance(),IDS_FILENAME_MISSING); } else { // check for % characters // if there are any, expand them. LPTSTR pch = _tcschr( (LPTSTR) szFullFileName, _T('%')); if (pch) { if (pcdParams->ConnectionInfo.IsLocal) { if (pch) { TCHAR szValue[_MAX_PATH + 1]; StringCbCopy(szValue, sizeof(szValue), szFullFileName); if (!ExpandEnvironmentStrings( (LPCTSTR)szFullFileName, szValue, sizeof(szValue)/sizeof(TCHAR))) { StringCbCopy(szValue, sizeof(szValue), szFullFileName); } StringCbCopy(szFullFileName, sizeof(szFullFileName), szValue); } } else { // we don't support % characters on remote systems. EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_PATH),_Module.GetResourceInstance(),IDS_FILENAME_NOREMOTE_EXPAND); return FALSE; } } // Check if valid folderpath if (!IsValidFolderPath(GetDlgItem(hDlg, IDC_EDIT_PATH),szFullFileName,TRUE)) { return FALSE; } AddPath(szFullFileName,sizeof(szFullFileName),szFileName); // Check if file has an extension. // if there is none, then add the .xml extention. AddFileExtIfNotExist(szFullFileName,sizeof(szFullFileName),strDefaultExt); if (!IsValidName(szFileName)) { EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_FILENAME),_Module.GetResourceInstance(),IDS_FILENAME_INVALID); return FALSE; } if (pcdParams->ConnectionInfo.IsLocal) { // Check if the file already exists... if (IsFileExist(szFullFileName)) { // check if the filename is a directory! if (IsFileADirectory(szFullFileName)) { EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_FILENAME),_Module.GetResourceInstance(),IDS_FILE_IS_A_DIR); return FALSE; } else { if (FALSE == AnswerIsYes(hDlg,IDS_REPLACE_FILE,szFullFileName)) { return FALSE; } } } } else { // Check if the file already exists... // security percaution:decypt password before using it...then zero out memory that used it if (pcdParams->ConnectionInfo.pszUserPasswordEncrypted) { LPWSTR lpwstrTemp = NULL; if (FAILED(DecryptMemoryPassword((LPWSTR) pcdParams->ConnectionInfo.pszUserPasswordEncrypted,&lpwstrTemp,pcdParams->ConnectionInfo.cbUserPasswordEncrypted))) { return FALSE; } if (IsFileExistRemote(pcdParams->ConnectionInfo.pszMachineName,szFullFileName,pcdParams->ConnectionInfo.pszUserName,lpwstrTemp)) { if (FALSE == AnswerIsYes(hDlg,IDS_REPLACE_FILE,szFullFileName)) { return FALSE; } } if (lpwstrTemp) { // security percaution:Make sure to zero out memory that temporary password was used for. SecureZeroMemory(lpwstrTemp,pcdParams->ConnectionInfo.cbUserPasswordEncrypted); LocalFree(lpwstrTemp); lpwstrTemp = NULL; } } } // Perform the action... // and then if successfull proceed to close the dialog... // check if everything is filled in. // if not then warn user and do nothing. BOOL bUsingPassword = (BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_CHECK_ENCRYPT)); if (bUsingPassword) { TCHAR szPW1[PWLEN + 1]; TCHAR szPW2[PWLEN + 1]; SecureZeroMemory(szPW1, sizeof(szPW1)); SecureZeroMemory(szPW2, sizeof(szPW2)); GetDlgItemText(hDlg, IDC_EDIT_PASSWORD1, szPW1, PWLEN); GetDlgItemText(hDlg, IDC_EDIT_PASSWORD2, szPW2, PWLEN); if ( _tcscmp(szPW1, szPW2) ) { // passwords do not match EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_PASSWORD1),_Module.GetResourceInstance(),IDS_PASSWORDS_NO_MATCH); return FALSE; } else { hr = DoExportConfigToFile(&pcdParams->ConnectionInfo,(BSTR) szFullFileName,(BSTR) pcdParams->pszMetabasePath,szPW1,pcdParams->dwExportFlags); } } else { hr = DoExportConfigToFile(&pcdParams->ConnectionInfo,(BSTR) szFullFileName,(BSTR) pcdParams->pszMetabasePath,NULL,pcdParams->dwExportFlags); } if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) { //0x80070003 EditShowBalloon(GetDlgItem(hDlg, IDC_EDIT_PATH),_Module.GetResourceInstance(),IDS_FILE_NOT_FOUND); } else { // we failed. // so keep the dialog open and do nothing CError err(hr); err.MessageBox(); } return FALSE; } else { TCHAR szNoSpaces2[_MAX_PATH + 1]; ZeroMemory(szFullFileName, sizeof(szFullFileName)); GetDlgItemText(hDlg, IDC_EDIT_PATH, szFullFileName, _MAX_PATH); RemoveSpaces(szNoSpaces2, sizeof(szNoSpaces2), szFullFileName); StringCbCopy(szFullFileName, sizeof(szFullFileName), szNoSpaces2); if (0 != _tcscmp(szFullFileName, _T(""))) { DefaultValueSettingsSave((LPCTSTR) pcdParams->ConnectionInfo.pszMachineName,LAST_USED_EXPORT_PATH,szFullFileName); } EndDialog(hDlg, (int)wParam); return TRUE; } } return FALSE; } case IDC_CHECK_ENCRYPT: { // user is toggling the checkbox. BOOL bUsingPassword = (BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_CHECK_ENCRYPT)); // enable/disable edit label EnableWindow(GetDlgItem(hDlg,IDC_STATIC_PASSWORD1), bUsingPassword); EnableWindow(GetDlgItem(hDlg,IDC_STATIC_PASSWORD2), bUsingPassword); // enable/disable edit boxes EnableWindow(GetDlgItem(hDlg,IDC_EDIT_PASSWORD1), bUsingPassword); EnableWindow(GetDlgItem(hDlg,IDC_EDIT_PASSWORD2), bUsingPassword); SetControlStates(hDlg,msg,wParam,pcdParams); return TRUE; } } break; } return FALSE; } HRESULT DoExportConfigToFile(PCONNECTION_INFO pConnectionInfo,BSTR bstrFileNameAndPath,BSTR bstrMetabasePath,BSTR bstrPassword,DWORD dwExportFlags) { 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); } // 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(bstrMetabasePath) > (_MAX_PATH)){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_PKT_PRIVACY); 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 DoExportConfigToFile_Exit; } pIMSAdminBase = (IMSAdminBase *)res[0].pItf; if (auth.UsesImpersonation()) { if (FAILED(hr = auth.ApplyProxyBlanket(pIMSAdminBase))) { goto DoExportConfigToFile_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 DoExportConfigToFile_Exit; } pUnk->Release();pUnk = NULL; } if (FAILED(hr = pIMSAdminBase->QueryInterface(IID_IMSAdminBase2, (void **)&pIMSAdminBase2))) { goto DoExportConfigToFile_Exit; } if (auth.UsesImpersonation()) { if (FAILED(hr = auth.ApplyProxyBlanket(pIMSAdminBase2))) { goto DoExportConfigToFile_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 DoExportConfigToFile_Exit; } } //IISDebugOutput(_T("Export:bstrPassword=%s,bstrFileNameAndPath=%s,bstrMetabasePath=%s,dwExportFlags=%d\r\n"),bstrPassword,bstrFileNameAndPath,bstrMetabasePath,dwExportFlags); IISDebugOutput(_T("Export:FileName=%s,MetabasePath=%s,ExportFlags=%d\r\n"),bstrFileNameAndPath,bstrMetabasePath,dwExportFlags); hr = pIMSAdminBase2->Export(bstrPassword,bstrFileNameAndPath,bstrMetabasePath,dwExportFlags); DoExportConfigToFile_Exit: IISDebugOutput(_T("Export:ret=0x%x\r\n"),hr); auth.FreeServerInfoStruct(pcsiName); 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; }