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
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
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
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 EXPORTS GetExtensionVersion HttpExtensionProc
or
LIBRARY Your_ISAPI_Filter_Name EXPORTS GetFilterVersion HttpFilterProc
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
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)
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
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 EXPORTS GetExtensionVersion HttpExtensionProc
or
LIBRARY Your_ISAPI_Filter_Name EXPORTS GetFilterVersion HttpFilterProc
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()]
- General... Configuration Type -> Change to "Dynamic Library (.dll)"
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. :-P
//David
Comments
Anonymous
December 19, 2005
If you cannot proofread your comments, perhaps you should not be making them?Anonymous
December 19, 2005
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.
//DavidAnonymous
December 19, 2005
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.Anonymous
December 19, 2005
As for my proofreading, I beg the fact that it's two in the morning.Anonymous
December 20, 2005
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...Anonymous
December 20, 2005
The comment has been removedAnonymous
December 20, 2005
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.
//DavidAnonymous
December 20, 2005
The comment has been removedAnonymous
December 20, 2005
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.
//DavidAnonymous
December 20, 2005
The comment has been removedAnonymous
December 20, 2005
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. :-)
//DavidAnonymous
January 25, 2006
I'm curious why you can't just post the DLL??Anonymous
January 25, 2006
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?
//DavidAnonymous
February 06, 2006
Hello,
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 AndreAnonymous
February 06, 2006
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 site:microsoft.com".
//DavidAnonymous
February 06, 2006
Hello,
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.
Thanks
AndreAnonymous
February 07, 2006
The comment has been removedAnonymous
February 10, 2006
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. ;-)
Thanks
AndreAnonymous
February 10, 2006
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.
//DavidAnonymous
February 10, 2006
Hello,
if found a free viewable status-page (not my server)
http://www.vertexdev.com/server-status
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.
AndreAnonymous
February 10, 2006
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.
//DavidAnonymous
February 12, 2006
The comment has been removedAnonymous
February 13, 2006
Andre - Thanks for the thought... but I probably do not have time at the moment to do it.
You can post your idea to http://weblogs.asp.net/scottgu/ and see if it works out some other way.
In the end, it is the community that matters; code availability is an associated effect...
//DavidAnonymous
February 23, 2006
The comment has been removedAnonymous
February 23, 2006
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...
//DavidAnonymous
April 06, 2006
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.
http://httpd.apache.org/docs/2.0/mod/mod_usertrack.html
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. ;-)
MikeAnonymous
April 06, 2006
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...
//DavidAnonymous
April 25, 2006
It never ceases to amaze me how easily users will download and install arbitrary binaries from arbitrary...Anonymous
May 05, 2006
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..
TalhaAnonymous
December 17, 2007
Hi 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? Thanks LeenaAnonymous
December 19, 2007
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. //DavidAnonymous
May 06, 2008
The comment has been removedAnonymous
May 06, 2008
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. //DavidAnonymous
May 21, 2008
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!. Cheers SeanAnonymous
May 22, 2008
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: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2935111&SiteID=1 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. //DavidAnonymous
June 03, 2008
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 ? TX OriAnonymous
October 17, 2009
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.Anonymous
August 12, 2010
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?