Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCardGetStatusChange for PNP notification return SCARD_E_TIMEOUT #76

Open
totti0858 opened this issue Apr 7, 2023 · 10 comments
Open

SCardGetStatusChange for PNP notification return SCARD_E_TIMEOUT #76

totti0858 opened this issue Apr 7, 2023 · 10 comments
Assignees

Comments

@totti0858
Copy link

totti0858 commented Apr 7, 2023

For the latest pcsc_scan.c file, I add code at 528 line to check the SCardGetStatusChange return value for the PNP notification, but unfortunately the return value is SCARD_E_TIMEOUT but not SCARD_S_SUCCESS. (my local pcsc-lite version is 1.8.23 and ubuntu Linux)

_rgReaderStates[0].szReader = "\\?PnP?\Notification";
rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;

rv = SCardGetStatusChange(hContext, 0, rgReaderStates, 1);
printf("SCardGetStatusChange for PNP notification result = %lu\n", rv)_

I think it should be SCARD_S_SUCCESS but not this SCARD_E_TIMEOUT value. Do you know why and do you have the plan to fix this issue?

@totti0858
Copy link
Author

I also compiled the same project under the Windows platform and found that the SCardGetStatusChange for PNP notification returns the right value SCARD_S_SUCCESS as expected after run it under Windows platform.

This difference under different platforms may cause issue under VDI user scenario.

@LudovicRousseau
Copy link
Owner

I can't reproduce your behavior on Windows.
I used this Python program:

#! /usr/bin/env python3

#   SCardGetStatusChange.py : Unitary test for SCardGetStatusChange()
#   Copyright (C) 2023  Ludovic Rousseau
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, see <http://www.gnu.org/licenses/>.

from smartcard.scard import *
from smartcard.pcsc.PCSCExceptions import *


hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
if hresult != SCARD_S_SUCCESS:
    raise EstablishContextException(hresult)

reader="\\\\?PnP?\\Notification"
readerstates = {}
readerstates[reader] = (reader, SCARD_STATE_UNAWARE)
hresult, newstates = SCardGetStatusChange(hcontext, 0,
        list(readerstates.values()))
if hresult != SCARD_S_SUCCESS:
    raise BaseSCardException(hresult)

hresult = SCardReleaseContext(hcontext)
print("SCardReleaseContext()", SCardGetErrorMessage(hresult))
if hresult != SCARD_S_SUCCESS:
    raise ReleaseContextException(hresult)

And on Windows I get:

(base) C:\Users\Ludovic\Downloads>python SCardGetStatusChange.py
Traceback (most recent call last):
  File "C:\Users\Ludovic\Downloads\SCardGetStatusChange.py", line 33, in <module>
    raise BaseSCardException(hresult)
smartcard.pcsc.PCSCExceptions.BaseSCardException: scard exception: Le délai d’attente spécifié par l’utilisateur a expiré.  (0x8010000A)

I receive 0x8010000A (SCARD_E_TIMEOUT) and not 0 (SCARD_S_SUCCESS).

In your program I note you use _rgReaderStates[0] and also rgReaderStates[0] (without the _).
Maybe the problem is a bug in your code.

@LudovicRousseau LudovicRousseau self-assigned this Apr 7, 2023
@totti0858
Copy link
Author

Just as the way you mentioned how to compile the pcsc_scan.exe for Windows (https://ludovicrousseau.blogspot.com/2017/05/pcscscan-on-windows.html), I had compile it and put the exe into the attachment file.

Please see the attached screen, you can see the log screen shot:
Screen Shot 2023-04-10 at 10 37 22 AM
git-modify.zip
you can use the compiled pcsc_scan exe to verify the result.

Why the SCardGetStatusChange has the different result under Linux and Windows platform?

@LudovicRousseau
Copy link
Owner

Do not send me binary program. Send me the patch you used instead.

On my side I tried with this patch:

--- pcsc_scan.c	2023-02-11 12:33:09.000000000 +0100
+++ pcsc_scan.c	2023-04-10 11:09:24.000000000 +0200
@@ -525,6 +527,7 @@
 	rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
 
 	rv = SCardGetStatusChange(hContext, 0, rgReaderStates, 1);
+	printf("rv: %lx\n", rv);
 	if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN)
 	{
 		if (Options.verbose)

And I confirm the returned value is SCARD_E_TIMEOUT on my Winows 10.
I get:

$ ./pcsc_scan.exe
PC/SC device scanner
V 1.6.2 (c) 2001-2022, Ludovic Rousseau <ludovic.rousseau@free.fr>
Press shift key to quit
rv: 8010000a
Using reader plug'n play mechanism

@totti0858
Copy link
Author

It is true that I modify the code as your patch do:
adding printf("SCardGetStatusChange for PNP notification result = %lu\n", rv) at line 528.

But when I run the pcsc_scan.exe on my desktop win10 and win11, the result always zero.

would you like to try the binary I provided on your desktop?

@LudovicRousseau
Copy link
Owner

Send me your source code instead.
A binary program is useless for me since I do not know what code is really executed.

@totti0858
Copy link
Author

totti0858 commented Apr 12, 2023

/home/test/pcsc-tools-master
$ diff pcsc_scan.c pcsc_scan.backout
528d527
< printf("SCardGetStatusChange for PNP notification result = %lx\n", rv);

I also attach the zip file that include the modified .c file compiled exe. Please have a try on your windows.
git.zip

for sure when execute the pcsc_scan.exe app, I had attached the physical smart card reader& card to the Windows machine.

@LudovicRousseau
Copy link
Owner

I see the problem.
With your program and no smart card reader connected I get:

C:\Users\Ludovic\Documents\git\git>pcsc_scan.exe
PC/SC device scanner
V 1.6.2 (c) 2001-2022, Ludovic Rousseau <ludovic.rousseau@free.fr>
Press shift key to quit
SCardGetStatusChange for PNP notification result = 8010000a
Using reader plug'n play mechanism
Scanning present readers...

I get the expected SCARD_E_TIMEOUT.

But if I connect a reader before running pcsc_scan.exe I get:

C:\Users\Ludovic\Documents\git\git>pcsc_scan.exe
PC/SC device scanner
V 1.6.2 (c) 2001-2022, Ludovic Rousseau <ludovic.rousseau@free.fr>
Press shift key to quit
SCardGetStatusChange for PNP notification result = 0
Using reader plug'n play mechanism
Scanning present readers...
0: Gemplus USB SmartCard Reader 0

Wed Apr 12 14:59:31 2023
 Reader 0: Gemplus USB SmartCard Reader 0
  Event number: 1
  Card state: Card inserted,
  ATR: 3B A7 00 40 18 80 65 A2 08 01 01 52
 Reader 1: \\?PnP?\Notification
  Event number: 1
  Card state:

I get the surprising SCARD_S_SUCCESS.

This is surprising because in the two cases only the special reader \\?PnP?\Notification is used in SCardGetStatusChange(). So the other reader should not have any impact.
I consider this a Windows bug, unless this behaviour is documented somewhere.

What do you think?

@totti0858
Copy link
Author

Yes, typical user scenario is that the physical smart card reader are attached before the pcsc_scan.exe executed. I think this is the expected result that return SCARD_S_SUCCESS at this scenario under Windows platform.

Here I want to say the Under Linux platform the pcsc_scan return SCARD_E_TIMEOUT is a bad case. how can we fix this issue?

@LudovicRousseau
Copy link
Owner

For me it is a bug on Windows.
If you think different then please provide technical arguments corresponding to the function documentation.

Why is it important for you to change the behavior of SCardGetStatusChange()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants