Posted by: Irfan Raza | October 23, 2008

XFS & its Applications

Background

With the extensive growth in the financial industry especially in United States and Europe in the early 90’s, an immediate need was felt for an industry wide platform to standardize the development of the financial systems. Microsoft at that time was the first one to realize this necessity and founded “Banking Solutions Vendor Council” in 1991 which comprises of leading vendors of Information technology of the financial Industry. Based on the windows platform using “Windows Open service Architecture” the very first version of the Financial Systems development Framework was introduced as “Extension for Financial Services” or WOSA/XFS. The very first version of XFS was released in 1995   followed by XFS 2.0 in 1997. We are using XFS 3.10 at the moment in 2008.

 

XFS was a revolution and a major success in the financial industry which leads to its adoption by CEN (European committee for standardization) as an international standard in 1998 and was named as CEN/XFS.

 

Definitions

Wikipedia defines CEN/XFS as “CEN/XFS or XFS provides client-server architecture for financial applications on the Microsoft Windows platform, especially peripheral devices such as EFTPOS terminals and ATMs which are unique to the financial industry”.

I as a developer of the XFS will define it in simpler manner as “An SP (Service provider) independent windows based set of APIs for communication with peripheral devices like EFTPOS and ATMs”.

 

You can make your system XFS compliant by following the following three conditions:

 

  1. The Service providers should make their device drivers compliant with the “XFS Manager” as distributed by Microsoft.
  2. Must be Win32 based.
  3. Should be compatible with the published XFS API definition.

 

Distinct Features

The key element of the XFS is the definition of set of APIs and a corresponding set of SPIs providing services to Windows based applications. XFS provides the set of APIs to the application developers which they can use without getting worried about the service providers; for example the Printers of the ATMs are provided by multiple vendors in the market, by implementing an XFS based application the developer should not worry about the make and model of the printer if the printer SP is compatible with the XFS Manager and XFS API, the same application will work without changing a single line of code. As far as I know all the peripheral device providers of ATMs and EFTPOS now are compatible with the XFS Manager and hence supports the XFS APIs.

 

One of the most powerful things provided by CEN/XFS is Form based printing from the peripheral devices like journal, receipt and document printers. Form is a simple specially formatted text file which is called within the XFS based application using the XFS APIs. The main advantage of using Form based printing is the ease of editing the printing data without recompiling your code but the developer should have to be very careful while editing a Form because a single wrong byte will crash the whole system and cause the machine to restart. There are many tools in the market to generate an XFS Form.

 

Applications

All the Financial standards like “Aptra Advance NDC” by NCR and “DTC” by Diebold are XFS compatible hence are vendor independent. XFS is the reason which made AANDC work on Diebold ATM machines without using any Emulator. NCR realizes the importance of XFS quite late in 2004 where they started developing their first XFS based vendor independent software AANDC 3.0. Before the release of 3.0 XFS was introduced in the AANDC 2.6 but at that time some devices were supporting ADI (Active Device interface) which was the reason of not completely moving to XFS.

 

We as the providers of the ATM extension application like Biometric authentication over ATMs, Non EMV Chip card transactions on ATMs, Cash and Cheque deposit enhancements on ATMs and integration of CRM with ATMs have a lot of applications of XFS. For me our perfect implementation of XFS was a system developed for Oman Arab Bank in 2007 to support DUET standard Chip cards over the ATM. I used XFS APIs to communicate with the Card ICC where we were reading and writing the card holder data on the chip and the XFS forms for printing Receipts and journal.

The implementation went extremely successful because no code was changed for different devices of the ATMs and I was really very relaxed except in the very end of the implementation just before the GO LIVE activity the Bank requested the journal printing module which was not even written, that was the point where I really felt the flexibility of XFS API because I only changed the logical name of the receipt printing module to journal printer and the journal printing started working.

For the bank it was an amazing thing, a completely new module of journal printing developed and tested properly within a day just before the GO LIVE activity (not to mention how thankful they were), but for me it was only a function call with journal printer logical name provided instead of receipt printerJ.

Posted by: Irfan Raza | April 16, 2009

Call Windows Scripting Components (WSC) from C/C++

How to call Windows Scripting Components from C/C++

 

Windows Scripting Components

Windows scripting components is a very powerful technology to create COM components using VB script and java script. More…

 

The main benefit of this kind of Com object is that they are easy to create and requires no compilation. So if you require creating a multi platform application with some shared functionality then use the scripting components to create those common functionality components.

 

As these components are COM object hence are easily useable within all the languages over windows platform. Here I will discuss only C language.

 

Create a Simple Scripting Component

First of all you should be able to create a simple scripting component. You can easily do that in notepad but i would recommend that you use Microsoft Windows Scripting Component Wizard to create a Scripting Component to avoid mistakes. This wizard will let you create a simple scripting file of WSC extension with skeleton of methods and variable that you want to expose.

 

·          After downloading/installing the scripting wizard run it from the Programs Menu.

·          Give the Name of the component; I am giving it “Irfantest”, press Next to move to next page…

·          Select language as VB.

·          Uncheck the Special Implement support and select Error Checking as runtime option. Press Next…

·          If you want to add some properties of the component add it, in this example I will not be using any property. Press Next…

·          Now on the Methods Screen you can add those functions that you want to be exposed by this object, add a method by the Name of “Irfantestmethod”, add a parameter by the name of “teststr” and press Next…

·          The next screen is the Add Event screen, we are not going to handle any event in this component hence skip to next screen…

·          Finish the wizard and you will be able to see a WSC file in the specified location.

·          Edit the file using any editor and edit the methods that you specified during its creation (In this example “Irfantestmethod”), Add a line in the method to show a Message Box which shows the parameter “teststr” to screen.

 

Your WSC file should look like following with off course with a different classid:

 

 

<?xml version=”1.0″?>

<component>

<?component error=”true” debug=”false”?>

<registration

            description=”Irfantest”

            progid=”Irfantest.WSC”

            version=”1.00″

            classid=”{3d97f297-4b97-4f6b-bfb4-95890bc2b2a2}”

</registration>

 

<public>

            <method name=”Irfantestmethod”>

                        <PARAMETER name=”teststr”/>

            </method>

</public>

 

<script language=”VBScript”>

<![CDATA[

function Irfantestmethod(teststr)

            MsgBox “Hello Irfan”

            Irfantestmethod = “returned”

end function

]]>

</script>

</component>

 

Register this file using regsvr32 command from run.

 

Call the WSC function from C

Your test component is ready. Now let’s have a look at the C code that is going to call the method “Irfantestmethod”.

 

Create a new project in visual studio.

Keep the project as a console application.

Add a Function as:

 

int CallWscComponent(char *cFileName, char*cFunctionName)

 

To call a WSC component function with some arguments is a bit different then calling a C++ or VB com object, you must define an array of VARIANT type which will hold the passing arguments along with their data types. We are using only one argument in the WSC object hence we will create an array of size one:

 

VARIANT arg[1];

 

Define the Type of the argument i.e. string:

 

arg[0].vt = VT_BYREF|VT_BSTR;

 

You can find the definition of other types in ks.h file under “c:\Program Files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\Include” directory.

I needed to pass a string “Hello World” to the WSC object method “Irfantestmethod”.

 

CString tempValue = “Hello World”;

BSTR bb = tempValue.AllocSysString();

arg[0].pbstrVal = &bb;

 

Use the CoGetObject to get the pointer to the object.

 

hr = CoGetObject(lpWscFileName, NULL, IID_IDispatch, (void**)&objWsc);

 

Get the mapping of the function Ids, in our case we only have one function that is required to be called hence only the name of that specific member function is passed, incase if more then 1 id is required of WSC member functions, and pass an array of function name. Subsequently the return IDs will be in an array.

 

hr = objWsc->GetIDsOfNames(IID_NULL, &sMemFuncName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);

 

Using the Id returned by the GetIDsoFName function call the “Invoke” method to execute the WSC function

 

hr = objWsc->Invoke( dispid,IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramArgs, &vResult, NULL, NULL);

 

The complete C code of the WSC call is as follow:

 

 

LPCWSTR MultiCharToUniChar(char* cStr)

{

            int iLen = strlen(cStr) + 1;

            wchar_t *ucString = new wchar_t[iLen];

 

            if (::MultiByteToWideChar(CP_ACP, 0, cStr, iLen, ucString , iLen) == 0)

                                    return NULL;

           

            return (LPCWSTR)ucString;

}

 

int CallWscComponent(char *cFileName, char*cFunctionName)

{

            HRESULT hr = -1;

            IDispatch* objWsc;

            DISPID dispid;

            VARIANT vResult;

            VariantInit(&vResult);

 

            CString strFuncName = cFunctionName;

            OLECHAR * sMemFuncName = strFuncName.AllocSysString();

            DISPPARAMS paramArgs;

            LPCWSTR lpWscFileName = MultiCharToUniChar(cFileName);

            VARIANT vArg[1];

            vArg[0].vt = VT_BYREF|VT_BSTR;

 

            CString tempValue = “Hello World”;

            BSTR bstring = tempValue.AllocSysString();

            vArg[0].pbstrVal = &bstring;

 

            paramArgs.rgvarg = vArg;

            paramArgs.cArgs = 1;

            paramArgs.cNamedArgs = 0;

   

            if(lpWscFileName != NULL)

            {

                        hr = CoGetObject(lpWscFileName, NULL, IID_IDispatch, (void**)&objWsc);

                        delete[] lpWscFileName;

            }

 

            if (FAILED(hr))

            {

                        return(hr);

            }

 

            hr = objWsc->GetIDsOfNames(IID_NULL, &sMemFuncName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);

 

            if (FAILED(hr))

            {

                        return(hr);

            }

 

            hr = objWsc->Invoke( dispid,IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramArgs, &vResult, NULL, NULL);

            if (FAILED(hr))

            {

                        return(hr);

            }

}

 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

            int nRetCode = 0;

 

            CoInitialize (NULL);

            CallWscComponent(“script:G:\\TEST Developments\\WSCCall\\Irfantest.WSC”,”Irfantestmethod”);

            CoUninitialize();

            return nRetCode;

}

Posted by: Irfan Raza | March 4, 2009

A Simple HTTPS Client

How to create a simple HTTPS Client?

Some time ago this question was roaming in my mind as I was looking for a way to communicate to an HTTPS Server from a desktop application, I was able to find some on the internet but i needed a library which I can use to send request and recieve data to an HTTPS web server. Many libraries are available on the internet as well but I was unable to find a free one which is easy to use as well :).  As a C++ coder we are always in search of one that is easy to use 🙂
Then I came across this article which led me to create a very simple HTTPS client application which was able to send and recieve data to a Web server using MSXML4.0. Its setup can be easily downloaded from Microsoft site, its a com dll hence can be easily called in C++ or VB, I tried it in VB and here is a simple code:

Open up VB console and create a new Project of “Standard Exe”.

Add a Reference of “Microsoft XML, v4.0” to the project from the Project Menu. (The dll will be Msxml4.dll)

Define a variable of the request as:
   Dim httpsreq As New MSXML2.XMLHTTP40
   Dim temp As String

Rest of the code can be written on the event of a Button or In the Form_Load method.

open up the URL first by POST method:
   httpsreq.Open “POST”, “https://localhost/TesthttpsServer/test.aspx“, False, Empty, Empty

Set the data that you want to send to the HTTPS server:
  temp = “This is a test request to test server”

Now set the request headers, i am not going to go in details of the header parameters:

 httpsreq.setRequestHeader “User-Agent”, “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)”
 httpsreq.setRequestHeader “Accept”, “image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, */*”
 httpsreq.setRequestHeader “Accept-Language”, “en-us\r\n”
 httpsreq.setRequestHeader “Content-Length”, Len(temp)
 httpsreq.setRequestHeader “Content-Type”, “application/x-www-form-urlencoded”
 httpsreq.setRequestHeader “Cache-Control”, “no-cache”

Now you are ready to post a requesst to the HTTPS server, this call can take long depending upon the response time of your server:
 httpsreq.send temp

After the request is executed you will be able to recieve the status of request either Success or failed:
 MsgBox “Reponse Status = ” & httpsreq.Status

If your Test Https server is to return some data to you, you can recieve it as:
 MsgBox “Reponse body = ” & httpsreq.ResponseBody & “. Response text = ” & httpsreq.responseText

Thats it, this is all that is required to set up a small HTTPS client :). The same code can be used for HTTP requests, just use HTTP instead of HTTPS in the Open method.
 httpsreq.Open “POST”, “http://localhost/TesthttpsServer/test.aspx“, False, Empty, Empty

Categories