简体   繁体   中英

How do I listen for smart card insert and remove event in C++?

I want to listen for the insert and remove event of a smart cart... The application is for windows and the smart card is using x.509 certificates. The reader I use is standard card readers that is inserted in most new laptops and you can also buy them for usb use..

One thing I have found is: cryptware.it/apidoc/scapi/index.html but it cant be the only way and I just wanted to know my options...

Does anyone know what's the best way to do this?

Thanks in advance!

The Windows API has this function:

LONG WINAPI SCardGetStatusChange(
  __in     SCARDCONTEXT hContext,
  __in     DWORD dwTimeout,
  __inout  LPSCARD_READERSTATE rgReaderStates,
  __in     DWORD cReaders
);

You can then check if the rgReaderStates contains SCARD_STATE_EMPTY or SCARD_STATE_PRESENT . Read the details here: MSDN description

It is strictly speaking not event-driven but it blocks execution until a change happened. So by creating a separate thread that calls this in a loop, you can easily generate an event yourself.

A example.

This should be incorporated in thread function which runs this function at a time interval (1 second). The thread function should use this and sends a notification to the application that the driver has changed.

WARNING: UGLY CODE. PLEASE USE THIS AS AN EXAMPLE AND IMPROVE IT AS YOU SEE FIT.

BOOL CheckDirProperties(const CString& path, BOOL& bReadOnly, BOOL& bRemovable)
{
    DWORD   FileAttributes;
    DWORD   DriveAttributes;
    UINT    uDriveType;

    if( path.GetLength() < 2 ||path.GetAt( 1 ) != ':' )
    {
        // invalid path, abort
        return FALSE;
    }
//Ugly path handling

    CString szFormattedDrivePath("C:\\"); // string of length 3 where drive letter will be replaced
// Replace the drive letter with the drive letter from the path
    szFormattedDrivePath.SetAt( 0, path.GetAt( 0 ) ); 

    DriveAttributes = GetFileAttributes( szFormattedDrivePath );
    FileAttributes  = GetFileAttributes( path);
    uDriveType      = GetDriveType( szFormattedDrivePath );

    if( !(FileAttributes  & FILE_ATTRIBUTE_DIRECTORY) || 
        !(DriveAttributes & FILE_ATTRIBUTE_DIRECTORY) )
    {   // Not a directory
        return FALSE;
    }

    if( (FileAttributes  & FILE_ATTRIBUTE_ARCHIVE) || 
        (DriveAttributes & FILE_ATTRIBUTE_ARCHIVE) ||
        (FileAttributes  & FILE_ATTRIBUTE_ENCRYPTED) || 
        (DriveAttributes & FILE_ATTRIBUTE_ENCRYPTED) ||
        (FileAttributes  & FILE_ATTRIBUTE_OFFLINE) || 
        (DriveAttributes & FILE_ATTRIBUTE_OFFLINE) ||
        (FileAttributes  & FILE_ATTRIBUTE_OFFLINE) || 
        (DriveAttributes & FILE_ATTRIBUTE_OFFLINE) )
    {   // Not a directory
        TRACE("The directory %s on drive %s has unexpected file attributes. Problems may occur.\n",path, szFormattedDrivePath );
    }   

    // To set m_bReadOnly to true, we need to know that the entire subtree is readonly.
    // Even if the drive or the directory has the FILE_ATTRIBUTE_READONLY set, the content may not be read-only.
    // Therefore the default value of bReadOnly must be FALSE.
    bReadOnly    = FALSE;

    switch( uDriveType )
    {
        case DRIVE_FIXED: 
        case DRIVE_REMOTE:
            bRemovable = FALSE;
            break;
        case DRIVE_CDROM:
            bRemovable = TRUE;
            bReadOnly    = TRUE; // We know that a CD-ROM drive is always read-only
            break;
        case DRIVE_REMOVABLE: 
        case DRIVE_RAMDISK:
            bRemovable = TRUE;
            break;
        case DRIVE_NO_ROOT_DIR: // fall through
        case DRIVE_UNKNOWN:     // fall through
        default:
            bRemovable = TRUE; // assume it is removable if we don't know what value to set
            break;
    }

    return TRUE;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM