getStatusChange method
Tuple2<SCardResult, List<SCardReaderState> >
getStatusChange(
- int hContext,
- int dwTimeout,
- List<
SCardReaderState> rgReaderStates
override
Implementation
@override
Tuple2<SCardResult, List<SCardReaderState>> getStatusChange(int hContext, int dwTimeout, List<SCardReaderState> rgReaderStates) {
// Define the maximum size of the ATR buffer.
final atrBufferSize = MAX_ATR_SIZE;
// Create a list of native string pointers for each reader name.
final List<ffi.Pointer<ffi.Char>> nativeReaderNames = rgReaderStates.map((state) => _allocateNativeString(state.szReader)).toList();
// Allocate memory for an array of SCARD_READERSTATE structures.
final nativeReaderStates = calloc<SCARD_READERSTATE>(rgReaderStates.length);
try {
// Copy each Dart reader state into its native counterpart.
for (int i = 0; i < rgReaderStates.length; i++) {
final state = rgReaderStates[i];
nativeReaderStates[i].szReader = nativeReaderNames[i];
nativeReaderStates[i].pvUserData = ffi.nullptr;
nativeReaderStates[i].dwCurrentState = state.dwCurrentState;
nativeReaderStates[i].dwEventState = 0;
nativeReaderStates[i].cbAtr = atrBufferSize;
// Copy any initial ATR bytes if provided (up to the available length and buffer size).
for (int j = 0; j < state.rgbAtr.length && j < atrBufferSize; j++) {
nativeReaderStates[i].rgbAtr[j] = state.rgbAtr[j];
}
}
// Call the native SCardGetStatusChange() function.
// This call will block until a reader event occurs or the timeout expires.
final response = _winscard.SCardGetStatusChange( hContext, dwTimeout, nativeReaderStates, rgReaderStates.length );
final result = SCardResult(response);
// If the call failed, return immediately with an empty state list.
if (!result.isSuccess) {
return Tuple2(result, []);
}
// Build the updated list of SCardReaderState objects based on the native structure values.
List<SCardReaderState> updatedStates = [];
for (int i = 0; i < rgReaderStates.length; i++) {
// The native structure's cbAtr should now contain the actual ATR length.
final int actualAtrLength = nativeReaderStates[i].cbAtr;
List<int> atrBytes = [];
// Copy only the valid ATR bytes.
for (int j = 0; j < actualAtrLength && j < atrBufferSize; j++) {
atrBytes.add(nativeReaderStates[i].rgbAtr[j]);
}
// Convert the native reader name back into a Dart string.
final readerName = _convertNativeString(nativeReaderStates[i].szReader);
// Create a new SCardReaderState with updated values from the native structure.
updatedStates.add( SCardReaderState( readerName, nativeReaderStates[i].dwCurrentState, nativeReaderStates[i].dwEventState, atrBytes ));
}
// Return the result code along with the updated list of reader states.
return Tuple2(result, updatedStates);
}
finally {
// Free each native string allocated for the reader names.
for (final ptr in nativeReaderNames) {
calloc.free(ptr);
}
// Free the allocated array of SCARD_READERSTATE.
calloc.free(nativeReaderStates);
}
}