Link to home
Start Free TrialLog in
Avatar of endasil
endasil

asked on

CertSelectCertificate hook Callback Function does not get called

I am trying to use a callback function in order to center the certificate window, but it can't seem to get it to work.

I have set the pfnHook pointer with
certSelect.pfnHook = (PFNCMHOOKPROC)&CertHookCallback;

I have  set the flag saying that a hook function should be called using:      
certSelect.dwFlags = CSS_ENABLEHOOK;

The selectCert dialog is displayed but it does not hit my breakpoint in the callback function nor does it print, so i assume it is never reached. What have i missed?
static UINT_PTR CALLBACK CertHookCallback( 
	HWND hDlg,
	UINT uiMsg,
	WPARAM wParam,
	LPARAM lParam)
{
          Trace(TRC_LOGIC, ("Callback function reached.\n"));
	if ( uiMsg == WM_SIZE) {

            // Center window and bring it to front
            Center(hdlg); 

         }
}

GetCert()
{
CERT_SELECT_STRUCT certSelect;
	PCCERT_CONTEXT pSelCert = NULL;
	// set cert dialog data and call function

	memset(&certSelect, 0, sizeof(CERT_SELECT_STRUCT));

	DLGTEMPLATE dlgTemplate;

	dlgTemplate.x = 0;
	dlgTemplate.y = 0;
	//certSelect.pTemplateName =&dlgTemplate;

	certSelect.dwFlags = CSS_ENABLEHOOK;
	certSelect.dwSize = sizeof(CERT_SELECT_STRUCT);
	certSelect.hwndParent = GetForegroundWindow();
	certSelect.pfnHook = (PFNCMHOOKPROC)&CertHookCallback;
	certSelect.cCertStore = 1;  
	certSelect.arrayCertStore = &hTmpStore;
	certSelect.cCertContext = 1;  
	certSelect.arrayCertContext = &pSelCert;


	DWORD rc = pCertSelectCertificate(&certSelect);


}

Open in new window

Avatar of jkr
jkr
Flag of Germany image

Stupid question - does that work with

certSelect.pfnHook = (PFNCMHOOKPROC) CertHookCallback;

instead? Also, according to the docs (http://msdn.microsoft.com/en-us/library/aa387047%28VS.85%29.aspx - "PFNCMHOOKPROC Callback Function"), the callback should be more like
UINT WINAPI CertHookCallback( 
        HWND hDlg,
        UINT uiMsg,
        WPARAM wParam,
        LPARAM lParam)
{
          Trace(TRC_LOGIC, ("Callback function reached.\n"));
        if ( uiMsg == WM_SIZE) {

            // Center window and bring it to front
            Center(hdlg); 

         }

  return 0;
}

Open in new window

Avatar of endasil
endasil

ASKER

I tried making the changes you suggested but it still does not get called. Here is a small program that only contains whats needed to run the dialog example with your suggestions included.
#include <windows.h>
#include <wincrypt.h>
#include <stdlib.h>
#include "C:\Program\Microsoft SDKs\Windows\v6.0A\include\cryptdlg.h"


UINT WINAPI CertHookCallback(HWND hDlg,
							 UINT uiMsg,
							 WPARAM wParam,
							 LPARAM lParam)
{	
	if ( uiMsg == WM_SIZE) { 
		exit(0);
	}
	return NULL;
}

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd)
{
	HMODULE hLib = LoadLibrary(L"cryptdlg.dll");;	
	HCERTSTORE hTmpStore = CertOpenStore(CERT_STORE_PROV_MEMORY, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0, NULL);	
	BOOL (WINAPI *pCertSelectCertificate)(PCERT_SELECT_STRUCT) = NULL;		
	pCertSelectCertificate = (BOOL (WINAPI *)(PCERT_SELECT_STRUCT))GetProcAddress(hLib, "CertSelectCertificateW");	
	
	CERT_SELECT_STRUCT certSelect;
	PCCERT_CONTEXT pSelCert = NULL;
	
	memset(&certSelect, 0, sizeof(CERT_SELECT_STRUCT));
	certSelect.dwFlags = CSS_ENABLEHOOK;
	certSelect.dwSize = sizeof(CERT_SELECT_STRUCT);
	certSelect.hwndParent = GetForegroundWindow();
	certSelect.pfnHook = (PFNCMHOOKPROC)CertHookCallback;
	certSelect.cCertStore = 1;  
	certSelect.arrayCertStore = &hTmpStore;
	certSelect.cCertContext = 1;  
	certSelect.arrayCertContext = &pSelCert;
	DWORD rc = pCertSelectCertificate(&certSelect);

	return 0;
}

Open in new window

What is the return value in

DWORD rc = pCertSelectCertificate(&certSelect);

?
Avatar of endasil

ASKER

It returns 0, and GetLastError returns 0 as well.
ASKER CERTIFIED SOLUTION
Avatar of DanRollins
DanRollins
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of endasil

ASKER

Thank you for your reply and taking your time to try to help me out here. Much appriciated. I have now tested my code on windows xp, visa as well as 7, all of them 32bit OS, but i have the same problem on all of them. So i guess it is not related to be related to 64bit.

I guess whats left is your spin-off thread idea. I had no idea you could find the hwnd of a dialog that exist on the screen, how would i go about to archive that?
Avatar of endasil

ASKER

The only function that i have found that can do something like this is FindWindow, that lets you find a window by the title. But this does not seem to be a reliable idea if the application is going to be used in multiple languages.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of endasil

ASKER

Thanks, got it working with the thread method. Complete source for anyone else who runs into this problem:


#include <afxwin.h>
#include <windows.h>
#include <wincrypt.h> 
#include <stdlib.h> 
#include <vector>
#include "C:\Program\Microsoft SDKs\Windows\v6.0A\include\cryptdlg.h" 
#define DIALOG_CLASS _T("#32770")

UINT WINAPI CertHookCallback(HWND hDlg, 
							 UINT uiMsg, 
							 WPARAM wParam, 
							 LPARAM lParam) 
{        
	exit(0);
	if ( uiMsg == WM_SIZE) {  
		exit(0); 
	} 
	return NULL; 
} 

bool g_run = true;


DWORD threadDlg = 0;
DWORD idapp = 0;
DWORD currThread = 0;
bool dialogFound = 0;

void CenterWindow(HWND hwnd)
{
	RECT    rect;
	LONG    dx, dy;
	LONG    dxParent, dyParent;
	LONG    Style;

	// Get window rect
	GetWindowRect(hwnd, &rect);

	dx = rect.right - rect.left;
	dy = rect.bottom - rect.top;

	// Get parent rect
	Style = GetWindowLong(hwnd, GWL_STYLE);
	if ((Style & WS_CHILD) == 0) {

		// Return the desktop windows size (size of main screen)
		dxParent = GetSystemMetrics(SM_CXSCREEN);
		dyParent = GetSystemMetrics(SM_CYSCREEN);
	} else {
		HWND    hwndParent;
		RECT    rectParent;

		hwndParent = GetParent(hwnd);
		if (hwndParent == NULL) {
			hwndParent = GetDesktopWindow();
		}

		GetWindowRect(hwndParent, &rectParent);

		dxParent = rectParent.right - rectParent.left;
		dyParent = rectParent.bottom - rectParent.top;
	}

	// Centre the child in the parent
	rect.left = (dxParent - dx) / 2;
	rect.top  = (dyParent - dy) / 3;

	// Move the child into position
	SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, 0, 0, SWP_NOSIZE);

}

BOOL CALLBACK FindDialog(HWND hwnd, LPARAM lparam)
{
	TCHAR name[MAX_PATH];
	ZeroMemory(name, sizeof(name));

	GetClassName(hwnd, name, MAX_PATH);

	// See if this is a dialog window
	if(_tcscmp(name, DIALOG_CLASS) == 0){						
		
		// Check if this app is the creator of the window.
		DWORD idOfCreator = 0;
		GetWindowThreadProcessId(hwnd,&idOfCreator);
		if(idOfCreator == lparam)
		{
			CenterWindow(hwnd);
			g_run = false;		
		}
	}
	// Return value is used by EnumWindows to know when to stop.	
	return g_run;

}


UINT MonitorCertWindow(LPVOID pParam)
{
	// Enumerate windows until the select certificate window is found	
	while(g_run == true)
	{
		EnumWindows(FindDialog, GetCurrentProcessId());
	}

	return 0;
}

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd) 
{ 
	

	HMODULE hLib = LoadLibrary(L"cryptdlg.dll");;    
	HCERTSTORE hTmpStore = CertOpenStore(CERT_STORE_PROV_MEMORY, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0, NULL);       
	BOOL (WINAPI *pCertSelectCertificate)(PCERT_SELECT_STRUCT) = NULL;               
	pCertSelectCertificate = (BOOL (WINAPI *)(PCERT_SELECT_STRUCT))GetProcAddress(hLib, "CertSelectCertificateW");   

	CERT_SELECT_STRUCT certSelect; 
	PCCERT_CONTEXT pSelCert = NULL; 
	
	AfxBeginThread(MonitorCertWindow, 0);
	memset(&certSelect, 0, sizeof(CERT_SELECT_STRUCT)); 
	certSelect.dwFlags = CSS_ENABLEHOOK; 
	certSelect.dwSize = sizeof(CERT_SELECT_STRUCT); 
	certSelect.hwndParent = GetForegroundWindow(); 
	certSelect.pfnHook = (PFNCMHOOKPROC)&CertHookCallback; 
	certSelect.cCertStore = 1;   
	certSelect.arrayCertStore = &hTmpStore; 
	certSelect.cCertContext = 1;   
	certSelect.arrayCertContext = &pSelCert; 
	

	DWORD rc = pCertSelectCertificate(&certSelect); 
	
	return 0; 
}

Open in new window