/** * \file CardReader.h * \brief Card reader (CardReader) plugin body. This defines the class/ * variables/methods used by RE 4.0 card reader plugin API methods * to implement the card reader functionality. */ #pragma once #include "MsrCApi.h" #include "Windows.h" #include "msr3000.h" #include "SIP.h" #include "logging/RhoLog.h" #include "../shared/api_generator/MethodResult.h" #include "common/StringConverter.h" #define FOCUS_SWITCH TRUE ///< flag used to indicate action to be performed as a result of a focus switch #define NO_FOCUS_SWITCH FALSE ///< flag used to indicate action to be performed not as a result of a focus switch enum eFocusResumeAction { NONE = 0, ACTIVATE, RESUME }; #define MAX_URL 2049 ///< Maximimum allowable length of a URL in Internet Explorer /* * DUKPT defines */ #define INVALIDREADERHANDLE -4 ///< Error code - Handle to read thread is null #define CARDREADER_DATA_MAX_PANLENGTH 19 ///< Maximum length of string containing PAN #define CARDREADER_DATA_MIN_PANLENGTH 2 ///< Minimum length of string containing PAN #define CARDREADER_READ TEXT("CR") ///< Message code indicating data is card reader read data #define DEBITCARDREADER_ENC TEXT("ENCDATA") ///< Message code indicating data is extracted PIN value #define CARDREADER_MSG TEXT("MESSAGE") ///< Message code indicating data is error message #define DEBITCARDREADER_PAN TEXT("PAN") ///< Message code indicating data is encrypted PAN #define PIN_ENTRY_ON TEXT("TRUE") ///< Metatag pinentry value to enable pin entry #define PIN_ENTRY_OFF TEXT("FALSE") ///< Metatag pinentry value to disable pin entry #define DCR_TEXT TEXT("DCR") ///< String that GetVersion supplies, indicating h/w is a DCR #define MSR_TEXT TEXT("MSR") ///< String that GetVersion supplies, indicating h/w is an MSR #define MAX_DRIVER_LEN 50 ///< Maximum length of string containing card reader driver dll name #define MAX_DEVICE_LEN 50 ///< Maximum length of string containing card reader device name /* * Typedefs for dynamic pointers to card reader driver functions */ /** * Template for pointer to driver function that loads and initializes the specified card reader driver. * Access to the card reader hardware is provided through the specified communications port. * A handle to the card reader reader is returned for use in subsequent calls to the card reader API. * \param lpszDeviceName Name of hardware specific magstripe reader dll to open * \param lpszPortName COM Port used by the magstripe reader * \param lphReader Handle to magnetic stripe reader for subsequent operations */ typedef RET_STATUS (*LPOPEN)(LPCTSTR lpszDeviceName, LPCTSTR lpszPortName, LPHANDLE lphReader); /** * Template for pointer to driver function that closes the communication port and disables the MSR. * \param lphReader Handle of open reader. */ typedef RET_STATUS (*LPCLOSE)(HANDLE lphReader); /** * Template for pointer to driver function that requests card data information from the MSR. * \param hReader Handle of open reader. * \param lpszDataBuffer Pointer to data buffer that will contain MSR data (This parameter must be at least 512 bytes in size). * \param dwTimeout Size of the buffer. This parameter is currently not being used. */ typedef RET_STATUS (*LPREADMSRUNBUFFER)(HANDLE hReader, LPCTSTR lpszDataBuffer, DWORD dwTimeout); /** * Template for pointer to driver function that finds the first available MSR DLL and creates * a find handle for use by MSR_FindNext. * \param lpMsrFindInfo Pointer to MSR_FINDINFO structure to be filled in with information about the first available MSR DLL. Information provided by this structure is used to open an MSR with MSR_Open. * \param lphFindHandle Pointer to a new find handle to be used by MSR_FindNext to continue the search. The handle must be closed by MSR_FindClose when done. */ typedef RET_STATUS (*LPFINDFIRST)(LPMSR_FINDINFO lpMsrFindInfo, LPHANDLE lphFindHandle); /** * Template for pointer to driver function that finds the next available MSR DLL in the search * specified by hFindHandle. * \param lpMsrFindInfo Pointer to MSR_FINDINFO structure to be filled in with information about the next available MSR DLL. Information provided by this structure is used to open an MSR with MSR_Open. * \param hFindHandle Find handle created by a call to MSR_FindFirst */ typedef RET_STATUS (*LPFINDNEXT) (LPMSR_FINDINFO lpMsrFindInfo, HANDLE hFindHandle); /** * Template for pointer to driver function that closes the find handle created by MSR_FINDINFO. * \param hFindHandle Find handle created by a call to MSR_FindFirst */ typedef RET_STATUS (*LPFINDCLOSE)(HANDLE hFindHandle); /** * Template for pointer to driver function that is used to obtain a PIN (Personal Identification Number) * from the user. It first prompts the user to enter their PIN number. It then creates and returns an * EPB (Encrypted PIN Block), which is a combination of the entered PIN and the PAN (Personal Account Number) * that was obtained from reading the Magnetic card. * \param hReader Handle of open reader * \param lpszPANDataBuffer Full PAN from card reader swipe in ASCII null-terminated char string * \param Encryption_Format Encryption format to be used. Currently only the value ISO-0 format is supported. * \param Wait_Time Timeout in milliseconds * \param ubszEncryptedKSNECPAN Pointer to encrypted PAN data returned by DCR */ typedef RET_STATUS (*LPGETPINBLOCK)(HANDLE hReader, LPCTSTR lpszPANDataBuffer, UBYTE Encryption_Format, UHWORD Wait_Time, UBYTE* ubszEncryptedKSNECPAN); /** * Template for pointer to driver function that cancels any pending MSR read request. * \param hFindHandle */ typedef RET_STATUS (*LPFLUSH)(HANDLE hFindHandle); /** * Template for pointer to driver function that gets MSR hardware and driver version info. * \param hFindHandle */ typedef RET_STATUS (*LPGETVERSION)(HANDLE hReader, LPMSR_VERSIONINFO lpMsrVerInfo); /* * Standard DLL function names */ #define FUNC_NAME_OPEN TEXT("MSR_Open") ///< DLL function that loads and initializes the specified MSR DLL. #define FUNC_NAME_CLOSE TEXT("MSR_Close") ///< DLL function that closes the communication port and disables the MSR. #define FUNC_NAME_READMSRUNBUFFER TEXT("MSR_ReadUnbuffer") ///< DLL function that requests card data information from the MSR. #define FUNC_NAME_FINDFIRST TEXT("MSR_FindFirst") ///< DLL function that finds the first available MSR DLL and creates a find handle for use by MSR_FindNext #define FUNC_NAME_FINDNEXT TEXT("MSR_FindNext") ///< DLL function that finds the next available MSR DLL. #define FUNC_NAME_FINDCLOSE TEXT("MSR_FindClose") ///< DLL function that closes handle used between MSR_FindFirst and MSR_FindNext #define FUNC_NAME_GETPINBLOCK TEXT("MSR_GetPINBlock") ///< DLL function that is used to obtain a PIN (Personal Identification Number) from the user #define FUNC_NAME_FLUSH TEXT("MSR_Flush") ///< DLL function that cancels any pending MSR read request #define FUNC_NAME_GETVERSION TEXT("MSR_GetVersion") ///< DLL function that cancels any pending MSR read request #define DEFAULT_DLL_NAME TEXT("MsrAPI32.dll") ///< Default DLL name to use #define MAX_DLLS 10 ///< Limit to the number of MSR DLL's that will be searched for in the DLL file #define READ_THREAD_TIMEOUT 2000 ///< Max number of milliseconds to wait for read thread to terminate after issuing a stop #define DEFAULT_PIN_ENTRY_TIMEOUT 30000 ///< Default value of pin entry timeout #define DEFAULT_PIN_ENTRY_TIMEOUT_S TEXT("30000") ///< Default value of pin entry timeout - string form /** * CCardReader is the class responsible for maintaining the state of the * card reader (CR), providing access methods for setting up the card reader * driver and generally operating the card reader. */ class CCardReader { public: /** * CardReader-specific actions to be taken upon "Preloading" of the device. * essentially initializing the CardReader object, loading * the card reader DLL and setting object's method pointers to the DLL proper functions * \param pMod pointer to the parent Module that manages all device instances * \param iID id of the app to which this instance belongs * \param hWnd handle to the window of the app to which this instance belongs */ CCardReader(int iID); /** * CardReader-specific actions to be taken upon "Disposing" of the device, * including stopping the read thread, deinitializing the object * referring to the CardReader object, and unloading the CardReader DLL. */ ~CCardReader(); /** * Steps through all of the card reader drivers in the DLL and finds the one * that successfully opens with the attached device. * \param bFocusSwitch flag indicating whether this method is being invoked as a result of a change in focus * \return 0 if successful in opening card reader driver and all card reader-related method pointers are non-zero * \return Non-zero if unsuccessful in opening card reader driver or any card reader-related method pointers are 0 */ DWORD OpenTheCardReader(BOOL bFocusSwitch); /** * \param lpParam pointer to object holding state of device to which this thread belongs * \return 0 if thread to terminate normally * \return 1 if error in reading card reader read buffer */ static DWORD WINAPI CardReaderReadThread (LPVOID lpParam); /** * Stops the card reader by telling the read thread to terminate, closing the card reader driver, and * clearing the thread pointer and handle. Terminates the read thread if it does not * terminate on its own. * \param bFocusSwitch flag indicating whether this method is being invoked as a result of a change in focus */ void StopTheCardReader(BOOL bFocusSwitch); /** * Under test conditions (PLUGINTESTER_DEBUG defined) prints this data * to the console in a message box * \param bPinEntry m_bPinEntry flag of the calling app * \param iID id of the calling app * \param lpszBuffer data to be sent to core * \param lpszMessageType flag indicating nature of message to send to the core */ void CardReaderMessage(int iID, LPTSTR lpszBuffer, LPTSTR lpszMessageType); /** * Get the value of the attribute m_bCardReaderHasBeenOpened * \return value of the attribute m_bCardReaderHasBeenOpened */ BOOL GetCardReaderHasBeenOpened(); /** * Get the value of the attribute m_hThreadRead * \return value of the attribute m_hThreadRead */ HANDLE GetThreadReadHandle(); /** * Set the value of the attribute m_hThreadRead * \param hHandle value with which to set m_hThreadRead */ void SetThreadReadHandle(HANDLE hHandle); /** * Set the value of the attribute m_bAutoTab. If the new value is invalid, * leave the value unchanged. * \param lpszValue value with which to set m_bAutoTab * \return TRUE if the new value is valid * \return FALSE otherwise */ BOOL SetAutoTab(LPCTSTR lpszValue); /** * Set the value of the attribute m_bAutoEnter. If the new value is invalid, * leave the value unchanged. * \param lpszValue value with which to set m_bAutoEnter * \return TRUE if the new value is valid * \return FALSE otherwise */ BOOL SetAutoEnter(LPCTSTR lpszValue); /** * Gets the attribute m_bAutoEnter * \lParam lpszValue value of m_bAutoEnter * \return TRUE always */ BOOL GetAutoEnter(LPTSTR lpszValue); /** * Gets the attribute m_bAutoTab * \lParam lpszValue value of m_bAutoTab * \return TRUE always */ BOOL GetAutoTab(LPTSTR lpszValue); /***********************************************************************/ /********************** DebitCardReader Support ************************/ /***********************************************************************/ /** * Parses the card data and picks out the PAN (personal account number) Data * \param lpszCardData data read from card * \param lpszPANData PAN data extracted from card data * \return TRUE if able to successfully parse lpSzCardData and put results in lpSzPANData * \return FALSE otherwise */ BOOL retPANData(LPCTSTR lpszCardData, LPTSTR lpszPANData); /** * Submits the card reader PAN data to the card reader to produce an encrypted string for server * \param lpszPANData PAN data to encrypt * \return 1 if able to successfully encrypt card reader PAN data * \return 0 otherwise */ DWORD PinTransactionDebitCardReader(LPCTSTR lpszPANData); /** * \return TRUE if the new value is valid and DCR functionality is enabled * \return FALSE otherwise */ BOOL ManualPANEntry(LPCTSTR lpszPAN); /** * Retrieves the manual pan Data * \param lpszPAN - returns the pan Data * \return TRUE if the value is valid */ BOOL GetManualPANEntry(LPTSTR lpszPAN); /** * Sets the m_Wait_Time variable which indicates the timeout limit when encrypting the * PAN data by the DebitCardReader. If the new value is invalid, * leave the value unchanged. * \param lpszMilliStr PIN timeout duration in milliseconds * \return TRUE if the new value is valid and DCR functionality is enabled * \return FALSE otherwise */ BOOL SetPinTimeout(LPCTSTR lpszMilliStr); /** * Sets the m_bPinEntry variable which indicates whether PIN entry is enabled or not. * If the new value is invalid, leave the value unchanged. * \param lpszSW if szSW has value PIN_ENTRY_ON, then enable PIN entry, else disable * \return TRUE if the new value is valid and DCR functions have been successfully loaded * \return FALSE otherwise */ BOOL SetPinEntry(LPCTSTR lpszSW); /** * Gets the m_Wait_Time variable which indicates the timeout limit when encrypting the * PAN data by the DebitCardReader. * \param lpszMilliStr PIN timeout duration in milliseconds * \return TRUE if the value is valid and DCR functionality is enabled * \return FALSE otherwise */ int GetPinTimeout(LPTSTR lpszMilliStr); /** * Gets the m_bPinEntry variable which indicates whether PIN entry is enabled or not. * \param lpszSW if szSW has value PIN_ENTRY_ON, then enable PIN entry, else disable * \return TRUE if the value is valid and DCR functions have been successfully loaded * \return FALSE otherwise */ int GetPinEntry(LPTSTR lpszSW); /** * Sets the m_bDCR variable which indicates whether device is a DCR or not. * \param bValue value used to set m_bDCR flag */ void SetDCR(BOOL bValue); /** * Sets the m_lpszDriverName variable which holds the name of the base level * MSR/DCR driver dll file to be used in opening the card reader * If lpszModuleName is not a recognized module name, m_lpszDriverName is left * unchanged. * \param lpszModuleName name of the card reader module (device) * \return TRUE if the new value is valid and the name has been successfully set * \return FALSE otherwise */ BOOL SetDriverName(LPCTSTR lpszModuleName); /** * Gets the m_lpszDriverName variable which holds the name of the base level * MSR/DCR driver dll file to be used in opening the card reader * \param lpszModuleName name of the card reader module (device) * \return TRUE if the value is valid and the name has been successfully set * \return FALSE otherwise */ BOOL GetDriverName(LPTSTR lpszModuleName); /** * Get the value of the attribute m_hStopEvent * \return value of the attribute m_hStopEvent */ HANDLE GetStopEventHandle(); /** * Get the value of the attribute m_hKeypadMutex * \return value of the attribute m_hKeypadMutex */ HANDLE GetKeypadMutexHandle(); /** * Set the value of the attribute m_hStopEvent */ void SetStopEventHandle(HANDLE h); /** * Set the value of the attribute m_hKeypadMutex */ void SetKeypadMutexHandle(HANDLE h); /** * Initializes the card reader object with the instance ID */ BOOL Initialise(bool bLaunchingAppHasFocus, const WCHAR* szID); /** * Sets a property or a method of the card reader module */ BOOL SetPropertyOrMethod(LPCTSTR szPropertyName, LPCTSTR szPropertyValue); /** * Retrieves a property of the card reader module */ BOOL RetrieveProperty(LPCTSTR szParameterName, WCHAR* szParameterValue); /** * Retrieves all the properties of the card reader module */ void RetrieveAllProperties(rho::apiGenerator::CMethodResult* pCallback); /** * Before we navigate to a different page */ BOOL BeforeNavigate(); /** * Sets the callback function for swipe event */ void SetCallback(rho::apiGenerator::CMethodResult* pCallback); /** * An Application focus change is received when this card reader instance either * goes to the background (bActivated False) or comes to the foreground (bActivated True). */ BOOL ApplicationFocusChange(bool bActivated); /** * On Document Complete implementation */ BOOL DocumentComplete(); /** * Clears all properties */ BOOL ClearAllProperties(); BOOL m_bDllPresent; ///