Click here to Skip to main content
15,891,316 members
Articles / Desktop Programming / MFC

The Ultimate Toolbox - Updates and User Contributions

Rate me:
Please Sign up or sign in to vote.
4.79/5 (26 votes)
12 Feb 2013CPOL8 min read 255.5K   23.7K   170  
Updates and User Contributions for the Ultimate Toolbox Libraries
// =================================================================
//  class: CUT_CertificateListDlg
//  File:  UTCertifListDlg.cpp
//  
//  Purpose:
//
//	  Certificate list dialog class
//       
// ===================================================================
// Ultimate TCP/IP v4.2
// This software along with its related components, documentation and files ("The Libraries")
// is � 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement").  Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office.  For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
// ===================================================================

#include "stdafx.h"
#include "..\\Res\\SecurityRes.h"

// Suppress warnings for non-safe str fns. Transitional, for VC6 support.
#pragma warning (push)
#pragma warning (disable : 4996)

// v4.2 - update 01 - 64-bit - included for GWL_USERDATA redef to GWLP_USERDATA
#include "UTCP64Bit.h"


#ifdef CUT_SECURE_SOCKET

#include "UTCertifListDlg.h"
#include "UT_CertWizard.h"
#include "UTCertifInstDlg.h"
#include "UTFile.h"
#include "shellapi.h"

#define LIST_SPACER		3
#define BORDER_SPACER	5
#define BITMAP_CX		16
#define BITMAP_CY		15

#define	CMD_REFRESH		WM_USER + 101
#define	CMD_VIEW		WM_USER + 102
#define	CMD_DELETE		WM_USER + 103
#define	CMD_REQUEST		WM_USER + 104
#define	CMD_INSTALL		WM_USER + 105

// ===================================================================
// CUT_CertificateListDlg class
// ===================================================================

/***********************************************
CUT_CertificateListDlg
    Constructor
Params
    none
Return
    none
************************************************/
CUT_CertificateListDlg::CUT_CertificateListDlg() :
	m_dwStoreLocations(STORE_LOCATION_CURRENT_USER | STORE_LOCATION_LOCAL_MACHINE),
	m_hInst((HINSTANCE)hDllHandle),
	m_hDlg(NULL),
	m_dwStoreListWidth(0),
	m_bShowStoreList(TRUE),
	m_bResizing(FALSE),
	m_nResizeXPos(0),
	m_nResizeOrigWidth(0),
	m_nSortingOrder(1),
	// v4.2 - changed - was using -1
	m_nLastColumnSorted(0xFFFFFFFF),
	m_StoresImageList(NULL),
	m_CertImageList(NULL),
	m_bViewCertOnDblClk(TRUE),
	m_hSmallIcon(NULL),
	m_hLargeIcon(NULL),
	m_bCertUsage(0)
{
	// Initialize
	_tcscpy(m_szDlgTitle, _T("Certificate list"));
	_tcscpy(m_szStoreNames, _T("MY,ROOT,TRUST,CA,"));
	_tcscpy(m_szReqInstallStoreNames, _T("MY,"));
	_tcscpy(m_szDeleteStoreNames, _T("MY,"));
}

/***********************************************
~CUT_CertificateListDlg
    Destructor
Params
    none
Return
    none
************************************************/
CUT_CertificateListDlg::~CUT_CertificateListDlg()
{
	// Delete image lists
	ImageList_Destroy(m_CertImageList);
	ImageList_Destroy(m_StoresImageList);

	// Destroy dialog icons
	if(m_hSmallIcon)
		DestroyIcon(m_hSmallIcon);
	if(m_hLargeIcon)
		DestroyIcon(m_hLargeIcon);
}

/***********************************************
OpenDlg
    Displays certificate list dialog
Params
    [hWnd]	- parent window of the list
Return
	-1		- in case of error
    IDOK
	IDCANCEL
************************************************/
int CUT_CertificateListDlg::OpenDlg(HWND hWndParent)
{
	return (int)DialogBoxParam((HINSTANCE)hDllHandle, MAKEINTRESOURCE(IDD_CERT_LIST_DIALOG), hWndParent, (DLGPROC)CertListDlgProc, (LPARAM)this);
}

/***********************************************
OnSize
    Called when the dialog size is changed
Params
    nWidth	- new width
	nHeight	- new Height
Return
	none
************************************************/
void CUT_CertificateListDlg::OnSize(int nWidth, int nHeight)
{
	// *****************************************************
	// ** Adjust position of the stores list
	// *****************************************************
	RECT	rectNewStorePos = {0,0,0,0};

	// Initialize window rect in dialog units
	rectNewStorePos.left = BORDER_SPACER;
	rectNewStorePos.top = BORDER_SPACER;

	// Convert from dialog units
	MapDialogRect(m_hDlg, &rectNewStorePos);

	// Get rect bottom and right position
	rectNewStorePos.bottom = nHeight - rectNewStorePos.top;
	rectNewStorePos.right = rectNewStorePos.left + m_dwStoreListWidth;

	// Move stores list
	int nListWidth = rectNewStorePos.right - rectNewStorePos.left;
	MoveWindow(	m_hStoresList, 
				rectNewStorePos.left, 
				rectNewStorePos.top, 
				(m_bShowStoreList && nListWidth > 4) ? nListWidth : 0,
				(m_bShowStoreList) ? rectNewStorePos.bottom - rectNewStorePos.top : 0, 
				TRUE);

	// *****************************************************
	// ** Adjust position of the certificates list
	// *****************************************************
	RECT	rectNewCertPos = {0,0,0,0};

	// Convert spacer from dialog units
	rectNewCertPos.left = LIST_SPACER;
	MapDialogRect(m_hDlg, &rectNewCertPos);
	
	// Initialize window rect 
	rectNewCertPos.left = (m_bShowStoreList) ? rectNewStorePos.right + rectNewCertPos.left : rectNewCertPos.left;
	rectNewCertPos.top = rectNewStorePos.top;
	rectNewCertPos.right = nWidth - rectNewStorePos.left;
	rectNewCertPos.bottom = rectNewStorePos.bottom;

	// Move certificate list
	nListWidth = rectNewCertPos.right - rectNewCertPos.left;
	MoveWindow(	m_hCertList, 
				rectNewCertPos.left, 
				rectNewCertPos.top, 
				(nListWidth > 4) ? nListWidth : 0, 
				rectNewCertPos.bottom - rectNewCertPos.top, 
				TRUE);

	// *****************************************************
	// ** Adjust position of the splitter
	// *****************************************************
	RECT	rectNewSplitPos;

	// Initialize window rect 
	rectNewSplitPos.left = rectNewStorePos.right;
	rectNewSplitPos.top = rectNewStorePos.top;
	rectNewSplitPos.right = rectNewCertPos.left;
	rectNewSplitPos.bottom = rectNewStorePos.bottom;

	// Move stores list
	MoveWindow(	GetDlgItem(m_hDlg, IDC_STATIC_SPLIT), 
				rectNewSplitPos.left, 
				rectNewSplitPos.top, 
				rectNewSplitPos.right - rectNewSplitPos.left, 
				rectNewSplitPos.bottom - rectNewSplitPos.top, 
				TRUE);

}

/***********************************************
IsCursorInSplitter
    Checks if we support splitter an cursor is
	located in splitter area
Params
    none
Return
	TRUE if yes
************************************************/
BOOL CUT_CertificateListDlg::IsCursorInSplitter()
{
	POINT	pt;
	RECT	rect;

	// We don't have splitter
	if(!m_bShowStoreList)
		return FALSE;

	// Get cursor position
	GetCursorPos(&pt);

	// Get splitter window position
	GetWindowRect(GetDlgItem(m_hDlg, IDC_STATIC_SPLIT), &rect);

	// Check if cursor is in the splitter
	return PtInRect(&rect, pt);
}

/***********************************************
OnInit
    Called when the dialog is initialized
Params
    none
Return
	none
************************************************/
void CUT_CertificateListDlg::OnInit()
{
	// Set dialog window text
	SetWindowText(m_hDlg, m_szDlgTitle);

	// Set store list size
	RECT	rect = {0,0,0,0};
	rect.left = 140;
	MapDialogRect(m_hDlg, &rect);
	m_dwStoreListWidth = rect.left;

	// Adjust windows size
	GetClientRect(m_hDlg, &rect);
	OnSize(rect.right, rect.bottom);

	// Set tree control images
	InitImageLists();

	// Set list columns
	InitListColumns();

	// Set dialog window icons
	m_hSmallIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_ICON_CERT_LIST_SMALL));
	m_hLargeIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_ICON_CERT_LIST_LARGE));
	SendMessage(m_hDlg, WM_SETICON, ICON_SMALL, (LPARAM)m_hSmallIcon);
	SendMessage(m_hDlg, WM_SETICON, ICON_BIG, (LPARAM)m_hLargeIcon);

	// Fill the list of certificate stores
	StoreListRefresh();
}

/***********************************************
StoreListRefresh
    Fill/Refresh the store list
Params
    none
Return
	none
************************************************/
void CUT_CertificateListDlg::StoreListRefresh()
{
	HTREEITEM		hFirstItem = NULL;
	CUT_TStringList	pListStores;
	DWORD			dwFlag = 0;

	// Delete all items first
	TreeView_DeleteAllItems(m_hStoresList);

	// Convert available store name string to upper case
	_tcsupr(m_szStoreNames);

	// String must end with the ','
	if(*m_szStoreNames != NULL && *(m_szStoreNames + _tcslen(m_szStoreNames) - 1) != _T(','))
		_tcscat(m_szStoreNames, _T(","));

	// Loop through all store locations
	for(int i = STORE_LOCATION_CURRENT_USER; i <= STORE_LOCATION_LOCAL_MACHINE_GROUP_POLICY; i *= 2)
	{
		// Should we display this one ?
		if(m_dwStoreLocations & i)
		{
			// Add location item to the tree
			AddItemToTree((_TCHAR *)GetStoreParams((enumStoreLocation)i, dwFlag), 1);

			// Get the list of stores in the location
			CUT_CertificateManager::GetSystemStoreList(pListStores, dwFlag);

			// Add store names to the tree control
			for(int j = 0; j < pListStores.GetCount(); j++)
			{
				// Convert store name string to upper case
				_TCHAR	szName[100];
				_tcscpy(szName, pListStores.GetString(j));
				_tcsupr(szName);
				_tcscat(szName, _T(","));

				// Check what store names we should show
				if(*m_szStoreNames == NULL || _tcsstr(m_szStoreNames, szName))
				{
					HTREEITEM hItem = AddItemToTree((_TCHAR *)GetStoreExtName(pListStores.GetString(j)), 2, dwFlag);
					if(hFirstItem == NULL)
						hFirstItem = hItem;
				}
			}
		}
	}

	// Select first store in the list 
	TreeView_SelectItem(m_hStoresList, hFirstItem);
}

/***********************************************
CertListRefresh
    Fill/Refresh the certificates list
Params
    TVITEM	- new item structure
Return
	none
************************************************/
void CUT_CertificateListDlg::CertListRefresh(TVITEM newItem)
{
	LVITEM	lvi;
	_TCHAR	szBuffer[300];

	// Close current certificate store
	m_CertStore.Close();

	// Delete all certificate list items first
	for(int index = 0; index < ListView_GetItemCount(m_hCertList); index++)
	{
		LVITEM	lvi;
		lvi.iItem = index;
		lvi.mask = LVIF_PARAM;
		if(ListView_GetItem(m_hCertList, &lvi))
		{
			if(lvi.lParam != NULL)
				delete ((CUT_Certificate *)lvi.lParam);
		}
	}
	ListView_DeleteAllItems(m_hCertList);

    // Initialize LVITEM members that are common to all items. 
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; 
    lvi.state = 0; 
    lvi.stateMask = 0; 
    lvi.iImage = 0;                     // image list index 
	lvi.iSubItem = 0;

	// Store location item selected
	if(newItem.lParam == 0)
		return;

	// Get item data
	TVITEM	tvi;
	tvi.hItem = newItem.hItem;
	tvi.mask = TVIF_TEXT;
	tvi.pszText = szBuffer;
	tvi.cchTextMax = sizeof(szBuffer);
	TreeView_GetItem(m_hStoresList, &tvi);

	// Remove extended name
	_TCHAR *lpszExtname = _tcsstr(szBuffer, _T(" - "));
	if(lpszExtname != NULL)
		*lpszExtname = NULL;

	// List all certificates in store
	m_CertStore.Open(szBuffer, (DWORD)newItem.lParam);
	m_CertStore.ListCertificates();
	for(int i = 0; i < m_CertStore.GetCertListSize(); i++)
	{
		_TCHAR	szBuffer[100];
		CUT_Certificate	*tmpCert = new CUT_Certificate();
		m_CertStore.GetCertListItem(i, *tmpCert);

		// Filter certificates by usage
		if(m_bCertUsage == 0 || tmpCert->GetKeyUsage() & m_bCertUsage)
		{
			// Add item into the list
			lvi.iItem = i;
			lvi.lParam = (LPARAM)tmpCert;
			lvi.pszText = (_TCHAR *)tmpCert->GetIssuedTo();
			lvi.cchTextMax = (int)strlen((char *)tmpCert->GetIssuedTo());
			ListView_InsertItem(m_hCertList, &lvi);
			
			// Add issuer
			ListView_SetItemText(m_hCertList, i, 1, (_TCHAR *)tmpCert->GetIssuer());

			// Add expiry date
			FILETIME	ft = tmpCert->GetValidTo();
			SYSTEMTIME	st;
			FileTimeToSystemTime(&ft, &st);
			_sntprintf(szBuffer, sizeof(szBuffer)/sizeof(_TCHAR)-1, _T("%d/%d/%d"), st.wMonth, st.wDay, st.wYear);
			ListView_SetItemText(m_hCertList, i, 2, szBuffer);

			// Add public key
			_sntprintf(szBuffer, sizeof(szBuffer)/sizeof(_TCHAR)-1, _T("%s (%d)"), tmpCert->GetKeyAlgId(), tmpCert->GetKeySize());
			ListView_SetItemText(m_hCertList, i, 3, szBuffer);
		}
	}
}

/***********************************************
GetStoreExtName
    Gets store extended name
	Replace "MY" with "Personel" ...
Params
    szName	- short name 
Return
	return store extended name
************************************************/
const _TCHAR *CUT_CertificateListDlg::GetStoreExtName(const _TCHAR *szName)
{
	const _TCHAR	*lpszResult = szName;
	static _TCHAR	*szStoreName[] = {	_T("My - Personal"),
										_T("Root - Trusted Root Certification Authorities"),
										_T("Trust - Enterprise Trust"),
										_T("CA - Intermediate Certification Authorities") };

	if(_tcsicmp(szName, _T("MY")) == 0)
		lpszResult = szStoreName[0];
	else if(_tcsicmp(szName, _T("ROOT")) == 0)
		lpszResult = szStoreName[1];
	else if(_tcsicmp(szName, _T("TRUST")) == 0)
		lpszResult = szStoreName[2];
	else if(_tcsicmp(szName, _T("CA")) == 0)
		lpszResult = szStoreName[3];

	return lpszResult;
}

/***********************************************
GetStoreParams
    Gets store location name and flag
Params
    Location	- store location type
	dwFlag		- return flag
Return
	return store location name
************************************************/
const _TCHAR *CUT_CertificateListDlg::GetStoreParams(enumStoreLocation Location, DWORD &dwFlag)
{
	_TCHAR			*lpszResult = NULL;
	static _TCHAR	*szLocationName[] = {	_T("Current User"),
										_T("Local Machine"),
										_T("Current Service"),
										_T("Services"),
										_T("Users"),
										_T("User Group Policy"),
										_T("Machine Group Policy") };
	dwFlag = 0;
	switch(Location)
	{
		case(STORE_LOCATION_CURRENT_USER):
			dwFlag = CERT_SYSTEM_STORE_CURRENT_USER;
			lpszResult = szLocationName[0];
			break;
		case(STORE_LOCATION_LOCAL_MACHINE):
			dwFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE;
			lpszResult = szLocationName[1];
			break;
		case(STORE_LOCATION_CURRENT_SERVICE):
			dwFlag = CERT_SYSTEM_STORE_CURRENT_SERVICE;
			lpszResult = szLocationName[2];
			break;
		case(STORE_LOCATION_SERVICES):
			dwFlag = CERT_SYSTEM_STORE_SERVICES;
			lpszResult = szLocationName[3];
			break;
		case(STORE_LOCATION_USERS):
			dwFlag = CERT_SYSTEM_STORE_USERS;
			lpszResult = szLocationName[4];
			break;
		case(STORE_LOCATION_CURRENT_USER_GROUP_POLICY):
			dwFlag = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
			lpszResult = szLocationName[5];
			break;
		case(STORE_LOCATION_LOCAL_MACHINE_GROUP_POLICY):
			dwFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
			lpszResult = szLocationName[6];
			break;
	}
	
	return lpszResult;
}

/***********************************************
AddItemToTree
    Adds item to the store tree
Params
	lpszItem	- item name
	nLevel		- item level
Return
	HTREEITEM	- item added
************************************************/
HTREEITEM CUT_CertificateListDlg::AddItemToTree(LPTSTR lpszItem, int nLevel, LPARAM lParam)
{ 
    TVITEM tvi; 
    TVINSERTSTRUCT tvins; 
    static HTREEITEM hPrev = (HTREEITEM) TVI_FIRST; 
    static HTREEITEM hPrevRootItem = NULL; 
    static HTREEITEM hPrevLev2Item = NULL; 
 
    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; 
 
    // Set the text of the item. 
    tvi.pszText = lpszItem; 
    tvi.cchTextMax = (int)_tcslen(lpszItem); 
 
    // Assume the item is not a parent item, so give it a document image. 
    tvi.iImage = nLevel - 1;
    tvi.iSelectedImage = (nLevel == 1) ? nLevel + 1 : nLevel - 1;
 
    // Save the parameter
    tvi.lParam = lParam; 
 
    tvins.item = tvi; 
    tvins.hInsertAfter = hPrev; 
 
    // Set the parent item based on the specified level. 
    if (nLevel == 1) 
        tvins.hParent = TVI_ROOT; 
    else if (nLevel == 2) 
        tvins.hParent = hPrevRootItem; 
    else 
        tvins.hParent = hPrevLev2Item; 

    // Add the item to the tree view control. 
    hPrev = (HTREEITEM) SendMessage(m_hStoresList, TVM_INSERTITEM, 0, (LPARAM) (LPTVINSERTSTRUCT) &tvins); 
 
    // Save the handle to the item. 
    if (nLevel == 1) 
        hPrevRootItem = hPrev; 
    else if (nLevel == 2) 
        hPrevLev2Item = hPrev; 
 
    return hPrev; 
} 
/***********************************************
InitListColumns
    Initialize certificates	list columns
Params
	none
Return
	TRUE if success
************************************************/
BOOL CUT_CertificateListDlg::InitListColumns() 
{
	LVCOLUMN	lvc; 
    int			iCol; 
	int			nSize[4];
	_TCHAR		*szNames[] = {	_T("Issued To"),
								_T("Issued By"),
								_T("Expiry Date"),
								_T("Public Key"});
 
	// Initialize columns size
	RECT	rect;
	int		nUnit;
	GetClientRect(m_hCertList, &rect);
	nUnit = (rect.right - rect.left) / 10;
	nSize[0] = 3 * nUnit;
	nSize[1] = 3 * nUnit;
	nSize[2] = 2 * nUnit;
	nSize[3] = 2 * nUnit;

    // Initialize the LVCOLUMN structure. 
    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 
    lvc.fmt = LVCFMT_LEFT; 
    lvc.pszText = _T("Hi there!"); 
 
    // Add the columns. 
    for (iCol = 0; iCol < 4; iCol++) 
	{ 
        lvc.iSubItem = iCol; 
		lvc.cx = nSize[iCol]; 
		lvc.pszText = szNames[iCol]; 
        if (ListView_InsertColumn(m_hCertList, iCol, &lvc) == -1) 
            return FALSE; 
    } 

	// Set extended list style
	ListView_SetExtendedListViewStyle(m_hCertList, LVS_EX_FULLROWSELECT);
	
	return TRUE;
}
 
/***********************************************
InitImageLists
    Initialize store tree control and certificates
	list image lists
Params
	none
Return
	TRUE if success
************************************************/
BOOL CUT_CertificateListDlg::InitImageLists() 
{
    HBITMAP		hbmp;	// handle to bitmap 
	HBITMAP		hmask;	// handle to mask bitmap 

	// *****************************************************
	// ** Storage tree
	// *****************************************************

    // Create the image list. 
    if ((m_StoresImageList = ImageList_Create(BITMAP_CX, BITMAP_CY, ILC_MASK, 2, 0)) == NULL) 
        return FALSE; 

    // Add bitmaps to the image list
    hbmp = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_STORE_LOCATION)); 
	hmask = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_STORE_LOCATION_MASK)); 
    ImageList_Add(m_StoresImageList, hbmp, hmask); 
    DeleteObject(hbmp); 
	DeleteObject(hmask); 

    hbmp = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_STORE)); 
	hmask = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_STORE_MASK)); 
    ImageList_Add(m_StoresImageList, hbmp, hmask); 
    DeleteObject(hbmp); 
	DeleteObject(hmask); 

    hbmp = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_STORE_LOCATION_SEL)); 
	hmask = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_STORE_LOCATION_SEL_MASK)); 
    ImageList_Add(m_StoresImageList, hbmp, hmask); 
    DeleteObject(hbmp); 
	DeleteObject(hmask); 

    // Associate the image list with the tree view control. 
    TreeView_SetImageList(m_hStoresList, m_StoresImageList, TVSIL_NORMAL); 

	// *****************************************************
	// ** Certificates list
	// *****************************************************

    // Create the image list. 
    if ((m_CertImageList = ImageList_Create(BITMAP_CX, BITMAP_CY, ILC_MASK, 1, 0)) == NULL) 
        return FALSE; 

    // Add bitmap to the image list
    hbmp = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_CERTIFICATE)); 
	hmask = LoadBitmap(m_hInst, MAKEINTRESOURCE(IDB_BITMAP_CERTIFICATE_MASK)); 
    ImageList_Add(m_CertImageList, hbmp, hmask); 
    DeleteObject(hbmp); 
	DeleteObject(hmask); 

    // Associate the image list with the tree view control. 
    ListView_SetImageList(m_hCertList, m_CertImageList, LVSIL_SMALL); 

	return TRUE; 
} 

/***********************************************
OnMouseMove
    Called on WM_MOUSEMOVE
Params
	fwKeys	- key flags 
    xPos	- horizontal position of cursor 
	yPos	- vertical position of cursor 
Return
	none
************************************************/
void CUT_CertificateListDlg::OnMouseMove(int /* fwKeys */, int xPos, int /* yPos */)
{
	// If store list is shown change the shape of the cursor in splitter area
	if(IsCursorInSplitter())
		SetCursor(LoadCursor(NULL, IDC_SIZEWE));
	else
		SetCursor(LoadCursor(NULL, IDC_ARROW));

	// Change splitter position and readjust windows
	if(m_bResizing)
	{
		// Get dialog client window
		RECT	rect, rect2 = {0,0,0,0};
		GetClientRect(m_hDlg, &rect);

		// Check if we are in the boundary of resizing area
		rect2.left = BORDER_SPACER;
		MapDialogRect(m_hDlg, &rect2);
		rect.left += rect2.left;
		rect.right -= rect2.left;
		if(xPos >= rect.left && xPos <= rect.right)
		{
			// Set new width of the stores list
			m_dwStoreListWidth = m_nResizeOrigWidth - (m_nResizeXPos - xPos);

			// Readjust windows
			GetClientRect(m_hDlg, &rect);
			OnSize(rect.right, rect.bottom);
		}
	}	

}

/***********************************************
OnLButtonDown
    Called on WM_LBUTTONDOWN
Params
	fwKeys	- key flags 
    xPos	- horizontal position of cursor 
	yPos	- vertical position of cursor 
Return
	none
************************************************/
void CUT_CertificateListDlg::OnLButtonDown(int /* fwKeys */, int xPos, int /* yPos */)
{
	// If button was clicked in splitter
	if(IsCursorInSplitter())
	{
		// Set splitter resizing flag
		m_bResizing = TRUE;

		// Capture mouse
		SetCapture(m_hDlg);

		// Save the horizontal position of cursor and original list width
		m_nResizeXPos = xPos;
		m_nResizeOrigWidth = m_dwStoreListWidth;
	}
}

/***********************************************
OnLButtonUp
    Called on WM_LBUTTONUP
Params
	fwKeys	- key flags 
    xPos	- horizontal position of cursor 
	yPos	- vertical position of cursor 
Return
	none
************************************************/
void CUT_CertificateListDlg::OnLButtonUp(int /* fwKeys */, int /* xPos */, int /* yPos */)
{
	// Release mouse capture 
	if(m_bResizing)
	{
		ReleaseCapture();
		m_bResizing = FALSE;
	}
}

/***********************************************
OnTreeSelChange
    Called when selection is changed in store list
Params
	pnmtv	- address of an NMTREEVIEW structure. 
Return
	none
************************************************/
void CUT_CertificateListDlg::OnTreeSelChange(LPNMTREEVIEW pnmtv)
{
	// Refresh certificates list
	CertListRefresh(pnmtv->itemNew);
}

/***********************************************
OnColumnClick
    Called when the column is clicked in the 
	certificate list
Params
	pnmv	- address of an NMLISTVIEW structure. 
Return
	none
************************************************/
void CUT_CertificateListDlg::OnColumnClick(LPNMLISTVIEW pnmv)
{
	// Change sorting order
	if(m_nLastColumnSorted == (DWORD)pnmv->iSubItem)
		m_nSortingOrder = m_nSortingOrder * (-1);
	
	// Sort items in the list
	ListView_SortItems(m_hCertList, (PFNLVCOMPARE)CompareFunc, MAKELONG(pnmv->iSubItem, m_nSortingOrder));

	// Remember last sorted column
	m_nLastColumnSorted = pnmv->iSubItem;
}

/***********************************************
OnDblClick
    Called on double click in the certificate list 
Params
	pnmv	- address of an NMLISTVIEW structure. 
Return
	none
************************************************/
void CUT_CertificateListDlg::OnDblClick(LPNMLISTVIEW pnmv)
{
	if(pnmv->hdr.hwndFrom == m_hCertList)
	{
		// View certificate and close dialog
		if(ViewCertificate() && !m_bViewCertOnDblClk)
			EndDialog(m_hDlg, IDOK);
	}
}

/***********************************************
OnRightClick
    Called when right mouse button is clicked
	in the certificate list 
Params
	pnmv	- address of an NMLISTVIEW structure. 
Return
	none
************************************************/
void CUT_CertificateListDlg::OnRightClick(LPNMLISTVIEW pnmv)
{
	if(pnmv->hdr.hwndFrom == m_hCertList)
	{
		// *****************************************************
		// ** Find selected item in the stores tree control
		// *****************************************************
		TVITEM		tviStore;
		// v4.2 added this memset to initialize - avoids warning
		memset(&tviStore, 0, sizeof(tviStore));
		tviStore.hItem = TreeView_GetSelection(m_hStoresList);
		tviStore.mask = TVIF_PARAM ;
		if(tviStore.hItem)
			TreeView_GetItem(m_hStoresList, &tviStore);

		// Don't show the menu if store name not selected
		if(tviStore.lParam == 0)
			return;

		// *****************************************************
		// ** Find selected item in the certificate list
		// *****************************************************
		LVITEM	lvi;
		lvi.lParam = NULL;
		lvi.iItem = ListView_GetSelectionMark(m_hCertList);
		if(lvi.iItem >= 0)
		{
			lvi.mask = LVIF_PARAM;
			ListView_GetItem(m_hCertList, &lvi);
		}

		// *****************************************************
		// ** Create pop-up menu
		// *****************************************************
		HMENU hMenu = CreatePopupMenu();

		// Get current store name
		_TCHAR	szStoreName[200] = {_T("")};
		if(m_CertStore.GetStoreName())
		{
			_tcsncpy(szStoreName, m_CertStore.GetStoreName(), sizeof(szStoreName)/sizeof(_TCHAR) - 2);
			_tcsupr(szStoreName);
			_tcscat(szStoreName, _T(","));
		}

		// Add Refresh menu item
		AppendMenu(hMenu, MF_STRING, CMD_REFRESH, _T("&Refresh"));
		AppendMenu(hMenu, MF_SEPARATOR, NULL, NULL);

		// Add View menu item
		AppendMenu(hMenu, ((lvi.lParam == NULL) ? MF_GRAYED : NULL) | MF_STRING, CMD_VIEW, _T("&View"));

		// Add Delete menu item
		if(	*m_szDeleteStoreNames != '-' &&
			(*m_szDeleteStoreNames == NULL || _tcsstr(m_szDeleteStoreNames, szStoreName)))
		{
			AppendMenu(hMenu, ((lvi.lParam == NULL) ? MF_GRAYED : NULL) | MF_STRING, CMD_DELETE, _T("&Delete"));
		}

		// Add Request/Install menu item
		if(	*m_szReqInstallStoreNames != '-' &&
			(*m_szReqInstallStoreNames == NULL || _tcsstr(m_szReqInstallStoreNames, szStoreName)))
		{
			AppendMenu(hMenu, MF_SEPARATOR, NULL, NULL);
			AppendMenu(hMenu, MF_STRING, CMD_REQUEST, _T("&Certificate Request"));
			AppendMenu(hMenu, MF_STRING, CMD_INSTALL, _T("&Install Certificate"));
		}


		// *****************************************************
		// ** Show menu and process commands
		// *****************************************************
		POINT	point;
		GetCursorPos(&point);
		int		nCmd = TrackPopupMenu(hMenu, TPM_NONOTIFY | TPM_RETURNCMD| TPM_LEFTALIGN | TPM_TOPALIGN, point.x, point.y, 0, m_hDlg, NULL);
		switch(nCmd)
		{
			// View certificate
			case(CMD_VIEW):
				ViewCertificate(TRUE);
				break;

			// Request new certificate
			case(CMD_REQUEST):
				if(m_CertStore.GetStoreName())
				{
					CUT_CertRequestWizard	wizard;
					wizard.DisplayWizard(m_CertStore.GetStoreLocation());
				}
				break;

			// Delete certificate from the list
			case(CMD_DELETE):
				if(MessageBox(m_hDlg, _T("Warning: This will permanantly delete the certificate. You will not be able to re-install it later.\r\n\r\nAre you sure you want to delete the certificate?"), _T("Delete Certificate"), MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDYES)
				{
					// Delete certificate 
					CUT_Certificate *pCert = (CUT_Certificate *)lvi.lParam;
					if(pCert != NULL) 
					{
						// Delete item from the list
						ListView_DeleteItem(m_hCertList, lvi.iItem);

						// Delete the certificate
						m_CertStore.DeleteCertificate(pCert);

						// Delet certificate object
						delete pCert;

					}
				}
				break;

			// Install new certificate
			case(CMD_INSTALL):
				if(nCmd != CMD_DELETE && m_CertStore.GetStoreName())
				{
					CUT_CertificateInstallDlg	dlg;
					dlg.OpenDlg();
				}
				// NOTE !!! 
				// There is no break in this case.
				// After installing the certificate - refreshing

			// Refresh certificate list
			case(CMD_REFRESH):
			{
				TVITEM		tvi;
				tvi.hItem = TreeView_GetSelection(m_hStoresList);
				tvi.mask = TVIF_PARAM ;
				if(tvi.hItem)
				{
					TreeView_GetItem(m_hStoresList, &tvi);
					CertListRefresh(tvi);
				}
				break;
			}
		}

		// Destroy the menu
		DestroyMenu(hMenu);
	}
}

/***********************************************
CompareFunc
    The comparison function used in column sorting
Params
	lParam1		- first item parameter
	lParam2		- second item parameter
	lParamSort	- sort items function parameter (column number)
Return
	The comparison function must return a negative 
	value if the first item should precede the 
	second, a positive value if the first item 
	should follow the second, or zero if the two 
	items are equivalent. 
************************************************/
int CALLBACK CUT_CertificateListDlg::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	CUT_Certificate	*cert1 = (CUT_Certificate *)lParam1, *cert2 = (CUT_Certificate *)lParam2;
	_TCHAR	szBuffer1[300], szBuffer2[300];
	int		nColumn = LOWORD(lParamSort);
	int		nOrder = (HIWORD(lParamSort) == 1) ? 1 : -1;
	
	if(cert1 == NULL || cert2 == NULL)
		return 0;

	// Get comparable data depending on the column
	switch(nColumn)
	{
		// Issued To
		case(0):
			_tcscpy(szBuffer1, cert1->GetIssuedTo());
			_tcscpy(szBuffer2, cert2->GetIssuedTo());
			break;
		// Issuer
		case(1):
			_tcscpy(szBuffer1, cert1->GetIssuer());
			_tcscpy(szBuffer2, cert2->GetIssuer());
			break;
		// Valid To
		case(2):
			{
			FILETIME	ft = cert1->GetValidTo();
			SYSTEMTIME	st;
			FileTimeToSystemTime(&ft, &st);
			_sntprintf(szBuffer1, sizeof(szBuffer1)/sizeof(TCHAR)-1, _T("%d/%d/%d"), st.wMonth, st.wDay, st.wYear);
			ft = cert2->GetValidTo();
			FileTimeToSystemTime(&ft, &st);
			_sntprintf(szBuffer2, sizeof(szBuffer2)/sizeof(TCHAR)-1, _T("%d/%d/%d"), st.wMonth, st.wDay, st.wYear);
			break;
			}
		// Key type & size
		case(3):
			_sntprintf(szBuffer1, sizeof(szBuffer1)/sizeof(TCHAR)-1, _T("%s (%d)"), cert1->GetKeyAlgId(), cert1->GetKeySize());
			_sntprintf(szBuffer2, sizeof(szBuffer2)/sizeof(TCHAR)-1, _T("%s (%d)"), cert2->GetKeyAlgId(), cert2->GetKeySize());
			break;

		default:
			return 0;
	}


	// Compare items
	return (_tcscmp(szBuffer1, szBuffer2)) * nOrder;
}

/***********************************************
OnClose
    Called when dialog is closed
Params
	none
Return
	none
************************************************/
void CUT_CertificateListDlg::OnClose(int nCommandID)
{
	// Get the selected certificate
	if(nCommandID == IDOK)
	{
		// Find selected item in the certificate list
		LVITEM	lvi;
		lvi.lParam = NULL;
		lvi.iItem = ListView_GetSelectionMark(m_hCertList);
		if(lvi.iItem >= 0)
		{
			// Get item data
			lvi.mask = LVIF_PARAM;
			ListView_GetItem(m_hCertList, &lvi);
			if(lvi.lParam != NULL)
				m_SelectedCert = *(CUT_Certificate *)lvi.lParam;
		}
	}

	// Delete all certificate list items first
	for(int i = 0; i < ListView_GetItemCount(m_hCertList); i++)
	{
		LVITEM	lvi;
		lvi.iItem = i;
		lvi.mask = LVIF_PARAM;
		if(ListView_GetItem(m_hCertList, &lvi))
		{
			if(lvi.lParam != NULL)
				delete ((CUT_Certificate *)lvi.lParam);
		}
	}
	ListView_DeleteAllItems(m_hCertList);

	// Close dialog
	EndDialog(m_hDlg, nCommandID);
}

/***********************************************
ViewCertificate
    View certificate data
Params
	bFromMenu	- TRUE if called from the menu
Return
	TRUE if certificate was found
************************************************/
BOOL CUT_CertificateListDlg::ViewCertificate(BOOL bFromMenu)
{
	BOOL	bResult = FALSE;

	// Find selected item in the certificate list
	LVITEM	lvi;
	lvi.lParam = NULL;
	lvi.iItem = ListView_GetSelectionMark(m_hCertList);
	if(lvi.iItem >= 0)
	{
		// Get item data
		lvi.mask = LVIF_PARAM;
		ListView_GetItem(m_hCertList, &lvi);
		CUT_Certificate *cert = (CUT_Certificate *)lvi.lParam;
		if(cert != NULL && cert->GetContext() != NULL)
		{
			bResult = TRUE;

			// Show certificate data
			if(m_bViewCertOnDblClk || bFromMenu)
			{
				// Get temp file name
				_TCHAR	szFileName[MAX_PATH + 1];
				GetTempPath(MAX_PATH, szFileName);
				_tcscat(szFileName, _T("Temp.cer"));

				// Save certificate into the temp file
				CUT_File	file;
				if(file.Open(szFileName, GENERIC_WRITE, CREATE_ALWAYS) == 0)
				{
					if(file.Write(cert->GetContext()->pbCertEncoded, cert->GetContext()->cbCertEncoded) == cert->GetContext()->cbCertEncoded)
					{
						// Close file
						file.Close();

						// Open the certificate file for viewing
						ShellExecute(m_hDlg, _T("open"), szFileName, NULL, NULL, SW_SHOWNORMAL);
					}
				}

				// Close file
				file.Close();

			}
			// Set selected certificate
			else
			{
				m_SelectedCert = *cert;
			}
		}
	}

	return bResult;
}

/***********************************************
CertListDlgProc
    Certificate list dialog function
************************************************/
BOOL CALLBACK CUT_CertificateListDlg::CertListDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	CUT_CertificateListDlg	*pCertListDlg = NULL;

	// *****************************************************
	// ** Get pointer to the CUT_CertificateListDlg class
	// *****************************************************
	if(message == WM_INITDIALOG)
	{
		// Save parameter as window long
		pCertListDlg = (CUT_CertificateListDlg *) lParam;
		SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)lParam);
		pCertListDlg->m_hDlg = hwndDlg;
		pCertListDlg->m_hCertList = GetDlgItem(hwndDlg, IDC_CERT_LIST);
		pCertListDlg->m_hStoresList = GetDlgItem(hwndDlg, IDC_STORE_TREE);
	}
	else
		pCertListDlg = (CUT_CertificateListDlg *) (ULONG_PTR)GetWindowLong(hwndDlg, GWL_USERDATA);

	// Don't do anything if the pointer to the CUT_CertificateListDlg class is not set
	if(pCertListDlg == NULL)
		return 0;


	// *****************************************************
	// ** Main window messages switch
	// *****************************************************
	switch(message) 
	{
		case WM_INITDIALOG:
			pCertListDlg->OnInit();
			return 1;
		case WM_COMMAND:
			if(wParam == IDCANCEL || wParam == IDOK)
				pCertListDlg->OnClose((int)wParam);
			break;
		case WM_CLOSE:
			pCertListDlg->OnClose(IDCANCEL);
			break;
		case WM_SIZE:
			pCertListDlg->OnSize(LOWORD(lParam), HIWORD(lParam));
			break;
		case WM_MOUSEMOVE :
			pCertListDlg->OnMouseMove((int)wParam, LOWORD(lParam), HIWORD(lParam));
			break;
		case WM_LBUTTONDOWN:
			pCertListDlg->OnLButtonDown((int)wParam, LOWORD(lParam), HIWORD(lParam));
			break;
		case WM_LBUTTONUP:
			pCertListDlg->OnLButtonUp((int)wParam, LOWORD(lParam), HIWORD(lParam));
			break;
		case WM_NOTIFY:
		{
			LPNMHDR pnmh = (LPNMHDR) lParam;
			if(pnmh != NULL)
			{
				if(pnmh->code == TVN_SELCHANGED)
					pCertListDlg->OnTreeSelChange((LPNMTREEVIEW)lParam);
				else if(pnmh->code == LVN_COLUMNCLICK)
					pCertListDlg->OnColumnClick((LPNMLISTVIEW)lParam);
				else if(pnmh->code == NM_RCLICK )
					pCertListDlg->OnRightClick((LPNMLISTVIEW)lParam);
				else if(pnmh->code == NM_DBLCLK)
					pCertListDlg->OnDblClick((LPNMLISTVIEW)lParam);
			}
			break;
		}

	}

	return 0;
}

 
#endif	// #ifdef CUT_SECURE_SOCKET

#pragma warning ( pop )

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
In January 2005, David Cunningham and Chris Maunder created TheUltimateToolbox.com, a new group dedicated to the continued development, support and growth of Dundas Software’s award winning line of MFC, C++ and ActiveX control products.

Ultimate Grid for MFC, Ultimate Toolbox for MFC, and Ultimate TCP/IP have been stalwarts of C++/MFC development for a decade. Thousands of developers have used these products to speed their time to market, improve the quality of their finished products, and enhance the reliability and flexibility of their software.
This is a Organisation

476 members

Comments and Discussions