2011-11-23 40 views
1

我想傾聽插入和刪除智能購物車的事件...該應用程序是爲Windows和智能卡使用x.509證書。我使用的讀者是插在大多數新的筆記本電腦,你也可以買給USB使用標準的讀卡器..如何在C++中偵聽智能卡插入和刪除事件?

有一件事我發現是: cryptware.it/apidoc/scapi/index.html 但它不能成爲唯一的方式,我只是想知道我的選擇...

有誰知道什麼是最好的方法來做到這一點?

在此先感謝!

+2

我們在這裏談論哪種平臺,設備,驅動程序和操作系統? – PeterT

+0

我的不好...我現在編輯了這個問題 – Alioooop

+1

[你有什麼嘗試?](http://mattgemmell.com/2008/12/08/what-have-you-tried/) –

回答

3

在Windows API具有這樣的功能:

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

然後,您可以檢查rgReaderStates包含SCARD_STATE_EMPTYSCARD_STATE_PRESENT。在此處閱讀詳細信息:MSDN description

嚴格來說,它不是事件驅動的,但會阻止執行,直到發生更改。所以通過創建一個單獨的線程來調用這個循環,您可以輕鬆地自行生成一個事件。

+0

謝謝我會研究這個! – Alioooop

+0

由於某種原因,這個函數不會對我的類型卡做出反應......它找到合適的讀卡器,但它不會對任何狀態變化做出反應......我也在c#.net中嘗試過構建示例項目,出於某種原因它也發現讀卡器,但它不會對任何事件做出反應... – Alioooop

+0

@Alioooop我想你可能在你的測試代碼中有一個錯誤,因爲java實現除了調用這個方法外沒有別的,就像你在[Java-Source]中看到的那樣。 (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/security/smartcardio/TerminalImpl.java#TerminalImpl.waitForCard%28boolean%2Clong%29)。您是否正確填寫了'LPSCARD_READERSTATE'並提供了'dwCurrentState'值,也許嘗試將其設置爲'SCARD_STATE_UNAWARE'來輪詢當前狀態,在這種情況下應該立即返回。 – PeterT

0

一個例子。

這應該包含在以一個時間間隔(1秒)運行此函數的線程函數中。線程函數應該使用此函數並向驅動程序已更改的應用程序發送通知。

警告:UGLY CODE。請以此爲例,並在您看到適合度時加以改進。

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; 
} 
+0

謝謝爲你的努力。如果我想讓自己的線程循環,我已經解決了這個問題,因爲我已經創建了一個函數來檢查是否插入了正確類型的智能卡:)但是我想要一個發送某種事件的解決方案所以我可以聽它,而不是隻是循環和檢查... – Alioooop

+0

@Alioooop:現在* *將是有用的信息,包括在你的問題。 –

相關問題