HOWTO: Compile and Use my ISAPI Code Samples

Since I get this following question on how to compile/use my ISAPI code examples quite a bit, I wager I should just have a blog post that answers it once and for all.

But, come on you guys… I already did the hard part in providing the full compiling sample source code illustrating the solution to your problem(s). Why can’t you figure out the simpler task of compiling that source code into an ISAPI DLL? 😉 I mean, it’s not rocket science. It’s just compilers and linkers.

Dare I say it… do I have to spoon-feed it to you like a child? hehe, ok, never mind… 😉 Here goes…

Anyways… I still use Visual C++ 6.0 to compile/link my ISAPI code samples (in fact, I usually test them out on IIS 5 as well as IIS 6, too). I am not bought into the .Net fever… at least not as far as ISAPI and IIS modifications are concerned. Don’t get me wrong, .Net is great for end users to accomplish what they need at the higher, business-logic levels… but I am not convinced that .Net is useful at the lower-levels that ISAPI runs at. In particular, the memory overhead and native/managed code transitions alone kill performance, not to mention the SxS issues of multiple CLR versions in the same memory space. Native ISAPI code simply does not have such problems.

Anyhow, getting off that sidetrack… here are step-by-step instructions on how to compile/link my ISAPI code samples for both Visual C++ 6.0 and Visual C++ 2005 Express Edition.

Visual C++ 6.0

  1. File… New… -> Projects… Win32 Dynamic-Link Library

    • Give the project a name, a folder to store the project, and create a workspace (if that’s what you want)
    • Create “an empty DLL project” and click OK to finish

  2. Project… Add to Project… New… -> C++ Source File

    • Give the source file a name and folder to store the file (preferably with the project you just created)
    • Copy/Paste the source code from my blog entry into the source file you just created

  3. Project… Add to Project… New… -> Text File

    • Give the text file a name (I usually use the same as the source file), extension of .DEF, and a folder to store the file (preferably with the C++ source file you just created)
    • Enter content into this file as directed by this blog entry for error data 0x7F. It is either
      LIBRARY Your_ISAPI_Extension_Name
      LIBRARY Your_ISAPI_Filter_Name

  4. Everything should compile and link properly and be immediately usable on IIS.

    If you have compilation errors, then it is probably because you are compiling against older ISAPI headers. To fix this, you need to download and install the latest Microsoft Platform SDK, configure Visual C++ to use the include and library files from the SDK instead of the older ones from Visual C++ (this is under Tools…Options…Directories tab, insert the full path for include and library directories from the SDK to the top of their respective lists), and then compile/link.

    It should work at this point, and if not… you need to be on your own to figure it out because it has nothing to do with IIS/ISAPI at this point. 🙂

Visual C++ 2005 Express Edition

  1. File… New… Project… -> Empty Project

    • Give the project a name, a folder to store the project, and create a workspace (if that’s what you want)

  2. Project… Add New Item -> Code… C++ File (.cpp)

    • Give the source file a name and folder to store the file (preferably with the project you just created)
    • Copy/Paste the source code from my blog entry into the source file you just created

  3. Use notepad and create the .DEF file in a folder (preferably with the C++ source file you just created) with contents as directed by this blog entry for error data 0x7F. It is either:
    LIBRARY Your_ISAPI_Extension_Name


    LIBRARY Your_ISAPI_Filter_Name

  4. Because the Express Edition does not give Win32 DLL Project as an option, we simply customize the empty project into what is necessary. Open up  Project… Properties (Alt-F7) -> Configuration Properties… and modify the following properties:

    • General… Configuration Type -> Change to “Dynamic Library (.dll)”
      [Why: Compile DLL instead of EXE]
    • General… Character Set -> Make sure it is “Not set”
      [Why: ISAPI is not Unicode]
    • C/C++… General -> Debug Information Format to “Program Database (/Zi)”
      [Why: Create PDB for debugging]
    • Linker… Debugging -> Generate Debug Info to “Yes (/DEBUG)”
      [Why: Create PDB for debugging]
    • Linker… Input -> Module Definition File. Give the full filepath to the .DEF file you just created
      [Why: Export the necessary signatures of ISAPI for IIS to LoadLibrary()]

  5. Everything should compile and link properly and be immediately usable on IIS.

    If you have compilation errors, then it is probably because you are compiling against older ISAPI headers. To fix this, you need to download and install the latest Microsoft Platform SDK, configure Visual C++ to use the include and library files from the SDK instead of the older ones from Visual C++ (this is under Tools…Options…Projects and Solutions…VC++ Directories -> insert the full path for include and library directories from the SDK to the top of their respective lists), and then compile/link.

    It should work at this point, and if not… you need to be on your own to figure it out because it has nothing to do with IIS/ISAPI at this point. 🙂

Yes, I went and walked through both sets directions using the LoadBalancedIP sample code and loaded the resulting DLL on IIS5 to verify that everything functioned as intended. I am happy to say that it all worked for me the first time. 🙂 The Client-IP in my log file changed to whatever X-Client-IP request header stated.

So… if this does not work for you… then I really do not know what else to do. Maybe you should chuck this ISAPI thing out the window and wait for IIS7 modules. 😛


Comments (38)

  1. kfarmer says:

    If you cannot proofread your comments, perhaps you should not be making them?

  2. David Wang says:

    Keith – I’m not certain what you are referencing.

    In this particular case, I spent several hours of my own personal time on vacation downloading and installing all of the software, crafting together the instructions, and trying things out.

    So, if you have problems with the wording, then I’d appreciate something more specific.

    Sometimes I even make edits right at the beginning as I notice and re-read things again.


  3. kfarmer says:

    I’d have sworn I saw the word "butter" used where "better" was meant.

    In any event, vacation or no (and that would be "no" in my case), your tone is not exactly good for PR. Remember that you’re the public interface into Microsoft: if people who are trying to learn how to learn ISAPI annoy you, then perhaps you should remember that, at one point, it *was* rocket science at some point for you as well. That, or not make yourself available. Nobody likes a teacher that insults them.

    Nothing personal. Just something to consider.

  4. kfarmer says:

    As for my proofreading, I beg the fact that it’s two in the morning.

  5. ryan says:

    I understand not using the CLR for ISAPI modules, but why use Visual C++ 6.0 to compile them? There’s been tons of improvements to the C++ compiler in the last 7 years, seems like you’d want to take advantage of those…

  6. David Wang says:

    Keith – I see…

    I apologize for the misinterpretation of my tone. However, I tend to think that blogging is a form of personal expression that gives a human identity/personality to this corporate entity called Microsoft, not exactly corporate PR or walking the party line.

    Because if the purpose is corporate PR, then:

    1. My topics probably would change

    2. My tone would change

    3. I would not go railing against the red-tape for DebugDiag

    4. I would not go railing against the MS KB System

    5. I would not dare cajole or 😉 to the reader

    6. etc, etc

    I am spending personal time to do this because I care. If people are so quick to interpret every non-positive as an insult, and I have to write around them… then I’m sorry. This is why I am in engineering and not marketing – I give you the straight facts as I see them, dirty or not, and I don’t play favorites. 🙂


  7. David Wang says:

    ryan – I tend to agree with you.

    However, you would be surprised at how many users have asked for instructions using VC++ 6.0. In contrast, I can say that no one has asked for VC++ 2005 Express instructions yet, but I went to look it up anyways… and found the support lacking without the details I gave, so I went ahead and posted that as well.

    My main goal is to not use the ISAPI Wizard in VC++ because it is not necessary to create an ISAPI, and it introduces some extra layers that people rarely use.


  8. kfarmer says:

    There was little to misinterpret: you call your readers children just because they aren’t ISAPI adepts.

    So you spent some vacation time on this. There are many who don’t get vacation, who suffer much more abuse than "Can you explain this some more?", and who still manage to not insult the people hurling it. And they make much less than either of us. Incidentally, there are several among them who *will* be senior devs at Microsoft one day.

    Don’t mistake the nature of Sure, you can speak with your own voice, but it is the single biggest and most effective PR campaign ever.

  9. David Wang says:

    keith – I’m sorry, but this blog entry is about how to compile sample source code and not about how adept you are at ISAPI.

    My goal with providing sample source code is so that I illustrate and do the heavy lifting to get you over the parts of ISAPI. I do not chide anyone about ISAPI because I know it is non-obvious. However, failing to compile/link working source code, given hints… that deserves something.

    Compiling source code is a really fundamental activity that is not tied to ISAPI. I doubt senior devs at Microsoft can survive without mastering it.

    I always try to demystify ISAPI by pointing out that ISAPI is just a normal Win32 DLL compiled against httpext.h or httpfilt.h and exports certain signatures.

    Now, I have compassion for people trying to write/use ISAPI because I believe Microsoft does not do a good job explaining this technology – hence I blog a lot about the topic, provide sample source code, illuminate interactions between IIS and ISAPI, etc.

    However, it is more of a stretch for me to help someone who does not want to understand/apply a fundamental development activity like compiling and linking source code *yet* still wants to reap the fruits of those labors. This is the crux of what I am discussing here.

    Anyways, this is diverging way off-topic and going into the softer realm of personal opinion, so I’m going to stop at this point.


  10. Jack says:

    for christ sake, i never take blog seriously and no one should. it’s more like a diary on the net for everyone to read about your thought, idea, rant…etc.

    i guess this blog entry is David’s rant…(?)

    anyway, it’s a good piece of rant. i doubt blog qualified as PR.

    on a off topic question, Do Microsoft plan to release new frontpage extension for IIS7? the latest is Frontpage 2002 and it seem to stop there. Is Microsoft try to force people to switch again after they invest time and money into frontpage?

  11. David Wang says:

    Jack – Your question is more suitable to be asked of the Office/Sharepoint folks because they own the technology and the roadmap.

    IIS is merely the server upon which that technology will run. We have no direct control over what other teams do with their user base.

    Yes, I know that most hosters and users associate FPSE as well as every other piece of technology that runs on IIS as "IIS", but we do not… so I cannot answer for another team. 🙂


  12. Jason C. Shave says:

    I’m curious why you can’t just post the DLL??

  13. David Wang says:

    Jason – I post the source code because:

    1. It allows people to learn how things work and make their own modifications

    2. It allows people to support their own use of the code

    If I just post the DLL, then I indirectly become "responsible" to support the DLL for all its users. That is not my intention.

    Also, I do not believe that users should download and install arbitrary binaries with no assurances onto their machines. Who says that I do not plant a backdoor into my DLL binaries?


  14. Andre says:


    i have only a little problem, i hope yopu can say a few sentences, because this should be no problem fpr you.

    I did the Tutorial HOWTO: ISAPI Filter logging request URL and headers based on User-Agent

    I compiled the dll under win98 an everthing was ok, but if i want to register the dll on win2003-server with regsvr32 a message is shown "dll was loaded , but the dllregisterserver entry point was not found. the file cannot be registerd"

    At the moment i have no idea to solve this problem, i did everything, also the part with the .DEF File.

    Can you please give a little help?

    Thank you Andre

  15. David.Wang says:

    Andre – Unless you write special code, ISAPI Filter DLLs are not registered using regsvr32. I am not certain why you want to register the DLL using regsvr32 – can you point out documentation which mentions that you should do this on Windows Server 2003?

    I suggest you locate and read basic IIS documentation on how to install an ISAPI Filter.

    I found the instructions by simply searching: "Install ISAPI Filter".


  16. Andre says:


    it was just a try. I installed the Filter just like the tutorial shows, but it is not working. (red arrow) and IIS tells "Service Unavailable" if i try to request a webpage. So i tried to register this dll by using regsvr32 to see what happens.

    The reason for this problem was too less permissions to create the LogFiles. Now its working.



  17. Andre says:

    Hello David,

    thanks again. Sure every information can be found somewhere, but only water takes always the way of smallest resistence (?) 😉

    I testet your dll and played a little bit, everything works fine.

    What im really looking for ist a good monitoring tool for iis which generates ouput just like the apache stat009 page. I testet a little bit with the tools from troxo oder the iis tracer, but they are not freeware. Windows Servertools are for my purposes to oversized.

    Do you know a tool like this? Ok, you will say you saw the c++ smaples, do it and complie it, but this is not very easy.  😉



  18. David.Wang says:

    Andre – you do mean electricity, not water, right? 😉

    I don’t know anything about Apache’s stat009 page. Went searching for "stat009 Apache" and did not find anything useful. Can you describe what sort of data/state is being monitored and reported?

    What you are describing is the proverbial Open Source "itch". Why someone doesn’t scratch that "itch" for free… I don’t know.


  19. Andre says:


    if found a free viewable status-page (not my server)

    You see uptime and some statistic data. But most interesting are the currently processed requests.  It’s a live status just like iisguard from troxo or the iis tracer, but its included in Serversoftware. I think we should inform them that anybody can see their Status-page, cause also Get-Params are viewable.

    electricity/water I think best example ist simple air or any other gas.

    My last lessions in physics i had many years ago 😉 i think you too.


  20. David.Wang says:

    Andre –  Hmm, I see. Yeah, that is doable as an ISAPI Filter to track currently executing requests and stats on existing IIS versions. Still dunno who does it for free.

    BTW, IIS7 will have a far better version of this sort of functionality, especially for diagnosing and troubleshooting.


  21. Andre says:


    upgrading to IIS 7 is not an option at this time. My IIS 6 System is running very good and i think I have to change some other scripts when i do an upgrade.

    Now comes the nasty question. Don’t you are interested in programming a small tool for this serverstatus? My part could be to compile and use it? Hmm ok,  we could do a ExChange, tell me what i could do if you agree. Yes, i know, this is very strange question, but i dont see an other option at this time, and asking is free of charge….


  22. David.Wang says:

    Andre – Thanks for the thought… but I probably do not have time at the moment to do it.

    You can post your idea to and see if it works out some other way.

    In the end, it is the community that matters; code availability is an associated effect…


  23. Mike Williams says:

    Hello David,

    Thanks for all your excellent code, insight and time! I have learnt a lot, compiled and run your loadbalancedip dll and it works great. We have an issue with a CMS system vendor that has another ISAPI filter, with high priority, but no other filters running after it get activated. I guess from googling that they have activated SF_STATUS_REQ_FINISHED. Only if I move your filter above theirs does it get run. But we have other ISAPI filters with Low priority that never get activated.

    They acknowledge that their filter prevents others from running but claim that a high priority filter should always prevent lower ones from running afterwards. I dont believe it – all I have read up on msdn etc says it is just based on priority and that multiple filters can have the same (high) priority, with running order determionded by order in IIS. Also that the only reason for terminating the request I can find is for authentication denials, keeping unwanted visitors away etc.

    Am I right?  By the way (just in case you know of some other good source for such a filter so I can create our own) the other low priority ISAPI filter is to issue a cookie, so we can then log this in IIS logs and use for stats analysis, as IIS itself as far as I am aware cant be set to do this.

    Thanks again!

    Mike Williams

  24. David.Wang says:

    Mike – it just sounds like a design flaw with the CMS ISAPI Filter. It should be possible for filters to provide request services and interact well with each other instead of assuming that they are the only filter allowed on the server.

    As for why IIS does not (and will likely never have) an option to issue cookies for stats analysis… Cookies for stat analysis usually imply an application-level logic of "session", which IIS at the HTTP layer has no idea about.

    Clearly, IIS cannot come with every possible feature, so it is nice to be able to modify IIS behavior and add on a feature with an ISAPI…


  25. Mike Williams says:

    Thanks David – you confirmed my suspicions – and I await the CMS vendor correcting their ISAPI filter.

    As for IIS not having the option to issue cookies for session tracking,  I had thought it would be analagous to Apache’s mod_usertrack module which issues cookies that can be used/logged. I though that was also ot at the application level.

    Is it possible to explain – just to help my understanding, how IIS is at a different layer to Apache and couldn’t have the same functionality? Apache is also independent of the application isn’t it at a similar layer to IIS.

    There was such a solution provided by WebTrends, for varoud servers, including  an ISAPI filter for IIS, but is no longer supported as they say  "Most modern Web servers contain functionality for serving cookies".

    Also, do you know of any existing ISAPI filter source to add this similar functionality to IIS?  There’s a challenge for you if you don’t.  😉


  26. David.Wang says:

    Mike – Apache and IIS are not at different layers. They are both web servers which support HTTP-level extensibility via modules. Apache calls them "modules" while IIS calls them "ISAPIs".

    For all practical purposes, Apache and IIS can do the same tasks and provide similar functionality. The difference is availability — Apache modules tend to be Open Source and freely available while ISAPIs tend to not be shared by its authors (for whatever reason).

    Cookies are merely request/response headers at the HTTP level, and Session ID at the application level.

    Thus, mod_usertrack is merely a Open Source module that manipulate the Cookie headers at an HTTP-level. It happens that these cookies can be used at an application level for user identification, but fundamentally, mod_usertrack is an HTTP-level module.

    An IIS counterpart to mod_usertrack would be the WebTrends ISAPI Filter. Which WebTrends chose not to support/share their code and instead lock it away.

    Thus, it is not that IIS is at a different layer or that IIS couldn’t have the same functionality. It is that no one has bothered sharing a module implementing that functionality for IIS. Apache core is worse than IIS; it is the availability of modules which make it appear that Apache is "more functional".

    And no, Microsoft can’t be the only ones creating modules for IIS. That would never scale. Thus, the real challenge is for users like you to step up and pick up the slack to add functionality to IIS.

    If you have an itch, scratch it; don’t complain to someone and try to make them scratch it for you, and then complain that no one is doing that for you for free…


  27. David Wang says:

    It never ceases to amaze me how easily users will download and install arbitrary binaries from arbitrary…

  28. talha says:

    hey david..

    i m new to isapi and i found this blog quite helpful..

    i m trying to make an isapi filter which logs the ip addresses and the urlzz accessed and other details of the users which access my website having extension .CBS..

    can u help me in dat..

    i m in real need of this coz my project is on hold..

    looking fwd to an early response..


  29. lkarve says:


    I am new to ISAPI.I need some help in developing an applicaion in which a Java API sends a http request to the server where the dll is stored.This dll handles the http request and sends the response back to the client.Also in the dll I want to write a db connection is it possible?



  30. David.Wang says:

    lkarve – what you want to do is possible, but why do you need to do it in ISAPI? It is much easier with ASP or ASP.Net on IIS.


  31. Chris Knight says:

    Oh thank you thank you thank you for this article; I’m new to ISAPI (long-time Apache extension programmer and VC++ programmer) and I was banging my head against the wall trying to get my .dll to load. MSDN should really provide some good examples ("hello world") of ISAPI extensions.

  32. David.Wang says:

    Chris – You’re welcome, and welcome to IIS!

    Yeah, I have found MSDN a real mixed bag. On the one hand, it is the only place that states everything. On the other hand, I often want different type of documentation than what it publishes.

    Hence, I chose to blog the sort of information and insight that is rarely captured in formal documentation, so that it can be helpful.


  33. Sean says:

    Great Article!

    Instructions work for VS2008 as well only issue I had was with C++ –> Code Generation –> Runtime Library had to be set to MultiThreaded Debug(/MTd)

    My ISAPI filetr compiled and loaded in IIS 6.0 first go!.



  34. David.Wang says:

    Sean – Thanks.

    Actually, your issue and resolution regarding Runtime Library have nothing to do with the instructions and requires more explanation

    That value always has to match with the debugging support installed on the server, which depends on the dependencies of your ISAPI Filter. See this URL for a quick description:

    In essence, your problem results because you don’t have the debug DLLs installed on the target machine and therefore need to compile them staticly into your DLL.

    However, it is not a requirement for ISAPI Source Code in general.


  35. ori says:

    I have a problem when downloading (using eVC IDE debugger) the ISAPI dll. I get the "403" ERROR when surfing to the ISAPI web page. I looked for this and found out there is a permission problem with a file.

     do you know how to use eVC4 to resolve the "permission denied" = 403 ERROR ?



  36. henry says:

    hello,i want to design a isapi extension instead of isapi filter.but i do not know how to make it.can you supply a simple example,thank you very much.

  37. JoeW says:

    I am trying to find a way to add custom content to the windows event log [like url and IP] when authentication fails and the Web Site is set to Windows Authentication. ISAPI looks like it would work if I can write to event logs, is this even possible?