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)&CertHookCa llback;
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?
I have set the pfnHook pointer with
certSelect.pfnHook = (PFNCMHOOKPROC)&CertHookCa
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);
}
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;
}
What is the return value in
DWORD rc = pCertSelectCertificate(&ce rtSelect);
?
DWORD rc = pCertSelectCertificate(&ce
?
ASKER
It returns 0, and GetLastError returns 0 as well.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
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?
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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;
}
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
Open in new window