ISAPI Filters are introduced in IIS 6, and not recommended any more since IIS 7. However, there might exists legacy code which needs to be maintained. So here is the guide to develop, troubleshoot and debug ISAPI Filters.

Create a VS Project

Using Visual Studio 2017:

Create ISAPI Project

An ISAPI Project is simply a Visual C++ Project if you're writing in C++.

And don't forget to set Project Configuration Type to Dynamic Library (.dll).

Set Project Configuration Type

Set up basic file structure

zzzbuzz-isapi.cpp:

#include <windows.h>
#include <httpfilt.h>

BOOL WINAPI GetFilterVersion(
    PHTTP_FILTER_VERSION pVer
)
{
  return TRUE;
}

DWORD WINAPI HttpFilterProc(
    PHTTP_FILTER_CONTEXT pfc,
    DWORD notificationType,
    LPVOID pvNotification
)
{
  return SF_STATUS_REQ_NEXT_NOTIFICATION;
}

Note: httpfilt.h contains ISAPI entry-point function declarations, and windows.h contains macro such as BOOL, DWORD, LPVOID, etc.

zzzbuzz-isapi.def:

LIBRARY ZzzBuzzISAPI
EXPORTS
	GetFilterVersion
	HttpFilterProc

Note: GetFilterVersion and HttpFilterProc are required exports for an ISAPI Filter.

For further development requirements, please refer to ISAPI Development section.

Troubleshooting

If HTTP Error 500.0 - Internal Server Error occurs after setting up ISAPI Filter, please turn on detailed errors in IIS Error Pages configuration to get more info on the exact error.

Detailed error shows Calling LoadLibraryEx on ISAPI filter "???" failed

This may be caused by unsatisfied dependencies of ISAPI Filter. For example, your DLL is built with debug version of VC DLL, while your server only has release version of VC redistributables installed.

Use Dependency Walker to help find out the dependencies of the ISAPI Filter.

Detailed error shows Calling GetProcAddress on ISAPI filter "???" failed

This may be caused by lack of Module Definition File when compiling your ISAPI Filter. Set it on command line when building or in project configuration to fix this.

Set Module Definition File

This may also be caused by GetFilterVersion or HttpFilterProc not exported in the ISAPI Filter. See ISAPI Filter Entry-Point Functions:

Both GetFilterVersion and HttpFilterProc must be provided by every ISAPI filter. The TerminateFilter function is called by IIS just before the filter is unloaded. This function is optional, although you should consider providing it if the ISAPI filter you are using needs to free any allocated or locked resources before being unloaded.

Debugging

ISAPI Filters are executed in w3wp.exe as native code.

Attach to: Native code - w3wp.exe

Microsoft Documents

ISAPI Development

ISAPI Debugging

.def Module-Definition Files

IIS Configuration

References