<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">David Wang</title><subtitle type="html">David Wang on IIS, ISAPI, Exchange, Virtual Server, and whatever else I fancy...</subtitle><id>http://blogs.msdn.com/b/david.wang/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/david.wang/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2007-04-11T14:15:00Z</updated><entry><title>HOWTO: IIS 6 Request Processing Basics, Part 2 - Web Site, Virtual Directory, and Web Application</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2008/12/07/howto-iis-6-request-processing-basics-part-2-web-site-virtual-directory-and-web-application.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2008/12/07/howto-iis-6-request-processing-basics-part-2-web-site-virtual-directory-and-web-application.aspx</id><published>2008-12-07T19:24:00Z</published><updated>2008-12-07T19:24:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: courier new"&gt;
&lt;P&gt;In brief, what is different about a virtual directory that is also set as a Web Application? I can have a virtual directory, and then optionally set it to be a Web Application. Beyond updating the metabase, what does IIS do that causes the virtual directory to "be" a Web application? And how is the runtime behavior or capabilities different between a virtual directory that is not also a Web application, and one that is a Web application?&lt;/P&gt;
&lt;P&gt;Is there anything different (in terms of runtime behavior or capabilities) between a Web Application defined on a Web Site root virtual directory, as compared to a Web Application additionally defined on a virtual directory beneath a Web Site root virtual directory (i.e., a "web application within a web application")?&lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;This is an often asked question and point of confusion. I will clarify the terms from an IIS perspective.&lt;/P&gt;
&lt;H4&gt;What's in a Name?&lt;/H4&gt;
&lt;P&gt;The generic terms "web application", "virtual directory", "virtual server", and "web site" are inconsistently defined between servers/applications/platforms, so you have to understand the term's meaning in each server/application/platform and translate appropriately. In fact, even Microsoft products do not standardize on a common meaning for those terms, and due to historical legacy of each product, they will likely never change, converge, nor standardize. Sigh.&lt;/P&gt;
&lt;P&gt;For example, a Sharepoint "Virtual Server" is the same as an IIS "Web Site" and not to be confused with Microsoft's "Virtual Server" virtualization platform, which hosts virtual machines - who themselves can end up hosting Sharepoint Virtual Servers aka IIS Web Sites. Confused yet? Good. :-)&lt;/P&gt;
&lt;P&gt;IIS's terminology does not include the term "Virtual Server". When most people talk about "Virtual Server" they are often thinking of an IIS Web Site, or something that answers HTTP requests to host their logical website, which consists of a single application codebase.&lt;/P&gt;
&lt;H4&gt;Web Site&lt;/H4&gt;
&lt;P&gt;An &lt;STRONG&gt;IIS Web Site&lt;/STRONG&gt; is a mapping between a &amp;lt;IP:Port:Hostname&amp;gt; Binding triplet and a "root" Web Application (defined shortly) that responds to "/". The Web Site is how IIS figures out whether it should handle any given HTTP request and if so, with what configuration. Since this determination directly affects how a HTTP request is handled, all Binding definitions MUST be unique on a IIS machine. You do not want two Web Sites potentially fighting over the same request, right? Now, the Binding triplet is different than the "Friendly Name", which is an optional string meant for User's identification benefit. It can be "Default Web Site" or anything else, and since it is optional and not used for request handling determination, it can be duplicate or not defined.&lt;/P&gt;
&lt;P&gt;For example, suppose you have the following Web Sites with the following Binding triplets. This is what each means: 
&lt;OL&gt;
&lt;LI&gt;:80: - across all IPs of all NICs, handle port 80 traffic, regardless of Host header&lt;/LI&gt;
&lt;LI&gt;12.34.56.78:443 - only requests to IP 12.34.56.67 on port 443&lt;/LI&gt;
&lt;LI&gt;:80:Domain2.com - across all IPs of all NICs, handle port 80 traffic for requests with Host header of Domain2.com&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;With this configuration, when IIS receives any request, it knows from TCP/IP which IP:Port the request is meant for, and if the data is unencrypted, it can decipher the Host: header, and with these three pieces of information, it can determine if it matches any Web Site's Binding definition (or none) and route/handle accordingly. If it matches nothing, a "400 Bad Request" response&amp;nbsp;is returned.&lt;/P&gt;
&lt;H4&gt;SSL Host Header (sidetrack)&lt;/H4&gt;
&lt;P&gt;At this point, I will briefly digress on another topic, SSL Host Headers.&lt;/P&gt;
&lt;P&gt;Technically, there is no such thing as SSL Host Header. From the perspective of the SSL Specification, host headers do not exist because they are defined in the HTTP specification and not TCP where SSL operates.&lt;/P&gt;
&lt;P&gt;When IIS receives any request, it only knows the IP:Port&amp;nbsp;that request is destined for. In order to determine the Host header of a request, IIS must decipher the request's payload data. And to do that for an SSL request, IIS has to first decrypt the payload data by using a Server Certificate to complete the SSL handshake with the Client. However, IIS needs to know the Host header in order to know which Binding, and hence which Server Certificate, to use to decrypt the payload data and decipher the Host header. This is clearly a Catch-22.&lt;/P&gt;
&lt;P&gt;So, how does IIS implement "SSL Host Headers"? It breaks the Catch-22 by requiring all sites using SSL Host Headers for a given Binding must be configured to&amp;nbsp;use the same Server Certificate. That way, when IIS gets a IP:Port of a request, it can unambiguously use that now-synchronized Server Certificate to first decrypt the Host: header, and THEN decide which Web Site matches the IP:Port:Host Binding and route the request to it.&lt;/P&gt;
&lt;H4&gt;Web Application&lt;/H4&gt;
&lt;P&gt;A &lt;STRONG&gt;Web Application&lt;/STRONG&gt; is a mapping between a name in the virtual namespace (i.e. the URLs "/", "/App", or "/cgi-bin") and its runtime properties. These runtime properties tell IIS how to execute a request which belongs in the virtual namespace. Common runtime properties include: 
&lt;UL&gt;
&lt;LI&gt;Whether user's application code is to be executed "In Process", "Out of Process", or "Pooled" [for IIS 4/5/5.1/6 in IIS5 Compatibility Mode] or specific Application Pood ID [for IIS6 in Worker Process Isolation Mode and IIS7]&lt;/LI&gt;
&lt;LI&gt;Process Identity used to execute program code&lt;/LI&gt;
&lt;LI&gt;Monitoring/Recycling Metrics&lt;/LI&gt;
&lt;LI&gt;etc...&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;By default, whenever you create a Web Site and define the Binding (and optionally the Friendly Name), IIS also creates a "root" Web Application for "/" and asks you for a Virtual Directory mapping (defined shortly). This is because people commonly create a Web Site to host a Web Application which consists of files located at same physical directory, so defining all three features make sense... but the three concepts are definitely different.&lt;/P&gt;
&lt;H4&gt;Virtual Directory&lt;/H4&gt;
&lt;P&gt;A &lt;STRONG&gt;Virtual Directory&lt;/STRONG&gt; is a mapping between a name in the virtual namespace (i.e. the URLs "/", "/App", or "/cgi-bin") and a corresponding physical name (i.e. the Filesystem name "C:\inetpub\wwwroot\App"). It allows IIS to calculate a physical resource name for any given virtual name and provide it to the handler of the request.&lt;/P&gt;
&lt;P&gt;For example, suppose "/" maps to the physical name "C:\inetpub\wwwroot".&amp;nbsp;A request for "/default.asp" refers to the physical name "C:\inetpub\wwwroot\default.asp".&lt;/P&gt;
&lt;P&gt;The astute reader should realize that the mapping provided by a Virtual Directory is merely a "recommendation" by IIS to the request's handler - the actual handler of a request can do whatever mapping it wants with the virtual and physical names provided.&lt;/P&gt;
&lt;P&gt;In the case of /default.asp, IIS first goes through &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/10/14/HOWTO_IIS_6_Request_Processing_Basics_Part_1.aspx" mce_href="http://blogs.msdn.com/david.wang/archive/2005/10/14/HOWTO_IIS_6_Request_Processing_Basics_Part_1.aspx"&gt;this process&lt;/A&gt; to figure out the handler. Suppose it ends up being ASP.DLL - it will honor the physical name C:\inetpub\wwwroot\default.asp and execute the script contained within it to generate a response.&lt;/P&gt;
&lt;P&gt;However, the handler or its script code can choose to implement its own name mapping scheme to process a given request. For example, some people write ASP pages like "redir.asp" which return different responses based on template&amp;nbsp;HTML stored within a SQL&amp;nbsp;database&amp;nbsp;depending on the querystring. i.e. /redir.asp?id=1 will load up some template HTML in SQL and generate a HTML response. Clearly, Virtual Directory is only a hint/recommendation provided by IIS to the request handler, which can do whatever it wants with the information.&lt;/P&gt;
&lt;H4&gt;Conclusion&lt;/H4&gt;
&lt;P&gt;Given the above information, the answers to your questions are straight forward.&lt;/P&gt;
&lt;P&gt;A plain Virtual Directory provides a virtual/physical name mapping and MUST inherit and use the runtime settings defined at its nearest parent to execute code contained within it.&lt;/P&gt;
&lt;P&gt;A Virtual Directory that is also a Web Application has the option to inherit from its nearest parent AND customize runtime settings to execute code contained within it.&lt;/P&gt;
&lt;P&gt;Clearly, if you do not customize runtime settings, then it is not necessary to create a Web Application. And if you create a Web Application and customize runtime settings, then behavior of code execution may be different than a plain Virtual Directory (assuming that the inherited settings by the Virtual Directory&amp;nbsp;do not match the customized settings of the Web Application).&lt;/P&gt;
&lt;P&gt;As for differences between a "root" Web Application and a nested Web Application within another Web Application or Virtual Directory. IIS does not treat them&amp;nbsp;differently since Web Applications are just runtime settings. However, application platforms running on top of IIS may choose to interpret the "application root" of an Web Application differently and behave accordingly. For example, ASP.Net uses "Web Application" to delimit the boundaries of its applications, so if you nest a Web Application within another, you end up with two different ASP.Net Web Applications.&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9181992" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /><category term="Tips" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/" /><category term="HOWTO..." scheme="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/" /></entry><entry><title>HOWTO: PreCondition an ISAPI Extension DLL</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2008/10/30/howto-precondition-an-isapi-extension-dll.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2008/10/30/howto-precondition-an-isapi-extension-dll.aspx</id><published>2008-10-31T08:00:00Z</published><updated>2008-10-31T08:00:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: Courier New"&gt;
&lt;P&gt;Hello&lt;/P&gt;
&lt;P&gt;We have a legacy x64 ISAPI extension that runs without problems in Win 2003 64bit - IIS 6.0.&lt;/P&gt;
&lt;P&gt;But in Win2008 EBS Security Manager setup, IIS 7.0 Default Application Pool's WOW64 / Enable32BitApp property is enabled by default, and this makes x64 ISAPI extension DLL to fail loading.&lt;/P&gt;
&lt;P&gt;By setting the Enable32BitApp option as false in application pool settings, the problem gets resolved.&lt;/P&gt;
&lt;P&gt;However we want to speicify ISAPI extension explicitly to be loaded as x64 module using "precondition='bitness64' " settings like ISAPI filters, so that ISAPI extension works no matter what application pool is configured for (x64 only, or both x64 and x86)&lt;/P&gt;
&lt;P&gt;Could anyone please suggest how we can do this or the app cmd that would allow us to do it.&lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Technically, preConditions only apply on a per-GlobalModule, per-Module, per-Handler, or per-ISAPI Filter basis. This is because globalModules, modules, handlers, and ISAPI Filters have to be explicitly configured within IIS to function. ISAPI Extensions simply need to be dropped into a web-accessible folder and then "allowed to execute" via Executable execution permission and IsapiCgiRestriction. There is no per-ISAPI Extension configuration to stick preConditions.&lt;/P&gt;
&lt;P&gt;However, as I will illustrate shortly, it is STILL possible to&amp;nbsp;apply preConditions on a per-ISAPI Extension basis in a fairly clean and clear manner.&lt;/P&gt;
&lt;P&gt;Some people would propose that it would be nice to stick&amp;nbsp;preCondition onto IsapiCgiRestriction since it is a sort of per-ISAPI Extension configuration, but IsapiCgiRestriction is really a security configuration which we hardly want to preCondition. Besides, what happens if notListedIsapisAllowed="true" and we still want to preCondition an ISAPI Extension - now we have to add a bogus entry for preCondition? Anyways, this is getting complicated very quickly, a sure sign that the proposed design has some fundamental logical flaw.&lt;/P&gt;
&lt;H4&gt;Common Misconceptions about Bitness and preConditions&amp;nbsp;&lt;/H4&gt;
&lt;P&gt;Now, before I get into how to setup per-ISAPI Extension preCondition, I want to clarify some of the misconceptions in your question about Bitness and preCondition. Using preCondition="bitness64" does NOT:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Explicitly load an ISAPI Extension as x64 module&lt;/LI&gt;
&lt;LI&gt;Make an ISAPI work no matter what the application pool is configured for&lt;/LI&gt;
&lt;LI&gt;Allow "both x64 and x86" of ANYTHING&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;A preCondition is a simple filtering mechanism on the affected IIS configuration. What preCondition="bitness64" means is that the affected configuration is ONLY applicable in a 64bit Application Pool.&amp;nbsp;A 64bit Application Pool will only see globalModule, module, handler, and isapiFilter with either bitness64 or no bitness preCondition. It will not see any globalModule, module, handler, and isapiFilter configuration with the bitness32 preCondition.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Thus, a preCondition does NOT cause an ISAPI to be explicitly loaded as any bitness. LoadLibrary() will just load the resolved DLL name into the process's address space, and if the bitness do not match, fail. Likewise, it cannot make the ISAPI work no matter what, because if the bitness does not match, it fails. Finally, Windows does not allow both 32bit and 64bit code to co-exist in the same process, and IIS does not allow an Application Pool to be both 32bit and 64bit.&lt;/P&gt;
&lt;P mce_keep="true"&gt;What is a correct way to use the bitness preConditions? Check out the various pre-defined "-64" handlers when ASP.Net Feature support is installed. For example, the svc-ISAPI-2.0 and svc-ISAPI-2.0-64 handlers. Notice that the bitness32 preCondition applies to a 32bit ISAPI, and bitness64 preCondition applies to a separate 64bit ISAPI. This dual configuration allows the same feature to work with both 32bit and 64bit Application Pools with no additional configurations changes in-between. Remember how you had to run aspnet_regiis.exe from the correct Framework bitness directory every time you changed Application Pool bitness with .Net Framework 2.0 on IIS6 in 64bit Windows, or else you would see 503 Service Unavailable failure? No longer necessary with preConditions on IIS7 and things just work!&lt;/P&gt;
&lt;H4&gt;PreConditioning an ISAPI Extension DLL&lt;/H4&gt;
&lt;P&gt;As I mentioned earlier, per-ISAPI Extension preCondition can be accomplished by leveraging preCondition support of handlers. The following configuration shows how to request an ISAPI Extension name "MyISAPI.dll" and have it work no matter the bitness of the Application Pool. It requires a 32bit version and 64bit version of the same DLL, named MyISAPI32.dll and MyISAPI64.dll, respectively.&lt;/P&gt;&lt;PRE&gt;&amp;lt;handlers&amp;gt;
  ...
  &amp;lt;add name="MyISAPI-64" path="MyISAPI.dll" verb="*" modules="IsapiModule" scriptProcessor="C:\inetpub\wwwroot\bin\MyISAPI64.dll" resourceType="File" requireAccess="Execute" preCondition="bitness64" /&amp;gt;
  &amp;lt;add name="MyISAPI-32" path="MyISAPI.dll" verb="*" modules="IsapiModule" scriptProcessor="C:\inetpub\wwwroot\bin\MyISAPI32.dll" resourceType="File" requireAccess="Execute" preCondition="bitness32" /&amp;gt;
  ...
&amp;lt;/handlers&amp;gt;&lt;/PRE&gt;
&lt;P&gt;Looking at the key configuration details:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Having two handlers, one with bitness32 preCondition on the 32bit MyISAPI32.dll, the other with bitness64 preCondition on the 64bit MyISAPI64.dll, assures that only one of these handlers with the correct bitness apply to any given Application Pool&lt;/LI&gt;
&lt;LI&gt;path="MyISAPI.dll" means that end consumers only request /MyISAPI.dll while the dynamic 32/64bit wiring happens underneath the covers via the bitness preCondition&lt;/LI&gt;
&lt;LI&gt;requireAccess="Execute" makes Execute permissions necessary to execute an ISAPI Extension DLL in a given URL namespace&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;The combination of preConditions, path-remapping, and requireAccess gives the illusion of a&amp;nbsp;single named ISAPI DLL which transparently works with similar requirements as ISAPI Extension&amp;nbsp;regardless of Application Pool bitness.&amp;nbsp;Yes, don't forget to set IsapiCgiRestriction on both MyISAPI64.dll and MyISAPI32.dll as well as enable "Execute" permission on your virtual directory... :-)&lt;/P&gt;
&lt;P mce_keep="true"&gt;Cheers.&lt;/P&gt;
&lt;P mce_keep="true"&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9025890" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="ISAPI" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/" /><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /><category term="Tips" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/" /><category term="HOWTO..." scheme="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/" /><category term="IIS7" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/" /></entry><entry><title>WebDAV, Source, and Read Permissions on IIS</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2008/09/29/webdav-source-and-read-permissions-on-iis.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2008/09/29/webdav-source-and-read-permissions-on-iis.aspx</id><published>2008-09-29T17:44:00Z</published><updated>2008-09-29T17:44:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: courier new"&gt;Hello: 
&lt;P&gt;With the new WebDAV upgrade in IIS 7.0, there is a permission named "Source". How is the "Source" permission different from "Read" please?&lt;/P&gt;
&lt;P&gt;What if "Source" is enabled but "Read" is not??&lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Source and Read permissions control different behaviors.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Read&lt;/STRONG&gt; permission controls whether the IIS Static File Handler allows the requested resource to be retrieved (i.e. read) as the response. This action is subject to all behaviors of the IIS Static File Handler, including the MIME Type check.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Source&lt;/STRONG&gt; permission, when WebDAV functionality is present (i.e. installed/enabled), controls what happens when the request has the Translate: header. The logic looks like:&lt;/P&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: courier new"&gt;&lt;PRE&gt;If Translate:f AND "Source" is enabled Then
    // Handle with Static File Handler
Else
    // Continue processing normally
End If&lt;/PRE&gt;&lt;PRE&gt;&lt;/SPAN&gt;Thus, the interesting combination for "Source" happens when:&lt;/PRE&gt;
&lt;OL&gt;
&lt;LI&gt;Execute Permissions is either "Scripts" (or "Scripts and Executables") AND &lt;/LI&gt;
&lt;LI&gt;The requested resource extension has an applicable Application Mapping (or is a DLL/EXE) AND&lt;/LI&gt;
&lt;LI&gt;Request has Translate:f header&lt;/LI&gt;
&lt;LI&gt;"Source" Permission&amp;nbsp;is enabled (along with Read Permission)&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;In this special combination, the "un-translated" resource (i.e. the script source or DLL/EXE executable binary) gets served as the response by the IIS Static File Handler, INSTEAD of the usual execution of&amp;nbsp;the script or binary to generate the response. This mechanism is how a WebDAV client (via Translate:f) as well as WebDAV server (via Source Permission) cooperatively implement WebDAV behavior. Both client and server have to implement their part in order for WebDAV to work.&lt;/P&gt;
&lt;P&gt;Note that this allows WedDAV clients&amp;nbsp;to retrieve of raw source code of an ASPX file even though the virtual directory has Script Execute Permissions and a .aspx Application Mapping, while a normal HTTP client will see response generated by running the ASPX file.&lt;/P&gt;
&lt;P&gt;As for what happens when Source is enabled without Read - that is actually an incomplete question.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If Translate:f is present on the request, then a 403.2 is returned because the Static File Handler requires the Read permission and a MIME Type to be able to serve the response&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;If Translate:f is NOT present on the request, "Source" has no meaning and the request processes normally, as follows...&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;If the resource is handled by the Static File Handler, then a 403.2 is returned because of the missing Read Permission.&lt;/LI&gt;
&lt;LI&gt;If the resource is handled by an Application Mapping or DLL/EXE, then it depends on the Execute Permission.&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;If it is None, then it is 403.1 for Application Mapping and 403.2 for DLL/EXE because of the missing Read Permission&lt;/LI&gt;
&lt;LI&gt;If it is Scripts, then Application Mapping executes and 403.2 for DLL/EXE because of the missing Read Permission&lt;/LI&gt;
&lt;LI&gt;If it is Scripts and Executables, then both Application Mapping and DLL/EXE executes&lt;/LI&gt;&lt;/UL&gt;&lt;/UL&gt;&lt;/UL&gt;
&lt;P&gt;Note that when I mention Application Mapping and&amp;nbsp;DLL/EXE from an IIS6 perspective, it just maps into handlers on IIS7. The logic remains the same. To the astute reader - yes, you can play around with the ordering of handlers and modules on IIS7 to generate any set of behaviors, including the one mentioned above. And yes, I consider all such permutation of&amp;nbsp;behaviors valid because that is the power of a completely extensible platform. You are empowered to shoot anything else, including yourself, in the head.&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8968704" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /></entry><entry><title>Managed Modules and ISAPI Filters</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2008/09/08/managed-modules-and-isapi-filters.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2008/09/08/managed-modules-and-isapi-filters.aspx</id><published>2008-09-09T07:36:00Z</published><updated>2008-09-09T07:36:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: courier new"&gt;
&lt;P&gt;Hello,&lt;/P&gt;
&lt;P&gt;I have an isapi filter and a managed module. I need to put both in the same website and I need that the manage module run before the isapi filter. The sequence are: Module---&amp;gt;ISAPI filter. How can I do this? &lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;The answer really depends on the filter events that the ISAPI Filter subscribes to.&lt;/P&gt;
&lt;P&gt;Unfortunately, no built-in IIS UI or tool displays this information since it is rarely of interest to the user.&lt;/P&gt;
&lt;P&gt;However, you can use my tool from &lt;A class="" href="http://blogs.msdn.com/david.wang/archive/2006/03/02/HOWTO_Add_and_Remove_an_ISAPI_Filter_using_JScript.aspx" target=_blank mce_href="http://blogs.msdn.com/david.wang/archive/2006/03/02/HOWTO_Add_and_Remove_an_ISAPI_Filter_using_JScript.aspx"&gt;here&lt;/A&gt; to view the events that an ISAPI Filter subscribes for. To the astute reader - this filter status&amp;nbsp;information is only available AFTER IIS successfully loads an ISAPI Filter (i.e. IIS successfully LoadLibrary(), GetProcAddress() the Filter DLL's GetFilterVersion() exported function, executes it&amp;nbsp;for registered events, and the function returns TRUE to IIS), and depending on IIS version/mode and the type of ISAPI Filter, IIS ends up loading an ISAPI Filter at different times. The history and rationale behind the differences is an entire blog entry all to itself, but the following table&amp;nbsp;is a sufficient summary for now:&lt;/P&gt;
&lt;TABLE class="" border=1&gt;
&lt;TBODY&gt;
&lt;TR bgColor=#000000&gt;
&lt;TD class=""&gt;&lt;FONT color=#ffffff&gt;IIS Version (Mode)&lt;/FONT&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;FONT color=#ffffff&gt;Global Filter Loads...&lt;/FONT&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;FONT color=#ffffff&gt;Site Filter Loads...&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;IIS4 / IIS5 / IIS5.1&lt;/TD&gt;
&lt;TD class=""&gt;On Server Startup&lt;/TD&gt;
&lt;TD class=""&gt;When Configured for a Website&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;IIS6 (IIS5 Compatibility Mode)&lt;/TD&gt;
&lt;TD class=""&gt;On Server Startup&lt;/TD&gt;
&lt;TD class=""&gt;When Configured, on first request to that Website&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;IIS6 (Worker Process Isolation Mode)&lt;/TD&gt;
&lt;TD class=""&gt;On w3wp.exe Startup&lt;/TD&gt;
&lt;TD class=""&gt;When Configured, on first request to that Website&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;IIS7 (Classic and Integrated Modes)&lt;/TD&gt;
&lt;TD class=""&gt;Same as IIS6 Worker Process Isolation&amp;nbsp;Mode&lt;/TD&gt;
&lt;TD class=""&gt;Same as IIS6 Worker Process Isolation Mode&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H4&gt;It's all about Timing&lt;/H4&gt;
&lt;P mce_keep="true"&gt;Now, you may wonder WHY knowing the subscribed filter events affect the answer. As in life and most things in our four dimensional world, it's all about timing, and this situation is no exception.&lt;/P&gt;
&lt;P mce_keep="true"&gt;ISAPI Filter triggers on various events fired by IIS throughout a request's processing, while Managed Modules trigger after only one of those events (and in IIS7 in Integrated Pipeline Mode, Managed Modules trigger on ALMOST all of the events). Thus, if you want the Managed Module to run before the ISAPI Filter, the ISAPI Filter's subscribed events must be limited to those that happen AFTER&amp;nbsp;the Module triggers.&lt;/P&gt;
&lt;P&gt;Since Modules trigger pretty late in the request processing, right before response generation and logging, and ISAPI Filters typically trigger early in the request process, to perform either custom authentication, URL rewriting, etc, it is highly likely that what you want to do is impossible&amp;nbsp;on any IIS version&amp;nbsp;- without knowing the exact filter events involved, I cannot be definitive.&lt;/P&gt;
&lt;P&gt;The following is a condensed outline of how ISAPI Filter and Managed Modules triggering are ordered:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;On IIS4, IIS5, IIS5.1, and IIS6, Managed Modules trigger between the SF_NOTIFY_AUTH_COMPLETE and SF_NOTIFY_SEND_RESPONSE filter events.&lt;/LI&gt;
&lt;LI&gt;On IIS7 in Classic Pipeline Mode, things behave as in IIS6.&lt;/LI&gt;
&lt;LI&gt;On IIS7 in Integrated Pipeline Mode, Managed Modules trigger in-line with all ISAPI Filter events in all Pipeline Modes (Classic and Integrated) because ISAPI Filters are actually just DLLs loaded by the "ISAPI Filter" Module, which acts as a shim to trigger appropriate ISAPI Filter events for the corresponding&amp;nbsp;Module events of the Integrated Pipeline. For example, the "ISAPI Filter Module" subscribes for the OnPreBeginRequest event, which when triggered by IIS will cause it to fire the SF_NOTIFY_PREPROC_HEADERS filter event to all applicable ISAPI Filters for that URL scope.&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Conclusion&lt;/H4&gt;
&lt;P&gt;In general, if your ISAPI filter does NOT subscribe to events earlier than SF_NOTIFY_SEND_RESPONSE, it would be possible for a Managed Module to execute before the ISAPI filter triggers.&lt;/P&gt;
&lt;P&gt;You should notice some direct correlations between the Module events of the IIS7 Integrated Pipeline and a merging of the ISAPI Filter events and classic ASP.Net HttpModule events. This is intentional - that is what we meant with the name "Integrated" Pipeline! :-)&lt;/P&gt;
&lt;P&gt;The astute reader should note that Managed Modules on IIS7 do not have access to the OnPreBeginRequest module event. Since that event is used by the "ISAPI Filter" Module to trigger the SF_NOTIFY_PREPROC_HEADERS event, this means that even in Integrated Pipeline mode, where Managed Modules trigger in-line with any other module&amp;nbsp;such as&amp;nbsp;the "ISAPI Filter" Module shim, a Managed Module will NOT be able to execute before an ISAPI Filter that subscribes to the SF_NOTIFY_PREPROC_HEADERS event.&lt;/P&gt;
&lt;P&gt;Yes, there is a huge story behind why OnPreBeginRequest even exists and why Managed Modules do not have access to that event (and other such global notification events). The blurbs on MSDN simply does not do it justice...&lt;/P&gt;
&lt;P&gt;But at long last, here is the long-winded response to it all.&lt;/P&gt;
&lt;P&gt;Cheers!&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8935722" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="ISAPI" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/" /><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /><category term="IIS7" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/" /></entry><entry><title>HOWTO: Change IIS User Impersonation Token</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2008/06/02/howto-change-iis-user-impersonation-token.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2008/06/02/howto-change-iis-user-impersonation-token.aspx</id><published>2008-06-02T10:30:00Z</published><updated>2008-06-02T10:30:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: Courier new"&gt;
&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;We are using our third party component for doing authentication and authorization with IIS6 web server on win2k3 X64 EE. Here we are using IMPERSONATION concept for this integration.&lt;/P&gt;
&lt;P&gt;Can anybody describe the required configuration which are needed at IIS 6 for successfully impersonation of users with third party component?&lt;/P&gt;
&lt;P&gt;Should we need to set Anonymous authentication explicitely for this kind of configuration?&lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Third party code will not be able to directly impersonate and have IIS use that user token. IIS will:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Strip off the impersonation token after ISAPI Extension returns control to it&lt;/LI&gt;
&lt;LI&gt;Ignore and re-apply IIS's desired impersonation token if ISAPI Filter changed it&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Thus, the only way for you to impersonate users with IIS is to change IIS's desired impersonation token. The following are the methods, in no particular order, that ISAPI can change IIS's desired impersonation token and hence control impersonated user. The method you choose depends on your authentication protocol's requirements.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;ISAPI Filter - SF_NOTIFY_PREPROC_HEADERS&lt;/STRONG&gt; event - change the "Authorization" request header value to be: Basic [base64 encoding of username:password] . Requires Basic Authentication enabled in IIS.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;ISAPI Filter - SF_NOTIFY_AUTHENTICATION&lt;/STRONG&gt; event - change pszUser and pszPassword fields on HTTP_FILTER_AUTHENT. Remember to SET your values&amp;nbsp;into the provided buffers (and change the cbUserBuff/cbPasswordBuf values) because those are the actual buffers IIS will use. Requires Anonymous or Basic Authentication enabled in IIS.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;ISAPI Extension - HSE_REQ_EXEC_URL&lt;/STRONG&gt; configured as Wildcard Application Mapping - change hImpersonationToken field on HSE_EXEC_URL_USER_INFO to be the actual NT User Token used by IIS for request impersonation. Requires Anonymous Authentication enabled in IIS.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8568348" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="ISAPI" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/" /><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /><category term="HOWTO..." scheme="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/" /></entry><entry><title>IIS7 Handlers - accessPolicy and requireAccess</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2008/06/01/iis7-handlers-accesspolicy-and-requireaccess.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2008/06/01/iis7-handlers-accesspolicy-and-requireaccess.aspx</id><published>2008-06-01T11:50:00Z</published><updated>2008-06-01T11:50:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008800; FONT-FAMILY: courier"&gt;
&lt;P&gt;Hello:&lt;/P&gt;
&lt;P&gt;In IIS 7.0, you can edit a handler mapping in the Handler Mappings applet (like for AspClassic), then click Request Restrictions button, Access tab, and select the "Write" permission. &amp;nbsp;But even when the "Edit Feature Permission" in that site/folder is set to Read+Script+Execute, the handler with the "Write" permission is still disabled!&lt;/P&gt;
&lt;P&gt;Why?&lt;/P&gt;
&lt;P&gt;How do you both keep a handler enabled and also set its request restriction to "Write" at the same time? I've read through all the IIS help files, they're either silent or incorrect on this question.&lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;What you want to do is not achievable via the UI. You have to configure the .config file directly.&lt;/P&gt;
&lt;P&gt;This looks like a bug in the UI because the "accessPolicy" and "requireAccess" attributes are not aligned.&lt;/P&gt;
&lt;P&gt;Here's what the UI is attempting to do:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;accessPolicy corresponds to the old "Execute Permissions" set of checkboxes&lt;/LI&gt;
&lt;LI&gt;requireAccess is brand new in IIS7. After we opened up the handler definition in IIS7, it became necessary to add requireAccess so that one could express the concept of "this handler requires script access permissions to execute" so that one could then use accessPolicy to control whether "scripts" can run or not.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Before IIS7, the logical tie between handlers and requireAccess was hardcoded into IIS into statements like:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;StaticFileHandler requires Read Permission&lt;/LI&gt;
&lt;LI&gt;All Other Handlers require Script Permission&lt;/LI&gt;
&lt;LI&gt;EXE and DLL require Execute Permission&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Starting from IIS7, it is completely wide open. The astute reader should realize that it is possible in IIS7 to do something goofy like set ISAPI Handler to require "no" permissions (instead of Execute) and allow the ISAPI Handler to be executed by IIS Core all the time. However, the actual execution of an ISAPI DLL by the ISAPI Handler is still subject to ISAPI CGI Restriction. This is another example of defense in depth!&lt;/P&gt;
&lt;P&gt;What the UI tries to display via the "State" view is: "if you allow only scripts, only these handlers are active". Of course, it is missing the "Write" permission as a filter. Even though the handler require access dialog just added "Write". Thus, when you selected "Write" request restriction for the handler, it makes it impossible for the UI to display as enabled because it does not have "Write" permission as a filter.&lt;/P&gt;
&lt;P&gt;I would chalk this up as a bug introduced when WebDAV was added for Windows Server 2008 because that's the main module that needs it. However, if you think about what I just said, this is really easy to work around. Remember, IIS7 does not know what "Execute" permission is (or else the goofy ISAPI Handler configuration would not be possible), so&amp;nbsp;IIS7 does not know what "Write" permission is, either.&lt;/P&gt;
&lt;P&gt;Internally, the handler execution logic in IIS7 Core is:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;accessPolicy contains "Text1, Text2, Text3".&lt;/LI&gt;
&lt;LI&gt;handler's requireAccess contains "Text3".&lt;/LI&gt;
&lt;LI&gt;requireAccess text is found inside of accessPolicy text. Allow handler execution.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8567407" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /><category term="IIS7" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/" /></entry><entry><title>Choice of Development Platform for IIS Modules</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2008/04/18/choice-of-development-platform-for-iis-modules.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2008/04/18/choice-of-development-platform-for-iis-modules.aspx</id><published>2008-04-18T11:40:00Z</published><updated>2008-04-18T11:40:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: courier new"&gt;
&lt;P&gt;I am starting a new project (ASP.NET 3.5) that will require at least one custom HTTP module. My two development computers are running 32-bit XP Pro/SP2, but I plan to reimage with Vista (already have it ready to be installed). My preference would be to NOT switch to Vista quite yet, but continue the project with my XP Pro systems.&lt;/P&gt;
&lt;P&gt;Is it possible or reasonable to proceed with developing the custom HTTP module(s) with my XP Pro system (IIS 5.1) and expect that they will work just fine with IIS7 - and with no changes - when I upgrade to Vista? Or do I really need to switch to Vista before developing these custom HTTP modules?&lt;/P&gt;
&lt;P&gt;One module will implement a custom authentication scheme. Another will load an assembly into a separate app domain, execute some code, marshal the results back, stick them into the ASP.NET application state, and then kill that separate app domain.&lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;I think the choice of development platform should depend on the features you want to provide and the platforms you plan to support. Personal preference and upgrade schedule should not decide the development platform unless you also want&amp;nbsp;them to decide your potential user/customer base.&lt;/P&gt;
&lt;P&gt;Personally, I believe you should develop on Vista, and here is why.&lt;/P&gt;
&lt;P&gt;First, IIS7 is finally the release where the development experience on the client OS matches the corresponding server OS. No more hassling over XP Pro and Windows Server 2003 differences in everything related to IIS, from security ACLs, security models, Application isolation between high/medium/low and Application Pools, Web Service Restrictions on CGI and ISAPI, configuration changes, TCP Connection limitations, etc... you get the picture. The same IIS7 server core is on Vista and Windows Server 2008, with the same security model, application isolation, configuration files, etc. Unity at last.&lt;/P&gt;
&lt;P&gt;Now, for some more technical reasons. IIS7 has two "Pipeline modes", classic and integrated, that offer completely different behavior/abilities for certain events (authentication being one of them):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Classic mode is supposed to mirror ASP.Net behavior on IIS5x/6.0. With some minor tweaks while reconciling IIS and ASP.Net behavior.&lt;/LI&gt;
&lt;LI&gt;Integrated mode is completely new and represents true managed code extensibility of IIS for the future that mostly matches the native code extensibility of IIS.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I must warn that Classic mode will NEVER match Integrated mode in terms of features and functionality - it exists only for legacy, compatibility reasons. Thus, by definition, the two modes are different.&lt;/P&gt;
&lt;P&gt;So, yes, it should be relatively painless to author a Custom Authentication HttpModule in ASP.Net on IIS 5.1 and run it in Classic mode on IIS7. However, that module will likely fail when you switch to Integrated mode, especially for Authentication since it is one of those events whose ordering changes (intentionally, for the better) between Classic and Integrated mode.&lt;/P&gt;
&lt;P&gt;In fact, the way you configure that module will be different in IIS7 between the&amp;nbsp;two modes:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;In Integrated mode, your simply add a new &amp;lt;module&amp;gt; using the type of your custom auth assembly in &amp;lt;modules&amp;gt;, and optionally add a preCondition to determine if&amp;nbsp;the module&amp;nbsp;should only run on requests involving managed code (i.e. only .aspx, .asmx, etc pages) or all requests (i.e. .html,&amp;nbsp;.xml, .css, .asp, .php,&amp;nbsp;pages).&lt;BR&gt;&lt;BR&gt;This is exactly what people tried (in vain) to do with ASP.Net 2.0 on IIS6 but could not, and certainly not with the elegance and compactness of preConditions.&lt;BR&gt;&lt;BR&gt;Instead, what one needs to do is the following set of kludges...&lt;/LI&gt;
&lt;LI&gt;In Classic mode, you need configuration that emulates what it took on IIS6 to get similar (but not identical) behavior. This means: 
&lt;OL&gt;
&lt;LI&gt;*-scriptmap to aspnet_isapi.dll -- this is now a *-&amp;lt;handler&amp;gt; to isapi.dll with aspnet_isapi.dll as the scriptProcessor&lt;/LI&gt;
&lt;LI&gt;&amp;lt;httpHandler&amp;gt; for * which derives from DefaultHttpHandler and tweaks some special settings on the HttpContext to cause it to call the HSE_REQ_EXEC_URL ISAPI ServerSupportFunction underneath the covers&lt;/LI&gt;
&lt;LI&gt;Order the remaining &amp;lt;httpHandlers&amp;gt; correctly relative to #2 to get reasonable behavior&lt;/LI&gt;&lt;/OL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The astute reader will remind you that I just rushed through a WHOLE lot of details there, which many&amp;nbsp;people have dedicated countless number of hours of&amp;nbsp;pain/frustration/anguish&amp;nbsp;and countless fragments of articles describing how to get an ASP.Net 2.0 Custom Authentication Module to [not] work on IIS 6. And what I just described does not even apply or work on the IIS 5.1 on XP Pro 32bit scenario you just described, unless you intend to only implement Custom Authentication module for ASP.Net pages and static files.&lt;/P&gt;
&lt;P&gt;Now, we could have made it easier on the users (but much harder on us) in implementation, but we chose the clean implementation you currently see PRECISELY because it starkly shows how much more elegent Integrated mode is in comparison to classic mode at resolving the issue of managed code extensibility of IIS.&lt;/P&gt;
&lt;P&gt;I hope this helps frame the discussion for your future development&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8407040" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="IIS7" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/" /></entry><entry><title>HOWTO: List all Virtual Directories and Paths of a List of Servers</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2007/12/19/howto-list-all-virtual-directories-and-paths-of-a-list-of-servers.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2007/12/19/howto-list-all-virtual-directories-and-paths-of-a-list-of-servers.aspx</id><published>2007-12-20T08:30:00Z</published><updated>2007-12-20T08:30:00Z</updated><content type="html">&lt;H3&gt;Question:&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: Courier New"&gt;
&lt;P&gt;I need to audit web servers in my domain, and would like to be able to connect to each server, and enumerate the virtual directories -- ultimately leading to a link to each web site hosted by the server. Can &lt;A href="http://blogs.msdn.com/david.wang/archive/2006/06/08/HOWTO-Enumerate-IIS-website-and-ftpsite-configuration-VBScript-using-ADSI.aspx" mce_href="http://blogs.msdn.com/david.wang/archive/2006/06/08/HOWTO-Enumerate-IIS-website-and-ftpsite-configuration-VBScript-using-ADSI.aspx"&gt;this code&lt;/A&gt; be modified to get that information?&lt;/P&gt;
&lt;P&gt;Thanks.&lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Yes, you can modify that code to get this information, but if you just want a list of virtual directories on a server, you don't need to write any script code to do it. At the end of this blog entry is one way, using a simple batch file,&amp;nbsp;to get this information using ADSUTIL.VBS, a built-in script. Just make sure to provide the right filepath for CMD_ADSUTIL. And of course, the user running the script must have administrator privileges to enumerate the IIS metabase on all required servers.&lt;/P&gt;
&lt;P&gt;This batch file accepts one optional input parameter.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If you provide no parameter, it will enumerate all vdirs and their respective physical paths of the local computer 
&lt;LI&gt;If you provide a computer name, it will enumerate all vdirs of that computer 
&lt;LI&gt;If you provide a filepath, it will treat each line of the file as a computer name and enumerate all its vdirs &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Since I often see this feature requested, I decided to show one simple way to turn a script which takes a server name as input into one that loops through a list of server names stored in a text file, one server name on each line. This should hopefully be illustrative enough of the powerful combination of both VBScript/JScript and Batch script.&lt;/P&gt;
&lt;H4&gt;Sample usage:&lt;/H4&gt;&lt;PRE&gt;C:\&amp;gt;enumvdirs -?
enumvdirs [servername | file-list]

Where:
    servername is the name of the server to query. DAVIDWANG by default
    file-list is filepath to text file containing list of servers, one per line

C:\&amp;gt;enumvdirs DAVIDWANG
DAVIDWANG/W3SVC/1/ROOT = "c:\inetpub\wwwroot"
DAVIDWANG/W3SVC/1/ROOT/IISHelp = "c:\windows\help\iishelp"
DAVIDWANG/W3SVC/1/ROOT/Printers = "C:\WINDOWS\web\printers"
DAVIDWANG/W3SVC/1/ROOT/Scripts = "C:\Inetpub\Scripts"

C:\&amp;gt;ECHO %COMPUTERNAME% &amp;gt; ListOfServers.txt

C:\&amp;gt;TYPE ListOfServers.txt
DAVIDWANG

C:\&amp;gt;enumvdirs ListOfServers.txt
DAVIDWANG/W3SVC/1/ROOT = "c:\inetpub\wwwroot"
DAVIDWANG/W3SVC/1/ROOT/IISHelp = "c:\windows\help\iishelp"
DAVIDWANG/W3SVC/1/ROOT/Printers = "C:\WINDOWS\web\printers"
DAVIDWANG/W3SVC/1/ROOT/Scripts = "C:\Inetpub\Scripts"&lt;/PRE&gt;
&lt;P&gt;Enjoy.&lt;/P&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: Courier New"&gt;&lt;PRE&gt;@IF NOT DEFINED _ECHO ECHO OFF
SETLOCAL
SET CMD_ADSUTIL=CSCRIPT.EXE //Nologo %SYSTEMDRIVE%\Inetpub\Adminscripts\ADSUTIL.VBS
SET PROPERTY_TO_FIND=Path

SET SERVERS="%1"
IF ?%1? EQU ?? SET SERVERS="%COMPUTERNAME%"
IF EXIST %SERVERS% SET SERVERS=%SERVERS:~1,-1%

SET NEED_HELP=%SERVERS:?=%
IF /I "%NEED_HELP%" NEQ "%SERVERS%" GOTO :Help

FOR /F %%A IN ( %SERVERS% ) DO (
    FOR /F "usebackq skip=1 tokens=*" %%I IN ( `%CMD_ADSUTIL% FIND %PROPERTY_TO_FIND% -s:%%A` ) DO (
        FOR /F "usebackq tokens=3,*" %%J IN ( `%CMD_ADSUTIL% GET %%I/%PROPERTY_TO_FIND% -s:%%A` ) DO (
            ECHO %%A/%%I = %%K
        )
    )
)

ENDLOCAL
GOTO :EOF



:Help
ECHO %0 [servername ^| file-list]
ECHO.
ECHO Where:
ECHO     servername is the name of the server to query. %COMPUTERNAME% by default
ECHO     file-list is filepath to text file containing list of servers, one per line

GOTO :EOF&lt;/PRE&gt;&lt;/SPAN&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6813791" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Sample Code" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Sample+Code/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /><category term="Tips" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/" /><category term="HOWTO..." scheme="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/" /></entry><entry><title>HOWTO: Create Custom Application Pool from Commandline</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2007/12/12/howto-create-custom-application-pool-by-commandline.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2007/12/12/howto-create-custom-application-pool-by-commandline.aspx</id><published>2007-12-13T09:15:00Z</published><updated>2007-12-13T09:15:00Z</updated><content type="html">&lt;H3&gt;Question&lt;/H3&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: courier new"&gt;
&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;I have a Web site configured to run in a custom application pool. The pool identify is set to a domain user. &lt;BR&gt;
&lt;P&gt;I can change the users password using IIS Manager, but is there a command line method ? &lt;BR&gt;
&lt;P&gt;Thanks &lt;/P&gt;&lt;/SPAN&gt;
&lt;H3&gt;Answer&lt;/H3&gt;
&lt;P&gt;You can use the &lt;A title=ADSUTIL.VBS href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/d3df4bc9-0954-459a-b5e6-7a8bc462960c.mspx?mfr=true" target=_blank mce_href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/d3df4bc9-0954-459a-b5e6-7a8bc462960c.mspx?mfr=true"&gt;ADSUTIL.VBS&lt;/A&gt; tool to do this from the commandline (or steal the code from it for your own custom script).&lt;/P&gt;
&lt;P&gt;The properties that you are interested in are all documented on MSDN at &lt;A href="http://msdn2.microsoft.com/en-us/library/ms525644.aspx" target=_blank&gt;Metabase Properties&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The following is an example of how to create a new Application Pool called "MyAppPool" and configure it to use a custom Application Pool identity of domain\username with a password of pass. You can find all the property syntax and valid values in the MSDN. Remember, if you want to use the space character as a parameter, you have to put it in double-quotes since the commandline processor uses space as parameter delimiter.&lt;/P&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #008000; FONT-FAMILY: courier new"&gt;
CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\ADSUTIL.VBS CREATE w3svc/AppPools/MyAppPool IIsApplicationPool
CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\ADSUTIL.VBS SET w3svc/AppPools/MyAppPool/WamUserName "domain\username"
CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\ADSUTIL.VBS SET w3svc/AppPools/MyAppPool/WamUserPass "pass"
CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\ADSUTIL.VBS SET w3svc/AppPools/MyAppPool/AppPoolIdentityType 3&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6755878" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="IIS" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/" /><category term="Your Questions" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/" /></entry><entry><title>I'm Back...</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/david.wang/archive/2007/04/11/i-m-back.aspx" /><id>http://blogs.msdn.com/b/david.wang/archive/2007/04/11/i-m-back.aspx</id><published>2007-04-11T16:15:00Z</published><updated>2007-04-11T16:15:00Z</updated><content type="html">&lt;P&gt;After a long and very much needed hiatus, I have regained control of this blog and returned to blogging. For the curious reader, you can read about some of the happenings &lt;A class="" title="Second Inauguration" href="http://w3-4u.blogspot.com/2006/10/second-inauguration.html" target=_blank mce_href="http://w3-4u.blogspot.com/2006/10/second-inauguration.html"&gt;here&lt;/A&gt;. But, I am not one for dwelling on the past (except to learn and improve upon); I look forward to the future.&lt;/P&gt;
&lt;P&gt;And speaking&amp;nbsp;of the future... technology-wise, my day-to-day interests have moved up the application stack to Exchange, specifically the Calendaring, OOF, and Free/Busy components. Basically, whenever you use Outlook or OWA to schedule a meeting, look up an&amp;nbsp;attendee's Free/Busy information, or toggle your own OOF on Exchange 2007 onward, you are looking at functionality that I am responsible for&amp;nbsp;within Exchange... and that is just the beginning. So,&amp;nbsp;I will certainly be offering tidbits and answering questions about that aspect of Exchange as well as others as I encounter them.&lt;/P&gt;
&lt;P&gt;Of course, I will continue to write and answer questions about IIS and ISAPI since&amp;nbsp;they remain woefully under-documented. Not much changes with ISAPI after IIS6 since it exists for compatibility. As for IIS7 and beyond... I was involved in a lot of the design discussions/reviews and co-inventor of the extensibility API introduced in IIS7, so I think I have a good idea how things SHOULD work at the core. ;-) Besides, most of the work on IIS7 and beyond should come in the form of additional modules/handler on top of the core extensibility API, so questions about them are really specific to those modules and not IIS...&lt;/P&gt;
&lt;P&gt;Cheers!&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;
&lt;P&gt;P.S. Yes, I am still working on answering the backlog of existing comments, and I have just re-enabled anonymous comments...&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2091205" width="1" height="1"&gt;</content><author><name>David.Wang</name><uri>http://blogs.msdn.com/David.Wang/ProfileUrlRedirect.ashx</uri></author><category term="Personal" scheme="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/" /></entry></feed>