UKEY通信CCID

来源:互联网 发布:市政造价软件 编辑:程序博客网 时间:2024/04/27 16:47

CCID通信和HID通信代码相似,借用微软API接口,可以查询到UKEY

所需特殊的头文件:winscard.h

http://blog.csdn.net/xiven/article/details/4747084

1:查询设备并进行连接

SCardTransmit(ghCard, &pioSendPci, bCmd, cmdLen, NULL, pBuf, &lRecLen);

<span style="white-space:pre"></span>(1)SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ghContext);
<span style="white-space:pre"></span>获得系统中CCID类设备列表
<span style="white-space:pre"></span>(2)SCardListReaders(ghContext, NULL, NULL, &dwReaders);
<span style="white-space:pre"></span>     <span style="white-space:pre"></span>mszReaders = (LPTSTR)malloc(dwReaders);<span style="white-space:pre"></span>rv = SCardListReaders(ghContext, NULL, mszReaders, &dwReaders);
<span style="white-space:pre"></span>两次调用<span style="font-family: Arial, Helvetica, sans-serif;">SCardListReaders</span>获得CCID设备列表中所有设备信息,第一次获得存储信息的所需内存大小,第二次获取存储的信息
<span style="white-space:pre"></span>mszReaders中存储的是读卡器的名字,找到设备然后连接设备
<span style="white-space:pre"><span style="white-space: pre;">(</span>3)SCardConnect(ghContext, szCcidPath, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &ghCard, &gActiveProtocol);</span><span style="font-family: Arial, Helvetica, sans-serif;"></span>
<span style="white-space:pre"></span>hContext:输入类型;ScardEstablishContext()建立的资源管理器上下文的句柄。<span style="white-space:pre"></span>szCcidPath:输入类型;包含智能卡的读卡器名称(读卡器名称由ScardListReaders()给出)。<span style="white-space:pre"></span>dwShareMode:输入类型;应用程序对智能卡的操作方式,SCARD_SHARE_SHARED(多个应用共享同一个智能卡)、SCARD_SHARE_EXCLUSIVE(应用独占智能卡)<span style="white-space:pre"></span>、SCARD_SHARE_DIRECT(应用将智能卡作为私有用途,直接操纵智能卡,不允许其它应用访问智能卡)。<span style="white-space:pre"></span>dwPreferredProtocols:输入类型;连接使用的协议,SCARD_PROTOCOL_T0(使用T=0协议)、SCARD_PROTOCOL_T1(使用T=1协议)。<span style="white-space:pre"></span>ghCard:输出类型;与智能卡连接的句柄。<span style="white-space:pre"></span>gActiveProtocol:输出类型;实际使用的协议。
主要为了获得读卡设备句柄,通过设备句柄获得对读卡器的操作控制权利。

2:连接设备

此处所使用的函数上面都已经介绍过了,主要是此处输入我们设定的硬件名称,此名称和获取到的设备名称相比较,在相同的情况下说明找到设备,然后对此设备进行连接即可。UKEY中比较设备标签是否相同,设备标签已经被写到设备硬件信息中,通过设备句柄获取设备标签信息,比较成功后说明寻找到设备。

3:数据传输:

SCardTransmit(ghCard, &pioSendPci, bCmd, cmdLen, NULL, pBuf, &lRecLen);
<span style="white-space:pre"></span>ghCard:[in] 智能卡(UKEY)句柄
<span style="white-space:pre"></span>pioSendPci:[in]SCARD_IO_REQUEST微软定义好的数据结构
<span style="white-space:pre"></span>bCmd:命令buffer
<span style="white-space:pre"></span>cmdLen:命令长度
<span style="white-space:pre"></span>pBuf:返回的数据buffer
<span style="white-space:pre"></span>lRecLen:返回的数据buffer的长度
下面是我们自己的完整CCID通信代码片段:

DWORD List3011Dev(OUT LPSTR pszDevLabels,OUT DWORD* pdwLen){BYTEindex;DWORDtempLen,totalLen;LONGrv;LPTSTRmszReaders = NULL;DWORDdwReaders,dwResult;rv = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ghContext);if(rv != SCARD_S_SUCCESS)return SAR_FAIL;//获得系统中安装的读卡器列表rv = SCardListReaders(ghContext, NULL, NULL, &dwReaders);if(rv != SCARD_S_SUCCESS){return SAR_FAIL;}mszReaders = (LPTSTR)malloc(dwReaders);rv = SCardListReaders(ghContext, NULL, mszReaders, &dwReaders);if(rv != SCARD_S_SUCCESS){free(mszReaders);return SAR_FAIL;}//解析读卡器的名字tempLen = 0;totalLen = (WORD)dwReaders;index = 0;BOOL bFindDevice=FALSE;CHAR szCcidPath[MAX_PATH+1];ZeroMemory(szCcidPath,sizeof(szCcidPath));while(tempLen < totalLen){if(mszReaders[tempLen] == 0)break; //strcpy(gUkeyInfo[index].ukeyPathName,&mszReaders[tempLen]);//if(strstr(gUkeyInfo[index].ukeyPathName,VID_PID_INFO) != NULL)strcpy(szCcidPath,&mszReaders[tempLen]);if (NULL!=strstr(&(mszReaders[tempLen]),g_bCcidProductStr)){bFindDevice=TRUE; break;}++index;tempLen += strlen(&mszReaders[tempLen]) + 1;}if(mszReaders != NULL)free(mszReaders);//连接读卡器CHAR szDevLabel[MAX_DEV_LABEL_STRING_LEN+1];if (bFindDevice){rv = SCardConnect(ghContext, szCcidPath, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &ghCard, &gActiveProtocol);if(rv != SCARD_S_SUCCESS)return SAR_DEVICE_REMOVED;DEVINFO mydev;ZeroMemory(&mydev,sizeof(mydev));//Get iddwResult=CMD_GetDevInfo((HANDLE)&ghCard, (BYTE *)&mydev, sizeof(DEVINFO));if(SAR_OK!=dwResult){return dwResult;}ZeroMemory(szDevLabel,sizeof(szDevLabel));strcpy(szDevLabel,mydev.SerialNumber);//获取设备序列号if (pszDevLabels){strcpy(pszDevLabels,szDevLabel);pszDevLabels[strlen(szDevLabel)+1]=0;}if (pdwLen){*pdwLen=strlen(szDevLabel)+2;}return SAR_OK;}else{SCardReleaseContext(ghContext);return SAR_DEVICE_REMOVED;}
}
DWORD Connect3011Device(IN LPSTR szName,IN OUT HANDLE*phDev){DWORD dwResult;HDEVINFO hDevInfo;DEVINFO mydev;tDevHandle hDevHandle;ZeroMemory(&hDevHandle,sizeof(hDevHandle));hDevHandle.hDevice=INVALID_HANDLE_VALUE;hDevHandle.hUSBRead=INVALID_HANDLE_VALUE;hDevHandle.hUSBWrite=INVALID_HANDLE_VALUE;hDevHandle.nDeviceType=DEVICE_CDROM;if (phDev){*phDev=NULL;}#ifdef __CCID_USB_COMMUNICATION_BYTEindex;DWORDtempLen,totalLen;LONGrv;LPTSTRmszReaders = NULL;DWORDdwReaders;CHAR szCcidPath[MAX_PATH+1];ZeroMemory(szCcidPath,sizeof(szCcidPath));if (NULL==ghContext){rv = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ghContext);if(rv != SCARD_S_SUCCESS)return SAR_FAIL;//获得系统中安装的读卡器列表rv = SCardListReaders(ghContext, NULL, NULL, &dwReaders);if(rv != SCARD_S_SUCCESS){return SAR_FAIL;}mszReaders = (LPTSTR)malloc(dwReaders);rv = SCardListReaders(ghContext, NULL, mszReaders, &dwReaders);if(rv != SCARD_S_SUCCESS){free(mszReaders);return SAR_FAIL;}//解析读卡器的名字tempLen = 0;totalLen = (WORD)dwReaders;index = 0;BOOL bFindDevice=FALSE;while(tempLen < totalLen){if(mszReaders[tempLen] == 0)break;strcpy(szCcidPath,&mszReaders[tempLen]);if (NULL!=strstr(&(mszReaders[tempLen]),g_bCcidProductStr)){bFindDevice=TRUE;break;}++index;tempLen += strlen(&mszReaders[tempLen]) + 1;}if(mszReaders != NULL)free(mszReaders);if (bFindDevice){rv = SCardConnect(ghContext, szCcidPath, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &ghCard, &gActiveProtocol);if(rv != SCARD_S_SUCCESS)return SAR_DEVICE_REMOVED;}else{return SAR_DEVICE_REMOVED;}}//连接读卡器CHAR szDevLabel[MAX_DEV_LABEL_STRING_LEN+1]; ZeroMemory(&mydev,sizeof(mydev));//Get iddwResult=CMD_GetDevInfo((HANDLE)&ghCard, (BYTE *)&mydev, sizeof(DEVINFO));if(SAR_OK!=dwResult){return dwResult;}ZeroMemory(szDevLabel,sizeof(szDevLabel));strcpy(szDevLabel,mydev.SerialNumber);if (!strcmp(szDevLabel,szName)){if(phDev){*phDev=(HANDLE)ghCard;}return SAR_OK;}else{return SAR_DEVICE_REMOVED;}}
传输部分的处理这里省略



0 0