From MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iissdk/iis/creating_simple_isapi_filters.aspFor an ISAPI filter to be used by IIS, it must provide a standard interface . to provide a standard interface, each filter application must implement and export two primary functions, GetFilterVersion and HttpFilterProc. A third function, TerminateFilter, is considered optional and is commonly used by filters to perform cleanup operations.
Example Code
The following example shows you how to use the C programming language to create a simple ISAPI filter. This filter converts HTML response data to uppercase letters if the client requests it. The request is made by specifying an extra subdirectory in the URL called "UC, "which does not actually exist on the server, but which is used by the filter to indicate that uppercase letters have been requested. The extra subdirectory is removed from the request before the HTTP server receives the request.
When a request is received, the filter inspects the subdirectories that are specified in the URL. If the nonexistent subdirectory is "UC" or "uc", the subdirectory is removed from the request, and the filter saves a value in its pFilterContext field, That Idicates That The Response Data Should Be Converted To Uppercase Letters.
When the filter entry point is later called for the response, it checks the pFilterContext field and converts the data if the mime-type of the response indicates that its an HTML file. This avoids conversions on binary data.
This Code Example Is Taken From The Upcase Sample Files That Are INCLUDED with The IIS Section of The Platform SDK. It can Also Be Downloaded from Platform SDK Update.
[C ] / *
CopyRight (c) Microsoft Corporation
Module Name: Upcase.c
* /
#include
#include
#include
#include
BOOL WINAPI __STDCALL GETFILTERVERSION (http_filter_version * pver)
{
/ * Specify the Types and ORDER OF NOTIFICATION * /
PVER-> DWFLAGS = (sf_notify_nonsecure_port | sf_notify_url_map | sf_notify_send_raw_data | sf_notify_order_default);
PVER-> DWFILTERVERSION = http_filter_revision;
STRCPY (PVER-> LPSZFILTERDESC, "Upper Case Conversion Filter, Version 1.0");
Return True;
}
DWORD WINAPI __STDCALL HTTPFILTERPROC (http_filter_context * PFC, DWORD NOTIFICTIONTYPE, VOID * PVDATA)
{
Char * pchin, * pphyspath;
DWORD CBBUFFER, CBTEMP;
PHTTP_FILTER_URL_MAP PURLMAP;
PHTTP_FILTER_RAW_DATA PRAWDATA;
Switch (notificationType) {
Case sf_notify_url_map:
/ * Check the url for a subdirectory in the form of / uc / or / uc / * /
PURLMAP = (phttp_filter_url_map) PVDATA;
PPHYSPATH = PURLMAP-> PSZPHYSICALPATH;
PFC-> pfiltercontext = 0;
For (; * pphyspath; pphyspath )
{
/ * ENSURE THAT THERE AT Least 4 Characters (Checking for "/ uc /") Left in the url before checking * /
IF (Strlen (PPHYSPATH)> 3)
{
IF (* pphyspath == '//' && (* (pphyspath 1) == 'u' || * (PPHYSPATH 1) == 'u') && (* (pphyspath 2) == 'c' || * (PPHYSPATH 2) == 'c') && * (PPHYSPATH 3) == '//')
{
/ * Now That We've Found It, Remove It by Collapsing Everything Down * /
For (; * (PPHYSPATH 3); PPHYSPATH )
* pphyspath = * (PPHYSPATH 3);
/ * Null terminate the string * / * pphyspath = '/ 0';
/ * And set the flag to let the sf_notify_send_raw_data handler know to uppercase the content * /
PFC-> pfiltercontext = (void *) 1;
/ * Break us out of the loop - Note That this will only find the first instance of / uc / in the url * /
Break;
}
}
}
Break;
Case sf_notify_send_raw_data:
IF (PFC-> PfilterContext)
{
PrawData = (phttp_filter_raw_data) PVDATA;
PCHIN = (Byte *) PrawData-> pvindata;
CBBuffer = 0;
IF (PFC-> PfilterContext == (void *) 1)
{
/ *
As this is The First Block, Scan Through It Until 2 CRLFS Are Seen, To Pass
All of the headers.
* /
For (; CBBuffer
{
IF (PChin [CBBuffer] == '/ n' &&phin [cbuffer 2] == '/ n')
{
CBBuffer = 3;
Break;
}
CBBuffer ;
}
For (cbtemp = 0; cbtemp <(CBBuffer - 3); CBTEMP )
{
IF (pchin [cbtemp] == '/' &&pchin [cbtemp 1] == 'h' &&pchin [cbtemp 2] == 't' &&pchin [CBTEMP 3] == 'm')
{
PFC-> PfilterContext = (void *) 2;
Break;
}
}
IF (cbtemp == cbuffer)
PFC-> PfilterContext = 0; / * NOT An HTML file * /
}
/ * Now Uppercase Everything * /
IF (PFC-> PfilterContext)
For (; cbbuffer
PCHIN [CBBuffer] = (PChin [CBBuffer]> = 'A' && PChin [CBBuffer] <= 'Z')? (PChin [CBBuffer] - 'A' 'A'): PChin [CBBuffer];
}
Break;
DEFAULT:
Break;
}
RETURN SF_STATUS_REQ_NEXT_NOTIFICATION;
}