<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>David Wang</title><link>http://blogs.msdn.com/b/david.wang/</link><description>David Wang on IIS, ISAPI, Exchange, Virtual Server, and whatever else I fancy...</description><dc:language>en-US</dc:language><generator>Telligent Community 5.6.583.21163 (Build: 5.6.583.21163)</generator><item><title>HOWTO: IIS 6 Request Processing Basics, Part 2 - Web Site, Virtual Directory, and Web Application</title><link>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</link><pubDate>Sun, 07 Dec 2008 19:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9181992</guid><dc:creator>David.Wang</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=9181992</wfw:commentRss><comments>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#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/">Tips</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category></item><item><title>HOWTO: PreCondition an ISAPI Extension DLL</title><link>http://blogs.msdn.com/b/david.wang/archive/2008/10/30/howto-precondition-an-isapi-extension-dll.aspx</link><pubDate>Fri, 31 Oct 2008 08:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9025890</guid><dc:creator>David.Wang</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=9025890</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2008/10/30/howto-precondition-an-isapi-extension-dll.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/">ISAPI</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/">Tips</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/">IIS7</category></item><item><title>WebDAV, Source, and Read Permissions on IIS</title><link>http://blogs.msdn.com/b/david.wang/archive/2008/09/29/webdav-source-and-read-permissions-on-iis.aspx</link><pubDate>Mon, 29 Sep 2008 17:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8968704</guid><dc:creator>David.Wang</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=8968704</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2008/09/29/webdav-source-and-read-permissions-on-iis.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category></item><item><title>Managed Modules and ISAPI Filters</title><link>http://blogs.msdn.com/b/david.wang/archive/2008/09/08/managed-modules-and-isapi-filters.aspx</link><pubDate>Tue, 09 Sep 2008 07:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8935722</guid><dc:creator>David.Wang</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=8935722</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2008/09/08/managed-modules-and-isapi-filters.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/">ISAPI</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/">IIS7</category></item><item><title>HOWTO: Change IIS User Impersonation Token</title><link>http://blogs.msdn.com/b/david.wang/archive/2008/06/02/howto-change-iis-user-impersonation-token.aspx</link><pubDate>Mon, 02 Jun 2008 10:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8568348</guid><dc:creator>David.Wang</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=8568348</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2008/06/02/howto-change-iis-user-impersonation-token.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/">ISAPI</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category></item><item><title>IIS7 Handlers - accessPolicy and requireAccess</title><link>http://blogs.msdn.com/b/david.wang/archive/2008/06/01/iis7-handlers-accesspolicy-and-requireaccess.aspx</link><pubDate>Sun, 01 Jun 2008 11:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8567407</guid><dc:creator>David.Wang</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=8567407</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2008/06/01/iis7-handlers-accesspolicy-and-requireaccess.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/">IIS7</category></item><item><title>Choice of Development Platform for IIS Modules</title><link>http://blogs.msdn.com/b/david.wang/archive/2008/04/18/choice-of-development-platform-for-iis-modules.aspx</link><pubDate>Fri, 18 Apr 2008 11:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8407040</guid><dc:creator>David.Wang</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=8407040</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2008/04/18/choice-of-development-platform-for-iis-modules.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS7/">IIS7</category></item><item><title>HOWTO: List all Virtual Directories and Paths of a List of Servers</title><link>http://blogs.msdn.com/b/david.wang/archive/2007/12/19/howto-list-all-virtual-directories-and-paths-of-a-list-of-servers.aspx</link><pubDate>Thu, 20 Dec 2007 08:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6813791</guid><dc:creator>David.Wang</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=6813791</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2007/12/19/howto-list-all-virtual-directories-and-paths-of-a-list-of-servers.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Sample+Code/">Sample Code</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/">Tips</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category></item><item><title>HOWTO: Create Custom Application Pool from Commandline</title><link>http://blogs.msdn.com/b/david.wang/archive/2007/12/12/howto-create-custom-application-pool-by-commandline.aspx</link><pubDate>Thu, 13 Dec 2007 09:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6755878</guid><dc:creator>David.Wang</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=6755878</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2007/12/12/howto-create-custom-application-pool-by-commandline.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category></item><item><title>I'm Back...</title><link>http://blogs.msdn.com/b/david.wang/archive/2007/04/11/i-m-back.aspx</link><pubDate>Wed, 11 Apr 2007 16:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2091205</guid><dc:creator>David.Wang</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=2091205</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2007/04/11/i-m-back.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/">Personal</category></item><item><title>Internet Explorer is not an HTTP Validator</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/08/17/internet-explorer-is-not-an-http-validator.aspx</link><pubDate>Fri, 18 Aug 2006 09:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:704859</guid><dc:creator>Anonymous</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=704859</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/08/17/internet-explorer-is-not-an-http-validator.aspx#comments</comments><description>&lt;H3&gt;Question:&lt;/H3&gt;&lt;FONT face="courier new" color=#008000&gt;
&lt;P&gt;I tried a 2nd approach in porting client code from WinInet, and that was to utilize managed C++, as opposed to WinHttp.&lt;/P&gt;
&lt;P&gt;After implementing the .NET managed client code...&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebRequest^ myReq = dynamic_cast&amp;lt;HttpWebRequest^&amp;gt;(WebRequest::Create( strTargetURL ));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; myReq-&amp;gt;Method = "POST";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpWebResponse^ HttpWResp = dynamic_cast&amp;lt;HttpWebResponse^&amp;gt;(myReq-&amp;gt;GetResponse());&lt;/P&gt;
&lt;P&gt;Within the code, GetResponse() throws...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; An unhandled exception of type 'System.Net.WebException' occurred in System.dll&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Additional information: The server committed a protocol violation. Section=ResponseStatusLine&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;On the Windows 2003 R2 SP1 server, the ISAPI extension has been simplified to the following...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DWORD dwPageSize, dwBytes;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char szPage[] = "We're good to go";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dwPageSize = (DWORD) strlen(szPage);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ( pECB-&amp;gt;WriteClient(pECB-&amp;gt;ConnID, (LPVOID) szPage, &amp;amp;dwPageSize, 0) ) ? HSE_STATUS_SUCCESS : HSE_STATUS_ERROR;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;Any help would be apreciated enabling more clients whether they are WinHttp or .NET clients, the ability to POST to the ISAPI extension.&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;&lt;/FONT&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Actually, the problem you observe comes from your ISAPI Extension DLL. It is actually sending an invalid HTTP response without an entity body, and the APIs correctly complain. Let me explain.&lt;/P&gt;
&lt;H4&gt;Problem Restated&lt;/H4&gt;
&lt;P&gt;My understanding of your facts:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;You have an ActiveX DLL using WinInet which successfully POSTs to an ISAPI Extension 
&lt;LI&gt;You have a Windows Service which fails to POST to the exact same ISAPI Extension using either WinHttp or .NET Client&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Based on that information, I hypothesize either:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The ISAPI Extension or other Server Side ISAPI Filter is doing something wrong, but WinInet ignores or covers it up while WinHttp/.NET Client correctly fail 
&lt;LI&gt;The ISAPI Extension or other Server Side ISAPI Filter is doing something wrong, but IIS/ISAPI/Windows Networking stack&amp;nbsp;does a special hack for WinInet but not others like WinHttp or .NET Client&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Personally, I am more inclined to believe that the former is happening. The latter is simply way too convoluted, difficult, and fragile. I am not a Conspiracy Theorist - I believe in straight-forward explanations for computer issues. :-)&lt;/P&gt;
&lt;H4&gt;Problem Confirmed&lt;/H4&gt;
&lt;P&gt;In this case, I am certain that #1 applies for several reasons:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The simplified ISAPI Extension does not send a proper HTTP Response 
&lt;LI&gt;"WinInet accepts the response" does NOT mean "it is a proper HTTP response"&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;In other words, the ISAPI Extension is doing something bad, but WinInet (and IE, which uses WinInet) tries very hard to succeed and hence overlooks such errors. &lt;/P&gt;
&lt;P&gt;&amp;lt;rant&amp;gt;&lt;/P&gt;
&lt;P&gt;Yes, it gives a great user experience to see IE render all sorts of improper HTTP responses and HTML pages, but it also gives false user confidence in the correctness of such HTTP/HTML. &lt;/P&gt;
&lt;P&gt;But, I do not think the problem is solely with Microsoft/IE but rather shared with the authors of such bad HTTP and HTML. Computer users expect things to magically "work", so someone has to make the broken things be "less broken" and "work". This expectation results in a viscious cycle:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;If IE refused to render the broken HTTP/HTML but some other browser did, then users think that IE is broken instead of blaming the incorrect web page. Since IE renders more broken HTTP/HTML, web page developers have less motivation to author&amp;nbsp;correctly... and IE will be punished for refusing to render that future broken web page.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;How whacky is that!?! Of course, Users have no idea that this is going on - they only see rendered pages and think everything is alright - when in fact the browser and web developers are slowly diverging from published specifications, increasing their maintenance costs, and causing headaches on the development side of things. And all because we are trying to shield the&amp;nbsp;End User...&lt;/P&gt;
&lt;P&gt;This downside is what hits you right now. In this case, you see a response from the ISAPI Extension when browsed with Internet Explorer or WinInet, so you probably think the ISAPI is perfectly simple and correct. Hence, you think that Microsoft has a bug somewhere that either causes WinHttp or .NET Client to not work with the ISAPI, or that there is some devious hack somewhere to favor WinInet. Bad Microsoft.&lt;/P&gt;
&lt;P&gt;But in reality, it is the ISAPI Extension that is broken, and you were fooled by the tainted validations with Internet Explorer and WinInet.&lt;/P&gt;
&lt;P&gt;&amp;lt;/rant&amp;gt;&lt;/P&gt;
&lt;H4&gt;Troubleshoot with Trusted Tools&lt;/H4&gt;
&lt;P&gt;This is why I only use the following basic but trusted tools to debug HTTP Client/Server issues...&amp;nbsp;because they have no alternative agenda to mislead anyone:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=9bfa49bc-376b-4a54-95aa-73c9156706e7&amp;amp;displaylang=en"&gt;WFetch&lt;/A&gt; to make raw requests and observe raw responses 
&lt;LI&gt;Network Monitor to tap the network and observe raw requests and responses 
&lt;LI&gt;&lt;A href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Native Code Debuggers&lt;/A&gt; to observe programmatic state inside a process&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I simply do not trust debugging/troubleshooting with anything else. If I have to use something like IE/FireFox, I always treat its answer with a heavy grain of salt and not as Gospel.&lt;/P&gt;
&lt;H4&gt;Resolution&lt;/H4&gt;
&lt;P&gt;If you change the ISAPI code to send the following response, then I believe it should work for WinHttp and .NET Client as well as WinInet: &lt;FONT face="Courier new" color=#008000&gt;&lt;PRE&gt;char szPage[] = "HTTP/1.1 200 OK\r\n"
                "Content-Type: text/html\r\n"
                "Content-Length: 16\r\n"
                "\r\n"
                "We're good to go";&lt;/PRE&gt;&lt;/FONT&gt;
&lt;P&gt;Basically, your ISAPI only sent back "We're good to go" as an HTTP response, and that is improperly formatted. The fix makes the ISAPI send back a proper HTTP response, so the client APIs like WinHttp or .NET Client should just work.&lt;/P&gt;
&lt;H4&gt;Conclusion&lt;/H4&gt;
&lt;P&gt;Powerful APIs, like ISAPI Extension and ISAPI Filter, directly control the data stream to/from IIS. Thus, they can either positively augment IIS behavior or negatively manipulate IIS to misbehave.&lt;/P&gt;
&lt;P&gt;In particular, they differ from programming environments like ASP, ASP.Net, or PHP, which removes some of the power to protect the user from generating common HTTP mistakes. One just has to be aware of the guard-rails and training wheels.&lt;/P&gt;
&lt;P&gt;Like many things, it is just a tradeoff that one needs to be aware of; nothing right or wrong.&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=704859" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/">ISAPI</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category></item><item><title>Water Day 2006</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/08/10/water-day-2006.aspx</link><pubDate>Thu, 10 Aug 2006 20:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:692929</guid><dc:creator>Anonymous</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=692929</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/08/10/water-day-2006.aspx#comments</comments><description>&lt;P&gt;Annually, the IIS team gathers at Emily's house on the shores of lake Sammamish to enjoy a day of fun under under the sun. We call it "water day", and it has been a team tradition for at least&amp;nbsp;as long as I have been on the IIS team.&lt;/P&gt;
&lt;P&gt;Its organization, activities, and participants constantly alter, but one thing remains constant - a large number of the IIS team take off on a work day to go have fun on the lake, and a sub group hangs around at the end to really chat/gripe about things on their mind, management excluded. It allows parts of the team who otherwise would not gather/socialize with each other a chance to do so, and it gives people a creative outlet to vent/relax. We try to not talk about work, but inevitably, issues/differences do get informally ironed out, and that is a cool side-effect.&lt;/P&gt;
&lt;P&gt;I remember water day starting out as a bunch of core developers who decided to coordinate a common ditch-work-day to go drink and play on the lake (water ski, wake board, swim, etc), and few key test process and automation folks with close working relationship with those developers who tagged along. It quickly got management sanction, organization, and catering, and it grew into the current, annual event. &lt;/P&gt;
&lt;P&gt;Yeah, it is symbolic of how many things come about on the IIS team - do it, and they will come. A small number of people decides to do something, the result gathers concensus from others, and management later comes along to rationalize/formalize what was intuitively done.&lt;/P&gt;
&lt;P&gt;In contrast to prior years, the team catered everything. Brian, Rich, and Keith manned the grill and churned out BBQ ribs, chicken, burgers, hot dogs, and ears of&amp;nbsp;corn. Chips/salsa, fresh veggie platter, fresh fruit platter, chocolate chip cookies, brownies, and ice cream were also present... along with two kegs of beer. Emily took interested people out for a ride on her boat. I took photos/movies of the event throughout the entire water day. Yeah, we had everything covered. :-)&lt;/P&gt;
&lt;P&gt;For the first half of the afternoon, the weather was overcast, and people staggered in from work between 12-2pm to eat. Some people went out for a ride on the jet skis and hopped off the water trampoline; others just ate and watched from shore. Fortunately, the sun broke through later in the afternoon, and that was when the fun began. Chris challenged Andrew to a team drinking game - team of people each sequentially drink an equal amount of beer and then attempt to flip their plastic cup to stand on its opposite end, and first team to have all its members complete the drink-and-flip task wins the round... and we played to the best of 7 rounds to win a game, and best two out of three games.&lt;/P&gt;
&lt;P&gt;Let's just say that this kept a large part of the IIS team entertained, and we were glad that the managers were no longer around. ;-) Jan made a strong showing for the women on the IIS team by consistently performing the drink-and-flip in a short amount of time, and there were several photo-finish moments, including&amp;nbsp;one where Edmund beat Wade by a matter of milliseconds. In the end, Andrew's team soundly beat Chris's team... but Andrew got really, really wasted. But it was all in good fun. We all had a great time.&lt;/P&gt;
&lt;P&gt;Most people left by 8pm, but Jan, Edmund, Andrew, Emily, and I hung around to watch the sunset and chat/gripe about the drama in our lives both work and personal. I swear... while it is nice to impersonally plan and negotiate a task completion schedule, it is very satisfying to just reach a mutual state of understanding and simply operate as friends instead of coworkers. Things just get done better when we do things as "favors" for friends and our team morale stays higher as well. Yes, I know it does not scale past a certain point, but the IIS team is not yet past that point... despite what team management tries to organize. We just try to pull together and get things done, fast.&lt;/P&gt;
&lt;P&gt;Ahh... it was such a nice, enjoyable&amp;nbsp;day..&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=692929" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/">Personal</category></item><item><title>Hunting for Real Estate</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/08/02/hunting-for-real-estate.aspx</link><pubDate>Wed, 02 Aug 2006 15:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:686376</guid><dc:creator>Anonymous</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=686376</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/08/02/hunting-for-real-estate.aspx#comments</comments><description>&lt;P&gt;Lately, I have not been making frequent blog posts. There are good reasons, of course... and&amp;nbsp;I will get to disclosing them in the near future.&lt;/P&gt;
&lt;P&gt;Recently, I have been spending a lot of time house-hunting. Yeah, I have decided that it is about time for me to move from my condo into a stand-alone house. I have a lot of furniture and electronics purchases all queued up behind buying a house, and it is about time I release that bottleneck.&lt;/P&gt;
&lt;P&gt;And I have been amazed at the tools available at my fingertips to make this search. I remember just three years ago how painful it was for me to locate appropriately priced condos in the areas that I wanted. I needed an agent to help locate and sort things out.&lt;/P&gt;
&lt;P&gt;Well, with websites like &lt;A href="http://www.johnlscott.com/"&gt;http://www.johnlscott.com&lt;/A&gt; and &lt;A href="http://www.windermere.com/"&gt;http://www.windermere.com&lt;/A&gt;, I can finally do most of the hunting on my own and engage a buyer's agent to help with the details and close the deal. I can easily enter in my criteria, like price range, location, features, rooms, etc... and scrolling/zooming around a map to narrow down the location... and the web app shows me the properties that match my criteria. How nifty is that! &lt;/P&gt;
&lt;P&gt;I am especially impressed with the John L Scott site because it is so intuitively functional. I start out by punching in a price range and simply start scrolling, panning,&amp;nbsp;and zooming into the area I want to focus on, and eventually I end up with a list of property matches with hyperlinks to lots of relevant information. And it works smoothly and quickly... so I have to say "score one for Microsoft technologies like ASP.Net, AJAX, and Virtual Earth"! Meanwhile, the Windermere site, which is based on ColdFusion and a MapQuest-like map called PropertyPoint... simply pales in comparison. Search criteria behavior is quirky at best, search/navigation is archaic in comparison to new standards like Virtual Earth and Google Maps, and usefulness of pricing information is not that high.&lt;/P&gt;
&lt;P&gt;In contrast, from the John L Scott site, I have quick access to information like:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Recent sale prices in the area, so I can guage price/sq.ft ratio and relative desire&lt;/LI&gt;
&lt;LI&gt;Historical public information on any property from metrokc.gov so that I have an idea of the price/profit range to help me determine position and approach for price negotiation&lt;/LI&gt;
&lt;LI&gt;I can also passively keep tabs on listings in the area, price changes... all of which help me easily assess property worth before I even invest the time into physically touring the place to determine if I like it or not&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Yeah... it is very different from my first home purchase experience where I spent days of time visiting dozens of homes before finding one I loved, had no clue&amp;nbsp;on the basis of price negotiation,&amp;nbsp;and then later rationalized the economics and details. That was a weird feeling for me because I never felt in control and my selection criteria was so emotional.&lt;/P&gt;
&lt;P&gt;Well... this time, I finally have the tools to apply an analytical approach of quantifying and qualifying what I am looking for and how important each criteria is... and then narrowing down amongst those choices. It leaves the emotions out until the end, which I think is the way it should be. After all, real-estate purchase is financial in nature for most people, not emotional&amp;nbsp;(don't know about you, but I don't buy houses because I am "bored" or for "fun")... :-)&lt;/P&gt;
&lt;P&gt;Next step -&amp;nbsp;how to make the financing work from an investment perspective...&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=686376" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/">Personal</category></item><item><title>What is wrong with Free?</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/28/what-is-wrong-with-free.aspx</link><pubDate>Fri, 28 Jul 2006 16:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:681417</guid><dc:creator>Anonymous</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=681417</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/28/what-is-wrong-with-free.aspx#comments</comments><description>&lt;P&gt;Ok, maybe this is something you business/marketing types understand intrinsically... but it is something that I do not understand, so please bear with me. Why do people complain about getting something for free that used to require money? I thought people like getting something for nothing.&lt;/P&gt;
&lt;P&gt;For example, Microsoft recently announced that Virtual PC 2004 will be &lt;A href="http://www.microsoft.com/windows/virtualpc/default.mspx"&gt;available free&lt;/A&gt; of charge. I expected users to be happy to get yet more quality software for free... but I did not expect the firestorm of complaint from users on newsgroups that fall along this line of logic:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;Gosh, I feel like a used&amp;nbsp;dummy for paying Microsoft $X for Virtual PC 2004 Y months ago. Either&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Microsoft is stealing money from me 
&lt;LI&gt;I am simply lining Microsoft's profits without even an acknowledgement&lt;/LI&gt;&lt;/UL&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;These users either want:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Microsoft to give compensation, either in the form of money-back or money voucher, for people who purchased Virtual PC 2004 in the last Y months 
&lt;LI&gt;To pirate other Microsoft&amp;nbsp;software to "get back" at Microsoft because it extorted money on eventually free software and who knows, it may be released for free in the future.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I simply do not understand the rationale for this line of logic. Software is not your possession; you purchase a license to give yourself the right to use that software.&lt;/P&gt;
&lt;P&gt;If I purchase a possession and the seller later decides to give the item away for free, then sure I will be bummed because it means I cannot later resell that possession. I am cheated from being able to resell that possession because the sellar has deflated the market&amp;nbsp;price for that item. However, regardless of price, I still get my utility and&amp;nbsp;value from using the item - it functions the same whether it is priced at something or nothing.&lt;/P&gt;
&lt;P&gt;If I merely purchase the RIGHT to use an item and the seller later decides to give the item away for free, then how can I be cheated? Since I never owned the item, I am not cheated from being able to resell the item because I could not sell the rights to it in the first place. However, I still get my utility and value from using the item regardless of price.&lt;/P&gt;
&lt;P&gt;So, I do not think there is any stealing going on. Instead, I think there is a natural sense of Buyer's Remorse. Why one thinks that s/he is magically entitled to compensation for feeling remorseful... I do not know.&lt;/P&gt;
&lt;P&gt;I mean... no one pointed a gun at you or otherwise extorted you to purchase an item Y months ago for $X. You willingly purchased the item because you believed its utility is worth at least $X at that time. Just because its price&amp;nbsp;is now free does not diminish its utility - you are not investing in something you don't own; the binary files didn't change; the software doesn't phone home and alter behavior, did it? And since you did not own it in the first place... what's changed?&lt;/P&gt;
&lt;P&gt;Are you upset that Joe Schmoe now gets the software for free while you had to pay for it? But what about those Y months when you had utility of the tool but Joe did not; was the price not worth it? But if it was not worth it, then why did you purchase it in the first place? Oh, you thought that Y was going to be a long period of time to amortize the initial cost... but who gives assurance of that assumption?&lt;/P&gt;
&lt;P&gt;I sense the same analogy in computer hardware. It seems like every year the hard drives double in capacity at the same price point. Do I complain to the hard drive manufacturers that I am simply lining their profits this year and that they are stealing money from me because next year they will charge me half the price for the same item? Or that they should just give me the discounted price now or give me cash back/voucher towards the future purchase of a hard drive? Or that I should steal an identically sized hard drive every year because it halves in price?&lt;/P&gt;
&lt;P&gt;Nope... I take comfort in the fact that when I purchase a hard drive, I do so at a reasonable price point at that time, and the utility of having that drive for a year is worth any depreciation in price. Looking back and feeling remorseful is only going to be upsetting because most things tend to get cheaper/faster/better as time goes on. I just accept it and move on.&lt;/P&gt;
&lt;P&gt;So... can anyone explain to me why Buyer's Remorse deserves compensation, or that Microsoft is somehow stealing by giving away software for free? Because as far as I see, Microsoft is far from stealing - it is simply not making money it can otherwise make. Maybe there are subtle points that I do not understand; feel free to kindly enlighten me. :-)&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=681417" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/">Personal</category></item><item><title>TS Gateway on Vista Server Rocks!</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/27/ts-gateway-on-vista-server-rocks.aspx</link><pubDate>Fri, 28 Jul 2006 09:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:681256</guid><dc:creator>Anonymous</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=681256</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/27/ts-gateway-on-vista-server-rocks.aspx#comments</comments><description>&lt;P&gt;Back in this &lt;A href="http://blogs.msdn.com/david.wang/archive/2006/03/04/Audio_over_Remote_Desktop_Rocks.aspx"&gt;blog entry&lt;/A&gt;, I mused about the nice Audio over RDP feature. It is pretty sweet to have secure, remote access to one's audio collection.&lt;/P&gt;
&lt;P&gt;Well, I recently started playing with RDP over the new TS Gateway on Vista Server, and I have to say that it just keeps getting better.&lt;/P&gt;
&lt;P&gt;In the past, I would VPN from home into Microsoft, open RDP from my laptop at home into my work machine at Microsoft, then stream audio from the work machine through my laptop at home. Life was good.&lt;/P&gt;
&lt;P&gt;With TS Gateway, I no longer need to VPN. I now directly open RDP from my laptop at home into my work machine at Microsoft and stream audio. Life is great.&lt;/P&gt;
&lt;P&gt;While you may think "big deal... you are still tunneling and get no substantially new features", it is important to me for one reason:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;I no longer need to run as local Administrator on any of my systems.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As I mentioned in this &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/11/09/HOWTO_Run_as_normal_user_on_Windows.aspx"&gt;blog entry&lt;/A&gt;&amp;nbsp;- I run as normal, unprivileged&amp;nbsp;User to do everything; I turn on the Windows Firewall to block all but a few select ports; I do not bother with personal Security Products because they simply intrude on my computing freedom... because, umm... the idea of a computer software "chaperone" scares me. Remember HAL 9000?&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;Dave... what's wrong? What are you doing? Please don't do that...&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Argh! :-P&lt;/P&gt;
&lt;P&gt;Anyways, the one and only reason that I still use my local Administrator account is to VPN from home into Microsoft, and once I have VPN, I&amp;nbsp;immediately RDP from my laptop to my machine at work using my non-priviledged account. I imagine that most everyone else in the world running Windows do something similar and run with Administrative priviliges with far greater amount of time.&lt;/P&gt;
&lt;P&gt;Well, the TS Gateway works perfectly for me:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;I still RDP from my laptop at home&amp;nbsp;to my machine at work 
&lt;LI&gt;I no longer need to VPN 
&lt;LI&gt;I no longer need to use my local Administrator accounts anywhere&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;To boot, RDP already allows me to copy files between the Host and Remote computers. So I do not need to VPN anymore to do these common operations.&lt;/P&gt;
&lt;P&gt;Yes, I know&amp;nbsp;you *nix-heads are shaking your heads and saying "welcome to modern computing; *nix has had SSH tunneling and X11 port-forwarding for decades now" -&amp;nbsp;but humor me for the moment. :-) How easy is it to work with and forward smart card so that you can double hop?&lt;/P&gt;
&lt;P&gt;To me, the TS Gateway feature, like IIS7, make Vista Server compelling.&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=681256" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/">Personal</category></item><item><title>Laptop Business 2006</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/19/laptop-business-2006.aspx</link><pubDate>Wed, 19 Jul 2006 12:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:670807</guid><dc:creator>Anonymous</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=670807</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/19/laptop-business-2006.aspx#comments</comments><description>&lt;P&gt;Ok, I know that I just purchased an IBM X41 Tablet last fall, but I am in the market for a new laptop again.&lt;/P&gt;
&lt;P&gt;No, nothing wrong with my computers... I am just going to be giving the X41 to my younger sister so that she can use it during Law School the next few years. I wager she needs it more than I do, and I still have my older Dell laptop, PC, and Mac Mini, so I have no shortage of computers. Yes, I am a nice older brother.&lt;/P&gt;
&lt;P&gt;Why am I giving her the X41 instead of the other machines? Because the X41 is new and still has its 3-year warranty. There is no way that I am giving my sister a machine out of warranty because if anything goes wrong, I will get the phone call... and we all know what long-distance computer troubleshooting can be like... ;-)&lt;/P&gt;
&lt;P&gt;All it means is that I must re-evaluate the ultraportable landscape again.&lt;/P&gt;
&lt;P&gt;Unfortunately, it seems that Dell's design philosophy for its Latitude Ultraportables no longer match what I am looking for. I do not want a widescreen LCD on the business-class Latitude; if I wanted widescreen LCDs for movies, I would choose the consumer-class Inspirons. PC Card slot and SD memory slot are necessary now, for my smart card reader and digital camera memory. And packing it all into a real ultraportable package (2.5-4lb, 1" thick) is important. Sigh... I do like Dell machines, especially their a la carte software setup, but their hardware design seems to go in a direction that no longer match what I want.&lt;/P&gt;
&lt;P&gt;Toshiba appears to still go with the R200, which while sleek and more business-minded, it is also demanding a price premium for last year's hardware (Pentium M instead of Solo/Duo, 4200rpm HDD). I may enjoy the fashion, but not at the cost of basic functionality. I am willing to trade-off some hardware functionality for a fashionable&amp;nbsp;ultraportable form factor (like the fastest CPUs, discrete graphics, or 1600x1200 LCD panels), but not&amp;nbsp;for last year's functionality. Gotta have standards, you know. ;-)&lt;/P&gt;
&lt;P&gt;Apple, HP/Compaq, and Gateway&amp;nbsp;are pretty much out of the picture because I have never seen a system from them that simultaneously satisify the price, functionality, reliability, and customizability ratio. I am always amazed at how Apple manages to pawn last year's hardware at premium prices and still get away with it - gotta love their marketing and spin-machine...&lt;/P&gt;
&lt;P&gt;So, I guess that leaves me with IBM (oops, Lenovo) for the this purchase. I am debating between the X60S and the T60P... because on the one hand, you have the classic ultraportable X60S with all the usual features and this year's hardware refresh (Duo, 7200rpm HDD) while still retaining the standard XGA resolution, PC Card/SD Memory, and now 3 USB 2.0 ports... and on the other, you have the classic power-machine T60P with all the top-end Vista-ready hardware (Duo, 7200 HDD, discrete graphics) while sporting a 1600x1200 LCD. I don't know... 1600x1200 is a really attractive resolution, especially for me to PPTP into my work machines. I have been really spoiled by my dual 1600x1200 and 1200x1600 monitor layout - having screen real-estate really helps my work efficiency.&lt;/P&gt;
&lt;P&gt;Hmm... I guess I will just have to toss a coin... :-)&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=670807" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/">Personal</category></item><item><title>HOWTO: Basic Native/Managed Code Interop</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/13/howto-basic-native-managed-code-interop.aspx</link><pubDate>Thu, 13 Jul 2006 14:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:663194</guid><dc:creator>Anonymous</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=663194</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/13/howto-basic-native-managed-code-interop.aspx#comments</comments><description>&lt;P&gt;IIS7 core extensibility model supports both native and managed code as first-class citizens. So, I feel it is time for a little refresher on managed/native code interop... starting with the more popular route of how to wrap native code API for use within managed code. I am using the newer syntax introduced with .Net Framework 2.0 instead of the older, kludgy syntax.&lt;/P&gt;
&lt;P&gt;Now, I am going to ignore&amp;nbsp;the reciprocal&amp;nbsp;route of calling managed code from native code for a couple of reasons:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;It is just boiler plate COM Interop within native code after generating and registering the CCW (COM Callable Wrapper) of the managed class. 
&lt;LI&gt;Why don't you just write a managed code module/handler in IIS7 to directly use that managed API?&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The example illustrates how to use Managed Code to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Pass a .NET String into Managed C++ 
&lt;LI&gt;Manipulate a .NET String in Managed C++ 
&lt;LI&gt;Return a .NET String from Managed C++ 
&lt;LI&gt;Pass in arbitrary number of args into Managed C++ &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Remember to use a Class Library Project for Sample.h and Sample.cpp to create a Managed C++ Wrapper around native code API, and you can use the resulting Managed Assembly from Sample.cs managed code.&lt;/P&gt;
&lt;P&gt;Enjoy,&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;
&lt;H4&gt;Sample.h&lt;/H4&gt;&lt;FONT color=#00800&gt;&lt;PRE&gt;#pragma once
#include &amp;lt;windows.h&amp;gt;
#include "SomeNativeAPI.h"

using namespace System;
using namespace System::Runtime::InteropServices;

namespace Sample
{
    public ref class ManagedClass
    {
    public:
        ManagedClass( String^ name );
        ~ManagedClass();
        !ManagedClass();
        String^ DebugPrint( String^ format, ...array&amp;lt;String^&amp;gt;&lt;STRING^&gt;^ args );
    private:
        SomeNativeType* m_pType;
    };
}&lt;/PRE&gt;&lt;/FONT&gt;
&lt;H4&gt;Sample.cpp&lt;/H4&gt;&lt;FONT color=#00800&gt;&lt;PRE&gt;#include "Sample.h"

Sample::ManagedClass::ManagedClass( String^ name )
{
    //
    // Convert .NET String into LPSTR for 
    // Native code API to use in constructor
    //
    IntPtr szName;
    szName = Marshal::StringToHGlobalAnsi( name );
    m_pType = new SomeNativeType( szName );
    Marshal::FreeHGlobal( szName );
}
Sample::ManagedClass::~ManagedClass()
{
    this-&amp;gt;!ManagedClass();
}
Sample::ManagedClass::!ManagedClass()
{
    delete m_pType;
}
String^ Sample::ManagedClass::DebugPrint( String^ format, ...array&amp;lt;String^&amp;gt;&lt;STRING^&gt;^ args )
{
    //
    // Use Managed Code to format variable arguments as .NET String,
    // convert the .NET String into Unicode String, and pass
    // it to Native API
    //
    String^ formattedString = System::String::Format( format, args );
    IntPtr  wszFormattedString;

    wszFormattedString = Marshal::StringToHGlobalUni( formattedString );
    m_pType-&amp;gt;SomeFunctionUnicode( wszFormattedString );
    Marshal::FreeHGlobal( wszFormattedString );

    return formattedString;
}&lt;/PRE&gt;&lt;/FONT&gt;
&lt;H4&gt;Sample.cs&lt;/H4&gt;&lt;FONT color=#00800&gt;&lt;PRE&gt;namespace Sample
{
    class Program
    {
        static void Main( string[] args )
        {
            Sample.ManagedClass cls = new Sample.ManagedClass( "Name?" );
            System.Console.WriteLine( cls.DebugPrint( "0:{0},1:{1}", "N", "V" ) );
        }
    }
}&lt;/PRE&gt;&lt;/FONT&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=663194" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Sample+Code/">Sample Code</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/">Tips</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category></item><item><title>CGI Failing with 404 on IIS</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/12/cgi-failing-with-404-on-iis.aspx</link><pubDate>Wed, 12 Jul 2006 11:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:663129</guid><dc:creator>Anonymous</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=663129</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/12/cgi-failing-with-404-on-iis.aspx#comments</comments><description>&lt;P&gt;Yes... software can have bugs, even if you test it. :-)&lt;/P&gt;
&lt;H3&gt;Question:&lt;/H3&gt;&lt;FONT face="courier new" color=#008000&gt;
&lt;P&gt;I have written a C EXE that I have renamed as 'prog.cgi'.&amp;nbsp; I have tested it successfully on IIS 5.0 on Windows 2000 Server and IIS 6.0 on Windows 2003 Server.&lt;/P&gt;
&lt;P&gt;The program is invoked like so:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://mysite.com/cgi-bin/prog.cgi"&gt;http://mysite.com/cgi-bin/prog.cgi&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;During the first run the program creates a dynamic page that includes a form with ACTION="prog.cgi".&amp;nbsp; It sets a hidden state variable so that the program can keep track of which screen to display.&amp;nbsp; Very basic stuff.&lt;/P&gt;
&lt;P&gt;I have a customer who has installed the file on their server (IIS 5.0 on W 2000 Svr), and they can get the first screen, but they get a 404 when they submit the form from the first screen with ACTION="prog.cgi".&lt;/P&gt;
&lt;P&gt;It looks to me like a relative path vs. absolute path issue.&amp;nbsp; In the code, I used the ACTION as the program name only, as opposed&amp;nbsp; to making it "/cgi-bin/prog.cgi" to allow customers to install it in and directory they saw fit on their system.&lt;/P&gt;
&lt;P&gt;I have read about absolute and relative paths in various places but they all seem to be referring to the file system and not the virtual path like the issue seems to be here.&lt;/P&gt;
&lt;P&gt;I did not see this in any of my testing on any version of Windows with IIS or OmniHTTPD, or Unix (with Apache).&lt;/P&gt;
&lt;P&gt;Thanks for any ideas.&lt;/P&gt;&lt;/FONT&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Yup, your issue is with relative path resolution of URIs by browsers, and it is caused by a bug in your CGI. Yes, I know you say that you have successfully tested the CGI on a number of platforms, but at the end of the day, your customer demonstrated a flaw within your CGI despite your testing, so you simply have to accept and fix it.&lt;/P&gt;
&lt;P&gt;To allow your customers to install your CGI wherever they want, I suggest that you fix your CGI to use the Server Variable (or CGI environment variable) SCRIPT_NAME to generate the correct URI for ACTION. SCRIPT_NAME resolves back to the URL that invoked the CGI, wherever the user installed it. So, for a first run URL of &lt;A href="http://mysite.com/cgi-bin/prog.cgi"&gt;http://mysite.com/cgi-bin/prog.cgi&lt;/A&gt; , SCRIPT_NAME returns&amp;nbsp;/cgi-bin/prog.cgi... which should correctly resolve as ACTION for your subsequent PostBack.&lt;/P&gt;
&lt;P&gt;If you just use "prog.cgi" as ACTION, you are assuming that the BROWSER&amp;nbsp;resolves /cgi-bin as the base directory of the request and makes the PostBack to /cgi-bin/prog.cgi. If the browser does not resolve /cgi-bin as the base directory, the PostBack likely results in a 404. You can verify this with the server log file corresponding to the failed PostBack that results in a 404.&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=663129" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category></item><item><title>Can ISAPI Filter change the Request's domain name?</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/06/can-isapi-filter-change-the-requests-domain-name.aspx</link><pubDate>Fri, 07 Jul 2006 08:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:657038</guid><dc:creator>Anonymous</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=657038</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/06/can-isapi-filter-change-the-requests-domain-name.aspx#comments</comments><description>&lt;H3&gt;Question:&lt;/H3&gt;&lt;FONT face="courier new" color=#008000&gt;
&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;I would like to know if we can get the entire URL that is sent through the browser into the ISAPI filter DLL. &lt;/P&gt;
&lt;P&gt;E.g. If I have a URL like - http://www.mysite.com/test&lt;/P&gt;
&lt;P&gt;what I get into the DLL (using GetHeader) is "/test". But I need the entire URL as I want to make changes even to the domain name http://www.mysite.com).&lt;/P&gt;
&lt;P&gt;Can we do this? I am sorry if I am asking the same questions that have already been asked, but I need to know this ugently.&lt;/P&gt;
&lt;P&gt;Thanks!&lt;/P&gt;&lt;/FONT&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;ISAPI Filter can access the entire request sent by the Browser, which includes the information you named (URL and Host [i.e. "domain name"]).&amp;nbsp;However, it may not be in the form you expect because:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The web browser does not necessarily send the exact typed text to the web server 
&lt;LI&gt;GetHeader("url") does not retrieve what is typed into the web browser&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The following is an abridged version of the BNF definition of a HTTP Request:&lt;/P&gt;&lt;PRE&gt;       HTTP-message   = Request | Response     ; HTTP/1.1 messages

        Request       = Request-Line              ; Section 5.1
                        *(( general-header        ; Section 4.5
                         | request-header         ; Section 5.3
                         | entity-header ) CRLF)  ; Section 7.1
                        CRLF
                        [ message-body ]          ; Section 4.3

       Request-Line   = Method SP Request-URI SP HTTP-Version CRLF

       Request-URI    = "*" | absoluteURI | abs_path | authority

       request-header = ...
                      | Host                     ; Section 14.23&lt;/PRE&gt;
&lt;P&gt;Given your example URL of &lt;CODE&gt;http://www.mysite.com/test&lt;/CODE&gt; , the web browser can send a couple of different valid requests. I color code what retrieves what:&lt;/P&gt;
&lt;P&gt;Example 1:&lt;/P&gt;&lt;PRE&gt;GET &lt;FONT color=#ff0000&gt;http://www.mysite.com/test&lt;/FONT&gt; HTTP/1.1\r\n
\r\n&lt;/PRE&gt;
&lt;P&gt;Example 2:&lt;/P&gt;&lt;PRE&gt;GET &lt;FONT color=#ff0000&gt;/test&lt;/FONT&gt; HTTP/1.1\r\n
Host: &lt;FONT color=#008000&gt;www.mysite.com&lt;/FONT&gt;\r\n
\r\n&lt;/PRE&gt;
&lt;P&gt;In particular, GetHeader("url") only retrieves the Request-URI (colored in red) and GetHeader("host:") only retrieves the Host header (colored in green). In other words, GetHeader() does not retrieving the "logical URL"&amp;nbsp;typed into the web browser; it retrieves specific parts of the request as identified by BNF.&lt;/P&gt;
&lt;P&gt;Since you want to know the logical "domain" and "URL" of the request, you will have to retrieve the data via ISAPI and parse it yourself according to HTTP specifications. I suggest you read the HTTP 1.1 RFC for all of the proper details since ISAPI just gives you access to the data - you have to make logical sense of it yourself.&lt;/P&gt;
&lt;P&gt;Now, as to your question about using ISAPI Filter to "change the domain name"... an ISAPI Filter can only change the domain name as it appears in the Host: header. It cannot alter IIS request processing nor server variables based on the website.&lt;/P&gt;
&lt;P&gt;This means that if the original request came in for domain "original.com", it will be processed by the metadata associated with the "original.com" website. Even if the ISAPI Filter uses SetHeader() changes the Host: header to "new.com" or sets the URL to &lt;CODE&gt;http://www.new.com/test&lt;/CODE&gt;,&amp;nbsp;the SERVER_NAME and request is still processed by "original.com" - you only see the Host header change in the ALL_RAW and HTTP_HOST server variables.&lt;/P&gt;
&lt;P&gt;In other words, it is not possible to transparently and easily change/re-route requests between different websites... unless you use a SF_NOTIFY_READ_RAW_DATA filter. But, you really do not want to do that for many reasons - on IIS6, you lose Worker Process Isolation Mode, and you also have to know HTTP backwards and forwards to write it correctly for all possible cases without crashing.&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=657038" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/ISAPI/">ISAPI</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category></item><item><title>HOWTO: Convert between JScript Array and VB Safe Array</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/04/howto-convert-between-jscript-array-and-vb-safe-array.aspx</link><pubDate>Tue, 04 Jul 2006 12:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:655884</guid><dc:creator>Anonymous</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=655884</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/04/howto-convert-between-jscript-array-and-vb-safe-array.aspx#comments</comments><description>&lt;P&gt;I recently got a question about how to manipulate the LIST data type within JScript since my &lt;A href="http://blogs.msdn.com/david.wang/archive/2004/12/02/273681.aspx"&gt;sample code&lt;/A&gt; only illustrated VBScript.&lt;/P&gt;
&lt;P&gt;Well... one reason why that example is in VBScript is because LIST manipulation (a VB SafeArray) is more straight forward and requires much less code in VBScript.&lt;/P&gt;
&lt;P&gt;Then, there is Microsoft documentation which says the following time and again (and echo'd in lots of other places):&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;There is currently no way to convert a JavaScript array into a VBArray&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Really? I could not believe it. A quick search of the Internet turned up no results of how to do this, either... so it sounds like a good challenge to me. :-)&lt;/P&gt;
&lt;P&gt;I racked my brain a little, and I came up with the following built-in solution to the problem of converting a JScript array into a VB SafeArray. Yes, I know it is not efficient, but for casual conversion for the purposes of IIS configuration, it definitely suffices. And it works on Windows 2000 on up with no additional requirements, a definite bonus from a dependency/ubiquity point-of-view.&lt;/P&gt;
&lt;P&gt;See the following JScript code which manipulates the IIS ScriptMaps property (a VB SafeArray) by first converting the SafeArray into JScript array, then manipulating it in JScript, and finally converting it back to a VB SafeArray for use by the Scriptmaps LIST property.&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;FONT color=#008000&gt;&lt;PRE&gt;var objRoot = GetObject( "IIS://localhost/w3svc/1/root" );
var arrVB = objRoot.Get( "ScriptMaps" );

//
// Convert from VB Array for manipulation in JScript
//
var arrJS = VB2JSArray( arrVB );
//
// Insert a test Value at end of ScriptMaps
//
arrJS[ arrJS.length ] = ".test,value,0";
//
// Convert back to VB Array to save by IIS
//
objRoot.ScriptMaps = JS2VBArray( arrJS );
objRoot.SetInfo();

function VB2JSArray( objVBArray )
{
    return new VBArray( objVBArray ).toArray();
}

function JS2VBArray( objJSArray )
{
    var dictionary = new ActiveXObject( "Scripting.Dictionary" );
    for ( var i = 0; i &amp;lt; objJSArray.length; i++ )
    {
        dictionary.add( i, objJSArray[ i ] );
    }

    return dictionary.Items();
}&lt;/PRE&gt;&lt;/FONT&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=655884" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Sample+Code/">Sample Code</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/">Tips</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category></item><item><title>IIS, Security Templates, and Anonymous Authentication</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/07/01/iis-security-templates-and-anonymous-authentication.aspx</link><pubDate>Sun, 02 Jul 2006 01:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:653709</guid><dc:creator>Anonymous</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=653709</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/07/01/iis-security-templates-and-anonymous-authentication.aspx#comments</comments><description>&lt;P&gt;Sigh... security is never black and white, is it? :-)&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Question:&lt;/H3&gt;&lt;FONT face="courier new" color=#008000&gt;
&lt;P&gt;Environment: IIS6.0 Windows 2003 R2, Windows 2003 level domain. Everything &lt;BR&gt;standard.&lt;/P&gt;
&lt;P&gt;1) The Microsoft security guide for IIS6.0 says that the IUSR account needs Log on Locally rights.&lt;BR&gt;2) The Microsoft group policy Enterprise security template for Member Servers removes this right. When the policy is applied, anonymous access is broken.&lt;BR&gt;3) The Member Server template is a baseline for all servers. You are supposed to ADD a Web Server template on top for web servers.&lt;BR&gt;4) The Security Policy guide specifies that if you apply the more restrictive Limited Functionality template to Member Servers, then you need to move the web server out of that OU so the policy is not applied. By inference you don't do this for the standard Enterprise policy template.&lt;BR&gt;5) Question: do the policy templates contradict the security guide?&lt;BR&gt;6) Question: I read somewhere that if you enable Basic authentication, you no longer need the Log on Locally right for anon. Is that correct?&lt;BR&gt;7) Question: I have enabled Advanced Digest authentication with the UseDigestSSP property set in the metabase. This works fine. I read something about this disabling subauthentication, and I recognise that subauthentication is something to do with the way IIS handles the IUSR account. Could it be that with Advanced Digest enabled, the IUSR account no longer works unless it has Log on Locally rights?&lt;/P&gt;
&lt;P&gt;Thanks very much,&lt;/P&gt;&lt;/FONT&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Yup, the security guide and policy template appear to contradict, but it is perfectly alright because security is relative, not absolute. This subtle point is often overlooked. If security was absolute, then any monkey can apply rules to achieve security... but then what would you and I be doing? :-)&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The IIS Security Guide simply says what is needed by IIS 
&lt;LI&gt;The Group Policy Template can say anything else because its scope is different 
&lt;LI&gt;The templates and guides just give you requirements and information. You have to assemble and decide which is more pertinent and important for your situation and reconcile the differences&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Put it another way (extreme example for illustration):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Security and Functionality are at odds 
&lt;LI&gt;You want the most secure and functional web server 
&lt;LI&gt;You may read somewhere that the most secure server is one that is not powered 
&lt;LI&gt;You may read somewhere else that the most functional server is one that is powered on 
&lt;LI&gt;Yes, the two statements contradict, but is either wrong? Nope. You just have to figure out the right balance given the information and your requirements.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Enablement of authentication protocols&amp;nbsp;does not have direct correlation with required user privileges. Likewise, enablement of SubAuthentication does not have direct correlation with required user privileges. The LogonMethod used to obtain the user token has direct correlation with the "Log on Locally" user privilege.&lt;/P&gt;
&lt;P&gt;See these links for more information:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/f594e137-e2da-4b22-ab58-f8edba938802.mspx?mfr=true"&gt;http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/f594e137-e2da-4b22-ab58-f8edba938802.mspx?mfr=true&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/cf438d2c-f9c7-4351-bf56-d2ab950d7d6e.mspx?mfr=true"&gt;http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/cf438d2c-f9c7-4351-bf56-d2ab950d7d6e.mspx?mfr=true&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/be052923-6022-4007-833f-587c2fa33e78.mspx?mfr=true"&gt;http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/be052923-6022-4007-833f-587c2fa33e78.mspx?mfr=true&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Yes, that's a lot of information. What do you really need to know between Anonymous, Basic, Advanced Digest, "Log on locally" privilege, and SubAuthentication?&lt;/P&gt;
&lt;H4&gt;Anonymous and SubAuthentication:&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Anonymous Authentication's "let IIS control anonymous user's password" feature requires SubAuthentication 
&lt;LI&gt;SubAuthentication requires LocalSystem as the process identity 
&lt;LI&gt;If IIS runs with process identity of LocalSystem, it can obtain a user's token, without knowing the password, by using SubAuthentication 
&lt;LI&gt;On IIS5, IIS runs as LocalSystem and can use SubAuthentication to offer the default feature of "let IIS control anonymous user's password" for the configured anonymous user. This is strictly a "usability" feature so that you do not have to remember to synchronize anonymous user password so Anonymous Authentication should not fail to logon (of course, &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/05/27/Access_Denied_to_Administrators_or_Anonymous_User.aspx"&gt;other failures&lt;/A&gt; can still happen with Anonymous Authentication...) 
&lt;LI&gt;On IIS6, IIS runs as Network Service and does NOT offer the "let IIS control anonymous user's password" feature by default&amp;nbsp;(it is not even in the UI) since it would require SubAuthentication and LocalSystem. This a security feature for IIS6, and you have to remember to synchronize anonymous user&amp;nbsp;credentials now. OS upgrade preserves the configuration; otherwise, you have to do extra work to tweak and configure the "let IIS control anonymous user's password" feature&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Anonymous, Basic, and "Log on Locally":&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Anonymous and Basic Authentication obtain user tokens compliant with LogonMethod 
&lt;LI&gt;On IIS5, LogonMethod is INTERACTIVE and thus requires its users to have "Log on locally" privilege 
&lt;LI&gt;On IIS6, LogonMethod is NEWORK_CLEARTEXT and thus does NOT require its users to have "Log on locally" privilege. But of course you can configure LogonMethod to be INTERACTIVE and require "Log on locally" privilege&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Anonymous and Advanced Digest&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Anonymous Authentication's "let IIS control anonymous user's password" feature requires SubAuthentication 
&lt;LI&gt;SubAuthentication requires LocalSystem as the process identity 
&lt;LI&gt;Advanced Digest does not require SubAuthentication 
&lt;LI&gt;Standard Digest requires SubAuthentication&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Conclusion&lt;/H4&gt;
&lt;P&gt;All of these boil down to security improvements in IIS6 vs IIS5:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;By changing default&amp;nbsp;LogonMethod to NETWORK_CLEARTEXT, anonymous and basic authentication users do not need "Log on locally" privilege 
&lt;LI&gt;By removing SubAuthentication, IIS worker process can run as the less privileged "Network Service" instead of privileged LocalSystem&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;These changes allow Anonymous, Basic, and Advanced Digest Authentication protocols to function while requiring fewer privileges of the user and process, but there are caveats - you now&amp;nbsp;have to synchronize anonymous user credentials (see this &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/07/14/HOWTO_Diagnose_IIS_401_Access_Denied.aspx"&gt;blog entry&lt;/A&gt; for a common failure pattern), and legacy applications that require INTERACTIVE may fail.&lt;/P&gt;
&lt;P&gt;As always, the choice is up to you as to which is preferable. :-)&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=653709" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category></item><item><title>HOWTO: Monitor Virtual Server Events</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/06/29/howto-monitor-virtual-server-events.aspx</link><pubDate>Thu, 29 Jun 2006 15:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:650686</guid><dc:creator>Anonymous</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=650686</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/06/29/howto-monitor-virtual-server-events.aspx#comments</comments><description>&lt;P&gt;I think Virtual Server Events and Asynchronous Tasks are two of the least utilized features of the Virtual Server Administration API.&lt;/P&gt;
&lt;P&gt;Contrary to the often-asked task of "find the VM, turn it off, manipulate its VHD, then turn it back on", which shows the synchronous, task-driven side of the VS Admin model, Events and Asynchronous Tasks show off a nice event-based, asynchronous model suitable for passive monitoring and response. What good is this?&lt;/P&gt;
&lt;P&gt;Well... that's the motivation behind this blog entry's sample code, which illustrates a simple "Virtual Server Monitor Agent" which does a few basic things:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;By default, it simply monitors all Virtual Server events and reports them to the console window. Assuming you named the JScript code VSMonitor.js, just launch it from the commandline with:&lt;BR&gt;START CSCRIPT VSMonitor.js 
&lt;LI&gt;Thereafter, whenever you start a Virtual Machine, a new child monitor script will pop up and monitor just that Virtual Machine 
&lt;LI&gt;If that Virtual Machine has a Virtual DVD drive, they will also be monitored for media insertion/ejection and type (ISO or drive letter path) 
&lt;LI&gt;When you turn off a Virtual machine, its associated child monitor script will also terminate (but it will first popup a message telling you this, in case you missed it). 
&lt;LI&gt;It also notices when you fail to startup a Virtual Machine due to Out-of-Memory and report that via a popup&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The sample basically illustrates how to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Sync on Virtual Server wide events 
&lt;LI&gt;Act on a Virtual Server wide event 
&lt;LI&gt;Sync on Virtual Machine specific events 
&lt;LI&gt;Act on&amp;nbsp;a Virtual Machine specific event 
&lt;LI&gt;Sync on Virtual DVD specific events 
&lt;LI&gt;Report on Virtual DVD events&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;And it should provide enough information for you to play around, note when events happen, and note available data for the event... and implement other interesting ideas supported by the API.&amp;nbsp;I don't have any in mind, but if you do... feel free to share... because then I may update this sample to do something more interesting. :-)&lt;/P&gt;
&lt;P&gt;Enjoy.&lt;/P&gt;
&lt;P&gt;//David&lt;/P&gt;&lt;FONT color=#008000&gt;&lt;PRE&gt;var strVMName = "sample VM Name";
var CRLF = "\r\n";
var NO_WAIT = false;
var VISIBLE = 1;

var ERROR_VM_NOT_FOUND = -2146828283;
var ERROR_VM_OUT_OF_MEMORY = 3238134821;

var fSignaled = false;
var fPopup = true;
var cPeriod = 10000;

var VM_STATE_STRING = {
    0 : "Invalid",
    1 : "Off",
    2 : "Saved",
    3 : "Turning on",
    4 : "Restoring",
    5 : "Running",
    6 : "Paused",
    7 : "Saving",
    8 : "Turning off",
    9 : "Merging drives",
    10 : "Deleting VM"
};
var VM_STATE_OFF = 1;
var VM_STATE_RUNNING = 5;

var objVS = null;
var objVM = null;
var objDVD = null;
var objShell = null;
var enumObjs;
var enumObj;

if ( WScript.Arguments.Length &gt; 0 )
{
    strVMName = WScript.Arguments.Item( 0 );
}

try
{
    objShell = new ActiveXObject( "WScript.Shell" );
    objVS = new ActiveXObject( "VirtualServer.Application" );

    try
    {
        //
        // Try to locate the specified VM and listen for its events
        // If fail to locate VM, just listen for VS-wide events
        //
        objVM = objVS.FindVirtualMachine( strVMName );
        WScript.ConnectObject( objVM, "VirtualMachineEvent_" );

        //
        // If the VM has any DVD drives, listen for their changes, too
        //
        enumObjs = new Enumerator( objVM.DVDROMDrives );

        for ( ; !enumObjs.atEnd(); enumObjs.moveNext() )
        {
            objDVD = enumObjs.item();
            WScript.ConnectObject( objDVD, "VirtualDVDEvent_" );
        }
    }
    catch ( e )
    {
        if ( e.number == ERROR_VM_NOT_FOUND )
        {
            LogEcho( "Failed to find VM " + strVMName + "." );
        }
        else
        {
            LogEcho( formatErrorString( e ) );
        }

        objVM = null;
        WScript.ConnectObject( objVS, "VirtualServerEvent_" );
    }

    LogEcho( "Waiting for Events from: " + CRLF +
             ( objVM  != null ? "- VM " + strVMName + CRLF : "- VS Wide" ) +
             ( objDVD != null ? "- DVD Drive(s)" + CRLF : "" ) +
             "" );

    //
    // Poll every cPeriod time period to determine if should exit
    //
    while ( !fSignaled )
    {
        WScript.Sleep( cPeriod );
    }
}
catch ( e )
{
    LogEcho(
        formatErrorString( e ) + CRLF +
        ( objShell == null ?
            "Failed to create WScript.Shell - check:" + CRLF +
            "- %windir%\System32\WSHOM.OCX is ACLed for user" + CRLF +
            "- Scripts are allowed by Personal Security products" + CRLF :
            "" ) +
        ( objVS == null ?
            "Failed to create Virtual Server COM object - check:" + CRLF +
            "- Virtual Server is installed" + CRLF +
            "- User has Control/Execute Access in VS Security" + CRLF :
            "" )
            );
    LogEcho( "Waiting a few seconds for you to read this..." );
    WScript.Sleep( cPeriod );
}

function LogEcho( str )
{
    WScript.Echo( str );
}

function LogPopup( str )
{
    if ( fPopup )
    {
        objShell.Popup( str );
    }
    else
    {
        LogEcho( str );
    }
}

function formatErrorString( objError )
{
    return "(" + Int32ToHRESULT( objError.number ) + ")" + ": " +
           objError.description;
}

function Int32ToHRESULT( num )
{
    if ( num &lt; 0 )
    {
        return "0x" + new Number( 0x100000000 + num ).toString( 16 );
    }
    else
    {
        return "0x" + num.toString( 16 );
    }
}

//
// Virtual Server Events
//
function VirtualServerEvent_OnEventLogged( e )
{
    LogEcho( "VirtualServer_OnEventLogged: (Event ID) " + e );

    if ( e == ERROR_VM_OUT_OF_MEMORY )
    {
        LogPopup( "Cannot start VM due to out of memory" );
    }
}
function VirtualServerEvent_OnHeartbeatStopped( e )
{
    LogEcho( "VirtualServer_OnHeartbeatStopped: (VMName) " + e );
}
function VirtualServerEvent_OnServiceEvent( e )
{
    LogEcho( "VirtualServer_OnServiceEvent: (Event ID) " + e );
}
function VirtualServerEvent_OnVMStateChange( e, s )
{
    var retVal;
    LogEcho( "VirtualServer_OnVMStateChange: VM " + e + " " +
             "changed to state " + s + "(" + VM_STATE_STRING[ s ] + ")" );
    switch ( s )
    {
        case VM_STATE_RUNNING:
            LogEcho( "Running " + WScript.ScriptFullName +
                     " to monitor VM " + e );
            retVal = objShell.Run(
                        "CSCRIPT.EXE" + " " +
                        "\"" + WScript.ScriptFullName + "\"" + " " +
                        "\"" + e + "\"",
                        VISIBLE,
                        NO_WAIT );
            break;
    }
}

function VirtualMachineEvent_OnConfigurationChanged( e, s )
{
    LogEcho( "VirtualMachine_OnConfigurationChanged: " + strVMName + " " +
             "config " + e + " = " + "\"" + s + "\"" );
}
function VirtualMachineEvent_OnHeartbeatStopped()
{
    LogEcho( "VirtualMachine_OnHeartbeatStopped: " + strVMName );
}
function VirtualMachineEvent_OnRequestShutdown()
{
    LogEcho( "VirtualMachine_OnRequestShutdown: " + strVMName );
    //
    // return true/false to reboot
    //
    return false;
}
function VirtualMachineEvent_OnReset()
{
    LogEcho( "VirtualMachine_OnReset: " + strVMName );
}
function VirtualMachineEvent_OnStateChange( e )
{
    LogEcho( "VirtualMachine_OnStateChange: " + strVMName + " " +
             "changed to state " + e + "(" + VM_STATE_STRING[ e ] + ")" );
    switch ( e )
    {
        case VM_STATE_OFF:
            LogPopup( "Signaled to stop monitoring VM " + strVMName );
            fSignaled = true;

            break;
    }
}
function VirtualMachineEvent_OnTripleFault()
{
    LogEcho( "VirtualMachine_OnTripleFault: " + strVMName );
}

function VirtualDVDEvent_OnMediaInsert( e )
{
    LogEcho( "VirtualDVDEvent_OnMediaInsert: " + strVMName + " " +
             "DVD is bound to " + e );
}
function VirtualDVDEvent_OnMediaEject( e )
{
    LogEcho( "VirtualDVDEvent_OnMediaEject: " + strVMName + " " +
             "DVD is not bound to " + e );
}&lt;/PRE&gt;&lt;/FONT&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=650686" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Sample+Code/">Sample Code</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Virtual+Server/">Virtual Server</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Tips/">Tips</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category></item><item><title>Six Years...</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/06/28/six-years.aspx</link><pubDate>Thu, 29 Jun 2006 06:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:645990</guid><dc:creator>Anonymous</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=645990</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/06/28/six-years.aspx#comments</comments><description>&lt;P&gt;Gosh, how quickly time flies by. It seems like yesterday when I was just getting started on this blog and typing out the entry for my &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/06/29/Five_Years_for_David.aspx"&gt;5-year anniversary&lt;/A&gt; at Microsoft. At that time, I had just finished doubling my number of blog entries, was in the midst of converting from purely newsgroup posts to blogging, and was having all sorts of wondering thoughts like whether a &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/07/20/Thoughts_on_the_Daily_Technical_Blog_Entry.aspx"&gt;daily technical blog&lt;/A&gt; is possible...&lt;/P&gt;
&lt;P&gt;Well, a year is a long time, and after 200+ blog entries... it is definitely possible. :-) And I still have a growing queue of 70+ ideas for blog entries in various states of completion, lots more source code sample ideas&amp;nbsp;for ISAPI and IIS7 Modules to introduce, script tools using the IIS administration APIs, and just general background details on IIS core and problem solving. I just wish I had the time and energy to push them to completion faster.&lt;/P&gt;
&lt;P&gt;As users, you never cease to amaze me with the sorts of things that you wonder about or plan to do with IIS. Yes, I observe the patterns, but I also observe the outliers. And believe me, I take your needs and make sure the developers writing features know about it and the testers validating scenarios add it to their list.&lt;/P&gt;
&lt;P&gt;Anyways... Andrew Lin, the developer lead for the IIS7 UI, had an awesome idea for his 5-year last Friday - instead of the 5 pounds of M&amp;amp;Ms that people usually bring, he brought in a 15.5 gallon keg of Hazelnut Brown Nectar - and we managed to drink it all in about 3 hours. Let's not talk about the revelries and controversies that it caused - jumping into bushes, wrestling matches, team drinking competitions... You know the cliche - what happens at Vegas, stays at Vegas... so there are no photographic evidence, right? ;-)&lt;/P&gt;
&lt;P&gt;Ok, so I am not one to go top that, but in the same spirit and tradition, I decided to bring 6 bottles of Belgium Lambic beer, various flavors (framboise, kriek, peche), to celebrate my 6-year. So, I sent out the email, and after 5pm, the IIS team (sans managers, somewhat unintentional since they left by 5pm) had a little impromptu gathering on a sunny Wednesday afternoon to relax for a while. We really needed&amp;nbsp;it, too,&amp;nbsp;because this week is the final push to get IIS7 done for Windows Vista...&lt;/P&gt;
&lt;P&gt;But, a little beer and team morale/gathering can't hurt in the grand scheme of things, right? :-)&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=645990" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Personal/">Personal</category></item><item><title>Deploying and Updating Virtual Machines</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/06/27/deploying-and-updating-virtual-machines.aspx</link><pubDate>Tue, 27 Jun 2006 14:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:648328</guid><dc:creator>Anonymous</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=648328</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/06/27/deploying-and-updating-virtual-machines.aspx#comments</comments><description>&lt;P&gt;The following are some of the more frequently asked questions when it comes to deploying a group Virtual Machines sharing common configuration.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;After updating the VHD and VMC, how to re-deploy the changes out to the group of physical machines 
&lt;LI&gt;After deploying the duplicate VHD and VMC, how to make the Windows OS in each Virtual Machine have unique name, SID, and MIC address 
&lt;LI&gt;After deploying, how to lock down the virtual and physical machine to prevent tampering 
&lt;LI&gt;And do all this with as much automation as possible... &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Well, here are my thoughts...&lt;/P&gt;
&lt;H3&gt;Question:&lt;/H3&gt;&lt;FONT face="courier new" color=#008000&gt;
&lt;P&gt;I'm considering the use of Virtual PC in a school environment. The idea is that I'll be gradually adding software and configuration options to one machine and, after making and testing each addition, copying the virtual machine to each of the other PCs.&lt;/P&gt;
&lt;P&gt;In addition to being able to access software and resources bundled with the virtual machine, each machine should be able to access resources stored on a server. A domain login is not required at this stage.&lt;/P&gt;
&lt;P&gt;There is no requirement that any changes made by students be saved.&lt;/P&gt;
&lt;P&gt;As to the ongoing management and updating of the system I am hoping to be able to copy the new image to the hosts after hours using a batch file.&lt;/P&gt;
&lt;P&gt;I have already learnt from various sources that the requirements for this configuration will be that each virtual machine must have a unique name, unique SID and unique mac address. Therefore I would like to find the most efficient way of changing these automatically, on the fly. Is there a utility which I could call from a batch file which would update these details for each instance? Ideally I would like to develop a single batch file which would update all the machines&lt;/P&gt;
&lt;P&gt;Another issue is that, when the student sits at the computer, I need as much lockdown as possible, preferably preventing them from shutting down, or modifying the configuration of the virtual machine. Is there a way of doing this?&lt;/P&gt;
&lt;P&gt;Further complicating matters I would like to close the virtual machine down automatically after hours so that any updating could take place.&lt;/P&gt;
&lt;P&gt;Thanks for any suggestions.&lt;/P&gt;&lt;/FONT&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;H4&gt;How to make the Windows OS in the Duplicated VMC/VHD Unique&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Change SID: &lt;A href="http://www.sysinternals.com/Utilities/NewSid.html"&gt;http://www.sysinternals.com/Utilities/NewSid.html&lt;/A&gt; 
&lt;LI&gt;Change ComputerName: &lt;A href="http://download.microsoft.com/download/8/7/6/876af3ca-070a-4846-9b19-bd0389b575fa/Virtual%20PC%202004%20Deployment.doc"&gt;http://download.microsoft.com/download/8/7/6/876af3ca-070a-4846-9b19-bd0389b575fa/Virtual%20PC%202004%20Deployment.doc&lt;/A&gt; 
&lt;LI&gt;Change MAC address: Modify the VMC file and change the &amp;lt;ethernet_card_address&amp;gt; element&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;How to Lockdown the Environment&lt;/H4&gt;
&lt;P&gt;I suggest locking down both:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;the Guest OS - Group Policy or 3rd party software - your pick 
&lt;LI&gt;the VPC host - &lt;A href="http://blogs.msdn.com/virtual_pc_guy/archive/2005/08/03/447572.aspx"&gt;http://blogs.msdn.com/virtual_pc_guy/archive/2005/08/03/447572.aspx&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;&lt;/UL&gt;
&lt;H4&gt;How to re-deploy Changes:&lt;/H4&gt;
&lt;P&gt;Closing VM after-hours to propagate changes is trivial to do with Virtual Server since it has a scriptable automation interface. See &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/10/18/HOWTO_Remotely_start_and_stop_a_Virtual_Machine_on_Virtual_Server_2005.aspx"&gt;this blog entry&lt;/A&gt; for code on how to remotely stop/start a VM&amp;nbsp; for the purposes of backing up the VHD (you would deploy the new VHD instead of backing up the existing VHD). Virtual PC does not have such provisions since it is meant for interactive and NOT automated use - see &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/07/22/Why_Virtual_PC_vs_Virtual_Server.aspx"&gt;this blog entry&lt;/A&gt;&amp;nbsp;for details.&lt;/P&gt;
&lt;H4&gt;My Observations&lt;/H4&gt;
&lt;P&gt;In terms of making each duplicate VHD/VMC unique, the main challenge is to automatically launch the Change SID and Change Computer Name commands INSIDE the Guest OS when you only have control outside. This is easy to do with Virtual Server's scriptable automation interface, to pass in keystrokes, etc from the outside in.&lt;/P&gt;
&lt;P&gt;Personally, I would run Virtual Server 2005 R2 instead of Virtual PC 2004. It's &lt;A href="http://blogs.msdn.com/david.wang/archive/2006/04/06/Virtual_Server_2005_R2_is_Free.aspx"&gt;completely free&lt;/A&gt;, has the scriptable automation interface to do everything you ask for and more, and though I don't know of a lockdown switch, its UI is pretty spartan and locked down already. You simply have more options with VS2005R2, even if you may have to program some of them. It all depends on if you are ok with "not possible with VPC 2004" or "requires programming with VS2005R2"...&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=648328" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Virtual+Server/">Virtual Server</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category></item><item><title>HOWTO: Diagnose One Cause of "%1 is not a valid Win32 application" on IIS6 on 64bit Windows</title><link>http://blogs.msdn.com/b/david.wang/archive/2006/06/27/howto-diagnose-one-cause-of-1-is-not-a-valid-win32-application-on-iis6-on-64bit-windows.aspx</link><pubDate>Tue, 27 Jun 2006 13:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:648301</guid><dc:creator>Anonymous</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/david.wang/rsscomments.aspx?WeblogPostID=648301</wfw:commentRss><comments>http://blogs.msdn.com/b/david.wang/archive/2006/06/27/howto-diagnose-one-cause-of-1-is-not-a-valid-win32-application-on-iis6-on-64bit-windows.aspx#comments</comments><description>&lt;H3&gt;Question:&lt;/H3&gt;&lt;FONT face="courier new" color=#008000&gt;
&lt;P&gt;I have a new development server that i put together on a Windows 2003 64 bit&amp;nbsp;machine.&amp;nbsp; I also have SQL Server 2005 and Developers Studio 2005 and 2003 installed on this machine.&amp;nbsp; I have executed the "Enable32bitAppOnWin64 1" command, as per the instructions when installing Developers Studio.&amp;nbsp; I am unable to server ASPX pages from this machine.&amp;nbsp; I started with a "500 - Internal Server Error" but am now getting a "%1 is not a valid Win32 application. "&lt;/P&gt;
&lt;P&gt;Under Application Configuration, ASPX is pointed to C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll.&lt;/P&gt;
&lt;P&gt;I have tried Googling this but haven't found anything.&lt;/P&gt;
&lt;P&gt;Any suggestions?&lt;/P&gt;
&lt;P&gt;Thanks!&lt;/P&gt;&lt;/FONT&gt;
&lt;H3&gt;Answer:&lt;/H3&gt;
&lt;P&gt;Back in this &lt;A href="http://blogs.msdn.com/david.wang/archive/2005/10/06/HOWTO_Diagnose_one_cause_of_503_Service_Unavailable_on_IIS6_on_64bit_Windows.aspx"&gt;blog entry&lt;/A&gt;, I looked at one of many ways to arrive at the dreaded "503 Service Unavailable" - trying to load a 32bit ISAPI Filter DLL into a 64bit w3wp.exe fails because Windows WOW64 compatibility requires DLL and its loading process to have the same bitness. This question arrives at the problem the other way - trying to load a 64bit ISAPI DLL into a 32bit w3wp.exe - which also fails the same OS requirement of the DLL matching bitness of its loading process.&lt;/P&gt;
&lt;P&gt;To make a long story short - there is a compatibility shim which triggers that recommendation for VS.Net 2003 Installation on 64bit Windows. However, there is a 50/50 chance that its recommendation is wrong - it totally depends on what you are trying to do and the order you do them - but we cannot change the .Net 1.1 installer, nor control the order of your installation, nor read your mind. So, we basically had to choose between 50%&amp;nbsp;of users&amp;nbsp;getting errors without ever seeing a warning dialog, or 50% getting errors after following instructions in the warning dialog - and we chose the latter.&lt;/P&gt;
&lt;P&gt;In your case, you managed to configure IIS6 to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Run worker processes in 32bit WOW64 mode (that's what Enable32bitAppOnWin64 1 means) AND &lt;/LI&gt;
&lt;LI&gt;Load 64bit ASP.Net ISAPI DLL into those processes (that's what&amp;nbsp;C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll means)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The bitness mismatch causes the "%1 is not a valid Win32 application." error when IIS6 tries and fails to load the ASP.Net ISAPI DLL handler.&lt;/P&gt;
&lt;P&gt;My guess is that you&amp;nbsp;first installed VS.Net 2005 (which set up 64bit Application Mappings), then installed VS.Net 2003 (which requires Enable32bitAppOnWin64), and upon following the advice, IIS6 stopped working.&lt;/P&gt;
&lt;P&gt;The correct solution? It completely depends on what you are trying to accomplish and what applications you want to run, and there may be no solution. Here are some relevant decision points:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If you want to run ASP.Net 1.1, you MUST run worker processes in 32bit WOW64 mode because it only has a 32bit DLL.&lt;/LI&gt;
&lt;LI&gt;If you want to use FPSE to deploy VS Solutions, you MUST run worker processes in 32bit WOW64 mode because it only has a 32bit DLL (through an ironic twist, there is a 64bit FPSE for Itanium but NOT 64bit FPSE for x64 - and I disregard Itanium availability/usage). Using UNC to deploy VS Solutions is bitness agnostic.&lt;/LI&gt;
&lt;LI&gt;ASP.Net 2.0 can run in either 32bit or 64bit mode. You just have to remember to run the aspnet_regiis.exe from the appropriate Framework/Framework64 folder so that it can tweak the Application Mappings appropriately.&lt;/LI&gt;
&lt;LI&gt;If you are using additional components/applications, make sure their bitness matches that of your configured worker process.&lt;/LI&gt;
&lt;LI&gt;You switch worker process bitness with Enable32bitAppOnWin64, and it is done globally across IIS6.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In general, my advice for 64bit Windows users is that if you want to run 64bit Windows, then only run 64bit applications on it, especially server applications like ASP.Net. Otherwise, you have to learn and understand how a 32bit server application triggers the WOW64 compatibility layer and its interactions with an&amp;nbsp;IIS6 worker process. If you do not do this, you will end up with either 500s or 503s - there are literally gazillion ways to trigger issues and hence very few documented solutions. I cannot document all those problem instances, but I CAN give you advice on how it works and how failures come about - so that you can apply the advice to your situation and determine what is right for you.&lt;/P&gt;
&lt;P&gt;Good luck.&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=648301" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/IIS/">IIS</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/Your+Questions/">Your Questions</category><category domain="http://blogs.msdn.com/b/david.wang/archive/tags/HOWTO_2E00__2E00__2E00_/">HOWTO...</category></item></channel></rss>
