设备序列号写入工具
工具说明:
此工具是功能是:1)用扫描枪扫描设备的序列号(如在超市买商品都要扫描一样),然后序列号会自动写入到图中的文本框中,序列号要求是:1、它必须是10位数的。2、每位数是0~9。
当不能扫描时,手动输入到文本框中,输入要求如上。
2)将设备被序列号用命令发送到设备中去,一共发4条命令,最后一
条命令返回序列号,与输入的序列号进行比对,相同则设备写入成功。(用到智能卡大师软件)
3)为了测试人员方便使用,只要测试人用扫描器扫描,其余的工作由
工具自动完成。
遇到的难点:1)首先没有按钮驱动,在这里用多线程解决了此问题。
2)在此过程中,遇到了杂七杂八的小问题,大多数都是调试解决。
主要的代码:
BOOL CReadShoterDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
CPCSCReader g_objReader;
CStringArray objStrArr;
//这里为了然工具已启动就初始化一次设备,我讲Init这个函数理解成主线称吧。。。
static int flag = 1;
//设备初始化
if(flag)
{
if (!CPCSCReader::ListPcscReader(objStrArr,CPCSCReader::LPR_TRUST_PAY_PORTABLE))
{
MessageBox(_T("获取设备列表失败!"));
// return;
}
std::string strName = "";
int nCount = objStrArr.GetSize();
for (int i=0; i<nCount; i++)
{
std::string strStr= objStrArr.GetAt(i);
strStr = strupr((char*)strStr.c_str());
#ifdef _NT_DEV_
if (strStr.find("NANTIAN") != std::string::npos)
#else
if (strStr.find("TIANYU") != std::string::npos)
#endif
{
strName = strStr;
break;
}
}
if (strName.empty())
{
MessageBox(_T("没有找到 TIANYU 的设备!"));
// return;
}
if (!g_objReader.Init(strName.c_str()))
{
MessageBox(_T("初始化设备失败!"));
// return;
}
if (!g_objReader.Connect())
{
MessageBox(_T("连接设备失败!"));
// return;
}
flag = 0;
}
//创建子线程,为什么要用的子线程,是因为我要自动读入序列号,之后对序列号的处 理不需要按钮驱动,但我又要用到文本框里的序列号,没有出来工具框怎么能用到呢, 所以要用到多线程,主线程的目的就是要出来对话框,能读取文本框的数据。子线程的
目的就是换一台设备读取序列号完成一系列的动作,循环反复。
CWinThread *pThread = new CWinThread();
pThread = AfxBeginThread(OnSnWrite,this);
if (pThread == NULL)
{
MessageBox(_T("线程启动失败!"));
}
//OnSnWrite函数
UINT CReadShoterDlg::OnSnWrite(LPVOID pParam)
{
//线程处理
CReadShoterDlg* pDlg = (CReadShoterDlg*)pParam;
ASSERT(pDlg!=NULL);
CString strTemp;
byteArray baSN;
char tmp[6];
char zero[10]={0};
…………………………
LPBYTE pcCmdHead;
DWORD dwDataLen;
LPBYTE pbRecv;
LPDWORD pdwRecvLen;
DWORD dwRecvLen;
LPWORD pwSW;
WORD sW;
DWORD dwSlot;
//反复序列号写入设备
while(1)
{
CPCSCReader g_objReader;
CStringArray objStrArr;
//数据合法性判断
//等待输入成功
static char lpText[MaxCount];
//等待输入10位序列号为止
if(pDlg->GetDlgItemText(IDC_SN_NUM,lpText,MaxCount)!=10)
{
continue;
}
//要求每位是0~9的数字
for (int j = 0; j<MaxCount-1; j++)
{
if (!((lpText[j] >='\x30') && (lpText[j] <= '\x39')))
{
AfxMessageBox(_T("请如输入0~9的正确数字!"));
}
}
//因为每次要换设备,所以每次要初始化
static int flag = 1;
//设备初始化
if(flag)
{
if (!CPCSCReader::ListPcscReader(objStrArr,CPCSCReader::LPR_TRUST_PAY_PORTABLE))
{
AfxMessageBox(_T("获取设备列表失败!"));
return -1;
}
std::string strName = "";
int nCount = objStrArr.GetSize();
for (int i=0; i<nCount; i++)
{
std::string strStr= objStrArr.GetAt(i);
strStr = strupr((char*)strStr.c_str());
#ifdef _NT_DEV_
if (strStr.find("NANTIAN") != std::string::npos)
#else
if (strStr.find("TIANYU") != std::string::npos)
#endif
{
strName = strStr;
break;
}
}
if (strName.empty())
{
AfxMessageBox(_T("没有找到 TIANYU 的设备!"));
return -1;;
}
if (!g_objReader.Init(strName.c_str()))
{
AfxMessageBox(_T("初始化设备失败!"));
return -1;
}
if (!g_objReader.Connect())
{
AfxMessageBox(_T("连接设备失败!"));
return -1;
}
flag = 1;
}
// TODO: Add your control notification handler code here
//以下是发送4次命令
pcCmdHead = array;
// LPBYTE pbData;
dwDataLen = (DWORD)5;
dwRecvLen = (DWORD)MAXSIZE_20;
pbRecv = (BYTE*) malloc(dwRecvLen*sizeof(BYTE));
pdwRecvLen = &dwRecvLen;
pwSW = &sW;
if(!(g_objReader.SendCommand(pcCmdHead,dwDataLen,pbRecv,pdwRecvLen,pwSW,dwSlot,0,FALSE)))
{
AfxMessageBox(_T("命令发送失败1!"));
return -1;
}
// free(pbRecv);
//第二次发送命令
pcCmdHead = array1;
dwDataLen = (DWORD)13;
dwRecvLen = (DWORD)MAXSIZE_20;
pdwRecvLen = &dwRecvLen;
pwSW = &sW;
// pbRecv = (BYTE*) malloc(dwRecvLen*sizeof(BYTE));
//去随机数
memset(random,0,sizeof(random));
memcpy(random,pbRecv,sizeof(random));
DES_EDE_Encryption cipher(authkey);
cipher.ProcessBlock(random,ucOutBlock);
memcpy(array1+5,ucOutBlock,sizeof(ucOutBlock));
if(!(g_objReader.SendCommand(pcCmdHead,dwDataLen,pbRecv,pdwRecvLen,pwSW,dwSlot,0,FALSE)))
{
AfxMessageBox(_T("命令发送失败2!"));
return -1;
}
//第3次发送命令
pcCmdHead = array2;
// dwDataLen = (DWORD)28;
dwRecvLen = (DWORD)MAXSIZE_30;
pdwRecvLen = &dwRecvLen;
pwSW = &sW;
pDlg->GetDlgItemText(IDC_SN_NUM,strTemp);
StrToHex(strTemp.GetBuffer(0),strTemp.GetLength(),baSN);
dwDataLen = (DWORD)(23+baSN.GetSize());
for (int i = 0; i <baSN.GetSize(); i++)
{
snArray[i] = *((BYTE*)(baSN.GetData()+i));
}
memcpy(array2+5,devoff,strlen(devoff));
array2[7] = devlen;
memcpy(array2+8,devrfu,strlen(devrfu));
array2[22] = devid;
memcpy(array2+23,snArray,baSN.GetSize());
if(!(g_objReader.SendCommand(pcCmdHead,dwDataLen,pbRecv,pdwRecvLen,pwSW,dwSlot,0,FALSE)))
{
AfxMessageBox(_T("命令发送失败3!"));
return -1;
}
//第4次发命令
pcCmdHead = array3;
dwDataLen = (DWORD)5;
dwRecvLen = (DWORD)MAXSIZE_30;
pdwRecvLen = &dwRecvLen;
pwSW = &sW;
if(!(g_objReader.SendCommand(pcCmdHead,dwDataLen,pbRecv,pdwRecvLen,pwSW,dwSlot,0,FALSE)))
{
AfxMessageBox(_T("命令发送失败4!"));
return -1;
}
memcpy(tmp,pbRecv+15,baSN.GetSize());
if(strncmp(snArray,tmp,5)==0)
{
AfxMessageBox(_T("SN成功写入!"));
}
else
{
AfxMessageBox(_T("SN写入失败!"));
}
//清除输入框
pDlg->SetDlgItemText(IDC_SN_NUM,zero);
free(pbRecv);
g_objReader.DisConnect();
}
return 0;
}
以上是个人的工作小节,写的可能自有自己能看懂。。。。。