[Pcsclite-muscle] A recent change causes SCardCancel() to block?

Ran Benita ran234
Wed Jun 14 02:43:46 PDT 2017


Hello,

I have noticed a change in behavior in one of the recent pcsclite
releases. I am using pcsclite 1.8.21 and ccid 1.4.27 on ArchLinux.

The program below calls a blocking SCardGetStatusChange, but before that
spwans a thread which waits for a key press, then calls SCardCancel (on
the same context). It is a port of the Rust program here:
https://raw.githubusercontent.com/bluetech/pcsc-rust/01bd4d80e366ef00f7006dabee45c8cb356d8566/pcsc/examples/cancel.rs

Previously, the SCardCancel would return immediately and would cause
SCardGetStatusChange to return SCARD_E_CANCELLED immediately.

Now, SCardCancel blocks until SCardGetStatusChange times out, and only
then returns SCARD_S_SUCCESS.

Is this an intended change, or a regression? Or maybe I'm doing
something wrong?

Thanks,
Ran

// gcc -Wall -pthread $(pkg-config --libs --cflags libpcsclite) cancel.c -o cancel
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>

#include <PCSC/winscard.h>

static SCARDCONTEXT context;

static void *canceler_thread(void *arg) {
    LONG ret;

    getchar();

    printf("Calling SCardCancel...\n");
    ret = SCardCancel(context);
    assert(ret == SCARD_S_SUCCESS);
    printf("SCardCancel returned SCARD_S_SUCCESS\n");

    return NULL;
}

int main(void) {
    LONG ret;

    ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &context);
    assert(ret == SCARD_S_SUCCESS);

    // Spawn a thread which waits for a key-press then cancels the operation.
    pthread_t thread;
    ret = pthread_create(&thread, NULL, canceler_thread, NULL);

    // Set up the blocking call, and wait for cancel or timeout.
    printf("Entering blocking call; press Enter to cancel\n");
    SCARD_READERSTATE reader_states[] = {
        {
            .szReader = "\\\\?PnP?\\Notification",
            .pvUserData = NULL,
            .dwCurrentState = SCARD_STATE_UNAWARE,
            .dwEventState = SCARD_STATE_UNAWARE,
        },
    };

    ret = SCardGetStatusChange(context, 5000, reader_states, 1);
    switch (ret) {
    case SCARD_S_SUCCESS:
        printf("Blocking call exited normally\n");
        break;

    case SCARD_E_CANCELLED:
        printf("Blocking call canceled\n");
        break;

    case SCARD_E_TIMEOUT:
        printf("Blocking call timed out\n");
        break;

    default:
        fprintf(stderr, "Failed to get status changes: %ld", ret);
        break;
    }

    printf("Sleeping before existing main thread...\n");
    sleep(5);

    return 0;
}




More information about the pcsclite-muscle mailing list