Writing a simple ISAPI Filter

ISAPI Filters can be written to do anything on the incoming requests; it could do some kind of logging, user authentication, traffic analysis, much more. You can design you own ISAPI filter for your own need. Here is what I have done in the sample ISAPI Filter, it just writes into a file, some data when it is being processed.

Essential Functions

ISAPI filter should have the following export functions:

            HttpFilterProc

            GetFilterVersion

A third function, TerminateFilter, is considered optional and is commonly used by filters to perform cleanup operations.

Example Code

I modified the code from https://msdn.microsoft.com/library/default.asp?url=/library/en-us/iissdk/html/636c6a84-cda4-4f2f-a9a8-fabea840a394.asp

Steps to create an ISAPI Filter using Visual Studio

·        Create an Empty project using VC++ in VS

·        Create a new .CPP file and name it as MyISAPI.cpp

Now, we need to write our code for the MyISAPI.CPP. As I mentioned earlier, we have to define two very important functions, HttpFilterProc and GetFilterVersion.

GetFilterVersion

BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer) {

            // Put your code here

            // Register for all the events

}

GetFilterVersion is the first function to be called whenever a request reaches IIS and it is passed to the ISAPI to process. Here is where you should register your ISAPI for the notifications, like SF_NOTIFY_PREPROC_HEADERS, SF_NOTIFY_AUTHENTICATION, etc. You can see the list of notifications you can register here.

Sample code

BOOL GetFilterVersion(HTTP_FILTER_VERSION *pVer)

{

  /* Specify the types and order of notification */

  pVer->dwFlags = (SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_AUTHENTICATION |

            SF_NOTIFY_URL_MAP | SF_NOTIFY_SEND_RAW_DATA | SF_NOTIFY_LOG | SF_NOTIFY_END_OF_NET_SESSION );

  pVer->dwFilterVersion = HTTP_FILTER_REVISION;

  strcpy(pVer->lpszFilterDesc, "My ISAPI Filter, Version 1.0");

  return TRUE;

}

HttpFilterProc

HttpFilterProc is the function where most of the works of the ISAPI filter are done.

DWORD HttpFilterProc(HTTP_FILTER_CONTEXT *pfc, DWORD NotificationType, VOID *pvData) {

            // Put your code for your core idea of this ISAPI Filter

}

For all the notifications you have registered in GetFilterVersion, this HttpFilterProc is called with appropriate NotificationType as its 2nd parameter in the function.

Sample Code to handle some notification:

DWORD WINAPI __stdcall HttpFilterProc(HTTP_FILTER_CONTEXT *pfc, DWORD NotificationType, VOID *pvData)

{

            CFile myFile("G:\\mylist.html", CFile::modeWrite);

            myFile.SeekToEnd();

            switch (NotificationType) {

            case SF_NOTIFY_URL_MAP :

            myFile.Write("SF_NOTIFY_URL_MAP",strlen("SF_NOTIFY_URL_MAP>"));

                        break;

  case SF_NOTIFY_PREPROC_HEADERS :

  myFile.Write("SF_NOTIFY_PREPROC_HEADERS",strlen("SF_NOTIFY_PREPROC_HEADERS"));

            break;

default :

   break;

            }

            myFile.Close();

            return SF_STATUS_REQ_NEXT_NOTIFICATION;

}

The above example will just write the data into a TEXT file. You can place your own logic in the code. You can also use the CHttpFilter class and do your ISAPI filter coding in an Object Oriented way. CHttpFilter class different functions for all the notifications and the CHttpFilter::HttpFilterProc function automatically calls them.

Two more important step you have to follow before you building the project.

1.       Go to project properties and change the Configuration Type to be Dynamic Library (.dll).

2.       Create a new file, name it as MyISAPI.def and place the following contents

LIBRARY “MyISAPI"

EXPORTS

            HttpFilterProc

GetFilterVersion

Build the project. Now you can use the MyISAPI.dll as an ISAPI Filter in IIS. I have attached the ISAPI_FILTER_CODE.zip on this post.

ISAPI_FILTER_CODE.zip