2727#include < array>
2828#include < cstring>
2929
30- Q_LOGGING_CATEGORY (APDU," QPCSC.APDU" )
31- Q_LOGGING_CATEGORY(SCard," QPCSC.SCard" )
30+ static Q_LOGGING_CATEGORY (APDU," QPCSC.APDU" )
31+ static Q_LOGGING_CATEGORY(SCard," QPCSC.SCard" )
3232
3333static quint16 toUInt16(const QByteArray &data, int size)
3434{
@@ -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 changed ();
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 ();
@@ -203,7 +212,6 @@ QPCSCReader::QPCSCReader( const QString &reader, QPCSC *parent )
203212QPCSCReader::~QPCSCReader ()
204213{
205214 disconnect ();
206- d->d ->lock [d->reader ]->unlock ();
207215 delete d;
208216}
209217
@@ -218,21 +226,16 @@ bool QPCSCReader::beginTransaction()
218226}
219227
220228bool QPCSCReader::connect (Connect connect, Mode mode)
221- {
222- return connectEx (connect, mode) == SCARD_S_SUCCESS;
223- }
224-
225- quint32 QPCSCReader::connectEx (Connect connect, Mode mode)
226229{
227230 LONG err = SC (Connect, d->d ->context , d->state .szReader , connect, mode, &d->card , &d->io .dwProtocol );
228231 updateState ();
229- return quint32 ( err) ;
232+ return err == SCARD_S_SUCCESS ;
230233}
231234
232235void QPCSCReader::disconnect ( Reset reset )
233236{
234- if (d->isTransacted )
235- endTransaction () ;
237+ if (d->isTransacted && SC (EndTransaction, d-> card , Reset::LeaveCard) == SCARD_S_SUCCESS )
238+ d-> isTransacted = false ;
236239 if ( d->card )
237240 SC (Disconnect, d->card , reset);
238241 d->io .dwProtocol = SCARD_PROTOCOL_UNDEFINED;
@@ -241,14 +244,6 @@ void QPCSCReader::disconnect( Reset reset )
241244 updateState ();
242245}
243246
244- bool QPCSCReader::endTransaction ( Reset reset )
245- {
246- bool result = SC (EndTransaction, d->card , reset) == SCARD_S_SUCCESS;
247- if (result)
248- d->isTransacted = false ;
249- return result;
250- }
251-
252247bool QPCSCReader::isPinPad () const
253248{
254249 if (d->reader .contains (" HID Global OMNIKEY 3x21 Smart Card Reader" ) ||
@@ -290,15 +285,6 @@ QHash<QPCSCReader::Properties, int> QPCSCReader::properties() const
290285 return properties;
291286}
292287
293- bool QPCSCReader::reconnect ( Reset reset, Mode mode )
294- {
295- if ( !d->card )
296- return false ;
297- LONG err = SC (Reconnect, d->card , DWORD (SCARD_SHARE_SHARED), mode, reset, &d->io .dwProtocol );
298- updateState ();
299- return err == SCARD_S_SUCCESS;
300- }
301-
302288QStringList QPCSCReader::state () const
303289{
304290 return stateToString (d->state .dwEventState );
0 commit comments