Closed iomode closed 8 years ago
PySCard does support Escape commands. What is the value of hresult?
print hex(hresult)
0x1L
I have no idea what could be wrong. Can you debug on your side? You could start by tracing the PC/SC calls done by your C application and your Python application. Maybe using ScardSpy https://www.idrix.fr/Root/content/category/7/25/48/
This are my results: python script:
2016-02-25 10:43:13.883 (Thread = 0x00000470) - SCardConnectA( hContext = 0xCD010000, szReader = "MYREADER 0", dwShareMode = 0x00000003, dwPreferredProtocols = 0x00000000 ):
2016-02-25 10:43:13.883 (Thread = 0x00000470) - SCardConnectA Handle = 0xEA010000
2016-02-25 10:43:13.883 (Thread = 0x00000470) - SCardControl( hCard = 0xEA010000 on reader "MYREADER 0", dwControlCode = 0x003136B0, lpOutBuffer = 0x02782F80, nOutBufferSize = 65548, lpBytesReturned = 0x005BF5D0 ):
Input command =
A0 BE
2016-02-25 10:43:13.884 (Thread = 0x00000470) - SCardControl Failed. Error 0x00000001
Duration = 1 ms
c++ programm (compiled with visual studio 2013):
2016-02-25 10:43:09.736 (Thread = 0x00000188) - SCardConnectA( hContext = 0xCD010000, szReader = "MYREADER 0", dwShareMode = 0x00000003, dwPreferredProtocols = 0x00000000 ):
2016-02-25 10:43:09.736 (Thread = 0x00000188) - SCardConnectW Returned Handle = 0xEA010000
2016-02-25 10:43:09.737 (Thread = 0x00000188) - SCardControl( hCard = 0xEA010000 on reader "MYREADER 0", dwControlCode = 0x003136B0, lpOutBuffer = 0x0034F9F8, nOutBufferSize = 256, lpBytesReturned = 0x0034F9EC ):
Input command =
A0 BE
2016-02-25 10:43:09.739 (Thread = 0x00000188) - SCardControl Response =
90 00
Duration = 2 ms
2016-02-25 10:43:09.739 (Thread = 0x00000188) - SCardDisconnect( hCard = 0xEA010000 on reader "MYREADER 0", dwDisposition = 0x00000000):
2016-02-25 10:43:09.739 (Thread = 0x00000188) - SCardDisconnect Success
My C++ programm:
#include "stdafx.h"
#include <windows.h>
#include <winscard.h>
#include <iostream>
#include <WinBase.h>
#include <string>
#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(3500)
using namespace std;
int main(int argc, char * argv[])
{
const BYTE ESCAPE_COMMAND_TEST[] = { 0xA0, 0xBE };
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
DWORD dwProtocol;
BYTE abResponse[256];
DWORD dwRespLen = NULL;
LONG rc = 0;
LPTSTR pmszReaders = NULL;
LPTSTR pReader;
LPTSTR pfirstReader = NULL;
LONG lReturn, lReturn2;
DWORD cch = SCARD_AUTOALLOCATE;
/* Instanciate the winscard.dll library */
rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
if (rc != SCARD_S_SUCCESS) {
cout << "Could not get context! (SCardEstablishContext)" << endl;
return -1;
}
// Retrieve the list the readers.
lReturn = SCardListReaders(hContext,
SCARD_DEFAULT_READERS,
(LPTSTR)&pmszReaders,
&cch);
switch (lReturn)
{
case SCARD_E_NO_READERS_AVAILABLE:
cout << "No readers connected! (SCARD_E_NO_READERS_AVAILABLE)" << endl;
return -2;
break;
case SCARD_S_SUCCESS:
{
// Do something with the multi string of readers.
// Output the values.
// A double-null terminates the list of values.
pReader = pmszReaders;
while ('\0' != *pReader)
{
// Display the value.
printf("Reader found: '%S'\n", pReader);
if (pfirstReader == NULL)
pfirstReader = pReader;
// Advance to the next value.
pReader = pReader + wcslen((wchar_t *)pReader) + 1;
}
rc = SCardConnect(hContext, pfirstReader, SCARD_SHARE_DIRECT, 0, &hCard, &dwProtocol);
if (rc != SCARD_S_SUCCESS) {
cout << "Could not connect to reader! (SCardConnect)" << endl;
return -3;
}
std::cout << "Successfully connected to reader!" << std::endl;
rc = SCardControl(hCard, IOCTL_CCID_ESCAPE, ESCAPE_COMMAND_TEST, sizeof(ESCAPE_COMMAND_TEST), abResponse, sizeof(abResponse), &dwRespLen);
if (rc != SCARD_S_SUCCESS) {
cout << "Control command sending failed (SCardControl)!" << endl;
exit(-4);
}
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
// Free the memory.
lReturn2 = SCardFreeMemory(hContext,
pfirstReader);
if (SCARD_S_SUCCESS != lReturn2)
printf("Failed SCardFreeMemory\n");
SCardReleaseContext(hContext);
std::cout << "Reader successfully disconnected." << std::endl;
}
break;
default:
printf("Failed SCardListReaders\n");
return -3;
break;
}
return 0;
}
Thanks. One difference is the size of the pbRecvBuffer
buffer.
Can you change your C++ code and use:
BYTE abResponse[65548];
What is the ScardSpy result?
I think we found the problem. abResponse[65548] fails the same way as python. abResponse[65544] is the biggest working size. Maybe this should better not exceed 2^16 (65536)?
Argh! Stupid Windows.
Can you try to rebuild pyscard with the following patch:
**--- /var/folders/5h/3d1x67_x5g30t36wypgxpmpc0000gn/T//pXYc2b_scard.i 2016-02-25 14:10:13.000000000 +0100
+++ smartcard/scard/scard.i 2016-02-25 14:10:07.000000000 +0100
@@ -152,7 +152,7 @@ Inc., 51 Franklin St, Fifth Floor, Bosto
#else // !PCSCLITE
// SCARD_CTL_CODE defined in WinSmCrd.h included by Win32 winscard.h
// MAX_BUFFER_SIZE_EXTENDED is pcsc-lite specific
-#define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3 + 2)
+#define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3 + 2) -4
#endif //PCSCLITE
#include "pcsctypes.h"
and test again your Python script?
It works! Thank you for your awesome support.
I can now send any escape command without problems. Btw. did this bug only affect the escape command?
You can check that SCardTransmit() is working but I guess it is (or I would have received bug reports :-)
Hi guys Well these days Im trying to design a software which use smart card readers, I am using ACR1252u and I have discovered how to buzz my smart card reader if a tag or card is on the reader. but still wondering how can I do this without the card on the reader. the code which works for when the card is on the reader is below:
retCode = Card.SCardConnect(hContext, readername, Card.SCARD_SHARE_SHARED, Card.SCARD_PROTOCOL_T0 | Card.SCARD_PROTOCOL_T1, ref hCard, ref Protocol);
Byte[] setBuzzerLoud = new Byte[6];
setBuzzerLoud[0] = 0xE0;
setBuzzerLoud[1] = 0x00;
setBuzzerLoud[2] = 0x00;
setBuzzerLoud[3] = 0x21;
setBuzzerLoud[4] = 0x01;
setBuzzerLoud[5] = 0x77;
uint pcBytesReturned = 0;
Byte[] RecieveBuff = new Byte[64];
uint controlcode = 3225264;
int status = Card.SCardControl(hCard, controlcode, ref setBuzzerLoud[0], 6, ref RecieveBuff[0], RecieveBuff.Length, ref pcBytesReturned);
MessageBox.Show(status.ToString());
The problem is when hcard is on the reader the status which is the error shows 6. which means wrong handle!. But why buzzing a reader is connected to if the card is over the reader? is there anyway to turn this over? cause after this I want to turn on LEDs while the card is not over the reader- Guys plz if anyone have solved this problem tell us.
@fmoghaddampoor please open a new issue for new problems.
OS: Windows 7 SP1 64-bit Python: 2.7.11 Pyscard: 1.9.2
I have a problem sending an CCID Escape command via pyscard to my CCID Reader. When I execute the code snippet I get: scard.error: Failed to control: Illegal function.
I wrote the same sequence in C using the original API and it works without problems. Is it possible that pyscard does not support Escape commands?