none
Smartcard Minidriver external Pin submitted handle not a valid HWND RRS feed

  • Question

  • Good morning,

    we have a problem with our smartcard minidriver. 

    The call of CardSetProperty with parameter CP_PARENT_WINDOW does not point to a valid HWND.
    This has worked in the past, we check the parameter for valid HWND and we try "GetWindowInfo" to extract title information.
    We double checked our code of CardSetProperty for CP_PARENT_WINDOW with the openSC minidriver implementation and they do it exactly the same way.

    What's wrong there? Minidriver specs V7.07 only talk of YYYYY being a HWND, but the submitted values are definitely not valid handles or current window handles.

    Hardware lab kit tests (cmck) fail and we have passed that test in the past without problems (previous driver version is Microsoft Certified)

    We tried on Windows 7 32bit, Windows 10 32Bit and Windows 10 64Bit, all platforms have the same issue.

    Kind regards

    Tuesday, September 27, 2016 6:41 AM

All replies

  • What values are you seeing for the HWND being provided? Are you using IsWindow() to verify the HWND and it is failing?

    I notice you said this occurs on Windows 7, which has been out for quite some time at this point and we haven't heard reports of this up until now. So, I'd like to really understand what your minidriver does here to figure out the issue.

    Thanks.


    Jeff Shipman [MSFT] -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, September 27, 2016 5:58 PM
  • Hi Jeff,

    i tried IsWindow() to check, too.
    Yes, i checked on Windows 7 to make sure, the problem is not only related to Windows 10
    And i checked 32 and 64Bit

    I'll post some code and more information when i get back to the office tomorrow morning

    What i can say is, that this does not work (from openSC minidriver):

    if (wcscmp(CP_PARENT_WINDOW, wszProperty) == 0) {
    		if (cbDataLen != sizeof(HWND) || !pbData)   {
    			return SCARD_E_INVALID_PARAMETER;
    		}
    		else   {
    			HWND cp = *((HWND *) pbData);
    			if (cp!=0 && !IsWindow(cp))
    				return SCARD_E_INVALID_PARAMETER;
    			vs->hwndParent = cp;
    		}
    		logprintf(pCardData, 3, "Saved parent window (%p)\n", vs->hwndParent);
    		return SCARD_S_SUCCESS;
    	}
    https://github.com/OpenSC/OpenSC/blob/master/src/minidriver/minidriver.c


    Tuesday, September 27, 2016 6:41 PM
  • Hi Jeff and everybody else,

    an example value for HWND from our logging (on Windows 10 64Bit):

    MiniDriverProperty.cpp:618 CardSetProperty()
    MiniDriverProperty.cpp:627 cbDataLen: 8
    MiniDriverProperty.cpp:635 wszProperty: 50006100720065006E00740020
    MiniDriverProperty.cpp:682 submitted: 98ffcda8
    MiniDriverProperty.cpp:689 Value of HWND 0
    MiniDriverProperty.cpp:703 IsWindow: false
    MiniDriverProperty.cpp:711 CardSetProperty(): No window handle !!
    MiniDriverProperty.cpp:913 Result: 80100004: Mindestens einer der angegebenen Parameter konnte nicht richtig interpretiert werden.

    The "98ffcda8" is what is provided by the CSP (pbData), 0 is "*pbData". Both are not valid window handle

    		if (wcscmp(wszProperty, CP_PARENT_WINDOW) == 0) {
    
    			if (cbDataLen != sizeof(HWND) || !pbData) {
    				LogIt(E_LOGTYPE_ERR, "CardSetProperty()", "cbDataLen invalid !");
    				dwRet = SCARD_E_INVALID_PARAMETER;
    				goto L_End;
    			}
    
    			LogIt(E_LOGTYPE_DBG, "submitted", LogHWNDToString((HWND)pbData));
    
    			HWND cp = (HWND)*pbData;
    			
    			LogIt(E_LOGTYPE_DBG, "Value of HWND", LogHWNDToString(cp));
    
    			if (dwFlags != 0) {
    				LogIt(E_LOGTYPE_ERR, "CardSetProperty()", "dwFlags invalid !");
    				dwRet = SCARD_E_INVALID_PARAMETER;
    				goto L_End;
    			}
    
    			if (IsWindowUnicode(cp) || IsWindow(cp))
    			{
    				LogIt(E_LOGTYPE_DBG, "IsWindow", "true");
    			}
    			else
    			{
    				LogIt(E_LOGTYPE_DBG, "IsWindow", "false");
    			}
    
    			WINDOWINFO pwi;
    			if (GetWindowInfo(cp, &pwi) == 0) {
    				LogIt(E_LOGTYPE_DBG, "CardSetProperty()", "No window handle !!");
    
    				dwRet = SCARD_E_INVALID_PARAMETER;
    				goto L_End;
    			}
    I'll try Windows 7 again and if i get a different result i'll let you know

    Wednesday, September 28, 2016 6:24 AM
  • The Windows 7 32Bit output:
    minidriverproperty.cpp:618 CardSetProperty()
    minidriverproperty.cpp:627 cbDataLen: 4
    minidriverproperty.cpp:635 wszProperty: 50006100720065006E00740020
    minidriverproperty.cpp:682 submitted: 2ae058
    minidriverproperty.cpp:686 Value of HWND: 0
    minidriverproperty.cpp:700 IsWindow: false
    minidriverproperty.cpp:705 CardSetProperty(): No window handle !!
    minidriverproperty.cpp:907 Result: 80100004: Mindestens einer der angegebenen Parameter konnte nicht richtig interpretiert werden.

    Wednesday, September 28, 2016 9:07 AM
  • Thanks for the detailed info. Do you know which component is setting this property on the minidriver? Is it coming from Logon UI or some other scenario? Also, I want to confirm you are also seeing this issue when CMCK is performing a test on the minidriver? Could you tell me the specific test?

    Jeff Shipman [MSFT] -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, September 28, 2016 5:52 PM
  • I use a self written .NET tool, that uses the CSP to sign a file, so no logon scenario.

    But the

    cmck exec CardSetProperty 

    is what's causing the trouble. It wasn't a problem last time we certified the driver, but a lot has changed in HCK /HLK. I don't even know, if that was actually part of the test back in 2013

    Wednesday, September 28, 2016 6:33 PM
  • Hi Jeff,

    i figured the cmck problem out, so the CardSetProperty is passing now.
    I changed some return values (SCARD_E_INVALID_PARAMETER to SCARD_E_UNSUPPORTED_FEATURE). I had to guess at some places which of the above was expected to be returned. The code looks like this now

    if (wcscmp(wszProperty, CP_PARENT_WINDOW) == 0) {
    			
    			if (cbDataLen != sizeof(HWND) || !pbData) {
    				LogIt(E_LOGTYPE_ERR, "CardSetProperty()", "cbDataLen invalid !");
    				dwRet = SCARD_E_INVALID_PARAMETER;
    				goto L_End;
    			}
    			if (dwFlags != 0) {
    				LogIt(E_LOGTYPE_ERR, "CardSetProperty()", "dwFlags invalid !");
    				dwRet = SCARD_E_INVALID_PARAMETER;
    				goto L_End;
    			}
    
    			CSmartCardTerminal*    pcTerminal = NULL;
    			CSmartCard*            pcCard = NULL;
    			CSmartCardFS*          pcCardFS = NULL;
    			TCMDContext*           psCtx = NULL;
    
    			if ((dwRet = GetTheCard(pCardData, &psCtx, &pcTerminal, &pcCard, &pcCardFS)) == SCARD_S_SUCCESS) {
    				if (!pcCard->supportsPinPad() || (pcCard->supportsPinPad() && !pcCardFS->getUsePinPad()))
    				{
    					LogIt(E_LOGTYPE_ERR, "CardSetProperty()", "PinPad Support is off!");
    
    					dwRet = SCARD_E_UNSUPPORTED_FEATURE;
    					goto L_End;
    				}
    			}
    
    			LogIt(E_LOGTYPE_DBG, "submitted", LogHWNDToString((HWND)pbData));
    
    			HWND cp = *((HWND *)pbData);
    			if (cp == 0) {
    				LogIt(E_LOGTYPE_ERR, "CardSetProperty()", "pbData HWND 0!");
    				dwRet = SCARD_E_UNSUPPORTED_FEATURE;
    				goto L_End;
    			}
    
    			LogIt(E_LOGTYPE_DBG, "Value of HWND", LogHWNDToString(cp));
    
    			if (IsWindowUnicode(cp) || IsWindow(cp))
    			{
    				LogIt(E_LOGTYPE_DBG, "IsWindow", "true");
    			}
    			else
    			{
    				LogIt(E_LOGTYPE_DBG, "CardSetProperty()", "No window handle !!");
    
    				dwRet = SCARD_E_UNSUPPORTED_FEATURE;
    				goto L_End;
    			}
    
    			WINDOWINFO pwi;
    			if (GetWindowInfo(cp, &pwi) == 0) {
    				LogIt(E_LOGTYPE_DBG, "CardSetProperty()", "No window handle !!");
    
    				dwRet = SCARD_E_INVALID_PARAMETER;
    				goto L_End;
    			}
    			LogIt(E_LOGTYPE_DBG, "Window Status:", LogIntToString(pwi.dwWindowStatus));

    But i still have the problem of invalid HWND with my application. It's of course now return "UNEXPECTED FEATURE", because the "cp==0"

    I tried with a small c++ console app and that works fine

    PFN_CARD_ACQUIRE_CONTEXT pAcquire = NULL;
    HMODULE hDll = LoadLibrary("C:\\SmartcardMinidrivertest\\tcos3cmd.dll");
    if (hDll == NULL) {
    	printf("Fehler beim Laden der Bibliothek");
    	exit(0);
    }
    
    pAcquire = (PFN_CARD_ACQUIRE_CONTEXT) GetProcAddress(hDll, "CardAcquireContext");
    if (hDll == NULL) {
    	printf("Fehler holen der Funktionsadresse");
    	exit(0);
    }
    if ((dwRet = pAcquire(p, dwFlags)) != SCARD_S_SUCCESS) {
    	printf("Fehler bei CardAcquireContext: 0x%.8X", dwRet);
    	exit(0);
    }
    HWND cp = GetDesktopWindow();
    PBYTE pbData = 	(PBYTE)myAlloc(sizeof(HWND));
    memcpy(pbData, &cp, sizeof(HWND));
    if ((dwRet = p->pfnCardSetProperty(p, CP_PARENT_WINDOW, pbData, sizeof(HWND), 0)) != SCARD_S_SUCCESS)
    {
    	printf("Fehler bei CardSetProperty: 0x%.8X", dwRet);
    	goto exit;
    }
    PDWORD remaining = 0;
    if ((dwRet = p->pfnCardAuthenticateEx(p, 0x01, 0, NULL, 0, NULL, 0, remaining) != SCARD_S_SUCCESS))
    {
    	printf("Fehler bei pfnCardAuthenticateEx: 0x%.8X", dwRet);
    	goto exit;
    }
    printf("OK!!");
     

    Now i'm completely puzzled...
    Or is there something special about the desktop window? The cmck is using only that, too. And my .NET app is not.

    Really hoping to get this straight

    Till

    Friday, September 30, 2016 10:40 AM
  • And if i set the cp to GetDesktopWindow() in case of pbData being 0, the cmck test runs without failure and i get a nice little box that asks me to enter my pin on the pinpad.
    But i'd rather have my apps window as parent than the desktop...


    Friday, September 30, 2016 11:04 AM
  • Just to wrap this topic up, i figured out, what the problem was/is:

    SignedCms signedMessage;
    signedMessage = new SignedCms(new ContentInfo(bInput), !CreateP7M);
    signedMessage.ComputeSignature(tmpSigner, false);
    return signedMessage.Encode();

    That is what i use to calculate the signature. So that API does not allow to specify the handle for the parent window.
    I found the CSPParameters class, that allows parsing the handle, but i did not manage to get a valid signature with that, yet.

    But we simply disabled the pinpad-support for the certification and everything works fine

    Wednesday, November 16, 2016 9:11 AM