SIM-Kartenleser ansteuern
-
Ich will in meiner MFC-Anwedung daten aus bestimmten Feldern von einer SIM-Karte lesen(z.B. das LOCI-Feld). Habe einen Gemxplore GRC410 Kartenleser(natürlich mit Software) und will ihn über COM1 ansteuern. Falls jemand Erfahrungen hat, die in diese Richtung gehen, würde ich mich sehr über hilfe freuen. Im Internet habe ich etwas gefunden:
Das ganze Programm hat keine Fehler. Wenn ich Daten vom COM2 lese und in eine Datei schreibe klappt alles( an COM2 ist nichts angeschlossen, somit wird eine mit Text gefüllte Datei mit "leer" beschrieben). Wenn ich aber von COM1 lesen will, wo der Karteleser dran hängt kommt: "Invalid Handle Value For Communication Port.Program Fails!" das ist im CODE FETT geschrieben.
Was bedeutet der Fehler genau???... void CTxRxDlg::OnButtonReceive() { // TODO: Add your control notification handler code here if (m_FileName.IsEmpty()) { MessageBox(_T("File has been not specified.Cancel Operation!")); return; } HANDLE hCom; LPDCB lpDcb; int i=m_ComboCom.GetCurSel(); switch (i) { case 0: hCom=CreateFile("\\.\\COM1:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); break; case 1: hCom=CreateFile("\\.\\COM2:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); break; case 2: hCom=CreateFile("\\.\\COM3:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); break; case 3: hCom=CreateFile("\\.\\COM4:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); break; default: hCom=CreateFile("\\.\\COM2:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); break; } [b]if (hCom==INVALID_HANDLE_VALUE) { MessageBox("Invalid Handle Value For Communication Port.Program Fails!"); return ; }[/b] lpDcb=new(DCB); if (!GetCommState(hCom,lpDcb)) { MessageBox("Program Fails To Get Communication Port State."); return ; } CString strTemp=_T("baud= parity= data= stop="); strTemp.Insert(strTemp.Find(_T("baud="))+5,m_Baud); if (m_RadioData81.GetCheck()) { strTemp.Insert(strTemp.Find(_T("data="))+5,_T("8")); strTemp.Insert(strTemp.Find(_T("stop="))+5,_T("1")); } else { strTemp.Insert(strTemp.Find(_T("data="))+5,_T("8")); strTemp.Insert(strTemp.Find(_T("stop="))+5,_T("2")); } if (CTxRxDlg::GetCheckedRadioButton(IDC_RadioParityN,IDC_RadioParityN)) strTemp.Insert(strTemp.Find(_T("parity="))+7,_T("N")); else { if (CTxRxDlg::GetCheckedRadioButton(IDC_RadioParityE,IDC_RadioParityE)) strTemp.Insert(strTemp.Find(_T("parity="))+7,_T("E")); else if (CTxRxDlg::GetCheckedRadioButton(IDC_RadioParityO,IDC_RadioParityO)) strTemp.Insert(strTemp.Find(_T("parity="))+7,_T("O")); else strTemp.Insert(strTemp.Find(_T("parity="))+7,_T("N")); } if (!BuildCommDCB(strTemp,lpDcb)) { MessageBox("Program Fails To Build Communication Port State."); return ; } if (!SetCommState(hCom,lpDcb)) { MessageBox("Program Fails To Set Communication Port State."); return ; } BYTE* Buffer; DWORD dwTimeout=1000; DWORD dwRead; DWORD dwResult; OVERLAPPED OL={0}; long BufferIndex=0; BOOL blContinue=TRUE; m_EditTimeout.GetWindowText(strTemp); dwTimeout=atol(strTemp); Buffer=(BYTE*) malloc(m_BytesOfMemory); if(Buffer==NULL) { MessageBox(_T("Program Failed!Can Not Allocate Memory")); return; } OL.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL); if (OL.hEvent ==NULL ) { MessageBox(_T("Program Failed!Can Not Create Event")); return ; } CFile bf; if (!bf.Open(m_FileName,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary)) { MessageBox(_T("Program Failed!Can Create File")); return; } m_ProgressRx.SetRange(0,100); do { m_ProgressRx.SetPos(0); m_LEDReceive.SetIcon(::LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_IconReceive))); dwRead=ReadFile(hCom,Buffer,1, &dwRead, &OL);//m_BytesOfMemory if (dwRead==0) { if (GetLastError() != ERROR_IO_PENDING) dwRead=0 ; else { // Write is pending. dwResult = WaitForSingleObject(OL.hEvent, dwTimeout); switch(dwResult) { case WAIT_OBJECT_0: if (!GetOverlappedResult(hCom, &OL, &dwRead, FALSE)) dwRead=0 ; break; case WAIT_ABANDONED: dwRead=0 ; break; case WAIT_TIMEOUT: dwRead=0 ; break; default: dwRead=0 ; break; } } if (dwRead==0) blContinue=FALSE; else { BufferIndex+=dwRead; bf.Write(Buffer,dwRead); } m_LEDReceive.SetIcon(::LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_IconOff))); } else { BufferIndex+=dwRead; m_LEDReceive.SetIcon(::LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_IconOff))); bf.Write(Buffer,dwRead); } m_ProgressRx.SetPos((int)((dwRead*100)/m_BytesOfMemory)); }while(blContinue); Sleep(700); m_ProgressRx.SetPos(0); bf.Close(); CloseHandle(OL.hEvent); CloseHandle(hCom); } ...
-
natürlich mit Software
die läuft aber nicht gleichzeitig mit deiner?
-
naturlich nicht. ging nur darum dass jemand die tolle idee hätte heben können, dass ich die Original software nehmen sollte um daten auszulesen
-
Kann das überhaup so gehen oder gibt es einen komplett anderen Ansatz? Muß ich vielleicht Treiber einbinden oder assembler code?
-
sollte so gehen.
ruf mal GetLastError auf um rauszufinden warum sich den COM post nicht öffnen lässt.
-
Hallo,
also ich bin zwar kein Profi in C++, aber zum SmartCard-Leser:
Es gibt für SmartCard-Leser 2 Protokolle.
PC/SC und CT-API.
PC/SC ist so weit ich weiß in Windows integriert, die CT-API ist eine Erfindung von einigen deutschen Firmen und wird über eine dll gesteuert.Die meisten Kartenleser die ich kenne, legen eine CTSCR.dll oder so für die CT-API im Windows/System32 Ordner ab.
Über diese dll werden die SmartCard Leser angesprochen.
Alternativ gibt es in der MSDN auch PC/SC-Funktionen dafür.mfg
trequ