// Tracking Functions public void Cancel() { if (this.m_hContext == IntPtr.Zero) { throw new InvalidOperationException(); } uint nErrCode = WinSCard.SCardCancel(this.m_hContext); if (nErrCode != 0) { //SCardException.RaiseWin32ResponseCode(nErrCode); } }
/// <summary> /// Wait until one of the specified status changes occur (or timeout) /// </summary> /// <param name="nTimeout"></param> /// <param name="vaSCStates"></param> /// <returns></returns> public bool GetStatusChange(int nTimeout, SCStateInfo[] vaSCStates) { int nLen = vaSCStates.Length; // Create the array for the API call WinSCard.SCARD_READERSTATE[] statearray = new WinSCard.SCARD_READERSTATE[nLen]; for (int nIter = 0; nIter < nLen; nIter++) { statearray[nIter].szReader = vaSCStates[nIter].sReaderName; statearray[nIter].pvUserData = IntPtr.Zero; statearray[nIter].dwCurrentState = (uint)vaSCStates[nIter].nCurrentState; statearray[nIter].dwEventState = (uint)SCStates.Unaware; statearray[nIter].cbAtr = 0; statearray[nIter].rgbAtr = null; } uint nErrCode = WinSCard.SCardGetStatusChange(this.m_hContext, (uint)nTimeout, statearray, (uint)statearray.Length); if (nErrCode == 0) { for (int nLoopCnt = 0; nLoopCnt < nLen; nLoopCnt++) { vaSCStates[nLoopCnt].nEventState = (SCStates)statearray[nLoopCnt].dwEventState; if ((statearray[nLoopCnt].cbAtr > 0) && (statearray[nLoopCnt].rgbAtr != null)) { vaSCStates[nLoopCnt].vbATR = new byte[statearray[nLoopCnt].cbAtr]; Buffer.BlockCopy(statearray[nLoopCnt].rgbAtr, 0, vaSCStates[nLoopCnt].vbATR, 0, (int)statearray[nLoopCnt].cbAtr); } else { vaSCStates[nLoopCnt].vbATR = null; } } return(true); } // If Timeout or SCardCancel happened just bail out if ((nErrCode == 0x8010000a) || (nErrCode == 0x80100002)) { return(false); } // If we reach here there is a problem //SCardException.RaiseWin32ResponseCode(nErrCode); throw new InvalidProgramException(); }
public SCardReaderState Status(out byte[] byteATR, out SCardReaderState eState, out SCardProtocolIdentifiers eProtocol) { if (this.m_fDisposed) { throw new ObjectDisposedException(base.GetType().FullName); } if (this.m_hCard == IntPtr.Zero) { throw new InvalidOperationException(); } StringBuilder builder1 = new StringBuilder(0x100); uint num3 = (uint)builder1.Capacity; byte[] atr = new byte[0x20]; uint num4 = (uint)atr.Length; uint dwState; uint dwProtocol; uint dwATRLength = (uint)atr.Length; uint num5 = WinSCard.SCardStatus(this.m_hCard, builder1, ref num3 /*builder1.Capacity*/, out dwState /*pdwState*/, out dwProtocol /*pdwProtocol*/, atr /*pbATR*/, ref dwATRLength /*pbcATRLen*/); if (num5 != 0) { //SmartCardException.RaiseWin32ResponseCode(num5); } eState = (SCardReaderState)dwState; eProtocol = (SCardProtocolIdentifiers)dwProtocol; if (dwATRLength > 0) { // copy only the valid portion of the ATR to the return buffer. byteATR = new byte[dwATRLength]; for (int i = 0; i < dwATRLength; i++) { byteATR[i] = atr[i]; } } else { byteATR = new byte[1]; byteATR[0] = 0;// return an invalid state. } return((SCardReaderState)dwState); }
// Database Functions /// <summary> /// List the reader groups. /// </summary> /// <param name="aReaderGroupsList">List of reader groups</param> /// <returns></returns> public int ListReaderGroups(IList aReaderGroupsList) { // Sanity Check if (this.m_fDisposed) { throw new ObjectDisposedException(base.GetType().FullName); } // Sanity Check if (this.m_hContext == IntPtr.Zero) { throw new InvalidOperationException(); } int nRet = 0; IntPtr ptrRMgrMem = IntPtr.Zero; uint nMax = uint.MaxValue; uint nErrCode = WinSCard.SCardListReaderGroups(this.m_hContext, ref ptrRMgrMem, ref nMax); // Success //if (nErrCode == 0) if (nErrCode == (uint)SCardReturnValues.SCARD_S_SUCCESS) { string text = Marshal.PtrToStringAuto(ptrRMgrMem, (int)nMax); nRet = this._SplitMultiString(text, aReaderGroupsList); nErrCode = WinSCard.SCardFreeMemory(this.m_hContext, ptrRMgrMem); return(nRet); } // Error //if (nErrCode == 2148532270) if (nErrCode == (uint)SCardReturnValues.SCARD_E_NO_READERS_AVAILABLE) { return(0); } // Exception //SCardException.RaiseWin32ResponseCode(nErrCode); return(nRet); }
/// <summary> /// Disconnect from the PCSC reader /// </summary> /// <param name="nDisposition"></param> public void Disconnect(SCardDisposition nDisposition) { if (this.m_fDisposed) { throw new ObjectDisposedException(base.GetType().FullName); } if ((this.m_hCard == IntPtr.Zero) || !this.m_fIsConnected) { throw new InvalidOperationException(); } // Terminate the connection with this SmartCard uint num1 = WinSCard.SCardDisconnect(this.m_hCard, (uint)nDisposition); this.m_hCard = IntPtr.Zero; this.m_dwActiveProtocol = 0; this.m_fIsConnected = false; //this.m_fInTransaction = false; if (num1 != 0) { //SCardException.RaiseWin32ResponseCode(num1); } }
public bool IsValidContext() { // Sanity Check if (this.m_fDisposed) { throw new ObjectDisposedException(base.GetType().FullName); } // Verify Context exists if (this.m_hContext == IntPtr.Zero) { throw new InvalidOperationException(); } // Call native fxn and return appropriately uint nErrCode = WinSCard.SCardIsValidContext(this.m_hContext); if (nErrCode == 0) { return(true); } return(false); }
/// <summary> /// Send a control code to the reader /// </summary> /// <param name="nControlCode"></param> /// <param name="vbInBuffer"></param> /// <param name="vbOutBuffer"></param> public void Control(int nControlCode, byte[] vbInBuffer, out byte[] vbOutBuffer) { if (m_fDisposed) { throw new ObjectDisposedException(GetType().FullName); } if (m_hCard == IntPtr.Zero || !m_fIsConnected) { throw new InvalidOperationException(); } byte[] bArr = new byte[65538]; uint ui1 = 0; // Send the control code using the PCSC interface to the reader uint ui2 = WinSCard.SCardControl(m_hCard, (uint)nControlCode, vbInBuffer, (uint)vbInBuffer.Length, bArr, (uint)bArr.Length, out ui1); // If the call was successful, get the response if ((int)ui2 == 0) { // Any bytes returned? if ((int)ui1 > 0) { // Get the response vbOutBuffer = new byte[ui1]; Buffer.BlockCopy(bArr, 0, vbOutBuffer, 0, (int)ui1); return; } vbOutBuffer = null; return; } // Error code //SCardException.RaiseWin32ResponseCode(ui2); throw new InvalidProgramException(); }
/// <summary> /// Connect the application to the PCSC driver /// </summary> /// <param name="sReader">The reader name</param> /// <param name="nAccessMode">Access mode (Direct, Exclusive or Shared).</param> /// <param name="nPreferredProtocols">Protocols the driver should use to communicate with the reader.</param> /// <returns>True if successfully connected, False if card removed.</returns> public bool Connect(string sReader, SCardAccessMode nAccessMode, SCardProtocolIdentifiers nPreferredProtocols) { if (this.m_fDisposed) { throw new ObjectDisposedException(base.GetType().FullName); } if (((this.m_hCard != IntPtr.Zero) || (this.Context == IntPtr.Zero)) || this.m_fIsConnected) { throw new InvalidOperationException(); } // Share mode and protocols from caller. uint num1 = (uint)nAccessMode; uint num2 = (uint)nPreferredProtocols; // Establish a connection between application and card docked in the reader. // (Gets the handle to the card and the active protocol of the connection) uint num3 = WinSCard.SCardConnect(this.Context, sReader, num1, num2, out this.m_hCard, out this.m_dwActiveProtocol); // Check error code - either successfully connected or the card was removed are ok. switch (num3) { case (uint)SCardErrorCodes.SCARD_S_SUCCESS: //case 0: this.m_fIsConnected = true; return(true); case (uint)SCardErrorCodes.SCARD_W_REMOVED_CARD: //case 0x80100069: return(false); } // Any other error codes are raised. //SCardException.RaiseWin32ResponseCode(num3); throw new InvalidProgramException(); }
/// <summary> /// List the installed readers within the given list of groups. /// </summary> /// <param name="vsGroups">List of reader groups</param> /// <param name="aReadersList">Provided list object</param> /// <returns></returns> public int ListReaders(string[] vsGroups, IList aReadersList) { // Sanity Check if (this.m_fDisposed) { throw new ObjectDisposedException(base.GetType().FullName); } // A handle to the context had to be established prior to this. // (i.e. by calling EstablishContext) if (this.m_hContext == IntPtr.Zero) { throw new InvalidOperationException(); } // Assume no readers yet int nReaders = 0; string text = null; // If a list of readers groups was provided then concatenate them // into a multi-string. If not then all reader groups will be read. if ((vsGroups != null) && (vsGroups.Length > 0)) { string[] textArray = vsGroups; for (int nIter = 0; nIter < textArray.Length; nIter++) { string strTemp = textArray[nIter]; text = text + strTemp; text = text + '\0'; } text = text + '\0'; } // NULL pointer - indicates to allocate the buffer internally. IntPtr ptrMem = IntPtr.Zero; // Autoallocate: SCARD_AUTOALLOCATE (which is -1). See Winscard.h within the DDK. uint nMax = uint.MaxValue; // List the reader names within the given groups. // // If pointer to the readers list (3rd parm) is NULL, SCardListReaders ignores the buffer length supplied // in the 4th parm, writes the length of the buffer that would have been returned if this parameter had not // been NULL to that passed in pointer, and returns a success code. // // The 4th parameter receives the actual length of the multi-string structure, including all trailing null // characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then mszReaders is converted to // a pointer to a byte pointer, and receives the address of a block of memory containing the multi-string // structure. This block of memory must be deallocated with SCardFreeMemory. uint nErrCode = WinSCard.SCardListReaders(this.m_hContext, text, ref ptrMem, ref nMax); // If the call returned OK then can interpret the results. if (nErrCode == (uint)SCardReturnValues.SCARD_S_SUCCESS) { // Marshall the list of readers to a string string sReaders = Marshal.PtrToStringAuto(ptrMem, (int)nMax); // Split the string into the ArrayList object provided by caller. nReaders = this._SplitMultiString(sReaders, aReadersList); // Free Autoallocate nErrCode = WinSCard.SCardFreeMemory(this.m_hContext, ptrMem); // Return the number of items in the ArrayList. return(nReaders); } // Not successfully read if (nErrCode == (uint)SCardReturnValues.SCARD_E_NO_READERS_AVAILABLE) { return(0); } // Report Error //SCardException.RaiseWin32ResponseCode(nErrCode); return(nReaders); }