smartcard 3.7.1 → 3.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/reader_monitor.cpp +32 -14
package/package.json
CHANGED
package/src/reader_monitor.cpp
CHANGED
|
@@ -245,39 +245,57 @@ void ReaderMonitor::MonitorLoop() {
|
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
if (result == SCARD_E_TIMEOUT) {
|
|
248
|
-
// Timeout -
|
|
249
|
-
// Windows
|
|
248
|
+
// Timeout - query fresh state to detect missed events (Issue #111)
|
|
249
|
+
// On Windows, dwEventState after timeout may just mirror dwCurrentState
|
|
250
|
+
// rather than reflecting actual hardware state. We must explicitly
|
|
251
|
+
// query with SCARD_STATE_UNAWARE to get the real current state.
|
|
250
252
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
251
253
|
|
|
252
|
-
|
|
253
|
-
if (states.size() <= 1) {
|
|
254
|
+
if (readerStates_.empty()) {
|
|
254
255
|
continue;
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
|
|
258
|
-
|
|
258
|
+
// Build fresh state query for all readers
|
|
259
|
+
std::vector<SCARD_READERSTATE> freshStates;
|
|
260
|
+
std::vector<std::string> freshNames;
|
|
261
|
+
|
|
262
|
+
for (const auto& pair : readerStates_) {
|
|
263
|
+
freshNames.push_back(pair.first);
|
|
264
|
+
SCARD_READERSTATE state = {};
|
|
265
|
+
state.szReader = freshNames.back().c_str();
|
|
266
|
+
state.dwCurrentState = SCARD_STATE_UNAWARE;
|
|
267
|
+
freshStates.push_back(state);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
LONG freshResult = SCardGetStatusChange(context_, 0, freshStates.data(), freshStates.size());
|
|
271
|
+
if (freshResult != SCARD_S_SUCCESS) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
for (size_t i = 0; i < freshStates.size(); i++) {
|
|
276
|
+
const std::string& name = freshNames[i];
|
|
259
277
|
auto it = readerStates_.find(name);
|
|
260
278
|
if (it != readerStates_.end()) {
|
|
261
|
-
DWORD
|
|
279
|
+
DWORD freshState = freshStates[i].dwEventState & ~SCARD_STATE_CHANGED;
|
|
262
280
|
DWORD storedState = it->second.lastState;
|
|
263
281
|
|
|
264
282
|
bool wasPresent = (storedState & SCARD_STATE_PRESENT) != 0;
|
|
265
|
-
bool isPresent = (
|
|
283
|
+
bool isPresent = (freshState & SCARD_STATE_PRESENT) != 0;
|
|
266
284
|
|
|
267
|
-
// If the PRESENT flag differs, we missed an event
|
|
268
285
|
if (wasPresent != isPresent) {
|
|
269
286
|
std::vector<uint8_t> atr;
|
|
270
|
-
if (
|
|
271
|
-
atr.assign(
|
|
287
|
+
if (freshStates[i].cbAtr > 0) {
|
|
288
|
+
atr.assign(freshStates[i].rgbAtr,
|
|
289
|
+
freshStates[i].rgbAtr + freshStates[i].cbAtr);
|
|
272
290
|
}
|
|
273
291
|
|
|
274
|
-
it->second.lastState =
|
|
292
|
+
it->second.lastState = freshState;
|
|
275
293
|
it->second.atr = atr;
|
|
276
294
|
|
|
277
295
|
if (isPresent) {
|
|
278
|
-
EmitEvent("card-inserted", name,
|
|
296
|
+
EmitEvent("card-inserted", name, freshState, atr);
|
|
279
297
|
} else {
|
|
280
|
-
EmitEvent("card-removed", name,
|
|
298
|
+
EmitEvent("card-removed", name, freshState, {});
|
|
281
299
|
}
|
|
282
300
|
}
|
|
283
301
|
}
|