diff --git a/src/minidriver/Makefile.mak b/src/minidriver/Makefile.mak index 5ce80ef5..da4c66f1 100644 --- a/src/minidriver/Makefile.mak +++ b/src/minidriver/Makefile.mak @@ -14,5 +14,5 @@ $(TARGET): $(OBJECTS) $(LIBS) echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type minidriver.exports >> $*.def - link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib /DELAYLOAD:bcrypt.dll + link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib Comctl32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib /DELAYLOAD:bcrypt.dll if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2 diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index b1508ead..fad646bf 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -30,11 +30,14 @@ #pragma managed(push, off) #endif + #include #include #include #include +#include +#include "cardmod.h" #include "common/compat_strlcpy.h" #include "libopensc/asn1.h" @@ -111,12 +114,7 @@ HINSTANCE g_inst; #endif /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ -#define IDD_PINPAD 101 -#define IDI_LOGO 102 -#define IDC_EXPLANATION_TEXT 1003 -#define IDC_PURPOSE_TEXT 1002 -#define IDC_PINPAD_TEXT 1001 -#define IDC_PINPAD_ICON 1000 +#define IDI_SMARTCARD 102 /* magic to determine previous pinpad authentication */ #define MAGIC_SESSION_PIN "opensc-minidriver" @@ -2304,39 +2302,6 @@ md_query_key_sizes(PCARD_DATA pCardData, DWORD dwKeySpec, CARD_KEY_SIZES *pKeySi return SCARD_S_SUCCESS; } -static VOID CenterWindow(HWND hwndWindow, HWND hwndParent) -{ - RECT rectWindow, rectParent; - int nWidth,nHeight, nScreenWidth, nScreenHeight; - int nX, nY; - GetWindowRect(hwndWindow, &rectWindow); - - nWidth = rectWindow.right - rectWindow.left; - nHeight = rectWindow.bottom - rectWindow.top; - - nScreenWidth = GetSystemMetrics(SM_CXSCREEN); - nScreenHeight = GetSystemMetrics(SM_CYSCREEN); - - // make the window relative to its parent - if (hwndParent != NULL) { - GetWindowRect(hwndParent, &rectParent); - nX = ((rectParent.right - rectParent.left) - nWidth) / 2 + rectParent.left; - nY = ((rectParent.bottom - rectParent.top) - nHeight) / 2 + rectParent.top; - } - else { - nX = (nScreenWidth - nWidth) /2; - nY = (nScreenHeight - nHeight) /2; - } - // make sure that the dialog box never moves outside of the screen - if (nX < 0) nX = 0; - if (nY < 0) nY = 0; - if (nX + nWidth > nScreenWidth) nX = nScreenWidth - nWidth; - if (nY + nHeight > nScreenHeight) nY = nScreenHeight - nHeight; - - MoveWindow(hwndWindow, nX, nY, nWidth, nHeight, TRUE); -} - - static DWORD WINAPI md_dialog_perform_pin_operation_thread(PVOID lpParameter) { @@ -2374,114 +2339,57 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter) return (DWORD) rv; } -static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { - UNREFERENCED_PARAMETER(wParam); - switch (message) - { - case WM_INITDIALOG: - { - LANGID lang = GetUserDefaultUILanguage(); - struct sc_pkcs15_card *p15card = (struct sc_pkcs15_card *) (((LONG_PTR*)lParam)[1]); - DWORD role = (DWORD) (((LONG_PTR*)lParam)[8]); - HICON hIcon = NULL; - PCARD_DATA pCardData = (PCARD_DATA) (((LONG_PTR*)lParam)[7]); - VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; - /* store parameter like pCardData for further use if needed */ - SetWindowLongPtr(hWnd, GWLP_USERDATA, lParam); - /* change the text shown on the screen */ - if (p15card->tokeninfo->preferred_language) { - /* choose the token's preferred language over the system's language */ - if (strncmp(p15card->tokeninfo->preferred_language, "de", 2)) - lang = LANG_GERMAN|SUBLANG_GERMAN; - } - - if (vs->wszPinContext ) { - SetWindowTextW(GetDlgItem(hWnd, IDC_PURPOSE_TEXT), vs->wszPinContext); - } - if (lang & LANG_GERMAN) { - SetWindowText(hWnd, - "PIN-Eingabe notwendig"); - SetWindowText(GetDlgItem(hWnd, IDC_EXPLANATION_TEXT), - "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde oder nach dem PINPAD-Timeout (typischerweise nach 30 Sekunden)."); - SetWindowText(GetDlgItem(hWnd, IDC_EXPLANATION_TEXT), - "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde oder nach dem PINPAD-Timeout (typischerweise nach 30 Sekunden)."); - SetWindowText(GetDlgItem(hWnd, IDCANCEL), - "Abbrechen"); - } - - switch (role) { - case ROLE_ADMIN: - if (lang & LANG_GERMAN) { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."); - } else { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Please enter your PIN to unblock the user PIN on the PINPAD."); - } - break; - case ROLE_USER: - if (lang & LANG_GERMAN) { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Bitte geben Sie Ihre Signatur-PIN auf dem PINPAD ein."); - } else { - SetWindowText(GetDlgItem(hWnd, IDC_PINPAD_TEXT), - "Please enter your digital signature PIN on the PINPAD."); - } - break; - default: - break; - - } - CenterWindow(hWnd, vs->hwndParent); - /* load the information icon */ - hIcon = (HICON) LoadImage(0, IDI_INFORMATION, IMAGE_ICON, 0, 0, LR_SHARED); - SendMessage(GetDlgItem(hWnd, IDC_PINPAD_ICON),STM_SETIMAGE,IMAGE_ICON, (LPARAM) hIcon); - /* change the icon */ - hIcon = LoadIcon(g_inst, MAKEINTRESOURCE(IDI_LOGO)); - if (hIcon) + UNREFERENCED_PARAMETER(lParam); + switch (message) { + case TDN_CREATED: { - SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIcon); - SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); + /* remove the icon from the window title */ + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (LONG_PTR) NULL); + SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_SMALL, (LONG_PTR) NULL); + /* store parameter like pCardData for further use if needed */ + SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData); + /* launch the function in another thread context store the thread handle */ + ((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd; + ((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL); } - /* launch the function in another thread context store the thread handle */ - ((LONG_PTR*)lParam)[10] = (LONG_PTR) hWnd; - ((LONG_PTR*)lParam)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (PVOID) lParam, 0, NULL); - } - return TRUE; - case WM_COMMAND: - { - /* This *must* be IDCANCEL, because we don't have any other command */ - if (LOWORD(wParam) != IDCANCEL) - return FALSE; + case TDN_TIMER: + // progress bar 30 seconds. + SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, wParam / 300 , 0L); + /* continue the tickcount */ + return S_OK; + case TDN_BUTTON_CLICKED: + { + /* We ignore anything else than the Cancel button */ + if (LOWORD(wParam) != IDCANCEL) + return S_FALSE; - /* cancel request */ - LPARAM param = GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (param) { - PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; - VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; - sc_cancel(vs->ctx); - /* Some readers don't support SCardCancel, though they're - * reporting SCARD_S_SUCCESS. We force closing of the dialog so - * that at least the application can continue. */ - if (((LONG_PTR*)param)[10] != 0) { - EndDialog((HWND) ((LONG_PTR*)param)[10], SC_ERROR_KEYPAD_CANCELLED); + LONG_PTR param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (param) { + PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7]; + VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific; + sc_cancel(vs->ctx); } } - } - return TRUE; - case WM_DESTROY: - { - /* clean resources used */ - LPARAM param = GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (param) { - HANDLE hThread = (HANDLE)((LONG_PTR*)param)[9]; - CloseHandle(hThread); + /* Some readers don't support SCardCancel, though they're + * reporting SCARD_S_SUCCESS. We force closing of the dialog so + * that at least the application can continue. */ + return S_OK; + case TDN_DESTROYED: + { + /* clean resources used */ + LONG_PTR param = GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (param) { + HANDLE hThread = (HANDLE)((LONG_PTR*)param)[9]; + CloseHandle(hThread); + } } - } - break; + break; } - return FALSE; + + /* don't close the Task Dialog */ + return S_FALSE; } @@ -2494,8 +2402,12 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p { LONG_PTR parameter[11]; INT_PTR result = 0; + HWND hWndDlg = 0; + TASKDIALOGCONFIG tc = {0}; int rv = 0; VENDOR_SPECIFIC* pv = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific); + LANGID lang = GetUserDefaultUILanguage(); + /* stack the parameters */ parameter[0] = (LONG_PTR)operation; parameter[1] = (LONG_PTR)p15card; @@ -2508,16 +2420,77 @@ md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_p parameter[8] = (LONG_PTR)role; parameter[9] = 0; /* place holder for thread handle */ parameter[10] = 0; /* place holder for window handle */ + /* launch the function to perform in the same thread context */ if (!displayUI) { rv = md_dialog_perform_pin_operation_thread(parameter); SecureZeroMemory(parameter, sizeof(parameter)); return rv; } + /* launch the UI in the same thread context than the parent and the function to perform in another thread context this is the only way to display a modal dialog attached to a parent (hwndParent != 0) */ - result = DialogBoxParam(g_inst, MAKEINTRESOURCE(IDD_PINPAD), pv->hwndParent, md_dialog_proc, (LPARAM) parameter); + tc.hwndParent = pv->hwndParent; + tc.hInstance = g_inst; + tc.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER | TDF_EXPAND_FOOTER_AREA | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_USE_HICON_FOOTER; + tc.dwCommonButtons = TDCBF_CANCEL_BUTTON; + + if (p15card->tokeninfo->preferred_language) { + /* choose the token's preferred language over the system's language */ + if (strncmp(p15card->tokeninfo->preferred_language, "de", 2)) + lang = LANG_GERMAN|SUBLANG_GERMAN; + } + + if (lang & LANG_GERMAN) { + tc.pszWindowTitle = L"Windows-Sicherheit"; + tc.pszMainInstruction = L"OpenSC Smartcard-Anbieter"; + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PINPAD ein."; + break; + } + tc.pszExpandedInformation = L"Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde (Timeout typischerweise nach 30 Sekunden)."; + tc.pszExpandedControlText = L"Weitere Informationen"; + tc.pszCollapsedControlText = L"Weitere Informationen"; + } else { + tc.pszWindowTitle = L"Windows Security"; + tc.pszMainInstruction = L"OpenSC Smart Card Provider"; + switch (role) { + case ROLE_ADMIN: + tc.pszContent = L"Please enter your PIN to unblock the user PIN on the PINPAD."; + break; + case ROLE_USER: + /* fall through */ + default: + tc.pszContent = L"Please enter your digital signature PIN on the PINPAD."; + break; + } + tc.pszExpandedInformation = L"This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds)."; + tc.pszExpandedControlText = L"Click here for more information"; + tc.pszCollapsedControlText = L"Click here for more information"; + } + if (pv->wszPinContext ) { + tc.pszMainInstruction = pv->wszPinContext; + } + + tc.pszMainIcon = MAKEINTRESOURCE(IDI_SMARTCARD); + tc.cButtons = 0; + tc.pButtons = NULL; + tc.cRadioButtons = 0; + tc.pRadioButtons = NULL; + tc.pfCallback = md_dialog_proc; + tc.lpCallbackData = (LONG_PTR)parameter; + tc.cbSize = sizeof(tc); + + result = TaskDialogIndirect(&tc, NULL, NULL, NULL); + SecureZeroMemory(parameter, sizeof(parameter)); + return (int) result; } diff --git a/src/minidriver/opensc-minidriver.dll.manifest b/src/minidriver/opensc-minidriver.dll.manifest new file mode 100644 index 00000000..029b3537 --- /dev/null +++ b/src/minidriver/opensc-minidriver.dll.manifest @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/src/minidriver/versioninfo-minidriver.rc.in b/src/minidriver/versioninfo-minidriver.rc.in index bcb5c789..f99d2b92 100644 --- a/src/minidriver/versioninfo-minidriver.rc.in +++ b/src/minidriver/versioninfo-minidriver.rc.in @@ -2,11 +2,7 @@ #define IDC_STATIC -1 /* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */ -#define IDD_PINPAD 101 -#define IDI_LOGO 102 -#define IDC_PURPOSE_TEXT 1002 -#define IDC_PINPAD_TEXT 1001 -#define IDC_PINPAD_ICON 1000 +#define IDI_SMARTCARD 102 VS_VERSION_INFO VERSIONINFO FILEVERSION @OPENSC_VERSION_MAJOR@,@OPENSC_VERSION_MINOR@,@OPENSC_VERSION_FIX@,@OPENSC_VERSION_REVISION@ @@ -44,20 +40,4 @@ BEGIN END END -IDD_PINPAD DIALOGEX 0, 0, 309, 89 -STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION -CAPTION "PIN Entry Required" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - LTEXT "OpenSC Smart Card Provider",IDC_PURPOSE_TEXT,46,9,256,10 - LTEXT "Please enter your PIN on the PINPAD",IDC_PINPAD_TEXT,46,19,256,19 - ICON "",IDC_PINPAD_ICON,6,11,20,20 - LTEXT "This window will be closed automatically after the PIN has been submitted on the PINPAD or if the PINPAD timeout occurs (in general 30 seconds).",IDC_STATIC,7,46,298,19 - PUSHBUTTON "Cancel",IDCANCEL,250,67,50,14 -END - -#ifndef __MINGW32__ -IDI_LOGO ICON "..\\..\\win32\\OpenSC.ico" -#else -IDI_LOGO ICON "../../win32/OpenSC.ico" -#endif +IDI_SMARTCARD ICON "..\\..\\win32\\DDORes.dll_14_2302.ico" diff --git a/win32/DDORes.dll_14_2302.ico b/win32/DDORes.dll_14_2302.ico new file mode 100644 index 00000000..4b4af230 Binary files /dev/null and b/win32/DDORes.dll_14_2302.ico differ diff --git a/win32/Make.rules.mak b/win32/Make.rules.mak index b8e0adf6..8780dadb 100644 --- a/win32/Make.rules.mak +++ b/win32/Make.rules.mak @@ -125,14 +125,14 @@ ALL_INCLUDES = /I$(TOPDIR)\win32 /I$(TOPDIR)\src $(OPENPACE_INCL_DIR) $(OPENSSL_ !IF "$(DEBUG_DEF)" == "/DDEBUG" LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMT /DEBUG CODE_OPTIMIZATION = -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0502 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MTd /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" /DDEBUG /Zi /Od !ELSE LINKDEBUGFLAGS = /NODEFAULTLIB:LIBCMTD -COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0502 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" +COPTS = /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT /nologo /DHAVE_CONFIG_H $(ALL_INCLUDES) /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN $(OPENPACE_DEF) $(OPENSSL_DEF) $(ZLIB_DEF) $(MINIDRIVER_DEF) $(SM_DEF) /DOPENSC_FEATURES="\"$(OPENSC_FEATURES)\"" !ENDIF -LINKFLAGS = /NOLOGO /INCREMENTAL:NO /MACHINE:$(PLATFORM) /MANIFEST:NO /NODEFAULTLIB:MSVCRTD /NODEFAULTLIB:MSVCRT /NXCOMPAT /DYNAMICBASE $(LINKDEBUGFLAGS) +LINKFLAGS = /NOLOGO /INCREMENTAL:NO /MACHINE:$(PLATFORM) /NODEFAULTLIB:MSVCRTD /NODEFAULTLIB:MSVCRT /NXCOMPAT /DYNAMICBASE $(LINKDEBUGFLAGS) LIBFLAGS = /nologo /machine:$(PLATFORM) !IF "$(PLATFORM)" == "x86" CANDLEFLAGS = -dPlatform=x86 $(CANDLEFLAGS) @@ -150,4 +150,4 @@ CANDLEFLAGS = -dPlatform=x64 $(CANDLEFLAGS) rc /l 0x0409 $< clean:: - del /Q *.obj *.dll *.exe *.pdb *.lib *.def *.manifest *.res + del /Q *.obj *.dll *.exe *.pdb *.lib *.def *.res