|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: cryptui.cpp
//
// Contents: Cert Server wrapper routines
//
//---------------------------------------------------------------------------
#include <pch.cpp>
#pragma hdrstop
#include "certmsg.h"
#include "clibres.h"
#include "setupids.h"
#include "tfc.h"
#include "Windowsx.h"
#define __dwFILE__ __dwFILE_INITLIB_CERTUI_CPP__
HRESULT myGetConfigStringFromPicker( OPTIONAL IN HWND hwndParent, OPTIONAL IN WCHAR const *pwszPrompt, OPTIONAL IN WCHAR const *pwszTitle, OPTIONAL IN WCHAR const *pwszSharedFolder, IN BOOL fUseDS, OUT WCHAR **ppwszConfig) { HRESULT hr; DWORD dwCACount; CRYPTUI_CA_CONTEXT const *pCAContext = NULL;
hr = myGetConfigFromPicker( hwndParent, pwszPrompt, pwszTitle, pwszSharedFolder, fUseDS, FALSE, &dwCACount, &pCAContext); _JumpIfError(hr, error, "myGetConfigFromPicker");
if (NULL == pCAContext) { hr = E_INVALIDARG; _JumpIfError(hr, error, "Internal error: myGetConfigFromPicker"); }
hr = myFormConfigString( pCAContext->pwszCAMachineName, pCAContext->pwszCAName, ppwszConfig); _JumpIfError(hr, error, "myFormConfigString");
error: if (NULL != pCAContext) { CryptUIDlgFreeCAContext(pCAContext); } return(hr); }
HRESULT myUIGetWindowText( IN HWND hwndCtrl, OUT WCHAR **ppwszText) { HRESULT hr; LRESULT len; DWORD i; WCHAR *pwszBegin; WCHAR *pwszEnd; WCHAR *pwszText = NULL;
CSASSERT(NULL != hwndCtrl && NULL != ppwszText);
// init
*ppwszText = NULL;
// get text string size
len = SendMessage(hwndCtrl, WM_GETTEXTLENGTH, 0, 0); if (0 < len) { pwszText = (WCHAR*)LocalAlloc(LMEM_FIXED, (UINT)((len+1) * sizeof(WCHAR))); if (NULL == pwszText) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } if (len != SendMessage(hwndCtrl, WM_GETTEXT, (WPARAM)len+1, (LPARAM)pwszText)) { hr = HRESULT_FROM_WIN32(ERROR_BAD_LENGTH); _JumpError(hr, error, "Internal error"); } } else { goto done; }
// trim trailing and heading blank strings
pwszBegin = pwszText; pwszEnd = &pwszText[wcslen(pwszText) - 1];
while (pwszEnd > pwszBegin && iswspace(*pwszEnd) ) { *pwszEnd = L'\0'; --pwszEnd; } while (pwszBegin <= pwszEnd && L'\0' != *pwszBegin && iswspace(*pwszBegin) ) { ++pwszBegin; }
if (pwszEnd >= pwszBegin) { MoveMemory( pwszText, pwszBegin, (SAFE_SUBTRACT_POINTERS(pwszEnd, pwszBegin) + 2) * sizeof(WCHAR)); } else { goto done; }
*ppwszText = pwszText; pwszText = NULL;
done: hr = S_OK; error: if (NULL != pwszText) { LocalFree(pwszText); } return hr; }
// following code for CA selection UI control
HRESULT UICASelectionUpdateCAList( HWND hwndList, WCHAR const *pwszzCAList) { HRESULT hr; int nItem; WCHAR const *pwszCA = pwszzCAList;
// remove current list
SendMessage(hwndList, CB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
// add to list
while (NULL != pwszCA && L'\0' != pwszCA[0]) { nItem = (INT)SendMessage( hwndList, CB_ADDSTRING, (WPARAM) 0, (LPARAM) pwszCA); if (LB_ERR == nItem) { hr = myHLastError(); _JumpError(hr, error, "SendMessage"); } pwszCA += wcslen(pwszCA) + 1; }
if (NULL != pwszzCAList) { // attempt to choose the 1st one as default
SendMessage(hwndList, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0); } hr = S_OK;
error: return hr; }
LRESULT CALLBACK myUICASelectionComputerEditFilterHook( HWND hwndComputer, UINT iMsg, WPARAM wParam, LPARAM lParam) { LRESULT lr; HRESULT hr; CERTSRVUICASELECTION *pData = (CERTSRVUICASELECTION*) GetWindowLongPtr(hwndComputer, GWLP_USERDATA); CSASSERT(NULL != pData);
switch(iMsg) { case WM_CHAR: // empty ca list
hr = UICASelectionUpdateCAList(pData->hwndCAList, NULL); _PrintIfError(hr, "UICASelectionUpdateCAList"); break; }
lr = CallWindowProc( pData->pfnUICASelectionComputerWndProcs, hwndComputer, iMsg, wParam, lParam);
//error:
return lr; }
HRESULT myUICAConditionallyDisplayEnterpriseWarning( IN CERTSRVUICASELECTION *pData) { HRESULT hr = S_OK; CAINFO *pCAInfo = NULL; BOOL fCoInit = FALSE; hr = CoInitialize(NULL); if (S_OK != hr && S_FALSE != hr) { _JumpError(hr, Ret, "CoInitialize"); } fCoInit = TRUE; hr = S_OK; // don't want to return this error
pData->CAType = ENUM_UNKNOWN_CA; // pinging specific CA is done in both cases -- reselect or new machine pointed at
WCHAR szCA[MAX_PATH]; WCHAR szComputer[MAX_PATH]; szCA[0]=L'\0'; szComputer[0]=L'\0'; int iSel; iSel = ComboBox_GetCurSel(pData->hwndCAList); ComboBox_GetLBText(pData->hwndCAList, iSel, szCA); GetWindowText(pData->hwndComputerEdit, szComputer, MAX_PATH); if ((szCA[0]==L'\0') || (szComputer[0]==L'\0')) { ShowWindow(GetDlgItem(pData->hDlg, IDC_CLIENT_WARN_ENTERPRISE_REQUIREMENTS), SW_HIDE); goto Ret; } hr = myPingCertSrv( szCA, szComputer, NULL, NULL, &pCAInfo, NULL, NULL); if ((hr == S_OK) && (pCAInfo != NULL)) { // copy catype into returned data
pData->CAType = pCAInfo->CAType;
if (IsEnterpriseCA(pCAInfo->CAType)) { ShowWindow(GetDlgItem(pData->hDlg, IDC_CLIENT_WARN_ENTERPRISE_REQUIREMENTS), SW_SHOW); } else { ShowWindow(GetDlgItem(pData->hDlg, IDC_CLIENT_WARN_ENTERPRISE_REQUIREMENTS), SW_HIDE); } }
Ret: if (NULL != pCAInfo) LocalFree(pCAInfo); if (fCoInit) CoUninitialize(); return hr; }
HRESULT myUICAHandleCAListDropdown( IN int iNotification, IN OUT CERTSRVUICASELECTION *pData, IN OUT BOOL *pfComputerChange) { HRESULT hr; WCHAR *pwszComputer = NULL; WCHAR *pwszzCAList = NULL; BOOL fCoInit = FALSE; WCHAR *pwszDnsName = NULL; DWORD dwVersion;
CSASSERT(NULL != pData);
// if this isn't a focus or selection change and computer name stayed same, nothing to do
if ((CBN_SELCHANGE != iNotification) && !*pfComputerChange) { goto done; }
ShowWindow(GetDlgItem(pData->hDlg, IDC_CLIENT_WARN_ENTERPRISE_REQUIREMENTS), SW_HIDE); SetCursor(LoadCursor(NULL, IDC_WAIT));
if (NULL == pData->hwndComputerEdit) { // not init
goto done; }
// make sure computer edit field is not empty
hr = myUIGetWindowText(pData->hwndComputerEdit, &pwszComputer); _JumpIfError(hr, error, "myUIGetWindowText"); if (NULL == pwszComputer) { goto done; }
if (*pfComputerChange) {
// ping to get ca list
hr = CoInitialize(NULL); if (S_OK != hr && S_FALSE != hr) { _JumpError(hr, error, "CoInitialize"); } fCoInit = TRUE;
// reset once ca list is updated. Do this now to prevent recursion
*pfComputerChange = FALSE;
hr = myPingCertSrv( pwszComputer, NULL, &pwszzCAList, NULL, NULL, &dwVersion, &pwszDnsName); CSILOG(hr, IDS_ILOG_GETCANAME, pwszComputer, NULL, NULL); if (S_OK != hr) { // make sure null
CSASSERT(NULL == pwszzCAList);
// can't ping the ca. Set focus now to prevent recursion
SetFocus(pData->hwndComputerEdit); SendMessage(pData->hwndComputerEdit, EM_SETSEL, 0, -1);
CertWarningMessageBox( pData->hInstance, FALSE, pData->hDlg, IDS_WRN_PINGCA_FAIL, hr, NULL); } else if(dwVersion<2 && pData->fWebProxySetup) { //bug 262316: don't allow installing Whistler proxy to an older CA
hr = HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION);
if(pwszzCAList) { LocalFree(pwszzCAList); pwszzCAList = NULL; }
SetFocus(pData->hwndComputerEdit); SendMessage(pData->hwndComputerEdit, EM_SETSEL, 0, -1);
CertWarningMessageBox( pData->hInstance, FALSE, pData->hDlg, IDS_WRN_OLD_CA, hr, NULL); }
if (NULL!=pwszDnsName && 0!=wcscmp(pwszComputer, pwszDnsName)) { // update computer
SendMessage(pData->hwndComputerEdit, WM_SETTEXT, 0, (LPARAM)pwszDnsName); }
// update ca list
hr = UICASelectionUpdateCAList(pData->hwndCAList, pwszzCAList); _JumpIfError(hr, error, "UICASelectionUpdateCAList"); }
// pinging specific CA is done in both cases -- reselect or new machine pointed at
hr = myUICAConditionallyDisplayEnterpriseWarning(pData); _PrintIfError(hr, "myUICAConditionallyDisplayEnterpriseWarning");
done: hr = S_OK;
error: SetCursor(LoadCursor(NULL, IDC_ARROW));
if (fCoInit) { CoUninitialize(); } if (NULL != pwszzCAList) { LocalFree(pwszzCAList); } if (NULL != pwszComputer) { LocalFree(pwszComputer); } if (NULL != pwszDnsName) { LocalFree(pwszDnsName); } return hr; }
HRESULT myInitUICASelectionControls( IN OUT CERTSRVUICASELECTION *pUICASelection, IN HINSTANCE hInstance, IN HWND hDlg, IN HWND hwndBrowseButton, IN HWND hwndComputerEdit, IN HWND hwndCAList, IN BOOL fDSCA, OUT BOOL *pfCAsExist) { HRESULT hr; PCCRYPTUI_CA_CONTEXT pCAContext = NULL; DWORD dwCACount; CString cstrText;
SetCursor(LoadCursor(NULL, IDC_WAIT)); hr = myGetConfigFromPicker( hDlg, NULL, NULL, NULL, fDSCA, TRUE, // fCountOnly
&dwCACount, &pCAContext); SetCursor(LoadCursor(NULL, IDC_ARROW)); if (S_OK != hr) { dwCACount = 0; _PrintError(hr, "myGetConfigFromPicker"); }
// enable/disable
*pfCAsExist = 0 < dwCACount; EnableWindow(hwndBrowseButton, *pfCAsExist);
// set computer edit control hook
pUICASelection->pfnUICASelectionComputerWndProcs = (WNDPROC)SetWindowLongPtr(hwndComputerEdit, GWLP_WNDPROC, (LPARAM)myUICASelectionComputerEditFilterHook);
pUICASelection->hInstance = hInstance; pUICASelection->hDlg = hDlg; pUICASelection->hwndComputerEdit = hwndComputerEdit; pUICASelection->hwndCAList = hwndCAList;
// pass data to both controls
SetWindowLongPtr(hwndComputerEdit, GWLP_USERDATA, (ULONG_PTR)pUICASelection); SetWindowLongPtr(hwndCAList, GWLP_USERDATA, (ULONG_PTR)pUICASelection);
// by default, don't show Enterprise CA warning
cstrText.LoadString(IDS_WARN_ENTERPRISE_REQUIREMENTS); SetWindowText(GetDlgItem(hDlg, IDC_CLIENT_WARN_ENTERPRISE_REQUIREMENTS), cstrText); ShowWindow(GetDlgItem(hDlg, IDC_CLIENT_WARN_ENTERPRISE_REQUIREMENTS), SW_HIDE);
if (NULL != pCAContext) { CryptUIDlgFreeCAContext(pCAContext); }
hr = S_OK; //error:
return hr; }
HRESULT myUICAHandleCABrowseButton( CERTSRVUICASELECTION *pData, IN BOOL fUseDS, OPTIONAL IN int idsPickerTitle, OPTIONAL IN int idsPickerSubTitle, OPTIONAL OUT WCHAR **ppwszSharedFolder) { HRESULT hr = S_OK; PCCRYPTUI_CA_CONTEXT pCAContext = NULL; WCHAR *pwszSubTitle = NULL; WCHAR *pwszTitle = NULL; DWORD dwCACount; WCHAR *pwszzCAList = NULL; WCHAR *pwszComputer = NULL; WCHAR *pwszTemp = NULL; BOOL fCoInit = FALSE; DWORD dwVersion;
if (NULL != ppwszSharedFolder) { *ppwszSharedFolder = NULL; }
if (0 != idsPickerTitle) { hr = myLoadRCString(pData->hInstance, idsPickerTitle, &pwszTitle); if (S_OK != hr) { pwszTitle = NULL; _PrintError(hr, "myLoadRCString"); } }
if (0 != idsPickerSubTitle) { hr = myLoadRCString(pData->hInstance, idsPickerSubTitle, &pwszSubTitle); if (S_OK != hr) { pwszSubTitle = NULL; _PrintError(hr, "myLoadRCString"); } }
/*
// REMOVED mattt 6/26/00: is this ever wanted: "Browse uses shared folder of machine editbox currently points at"?
// just seems to make changing away from bad machine very very slow
// get remote shared folder if possible
hr = myUIGetWindowText(pData->hwndComputerEdit, &pwszComputer); _JumpIfError(hr, error, "myUIGetWindowText");
if (NULL != pwszComputer) { hr = CoInitialize(NULL); if (S_OK != hr && S_FALSE != hr) { _JumpError(hr, error, "CoInitialize"); } fCoInit = TRUE; // get shared folder path on remote machine here
SetCursor(LoadCursor(NULL, IDC_WAIT)); hr = myPingCertSrv(pwszComputer, NULL, NULL, &pwszTemp, NULL, NULL, NULL); SetCursor(LoadCursor(NULL, IDC_ARROW)); if (S_OK != hr) { CSASSERT(NULL == pwszTemp); _JumpError(hr, localsharedfolder, "myPingCertSrv"); } }
localsharedfolder: */ hr = myGetConfigFromPicker( pData->hDlg, pwszSubTitle, pwszTitle, pwszTemp, fUseDS, FALSE, // fCountOnly
&dwCACount, &pCAContext); if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_CANCELLED) != hr) { CSILOG(hr, IDS_ILOG_SELECTCA, NULL, NULL, NULL); _JumpError(hr, error, "myGetConfigFromPicker"); }
if (S_OK != hr) goto done;
if (NULL == pCAContext) { CertWarningMessageBox( pData->hInstance, FALSE, pData->hDlg, IDS_WRN_CALIST_EMPTY, S_OK, NULL); SetWindowText(pData->hwndCAList, L""); SetFocus(pData->hwndComputerEdit); SendMessage(pData->hwndComputerEdit, EM_SETSEL, 0, -1); } else { CSILOG(hr, IDS_ILOG_SELECTCA, pCAContext->pwszCAMachineName, pCAContext->pwszCAName, NULL); // update computer
SendMessage(pData->hwndComputerEdit, WM_SETTEXT, 0, (LPARAM)pCAContext->pwszCAMachineName); // construct a single multi string for list update
DWORD len = wcslen(pCAContext->pwszCAName); pwszzCAList = (WCHAR*)LocalAlloc(LMEM_FIXED, (len+2) * sizeof(WCHAR)); if (NULL == pwszzCAList) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } wcscpy(pwszzCAList, pCAContext->pwszCAName); pwszzCAList[len+1] = '\0'; hr = UICASelectionUpdateCAList(pData->hwndCAList, pwszzCAList); _JumpIfError(hr, error, "UICASelectionUpdateCAList"); LocalFree(pwszzCAList); pwszzCAList = NULL;
// this thread blocks paint message, send it before ping
UpdateWindow(pData->hDlg); // ping the computer to see if found a matched ca
if (!fCoInit) { hr = CoInitialize(NULL); if (S_OK != hr && S_FALSE != hr) { _JumpError(hr, error, "CoInitialize"); } fCoInit = TRUE; } SetCursor(LoadCursor(NULL, IDC_WAIT)); // ping to get ca list
hr = myPingCertSrv( pCAContext->pwszCAMachineName, NULL, &pwszzCAList, NULL, NULL, &dwVersion, NULL); SetCursor(LoadCursor(NULL, IDC_ARROW)); CSILOG(hr, IDS_ILOG_GETCANAME, pCAContext->pwszCAMachineName, NULL, NULL); if (S_OK == hr) { //bug 262316: don't allow installing Whistler proxy to an older CA
if(dwVersion<2 && pData->fWebProxySetup) { hr = HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION); // focus on the CA list to trigger a verification of the CA
SetFocus(pData->hwndCAList);
} else { // ping successful
WCHAR const *pwszPingCA = pwszzCAList; // go through the list to see if any match
while (NULL != pwszPingCA && L'\0' != pwszPingCA[0]) { if (0 == wcscmp(pCAContext->pwszCAName, pwszPingCA)) { // found matched one
goto done; } pwszPingCA += wcslen(pwszPingCA) + 1; } // if we get here, either the CA is offline or the machine is
// offline and another machine is using the same IP address.
CertWarningMessageBox( pData->hInstance, FALSE, pData->hDlg, IDS_WRN_CANAME_NOT_MATCH, 0, NULL); // only empty combo edit field
SetWindowText(pData->hwndCAList, L""); SetFocus(pData->hwndCAList); } } else { // can't ping the ca, selected an estranged ca
CertWarningMessageBox( pData->hInstance, FALSE, pData->hDlg, IDS_WRN_PINGCA_FAIL, hr, NULL); // empty list anyway
hr = UICASelectionUpdateCAList(pData->hwndCAList, NULL); _JumpIfError(hr, error, "UICASelectionUpdateCAList"); SetFocus(pData->hwndComputerEdit); SendMessage(pData->hwndComputerEdit, EM_SETSEL, 0, -1); } }
done: hr = myUICAConditionallyDisplayEnterpriseWarning(pData); _PrintIfError(hr, "myUICAConditionallyDisplayEnterpriseWarning");
if (NULL != ppwszSharedFolder) { *ppwszSharedFolder = pwszTemp; pwszTemp = NULL; }
hr = S_OK; error: if (NULL != pwszzCAList) { LocalFree(pwszzCAList); } if (NULL != pwszSubTitle) { LocalFree(pwszSubTitle); } if (NULL != pwszTitle) { LocalFree(pwszTitle); } if (NULL != pwszTemp) { LocalFree(pwszTemp); } if (NULL != pwszComputer) { LocalFree(pwszComputer); } if (NULL != pCAContext) { CryptUIDlgFreeCAContext(pCAContext); } if (fCoInit) { CoUninitialize(); }
return hr; }
HRESULT myUICASelectionValidation( CERTSRVUICASELECTION *pData, BOOL *pfValidate) { HRESULT hr; WCHAR *pwszComputer = NULL; WCHAR *pwszCA = NULL;
CSASSERT(NULL != pData);
*pfValidate = FALSE;
// first, make sure not empty
hr = myUIGetWindowText(pData->hwndComputerEdit, &pwszComputer); _JumpIfError(hr, error, "myUIGetWindowText");
if (NULL == pwszComputer) { CertWarningMessageBox( pData->hInstance, FALSE, pData->hDlg, IDS_WRN_COMPUTERNAME_EMPTY, 0, NULL); SetFocus(pData->hwndComputerEdit); goto done; }
hr = myUIGetWindowText(pData->hwndCAList, &pwszCA); _JumpIfError(hr, error, "myUIGetWindowText");
if (NULL == pwszCA) { CertWarningMessageBox( pData->hInstance, FALSE, pData->hDlg, IDS_WRN_CANAME_EMPTY, 0, NULL); SetFocus(pData->hwndComputerEdit); SendMessage(pData->hwndComputerEdit, EM_SETSEL, 0, -1); goto done; }
CSASSERT(pData->CAType != ENUM_UNKNOWN_CA); if (pData->CAType == ENUM_UNKNOWN_CA) { hr = E_UNEXPECTED; _JumpIfError(hr, error, "CAType not determined"); }
// if hit here
*pfValidate = TRUE;
done: hr = S_OK; error: if (NULL != pwszComputer) { LocalFree(pwszComputer); } if (NULL != pwszCA) { LocalFree(pwszCA); } return hr; }
|