//+------------------------------------------------------------------------- // // 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;cCrtKRAGetCAProperty( 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(dwNewKRACountSetCAProperty( 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;cStrpCert?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; }