windows-nt/Source/XPSP1/NT/ds/security/services/ca/certmmc/krapage.cpp
2020-09-26 16:20:57 +08:00

1185 lines
29 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: krapage.cpp
//
//--------------------------------------------------------------------------
#include "stdafx.h"
#include "resource.h"
#include "genpage.h"
#include "csmmchlp.h"
#include "cslistvw.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//defines
//dwFlags in KRA_NODE
#define KRA_FROM_CACHE 0x00000001
#define KRA_MARK_ADDED 0x00000002
static const int nImageValidCert = 3;
static const int nImageInvalidCert = 2;
//macros
//local globals
CString CSvrSettingsKRAPage::m_strDispositions[7];
//add a new into the link list
HRESULT
AddNewKRANode(
IN CERT_CONTEXT const *pCert,
IN DWORD dwDisposition,
IN DWORD dwFlags,
IN OUT KRA_NODE **ppKRAList,
OUT OPTIONAL KRA_NODE **ppKRA)
{
CSASSERT(NULL != ppKRAList);
HRESULT hr;
KRA_NODE *pKRANode = NULL;
KRA_NODE *pKRA = *ppKRAList;
pKRANode = (KRA_NODE*)LocalAlloc(LMEM_FIXED, sizeof(KRA_NODE));
if (NULL == pKRANode)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "Out of memory");
}
//assign node data and put it at the end
pKRANode->pCert = pCert;
pKRANode->dwFlags = dwFlags;
pKRANode->next = NULL;
pKRANode->dwDisposition = dwDisposition;
if (NULL == pKRA)
{
//empty list, 1st one
*ppKRAList = pKRANode;
}
else
{
//always add to the end
while (NULL != pKRA->next)
{
pKRA = pKRA->next;
}
//add
pKRA->next = pKRANode;
}
if (NULL != ppKRA)
{
//optional return
*ppKRA = pKRANode;
}
hr = S_OK;
error:
return hr;
}
void
FreeKRANode(
KRA_NODE *pKRA)
{
if (NULL != pKRA->pCert)
{
CertFreeCertificateContext(pKRA->pCert);
pKRA->pCert = NULL;
}
LocalFree(pKRA);
}
void
FreeKRAList(
KRA_NODE *pKRAList)
{
KRA_NODE *pKRA = pKRAList; //point to list
KRA_NODE *pKRATemp;
while (NULL != pKRA)
{
pKRATemp= pKRA; //save it for free
// update for the loop
pKRA= pKRA->next;
FreeKRANode(pKRATemp);
}
}
//remove a kra node from the link list
void
RemoveKRANode(
IN OUT KRA_NODE **ppKRAList,
IN KRA_NODE *pKRA)
{
CSASSERT(NULL != ppKRAList && NULL != *ppKRAList && NULL != pKRA);
KRA_NODE *pKRACurrent = *ppKRAList;
KRA_NODE *pKRALast = NULL;
//find the node
while (NULL != pKRACurrent && pKRACurrent != pKRA)
{
pKRALast = pKRACurrent; //remember last one
pKRACurrent = pKRACurrent->next;
}
CSASSERT(NULL != pKRACurrent); //node must be in the list
if (NULL != pKRACurrent->next)
{
if (NULL == pKRALast)
{
//means the node is the begining
CSASSERT(pKRA == *ppKRAList);
*ppKRAList = pKRA->next; //make next as begining
}
else
{
//make next pointer of the last node to the next
pKRALast->next = pKRACurrent->next;
}
}
else
{
if (NULL == pKRALast)
{
//this is the only node
*ppKRAList = NULL; //empty list
}
else
{
//the node is the end, make last as the end
pKRALast->next = NULL;
}
}
//now, remove the current node
FreeKRANode(pKRACurrent);
}
BOOL
DoesKRACertExist(
IN KRA_NODE *pKRAList,
IN CERT_CONTEXT const *pKRACert)
{
BOOL fExists = FALSE;
while (NULL != pKRAList)
{
if(pKRAList->pCert)
{
fExists = CertCompareCertificate(
X509_ASN_ENCODING,
pKRAList->pCert->pCertInfo,
pKRACert->pCertInfo);
if (fExists)
{
//done
break;
}
}
pKRAList = pKRAList->next;
}
return fExists;
}
DWORD
GetKRACount(
IN KRA_NODE const *pKRAList)
{
DWORD count = 0;
while(NULL != pKRAList)
{
pKRAList = pKRAList->next;
++count;
}
return count;
}
LPCWSTR CSvrSettingsKRAPage::MapDispositionToString(DWORD dwDisp)
{
if(dwDisp>ARRAYSIZE(m_strDispositions))
dwDisp = KRA_DISP_INVALID;
return CSvrSettingsKRAPage::m_strDispositions[dwDisp];
}
void CSvrSettingsKRAPage::LoadKRADispositions()
{
DWORD cKRA = GetKRACount(m_pKRAList);
variant_t var;
HWND hwndList = GetDlgItem(m_hWnd, IDC_LIST_KRA);
LVITEM lvitem;
ICertAdmin2 *pAdmin = NULL;
// Don't use a cached admin interface, we need latest KRA cert
// state from the server, not a cached result
m_pCA->m_pParentMachine->GetAdmin2(&pAdmin);
if(!pAdmin)
return;
lvitem.mask = LVIF_IMAGE;
lvitem.iSubItem = 0;
for(DWORD cCrtKRA=0;cCrtKRA<cKRA;cCrtKRA++)
{
V_I4(&var) = KRA_DISP_INVALID;
pAdmin->GetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERTSTATE,
cCrtKRA,
PROPTYPE_LONG,
0,
&var);
ListView_SetItemText(
hwndList,
cCrtKRA,
3,
(LPWSTR)MapDispositionToString(V_I4(&var)));
lvitem.iImage = V_I4(&var)==KRA_DISP_VALID?
nImageValidCert:nImageInvalidCert;
lvitem.iItem = cCrtKRA;
ListView_SetItem(
hwndList,
&lvitem);
}
if(pAdmin)
pAdmin->Release();
}
HRESULT
CSvrSettingsKRAPage::LoadKRAList(ICertAdmin2 *pAdmin)
{
HRESULT hr;
KRA_NODE *pKRAList = NULL;
DWORD i;
const CERT_CONTEXT *pCertContext;
LPCWSTR pwszSanitizedCAName = m_pCA->m_strSanitizedName;
KRA_NODE **ppKRAList = &m_pKRAList;
variant_t var;
hr = pAdmin->GetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERTCOUNT,
0,
PROPTYPE_LONG,
0,
&var);
_JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERTCOUNT");
CSASSERT(V_VT(&var)==VT_I4);
m_dwKRACount = V_I4(&var);
for (i = 0; i < m_dwKRACount; ++i)
{
variant_t varCert;
variant_t varDisp;
pCertContext = NULL;
hr = pAdmin->GetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERT,
i,
PROPTYPE_BINARY,
CR_OUT_BINARY,
&varCert);
if(S_OK==hr)
{
CSASSERT(V_VT(&varCert)==VT_BSTR);
CSASSERT(V_BSTR(&varCert));
pCertContext = CertCreateCertificateContext(
X509_ASN_ENCODING,
(BYTE*)V_BSTR(&varCert),
SysStringByteLen(V_BSTR(&varCert)));
if(!pCertContext)
{
hr = HRESULT_FROM_WIN32(GetLastError());
_JumpError(hr, error, "CertCreateCertificateContext");
}
}
V_I4(&varDisp) = KRA_DISP_INVALID;
pAdmin->GetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERTSTATE,
i,
PROPTYPE_LONG,
0,
&varDisp);
hr = AddNewKRANode(
pCertContext, V_I4(&varDisp), KRA_FROM_CACHE, &pKRAList, NULL);
_JumpIfError(hr, error, "AddNewKRANode");
}
*ppKRAList = pKRAList;
pKRAList = NULL;
hr = pAdmin->GetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERTUSEDCOUNT,
0,
PROPTYPE_LONG,
0,
&var);
_JumpIfError(hr, error, "GetCAProperty wszREGKRACERTCOUNT");
CSASSERT(VT_I4==V_VT(&var));
m_dwKRAUsedCount = V_I4(&var);
m_fArchiveKey = m_dwKRAUsedCount?TRUE:FALSE;
hr = S_OK;
error:
if (NULL != pKRAList)
{
FreeKRAList(pKRAList);
}
return hr;
}
HRESULT
CSvrSettingsKRAPage::SaveKRAList(ICertAdmin2 *pAdmin)
{
HRESULT hr;
HCERTSTORE hCAStore = NULL;
KRA_NODE *pKRA = m_pKRAList; //point to the list
DWORD dwIndex = 0;
DWORD dwNewKRACount;
variant_t var;
if (m_fKRAUpdate)
{
while (NULL != pKRA)
{
if(pKRA->pCert)
{
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = NULL;
hr = EncodeCertString(
pKRA->pCert->pbCertEncoded,
pKRA->pCert->cbCertEncoded,
CV_OUT_BINARY,
&(V_BSTR(&var)));
_JumpIfError(hr, error, "EncodeCertString");
hr = pAdmin->SetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERT,
dwIndex,
PROPTYPE_BINARY,
&var);
_JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERT");
var.Clear();
}
++dwIndex;
pKRA = pKRA->next;
}
dwNewKRACount = dwIndex;
// Update total cert count only if the new list is smaller than the old
// list, otherwise SetCAProperty calls above already extended the list
if(dwNewKRACount<m_dwKRACount)
{
V_VT(&var) = VT_I4;
V_I4(&var) = dwNewKRACount;
hr = pAdmin->SetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERTCOUNT,
0,
PROPTYPE_LONG,
&var);
_JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERTCOUNT");
}
m_dwKRACount = dwNewKRACount;
}
if (m_fCountUpdate)
{
V_VT(&var) = VT_I4;
V_I4(&var) = m_dwKRAUsedCount;
hr = pAdmin->SetCAProperty(
m_pCA->m_bstrConfig,
CR_PROP_KRACERTUSEDCOUNT,
0,
PROPTYPE_LONG,
&var);
_JumpIfError(hr, error, "GetCAProperty CR_PROP_KRACERTUSEDCOUNT");
}
hr = S_OK;
error:
var.Clear();
return hr;
}
HRESULT
KRACertGetName(
IN CERT_CONTEXT const *pCert,
IN DWORD dwFlags, //dwFlags in CertGetNameString
OUT WCHAR **ppwszName)
{
HRESULT hr;
DWORD dwTypeParam;
DWORD cch = 0;
WCHAR *pwszName = NULL;
LPCWSTR pcwszEmpty = L"";
CSASSERT(NULL != ppwszName);
cch = 0;
while (TRUE)
{
if(pCert)
{
cch = CertGetNameString(
pCert,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
dwFlags, //subject or issuer
&dwTypeParam,
pwszName,
cch);
}
else
{
if(!pwszName)
cch = sizeof(WCHAR)*(wcslen(pcwszEmpty)+1);
else
wcscpy(pwszName, pcwszEmpty);
}
if (0 == cch)
{
hr = myHLastError();
_JumpError(hr, error, "CertGetNameString");
}
if (NULL != pwszName)
{
//done
break;
}
pwszName = (WCHAR*)LocalAlloc(LMEM_FIXED, cch * sizeof(WCHAR));
if (NULL == pwszName)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "LocalAlloc");
}
}
*ppwszName = pwszName;
pwszName = NULL;
hr = S_OK;
error:
if (NULL != pwszName)
{
LocalFree(pwszName);
}
return hr;
}
void
ListView_AddKRAItem(
HWND hwndListKRA,
int iItem,
KRA_NODE *pKRA)
{
HRESULT hr;
WCHAR *pwszSubject = NULL;
WCHAR *pwszIssuer = NULL;
CSASSERT(NULL != pKRA);
//get subject name
hr = KRACertGetName(pKRA->pCert, 0x0, &pwszSubject);
if (S_OK != hr)
{
CSASSERT(NULL == pwszSubject);
_PrintError(hr, "Invalid KRA cert");
}
//create a new item, 1st column, subject name, item data point to KRA
ListView_NewItem(hwndListKRA, iItem, pwszSubject, (LPARAM)pKRA,
pKRA->dwDisposition==KRA_DISP_VALID?nImageValidCert:nImageInvalidCert);
if(pKRA->pCert)
{
//get issuer name
hr = KRACertGetName(pKRA->pCert, CERT_NAME_ISSUER_FLAG, &pwszIssuer);
if (S_OK != hr)
{
CSASSERT(NULL == pwszIssuer);
_PrintError(hr, "KRACertGetName(issuer)");
}
//2nd column, issuer name
ListView_SetItemText(hwndListKRA, iItem, 1, pwszIssuer);
//3rd column, expiration date
ListView_SetItemFiletime(hwndListKRA, iItem, 2,
&pKRA->pCert->pCertInfo->NotAfter);
}
//4th column, status
ListView_SetItemText(hwndListKRA, iItem, 3,
(LPWSTR)CSvrSettingsKRAPage::MapDispositionToString(
pKRA->dwDisposition));
if (NULL != pwszSubject)
{
LocalFree(pwszSubject);
}
if (NULL != pwszIssuer)
{
LocalFree(pwszIssuer);
}
}
////
// Settings: KRA page
/////////////////////////////////////////////////////////////////////////////
// CSvrSettingsKRAPage property page
CSvrSettingsKRAPage::CSvrSettingsKRAPage(
CertSvrCA *pCA,
CSvrSettingsGeneralPage *pControlPage,
UINT uIDD)
: CAutoDeletePropPage(uIDD), m_pControlPage(pControlPage), m_pCA(pCA)
{
m_fArchiveKey = FALSE;
m_fCountUpdate = FALSE;
m_fKRAUpdate = FALSE;
m_pKRAList = NULL;
m_dwKRAUsedCount = 0;
m_dwKRACount = 0;
for(DWORD cStr=0;cStr<ARRAYSIZE(m_strDispositions);cStr++)
{
// IDS_DISPOSITION_* order must match KRA_DISP_*
if(m_strDispositions[cStr].IsEmpty())
m_strDispositions[cStr].LoadString(IDS_DISPOSITION_EXPIRED+cStr);
}
SetHelp(CERTMMC_HELPFILENAME, g_aHelpIDs_IDD_CERTSRV_PROPPAGE_CHOOSE_KRA);
}
CSvrSettingsKRAPage::~CSvrSettingsKRAPage()
{
if (NULL != m_pKRAList)
{
FreeKRAList(m_pKRAList);
}
}
// replacement for DoDataExchange
BOOL CSvrSettingsKRAPage::UpdateData(BOOL fSuckFromDlg /*= TRUE*/)
{
if (fSuckFromDlg)
{
m_dwKRAUsedCount = GetDlgItemInt(
m_hWnd, IDC_KRA_EDITCOUNT, NULL, FALSE);
}
else
{
SetDlgItemInt(m_hWnd, IDC_KRA_EDITCOUNT, m_dwKRAUsedCount, FALSE);
}
return TRUE;
}
void CSvrSettingsKRAPage::EnableKRAEdit(BOOL fEnabled)
{
::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_EDITCOUNT), fEnabled);
}
void CSvrSettingsKRAPage::EnableKRAListView(BOOL fEnabled)
{
// when disabling the list, deselect any item
if(!fEnabled)
{
ListView_SetItemState(GetDlgItem(m_hWnd, IDC_LIST_KRA),
-1, 0, LVIS_SELECTED);
}
// when enabling the list, select first item
else
{
ListView_SetItemState(GetDlgItem(m_hWnd, IDC_LIST_KRA),
0, LVIS_SELECTED, LVIS_SELECTED);
}
::EnableWindow(GetDlgItem(m_hWnd, IDC_LIST_KRA), fEnabled);
}
bool CSvrSettingsKRAPage::IsCurrentItemValidCert()
{
HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
// get kra index # from the current selection
int iSel = ListView_GetCurSel(hwndListKRA);
if (-1 == iSel)
{
return false;
}
// get item data
KRA_NODE* pKRA = (KRA_NODE*)ListView_GetItemData(hwndListKRA, iSel);
if(pKRA)
return pKRA->pCert?true:false;
else
return false;
}
void CSvrSettingsKRAPage::EnableKRARemoveViewListButtons(BOOL fEnabled)
{
::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_REMOVE), fEnabled);
::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_VIEW), fEnabled &&
IsCurrentItemValidCert());
}
void CSvrSettingsKRAPage::EnableKRAAddListButton(BOOL fEnabled)
{
::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_ADD), fEnabled);
}
void CSvrSettingsKRAPage::EnableKRARadioButtons(BOOL fMoreThanZero)
{
::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_ENABLE), fMoreThanZero);
::EnableWindow(GetDlgItem(m_hWnd, IDC_KRA_DISABLE), fMoreThanZero);
}
void
CSvrSettingsKRAPage::OnAddKRA()
{
HRESULT hr;
CERT_CONTEXT const *pKRACert = NULL; //don't free
KRA_NODE *pKRA = NULL; //don't free
HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
hr = myGetKRACertificateFromPicker(
g_hInstance,
hwndListKRA,
IDS_KRA_ADD_TITLE,
IDS_KRA_ADD_SUBTITLE,
NULL,
m_pCA->FIsUsingDS(),
FALSE, // fSilent
&pKRACert);
if ((S_OK == hr) && (pKRACert == NULL))
hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
if (S_OK != hr)
{
CSASSERT(NULL == pKRACert);
_PrintError(hr, "myGetKRACertificateFromPicker");
return;
}
if (!DoesKRACertExist(m_pKRAList, pKRACert))
{
hr = AddNewKRANode(
pKRACert,
KRA_DISP_NOTLOADED,
KRA_MARK_ADDED,
&m_pKRAList,
&pKRA);
if (S_OK == hr)
{
//add to the kra to the end of the list
int iItem = ListView_GetItemCount(hwndListKRA);
ListView_AddKRAItem(hwndListKRA, iItem, pKRA);
ListView_SetItemState(hwndListKRA, iItem, LVIS_SELECTED, LVIS_SELECTED);
if (0 == iItem)
{
//first item, buttons must have been disabled
EnableKRARemoveViewListButtons(TRUE);
EnableKRARadioButtons(TRUE);
EnableKRAListView(TRUE);
SendMessage(GetDlgItem(m_hWnd, IDC_KRA_ENABLE),
BM_CLICK, (WPARAM)0, (LPARAM)0);
}
SetModified(TRUE);
m_fDirty = TRUE;
m_fKRAUpdate = TRUE;
}
else
{
//pop up???
_PrintError(hr, "AddNewKRANode");
}
}
else
{
//UNDONE, ideally, pass m_pKRAList to picker to filter them out
_PrintError(S_OK, "KRA cert from the picker already in the list");
}
}
void
CSvrSettingsKRAPage::OnRemoveKRA()
{
KRA_NODE *pKRA;
int cItem;
HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
//get the selected KRA
int iSel = ListView_GetCurSel(hwndListKRA);
if (-1 == iSel)
{
return;
}
//get current count
cItem = ListView_GetItemCount(hwndListKRA);
pKRA = (KRA_NODE*)ListView_GetItemData(hwndListKRA, iSel);
CSASSERT(NULL != pKRA);
//remove it from the link list
RemoveKRANode(&m_pKRAList, pKRA);
//remove it from UI
if (ListView_DeleteItem(hwndListKRA, iSel))
{
//determine which item is selected
if (iSel == cItem - 1)
{
//the item removed was the last, modify the index
--iSel;
}
if (NULL != m_pKRAList)
{
ListView_SetItemState(hwndListKRA, iSel, LVIS_SELECTED, LVIS_SELECTED);
}
else
{
CSASSERT(1 == cItem);
//should check disable radio
SendMessage(GetDlgItem(m_hWnd, IDC_KRA_DISABLE),
BM_CLICK, (WPARAM)0, (LPARAM)0);
}
SetModified(TRUE);
m_fKRAUpdate = TRUE;
}
else
{
_PrintError(E_UNEXPECTED, "ListView_DeleteItem");
}
}
void
CSvrSettingsKRAPage::OnViewKRA()
{
HRESULT hr;
HCERTSTORE rghStores[2];
DWORD cStores = 0;
HCERTSTORE hCAStore;
HCERTSTORE hRootStore;
KRA_NODE *pKRA;
HWND hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
CRYPTUI_VIEWCERTIFICATE_STRUCTW sViewCert;
ZeroMemory(&sViewCert, sizeof(sViewCert));
// get kra index # from the current selection
int iSel = ListView_GetCurSel(hwndListKRA);
if (-1 == iSel)
{
return;
}
// get item data
pKRA = (KRA_NODE*)ListView_GetItemData(hwndListKRA, iSel);
CSASSERT(NULL != pKRA);
// get CA stores
hr = m_pCA->GetRootCertStore(&hRootStore);
if (S_OK == hr)
{
rghStores[cStores] = hRootStore;
++cStores;
}
else
{
_PrintError(hr, "GetRootCertStore");
}
hr = m_pCA->GetCACertStore(&hCAStore);
if (S_OK == hr)
{
rghStores[cStores] = hCAStore;
++cStores;
}
else
{
_PrintError(hr, "GetCACertStore");
}
sViewCert.pCertContext = pKRA->pCert;
sViewCert.hwndParent = m_hWnd;
sViewCert.dwSize = sizeof(sViewCert);
sViewCert.dwFlags = CRYPTUI_ENABLE_REVOCATION_CHECKING |
CRYPTUI_WARN_UNTRUSTED_ROOT |
CRYPTUI_DISABLE_ADDTOSTORE;
// if we're opening remotely, don't open local stores
if (! m_pCA->m_pParentMachine->IsLocalMachine())
sViewCert.dwFlags |= CRYPTUI_DONT_OPEN_STORES;
if (0 < cStores)
{
sViewCert.rghStores = rghStores;
sViewCert.cStores = cStores;
if (!CryptUIDlgViewCertificateW(&sViewCert, NULL))
{
hr = myHLastError();
if (hr != HRESULT_FROM_WIN32(ERROR_CANCELLED))
{
_PrintError(hr, "CryptUIDlgViewCertificateW");
}
}
}
else
{
DisplayCertSrvErrorWithContext(m_hWnd, hr, IDS_KRA_CANNOT_OPEN_STORE);
}
}
// replacement for BEGIN_MESSAGE_MAP
BOOL CSvrSettingsKRAPage::OnCommand(WPARAM wParam, LPARAM lParam)
{
BOOL fRet = TRUE;
DWORD dwNewVal;
switch(LOWORD(wParam))
{
case IDC_KRA_ADD:
OnAddKRA();
break;
case IDC_KRA_REMOVE:
OnRemoveKRA();
break;
case IDC_KRA_VIEW:
OnViewKRA();
break;
case IDC_KRA_DISABLE:
if ((BN_CLICKED == HIWORD(wParam)) && (m_dwKRAUsedCount != 0)) // if click to change state
{
SetModified(TRUE);
m_fArchiveKey = FALSE;
m_fCountUpdate = TRUE;
m_dwKRAUsedCount = 0;
EnableKRAListView(FALSE);
EnableKRARemoveViewListButtons(FALSE);
EnableKRAAddListButton(FALSE);
EnableKRAEdit(FALSE);
UpdateData(FALSE);
}
break;
case IDC_KRA_ENABLE:
if ((BN_CLICKED == HIWORD(wParam)) && (m_dwKRAUsedCount == 0)) // if click to change state
{
SetModified(TRUE);
m_fArchiveKey = TRUE;
m_fCountUpdate = TRUE;
m_dwKRAUsedCount = 1;
EnableKRAListView(TRUE);
EnableKRARemoveViewListButtons(GetKRACount(m_pKRAList));
EnableKRAAddListButton(TRUE);
EnableKRAEdit(TRUE);
UpdateData(FALSE);
}
break;
case IDC_KRA_EDITCOUNT:
dwNewVal = GetDlgItemInt(
m_hWnd, IDC_KRA_EDITCOUNT, NULL, FALSE);
switch(HIWORD(wParam))
{
case EN_CHANGE:
if(dwNewVal != m_dwKRAUsedCount)
{
SetModified(TRUE);
m_fCountUpdate = TRUE;
}
break;
default:
fRet = FALSE;
break;
}
break;
case IDC_LIST_KRA:
switch(HIWORD(wParam))
{
case LBN_SELCHANGE:
int selected = ListView_GetCurSel(
GetDlgItem(m_hWnd, IDC_LIST_KRA));
EnableKRARemoveViewListButtons(selected!=-1);
break;
}
break;
default:
fRet = FALSE;
break;
}
return fRet;
}
/////////////////////////////////////////////////////////////////////////////
// CSvrSettingsKRAPage radio controls handlers
void CSvrSettingsKRAPage::UpdateKRARadioControls()
{
int iRadio = IDC_KRA_ENABLE;
if (0 == m_dwKRAUsedCount)
{
iRadio = IDC_KRA_DISABLE;
}
SendMessage(GetDlgItem(m_hWnd, iRadio), BM_CLICK, (WPARAM)0, (LPARAM)0);
}
/////////////////////////////////////////////////////////////////////////////
// CSvrSettingsKRAPage message handlers
BOOL CSvrSettingsKRAPage::OnInitDialog()
{
HRESULT hr;
HWND hwndListKRA;
int iItem;
CString cstrItemName;
KRA_NODE *pKRA;
variant_t var;
ICertAdmin2 *pAdmin = NULL;
HIMAGELIST hImageList = NULL;
CWaitCursor WaitCursor;
// does parent init and UpdateData call
CAutoDeletePropPage::OnInitDialog();
hr = m_pCA->m_pParentMachine->GetAdmin2(&pAdmin);
_JumpIfError(hr, error, "GetAdmin2");
// set edit max char limit
SendDlgItemMessage(
IDC_KRA_EDITCOUNT,
EM_SETLIMITTEXT,
(WPARAM)4,
(LPARAM)0);
// init listview
hwndListKRA = GetDlgItem(m_hWnd, IDC_LIST_KRA);
//make listviews whole row selection
ListView_SetExtendedListViewStyle(hwndListKRA, LVS_EX_FULLROWSELECT);
hImageList = ImageList_LoadBitmap(
g_hInstance,
MAKEINTRESOURCE(IDB_16x16),
16,
1,
RGB(255, 0, 255));
ListView_SetImageList(hwndListKRA, hImageList, LVSIL_SMALL);
//set kra list as default focus
SetFocus(hwndListKRA);
//add multiple columns
//column 0
cstrItemName.LoadString(IDS_LISTCOL_SUBJECT);
ListView_NewColumn(hwndListKRA, 0, 90, (LPWSTR)(LPCWSTR)cstrItemName);
//column 1
cstrItemName.LoadString(IDS_LISTCOL_ISSUER);
ListView_NewColumn(hwndListKRA, 1, 90, (LPWSTR)(LPCWSTR)cstrItemName);
//column 2
cstrItemName.LoadString(IDS_LISTCOL_EXPIRATION_DATE);
ListView_NewColumn(hwndListKRA, 2, 90, (LPWSTR)(LPCWSTR)cstrItemName);
//column 3
cstrItemName.LoadString(IDS_LISTCOL_STATUS);
ListView_NewColumn(hwndListKRA, 3, 65, (LPWSTR)(LPCWSTR)cstrItemName);
CSASSERT(NULL == m_pKRAList);
//load all KRA certs
hr = LoadKRAList(pAdmin);
if (S_OK != hr)
{
CSASSERT(NULL == m_pKRAList);
_JumpError(hr, error, "LoadKRAList");
}
//list KRA certs in UI
pKRA = m_pKRAList;
iItem = 0;
while (NULL != pKRA)
{
ListView_AddKRAItem(hwndListKRA, iItem, pKRA);
++iItem;
pKRA = pKRA->next;
}
//enable view/remove buttons
EnableKRARemoveViewListButtons(m_fArchiveKey && 0 < iItem);
//enable add button
EnableKRAAddListButton(m_fArchiveKey);
EnableKRARadioButtons(TRUE);
if (m_fArchiveKey && 0 < iItem)
{
//select first one
ListView_SetItemState(hwndListKRA, 0, LVIS_SELECTED, LVIS_SELECTED);
}
EnableKRAEdit(m_dwKRAUsedCount);
UpdateKRARadioControls();
UpdateData(FALSE);
EnableKRAListView(m_dwKRAUsedCount);
error:
if(pAdmin)
pAdmin->Release();
if (hr != S_OK)
{
DisplayGenericCertSrvError(m_hWnd, hr);
return FALSE;
}
return TRUE;
}
void CSvrSettingsKRAPage::OnDestroy()
{
// Note - This needs to be called only once.
// If called more than once, it will gracefully return an error.
// if (m_hConsoleHandle)
// MMCFreeNotifyHandle(m_hConsoleHandle);
// m_hConsoleHandle = NULL;
CAutoDeletePropPage::OnDestroy();
}
BOOL CSvrSettingsKRAPage::OnApply()
{
HRESULT hr = S_OK;
ICertAdmin2 *pAdmin = NULL;
HWND hwndEdit = GetDlgItem(m_hWnd, IDC_KRA_EDITCOUNT);
DWORD dwNewVal = GetDlgItemInt(
m_hWnd, IDC_KRA_EDITCOUNT, NULL, FALSE);
// If key archival is enabled, you must have at least one
// KRA defined and the number of used KRAs must be between
// 1 and total number of KRAs defined
if(m_fArchiveKey)
{
if(0==GetKRACount(m_pKRAList))
{
DisplayCertSrvErrorWithContext(m_hWnd, S_OK, IDS_KRA_NOKRADEFINED);
SetFocus(GetDlgItem(m_hWnd, IDC_KRA_ADD));//focus on add button
return FALSE;
}
if(dwNewVal < 1 || dwNewVal > GetKRACount(m_pKRAList))
{
DisplayCertSrvErrorWithContext(m_hWnd, S_OK, IDS_KRA_COUNT_TOO_BIG);
SetFocus(hwndEdit); // focus on edit box
SendMessage(hwndEdit, EM_SETSEL, 0, -1); // select all text
return FALSE;
}
}
UpdateData(TRUE);
if (m_fKRAUpdate || m_fCountUpdate)
{
hr = m_pCA->m_pParentMachine->GetAdmin2(&pAdmin);
_JumpIfError(hr, error, "GetAdmin");
// update reg hash list
hr = SaveKRAList(pAdmin);
_JumpIfError(hr, error, "SaveKRAList");
m_pControlPage->NeedServiceRestart(SERVERSETTINGS_PROPPAGE_KRA);
m_pControlPage->TryServiceRestart(SERVERSETTINGS_PROPPAGE_KRA);
LoadKRADispositions();
m_fKRAUpdate = FALSE;
m_fCountUpdate = FALSE;
}
error:
if(pAdmin)
pAdmin->Release();
if (hr != S_OK)
{
DisplayGenericCertSrvError(m_hWnd, hr);
return FALSE;
}
return CAutoDeletePropPage::OnApply();
}
BOOL CSvrSettingsKRAPage::OnNotify(UINT idCtrl, NMHDR* pnmh)
{
LPNM_LISTVIEW pnmlv = (LPNM_LISTVIEW)pnmh;
switch(idCtrl)
{
//handle double click on list items
case IDC_LIST_KRA:
switch(pnmh->code)
{
case NM_DBLCLK:
OnViewKRA();
break;
case LVN_ITEMCHANGED:
EnableKRARemoveViewListButtons(pnmlv->uNewState & LVIS_SELECTED);
break;
}
}
return FALSE;
}