Tool description:
This tool provides the following functions: 1) scan the serial number of a device with a scanner (for example, scanning the serial number of a product purchased in a supermarket), and then the serial number is automatically written to the text box in the figure, the serial number must be: 1. It must be 10 digits. 2. Each digit is 0 ~ 9.
When scanning is not available, manually enter it in the text box. The input requirements are as follows.
2) Send the serial number of the device to the device. Four commands are sent in total.
Command returns the serial number, which is compared with the input serial number. If the Input Serial number is the same, the device is successfully written. (Using the smart card master software)
3) for the convenience of the tester, as long as the tester scans with a scanner, the rest of the work
The tool is automatically completed.
Difficulties encountered: 1) There is no button driver first, and multithreading is used here to solve this problem.
2) in this process, most of the minor problems encountered were solved by debugging.
// Readshoterdlg. CPP: implementation file // # include "stdafx. H "# include" readshoter. H "# include" readshoterdlg. H "# include <afxwin. h> # include <stdlib. h> # include <stdio. h> # include <string. h> # include <string> # include "pcscreader. H "# include" toolfun. H "# include" softenc. H "# include" message. H "# include" messagew. H "# ifdef _ debug # define new debug_new # UNDEF this_filestatic char this_file [] = _ file __; # endif // //////////////////////////////////////// /// // Caboutdlg Dialog used for app about # define max_num 30 # define maxsize_20 # define maxsize_30 30 # define maxcount 10 // cpcscreader g_objreader; // cstringarray objstrarr; Class caboutdlg: Public cdialog {public: caboutdlg (); // dialog data // {afx_data (caboutdlg) Enum {IDD = idd_aboutbox }; //} afx_data // classwizard generated v Irtual function overrides // {afx_virtual (caboutdlg) protected: Virtual void dodataexchange (cdataexchange * PDX); // DDX/DDV support //} afx_virtual // implementationprotected: // {afx_msg (caboutdlg) //} specify ()}; caboutdlg: caboutdlg (): cdialog (caboutdlg: IDD) {// {afx_data_init (caboutdlg) //} afx_data_init} void caboutdlg: dodataexchange (cdataexchange * PDX) {cdialog: dodataexchange (PDX); // {Afx_data_map (caboutdlg) //} afx_data_map} begin_message_map (caboutdlg, cdialog) // {afx_msg_map (caboutdlg) // No message handlers //} afx_msg_mapend_message_map () //////////////////////////////////////// /// // creadshoterdlg dialogcreadshoterdlg:: creadshoterdlg (cwnd * pparent/* = NULL */): cdialog (creadshoterdlg: IDD, pparent) {// {afx_data_init (creadshoterdlg) // note: The classwizard will add member initialization here //} afx_data_init // note that loadicon does not require a subsequent destroyicon in response = afxgetapp ()-> loadicon (idr_mainframe);} void response:: dodataexchange (cdataexchange * PDX) {cdialog: dodataexchange (PDX); // {afx_data_map (creadshoterdlg) // note: the classwizard will add DDX and DDV cballs here //} afx_data_map} begin_message_map (CREA Dshoterdlg, cdialog) // {afx_msg_map (creadshoterdlg) on_wm_syscommand () on_wm_paint () lower () // lower (idc_sn_write, onsnwrite) //} lower () //////////////////////////////////////// /// // creadshoterdlg message handlersbool creadshoterdlg:: oninitdialog () {cdialog: oninitdialog (); // Add "about... "menu item to system menu. // idm_abou Tbox 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 dialogseticon (m_hicon, true); // set big iconseticon (m_hicon, false ); // set small icon // todo: add extra initialization herestatic int flag = 1; if (flag = 1) // modify the Registry {r Egeditdevice (); setregedit (); flag = 0;} // create a subthread cwinthread * pthread = new cwinthread (); pthread = afxbeginthread (onsnwrite, this ); if (pthread = NULL) {MessageBox (_ T ("thread startup failed! ");} // Delete pthread; return true; // return true unless you set the focus to a control} void creadshoterdlg: onsyscommand (uint NID, lparam) {If (NID & 0xfff0) = idm_aboutbox) {caboutdlg dlgabout; dlgabout. domodal ();} else {cdialog: onsyscommand (NID, lparam) ;}// if you add a Minimize button to your dialog, you will need the code below // to draw the icon. for MFC applications using the document/ View model, // This is automatically done for you by the framework. void creadshoterdlg: onpaint () {If (isiconic () {cpaintdc DC (this); // device context for paintingsendmessage (wm_iconerasebkgnd, (wparam) DC. getsafehdc (), 0); // center icon in client rectangleint cxicon = getsystemmetrics (sm_cxicon); int cyicon = getsystemmetrics (sm_cyicon); crect rect; getclientrect (& rect ); int x = (rect. width ()-cxico N + 1)/2; int y = (rect. height ()-cyicon + 1)/2; // draw the icondc. drawicon (X, Y, m_hicon);} else {cdialog: onpaint ();}} // The system callthis to obtain the cursor to display while the user drags // The minimized window. hcursor restart: onquerydragicon () {return (hcursor) m_hicon;} uint creadshoterdlg: onsnwrite (lpvoid pparam) {// The thread processes creadshoterdlg * pdlg = (callback *) pparam; assert (PD LG! = NULL); // cstringstrtemp; bytearraybasn; chartmp [6]; charzero [10] = {0}; // Sn array char snarray [maxsize_20] = {0 }; // vendor code char devid = '\ x01 '; // reserved char devrfu [max_num] = "\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 "; // offset in the segment char 0000ff [3] = "\ x20 \ x00"; // length char devlen = '\ x14 '; // key byte authkey [17] = {0}; // des returns the unsigned char ucoutblock [8] = {0 }; // random number Storage byte random [8] = {0}; // command 1 Format byte array [maxsize_2 0] = "\ xf0 \ x91 \ x00 \ x00 \ x08 "; // command 2 format // byte array1 [maxsize_20] = "\ xf0 \ x92 \ x00 \ x00 \ x08 "; byte array1 [maxsize_20] = "\ xf0 \ x00 \ x00 \ x00 \ x08 "; // command 3 Format Byte array2 [maxsize_30] = "\ xf0 \ xa2 \ x01 \ x00 \ x17 "; // command 4 Format Byte array3 [direction] = "\ xf0 \ x02 \ x03 \ x00 \ x00"; lpbyte pc1_head; DWORD dwdatalen; lpbyte pbrecv; lpdword direction; DWORD dwrecvlen; lpword pwsw; Word SW; // DWORD dwslot; while (1) {cpcscreader g_objreader; CST Ringarray objstrarr; cstringstrtemp; creadshoterdlg DLG; cwnd WND; message MSG; // Data Validity judgment // wait until the input is successful static char lptext [maxcount]; int f_flag = 0; // static int statue = 0; pdlg-> getdlgitemtext (idc_sn_num, strtemp); If (strtemp. getlength () <10) {continue; // If 10 digits are not met, the system waits for 10 digits in a loop.} If (strtemp. getlength () = 10) {sleep (2000); pdlg-> getdlgitemtext (idc_sn_num, strtemp); // check whether it is 10 digits} If (strtemp. getlength ()> 10) {afxmessagebox (_ T (" Enter the correct number! "); // If there are more than 10 error messages, clear pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} memcpy (lptext, strtemp. getbuffer (0), maxcount); For (Int J = 0; j <maxcount; j ++) {If (! (Lptext [J]> = '\ x30') & (lptext [J] <=' \ x39 ') {afxmessagebox (_ T ("enter 0 ~ The correct number of 9! "); Pdlg-> setdlgitemtext (idc_sn_num, zero); f_flag = 1; break ;}} if (f_flag = 1) continue; static int flag = 1; // device initialization if (FLAG) {If (! Cpcscreader: listpcscreader (objstrarr, cpcscreader: lpr_trust_pay_portable) {afxmessagebox (_ T ("failed to get the device. Please insert the device! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} 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) # elseif (strstr. Find ("Tianyu ")! = STD: String: NPOs) # endif {strname = strstr; break;} If (strname. empty () {afxmessagebox (_ T ("Tianyu device not found! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} If (! G_objreader.init (strname. c_str () {afxmessagebox (_ T ("failed to initialize the device! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} If (! G_objreader.connect (true) {afxmessagebox (_ T ("failed to connect to the device! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} flag = 1;} // todo: add your control notification handler code here // The first sending command 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 (pc1_head, dwdatalen, pbrecv, pdwrecvlen, pwsw, dwslot, 0, false) */If (! (G_objreader.sendcommandi (pc1_head, dwdatalen, pbrecv, pdwrecvlen, pwsw, true) {afxmessagebox (_ T ("command failed to send 1! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} // free (pbrecv); // The second sending command pc1_head = array1; dwdatalen = (DWORD) 13; dwrecvlen = (DWORD) maxsize_20; pdwrecvlen = & dwrecvlen; pwsw = & SW; // pbrecv = (byte *) malloc (dwrecvlen * sizeof (byte); // The key ID and key file * FD = fopen ("key. bin "," RB + "); If (FD = NULL) {afxmessagebox (_ T (" failed to open the key file! "); Return-1;} memset (authkey, 0, sizeof (authkey); If (fread (authkey, 17,1, FD) <1) {afxmessagebox (_ T ("failed to read key! "); Return-1;} fclose (FD); array1 [1] = authkey [0]; // key ID = 0x02; // random number memset (random, 0, sizeof (random); memcpy (random, pbrecv, sizeof (random); des_ede_encryption cipher (authkey + 1 ); // 3DES encryption key cipher. processblock (random, ucoutblock); memcpy (array1 + 5, ucoutblock, sizeof (ucoutblock); If (! (G_objreader.sendcommandi (pc1_head, dwdatalen, pbrecv, pdwrecvlen, pwsw, true) {afxmessagebox (_ T ("command failed to send 2! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} // 3rd sending command pc1_head = 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. g Etdata () + I);} memcpy (array2 + 5, 0000ff, strlen (0000ff); array2 [7] = devlen; memcpy (array2 + 8, devrfu, strlen (devrfu); array2 [22] = devid; memcpy (array2 + 23, snarray, basn. getsize (); If (! (G_objreader.sendcommandi (pc1_head, dwdatalen, pbrecv, pdwrecvlen, pwsw, true) {afxmessagebox (_ T ("command failed to send 3! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} // 4th times the command pc1_head = array3; dwdatalen = (DWORD) 5; dwrecvlen = (DWORD) maxsize_30; pdwrecvlen = & dwrecvlen; // pwsw = & SW; If (! (G_objreader.sendcommandi (pc1_head, dwdatalen, pbrecv, pdwrecvlen, pwsw, true) {afxmessagebox (_ T ("command failed to send 4! "); G_objreader.disconnect (); pdlg-> setdlgitemtext (idc_sn_num, zero); continue;} memcpy (TMP, pbrecv + 15, basn. getsize (); If (strncmp (snarray, TMP, 5) = 0) {DLG. messageboxdlgright (); // afxmessagebox (_ T ("√"); // sleep (3000); // hwnd =: findwindow (null, "readshoter");} else {// afxmessagebox (_ T ("×"); DLG. messageboxdlgwrong ();} // clear the input box pdlg-> setdlgitemtext (idc_sn_num, zero); free (pbrecv); g_objreader.disconnect ();} DELE Te pdlg; return 0;} void creadshoterdlg: messageboxdlgright () {// modal // message MSG; // MSG. domodal (); // non-modal message * PMSG = new message; PMSG-> Create (idd_message_dialog, null); PMSG-> showwindow (sw_shownormal); PMSG-> updatewindow (); sleep (2000); PMSG-> sendmessage (wm_close); Delete PMSG;} void creadshoterdlg: messageboxdlgwrong () {// modal // message MSG; // MSG. domodal (); // non-modal message * PMSG = new message; PMSG-> Create (Idd_msg_wrong, null); PMSG-> showwindow (sw_shownormal); PMSG-> updatewindow (); sleep (3000); PMSG-> sendmessage (wm_close); Delete PMSG ;} /*************************************** * function: set the registry key value * // * input parameter: none * // ** // * output parameter: none * // * return value: none *//**//******************************** **************************************** /void creadshoterdlg:: setregedit () {hkey = 0; hkey hsubkey = 0; DWORD dwkeyvalue = 1; DWORD dwsize = 0; DWORD dwvalue = 0; // char * pchpath = "System \ CurrentControlSet \ Enum \ USB \ vid_1a2c & pid_0002 & mi_00"; char actemp [max_path] = {0 }; // \ 5 & 2c5c6891 & 0 & 4 \ Device Parameters "; DWORD dwtemplen = 0; char absubkeyname [max_path] = {0}; DWORD dwsubkeynamelen = 0; DWORD I = 0; DWORD dwret = 0; DWORD dwflagmodify = 0; tchar athpchpath [max_path] = {0}; cstring strmidvar; boolm_bfirs Tflag; If (m_strarrmidvar.getsize () = 0) {afxmessagebox ("CCID card reader, an error occurred while setting the registry key value! ") ;}For (Int J = 0; j <m_strarrmidvar.getsize (); j ++) {strmidvar = m_strarrmidvar.getat (j); strcpy (athpchpath, strmidvar. getbuffer (0); regcreatekey (HKEY_LOCAL_MACHINE, athpchpath, & hkey); If (! Hkey) {afxmessagebox ("CCID card reader, failed to set registry key value! "); Return;} I = 0; while (1) {dwtemplen = sizeof (actemp); memset (actemp, 0, dwtemplen); dwsubkeynamelen = sizeof (absubkeyname ); memset (absubkeyname, 0, dwsubkeynamelen); If (error_success! = Regenumkeyex (hkey, I ++, absubkeyname, & dwsubkeynamelen, 0, 0, 0) |! Sprintf (actemp, "% s \ Device Parameters", athpchpath, absubkeyname) | error_success! = Regopenkey (HKEY_LOCAL_MACHINE, actemp, & hsubkey) {If (hsubkey) {regclosekey (hsubkey) ;}hsubkey = 0; break;} If (error_success! = Regqueryvalueex (hsubkey, "escapecommandenable", 0, null, null, & dwsize) {m_bfirstflag = true; // afxmessagebox ("because you are using this device for the first time, the device will perform initialization settings. Please wait... "); // getdlgitem (idc_download_button)-> enablewindow (false); sleep (3000);} else if (error_success = regqueryvalueex (hsubkey," escapecommandenable ", 0, null, (unsigned char *) & dwvalue, & dwsize) {if (1! = Dwvalue) {m_bfirstflag = true; // afxmessagebox ("because you are using this device for the first time, this device will perform initialization settings. Please wait... "); // getdlgitem (idc_download_button)-> enablewindow (false); sleep (3000);} else {m_bfirstflag = false ;} dwret = regsetvalueex (hsubkey, "escapecommandenable", 0, REG_DWORD, (unsigned char *) & dwkeyvalue, sizeof (dwkeyvalue) ;}} if (hsubkey) {regclosekey (hsubkey);} hsubkey = 0 ;} /*************************************** * function: add the registry key * // * input parameter: none * // ** // * output parameter: none * // * return value: none *//**//******************************** **************************************** /void creadshoterdlg:: regeditdevice () {handle htoken = NULL; cstring strpchpath1; cstring strpchpath2; cstring strpchpath3; cstring strpchpath; strpchpath1 = _ T ("System \ CurrentControlSet \ Enum \ USB \ vid_a625 & pid_0902 "); strpchpath2 = _ T ("System \ CurrentControlSet \ Enum \ USB \ vid_a625 & pid_0902 & mi_00 "); strpchpath3 = _ T ("SYSTEM \ CurrentControlSet \ Enum \ USB \ vid_a625 & pid_0902 & mi_01"); reverse (strpchpath1); m_strarrmidvar.add (strpchpath2 ); m_strarrmidvar.add (strpchpath3); setregedit (); // startinteractiveclientprocess (null, htoken );}
The above is my work section, which may be self-explanatory .....