2023_09_macOS_Sonoma_bug_SCardControl.c (Source)

//
//  main.c
//  scardcontrol
//
//  Created by Ludovic Rousseau on 28/07/2023.
//
#include <stdio.h>
#include <stdlib.h>
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#define SCARD_CTL_CODE(code) (0x42000000 + (code))
#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
#define PCSC_ERROR_EXIT(rv, text) \
if (rv != SCARD_S_SUCCESS) \
{ \
printf(text ": %s (0x%8X)\n", pcsc_stringify_error(rv), rv); \
goto end; \
} \
else \
printf(text ": OK\n");
int main(int argc, const char * argv[]) {
LONG rv;
SCARDCONTEXT hContext;
DWORD dwReaders;
LPSTR mszReaders = NULL;
SCARDHANDLE hCard;
unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
DWORD length;
DWORD dwActiveProtocol;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
if (rv != SCARD_S_SUCCESS)
{
printf("SCardEstablishContext: Cannot Connect to Resource Manager %s\n", pcsc_stringify_error(rv));
return 1;
}
/* Retrieve the available readers list */
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
PCSC_ERROR_EXIT(rv, "SCardListReaders")
mszReaders = malloc(sizeof(char)*dwReaders);
if (mszReaders == NULL)
{
printf("malloc: not enough memory\n");
goto end;
}
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
if (rv != SCARD_S_SUCCESS)
printf("SCardListReader: %8X\n", rv);
/* connect to a reader (even without a card) */
dwActiveProtocol = -1;
printf("Using reader: %s\n", mszReaders);
rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_DIRECT,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
PCSC_ERROR_EXIT(rv, "SCardConnect")
/* get features */
rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
bRecvBuffer, sizeof(bRecvBuffer), &length);
PCSC_ERROR_EXIT(rv, "SCardControl")
printf("Received buffer (%d bytes)\n", length);
for (int i=0; i<length; i++)
printf("%02X ", bRecvBuffer[i]);
printf("\n");
/* disconnect */
rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
PCSC_ERROR_EXIT(rv, "SCardDisconnect")
end:
/* We try to leave things as clean as possible */
rv = SCardReleaseContext(hContext);
if (rv != SCARD_S_SUCCESS)
printf("SCardReleaseContext: %s (0x%8X)\n", pcsc_stringify_error(rv),
rv);
/* free allocated memory */
if (mszReaders)
free(mszReaders);
return 0;
}