我有一个.Net控制台应用程序,它使用winscard / pcsclite与智能卡通信。 它在Windows和32位Linux上没有问题,但在64位Linux上失败。 SCardTransmit函数返回0但是RecvLength没有更新,也没有收到数据。
更新
问题似乎在于调用SCardTransmit函数。 Dllimport就是这样指定的。 我也尝试将recvLen指定为具有相同结果的IntPtr。
[StructLayout(LayoutKind.Sequential)]
internal struct SCardIoRequest
{
internal SCardIoRequest(CardProtocol protocol)
{
Protocol = (uint)protocol;
Length = (uint)Marshal.SizeOf(typeof(SCardIoRequest));
}
public uint Protocol;
public uint Length;
}
[DllImport("Winscard.dll", SetLastError = true)]
private static extern int SCardTransmit(IntPtr card, [In] ref SCardIoRequest sendPci, byte[] sendBuffer, uint sendLen, IntPtr recvPci, [Out] byte[] recvBuffer, ref int recvLen);
其他信息和日志:
mono version 2.10.8 pcsc-lite version 1.4.4 [centos@localhost ~]$ mono pcsctest.exe Test PC/CS SCardEstablishContext - returned 0 SCardListReaders - returned 0 SCardListReaders - returned 0 After GetReaders Reader: OmniKey CardMan 6121 00 00 SCardConnect - returned 0 Connect to Card, protocol: 2 SCardTransmit - returned 0 recvlen = 256 Serial: 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 SCardTransmit - returned 0 winscard_msg_srv.c:217:SHMProcessEventsServer() Common channel packet arrival winscard_msg_srv.c:226:SHMProcessEventsServer() SHMProcessCommonChannelRequest detects: 7 pcscdaemon.c:174:SVCServiceRunLoop() A new context thread creation is requested: 7 winscard_svc.c:131:ContextThread() Thread is started: 7 winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard_svc.c:179:ContextThread() Client is protocol version 2:2 winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard.c:242:SCardEstablishContext() Establishing Context: 16985718 winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard.c:298:SCardConnect() Attempting Connect to OmniKey CardMan 6121 00 00 using protocol: 2 prothandler.c:130:PHSetProtocol() Attempting PTS to T=1 ifdhandler.c:488:IFDHSetProtocolParameters() lun: 0, protocol T=1 winscard.c:433:SCardConnect() Active Protocol: T=1 winscard.c:443:SCardConnect() hCard Identity: eaf1 winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard_svc.c:730:MSGCheckHandleAssociation() Client failed to authenticate winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard_svc.c:730:MSGCheckHandleAssociation() Client failed to authenticate winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard_svc.c:730:MSGCheckHandleAssociation() Client failed to authenticate winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard_svc.c:730:MSGCheckHandleAssociation() Client failed to authenticate winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard_svc.c:730:MSGCheckHandleAssociation() Client failed to authenticate winscard_msg_srv.c:288:SHMProcessEventsContext() correctly processed client: 7 winscard.c:253:SCardReleaseContext() Releasing Context: 16985718 winscard.c:848:SCardDisconnect() Active Contexts: 1 winscard_msg_srv.c:276:SHMProcessEventsContext() Client has disappeared: 7 winscard_svc.c:144:ContextThread() Client die: 7
答案 0 :(得分:2)
你没有发布你的代码,所以这只是猜测,但看起来你的互操作代码中的问题是指定数据如何在托管 - C# - 和非托管 - C - 内存之间编组。你很可能面对我在多平台Pkcs11Interop项目开发过程中遇到的famous C 'long' type marshaling problem。
PCSC API使用C'long'类型,这种类型非常难以编组,因为.NET中没有与所有平台上的大小相匹配的类型。问题是在某些平台(Win32,Win64和Unix32)上C'long'类型可以是4个字节长,同时在其他平台(Unix64)上它可以是8个字节长。在.NET中有'int'类型,无论平台如何都是4字节长,并且有'long'类型,无论平台如何都是8字节长。它们都不能用作C'long'类型的多平台替代方案,唯一的解决方案是使用和编组两组不同的函数和结构,一个用'int'.NET类型用于C'long'类型的平台长度为4个字节,另一个为“long”.NET类型,用于C'long'类型为8个字节长的平台。
总结一下:你应该修复你的编组代码,或者你应该使用更好的托管PCSC互操作库,它也支持C'long'类型长度为8个字节的平台。看起来pcsc-sharp可能是一种方式,但我还没有测试过它。