<?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>Robert McMurray's Blog [MSFT] : IIS Topics</title><link>http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx</link><description>Tags: IIS Topics</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>IIS Videos on Dr. Dobb's Web Site</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/12/26/iis-videos-on-dr-dobb-s-web-site.aspx</link><pubDate>Sun, 27 Dec 2009 06:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9941349</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9941349.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9941349</wfw:commentRss><description>&lt;P&gt;Like many people I know, I get a lot of email from various industry-related publications; some of the emails are spam, and the others are from computer magazines that I subscribe to. (And there are several of those. ;-] )&lt;/P&gt;
&lt;P&gt;Anyway, I received an email the other day from the folks at Dr. Dobb’s, and it contained a link for a video on IIS Bitrate Throttling. It always piques my interest to see what others have to say about IIS, so I followed the link and discovered that the following page has several IIS-related videos listed:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.ddj.com/ddjtvmsondemand.jhtml" target=_blank mce_href="http://www.ddj.com/ddjtvmsondemand.jhtml"&gt;http://www.ddj.com/ddjtvmsondemand.jhtml&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Within the list of videos I found videos for FTP and WebDAV, so I couldn't resist watching those:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;IIS FTP Publishing Service&lt;BR&gt;&lt;A href="http://ddj.com/ddjtvmsondemand.jhtml?bcpid=10177845001&amp;amp;bclid=9347349001&amp;amp;bctid=40439588001" target=_blank mce_href="http://ddj.com/ddjtvmsondemand.jhtml?bcpid=10177845001&amp;amp;bclid=9347349001&amp;amp;bctid=40439588001"&gt;http://ddj.com/ddjtvmsondemand.jhtml?bcpid=10177845001&amp;amp;bclid=9347349001&amp;amp;bctid=40439588001&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;IIS WebDAV&lt;BR&gt;&lt;A href="http://ddj.com/ddjtvmsondemand.jhtml?bcpid=10177845001&amp;amp;bclid=9347349001&amp;amp;bctid=40444327001" target=_blank mce_href="http://ddj.com/ddjtvmsondemand.jhtml?bcpid=10177845001&amp;amp;bclid=9347349001&amp;amp;bctid=40444327001"&gt;http://ddj.com/ddjtvmsondemand.jhtml?bcpid=10177845001&amp;amp;bclid=9347349001&amp;amp;bctid=40444327001&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;As I was watching those videos, the thought occurred to me that those videos were really familiar - but not in a déjà vu kind of way. As it turns out, those are the same videos that are on the IIS.NET web site:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;IIS FTP Publishing Service&lt;BR&gt;&lt;A href="http://www.iis.net/expand/ftp" target=_blank mce_href="http://www.iis.net/expand/ftp"&gt;http://www.iis.net/expand/ftp&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;IIS WebDAV&lt;BR&gt;&lt;A href="http://www.iis.net/expand/WebDAV" target=_blank mce_href="http://www.iis.net/expand/WebDAV"&gt;http://www.iis.net/expand/WebDAV&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Oh well - I was hoping for something new. But the fact remains that the folks at Dr. Dobb’s have collected a good number of IIS and Windows-related videos and put them all in one place, so it's a nice reference to have around.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9941349" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/WebDAV/default.aspx">WebDAV</category></item><item><title>IP Address Lookups for Addresses that were Blocked by FTP Dynamic IP Restrictions</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/11/29/ip-address-lookups-for-addresses-that-were-blocked-by-ftp-dynamic-ip-restrictions.aspx</link><pubDate>Mon, 30 Nov 2009 00:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9929961</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9929961.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9929961</wfw:commentRss><description>&lt;P&gt;A few months ago I wrote a blog post that was titled "&lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/08/19/merging-ftp-extensibility-walkthroughs-part-2.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2009/08/19/merging-ftp-extensibility-walkthroughs-part-2.aspx"&gt;Merging FTP Extensibility Walkthroughs - Part 2&lt;/A&gt;", where I described how to merge my &lt;A href="http://learn.iis.net/page.aspx/673/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-with-dynamic-ip-restrictions/" target=_blank mce_href="http://learn.iis.net/page.aspx/673/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-with-dynamic-ip-restrictions/"&gt;FTP Dynamic IP Restrictions Authentication Provider&lt;/A&gt; walkthrough with my &lt;A href="http://learn.iis.net/page.aspx/632/how-to-use-managed-code-c-to-create-an-ftp-provider-that-sends-an-email-when-files-are-uploaded/" mce_href="http://learn.iis.net/page.aspx/632/how-to-use-managed-code-c-to-create-an-ftp-provider-that-sends-an-email-when-files-are-uploaded/"&gt;FTP Provider that Sends an Email when Files are Uploaded&lt;/A&gt; walkthrough. The result of this code combination was a custom FTP authentication provider that provides support for dynamic IP restrictions that sends me an email every time a new IP address is blocked. I deployed this custom FTP authentication provider on one of my public-facing FTP sites when I wrote the blog post, and in the three months that I have been using that provider it has blocked 88 IP addresses.&lt;/P&gt;
&lt;P&gt;Recently it seems that every day I receive a new email that another IP address has been blocked. If you've seen my &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/tags/LogParser/default.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/tags/LogParser/default.aspx"&gt;LogParser&lt;/A&gt; and other log-related blog posts you'll realize that I'm kind of a log analysis geek, so I thought that it might be interesting to at least show something of a breakdown for the information that I've been seeing. For privacy reasons I can't distribute the list of IP addresses, so I'll just show a list of countries that I've seen in my dynamic IP restriction provider's SQL database since I deployed my provider.&lt;/P&gt;
&lt;P&gt;The method that I employed for obtaining the location information was to write a couple of small scripts that dumped the list of IP addresses from my dynamic IP restriction provider's SQL database to a text file and then perform an IP address lookup to count the various countries from where the various hacking attempts have been originating. This gave me the following country-by-country information:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=1 cellSpacing=1 borderColorLight=#000000 borderColorDark=#000000 cellPadding=4 bgColor=#ffffff&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH vAlign=top noWrap align=left&gt;Country&lt;/TH&gt;
&lt;TH noWrap align=right&gt;Total&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;UNITED STATES&lt;/TD&gt;
&lt;TD noWrap align=right&gt;23&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;CHINA&lt;/TD&gt;
&lt;TD noWrap align=right&gt;20&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;[&lt;I&gt;unknown&lt;/I&gt;]&lt;/TD&gt;
&lt;TD noWrap align=right&gt;15&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;GERMANY&lt;/TD&gt;
&lt;TD noWrap align=right&gt;5&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;REPUBLIC OF KOREA&lt;/TD&gt;
&lt;TD noWrap align=right&gt;4&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;FRANCE&lt;/TD&gt;
&lt;TD noWrap align=right&gt;3&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;CZECH REPUBLIC&lt;/TD&gt;
&lt;TD noWrap align=right&gt;3&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;SPAIN&lt;/TD&gt;
&lt;TD noWrap align=right&gt;3&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;POLAND&lt;/TD&gt;
&lt;TD noWrap align=right&gt;2&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;BRAZIL&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;CYPRUS&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;SAUDI ARABIA&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;ARGENTINA&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;NETHERLANDS&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;JAPAN&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;THAILAND&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;SWITZERLAND&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;UKRAINE&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top noWrap align=left&gt;INDIA&lt;/TD&gt;
&lt;TD noWrap align=right&gt;1&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH vAlign=top noWrap align=left&gt;Total&lt;/TH&gt;
&lt;TH noWrap align=right&gt;88&lt;/TH&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I can't give out the name of the site that I used for the IP lookups, but there are several IP locator, geotargeting, or IP mapping sites available; a simple Internet search should provide you with a list of those sites. Once I choose one of those sites, writing a script to pull the IP addresses from my dynamic IP restriction provider's SQL database and perform the lookup was simple. The code that I wrote for the IP lookups was in VBScript, which I have included below. To use this script, you would need to populate a file named "IP_Addresses.txt" with the IP addresses to query, change the value of IP_LOOKUP_STUB in the example below to one of the available IP lookup URLs, then run the script, which will create a file named "IP_Addresses.log" with the resulting IP lookup information:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #008000"&gt;' ****************************************&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Option&lt;/SPAN&gt; Explicit
&lt;SPAN style="COLOR: #008000"&gt;
' ****************************************&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; MAX_ATTEMPTS   = 10    &lt;SPAN style="COLOR: #008000"&gt;' the number of times to keep retrying to get a file&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; FAILURE_SLEEP  = 1000  &lt;SPAN style="COLOR: #008000"&gt;' the number of milliseconds to sleep between retries&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; SUCCESS_SLEEP  = 1000  &lt;SPAN style="COLOR: #008000"&gt;' the number of milliseconds to sleep between successes
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; IP_LOOKUP_STUB = "&lt;SPAN style="COLOR: #8b0000"&gt;http://www.example.com/page?ip=&lt;/SPAN&gt;"
&lt;SPAN style="COLOR: #008000"&gt;
' ****************************************&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objFSO
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objFile
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; strLookupURL
&lt;SPAN style="COLOR: #008000"&gt;
' ****************************************&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objFSO = WScript.CreateObject("&lt;SPAN style="COLOR: #8b0000"&gt;Scripting.FileSystemObject&lt;/SPAN&gt;")
&lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objFile = objFSO.OpenTextFile("&lt;SPAN style="COLOR: #8b0000"&gt;IP_Addresses.txt&lt;/SPAN&gt;")
&lt;SPAN style="COLOR: #0000ff"&gt;Do&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;While&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Not&lt;/SPAN&gt; objFile.AtEndOfStream
  strLookupURL = IP_LOOKUP_STUB &amp;amp; Trim(objFile.ReadLine)
  &lt;SPAN style="COLOR: #0000ff"&gt;Call&lt;/SPAN&gt; IpLookup(strLookupURL)
&lt;SPAN style="COLOR: #0000ff"&gt;Loop&lt;/SPAN&gt;
objFile.Close
WScript.Quit
&lt;SPAN style="COLOR: #008000"&gt;
' ****************************************&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Function&lt;/SPAN&gt; IpLookup(tmpURL)
  &lt;SPAN style="COLOR: #0000ff"&gt;On&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Error&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Resume&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Next&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; intTempAttempt
  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; blnTempStatus
  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objTempFSO
  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objTempFile
  &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objTempFSO = CreateObject("&lt;SPAN style="COLOR: #8b0000"&gt;Scripting.FileSystemObject&lt;/SPAN&gt;")
  blnTempStatus = &lt;SPAN style="COLOR: #0000ff"&gt;False&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objHTTP
  &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objHTTP = CreateObject("&lt;SPAN style="COLOR: #8b0000"&gt;MSXML2.ServerXMLHTTP&lt;/SPAN&gt;")
  &lt;SPAN style="COLOR: #0000ff"&gt;For&lt;/SPAN&gt; intTempAttempt = 1 &lt;SPAN style="COLOR: #0000ff"&gt;To&lt;/SPAN&gt; MAX_ATTEMPTS
    objHTTP.Open "&lt;SPAN style="COLOR: #8b0000"&gt;GET&lt;/SPAN&gt;", tmpURL, &lt;SPAN style="COLOR: #0000ff"&gt;False&lt;/SPAN&gt;
    objHTTP.Send
    &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; (objHTTP.Status = 200) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; Err.Number = 0 &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
        blnTempStatus = &lt;SPAN style="COLOR: #0000ff"&gt;True&lt;/SPAN&gt;
        &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objTempFile = objTempFSO.OpenTextFile("&lt;SPAN style="COLOR: #8b0000"&gt;IP_Addresses.log&lt;/SPAN&gt;",8,&lt;SPAN style="COLOR: #0000ff"&gt;True&lt;/SPAN&gt;)
        objTempFile.WriteLine &lt;SPAN style="COLOR: #0000ff"&gt;String&lt;/SPAN&gt;(80,"&lt;SPAN style="COLOR: #8b0000"&gt;=&lt;/SPAN&gt;")
        objTempFile.WriteLine tmpURL
        objTempFile.WriteLine objHTTP.responseText
        objTempFile.Close
        &lt;SPAN style="COLOR: #0000ff"&gt;Exit&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;For&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt;
    WScript.Sleep FAILURE_SLEEP * intTempAttempt
  &lt;SPAN style="COLOR: #0000ff"&gt;Next&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objHTTP = &lt;SPAN style="COLOR: #0000ff"&gt;Nothing&lt;/SPAN&gt;
  IpLookup = blnTempStatus
&lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Function&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you would rather use managed-code, a great example that you could use as a starting point is the &lt;A href="http://www.codeproject.com/KB/cs/KBSoftIPLocator.aspx" target=_blank mce_href="http://www.codeproject.com/KB/cs/KBSoftIPLocator.aspx"&gt;KBSoft IP Locator&lt;/A&gt; example by Alexandr Golovanov, which also includes the URLs for a couple of IP locator services. Sometime in the future I think that I might write an ASP.NET application that replaces the VBScript code with a web-based interface, or I might add the IP locator logic to my dynamic IP restriction provider&amp;nbsp;through an asynchronous function so that I have the information readily available whenever I want, but for the moment I'm content with my low-tech solution. ;-]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9929961" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category></item><item><title>Using URL Rewrite with Web Site Testing</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/10/13/using-url-rewrite-with-web-site-testing.aspx</link><pubDate>Tue, 13 Oct 2009 22:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9906874</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9906874.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9906874</wfw:commentRss><description>&lt;P&gt;Recently I ran into an interesting situation when I was rolling out a new web-based application. I had tested it on my development server, and because it was a rather complex application I wanted to test it on my production server before making it live. I had already set up a placeholder web site with a home page that announced the new site as "Coming Soon," and I had some of the supporting infrastructure configured for the placeholder site: database connections, permissions, FTP bindings, etc.&lt;/P&gt;
&lt;P&gt;In order to test the new site, I could have set up a temporary web site by duplicating the placeholder web site, running my tests, and then deleting the temporary site after I was comfortable that everything was working in production. Or I could simply remove the placeholder web site and replace it with the temporary web site once the testing phase was over. I didn't like either of those ideas, so I came up with much easier solution using URL Rewrite. Here are the details:&lt;/P&gt;
&lt;P&gt;First, I added an additional host header binding to the placeholder web site with a temporary name that only I knew about. Since I use a wildcard A record for my DNS, I can add any additional prefixes to my domain name without registering those as CNAME records in DNS. (This makes the temporary name more difficult to discover.) For example, if I created an A record for "*.example.com," then I could use "temp.example.com" without any changes to DNS.&lt;/P&gt;
&lt;P&gt;Second, I added a URL Rewrite rule that checked all inbound requests by using the following logic:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If the request was for "temp.example.com", then URL Rewrite would allow regular access the web site.&lt;/LI&gt;
&lt;LI&gt;If the request was for any other domain name and any web page other than "ComingSoon.htm", then URL Rewrite would redirect those requests to "/ComingSoon.htm".&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Here's what the URL Rewrite rule looked like in my web.config file:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: black" id=codeSnippet&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;system.webServer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;rules&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;clear&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;rule&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Temporary Redirect"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;patternSyntax&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Wildcard"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;stopProcessing&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="true"&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;match&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;url&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ComingSoon.htm"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;negate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;conditions&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;          &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;input&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="{HTTP_HOST}"
           &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;negate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="true"
           &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;pattern&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="temp.example.com"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;conditions&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;action&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Redirect"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;url&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="/ComingSoon.htm"
          &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;appendQueryString&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="false"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;redirectType&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Found"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;rule&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;rules&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;system.webServer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This allowed me to test the web site on my production server by using a temporary domain name that no one else knew about, and sending every other HTTP request to the "Coming Soon" announcement page. After a few days of putting the web site through some test passes, all that I needed to do was to remove the URL Rewrite rule and the site was officially live.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9906874" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category></item><item><title>Creating a Microsoft Access Provider for IIS Database Manager</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/09/25/creating-a-microsoft-access-provider-for-iis-database-manager.aspx</link><pubDate>Sat, 26 Sep 2009 01:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9899735</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9899735.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9899735</wfw:commentRss><description>&lt;P&gt;Following up on my &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/09/24/database-manager-api-topics-on-msdn.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2009/09/24/database-manager-api-topics-on-msdn.aspx"&gt;last blog post&lt;/A&gt; about the API set for the &lt;A href="http://www.iis.net/extensions/DatabaseManager" target=_blank mce_href="http://www.iis.net/extensions/DatabaseManager"&gt;IIS Database Manager&lt;/A&gt;, I have something of a secret to let you in on - you can use the code samples in several of those API documents to create a fully functional provider for Microsoft Access databases. I would never use an Access database in a production environment, but having an Access provider has had some great benefits for me from a test perspective. I often use Access databases for test projects, and using the IIS Database Manager to manage the Access databases on my test systems means that I don't need to install Microsoft Access on any of my test servers.&lt;/P&gt;
&lt;P&gt;That being said, as I was writing the API documentation I needed to create something of value to test my code samples. Since the Database Manager feature team was already creating database providers for SQL Server and MySQL, it seemed to me like Microsoft Access was the only other readily-accessible database that I could use for my samples. I mentioned in my last post that Saad Ladki was the Program Manager for Database Manager; Saad had started work on an Access provider at one point, but he abandoned the provider as his schedule grew tighter, so I took over that project so I could use it for the API samples.&lt;/P&gt;
&lt;P&gt;With that in mind, here's what you need to do to create a Microsoft Access provider for the IIS Database Manager:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Create a new class project named "AccessDatabase" in Visual Studio&lt;/LI&gt;
&lt;LI&gt;Add project references for: 
&lt;UL&gt;
&lt;LI&gt;System.Configuration&lt;/LI&gt;
&lt;LI&gt;Microsoft.Web.Management.DatabaseManager&lt;BR&gt;&lt;B&gt;Note&lt;/B&gt;: This may require adding a reference path for your project, such as "C:\Windows\assembly\GAC_MSIL\Microsoft.Web.Management.DatabaseManager\1.0.1.0__31bf3856ad364e35", where "C:" is your operating system drive.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Open the class in the editor, remove the existing code, and insert the following empty class:&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: black"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Collections;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Collections.Generic;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Configuration.Provider;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Data;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Data.Common;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Diagnostics;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.IO;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Linq;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Text;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Reflection;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Data.OleDb;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; Microsoft.Web.Management.DatabaseManager;

&lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; AccessDatabase
{
    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2992ad"&gt;AccessProvider&lt;/SPAN&gt; :
        &lt;SPAN style="COLOR: #2992ad"&gt;DatabaseProvider&lt;/SPAN&gt;,
        &lt;SPAN style="COLOR: #2992ad"&gt;IDbTableManager&lt;/SPAN&gt;,
        &lt;SPAN style="COLOR: #2992ad"&gt;IDbTableDataManager&lt;/SPAN&gt;,
        &lt;SPAN style="COLOR: #2992ad"&gt;IDbViewManager&lt;/SPAN&gt;,
        &lt;SPAN style="COLOR: #2992ad"&gt;IDbBackupManager&lt;/SPAN&gt;,
        &lt;SPAN style="COLOR: #2992ad"&gt;IDbRestoreManager&lt;/SPAN&gt;
    {

    }
}&lt;/PRE&gt;&lt;/LI&gt;
&lt;LI&gt;Copy the code samples from the following MSDN topics into the class; note that some of the utility methods in the code samples will be duplicated so you'll have to remove the duplicate methods: 
&lt;UL&gt;
&lt;LI&gt;&lt;U&gt;DatabaseProvider&lt;/U&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.connectionstringarguments.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.connectionstringarguments.aspx"&gt;ConnectionStringArguments Property&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.calculateconnectionstring.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.calculateconnectionstring.aspx"&gt;CalculateConnectionString Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/ee255810.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ee255810.aspx"&gt;ExecuteQuery Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.testconnection.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.testconnection.aspx"&gt;TestConnection Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.getdatabasehostname.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.getdatabasehostname.aspx"&gt;GetDatabaseHostName Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.getservertypes.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.getservertypes.aspx"&gt;GetServerTypes Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.getdatabaseinfo.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.getdatabaseinfo.aspx"&gt;GetDatabaseInfo Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.verifydependencies.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.databaseprovider.verifydependencies.aspx"&gt;VerifyDependencies Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;U&gt;IDbTableManager&lt;/U&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.createtable.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.createtable.aspx"&gt;CreateTable Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.droptable.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.droptable.aspx"&gt;DropTable Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.edittable.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.edittable.aspx"&gt;EditTable Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.getprimarykey.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.getprimarykey.aspx"&gt;GetPrimaryKey Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.gettableinfo.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.gettableinfo.aspx"&gt;GetTableInfo Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.gettables.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtablemanager.gettables.aspx"&gt;GetTables Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;U&gt;IDbTableDataManager&lt;/U&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.deleterow.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.deleterow.aspx"&gt;DeleteRow Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.editrow.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.editrow.aspx"&gt;EditRow Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.getdata.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.getdata.aspx"&gt;GetData Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.insertrow.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbtabledatamanager.insertrow.aspx"&gt;InsertRow Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;U&gt;IDbViewManager&lt;/U&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.createview.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.createview.aspx"&gt;CreateView Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.dropview.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.dropview.aspx"&gt;DropView Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.editview.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.editview.aspx"&gt;EditView Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.getviews.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbviewmanager.getviews.aspx"&gt;GetViews Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;U&gt;IDbBackupManager&lt;/U&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbbackupmanager.createbackup.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbbackupmanager.createbackup.aspx"&gt;CreateBackup Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;U&gt;IDbRestoreManager&lt;/U&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbrestoremanager.restorebackup.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.idbrestoremanager.restorebackup.aspx"&gt;RestoreBackup Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Save, compile, sign, and GAC the provider. For more information about using the Gacutil.exe tool, see the following topic on Microsoft the MSDN Web site: 
&lt;BLOCKQUOTE&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/ex0ss12c(VS.80).aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ex0ss12c(VS.80).aspx"&gt;Global Assembly Cache Tool (Gacutil.exe)&lt;/A&gt;&lt;/BLOCKQUOTE&gt;&lt;/LI&gt;
&lt;LI&gt;Follow the instructions in the &lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.aspx"&gt;Microsoft.Web.Management.DatabaseManager Namespace&lt;/A&gt; topic to add the following entry to your administration.config file, which will register the provider for IIS Manager:&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: black"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;provider&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Access Provider"
  &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;providerName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="System.Data.OleDb"
  &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="AccessDatabase.AccessProvider,AccessDatabase,Version=1.0.0.0,Culture=neutral,PublicKeyToken=426f62526f636b73"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
   &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;databaseBackup&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #ff0000"&gt;backupEnabled&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="true"&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #ff0000"&gt;restoreEnabled&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="true"&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #ff0000"&gt;backupPath&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="C:\backups"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;provider&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: You will need to update the PublicKeyToken with the public key token from your assembly.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;Add an OLEDB connection string for your Access database; the following web.config sample shows what that might look like:&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: black"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;connectionStrings&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Northwind"&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #ff0000"&gt;providerName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="System.Data.OleDb"&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #ff0000"&gt;connectionString&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\inetpub\wwwroot\App_Data\Northwind.mdb;"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;connectionStrings&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: Since the code samples were all written using OLEDB, not ODBC, you will need to make sure that you use an OLEDB connection string like my example.&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;Open the IIS Manager and open the Database Manager for the site where you added the connection string. You should now be able to manage the tables and views for your Access database, as well as backing up and restoring your database.&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Additional Notes&lt;/H3&gt;
&lt;H4&gt;Creating Database Backups&lt;/H4&gt;
&lt;P&gt;Even though I wrote my provider to implement backing up and restoring databases, this functionality is purely optional - you could easily remove the &lt;SPAN style="COLOR: #2992ad"&gt;IDbBackupManager&lt;/SPAN&gt; and &lt;SPAN style="COLOR: #2992ad"&gt;IDbRestoreManager&lt;/SPAN&gt; implementations from the class and remove the &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;databaseBackup&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt; element from administration.config.&lt;/P&gt;
&lt;H4&gt;OLEDB Errors When Saving JOIN/ORDER BY Views (Queries)&lt;/H4&gt;
&lt;P&gt;Unfortunately, there is one unexpected OLEDB problem with Microsoft Access databases that I ran into that I could not work around. When you attempt to save a view (query) that contains both &lt;CODE style="COLOR: #0000ff"&gt;JOIN&lt;/CODE&gt; statements and &lt;CODE style="COLOR: #0000ff"&gt;ORDER BY&lt;/CODE&gt; statements, you will receive an error that states "Only simple SELECT queries are allowed in VIEWS."&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG src="http://y7b40a.blu.livefilestore.com/y1pjFQ4CUsjEl2QqYKBlpvHBm0umh-Sr24a2Z-GifS8O97pPE7nqXznC_8Bdz1q_4L6ZE_YPl4uaEIs3kR33m8LuBDiFfbvMoln/SimpleSelectQueries.jpg" width=338 height=145 mce_src="http://y7b40a.blu.livefilestore.com/y1pjFQ4CUsjEl2QqYKBlpvHBm0umh-Sr24a2Z-GifS8O97pPE7nqXznC_8Bdz1q_4L6ZE_YPl4uaEIs3kR33m8LuBDiFfbvMoln/SimpleSelectQueries.jpg"&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As long as the SQL code is syntactically correct you can execute the query, but you cannot save it. If a query that contains both &lt;CODE style="COLOR: #0000ff"&gt;JOIN&lt;/CODE&gt; statements and &lt;CODE style="COLOR: #0000ff"&gt;ORDER BY&lt;/CODE&gt; statements has already been created in Microsoft Access, you can open it and make changes, but you will not be able to save those changes back to the database.&lt;/P&gt;
&lt;P&gt;For example, the following SQL code will cause the error to occur:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: black"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;SELECT&lt;/SPAN&gt; Categories.CategoryName, Products.ProductName
&lt;SPAN style="COLOR: #0000ff"&gt;FROM&lt;/SPAN&gt; Products &lt;SPAN style="COLOR: #0000ff"&gt;INNER&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;JOIN&lt;/SPAN&gt; Categories &lt;SPAN style="COLOR: #0000ff"&gt;ON&lt;/SPAN&gt; Products.CategoryID = Categories.CategoryID
&lt;SPAN style="COLOR: #0000ff"&gt;ORDER&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;BY&lt;/SPAN&gt; Categories.CategoryName, Products.ProductName;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;While the following code will not cause the error:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: black"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;SELECT&lt;/SPAN&gt; Categories.CategoryName, Products.ProductName
&lt;SPAN style="COLOR: #0000ff"&gt;FROM&lt;/SPAN&gt; Products &lt;SPAN style="COLOR: #0000ff"&gt;INNER&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;JOIN&lt;/SPAN&gt; Categories &lt;SPAN style="COLOR: #0000ff"&gt;ON&lt;/SPAN&gt; Products.CategoryID = Categories.CategoryID;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Even though the SQL code is syntactically correct and will execute without any problems, the error occurs at the OLEDB layer when the provider executes the &lt;CODE style="COLOR: #0000ff"&gt;CREATE VIEW&lt;/CODE&gt; statement to save the view to the database. This appears to be an unfortunate and irresolvable OLEDB limitation when you are using an Access database. When you are faced with such a situation, you will need to open the database in Microsoft Access to save the query.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899735" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category></item><item><title>Database Manager API Topics on MSDN</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/09/24/database-manager-api-topics-on-msdn.aspx</link><pubDate>Thu, 24 Sep 2009 21:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9899083</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9899083.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9899083</wfw:commentRss><description>&lt;P&gt;Today Microsoft released version 1.0 of the &lt;A href="http://www.iis.net/extensions/DatabaseManager" target=_blank mce_href="http://www.iis.net/extensions/DatabaseManager"&gt;IIS Database Manager&lt;/A&gt;, which enables you to manage local and remote SQL Server or MySQL databases through the IIS Manager. I cannot stress enough how this module has rapidly become one of my favorite extensions for IIS Manager. There are many times when I need to access the data in one of my databases where opening the database management tool would be inconvenient or impossible. (For example, when I am working remotely, or when I don't have the database management tools installed.) In these situations, the Database Manager has been worth its weight in gold.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://kcqorw.blu.livefilestore.com/y1p3SKuJU-n7sGoMIdJtUXyKBtJ9WL-5bXR3digSGCObRXLo5Hi3rmeiGNscNL3Jnl4dwQDaDKAxEFwd3ThxFAOQFQDjUkfgjGp/Database_Manager_UI.jpg" target=_blank mce_href="http://kcqorw.blu.livefilestore.com/y1p3SKuJU-n7sGoMIdJtUXyKBtJ9WL-5bXR3digSGCObRXLo5Hi3rmeiGNscNL3Jnl4dwQDaDKAxEFwd3ThxFAOQFQDjUkfgjGp/Database_Manager_UI.jpg"&gt;&lt;IMG src="http://kcqorw.blu.livefilestore.com/y1pEMF4wLCYxxLX4u0uUdhLLSn5KIsJkFFgbhxtMHceCBRSOZku4LGMO-lI3hnB3aPxwO7qHgyVpNtu1rcNZEi-vp8-ihWb4dhg/DatabaseManager_small.jpg" width=640 height=467 mce_src="http://kcqorw.blu.livefilestore.com/y1pEMF4wLCYxxLX4u0uUdhLLSn5KIsJkFFgbhxtMHceCBRSOZku4LGMO-lI3hnB3aPxwO7qHgyVpNtu1rcNZEi-vp8-ihWb4dhg/DatabaseManager_small.jpg"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Another great feature of the IIS Database Manager is that it is extensible, like every other part of IIS these days, meaning that you can create your own database providers. Following up on that thought, in addition to all of the walkthroughs and blog posts that I've been writing about FTP and WebDAV over the past several months, I've also been working on documenting the API set for the &lt;A href="http://www.iis.net/extensions/DatabaseManager" target=_blank mce_href="http://www.iis.net/extensions/DatabaseManager"&gt;IIS Database Manager&lt;/A&gt;, and all of those topics have been published on the MSDN Web site under the following URL:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.aspx" mce_href="http://msdn.microsoft.com/en-us/library/microsoft.web.management.databasemanager.aspx"&gt;Microsoft.Web.Management.DatabaseManager Namespace&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I would be remiss if I didn't give credit where it's due, so my special thanks go to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;The Database Manager Feature Team&lt;/B&gt; - the entire team did some great work: 
&lt;UL&gt;
&lt;LI&gt;Saad, &lt;A href="http://blogs.iis.net/bdela/" target=_blank mce_href="http://blogs.iis.net/bdela/"&gt;Brian&lt;/A&gt;, &lt;A href="http://blogs.iis.net/rlucero/" target=_blank mce_href="http://blogs.iis.net/rlucero/"&gt;Bob&lt;/A&gt;, Tim, Andrew, Nitasha, Richard, &lt;A href="http://blogs.msdn.com/carlosag/" target=_blank mce_href="http://blogs.msdn.com/carlosag/"&gt;Carlos&lt;/A&gt;, Madhur, &lt;A href="http://blogs.iis.net/nazim/" target=_blank mce_href="http://blogs.iis.net/nazim/"&gt;Nazim&lt;/A&gt;, Ivan, Crystal, Faith, Diana, Pete, Rich, Raul&lt;/LI&gt;
&lt;LI&gt;That being said, there are two people that I'd like to call our for their additional assistance: 
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;Saad Ladki&lt;/B&gt; - Saad was the Program Manager for the Database Manager. I have to give credit where it's due and say that my job would have been a lot harder if Saad hadn't done the initial research for some of my code samples.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;&lt;A href="http://blogs.iis.net/bdela/" mce_href="http://blogs.iis.net/bdela/"&gt;Brian Delahunty&lt;/A&gt;&lt;/B&gt; - Brian was my principal contact on the feature team whenever I needed help or backed myself into a corner. Brian was very accommodating when I suggested changes, and he always had great explanations when something needed clarification.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;&lt;A href="http://www.microsoft.com/mspress/" mce_href="http://www.microsoft.com/mspress/"&gt;Microsoft Press&lt;/A&gt;&lt;/B&gt; - I know that it seems like a gratuitous plug, but I spent dozens of hours going through my "&lt;A href="http://www.microsoft.com/mspress/books/2520.aspx" mce_href="http://www.microsoft.com/mspress/books/2520.aspx"&gt;Microsoft® OLE DB 2.0 Programmer's Reference and Data Access SDK&lt;/A&gt;" book looking up the various parts of the OLEDB schema. That book was simply indispensable while I was writing my API samples.&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899083" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category></item><item><title>eWeek Reviews for IIS 7.5 and FTP 7.5</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/09/23/eweek-reviews-for-iis-7-5-and-ftp-7-5.aspx</link><pubDate>Thu, 24 Sep 2009 01:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9898705</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9898705.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9898705</wfw:commentRss><description>&lt;P&gt;One of my coworkers, Vijay Sen, just forwarded the following eWeek review of IIS 7.5 to me:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.eweek.com/c/a/Windows/REVIEW-Microsoft-IIS-75-Improves-Management-Deployment-Options-822018/" target=_blank mce_href="http://www.eweek.com/c/a/Windows/REVIEW-Microsoft-IIS-75-Improves-Management-Deployment-Options-822018/"&gt;http://www.eweek.com/c/a/Windows/REVIEW-Microsoft-IIS-75-Improves-Management-Deployment-Options-822018/&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The review was written by &lt;A href="http://www.eweek.com/cp/bio/Jim-Rapoza/" target=_blank mce_href="http://www.eweek.com/cp/bio/Jim-Rapoza/"&gt;Jim Rapoza&lt;/A&gt;, and he said some great things about IIS 7.5, which ships with both Windows Server 2008 R2 and Windows 7 client. But what really made my day was the following things that he said about FTP 7.5:&lt;/P&gt;
&lt;BLOCKQUOTE style="BACKGROUND-COLOR: #eeeeee; COLOR: #000000"&gt;
&lt;P&gt;&lt;EM&gt;Another welcome change in IIS 7.5 is the elevation of FTP as a full-fledged part of the server. In previous versions, setup and management of an FTP server in IIS were done pretty much separately from Web server management. In IIS 7.5, FTP administration is fully integrated into the IIS Management Console.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;I found this to be a very good implementation of FTP, making it possible to quickly set up secure FTP servers and tie them to my Websites. Especially nice was the ability to easily use virtual host names for the FTP sites. All in all, the FTP implementation in IIS 7.5 is one of the best I’ve seen, even when compared with dedicated FTP server products.&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;It’s great to see all of our hard work being recognized!&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/regular_smile.gif"&gt;&lt;/P&gt;
&lt;P&gt;My thanks once again to everyone on the FTP and IIS feature teams that helped make this version of the FTP service: &lt;A href="http://blogs.iis.net/jaroslad/" mce_href="http://blogs.iis.net/jaroslad/"&gt;Jaroslav&lt;/A&gt;, Emily, &lt;A href="http://blogs.msdn.com/danielvl/" mce_href="http://blogs.msdn.com/danielvl/"&gt;Daniel&lt;/A&gt;, Umer, &lt;A href="http://blogs.iis.net/suDt/" mce_href="http://blogs.iis.net/suDt/"&gt;Suditi&lt;/A&gt;, Ciprian, Jeong, &lt;A href="http://blogs.iis.net/davcox/" mce_href="http://blogs.iis.net/davcox/"&gt;Dave&lt;/A&gt;, Andrew, &lt;A href="http://blogs.msdn.com/carlosag/" mce_href="http://blogs.msdn.com/carlosag/"&gt;Carlos&lt;/A&gt;, &lt;A href="http://blogs.iis.net/bdela/" mce_href="http://blogs.iis.net/bdela/"&gt;Brian&lt;/A&gt;, &lt;A href="http://blogs.iis.net/wadeh/" mce_href="http://blogs.iis.net/wadeh/"&gt;Wade&lt;/A&gt;, Ulad, &lt;A href="http://blogs.iis.net/nazim/" mce_href="http://blogs.iis.net/nazim/"&gt;Nazim&lt;/A&gt;, Reagan, Claudia, Rick, Tim, &lt;A href="http://blogs.iis.net/TobinTitus/" mce_href="http://blogs.iis.net/TobinTitus/"&gt;Tobin&lt;/A&gt;, Kern, Jenny, Nitasha, Venkat, Vijay. (I hope that I didn't leave anyone out!)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9898705" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category></item><item><title>FTP 7.5 Extensibility and Visual Studio Express Editions</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/09/17/ftp-7-5-extensibility-and-visual-studio-express-editions.aspx</link><pubDate>Thu, 17 Sep 2009 21:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9896442</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9896442.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9896442</wfw:commentRss><description>&lt;P&gt;In earlier blog posts I have mentioned that I written the several walkthroughs to help developers get started writing providers for the FTP 7.5 service, all of which available on Microsoft's &lt;A href="http://learn.iis.net/" target=_blank mce_href="http://learn.iis.net/"&gt;learn.iis.net&lt;/A&gt; Web site under the "&lt;A href="http://learn.iis.net/page.aspx/590/developing-for-ftp-75/" target=_blank mce_href="http://learn.iis.net/page.aspx/590/developing-for-ftp-75/"&gt;Developing for FTP 7.5&lt;/A&gt;" section. In each of these walkthroughs I wrote the steps as if you were using Visual Studio 2008.&lt;/P&gt;
&lt;P&gt;Following up on that, I received a great question yesterday from a customer, Paul Dowdle, who wondered if it was possible to write an extensibility provider for the FTP 7.5 service using one of the Visual Studio Express Editions. By way of coincidence, I used to install Visual C# Express Edition on my laptop when I was traveling around the world to speak at events like &lt;A href="http://www.msteched.com/" target=_blank mce_href="http://www.msteched.com/"&gt;TechEd&lt;/A&gt;. I usually did this because the Express Edition took up less hard drive space than a full installation of Visual Studio, and I was only writing code in C# on my laptop.&lt;/P&gt;
&lt;P&gt;To answer Paul's question, the short answer is - yes, you can use Visual Studio Express Editions to develop custom providers for the FTP 7.5 service, with perhaps a few small changes from my walkthroughs.&lt;/P&gt;
&lt;P&gt;For example, if you look at my "&lt;A href="http://learn.iis.net/page.aspx/598/how-to-use-managed-code-c-to-create-a-simple-ftp-authentication-provider/" target=_blank&gt;How to Use Managed Code (C#) to Create a Simple FTP Authentication Provider&lt;/A&gt;" walkthrough, in the section that is titled "Step 1: Set up the Project Environment", there is an optional step 6 for adding a custom build event to register the DLL automatically in the Global Assembly Cache (GAC) on your development computer.&lt;/P&gt;
&lt;P&gt;When I installed Microsoft Visual C# 2008 Express Edition on a new computer, I didn't have the "%VS90COMNTOOLS%" environment variable or the "vsvars32.bat" file, so I had to update the custom build event to the following:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;net stop ftpsvc
"%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe" /if "$(TargetPath)"
net start ftpsvc&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Once I made that change, the rest of the walkthrough worked as written.&lt;/P&gt;
&lt;P&gt;So, to reiterate my earlier statement - you can use Visual Studio Express Editions to develop custom providers for the FTP 7.5 service. My thanks to Paul for the great question!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9896442" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category></item><item><title>Hiding your FTP Server Type and Preventing Unauthorized Access</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/09/10/hiding-your-ftp-server-type-and-preventing-unauthorized-access.aspx</link><pubDate>Thu, 10 Sep 2009 23:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9893855</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9893855.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9893855</wfw:commentRss><description>&lt;P&gt;As evidenced by my &lt;A href="http://learn.iis.net/page.aspx/673/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-with-dynamic-ip-restrictions" target=_blank mce_href="http://learn.iis.net/page.aspx/673/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-with-dynamic-ip-restrictions"&gt;How to Use Managed Code (C#) to Create an FTP Authentication Provider with Dynamic IP Restrictions&lt;/A&gt; walkthrough and my other FTP authentication extensibility walkthroughs, I spend a lot of time trying to find ways to prevent unauthorized access to my FTP server while still allowing valid users to have easy access to their site content. Today's blog discusses several of the ideas that I like to use on my FTP servers.&lt;/P&gt;
&lt;H4&gt;Preventing Unauthorized Access&lt;/H4&gt;
&lt;P&gt;To start things off, I globally disable FTP Basic Authentication on my server and I only use custom authentication providers. Since my FTP users do not have actual accounts on my server or my domain, that helps prevent access to my physical server. It was for this reason that I wrote the authentication provider that I discuss in my &lt;A href="http://learn.iis.net/page.aspx/669/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-using-an-xml-database/" target=_blank mce_href="http://learn.iis.net/page.aspx/669/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-using-an-xml-database/"&gt;How to Use Managed Code (C#) to Create an FTP Authentication Provider using an XML Database&lt;/A&gt; walkthrough; I can hand out accounts with FTP access for sites that are hosted on my servers, but those accounts are stored in an XML file and not in the security accounts database on my server or my domain.&lt;/P&gt;
&lt;P&gt;But there are other ways to help secure your FTP server. For example, I wrote an earlier blog post about &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2008/12/17/ftp-clients-part-3-creating-a-global-listener-ftp-site.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2008/12/17/ftp-clients-part-3-creating-a-global-listener-ftp-site.aspx"&gt;Creating a Global Listener FTP Site&lt;/A&gt;. On my servers I like to create a global listener site and disable all of the built-in authentication methods.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://y7b40a.blu.livefilestore.com/y1po9uDXUnvLNqdZK2dEzQWsLqaXG7inoFz_H881H8J--X-hwo41dWJ3_eHb50XzagqsV_RP9VLJiSFaDgHhAod6i0EICF7SzL2/global%20listener%20site.jpg" target=_blank mce_href="http://y7b40a.blu.livefilestore.com/y1po9uDXUnvLNqdZK2dEzQWsLqaXG7inoFz_H881H8J--X-hwo41dWJ3_eHb50XzagqsV_RP9VLJiSFaDgHhAod6i0EICF7SzL2/global%20listener%20site.jpg"&gt;&lt;IMG border=3 src="http://y7b40a.blu.livefilestore.com/y1po9uDXUnvLNqdZK2dEzQWsLqaXG7inoFz_H881H8J--X-hwo41dWJ3_eHb50XzagqsV_RP9VLJiSFaDgHhAod6i0EICF7SzL2/global%20listener%20site.jpg" width="50%" height="50%" mce_src="http://y7b40a.blu.livefilestore.com/y1po9uDXUnvLNqdZK2dEzQWsLqaXG7inoFz_H881H8J--X-hwo41dWJ3_eHb50XzagqsV_RP9VLJiSFaDgHhAod6i0EICF7SzL2/global%20listener%20site.jpg"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Once that has been completed I add the custom authentication provider from my &lt;A href="http://learn.iis.net/page.aspx/673/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-with-dynamic-ip-restrictions" target=_blank mce_href="http://learn.iis.net/page.aspx/673/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-with-dynamic-ip-restrictions"&gt;How to Use Managed Code (C#) to Create an FTP Authentication Provider with Dynamic IP Restrictions&lt;/A&gt; walkthrough, but I don't create any accounts in the database - I just want to log and block the IP addresses of would-be attackers that are attempting to brute force their way into my server. Configuring the authentication options is accomplished through the &lt;B&gt;FTP Authentication&lt;/B&gt; feature in IIS Manager.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://y7b40a.blu.livefilestore.com/y1pnRv7mOVfWdg6rqBSthl45xDuJRnaqxFGxoknchIvknjoE68WE45N0Zte2euTZx2x-MmrZFCz5qtcASgMgOVM2Q/custom%20authentication.jpg" target=_blank mce_href="http://y7b40a.blu.livefilestore.com/y1pnRv7mOVfWdg6rqBSthl45xDuJRnaqxFGxoknchIvknjoE68WE45N0Zte2euTZx2x-MmrZFCz5qtcASgMgOVM2Q/custom%20authentication.jpg"&gt;&lt;IMG border=3 src="http://y7b40a.blu.livefilestore.com/y1pnRv7mOVfWdg6rqBSthl45xDuJRnaqxFGxoknchIvknjoE68WE45N0Zte2euTZx2x-MmrZFCz5qtcASgMgOVM2Q/custom%20authentication.jpg" width="50%" height="50%" mce_src="http://y7b40a.blu.livefilestore.com/y1pnRv7mOVfWdg6rqBSthl45xDuJRnaqxFGxoknchIvknjoE68WE45N0Zte2euTZx2x-MmrZFCz5qtcASgMgOVM2Q/custom%20authentication.jpg"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Ever since I wrote and deployed my dynamic IP address restriction authentication provider, it has faithfully blocked dozens of would-be attackers.&lt;/P&gt;
&lt;H4&gt;Hiding your FTP Server Type&lt;/H4&gt;
&lt;P&gt;The next approach that I take is "Security through Obscurity", where I hide the easily recognizable signatures that identify my FTP server. The first step is to suppress the default banner and add a custom FTP banner. This is accomplished through the &lt;B&gt;FTP Messages&lt;/B&gt; feature in IIS Manager.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://y7b40a.blu.livefilestore.com/y1pkwDMrU610dFt0Ug2OZmoqQJtBHCvs7dpjxkg-5UGYdkKDuoaQ0RUwwriheMaJfsjw37mKU0-86yebF1hhmCNbA/messages.jpg" target=_blank mce_href="http://y7b40a.blu.livefilestore.com/y1pkwDMrU610dFt0Ug2OZmoqQJtBHCvs7dpjxkg-5UGYdkKDuoaQ0RUwwriheMaJfsjw37mKU0-86yebF1hhmCNbA/messages.jpg"&gt;&lt;IMG border=3 src="http://y7b40a.blu.livefilestore.com/y1pkwDMrU610dFt0Ug2OZmoqQJtBHCvs7dpjxkg-5UGYdkKDuoaQ0RUwwriheMaJfsjw37mKU0-86yebF1hhmCNbA/messages.jpg" width="50%" height="50%" mce_src="http://y7b40a.blu.livefilestore.com/y1pkwDMrU610dFt0Ug2OZmoqQJtBHCvs7dpjxkg-5UGYdkKDuoaQ0RUwwriheMaJfsjw37mKU0-86yebF1hhmCNbA/messages.jpg"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Next, switch your directory listing style to Unix format. All FTP clients that I have tested understand this format, but it hides the fact that your server can do MS-DOS listings. Configuring your directory listing style is accomplished through the &lt;B&gt;FTP Directory Browsing &lt;/B&gt;feature in IIS Manager.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://y7b40a.blu.livefilestore.com/y1pF7d1kpsjM9VBLgUc2GuWw_Ukko9FUQU_JtdKrKgDFaiD-tTp3UoVfgsyNfltgAADqmM-m7JjlkL64edKdU09iQ/directory%20browsing.jpg" target=_blank mce_href="http://y7b40a.blu.livefilestore.com/y1pF7d1kpsjM9VBLgUc2GuWw_Ukko9FUQU_JtdKrKgDFaiD-tTp3UoVfgsyNfltgAADqmM-m7JjlkL64edKdU09iQ/directory%20browsing.jpg"&gt;&lt;IMG border=3 src="http://y7b40a.blu.livefilestore.com/y1pF7d1kpsjM9VBLgUc2GuWw_Ukko9FUQU_JtdKrKgDFaiD-tTp3UoVfgsyNfltgAADqmM-m7JjlkL64edKdU09iQ/directory%20browsing.jpg" width="50%" height="50%" mce_src="http://y7b40a.blu.livefilestore.com/y1pF7d1kpsjM9VBLgUc2GuWw_Ukko9FUQU_JtdKrKgDFaiD-tTp3UoVfgsyNfltgAADqmM-m7JjlkL64edKdU09iQ/directory%20browsing.jpg"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;After implementing these changes, it might now resemble the following example FTP session when you log in with FTP:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE style="BACKGROUND-COLOR: #000000; COLOR: #ffffff"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;PRE&gt;CMD&amp;gt;ftp localhost

Connected to DESKTOP.domain.local.
220 Welcome to my server!
User (DESKTOP.domain.local:(none)): foobar
331 Password required for foobar.
Password:
230 User logged in.
ftp&amp;gt; dir
200 EPRT command successful.
125 Data connection already open; Transfer starting.
drwxrwxrwx   1 owner    group               0 Jan 22 11:45 App_Code
drwxrwxrwx   1 owner    group               0 Sep 10 10:32 App_Data
drwxrwxrwx   1 owner    group               0 Aug 17 13:35 bin
-rwxrwxrwx   1 owner    group             689 May  8  2008 iisstart.htm
-rwxrwxrwx   1 owner    group            2714 Jan 22 11:54 web.config
-rwxrwxrwx   1 owner    group          184946 May  8  2008 welcome.png
226 Transfer complete.
ftp: 418 bytes received in 0.02Seconds 83.00Kbytes/sec.
ftp&amp;gt; bye
221 Goodbye.

CMD&amp;gt;&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The last step that I take is to block the FTP infrastructure commands &lt;B&gt;SYST&lt;/B&gt; and &lt;B&gt;FEAT&lt;/B&gt; on the global listener FTP site. These commands respectively display your operating system and list of FTP features. Blocking these commands helps to further obfuscate your server type from attackers.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: It is important that you block these two commands only on your global listener FTP site and not on your other FTP sites, because some FTP clients may depend on these commands in order to interact properly with your other FTP sites. That said, if you are working with a small set of FTP clients and none of them seem to have a problem with suppressing the &lt;B&gt;SYST&lt;/B&gt; command, you could probably suppress that globally. Most clients that I have tested seem to have no problem with that, especially if you are using Unix directory listings.&lt;/P&gt;
&lt;P&gt;In any event, you block the &lt;B&gt;SYST&lt;/B&gt; and &lt;B&gt;FEAT&lt;/B&gt; commands through the &lt;B&gt;FTP Request Filtering &lt;/B&gt;feature in IIS Manager.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://y7b40a.blu.livefilestore.com/y1pyRKiOzDCI1bIKmYbXQPEMbdt80pRsnwJ-mw83yyp9UUtFP3Li67R3egteQT6MDhD1JCF8ofHxKt8IWLZ0ZruBA/request%20filtering.jpg" target=_blank mce_href="http://y7b40a.blu.livefilestore.com/y1pyRKiOzDCI1bIKmYbXQPEMbdt80pRsnwJ-mw83yyp9UUtFP3Li67R3egteQT6MDhD1JCF8ofHxKt8IWLZ0ZruBA/request%20filtering.jpg"&gt;&lt;IMG border=3 src="http://y7b40a.blu.livefilestore.com/y1pyRKiOzDCI1bIKmYbXQPEMbdt80pRsnwJ-mw83yyp9UUtFP3Li67R3egteQT6MDhD1JCF8ofHxKt8IWLZ0ZruBA/request%20filtering.jpg" width="50%" height="50%" mce_src="http://y7b40a.blu.livefilestore.com/y1pyRKiOzDCI1bIKmYbXQPEMbdt80pRsnwJ-mw83yyp9UUtFP3Li67R3egteQT6MDhD1JCF8ofHxKt8IWLZ0ZruBA/request%20filtering.jpg"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now when you log in with FTP and attempt to use the &lt;B&gt;SYST&lt;/B&gt; and &lt;B&gt;FEAT&lt;/B&gt; commands, it should look like the following example FTP session:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE style="BACKGROUND-COLOR: #000000; COLOR: #ffffff" id=table1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;PRE&gt;CMD&amp;gt;ftp localhost

Connected to DESKTOP.domain.local.
220 Welcome to my server!
User (DESKTOP.domain.local:(none)): foobar
331 Password required for foobar.
Password:
230 User logged in.
ftp&amp;gt; quote SYST
500 'SYST': command not allowed.
ftp&amp;gt; quote FEAT
500 'FEAT': command not allowed.
ftp&amp;gt; bye
221 Goodbye.

CMD&amp;gt;&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Summary&lt;/H4&gt;
&lt;P&gt;The steps in this blog are certainly not all-inclusive, and I keep coming up with other ideas as time goes on, but following these steps should help to prevent unauthorized access to your FTP service. All of the normal warnings about using strong passwords, changing your passwords often, using SSL whenever you can, and keeping your hotfixes up-to-date will always apply.&lt;/P&gt;
&lt;P&gt;But that being said, one of the ways that I keep finding new things to block is by simply watching my FTP log files to see what attackers are trying to do. By using some of the techniques that I discuss in my &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/06/11/using-logparser-with-ftp-7-x-sessions.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2009/06/11/using-logparser-with-ftp-7-x-sessions.aspx"&gt;Using LogParser with FTP 7.x Sessions&lt;/A&gt; blog, you can monitor your FTP log files in order to analyze what would-be attackers are trying to do.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9893855" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category></item><item><title>The End of Metabase Corruption (R.I.P.)</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/08/22/the-end-of-metabase-corruption-r-i-p.aspx</link><pubDate>Sat, 22 Aug 2009 10:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9880070</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9880070.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9880070</wfw:commentRss><description>&lt;P&gt;Even though IIS 7 with its new XML-based configuration settings has been around for a while, I was going through some old directories on one of my computers the other day and I stumbled across an image that I had labeled "Metabase Corruption." I have kept that image around for the past decade or so because it's one of the few actual examples of metabase corruption that I have actually verified, although there have definitely been more cases than just the ones that I have seen. But I thought that it might make for a good blog entry to explain the origins of the term "Metabase Corruption" and what that means to you if you're using a version of IIS that is earlier than IIS 7.&lt;/P&gt;
&lt;H4&gt;A brief history of the IIS metabase and metabase editors&lt;/H4&gt;
&lt;P&gt;Many years ago I was working in the Microsoft Product Support Services (PSS) group, where I provided support for enterprise-level customers that were using IIS versions 1.0 through 6.0. The early versions of IIS, (versions 1.0 through 3.0), stored all of their settings in the registry. This was fine for that period of time, but it didn't scale well and for several other reasons it was cumbersome to deal with. Just to bring back some nightmares, here's an image of the IIS 3.0 manager:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9530997/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/robert_mcmurray/images/9530997/original.aspx"&gt;&lt;IMG alt="IIS 3.0 Manager" src="http://blogs.msdn.com/photos/robert_mcmurray/images/9530997/500x265.aspx" mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9530997/500x265.aspx"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;When IIS 4.0 was released, it introduced the "metabase," which was a proprietary database that stored all of the metadata for IIS, and all of that information was physically stored in a file that was named metabase.bin. The metabase scaled considerably better than the registry, but it introduced several other problems. The biggest problem was that the metabase was something of a "black box" for end users - all of your settings were stored in the metabase, and the only way to get to those settings was through the IIS Manager or by using unsupported command-line tools. The next big problem was that the metabase wasn't portable - you couldn't copy the metabase from one computer to another. (If you tried you would quickly realize that you just killed IIS.) When the IIS 4.0 Resource Kit was released it introduced MetaEdit 1.0, which was an editor for the metabase that looked like RegEdit, but it crashed so often that it really wasn't useful.&lt;/P&gt;
&lt;P&gt;During the Windows 2000 timeframe I took over the MetaEdit code base and I created MetaEdit 2.0, which was released with the Windows 2000 Resource Kit. I fixed all of the stability problems from MetaEdit 1.0 and I added export/import functionality so that users could copy sections of the metabase between servers. Actually, I wrote MetaEdit before Microsoft stopped adding Easter Eggs to software, so there's a small Easter Egg in the Help::About for MetaEdit that you can find by holding down Shift-Ctrl-Alt and double-clicking the icon - you first see a photo of Bill Gates and then you see a photo of me from the days when I had longer hair...&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG src="http://y7b40a.blu.livefilestore.com/y1pf2cuhrhPrw3keEIlIgRIt4p_cjoEEgioFb5VwJeO8yOEgsWtnxcH857pJSvkPkAdHwDwELFI4VeymXmrXof8BQ/MetaEdit22.jpg" mce_src="http://y7b40a.blu.livefilestore.com/y1pf2cuhrhPrw3keEIlIgRIt4p_cjoEEgioFb5VwJeO8yOEgsWtnxcH857pJSvkPkAdHwDwELFI4VeymXmrXof8BQ/MetaEdit22.jpg"&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I released a couple of patches to MetaEdit over the years, and the last version that I released is version 2.2, which you can download through the following URL:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://support.microsoft.com/kb/301386" target=_blank mce_href="http://support.microsoft.com/kb/301386"&gt;How To Install MetaEdit 2.2 on Windows NT 4.0 or Windows 2000&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;When Windows Server 2003 was in development, XML had risen within the development community as a great way to store your data, so the IIS team decided to switch from the metabase.bin format to metabase.xml. This allowed for editing the metabase using any XML editor, even Windows Notepad, and IIS added native export and import functionality, so you could migrate settings from one computer to another by using IIS Manager.&lt;/P&gt;
&lt;P&gt;It was sometime during the Windows 2003 timeframe that I was working on MetaEdit 3.0 when I heard that someone else was working on Metabase Explorer, and the early versions of Metabase Explorer that I was able to test were really cool, so I ceased work on MetaEdit in favor of Metabase Explorer, which was eventually released with the IIS 6.0 Resource Kit Tools. You can download the IIS 6.0 Resource Kit Tools through the following URL:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=56fc92ee-a71a-4c73-b628-ade629c89499" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=56fc92ee-a71a-4c73-b628-ade629c89499"&gt;Internet Information Services (IIS) 6.0 Resource Kit Tools&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: MetaEdit should only be used on Windows NT 4.0 with IIS 4.0 or Windows 2000 with IIS 5.0. For IIS 6.0 you should only use Metabase Explorer. (And yes - you can blame me for the totally useless dialog that you get when you try to use MetaEdit with IIS 6.0. Sorry about that. &lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/regular_smile.gif" mce_src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/regular_smile.gif"&gt;)&lt;/P&gt;
&lt;H4&gt;What's all this about metabase corruption?&lt;/H4&gt;
&lt;P&gt;It was shortly after the release of IIS 4.0 that I first heard the term "Metabase Corruption" being used. People were using the term "Metabase Corruption" as a catch-all phrase for "I don't what's broken but reinstalling IIS fixed the problem so it must have been a problem with the metabase." Everyone's general opinion seemed to be that if you couldn't find the problem and you can't look at the metabase, then it must be corruption in the metabase if you can't resolve the issue without reinstalling IIS. To me, this seemed like a cop-out for good troubleshooting, and since I was a technical lead in PSS around the time that IIS 5.0 was being released I would generally refuse to accept anyone's claim when they said that they had a customer with "Metabase Corruption." Instead, I would require them to troubleshoot the problem further, and in nearly 100% of those situations the problem was &lt;B&gt;&lt;I&gt;not&lt;/I&gt;&lt;/B&gt; caused by the metabase but by some other problem that could be rectified &lt;I&gt;without&lt;/I&gt; reinstalling IIS.&lt;/P&gt;
&lt;P&gt;Here's a case in point - several years ago I worked on an issue that some of the folks that supported SharePoint Portal Server 2001 on IIS 5.0 were seeing. They first described the problem to me as "IIS was losing settings." What they were actually seeing was that they would make changes in IIS Manager and apply them, but when they would close and reopen IIS Manager they saw that all their settings were gone. They claimed that this was "Metabase Corruption," and because of this they would often make the customer reinstall IIS completely. Needless to say I made them quite angry by stating that "Metabase Corruption" is almost never actual corruption, and that they were wasting the customer's time by making them reinstall IIS. Even though reinstalling IIS made the problem go away, it didn't actually fix the problem and it only hid the actual cause at the customer's expense.&lt;/P&gt;
&lt;P&gt;Since I knew a little more than they did about how the metabase worked, I could theorize reasons why that behavior might occur and I asked them to contact me when they had a customer with this problem again. The next time they saw this problem I asked them to follow these steps:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Stop IIS by using "iisreset /stop" from a command-line&lt;/LI&gt;
&lt;LI&gt;Start just the IISADMIN service by using "net start IISADMIN" from a command-line&lt;/LI&gt;
&lt;LI&gt;Open the IIS Manager, make their changes, then close the IIS Manager&lt;/LI&gt;
&lt;LI&gt;Restart IIS by using "iisreset /restart" from a command-line&lt;/LI&gt;
&lt;LI&gt;Open IIS Manager and verify their settings&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In 100% of the cases this enabled them to work around the issue, but that was only part of the solution. I theorized that something was causing IIS to crash before the metabase changes were flushed to disk, but the Windows service recovery settings were instructing the server to restart IIS whenever it crashed so it seemed to the customer like nothing had crashed at all. With this in mind, I had them check the Windows System Log in the Event Viewer, and it listed several errors indicating that the IISADMIN service had terminated unexpectedly, which confirmed my suspicions. After some additional troubleshooting I discovered that SharePoint Portal Server 2001 was setting several illegal values in the metabase, and sooner or later that would cause IIS 5.0 to crash. (SharePoint has long since fixed that problem.)&lt;/P&gt;
&lt;H4&gt;Does metabase corruption actually happen? If so, what can I do about it?&lt;/H4&gt;
&lt;P&gt;Sadly - yes it does. It doesn't happen as often as some people seem to think that it does, but it is certainly possible. The metabase is simply a file, and file corruption can occur for any number of reasons. In the early days of IIS 5.0 on the Windows 2000 beta I discovered (quite by accident) how I could overwrite one specific value in the metabase and crash IIS so badly that IIS couldn't even be uninstalled. (Don't worry - that problem has long since been fixed.) I have also seen metabase corruption due to hardware failures, like a drive controller that is going bad and the problem is manifesting itself slowly over time.&lt;/P&gt;
&lt;P&gt;That being said, there are several methods to check if you actually have metabase corruption:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The first and easiest thing to check is - does IIS start and all of your web sites seem to work?&lt;/LI&gt;
&lt;LI&gt;Can you open up the IIS Manager and see all of your sites?&lt;/LI&gt;
&lt;LI&gt;Can you enumerate the metabase without errors using MetaEdit, Metabase Explorer, or "adsutil.vbs enum_all w3svc" from a command line?&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;If the answer to any or all of these questions is yes - then chances are good that you do not have metabase corruption, and whatever problem you have is due to misconfiguration or some other issue.&lt;/P&gt;
&lt;P&gt;The best way that I can think of to prevent metabase corruption is to avoid using a variety of tools to constantly read and write to the metabase outside of normal IIS operations. I have written scripts that perform literally thousands of metabase operations under a nominal load in a lab environment for testing purposes and never had a problem, but a server under heavy load with thousands of read/write operations per minute could theoretically run into problems if left to run like that for an indefinite length of time. But theoretically the same may be true for any file under heavy read/write load for an indefinite length of time.&lt;/P&gt;
&lt;H4&gt;Protecting against metabase corruption&lt;/H4&gt;
&lt;P&gt;The best thing that you can do to prevent against metabase corruption is &lt;B&gt;&lt;I&gt;backup the metabase regularly&lt;/I&gt;&lt;/B&gt;!!! I cannot count the number of times where having a good backup of the metabase saved me from a myriad of issues. Fortunately, there are several KB articles that describe backing up the metabase:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://support.microsoft.com/kb/300672" target=_blank mce_href="http://support.microsoft.com/kb/300672"&gt;KB 300672: How to create a metabase backup in IIS 5&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://support.microsoft.com/kb/324277" target=_blank mce_href="http://support.microsoft.com/kb/324277"&gt;KB 324277: How To Create a Metabase Backup by Using IIS 6.0 in Windows Server 2003&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://support.microsoft.com/kb/234429" target=_blank mce_href="http://support.microsoft.com/kb/234429"&gt;KB 234429: How to manually restore the metabase when no proper backup exists or when the MMC does not start&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://support.microsoft.com/kb/302888" mce_href="http://support.microsoft.com/kb/302888"&gt;KB 302888: How To Schedule Metabase Backups Using WSH&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The last KB article in the above list is based on a script that I wrote for one of my IIS 5.0 on Windows 2000 servers many years ago that I continue to use on any servers that run IIS 6.0 on Windows Server 2003.&lt;/P&gt;
&lt;H4&gt;Does IIS 7 have metabase corruption?&lt;/H4&gt;
&lt;P&gt;The quick answer to this is "no", but that answer is a little misleading since IIS 7 doesn't have a metabase!&lt;/P&gt;
&lt;P&gt;In IIS 7 we rolled out a brand new XML-based configuration store, and the bulk of your IIS settings are stored in a file named applicationHost.config, which greatly resembles the web.config configuration paradigm that was established with the .NET framework. That being said, applicationHost.config is just another file, and even though its syntax is much easier to understand and manually edit, any file can theoretically become corrupted, so you should always make sure that you backup your applicationHost.config file as well.&lt;/P&gt;
&lt;P&gt;With this in mind I wrote the following blog post some time ago where I discuss creating a script to automate backing up your IIS 7 configuration settings:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx"&gt;Automating IIS 7 Backups&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;(&lt;B&gt;Note&lt;/B&gt;: I also wrote &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/07/27/a-little-scripting-saved-my-day.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2009/07/27/a-little-scripting-saved-my-day.aspx"&gt;another blog post&lt;/A&gt; recently about how the script in that blog post saved my day when something did get corrupted on one of my servers.)&lt;/P&gt;
&lt;H4&gt;Parting thoughts&lt;/H4&gt;
&lt;P&gt;I started out this blog post by describing an image that I found on one of my computers where actual metabase corruption had occurred, so I thought that a nice way to close out this blog post would be to show you the actual image:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG src="http://y7b40a.blu.livefilestore.com/y1p8jpY-8nxRp2_6XkjOvo1sOd0SsYtpeL55cAbq3JFGWjWlalXTY9KxMYMDepiitDuHIn0fMwX9Q3VPbOxwC2oLAleYsFd8BAZ/Metabase%20Corruption.jpg" mce_src="http://y7b40a.blu.livefilestore.com/y1p8jpY-8nxRp2_6XkjOvo1sOd0SsYtpeL55cAbq3JFGWjWlalXTY9KxMYMDepiitDuHIn0fMwX9Q3VPbOxwC2oLAleYsFd8BAZ/Metabase%20Corruption.jpg"&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;It's been almost ten years now, so I don't remember the root cause anymore, but I remember what it looked like. I had a mixture of sites that were working and others that were not, and when I opened the metabase in MetaEdit I noticed that scattered throughout the metabase were hundreds of values that shouldn't be there or values that did not make sense. MetaEdit was trying its best to show all of the data, but you'll notice in the highlighted areas of the image that several of the values had bad data in them.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9880070" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category></item><item><title>A Little Scripting Saved My Day (;-])</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/07/27/a-little-scripting-saved-my-day.aspx</link><pubDate>Mon, 27 Jul 2009 21:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9850238</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9850238.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9850238</wfw:commentRss><description>&lt;P&gt;I have mentioned in previous blog posts that I tend to write many of my blog posts and walkthroughs for &lt;A href="http://www.iis.net/" target=_blank mce_href="http://www.iis.net/"&gt;IIS.NET&lt;/A&gt; based on code that I’ve written for myself, and today’s blog post is the story of how one of my samples saved my rear over this past weekend.&lt;/P&gt;
&lt;P&gt;One of the servers that I manage is used to host web sites for several friends of mine. (It’s their hobby to have a web site and it’s my hobby to host it for them.) Anyway, sometime on Sunday someone let me know that one of my sites didn’t seem to be behaving correctly, so I browsed it with Internet Explorer and saw that I was getting an HTTP 503 error. I’ve seen this error when an application pool goes offline for some reason, so I didn’t panic – yet – because I knew that the web site was in a separate application pool. With that in mind, I browsed to a web site that is in a different application pool. Same thing – HTTP 503 error. This was beginning to concern me.&lt;/P&gt;
&lt;P&gt;I logged into the web server and ran iisreset from a command-line – this threw the following error - and now I was really starting to become agitated:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="" style="COLOR: #ffffff"&gt;
&lt;P style="COLOR: #ffffff"&gt;&lt;TT&gt;CMD&amp;gt;iisreset&lt;BR&gt;&lt;BR&gt;Attempting stop...&lt;BR&gt;Internet services successfully stopped&lt;BR&gt;Attempting start...&lt;BR&gt;Restart attempt failed.&lt;BR&gt;The IIS Admin Service or the World Wide Web Publishing Service, or a service dependent on them failed to start. The service, or dependent services, may had an error during its startup or may be disabled.&lt;BR&gt;&lt;BR&gt;CMD&amp;gt;&lt;/TT&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I knew that the cause of the error should be in the Windows Event Viewer, so I opened the System log in Event Viewer and saw the following error:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="BORDER-COLLAPSE: collapse" cellSpacing=1 cellPadding=2 width="100%" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Log Name:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;System&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Source:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;Microsoft-Windows-WAS&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Date:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;7/26/2009 10:59:52 AM&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Event ID:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;5172&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Task Category:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;None&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Level:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;Error&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Keywords:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;Classic&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;User:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;N/A&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Computer:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;MYSERVER&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Description:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;The Windows Process Activation Service encountered an error trying to read configuration data from file '\\?\C:\Windows\system32\inetsrv\config\applicationHost.config', line number '308'. The error message is: 'Configuration file is not well-formed XML'. The data field contains the error number.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left colSpan=2&gt;Event Xml:&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left colSpan=2&gt;
&lt;P style="COLOR: black; BACKGROUND-COLOR: #ffffff"&gt;&lt;TT&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Event&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="http://schemas.microsoft.com/win/2004/08/events/event"&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;System&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Provider&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Microsoft-Windows-WAS"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt; Guid&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="{4E616D65-6F6E-6D65-6973-526F62657274}"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt; EventSourceName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="WAS"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventID&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Qualifiers&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="49152"&amp;gt;&lt;/SPAN&gt;5172&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Version&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Version&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Level&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;2&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Level&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Opcode&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Opcode&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Keywords&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0x80000000000000&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Keywords&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;TimeCreated&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;SystemTime&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="2009-07-26T17:59:52.000Z"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventRecordID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;32807&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventRecordID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Correlation&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Execution&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;ProcessID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="0"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;ThreadID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="0"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Channel&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;System&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Channel&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Computer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;MYSERVER&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Computer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Security&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;System&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventData&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="File"&amp;gt;&lt;/SPAN&gt;\\?\C:\Windows\system32\inetsrv\config\applicationHost.config&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="LineNumber"&amp;gt;&lt;/SPAN&gt;308&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Error"&amp;gt;&lt;/SPAN&gt;Configuration file is not well-formed XML&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Binary&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0D000780&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Binary&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventData&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Event&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/TT&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now that I was armed with the file name and line number of the failure in my configuration settings, I was able to go straight to the source of the problem. (I love IIS 7's descriptive error messages - don't you?) Once I opened the file and jumped to the correct location, I saw several lines of unintelligible garbage. For reasons that are still unknown to me – my applicationHost.config file had become corrupted and IIS was dead in the water until I fixed the problem. I looked through the file and removed most of the garbage and saved the edited file&amp;nbsp;to IIS – this got the web sites working, but only partially. Some necessary settings had obviously been removed while I was clearing all of out the unintelligible garbage, and it might take me a long time to discover what those settings were.&lt;/P&gt;
&lt;P&gt;The next thing that I did was to take a look in my two readily-accessible backup drives; I have two external hard drives that keep a backup of the web server - one hard drive is directly plugged into the web server via a USB cable, and the other hard drive is plugged into a physically separate server that rotates drives with off-site storage on a monthly basis. The problem is, my weekly backups had just run, so the copy in each backup location had been overwritten with the corrupted version. (I’m going to have to rethink my backup strategy after this – but that’s another story.) The backup copy in my off-site storage location should be intact, but that copy would be a few weeks old so I would be missing some settings, and I would have to drive an hour or so round-trip in order to pick up the drive. This wasn’t an ideal solution – but it was definitely a feasible strategy.&lt;/P&gt;
&lt;P&gt;It was at this point that I remembered that I had written following blog post some time ago:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Automating IIS 7 Backups&lt;/STRONG&gt; &lt;BR&gt;&lt;A title=http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx href="http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx"&gt;http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I wrote the script in that blog post for the server that I was currently managing, and because of this preventative measure I had dozens of backups going back several weeks to choose from. So I was able to quickly find a copy with no corruption and I restored that copy to my IIS config directory. At this point all of my web sites came online with all of their functionality. Having fixed the major issues, I used WinDiff to verify any settings that might have been changed between the restored copy and the corrupted copy.&lt;/P&gt;
&lt;P&gt;So in conclusion, this story had a happy ending, and it left me with a few lessons learned:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;You can never have too many backups &lt;/LI&gt;
&lt;LI&gt;I need to rethink how I roll out my backup strategy with regard to using external hard drives &lt;/LI&gt;
&lt;LI&gt;Writing cool scripts to automate your backups can save your rear end &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;That sums it up for today’s post. ;-]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9850238" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Using Apple's WebDavFS for Mac OS X with WebDAV on IIS 7</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/07/01/using-apple-s-webdavfs-for-mac-os-x-with-webdav-on-iis-7.aspx</link><pubDate>Thu, 02 Jul 2009 05:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9812594</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9812594.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9812594</wfw:commentRss><description>&lt;P&gt;Today's blog post needs to have a disclaimer right up front - I freely admit I'm not a Mac OS X expert, so I may not have everything 100% correct in this post. But I've seen a lot of questions on &lt;A href="http://forums.iis.net/" target=_blank&gt;forums.iis.net&lt;/A&gt; that discuss using IIS WebDAV with Mac OS X, so I thought that I'd share a few of the things that I've noticed. Just the same, if I were writing a formal walkthrough I would have said something like, "&lt;I&gt;Microsoft is not responsible for the behavior of Apple's Mac family of products. The information that is provided in this topic is provided to assist Mac OS X users that are connecting to IIS using WebDAV.&lt;/I&gt;" &lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;&lt;/P&gt;
&lt;P&gt;All that being said, here are the prerequisites for getting your environment together:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Your server needs to be running Windows Vista, Windows Server 2008, or Windows 7.&lt;/LI&gt;
&lt;LI&gt;Your server needs to have Internet Information Services 7 and the WebDAV module installed. (&lt;B&gt;Note&lt;/B&gt;: See the &lt;A href="http://go.microsoft.com/fwlink/?LinkId=105146" target=_blank mce_href="http://go.microsoft.com/fwlink/?LinkId=105146"&gt;Installing and Configuring WebDAV on IIS 7.0&lt;/A&gt; topic for more information.)&lt;/LI&gt;
&lt;LI&gt;For best results, your Mac client needs to be running OS X version 10.4 or later.&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Connecting to a WebDAV server using Mac OS X&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;In Mac OS X, open &lt;B&gt;Finder&lt;/B&gt;.&lt;/LI&gt;
&lt;LI&gt;Choose &lt;B&gt;Go&lt;/B&gt;, then &lt;B&gt;Connect To Server&lt;/B&gt;.&lt;/LI&gt;
&lt;LI&gt;Enter the URL of the WebDAV server in &lt;B&gt;Server Address&lt;/B&gt;. For example: 
&lt;BLOCKQUOTE&gt;&lt;I&gt;http://www.example.com/path/&lt;/I&gt;&lt;/BLOCKQUOTE&gt;&lt;/LI&gt;
&lt;LI&gt;Click &lt;B&gt;Connect&lt;/B&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;For more information, please see the following help topics that are available on Apple's Web site:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://docs.info.apple.com/article.html?path=Mac/10.4/en/mh1050.html" target=_blank&gt;Mac OS X 10.4 Help: Connecting to a WebDAV server&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://docs.info.apple.com/article.html?path=Mac/10.5/en/8160.html" target=_blank&gt;Mac OS X 10.5 Help: Connecting to a WebDAV server&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Troubleshooting WebDAV connections using Mac OS X&lt;/H3&gt;
&lt;P&gt;These are some of the issues that I've seen:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;WebDavFS connections are read-only if WebDAV LOCKs are disabled on the server. Because of this: 
&lt;UL&gt;
&lt;LI&gt;If you are using WebDAV 7.0 on IIS 7 you will not be able write files to the server; this is because WebDAV locks were not available in this release.&lt;/LI&gt;
&lt;LI&gt;If you are using WebDAV 7.5 on IIS 7 you will need to enable locks before you can write files to the server; this is because WebDAV locks are disabled by default. (&lt;B&gt;Note&lt;/B&gt;: See the &lt;A href="http://learn.iis.net/page.aspx/596/how-to-use-webdav-locks/" target=_blank&gt;How to Use WebDAV Locks&lt;/A&gt; topic for more information.)&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;WebDavFS connections attempt to create files that may be blocked by IIS: 
&lt;UL&gt;
&lt;LI&gt;"&lt;I&gt;Desktop Services Store&lt;/I&gt;" (.DS_Store) files. (See &lt;A href="http://en.wikipedia.org/wiki/.DS_Store" target=_blank&gt;http://en.wikipedia.org/wiki/.DS_Store&lt;/A&gt; for a description.)&lt;/LI&gt;
&lt;LI&gt;"&lt;I&gt;Resource Fork&lt;/I&gt;" (e.g. "._filename.ext") files. (See &lt;A href="http://en.wikipedia.org/wiki/Resource_fork" target=_blank&gt;http://en.wikipedia.org/wiki/Resource_fork&lt;/A&gt; for a description.)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Allowing unknown MIME types for WebDAV requests should allow these file types, and that setting is located under &lt;B&gt;Web Settings&lt;/B&gt; action for the &lt;B&gt;WebDAV Authoring Rules&lt;/B&gt; feature of IIS Manager.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://bxtqig.blu.livefilestore.com/y1pPrNDkYWHbqzLrclDaaMqC1dlPhS2et-S5L2CPeoBoX77rY2LXMY8Royxui0oJtJddhYcPIW6nxii6ACKKG_EtA/Allow%20Unknown%20MIME%20Types.jpg"&gt;&lt;/P&gt;
&lt;P&gt;For more information, see the following topics that are available on Apple's Web site:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://support.apple.com/kb/HT1629" target=_blank&gt;Mac OS X 10.4: How to prevent .DS_Store file creation over network connections&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://support.apple.com/kb/TA24245" target=_blank&gt;Mac OS X 10.4: Windows Server 2003 IIS Web Server fails GET call on .DS_Store and ._ files&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;In Closing...&lt;/H4&gt;
&lt;P&gt;I have to reiterate that I'm not a Mac OS X expert, so this list is probably not all-inclusive, but it's helped to resolve some of the issues that I've seen.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9812594" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/WebDAV/default.aspx">WebDAV</category></item><item><title>FTP Clients - Part 6: Core FTP LE</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/05/01/ftp-clients-part-6-core-ftp-le.aspx</link><pubDate>Sat, 02 May 2009 02:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9583119</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9583119.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9583119</wfw:commentRss><description>&lt;P&gt;For this installment in my series about FTP Clients, I'd like to take a look at the Core FTP client. For this blog post I used Core FTP Lite Edition (LE) version 1.3c (build 1447) and version 2.1 (build 1603), although all of my screen shots are from version 2.1. Core FTP is available from the following URL:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.coreftp.com/"&gt;http://www.coreftp.com/&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;At the time of this blog post, Core FTP provides the LE for free and charges a small fee for a professional version.&lt;/P&gt;
&lt;P&gt;Like most graphical FTP clients, the Core FTP LE user interface is pretty easy to use and rather straight-forward - you have separate windows for your local and remote files/folders, as well as a logging window that lists the FTP commands that are sent and the FTP server's responses:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1p2oc7h-AOjpqzlSt1vktdR94GTRDsAW6Rsn5qr_KB3PiZ6Q5vUZs6HF4k-0cu4sxGO_vKbJAgqd1iVO06mAD_9me3Oji5bAZt/CoreFtp1.jpg" target=_blank&gt;&lt;IMG height=450 src="http://yy3flw.blu.livefilestore.com/y1p2oc7h-AOjpqzlSt1vktdR94GTRDsAW6RaK-UHQqTUNxQo4FQRGtRc9cGSSg0QRquMKy_5OXuNrERrfOQ_eaD0Uko5Q6McK-P/CoreFtp1.jpg" width=600 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Core FTP LE has a great Site Manager feature, which allows you to store commonly-used connections to FTP sites:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1pq2PaChNVilw0Jz5PYR1rVWF2k1DFxqLRlAKrsQmXqJilox5eGyeuW0ihixQAzXTGNGWYh45ZGnHdAuPp4Tb7AQ/CoreFtp2.jpg" target=_blank&gt;&lt;IMG height=450 src="http://yy3flw.blu.livefilestore.com/y1pq2PaChNVilw0Jz5PYR1rVeBMAtm_0LLHWQArcz_XQwQfcaF9aOynPbZMsr69A7vjN0zWjerkexHAOT9zvpYWXg/CoreFtp2.jpg" width=477 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Clicking on the &lt;B&gt;Advanced&lt;/B&gt; button gives you a great deal of additional configuration settings, and I'll say more about that later:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1pPv2A5QUnG1_QvuDOPwhf-sbkEtAlWkLNNBJO6kSys4bvwxOxg1_xRYhhiN8cSPkKWVEH5xp6WFZa8b_cL_jmNg/CoreFtp3.jpg" target=_blank&gt;&lt;IMG height=406 src="http://yy3flw.blu.livefilestore.com/y1pPv2A5QUnG1_QvuDOPwhf-kYLxppBGQ8bpcs4KjenUFEar9LftdcgP31fGhlUbgWsd2LI__0Olk6bS43pt9MNCA/CoreFtp3.jpg" width=548 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H4&gt;Command-Line Support&lt;/H4&gt;
&lt;P&gt;This is one of my favorite Core FTP LE features: &lt;I&gt;command-line support&lt;/I&gt;. Yes - I'm a geek - and I like being able to script things and run batch jobs to automate whatever I can, so command-line support is always a plus for me. That said, the interface for the Core FTP LE command-line client is not an interactive experience like you get with the built-in Windows FTP.EXE or &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/01/06/ftp-clients-part-5-moveit-freely-command-line-secure-ftp-client.aspx" target=_blank&gt;MOVEit Freely&lt;/A&gt; command-line clients. The Core FTP LE command-line client is provided as via the Corecmd.exe file that is installed in the main the Core FTP LE application directory, and is used for a single FTP operation like GET or PUT - although you can pass the name of a script file to execute several commands before/after logging in or before/after a file transfer.&lt;/P&gt;
&lt;P&gt;So my final judgment is that the Core FTP LE client doesn't have great command-line support, but it's still really nice to have.&lt;/P&gt;
&lt;H3&gt;Using FTP over SSL (FTPS)&lt;/H3&gt;
&lt;P&gt;The Core FTP LE client supports both &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2008/11/10/ftp-clients-part-2-explicit-ftps-versus-implicit-ftps.aspx" target=_blank&gt;Implicit and Explicit FTPS&lt;/A&gt;, so the choice is up to you which method to use. When creating a connection to a server, Core FTP LE has three FTP options that you can use with FTP7:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;AUTH SSL&lt;/LI&gt;
&lt;LI&gt;AUTH TLS&lt;/LI&gt;
&lt;LI&gt;FTPS (SSL DIRECT)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;It's important to choose this option correctly, otherwise you will run into problems when trying access a site using FTPS. If you'll recall from my "&lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2008/11/10/ftp-clients-part-2-explicit-ftps-versus-implicit-ftps.aspx" target=_blank&gt;FTP Clients - Part 2: Explicit FTPS versus Implicit FTPS&lt;/A&gt;" and my other FTP client blog posts, Explicit FTPS allows the client to initiate SSL/TLS whenever it wants, but for most FTP clients that will be when logging in to your FTP site, and in that regard it may almost seem like Implicit FTPS, but behind the scenes the FTP client and server are communicating differently.&lt;/P&gt;
&lt;P&gt;In the case of FTP7, the following rules apply:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If you enable FTPS in FTP7 and you assign the FTP site to port 990, you are using &lt;B&gt;Implicit FTPS&lt;/B&gt; - Core FTP LE refers to this as &lt;B&gt;FTPS (SSL DIRECT)&lt;/B&gt;. (&lt;B&gt;Note&lt;/B&gt;: make sure that you configure your FTP client to connect on port 990.)&lt;/LI&gt;
&lt;LI&gt;If you enable FTPS in FTP7 and you assign the FTP site to any port other than port 990, you are using &lt;B&gt;Explicit FTPS&lt;/B&gt; - Core FTP LE allows you to configure your connection to use &lt;B&gt;AUTH SSL&lt;/B&gt; or &lt;B&gt;AUTH TLS&lt;/B&gt; for the explicit connection.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The type of FTPS is specified on the &lt;B&gt;Connection&lt;/B&gt; drop-down menu:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1pUvSuPf1uY9MJ8RPaS6U1W2QYsG27D0CbzTqW3QX6jbeYxA65nhAl747sox7p-4ox5tBO8ibEszKuPOjGXi_3bQ/CoreFtp4.jpg" target=_blank&gt;&lt;IMG height=450 src="http://yy3flw.blu.livefilestore.com/y1pUvSuPf1uY9MJ8RPaS6U1W09ILkzYYQ8Rs5TfmRZqgBvKzbh_gyjolTvIEHHOymmitGxOilImoYRzXpbNrBm3ww/CoreFtp4.jpg" width=477 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Once you have chosen an FTPS connection, the Core FTP LE client offers you additional options where you can customize which parts of the session will be encrypted:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1pAhNYDZTTgG8K15iSBkTQyp911vG01D5LvxSdbCdu2Zw25Im5-DWAFJ4EYiymHYrFp4BlrhVadAS0_M_uMATvSg/CoreFtp5.jpg" target=_blank&gt;&lt;IMG height=450 src="http://yy3flw.blu.livefilestore.com/y1pAhNYDZTTgG8K15iSBkTQyrGMAiOyvcydU-q_Z2cncnRYROF9VZFFyfR7SzXoiIIjs0Wq-tS4SugYkS6tdnEjvA/CoreFtp5.jpg" width=477 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;You can combine the Core FTP SSL options with the advanced SSL policies for your FTP7 sites to customize your security level:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1p4fBz3NYQ9ZfH5EgsjrFj8Y4hifzio778a9VYJfgFsTki-Bu53pLj-szre0yeec7RAuN6ASxmNIw3_vigaakrdg/CoreFtp6.jpg" target=_blank&gt;&lt;IMG height=360 src="http://yy3flw.blu.livefilestore.com/y1p4fBz3NYQ9ZfH5EgsjrFj8eaVXCOL3_wXo4o7ik3JjafNTfBUTkUmaMD6uzGrAHkPFUihfeTCYguCvyFLieanUQ/CoreFtp6.jpg" width=600 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H3&gt;Using FTP Virtual Hosts&lt;/H3&gt;
&lt;P&gt;Because Core FTP LE's site manager allows you to specify the virtual host name as part of the user credentials, Core FTP LE works great with FTP7's virtual host names. All that you need to do is use the "ftp.example.com|username" syntax when specifying your username, and when you connect to the FTP7 server it will route your requests to the correct FTP virtual host site.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1pSmbFAU_qjHH-5_6usShQZuUoAlHEml39LuGDeFcfpzHQVkwCgmVCmeOAaU9C569wYf1sCLwd8lc1ifS4oBBxDA/CoreFtp7.jpg" target=_blank&gt;&lt;IMG height=450 src="http://yy3flw.blu.livefilestore.com/y1p-tl22lkzVwbPUwLLUHrBrUbw8ZYv8u9LIdlZ05nA34NIN43H-5EqnhYhKoCwCX_TNRzUAs6w4PAlzyQR2X-P0w/CoreFtp7.jpg" width=477 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H3&gt;Using True FTP Hosts&lt;/H3&gt;
&lt;P&gt;A really great feature of Core FTP LE is the ability to send pre-login commands, and since this feature allows you to enter custom commands you can specify the actual FTP HOST command as part of your login:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://yy3flw.blu.livefilestore.com/y1pgEnNmRPYRbGCD1pc5bs8G3gArhk8uhHHW23L0dFGseCxnPSLOHu39PBKSvgxXmT4sheZGIcPq4wU9tcJ_atFuA/CoreFtp8.jpg" target=_blank&gt;&lt;IMG height=406 src="http://yy3flw.blu.livefilestore.com/y1pgEnNmRPYRbGCD1pc5bs8G9TB5x7v5ORRPmg1A-kcRnDQycwKhcflCWyaF6uuo7Ger0mFRzLWNldPHQBTw36G6w/CoreFtp8.jpg" width=548 border=2&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;This is a tremendous feature if you're hosting multiple FTP sites on the same IP address, and gives Core FTP LE some of the best support for true FTP HOSTs.&lt;/P&gt;
&lt;H3&gt;Scorecard for Core FTP LE&lt;/H3&gt;
&lt;P&gt;That wraps it up for our quick round-trip for some of Core FTP LE's features, and here's the scorecard results:&lt;/P&gt;
&lt;TABLE class="" width=500 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="" noWrap&gt;Client Name&lt;/TH&gt;
&lt;TH class="" noWrap width=75&gt;Directory&lt;BR&gt;Browsing&lt;/TH&gt;
&lt;TH class="" noWrap width=75&gt;&lt;A href="http://go.microsoft.com/fwlink/?LinkId=89117" mce_href="http://go.microsoft.com/fwlink/?LinkId=89117"&gt;Explicit&lt;BR&gt;FTPS&lt;/A&gt;&lt;/TH&gt;
&lt;TH class="" noWrap width=75&gt;&lt;A href="http://go.microsoft.com/fwlink/?LinkId=89117" mce_href="http://go.microsoft.com/fwlink/?LinkId=89117"&gt;Implicit&lt;BR&gt;FTPS&lt;/A&gt;&lt;/TH&gt;
&lt;TH class="" noWrap width=75&gt;&lt;A href="http://go.microsoft.com/fwlink/?LinkId=89119" mce_href="http://go.microsoft.com/fwlink/?LinkId=89119"&gt;Virtual&lt;BR&gt;Hosts&lt;/A&gt;&lt;/TH&gt;
&lt;TH class="" noWrap width=75&gt;&lt;A href="http://go.microsoft.com/fwlink/?LinkId=89119" mce_href="http://go.microsoft.com/fwlink/?LinkId=89119"&gt;True&lt;BR&gt;HOSTs&lt;/A&gt;&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;Core FTP LE 1.3&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Rich&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y &lt;SUP&gt;1&lt;/SUP&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;Core FTP LE 2.1&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Rich&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;Y &lt;SUP&gt;1&lt;/SUP&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left colSpan=6&gt;&lt;SUP&gt;1&lt;/SUP&gt; As noted earlier, true FTP HOSTs are available in Site Manager using pre-login commands.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: Keeping with my standard disclaimer, there are a great number of additional features that Core FTP LE provides - and I just focused on the topic areas that apply to FTP7.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9583119" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category></item><item><title>BLOG - FTP 7.5 Service Extensibility References</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/04/23/blog-ftp-7-5-service-extensibility-references.aspx</link><pubDate>Fri, 24 Apr 2009 03:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9565757</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9565757.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9565757</wfw:commentRss><description>&lt;P&gt;As I pointed out in my recent blog post that was titled "&lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/03/18/ftp-7-5-and-webdav-7-5-have-been-released.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2009/03/18/ftp-7-5-and-webdav-7-5-have-been-released.aspx"&gt;FTP 7.5 and WebDAV 7.5 have been released&lt;/A&gt;", one of the great new features of the FTP 7.5 service is extensibility. In that blog post I mentioned that I wrote the following walkthroughs to help developers get started writing providers for the FTP 7.5 service, and these walkthroughs are all available on Microsoft's &lt;A href="http://learn.iis.net/" target=_blank mce_href="http://learn.iis.net/"&gt;learn.iis.net&lt;/A&gt; Web site:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;For Managed Code Developers: 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://learn.iis.net/page.aspx/598/how-to-use-managed-code-to-create-a-simple-ftp-authentication-provider/" target=_blank mce_href="http://learn.iis.net/page.aspx/598/how-to-use-managed-code-to-create-a-simple-ftp-authentication-provider/"&gt;How to Use Managed Code to Create a Simple FTP Authentication Provider&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://learn.iis.net/page.aspx/600/how-to-use-managed-code-to-create-a-simple-ftp-home-directory-provider/" target=_blank mce_href="http://learn.iis.net/page.aspx/600/how-to-use-managed-code-to-create-a-simple-ftp-home-directory-provider/"&gt;How to Use Managed Code to Create a Simple FTP Home Directory Provider&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://learn.iis.net/page.aspx/602/how-to-use-managed-code-to-create-a-simple-ftp-logging-provider/" target=_blank mce_href="http://learn.iis.net/page.aspx/602/how-to-use-managed-code-to-create-a-simple-ftp-logging-provider/"&gt;How to Use Managed Code to Create a Simple FTP Logging Provider&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;For Native Code Developers: 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://learn.iis.net/page.aspx/599/how-to-use-native-code-to-create-a-simple-ftp-authentication-provider/" target=_blank mce_href="http://learn.iis.net/page.aspx/599/how-to-use-native-code-to-create-a-simple-ftp-authentication-provider/"&gt;How to Use Native Code to Create a Simple FTP Authentication Provider&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://learn.iis.net/page.aspx/601/how-to-use-native-code-to-create-a-simple-ftp-home-directory-provider/" target=_blank mce_href="http://learn.iis.net/page.aspx/601/how-to-use-native-code-to-create-a-simple-ftp-home-directory-provider/"&gt;How to Use Native Code to Create a Simple FTP Home Directory Provider&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://learn.iis.net/page.aspx/603/how-to-use-native-code-to-create-a-simple-ftp-logging-provider/" target=_blank mce_href="http://learn.iis.net/page.aspx/603/how-to-use-native-code-to-create-a-simple-ftp-logging-provider/"&gt;How to Use Native Code to Create a Simple FTP Logging Provider&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;We have also recently published the &lt;A href="http://msdn.microsoft.com/en-us/library/dd723667.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd723667.aspx"&gt;FTP Service Extensibility Reference&lt;/A&gt; on Microsoft's MSDN Web site, and here is a list of all the reference topics that we have written for FTP 7.5 service extensibility:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692905.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692905.aspx"&gt;FTP Managed-Code Extensibility API Reference&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692904.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692904.aspx"&gt;FTP Managed-Code Extensibility Interfaces&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692892.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692892.aspx"&gt;IFtpAuthenticationProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692879.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692879.aspx"&gt;IFtpAuthenticationProvider.AuthenticateUser Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692902.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692902.aspx"&gt;IFtpAuthenticationProvider.Initialize Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692893.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692893.aspx"&gt;IFtpHomeDirectoryProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692881.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692881.aspx"&gt;IFtpHomeDirectoryProvider.GetUserHomeDirectoryData Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692886.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692886.aspx"&gt;IFtpHomeDirectoryProvider.Initialize Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692885.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692885.aspx"&gt;IFtpLogProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692894.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692894.aspx"&gt;IFtpLogProvider.Log Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692887.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692887.aspx"&gt;IFtpLogProvider.Initialize Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692895.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692895.aspx"&gt;IFtpRoleProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692899.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692899.aspx"&gt;IFtpRoleProvider.IsUserInRole Method&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692875.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692875.aspx"&gt;IFtpRoleProvider.Initialize Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692896.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692896.aspx"&gt;FTP Managed-Code Extensibility Structures&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692903.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692903.aspx"&gt;FtpLogEntry Class&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692882.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692882.aspx"&gt;FTP Native-Code Extensibility API Reference&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692898.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692898.aspx"&gt;FTP Native-Code Extensibility Interfaces&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692889.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692889.aspx"&gt;IFtpAuthenticationProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692897.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692897.aspx"&gt;IFtpAuthenticationProvider::AuthenticateUser Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692900.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692900.aspx"&gt;IFtpHomeDirectoryProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692880.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692880.aspx"&gt;IFtpHomeDirectoryProvider::GetUserHomeDirectoryData Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692877.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692877.aspx"&gt;IFtpLogProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692876.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692876.aspx"&gt;IFtpLogProvider::Log Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692908.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692908.aspx"&gt;IFtpProviderConstruct Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692891.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692891.aspx"&gt;IFtpProviderConstruct::Construct Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692883.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692883.aspx"&gt;IFtpRoleProvider Interface&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692907.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692907.aspx"&gt;IFtpRoleProvider::IsUserInRole Method&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692901.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692901.aspx"&gt;FTP Native-Code Extensibility Structures&lt;/A&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd692906.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd692906.aspx"&gt;LOGGING_PARAMETERS Structure&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I hope this helps!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9565757" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category></item><item><title>Creating a Read-Only Membership Provider for phpBB 2.0 Users</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/04/20/creating-a-read-only-membership-provider-for-phpbb-2-0-users.aspx</link><pubDate>Tue, 21 Apr 2009 02:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9557707</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9557707.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9557707</wfw:commentRss><description>&lt;P&gt;I recently posted a blog that was titled &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/02/16/creating-a-read-only-snitz-membership-provider.aspx" target=_blank&gt;Creating a Read-Only Snitz Membership Provider&lt;/A&gt;, where I re-used the code from my &lt;A href="http://learn.iis.net/page.aspx/528/how-to-use-the-sample-read-only-xml-membership-and-role-providers-with-iis-70/" target=_blank&gt;How to use the Sample Read-Only XML Membership and Role Providers with IIS 7.0&lt;/A&gt; walkthrough on the &lt;A href="http://learn.iis.net/"&gt;learn.iis.net&lt;/A&gt; web site to write a membership provider for web sites that use the &lt;A href="http://forum.snitz.com/" target=_blank&gt;Snitz Forums&lt;/A&gt; application. After I finished writing that blog post, I started thinking about the web sites where I use the &lt;A href="http://www.phpbb.com/" target=_blank&gt;phpBB 2.0&lt;/A&gt; application, which leads us to today's blog post. &lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;&lt;/P&gt;
&lt;P&gt;Following in the footsteps of my Snitz blog and XML walkthrough, today's blog post will show how to set up a simple, read-only provider for phpBB 2.0, although for this blog I tested a web site that was specifically using the phpBB 2.0.22 version. (Before anyone sends me email about it - I know that phpBB 3.0 is has been released and it's way cooler, but I still have web sites that are running the 2.0 phpBB forums.)&lt;/P&gt;
&lt;P&gt;As I did with the Snitz provider, I chose to create a single namespace ("ReadOnlyPhpBBProvider") that contained two classes: one for the membership provider ("PhpBBMembershipProvider") and the other for the role provider ("PhpBBRoleProvider"); and once again I added an additional class ("PhpBBUtils") with a couple of helper methods.&lt;/P&gt;
&lt;P&gt;Here are some of the additional implementation details:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Unlike the Snitz forums, the phpBB forums have groups, so I used those for my roles implementation.&lt;/LI&gt;
&lt;LI&gt;My SQL queries are hard-coded to use the default "phpbb_" prefix; this could easily be modified.&lt;/LI&gt;
&lt;LI&gt;I use the "user_regdate" and "user_session_time" fields in the "phpp_users" table to populate the membership CreationDate, LastLoginDate, and LastActivityDate values. It would be possible to retrieve the last post for a user from the phpbb_posts table and compute the LastActivityDate, but I'm not really using that value so I chose to avoid the hassle.&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Step 1: Creating the Project&lt;/H3&gt;
&lt;P&gt;In this section you will create a project in Visual Studio for the membership/role provider.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Open Microsoft Visual Studio 2008. &lt;/LI&gt;
&lt;LI&gt;Click the &lt;B&gt;File&lt;/B&gt; menu, then &lt;STRONG&gt;New&lt;/STRONG&gt;, then &lt;STRONG&gt;Project&lt;/STRONG&gt;. &lt;/LI&gt;
&lt;LI&gt;In the &lt;B&gt;New Project&lt;/B&gt; dialog: 
&lt;UL&gt;
&lt;LI&gt;Choose &lt;B&gt;Visual C#&lt;/B&gt; as the project type. &lt;/LI&gt;
&lt;LI&gt;Choose &lt;B&gt;Class Library&lt;/B&gt; as the template. &lt;/LI&gt;
&lt;LI&gt;Type &lt;B&gt;ReadOnlyPhpBBProvider&lt;/B&gt; as the name of the project. &lt;/LI&gt;
&lt;LI&gt;Uncheck the &lt;B&gt;Create directory for solution&lt;/B&gt; box. &lt;/LI&gt;
&lt;LI&gt;Click &lt;B&gt;OK&lt;/B&gt;.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Add a reference path to the System.Configuration library: 
&lt;UL&gt;
&lt;LI&gt;In the solution explorer, right-click the &lt;B&gt;ReadOnlyPhpBBProvider&lt;/B&gt; project, then &lt;B&gt;Add Reference...&lt;/B&gt; &lt;/LI&gt;
&lt;LI&gt;Click the .NET tab. &lt;/LI&gt;
&lt;LI&gt;Select "System.Configuration" in the list of assemblies. &lt;/LI&gt;
&lt;LI&gt;Click &lt;B&gt;OK&lt;/B&gt;.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Add a reference path to the System.Web library: 
&lt;UL&gt;
&lt;LI&gt;In the solution explorer, right-click the &lt;B&gt;ReadOnlyPhpBBProvider&lt;/B&gt; project, then &lt;B&gt;Add Reference...&lt;/B&gt; &lt;/LI&gt;
&lt;LI&gt;Click the .NET tab. &lt;/LI&gt;
&lt;LI&gt;Select "System.Web" in the list of assemblies. &lt;/LI&gt;
&lt;LI&gt;Click &lt;B&gt;OK&lt;/B&gt;.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Add a strong name key to the project: 
&lt;UL&gt;
&lt;LI&gt;In the solution explorer, right-click the &lt;B&gt;ReadOnlyPhpBBProvider&lt;/B&gt; project, then&lt;B&gt; Properties&lt;/B&gt;. &lt;/LI&gt;
&lt;LI&gt;Click the &lt;B&gt;Signing&lt;/B&gt; tab. &lt;/LI&gt;
&lt;LI&gt;Check the &lt;B&gt;Sign the assembly&lt;/B&gt; check box. &lt;/LI&gt;
&lt;LI&gt;Choose &lt;B&gt;&amp;lt;New...&amp;gt;&lt;/B&gt; from the strong key name drop-down box. &lt;/LI&gt;
&lt;LI&gt;Enter &lt;B&gt;ReadOnlyPhpBBProviderKey&lt;/B&gt; for the key file name. &lt;/LI&gt;
&lt;LI&gt;If desired, enter a password for the key file; otherwise, uncheck the &lt;B&gt;Protect my key file with a password&lt;/B&gt; box. &lt;/LI&gt;
&lt;LI&gt;Click &lt;B&gt;OK&lt;/B&gt;.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;(Optional) Add a custom build event to automatically register the DLL in the GAC: 
&lt;UL&gt;
&lt;LI&gt;In the solution explorer, right-click the &lt;B&gt;ReadOnlyPhpBBProvider&lt;/B&gt; project, then&lt;B&gt; Properties&lt;/B&gt;. &lt;/LI&gt;
&lt;LI&gt;Click the &lt;B&gt;Build Events&lt;/B&gt; tab. &lt;/LI&gt;
&lt;LI&gt;Enter the following in the &lt;B&gt;Post-build event command line&lt;/B&gt; box:&lt;BR&gt;&lt;KBD&gt;call "%VS90COMNTOOLS%\vsvars32.bat"&amp;gt;null&lt;BR&gt;gacutil.exe /if "$(TargetPath)"&lt;/KBD&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Save the solution.&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Step 2: Add the provider classes for the project&lt;/H3&gt;
&lt;P&gt;In this second step you will create the classes for the membership and role providers. Once again, the code for these classes is largely based on the &lt;A href="http://msdn.microsoft.com/en-us/library/aa479031.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/aa479031.aspx"&gt;Membership Providers&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/library/aa479032.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/aa479032.aspx"&gt;Role Providers&lt;/A&gt; topics on MSDN.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Open the &lt;B&gt;Class1.cs&lt;/B&gt; file if it is not already open.&lt;/LI&gt;
&lt;LI&gt;Remove all of the existing code from the class.&lt;/LI&gt;
&lt;LI&gt;Paste the following sample code into the editor: &lt;PRE&gt;&lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;// ReadOnlyPhpBBProvider&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;// A read-only membership and role provider for phpBB forums.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;

&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Collections;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Collections.Generic;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Collections.Specialized;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Configuration;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Configuration.Provider;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Data.Odbc;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Linq;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Security.Cryptography;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Text;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Web.Security;

&lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; ReadOnlyPhpBBProvider
{
  &lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;// PhpBBMembershipProvider&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;

  &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; PhpBBMembershipProvider : MembershipProvider
  {
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; Dictionary&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, MembershipUser&amp;gt; _Users;
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; _connectionStringName;
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; _connectionString;
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; PhpBBUtils _phpbbUtils;

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;// MembershipProvider Properties&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; ApplicationName
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
      set { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; EnablePasswordRetrieval
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;; }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; EnablePasswordReset
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;; }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; MaxInvalidPasswordAttempts
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; MinRequiredNonAlphanumericCharacters
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; MinRequiredPasswordLength
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; PasswordAttemptWindow
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; MembershipPasswordFormat PasswordFormat
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; PasswordStrengthRegularExpression
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; RequiresQuestionAndAnswer
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; RequiresUniqueEmail
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;// MembershipProvider Methods&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; Initialize(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; name, NameValueCollection config)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (config == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentNullException(&lt;SPAN style="COLOR: #800000"&gt;"config"&lt;/SPAN&gt;);
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(name))
        name = &lt;SPAN style="COLOR: #800000"&gt;"ReadOnlyPhpBBMembershipProvider"&lt;/SPAN&gt;;
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(config[&lt;SPAN style="COLOR: #800000"&gt;"description"&lt;/SPAN&gt;]))
      {
        config.Remove(&lt;SPAN style="COLOR: #800000"&gt;"description"&lt;/SPAN&gt;);
        config.Add(&lt;SPAN style="COLOR: #800000"&gt;"description"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #800000"&gt;"Read-only phpBB membership provider"&lt;/SPAN&gt;);
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;base&lt;/SPAN&gt;.Initialize(name, config);
      _connectionStringName = config[&lt;SPAN style="COLOR: #800000"&gt;"connectionStringName"&lt;/SPAN&gt;];
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(_connectionStringName))
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"No connection string was specified.\n"&lt;/SPAN&gt;);
      }
      _connectionString = ConfigurationManager.ConnectionStrings[
        _connectionStringName].ConnectionString;
      _phpbbUtils = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; PhpBBUtils();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; ValidateUser(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; password)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(username) ||
        String.IsNullOrEmpty(password))
        &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
      &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
      {
        ReadMembershipDataStore();
        MembershipUser user;
        &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (_Users.TryGetValue(username, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; user))
        {
          &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; ((user.Comment == _phpbbUtils.PasswordHash(password))
            &amp;amp;&amp;amp; (user.IsLockedOut == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)
            &amp;amp;&amp;amp; (user.IsApproved == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;))
          {
            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;;
          }
        }
        &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception)
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
      }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; MembershipUser GetUser(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; userIsOnline)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(username)) &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;;
      ReadMembershipDataStore();
      &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
      {
        MembershipUser user;
        &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (_Users.TryGetValue(username, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; user)) &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; user;
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception ex)
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Error: "&lt;/SPAN&gt; + ex.Message);
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;;
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; MembershipUserCollection GetAllUsers(
      &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; pageIndex, &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; pageSize, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; totalRecords)
    {
      ReadMembershipDataStore();
      MembershipUserCollection users = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; MembershipUserCollection();
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; ((pageIndex &amp;gt;= 0) &amp;amp;&amp;amp; (pageSize &amp;gt;= 1))
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
        {
          &lt;SPAN style="COLOR: #0000ff"&gt;foreach&lt;/SPAN&gt; (KeyValuePair&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, MembershipUser&amp;gt; pair
            &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; _Users.Skip(pageIndex * pageSize).Take(pageSize))
          {
            users.Add(pair.Value);
          }
        }
        &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception ex)
        {
          &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Error: "&lt;/SPAN&gt; + ex.Message);
        }
      }
      totalRecords = _Users.Count;
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; users;
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; GetNumberOfUsersOnline()
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; ChangePassword(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; oldPassword, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; newPassword)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; ChangePasswordQuestionAndAnswer(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; password,
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; newPasswordQuestion, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; newPasswordAnswer)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; MembershipUser CreateUser(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; password, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; email,
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; passwordQuestion, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; passwordAnswer,
      &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; isApproved, &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt; providerUserKey,
      &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; MembershipCreateStatus status)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; DeleteUser(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; deleteAllRelatedData)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; MembershipUserCollection FindUsersByEmail(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; emailToMatch, &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; pageIndex,
      &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; pageSize, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; totalRecords)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; MembershipUserCollection FindUsersByName(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; usernameToMatch, &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; pageIndex,
      &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; pageSize, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; totalRecords)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; GetPassword(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; answer)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; MembershipUser GetUser(
      &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt; providerUserKey, &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; userIsOnline)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; GetUserNameByEmail(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; email)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; ResetPassword(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; answer)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; UnlockUser(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; userName)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; UpdateUser(MembershipUser user)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;// MembershipProvider helper method&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; ReadMembershipDataStore()
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;lock&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;this&lt;/SPAN&gt;)
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (_Users == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
        {
          &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
          {
            _Users = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; Dictionary&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, MembershipUser&amp;gt;(
              16, StringComparer.InvariantCultureIgnoreCase);
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; queryString = &lt;SPAN style="COLOR: #800000"&gt;"SELECT * FROM phpbb_users WHERE [user_id]&amp;gt;0"&lt;/SPAN&gt;;
            &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; (OdbcConnection connection =
              &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; OdbcConnection(_connectionString))
            {
              OdbcCommand command =
                &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; OdbcCommand(queryString, connection);
              connection.Open();
              OdbcDataReader reader =
                command.ExecuteReader();
              &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt; (reader.Read())
              {
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; sUserName = reader[&lt;SPAN style="COLOR: #800000"&gt;"username"&lt;/SPAN&gt;].ToString();
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; sEmail = reader[&lt;SPAN style="COLOR: #800000"&gt;"user_email"&lt;/SPAN&gt;].ToString();
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; sPassword = reader[&lt;SPAN style="COLOR: #800000"&gt;"user_password"&lt;/SPAN&gt;].ToString();
                DateTime dCreationDate =
                  _phpbbUtils.ConvertDate(reader[&lt;SPAN style="COLOR: #800000"&gt;"user_regdate"&lt;/SPAN&gt;].ToString());
                DateTime dLastLoginDate =
                  _phpbbUtils.ConvertDate(reader[&lt;SPAN style="COLOR: #800000"&gt;"user_session_time"&lt;/SPAN&gt;].ToString());
                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (dLastLoginDate == &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DateTime(1970, 1, 1))
                {
                  dLastLoginDate = dCreationDate;
                }
                DateTime dLastActivityDate =
                  _phpbbUtils.ConvertDate(reader[&lt;SPAN style="COLOR: #800000"&gt;"user_session_time"&lt;/SPAN&gt;].ToString());
                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (dLastActivityDate == &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DateTime(1970, 1, 1))
                {
                  dLastActivityDate = dLastLoginDate;
                }
                Int32 status = Convert.ToInt32(reader[&lt;SPAN style="COLOR: #800000"&gt;"user_active"&lt;/SPAN&gt;].ToString());
                &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; approved = (status == 0) ? &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;;
                &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; locked = (status == 0) ? &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt; : &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
                MembershipUser user = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; MembershipUser(
                  Name,        &lt;SPAN style="COLOR: #008000"&gt;      // Provider name&lt;/SPAN&gt;
                  sUserName,     &lt;SPAN style="COLOR: #008000"&gt;    // UserName&lt;/SPAN&gt;
                  &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;,        &lt;SPAN style="COLOR: #008000"&gt;      // ProviderUserKey&lt;/SPAN&gt;
                  sEmail,      &lt;SPAN style="COLOR: #008000"&gt;      // Email&lt;/SPAN&gt;
                  String.Empty,    &lt;SPAN style="COLOR: #008000"&gt;  // PasswordQuestion&lt;/SPAN&gt;
                  sPassword,     &lt;SPAN style="COLOR: #008000"&gt;    // Comment&lt;/SPAN&gt;
                  approved,      &lt;SPAN style="COLOR: #008000"&gt;    // IsApproved&lt;/SPAN&gt;
                  locked,      &lt;SPAN style="COLOR: #008000"&gt;      // IsLockedOut&lt;/SPAN&gt;
                  dCreationDate,   &lt;SPAN style="COLOR: #008000"&gt;  // CreationDate&lt;/SPAN&gt;
                  dLastLoginDate,  &lt;SPAN style="COLOR: #008000"&gt;  // LastLoginDate&lt;/SPAN&gt;
                  dLastActivityDate, &lt;SPAN style="COLOR: #008000"&gt;// LastActivityDate&lt;/SPAN&gt;
                  dCreationDate,   &lt;SPAN style="COLOR: #008000"&gt;  // LastPasswordChangedDate&lt;/SPAN&gt;
                  dCreationDate    &lt;SPAN style="COLOR: #008000"&gt;  // LastLockoutDate&lt;/SPAN&gt;
                 );
                _Users.Add(user.UserName, user);
              }
              reader.Close();
            }
          }
          &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception ex)
          {
            &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Error: "&lt;/SPAN&gt; + ex.Message);
          }
        }
      }
    }
  }

  &lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;// PhpBBRoleProvider&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;

  &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; PhpBBRoleProvider : RoleProvider
  {
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; _connectionStringName;
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; _connectionString;
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; PhpBBUtils _phpbbUtils;
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; Dictionary&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[]&amp;gt; _UsersAndRoles =
      &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; Dictionary&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[]&amp;gt;(
        16, StringComparer.InvariantCultureIgnoreCase);
    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; Dictionary&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[]&amp;gt; _RolesAndUsers =
      &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; Dictionary&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[]&amp;gt;(
        16, StringComparer.InvariantCultureIgnoreCase);

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;// RoleProvider properties&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; ApplicationName
    {
      get { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
      set { &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException(); }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;// RoleProvider methods&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; Initialize(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; name, NameValueCollection config)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (config == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentNullException(&lt;SPAN style="COLOR: #800000"&gt;"config"&lt;/SPAN&gt;);
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(name))
        name = &lt;SPAN style="COLOR: #800000"&gt;"ReadOnlyPhpBBRoleProvider"&lt;/SPAN&gt;;
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(config[&lt;SPAN style="COLOR: #800000"&gt;"description"&lt;/SPAN&gt;]))
      {
        config.Remove(&lt;SPAN style="COLOR: #800000"&gt;"description"&lt;/SPAN&gt;);
        config.Add(&lt;SPAN style="COLOR: #800000"&gt;"description"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #800000"&gt;"Read-only phpBB role provider"&lt;/SPAN&gt;);
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;base&lt;/SPAN&gt;.Initialize(name, config);
      _connectionStringName = config[&lt;SPAN style="COLOR: #800000"&gt;"connectionStringName"&lt;/SPAN&gt;];
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(_connectionStringName))
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(
          &lt;SPAN style="COLOR: #800000"&gt;"No connection string was specified.\n"&lt;/SPAN&gt;);
      }
      _connectionString = ConfigurationManager.ConnectionStrings
        [_connectionStringName].ConnectionString;
      _phpbbUtils = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; PhpBBUtils();
      ReadRoleDataStore();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; IsUserInRole(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; roleName)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (username == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt; || roleName == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentNullException();
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (username == String.Empty || roleName == String.Empty)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException();
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (!_UsersAndRoles.ContainsKey(username))
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Invalid user name"&lt;/SPAN&gt;);
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (!_RolesAndUsers.ContainsKey(roleName))
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Invalid role name"&lt;/SPAN&gt;);
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] roles = _UsersAndRoles[username];
      &lt;SPAN style="COLOR: #0000ff"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; role &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; roles)
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.Compare(role, roleName, &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;) == 0)
          &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;;
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] GetRolesForUser(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; username)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (username == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentNullException();
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (username == String.Empty)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException();
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] roles;
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (!_UsersAndRoles.TryGetValue(username, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; roles))
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Invalid user name"&lt;/SPAN&gt;);
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; roles;
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] GetUsersInRole(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; roleName)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (roleName == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentNullException();
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (roleName == &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Empty)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException();
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] users;
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (!_RolesAndUsers.TryGetValue(roleName, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; users))
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Invalid role name"&lt;/SPAN&gt;);
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; users;
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] GetAllRoles()
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; i = 0;
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] roles = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[_RolesAndUsers.Count];
      &lt;SPAN style="COLOR: #0000ff"&gt;foreach&lt;/SPAN&gt; (KeyValuePair&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[]&amp;gt; pair &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; _RolesAndUsers)
        roles[i++] = pair.Key;
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; roles;
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; RoleExists(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; roleName)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (roleName == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentNullException();
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (roleName == String.Empty)
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException();
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; _RolesAndUsers.ContainsKey(roleName);
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; CreateRole(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; roleName)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; DeleteRole(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; roleName, &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; throwOnPopulatedRole)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; AddUsersToRoles(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] usernames, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] roleNames)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] FindUsersInRole(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; roleName, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; usernameToMatch)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; RemoveUsersFromRoles(
      &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] usernames, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] roleNames)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; NotSupportedException();
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;// RoleProvider helper method&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; ReadRoleDataStore()
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;lock&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;this&lt;/SPAN&gt;)
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
        {
          &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; userQueryString = &lt;SPAN style="COLOR: #800000"&gt;"SELECT * FROM phpbb_users WHERE [user_id]&amp;gt;0"&lt;/SPAN&gt;;
          &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; (OdbcConnection connection =
            &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; OdbcConnection(_connectionString))
          {
            connection.Open();
            OdbcCommand userCommand =
              &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; OdbcCommand(userQueryString, connection);            
            OdbcDataReader userReader =
              userCommand.ExecuteReader();
            &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt; (userReader.Read())
            {
              &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; user =
                userReader[&lt;SPAN style="COLOR: #800000"&gt;"username"&lt;/SPAN&gt;].ToString();
              &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; userid =
                userReader[&lt;SPAN style="COLOR: #800000"&gt;"user_id"&lt;/SPAN&gt;].ToString();

              &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; groupQueryString =
                &lt;SPAN style="COLOR: #800000"&gt;"SELECT phpbb_groups.group_name "&lt;/SPAN&gt; +
                &lt;SPAN style="COLOR: #800000"&gt;" FROM phpbb_user_group INNER JOIN phpbb_groups "&lt;/SPAN&gt; +
                &lt;SPAN style="COLOR: #800000"&gt;" ON phpbb_user_group.group_id = phpbb_groups.group_id "&lt;/SPAN&gt; +
                &lt;SPAN style="COLOR: #800000"&gt;" WHERE (((phpbb_user_group.user_pending)=0) "&lt;/SPAN&gt; +
                &lt;SPAN style="COLOR: #800000"&gt;" AND ((phpbb_user_group.user_id)="&lt;/SPAN&gt; + userid + &lt;SPAN style="COLOR: #800000"&gt;") "&lt;/SPAN&gt; +
                &lt;SPAN style="COLOR: #800000"&gt;" AND ((phpbb_groups.group_single_user)=0));"&lt;/SPAN&gt;;

              OdbcCommand groupCommand =
                &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; OdbcCommand(groupQueryString, connection);
              OdbcDataReader groupReader =
                groupCommand.ExecuteReader();

              &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (groupReader.HasRows == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)
              {
                _UsersAndRoles.Add(user, &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[0]);
              }
              &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;
              {
                ArrayList roleList = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArrayList();
                &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt; (groupReader.Read())
                {
                  roleList.Add(groupReader[&lt;SPAN style="COLOR: #800000"&gt;"group_name"&lt;/SPAN&gt;].ToString());
                }
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] roles =
                  (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[])roleList.ToArray(&lt;SPAN style="COLOR: #0000ff"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;));
                _UsersAndRoles.Add(user, roles);
                &lt;SPAN style="COLOR: #0000ff"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; role &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; roles)
                {
                  &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] users1;
                  &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (_RolesAndUsers.TryGetValue(role, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; users1))
                  {
                    &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] users2 = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[users1.Length + 1];
                    users1.CopyTo(users2, 0);
                    users2[users1.Length] = user;
                    _RolesAndUsers.Remove(role);
                    _RolesAndUsers.Add(role, users2);
                  }
                  &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;
                    _RolesAndUsers.Add(role, &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;[] { user });
                }
              }
              groupReader.Close();
            }
            userReader.Close();
          }
        }
        &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception ex)
        {
          &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Error: "&lt;/SPAN&gt; + ex.Message);
        }
      }
    }
  }

  &lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;// PhpBBUtils&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;

  &lt;SPAN style="COLOR: #0000ff"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; PhpBBUtils
  {
    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; PasswordHash(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; password)
    {
      &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
      {
        MD5 md5 = MD5.Create();
        &lt;SPAN style="COLOR: #0000ff"&gt;byte&lt;/SPAN&gt;[] byteArray =
          md5.ComputeHash(Encoding.ASCII.GetBytes(password));
        StringBuilder stringBuilder =
          &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; StringBuilder(byteArray.Length * 2);
        &lt;SPAN style="COLOR: #0000ff"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;byte&lt;/SPAN&gt; byteMember &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; byteArray)
        {
          stringBuilder.AppendFormat(&lt;SPAN style="COLOR: #800000"&gt;"{0:x2}"&lt;/SPAN&gt;, byteMember);
        }
        &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; stringBuilder.ToString();
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception ex)
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Error: "&lt;/SPAN&gt; + ex.Message);
      }
    }

    &lt;SPAN style="COLOR: #008000"&gt;/* ---------------------------------------- */&lt;/SPAN&gt;

    &lt;SPAN style="COLOR: #0000ff"&gt;internal&lt;/SPAN&gt; DateTime ConvertDate(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; offset)
    {
      DateTime dateTime = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DateTime(1970, 1, 1);
      &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (!(String.IsNullOrEmpty(offset)))
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
        {
          dateTime = dateTime.AddSeconds(Convert.ToDouble(offset));
        }
        &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception ex)
        {
          &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ProviderException(&lt;SPAN style="COLOR: #800000"&gt;"Error: "&lt;/SPAN&gt; + ex.Message);
        }
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; dateTime;
    }
  }
}&lt;/PRE&gt;&lt;/LI&gt;
&lt;LI&gt;Save and compile the project.&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Step 3: Add the provider to IIS&lt;/H3&gt;
&lt;P&gt;In this third step you will determine the assembly information for the membership and role provider, and then add that information to the list of trusted providers for IIS.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Determine the assembly information for the provider: 
&lt;UL&gt;
&lt;LI&gt;In Windows Explorer, open your "%WinDir%\assembly" path. &lt;/LI&gt;
&lt;LI&gt;Right-click the &lt;B&gt;ReadOnlyPhpBBProvider&lt;/B&gt; assembly and click &lt;B&gt;Properties&lt;/B&gt;. &lt;/LI&gt;
&lt;LI&gt;Copy the &lt;B&gt;Culture&lt;/B&gt; value; for example: &lt;B&gt;Neutral&lt;/B&gt;. &lt;/LI&gt;
&lt;LI&gt;Copy the &lt;B&gt;Version&lt;/B&gt; number; for example: &lt;B&gt;1.0.0.0&lt;/B&gt;. &lt;/LI&gt;
&lt;LI&gt;Copy the &lt;B&gt;Public Key Token&lt;/B&gt; value; for example: &lt;B&gt;f0e1d2c3b4a59687&lt;/B&gt;. &lt;/LI&gt;
&lt;LI&gt;Click &lt;B&gt;Cancel&lt;/B&gt;.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Add the provider to the list of trusted providers for IIS: 
&lt;UL&gt;
&lt;LI&gt;Open the Administration.config file for editing. (&lt;B&gt;Note&lt;/B&gt;: This file is located in your "%WinDir%\System32\Inetsrv\Config" folder.)&lt;/LI&gt;
&lt;LI&gt;Add the providers with the assembly properties from the previous steps to the &lt;TT&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;trustedProviders&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/TT&gt; section using the following syntax: 
&lt;P&gt;&lt;TT&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;SPAN style="COLOR: #a31515"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;="ReadOnlyPhpBBProvider.PhpBBMembershipProvider, ReadOnlyPhpBBProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0e1d2c3b4a59687" /&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;add&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlyPhpBBProvider.PhpBBRoleProvider, ReadOnlyPhpBBProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0e1d2c3b4a59687" /&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&lt;/TT&gt;&lt;/P&gt;&lt;/LI&gt;
&lt;LI&gt;Save and close the the Administration.config file.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Step 4: Configure your site for Forms Authentication using the phpBB provider&lt;/H3&gt;
&lt;P&gt;In this fourth step you will configure your Web site to use forms authentication with the membership and role providers by manually creating a Web.config file for your Web site that sets the requisite properties for forms authentication/authorization, and adding a Login.aspx page to the Web site that will process forms authentication requests.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: This example will authorize phpBB accounts that are members of the user-created "Members" group.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create a Login.aspx file for your Web site: 
&lt;UL&gt;
&lt;LI&gt;Paste the following code into a text editor: &lt;PRE&gt;&lt;SPAN style="COLOR: #000000; BACKGROUND-COLOR: #ffee62"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;@&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Page&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR: #ffee62"&gt;%&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #000000; BACKGROUND-COLOR: #ffee62"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;@&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Import&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Namespace&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="System.ComponentModel"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR: #ffee62"&gt;%&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;html&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;head&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="server"&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;Login Page&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;head&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;body&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
   &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;form&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="form1"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="server"&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Login&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Login1"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="server"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;BorderStyle&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Solid"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;BackColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="#ffffcc"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;BorderWidth&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="1px"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;BorderColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="#cccc99"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;Font-Size&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="10pt"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;Font-Names&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Verdana"&amp;gt;&lt;/SPAN&gt;
         &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TitleTextStyle&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Font-Bold&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="True"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="#ffffff"&lt;/SPAN&gt;
            &lt;SPAN style="COLOR: #ff0000"&gt;BackColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="#666666"/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&lt;SPAN style="COLOR: #a31515"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Login&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
   &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;form&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;body&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;html&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/LI&gt;
&lt;LI&gt;Save the code as "Login.aspx" in the root of your Web site.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Create a Web.config file for your Web site: 
&lt;UL&gt;
&lt;LI&gt;Paste the following code into a text editor: &lt;PRE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;&amp;lt;!-- Add the connection string for the providers. --&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;connectionStrings&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="PhpBBForums"
     &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;connectionString&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="DRIVER={Microsoft Access Driver (*.mdb)};DBQ=C:\Inetpub\wwwdata\phpbb.mdb"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;connectionStrings&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;system.web&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;&amp;lt;!-- Add the read-only membership provider and set it as the default. --&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;membership&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;defaultProvider&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlyPhpBBMembershipProvider"&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;providers&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlyPhpBBMembershipProvider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlyPhpBBProvider.PhpBBMembershipProvider, ReadOnlyPhpBBProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0e1d2c3b4a59687"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;description&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Read-only PhpBB membership provider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;connectionStringName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="PhpBBForums"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;providers&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;membership&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;&amp;lt;!-- Add the read-only role provider and set it as the default. --&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;roleManager&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;defaultProvider&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlyPhpBBRoleProvider"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;enabled&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="true"&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;providers&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlyPhpBBRoleProvider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlyPhpBBProvider.PhpBBRoleProvider, ReadOnlyPhpBBProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0e1d2c3b4a59687"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;description&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Read-only PhpBB role provider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;connectionStringName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="PhpBBForums"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;providers&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;roleManager&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #008000"&gt;&amp;lt;!-- Set the authentication mode to forms authentication. --&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;authentication&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;mode&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Forms"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;system.web&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;system.webServer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;modules&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #008000"&gt;&amp;lt;!-- Set authentication for the application. --&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;remove&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="FormsAuthentication"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="FormsAuthentication"
       &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="System.Web.Security.FormsAuthenticationModule"
       &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;preCondition&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=""&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;remove&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="DefaultAuthentication"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="DefaultAuthentication"
       &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="System.Web.Security.DefaultAuthenticationModule"
       &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;preCondition&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=""&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;remove&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="RoleManager"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="RoleManager"
       &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="System.Web.Security.RoleManagerModule"
       &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;preCondition&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=""&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;modules&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;security&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #008000"&gt;&amp;lt;!-- Set authorization for the application. --&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;authorization&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;remove&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;users&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="*"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;roles&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=""&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;verbs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=""&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
        &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;accessType&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Allow"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;roles&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Members"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;authorization&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;security&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;system.webServer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Note&lt;/B&gt;: Make sure that the &lt;I&gt;PublicKeyToken&lt;/I&gt; value contains the correct public key token from the assembly properties that you copied in previous steps, and the &lt;I&gt;connectionString&lt;/I&gt; value contains the correct information for your phpBB database.&lt;/LI&gt;
&lt;LI&gt;Save the code as "Web.config" in the root of your Web site.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;Additional notes for using the read-only phpBB provider&lt;/H3&gt;
&lt;P&gt;As mentioned before, all of the user account management features are built-in to the phpBB forums, so I did not add them to my provider. The being said, there are still several features that integrate nicely with IIS. The following screenshot shows the list of users for a phpBB forum in Internet Explorer:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9557623/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9557623/500x375.aspx" border=2&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;You'll notice that several pieces of information are listed for each user: username, date joined, number of posts, etc. If you open the &lt;B&gt;.NET Users&lt;/B&gt; feature for your site, you'll notice that some of the account information is mirrored there, as shown in the following illustration:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9557625/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9557625/500x375.aspx" border=2&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Likewise, if you open the &lt;B&gt;.NET Roles&lt;/B&gt; feature for your site, you'll notice that the three roles are enumerated and the number of users per role is listed:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9557627/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9557627/500x375.aspx" border=2&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As with my &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2009/02/16/creating-a-read-only-snitz-membership-provider.aspx" target=_blank&gt;Read-Only Snitz Provider&lt;/A&gt;, all of the above information in the &lt;B&gt;.NET Users&lt;/B&gt; and &lt;B&gt;.NET Roles&lt;/B&gt; features is read-only, so any attempt to modify user or role information will return an error that the specified method is not supported:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9426930/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9426930/640x312.aspx"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;But unlike my Snitz provider, which is limited to three built-in roles, you can add as many groups as you want to your phpBB forums and use those groups as membership roles.&lt;/P&gt;
&lt;H3&gt;Summary and parting thoughts&lt;/H3&gt;
&lt;P&gt;So now you have a simple read-only membership and role provider for the phpBB 2.0 forums. As previously mentioned - this is not a full-featured provider because I only needed it to fulfill a specific need for forms authentication. If you want to be a little adventurous, you could easily expand this provider to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Work with the phpBB 3.0 application.&lt;/LI&gt;
&lt;LI&gt;Perform some of the additional provider tasks like adding and removing users or assigning users to roles.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Have fun. ;-]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9557707" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category></item><item><title>Advertising IIS Around the World</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/04/10/advertising-iis-around-the-world.aspx</link><pubDate>Fri, 10 Apr 2009 19:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9543564</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9543564.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9543564</wfw:commentRss><description>&lt;P&gt;In case you haven't already surmised from some of my other blog posts, I've been around IIS for a &lt;STRONG&gt;&lt;EM&gt;long&lt;/EM&gt;&lt;/STRONG&gt; time, so it should go without saying that I'm a big fan of IIS.&lt;/P&gt;
&lt;P&gt;I remember when we first released IIS 1.0 for Windows NT 3.51 and we were handing out IIS CD-ROMs at trade shows way back in early 1996; everyone kept asking, "What is this for?" (Obviously the Internet was still a new concept to a lot of people back then.) Out of nostalgia, I kept a shrink-wrapped copy of IIS 1.0 for myself, and I think that I have one of the few boxes left. It usually sits in my office next to my IIS 4.0 Limited Edition CD-ROM...&lt;/P&gt;
&lt;DIV align=center&gt;
&lt;TABLE class=""&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9530962/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/robert_mcmurray/images/9530962/original.aspx"&gt;&lt;IMG height=140 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9530962/secondarythumb.aspx" width=117 mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9530962/secondarythumb.aspx"&gt;&lt;/A&gt; &lt;/TD&gt;
&lt;TD class=""&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9531060/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/robert_mcmurray/images/9531060/original.aspx"&gt;&lt;IMG height=140 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9531060/secondarythumb.aspx" width=156 mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9531060/secondarythumb.aspx"&gt;&lt;/A&gt; &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;Anyway, over the years the IIS team has printed up an assortment of IIS shirts, and I have been wearing several of these various IIS shirts as I have travelled around the world. Because I have been doing so for some time, I've found myself advertising IIS in some unexpected places. For example, my wife and I were visiting our daughter in Peru this past March, and we took the following photograph of my daughter and me (wearing one of my IIS shirts) at Machu Picchu:&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9531064/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/robert_mcmurray/images/9531064/original.aspx"&gt;&lt;IMG height=334 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9531064/500x334.aspx" width=500 mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9531064/500x334.aspx"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;So - you may ask, "What does IIS have to do with one of the newest wonders of the world?" My answer is, "&lt;I&gt;Um... nothing, really&lt;/I&gt;." I happened to be wearing my IIS shirt that day, and it made a pretty good photo. (Obviously, it was a bad hair day for me... so I'm blaming the mountain winds. ;-] )&lt;/P&gt;
&lt;P&gt;As another example, my son and I took a road trip down the California coast this past summer to visit my brother in San Francisco, and we posed for the following photo before boarding the boat to Alcatraz:&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9531088/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/robert_mcmurray/images/9531088/original.aspx"&gt;&lt;IMG height=334 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9531088/500x334.aspx" width=500 mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9531088/500x334.aspx"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;There are other times where I have taken advantage of a situation to deliberately and shamelessly pose for IIS. For example, I was scuba diving in Hawaii a couple of years ago, and I borrowed someone's dive slate to write the following message:&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9530976/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/robert_mcmurray/images/9530976/original.aspx"&gt;&lt;IMG height=375 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9530976/281x375.aspx" width=281 mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9530976/281x375.aspx"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Actually, I tend to wear IIS shirts when I go scuba diving as a matter of habit - it's kind of a good luck charm for me - and this behavior of mine has led to some interesting experiences.&lt;/P&gt;
&lt;P&gt;For example, my wife and I were going scuba diving in the Bahamas several years ago, and once again I was wearing one of my IIS t-shirts that day. The dive company had sent a van to our hotel to pick up several divers, and as I climbed aboard one of the other passengers saw my shirt and remarked, "Oh, we have an IIS person today. I'm more of an Apache Girl myself." I quickly replied, "That's okay, everybody needs a hobby." I really only expected her to get the joke, but apparently we had a tech-savvy group that day because everyone else on the bus chimed in with, "Ooooooh - you're in trouble." I didn't realize what everyone meant until we got to the dive boat where Apache Girl came walking up to me holding an air tank and said, "I'm your dive guide today, and I picked this air tank especially for you." We both had a good laugh, and I survived the dive so she can thankfully take a joke.&lt;/P&gt;
&lt;P align=center&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9542397/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/robert_mcmurray/images/9542397/original.aspx"&gt;&lt;IMG height=334 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9542397/500x334.aspx" width=500 mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9542397/500x334.aspx"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;All that being said, I really like to show off IIS. It's a lot of fun to demonstrate the many features of IIS to customers at trade shows, and it's a lot of fun to unofficially advertise IIS when I'm traveling on vacation in various places around the world. So if you see me when I'm on vacation somewhere, the chances are good that you'll be able to find me in a crowd - because I'll be the geek wearing the IIS shirt.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9543564" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Random+Thoughts/default.aspx">Random Thoughts</category></item></channel></rss>