@@ -94,10 +94,12 @@ QPCSC::QPCSC()
9494QPCSC ::~QPCSC ()
9595{
9696 requestInterruption ();
97+ d->sleepCond .wakeAll ();
98+ if (d->thread )
99+ SC (Cancel, d->thread );
97100 wait ();
98- if ( d->context )
101+ if (d->context )
99102 SC (ReleaseContext, d->context );
100- qDeleteAll (d->lock );
101103 delete d;
102104}
103105
@@ -138,23 +140,30 @@ void QPCSC::run()
138140 std::vector<SCARD_READERSTATE > list;
139141 while (!isInterruptionRequested ())
140142 {
141- if (!pcsc.serviceRunning ())
142- {
143- sleep (5 );
144- continue ;
145- }
146143 // "\\?PnP?\Notification" does not work on macOS
147144 QByteArray data = pcsc.rawReaders ();
148145 if (data.isEmpty ())
149146 {
150- sleep (5 );
147+ QMutexLocker locker (&d->sleepMutex );
148+ if (isInterruptionRequested ())
149+ break ;
150+ d->sleepCond .wait (&d->sleepMutex , 5000 );
151151 continue ;
152152 }
153153 for (const char *name = data.constData (); *name; name += strlen (name) + 1 )
154154 {
155155 if (std::none_of (list.cbegin (), list.cend (), [&name](const SCARD_READERSTATE &state) { return strcmp (state.szReader , name) == 0 ; }))
156156 list.push_back ({ strdup (name), nullptr , 0 , 0 , 0 , {} });
157157 }
158+ if (list.empty ())
159+ {
160+ QMutexLocker locker (&d->sleepMutex );
161+ if (isInterruptionRequested ())
162+ break ;
163+ d->sleepCond .wait (&d->sleepMutex , 5000 );
164+ continue ;
165+ }
166+ d->thread = pcsc.d ->context ;
158167 if (SC (GetStatusChange, pcsc.d ->context , 5 *1000U , list.data (), DWORD (list.size ())) != SCARD_S_SUCCESS )
159168 continue ;
160169 for (auto i = list.begin (); i != list.end (); )
@@ -164,6 +173,8 @@ void QPCSC::run()
164173 ++i;
165174 continue ;
166175 }
176+ if ((i->dwCurrentState & SCARD_STATE_PRESENT ) != (i->dwEventState & SCARD_STATE_PRESENT ))
177+ Q_EMIT cardChanged ();
167178 i->dwCurrentState = i->dwEventState ;
168179 qCDebug (SCard) << " New state: " << QString::fromLocal8Bit (i->szReader ) << stateToString (i->dwCurrentState );
169180 Q_EMIT statusChanged (QString::fromLocal8Bit (i->szReader ), stateToString (i->dwCurrentState ));
@@ -176,6 +187,7 @@ void QPCSC::run()
176187 ++i;
177188 }
178189 }
190+ d->thread = {};
179191}
180192
181193bool QPCSC::serviceRunning () const
@@ -191,9 +203,6 @@ bool QPCSC::serviceRunning() const
191203QPCSCReader::QPCSCReader ( const QString &reader, QPCSC *parent )
192204 : d(new Private)
193205{
194- if (!parent->d ->lock .contains (reader))
195- parent->d ->lock [reader] = new QMutex ();
196- parent->d ->lock [reader]->lock ();
197206 d->d = parent->d ;
198207 d->reader = reader.toUtf8 ();
199208 d->state .szReader = d->reader .constData ();
@@ -202,8 +211,10 @@ QPCSCReader::QPCSCReader( const QString &reader, QPCSC *parent )
202211
203212QPCSCReader::~QPCSCReader ()
204213{
205- disconnect ();
206- d->d ->lock [d->reader ]->unlock ();
214+ if (d->isTransacted )
215+ SC (EndTransaction, d->card , SCARD_LEAVE_CARD );
216+ if (d->card )
217+ SC (Disconnect, d->card , SCARD_LEAVE_CARD );
207218 delete d;
208219}
209220
@@ -212,29 +223,14 @@ QByteArray QPCSCReader::atr() const
212223 return QByteArray::fromRawData ((const char *)d->state .rgbAtr , int (d->state .cbAtr )).toHex ().toUpper ();
213224}
214225
215- bool QPCSCReader::beginTransaction ()
216- {
217- return d->isTransacted = SC (BeginTransaction, d->card ) == SCARD_S_SUCCESS ;
218- }
219-
220226bool QPCSCReader::connect (Connect connect, Mode mode)
221227{
222228 LONG err = SC (Connect, d->d ->context , d->state .szReader , connect, mode, &d->card , &d->io .dwProtocol );
223229 updateState ();
224- return err == SCARD_S_SUCCESS ;
225- }
226-
227- void QPCSCReader::disconnect ( Reset reset )
228- {
229- if (d->isTransacted )
230- SC (EndTransaction, d->card , reset);
231- d->isTransacted = false ;
232- if ( d->card )
233- SC (Disconnect, d->card , reset);
234- d->io .dwProtocol = SCARD_PROTOCOL_UNDEFINED ;
235- d->card = {};
236- d->featuresList .clear ();
237- updateState ();
230+ if (err != SCARD_S_SUCCESS )
231+ return false ;
232+ d->isTransacted = SC (BeginTransaction, d->card ) == SCARD_S_SUCCESS ;
233+ return true ;
238234}
239235
240236bool QPCSCReader::isPinPad () const
@@ -272,7 +268,7 @@ QHash<QPCSCReader::Properties, int> QPCSCReader::properties() const
272268 int tag = *p++, len = *p++, value = 0 ;
273269 for (int i = 0 ; i < len; ++i)
274270 value |= *p++ << 8 * i;
275- properties[ Properties (tag)] = value;
271+ properties. emplace ( Properties (tag), value) ;
276272 }
277273 }
278274 return properties;
@@ -303,7 +299,7 @@ QPCSCReader::Result QPCSCReader::transfer( const QByteArray &apdu ) const
303299 case 0x6100 : // Read more
304300 {
305301 QByteArray cmd ( " \x00\xC0\x00\x00\x00 " , 5 );
306- cmd[4 ] = data. at ( int (size - 1 ) );
302+ cmd[4 ] = char (result. SW );
307303 Result result2 = transfer ( cmd );
308304 result2.data .prepend (result.data );
309305 return result2;
0 commit comments