<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Robert McMurray's Blog [MSFT]</title><subtitle type="html">IIS, FTP, WebDAV, FPSE, WMI, ADSI, ISAPI, ASP, FastCGI, etc. ;-)</subtitle><id>http://blogs.msdn.com/robert_mcmurray/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/robert_mcmurray/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2008-10-02T10:20:00Z</updated><entry><title>Using Apple's WebDavFS for Mac OS X with WebDAV on IIS 7</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/07/01/using-apple-s-webdavfs-for-mac-os-x-with-webdav-on-iis-7.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/07/01/using-apple-s-webdavfs-for-mac-os-x-with-webdav-on-iis-7.aspx</id><published>2009-07-02T02:19:00Z</published><updated>2009-07-02T02:19:00Z</updated><content type="html">&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 connect 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;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /><category term="WebDAV" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/WebDAV/default.aspx" /></entry><entry><title>Using LogParser with FTP 7.x Sessions</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/06/11/using-logparser-with-ftp-7-x-sessions.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/06/11/using-logparser-with-ftp-7-x-sessions.aspx</id><published>2009-06-12T02:15:00Z</published><updated>2009-06-12T02:15:00Z</updated><content type="html">&lt;P&gt;One of the great features that we added to our W3C logging enhancements in FTP 7.0 and FTP 7.5 is the ability to track unique sessions, which are represented by GUIDs in a field that is named &lt;I&gt;&lt;B&gt;x-session&lt;/B&gt;&lt;/I&gt;. Because of this addition, you can do some interesting things with LogParser when analyzing your FTP logs.&lt;/P&gt;
&lt;P&gt;The purpose of today's blog is to show a couple of the scripts that I use to analyze some of the session-based information that I'm interested in from time to time.&lt;/P&gt;
&lt;H3&gt;Using LogParser to Count FTP Sessions&lt;/H3&gt;
&lt;P&gt;Since the new FTP service tracks unique sessions, it is now possible to generate reports that show the number of unique FTP sessions you served by day. The following batch file accomplishes this in two parts: first it creates a temporary tab-separated-value file that contains the unique sessions by day, then it calculates the number of sessions by day and writes the totals to a tab-separated-value file that is named &lt;I&gt;Sessions.tsv&lt;/I&gt;, which you can open using an application like Microsoft Excel.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;TT&gt;@echo off&lt;BR&gt;&lt;BR&gt;set LOGPATTERN=u_ex*.log&lt;BR&gt;&lt;BR&gt;logparser.exe "SELECT DISTINCT date,x-session INTO '%~n0.tmp' from %LOGPATTERN%" -i:w3c -o:tsv -headers:ON&lt;BR&gt;&lt;BR&gt;if exist "%~n0.tmp" (&lt;BR&gt;logparser.exe "SELECT date,COUNT(x-session) AS sessions INTO sessions.tsv FROM '%~n0.tmp' GROUP BY date" -i:tsv -o:tsv -headers:ON&lt;BR&gt;del "%~n0.tmp"&lt;BR&gt;)&lt;BR&gt;&lt;BR&gt;set LOGPATTERN=&lt;/TT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Using LogParser to Split FTP Log Files into Unique Session Activity Logs&lt;/H3&gt;
&lt;P&gt;I use the following script when I am testing various FTP scenarios that will split my FTP log files into individual log files that are named after the GUID for each session. (&lt;B&gt;Note&lt;/B&gt;: Please bear in mind, this may generate a lot of log files, so use it sparingly!) You can then analyze the resulting log files to see the list of client activity that was unique to each session.&lt;/P&gt;
&lt;P&gt;This script accomplishes its objective in two parts: first it creates a temporary tab-separated-value file with the list of unique session IDs, then it loops through each session ID and creates a W3C log file for each session's activity.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;TT&gt;@echo off&lt;BR&gt;&lt;BR&gt;set LOGPATTERN=u_ex*.log&lt;BR&gt;&lt;BR&gt;logparser.exe "select distinct x-session into '%~n0.tmp' from '%LOGPATTERN%'" -i:w3c -o:tsv -headers:off &lt;BR&gt;&lt;BR&gt;if exist "%~n0.tmp" (&lt;BR&gt;for /f "delims=|" %%a in (%~n0.tmp) do (&lt;BR&gt;logparser.exe "select date,time,c-ip,cs-username,s-ip,s-port,cs-method,cs-uri-stem,sc-status,sc-win32-status,sc-substatus,x-session,x-fullpath into '%%a.log' from '%LOGPATTERN%' where x-session='%%a' order by date,time" -i:w3c -o:w3c&lt;BR&gt;)&lt;BR&gt;del "%~n0.tmp"&lt;BR&gt;)&lt;BR&gt;&lt;BR&gt;set LOGPATTERN=&lt;/TT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;That about does it for today - I hope this helps!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9728698" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /><category term="LogParser" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/LogParser/default.aspx" /></entry><entry><title>FTP Clients - Part 6: Core FTP LE</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/05/01/ftp-clients-part-6-core-ftp-le.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/05/01/ftp-clients-part-6-core-ftp-le.aspx</id><published>2009-05-01T23:10:00Z</published><updated>2009-05-01T23:10:00Z</updated><content type="html">&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;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>BLOG - FTP 7.5 Service Extensibility References</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/04/23/blog-ftp-7-5-service-extensibility-references.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/04/23/blog-ftp-7-5-service-extensibility-references.aspx</id><published>2009-04-24T00:23:00Z</published><updated>2009-04-24T00:23:00Z</updated><content type="html">&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;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>Creating a Read-Only Membership Provider for phpBB 2.0 Users</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/04/20/creating-a-read-only-membership-provider-for-phpbb-2-0-users.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/04/20/creating-a-read-only-membership-provider-for-phpbb-2-0-users.aspx</id><published>2009-04-20T23:16:00Z</published><updated>2009-04-20T23:16:00Z</updated><content type="html">&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;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /></entry><entry><title>Advertising IIS Around the World</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/04/10/advertising-iis-around-the-world.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/04/10/advertising-iis-around-the-world.aspx</id><published>2009-04-10T16:43:00Z</published><updated>2009-04-10T16:43:00Z</updated><content type="html">&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;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /><category term="Random Thoughts" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/Random+Thoughts/default.aspx" /></entry><entry><title>FTP 7.5 and WebDAV 7.5 have been released!</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/03/18/ftp-7-5-and-webdav-7-5-have-been-released.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/03/18/ftp-7-5-and-webdav-7-5-have-been-released.aspx</id><published>2009-03-18T07:29:00Z</published><updated>2009-03-18T07:29:00Z</updated><content type="html">&lt;P&gt;Over the next few days you're going to hear a lot of details about many of the great new IIS extensions that the IIS feature team is releasing for the &lt;A class="" href="http://www.microsoft.com/events/mix/default.mspx" target=_blank mce_href="http://www.microsoft.com/events/mix/default.mspx"&gt;2009 MIX Conference&lt;/A&gt; in Las Vegas later today. I don't want to spoil any surprises by talking about anyone else’s feature areas, but I’m about to board a plane to head out on vacation (to Peru!) and I'm not taking a computer with me (believe it or not!) so I thought that I’d take a moment to highlight just a few of the features that are in the FTP 7.5 and WebDAV 7.5 releases.&lt;/P&gt;
&lt;P&gt;&lt;BIG&gt;&lt;U&gt;&lt;B&gt;FTP 7.5&lt;/B&gt;&lt;/U&gt;&lt;/BIG&gt;&lt;/P&gt;
&lt;P&gt;One of the great new features in FTP 7.5 is &lt;I&gt;extensibility&lt;/I&gt;. We had some extensibility features that were partially implemented in FTP 7.0, and we used those for the ASP.NET and IIS Manager authentication providers, but FTP extensibility was not officially supported in the 7.0 release. With FTP 7.5 extensibility is fully supported, so you can now write providers that implement custom functionality for authentication/authorization, home directory lookups, and logging.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9486115/original.aspx" target=_blank&gt;&lt;IMG height=480 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9486115/493x480.aspx" width=493&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;To help developers get started writing providers for FTP 7.5, I wrote the following walkthroughs that are available on Microsoft's &lt;A href="http://learn.iis.net/" target=_blank&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&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&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&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&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&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&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;Another highlight in FTP 7.5 is the addition of a user interface for the FTP Request Filtering features. We shipped request filtering with FTP 7.0 while the request filtering user interface was still in development, and the 7.5 version seemed like a great time to release it.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9486127/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9486127/500x260.aspx"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;For those of you that are unfamiliar with FTP request filtering, it allows you to add rules that allow or deny specific file extensions, hidden segments, URL sequences, and even FTP commands.&lt;/P&gt;
&lt;P&gt;For more information about the features in the new FTP service, see the following page on the &lt;A href="http://www.iis.net/" target=_blank&gt;http://www.iis.net/&lt;/A&gt; web site:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.iis.net/extensions/FTP" target=_blank&gt;http://www.iis.net/extensions/FTP&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;BIG&gt;&lt;U&gt;&lt;B&gt;WebDAV 7.5&lt;/B&gt;&lt;/U&gt;&lt;/BIG&gt;&lt;/P&gt;
&lt;P&gt;One of the big changes in WebDAV 7.5 is the inclusion of WebDAV locks, which are implemented through a simple locking mechanism. Our lock implementation was still in development when we shipped the WebDAV 7.0 release, and this release should help publishing scenarios where WebDAV locks are required.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9486130/original.aspx" target=_blank&gt;&lt;IMG height=260 src="http://blogs.msdn.com/photos/robert_mcmurray/images/9486130/500x260.aspx" width=500&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;To help you get started using locks with WebDAV 7.5, I wrote the following walkthrough that is available on Microsoft's &lt;A href="http://learn.iis.net/"&gt;learn.iis.net&lt;/A&gt; web site:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&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;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;For more information about the features in the new WebDAV module, see the following page on the &lt;A href="http://www.iis.net/" target=_blank&gt;http://www.iis.net/&lt;/A&gt; web site:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.iis.net/extensions/WebDAV" target=_blank&gt;http://www.iis.net/extensions/WebDAV&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;BIG&gt;&lt;U&gt;&lt;B&gt;In Closing...&lt;/B&gt;&lt;/U&gt;&lt;/BIG&gt;&lt;/P&gt;
&lt;P&gt;So that about wraps it up for some of the major highlights for FTP and WebDAV; for news about everything else that's coming out for IIS, watch the news items on the &lt;A href="http://www.iis.net/" target=_blank&gt;http://www.iis.net/&lt;/A&gt; home page!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9486224" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /><category term="WebDAV" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/WebDAV/default.aspx" /></entry><entry><title>Creating a Read-Only Snitz Membership Provider</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/02/16/creating-a-read-only-snitz-membership-provider.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/02/16/creating-a-read-only-snitz-membership-provider.aspx</id><published>2009-02-17T02:53:00Z</published><updated>2009-02-17T02:53:00Z</updated><content type="html">&lt;P&gt;For this blog post I'm going to take a brief departure from my FTP client series and share some code that I put together recently to help address a situation that presented itself a short time ago.&lt;/P&gt;
&lt;H4&gt;Problem Description&lt;/H4&gt;
&lt;P&gt;I keep a web site for my extended family that uses the &lt;A href="http://forum.snitz.com/" target=_blank&gt;Snitz Forums&lt;/A&gt; for private discussions between family members. Recently one of my relatives scanned several historical photographs of family members from the early 1900s, and I thought that uploading those to the family web site would be a great way to share them with everyone. Of course, I don't want to share those photos with the entire Internet, so I needed to come up with a way to share them with just my family members.&lt;/P&gt;
&lt;P&gt;My site has been using the Snitz forums application since the dark ages, (meaning my pre-ASP.NET days), so I already have a list of family members that have active accounts on my site and I didn't want to roll out some new authentication method that would confuse everyone. I could write a photo gallery application of my own that used the Snitz accounts for authentication, but &lt;A href="http://blogs.iis.net/bills/default.aspx" target=_blank&gt;Bill Staples&lt;/A&gt; had already written a really cool sample photo gallery application as an HTTP module for IIS 7.0 that I wanted to use, which suggested to me that forms authentication was my best bet for the application. But how could I consume the existing Snitz accounts?&lt;/P&gt;
&lt;H4&gt;Problem Resolution&lt;/H4&gt;
&lt;P&gt;The answer was simple - create a membership and role provider using the Snitz database. Since the Snitz forums application already handles all of the user registration and account modification features, I didn't need a full membership provider - I just needed a simple provider that would perform user validation and role lookups.&lt;/P&gt;
&lt;H4&gt;Provider Design&lt;/H4&gt;
&lt;P&gt;I had just recently written a walkthrough for the &lt;A href="http://learn.iis.net/"&gt;learn.iis.net&lt;/A&gt; web site titled &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; that describes how to create and use the MSDN sample membership and role providers for IIS 7.0, so I leveraged a great deal of that code design to create my new read-only Snitz membership provider. (You should notice a great deal of intentional similarities in my code. &lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;)&lt;/P&gt;
&lt;P&gt;I chose to create a single namespace ("ReadOnlySnitzProvider") that contained two classes: one for the membership provider ("SnitzMembershipProvider") and the other for the role provider ("SnitzRoleProvider"); and I added an additional class ("SnitzUtils") with a couple of helper methods. (I had a few more helper methods at one point, but I trimmed down the code to just these methods. I'll say a little more about that later.)&lt;/P&gt;
&lt;P&gt;The Snitz forums user accounts don't really have much of a concept of roles, so my provider only works with three roles: Members, Moderators, and Administrators. These roles are mapped to the corresponding user account levels that exist in Snitz. Several other account properties such as creation date/time, last logged in date/time, lockout status, etc., are all accurately represented by this provider. &lt;B&gt;Note&lt;/B&gt;: I only check the FORUM_MEMBERS table, not the FORUM_MEMBERS_PENDING table, so any pending accounts will not show up in the list of users.&lt;/P&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;ReadOnlySnitzProvider&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;ReadOnlySnitzProvider&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;ReadOnlySnitzProvider&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;ReadOnlySnitzProvider&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;ReadOnlySnitzProviderKey&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;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;ReadOnlySnitzProvider&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. The code for these classes is 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;// ReadOnlySnitzProvider&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 Snitz 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; ReadOnlySnitzProvider
{
  &lt;SPAN style="COLOR: #008000"&gt;/* ======================================== */&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;//&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;// SnitzMembershipProvider&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; SnitzMembershipProvider : 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; SnitzUtils _snitzUtils;

    &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;"ReadOnlySnitzMembershipProvider"&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 Snitz 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;
      _snitzUtils = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SnitzUtils();
    }

    &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 == _snitzUtils.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 FORUM_MEMBERS"&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;"M_NAME"&lt;/SPAN&gt;].ToString();
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; sEmail = reader[&lt;SPAN style="COLOR: #800000"&gt;"M_EMAIL"&lt;/SPAN&gt;].ToString();
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; sPassword = reader[&lt;SPAN style="COLOR: #800000"&gt;"M_PASSWORD"&lt;/SPAN&gt;].ToString();
                DateTime dCreationDate =
                  _snitzUtils.ConvertDate(reader[&lt;SPAN style="COLOR: #800000"&gt;"M_DATE"&lt;/SPAN&gt;].ToString());
                DateTime dLastLoginDate =
                  _snitzUtils.ConvertDate(reader[&lt;SPAN style="COLOR: #800000"&gt;"M_LASTHEREDATE"&lt;/SPAN&gt;].ToString());
                DateTime dLastActivityDate =
                  _snitzUtils.ConvertDate(reader[&lt;SPAN style="COLOR: #800000"&gt;"M_LASTPOSTDATE"&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(1980, 1, 1))
                {
                  dLastActivityDate = dLastLoginDate;
                }
                Int32 status = Convert.ToInt32(reader[&lt;SPAN style="COLOR: #800000"&gt;"M_STATUS"&lt;/SPAN&gt;].ToString());
                &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; approved = (status == -1) ? &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;// SnitzRoleProvider&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; SnitzRoleProvider : 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; SnitzUtils _snitzUtils;
    &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;"ReadOnlySnitzRoleProvider"&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 Snitz 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;
      _snitzUtils = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SnitzUtils();
      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; queryString = &lt;SPAN style="COLOR: #800000"&gt;"SELECT * FROM FORUM_MEMBERS"&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; user =
                reader[&lt;SPAN style="COLOR: #800000"&gt;"M_NAME"&lt;/SPAN&gt;].ToString();
              Int32 level =
                Convert.ToInt32(reader[&lt;SPAN style="COLOR: #800000"&gt;"M_LEVEL"&lt;/SPAN&gt;].ToString());
              ArrayList roleList = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArrayList();
              roleList.Add(&lt;SPAN style="COLOR: #800000"&gt;"Members"&lt;/SPAN&gt;);
              &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; ((level == 2) || (level == 3))
                roleList.Add(&lt;SPAN style="COLOR: #800000"&gt;"Moderators"&lt;/SPAN&gt;);
              &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (level == 3)
                roleList.Add(&lt;SPAN style="COLOR: #800000"&gt;"Administrators"&lt;/SPAN&gt;);
              &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 });
              }
            }
            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;// SnitzUtils&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; SnitzUtils
  {
    &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;
      {
        SHA256 sha256 = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SHA256Managed();
        &lt;SPAN style="COLOR: #0000ff"&gt;byte&lt;/SPAN&gt;[] byteArray =
          sha256.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; snitzDate)
    {
      DateTime dateTime;
      &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;
      {
        &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (String.IsNullOrEmpty(snitzDate))
        {
          dateTime = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DateTime(1980, 1, 1);
        }
        &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;
        {
          dateTime = Convert.ToDateTime(
            snitzDate.Substring(0, 4) + &lt;SPAN style="COLOR: #800000"&gt;"/"&lt;/SPAN&gt; +
            snitzDate.Substring(4, 2) + &lt;SPAN style="COLOR: #800000"&gt;"/"&lt;/SPAN&gt; +
            snitzDate.Substring(6, 2) + &lt;SPAN style="COLOR: #800000"&gt;" "&lt;/SPAN&gt; +
            snitzDate.Substring(8, 2) + &lt;SPAN style="COLOR: #800000"&gt;":"&lt;/SPAN&gt; +
            snitzDate.Substring(10, 2) + &lt;SPAN style="COLOR: #800000"&gt;":"&lt;/SPAN&gt; +
            snitzDate.Substring(12, 2)
            );
        }
      }
      &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt;
      {
        dateTime = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DateTime(1980, 1, 1);
      }
      &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;ReadOnlySnitzProvider&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;="ReadOnlySnitzProvider.SnitzMembershipProvider, ReadOnlySnitzProvider, 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;="ReadOnlySnitzProvider.SnitzRoleProvider, ReadOnlySnitzProvider, 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 Snitz 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;B&gt;Note&lt;/B&gt;: This example will authorize all Snitz accounts through the "Members" role.&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="BACKGROUND-COLOR: #ffee62; COLOR: #000000"&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="BACKGROUND-COLOR: #ffee62; COLOR: #000000"&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;="SnitzForums"
     &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\snitz_forums_2000.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;="ReadOnlySnitzMembershipProvider"&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;add&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlySnitzMembershipProvider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlySnitzProvider.SnitzMembershipProvider, ReadOnlySnitzProvider, 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 Snitz membership provider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;connectionStringName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="SnitzForums"&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;="ReadOnlySnitzRoleProvider"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;enabled&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;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;="ReadOnlySnitzRoleProvider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="ReadOnlySnitzProvider.SnitzRoleProvider, ReadOnlySnitzProvider, 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 Snitz role provider"
         &lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;connectionStringName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="SnitzForums"&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 Snitz 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 Snitz provider&lt;/H3&gt;
&lt;P&gt;As mentioned before, all of the user account management features are built-in to the Snitz 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 Snitz forum in Internet Explorer:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9426907/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9426907/640x375.aspx"&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: user name, title (role), account creation date, last visit, lockout status, etc. If you open the &lt;B&gt;.NET Users&lt;/B&gt; feature for your site, you'll notice that 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/9426908/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9426908/640x312.aspx"&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/9426909/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9426909/640x312.aspx"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&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;That being said, you can use the IIS manager to allow or deny and of the user accounts or Snitz roles using the &lt;B&gt;Authorization Rules&lt;/B&gt; feature: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9426910/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9426910/640x312.aspx"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;You should recall from earlier that you can use any of the three roles from the provider: Members, Moderators, and Administrators.&lt;/P&gt;
&lt;H3&gt;Summary and parting thoughts&lt;/H3&gt;
&lt;P&gt;So there you have it - a simple read-only membership and role provider for the Snitz forums. As previously mentioned - this is not a full-featured provider because I only needed it to fulfill a specific need for forms authentication. I had added more features at one point, and that's why the utility class used to be a little larger, but in the end I decided that it was overkill for my purpose and I deleted some of the original code. If you want to be a little adventurous, you could easily expand this provider to perform some of the additional provider tasks like adding and removing users or assigning users to roles.&lt;/P&gt;
&lt;P&gt;I hope this provider helps someone out there, and I had a lot of fun writing it - which is the point of writing code, isn't it? &lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9426965" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /></entry><entry><title>New IIS 7.0 Configuration Reference</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/01/21/new-iis-7-0-configuration-reference.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/01/21/new-iis-7-0-configuration-reference.aspx</id><published>2009-01-21T23:51:00Z</published><updated>2009-01-21T23:51:00Z</updated><content type="html">&lt;P&gt;For the past several months I have been working with several members of the IIS team on a brand-new configuration reference for IIS 7.0 that describes every configuration setting for IIS in great detail, which is now located at the following URL:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.iis.net/configreference" mce_href="http://www.iis.net/configreference"&gt;http://www.iis.net/configreference&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Each topic focuses on a specific configuration element and contains an overview section that describes the purpose of each configuration element, setup steps when appropriate, "How To" examples using the IIS Manager, and practical examples using IIS configuration settings and code samples. The complete reference contains hundreds of screenshots and thousands of lines of code using AppCmd, C#, VB.NET, JavaScript, and VBScript&amp;nbsp;- all of which should help you understand and use the IIS configuration system to manage your IIS 7.0 Web sites.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/robert_mcmurray/images/9360533/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9360533/428x375.aspx"&gt;&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;My thanks go to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Pete Harris for helping to get this reference deployed on IIS.NET&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.iis.net/bills/" target=_blank mce_href="http://blogs.iis.net/bills/"&gt;Bill Staples&lt;/A&gt; and &lt;A href="http://blogs.iis.net/mailant/" target=_blank mce_href="http://blogs.iis.net/mailant/"&gt;Mai-lan Tomsen Bukovec&lt;/A&gt; for some great vision-casting and feedback&amp;nbsp;throughout the project&lt;/LI&gt;
&lt;LI&gt;Alec Rowell for all of the great editing support&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.iis.net/sudt/" target=_blank mce_href="http://blogs.iis.net/sudt/"&gt;Suditi Lahiri&lt;/A&gt;, Lin Liu, and Yanyan Zhang for tech reviewing everything&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9360494" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /></entry><entry><title>FTP Clients - Part 5: MOVEit Freely Command-Line Secure FTP Client</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2009/01/06/ftp-clients-part-5-moveit-freely-command-line-secure-ftp-client.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2009/01/06/ftp-clients-part-5-moveit-freely-command-line-secure-ftp-client.aspx</id><published>2009-01-07T06:10:00Z</published><updated>2009-01-07T06:10:00Z</updated><content type="html">&lt;P&gt;For this installment in my series about FTP Clients, I'd like to take a look at the MOVEit Freely Command-Line Secure FTP Client ("FTPS.EXE") from Ipswitch. For this blog post I used MOVEit Freely FTP Client version 5.0.0.0, and it is available from the following URL:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.ipswitchft.com/products/moveit/client/freely/" target=_blank&gt;http://www.ipswitchft.com/products/moveit/client/freely/&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;At the time of this blog post, Ipswitch is providing the MOVEit Freely FTP client for free, although you are required to fill out a registration page with a short questionnaire. For more information on the license for the MOVEit Freely command-line FTP client, please see &lt;A href="http://www.ipswitchft.com/" target=_blank&gt;Ipswitch's web site&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;If you're like me and you like to script a lot of batch jobs on your servers, the MOVEit Freely command-line FTP client can be quite handy. The command set for the MOVEit Freely FTP client is a greatly-enhanced superset of the commands that are available with the command-line FTP.EXE client that is built-in to Windows, with added features that make additional functionality possible, such as SSL, passive FTP, resumable downloads, etc. There is a manual available with the MOVEit Freely FTP client, and I highly recommend using the manual as a reference when writing automation scripts because there are a lot of options that are available to you.&lt;/P&gt;
&lt;H3&gt;Active and Passive FTP&lt;/H3&gt;
&lt;P&gt;One of the great things about the MOVEit Freely command-line FTP client is the ability to use either Passive or Active connections, and you can switch between the two connection types using the "passive" command in the FTP session. This helps immensely when working with firewalls and such. The following example shows what that might look like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" width=500 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;ftps.exe ftp.example.com

220 Microsoft FTP Service
Connected to ftp.example.com.
User: administrator
331 Password required for administrator.
Password: ********
230 User logged in.
ftp&amp;gt; passive
Passive mode  On .
ftp&amp;gt; put foobar.txt
227 Entering Passive Mode (192,168,0,1,224,39).
150 Opening ASCII mode data connection.
226 Transfer complete.
ftp: 8 bytes sent in 0.06Seconds 0.13Kbytes/sec.
ftp&amp;gt; passive
Passive mode  Off .
ftp&amp;gt; put foobar.txt
200 PORT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
ftp: 8 bytes sent in 0.01Seconds 0.78Kbytes/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;H3&gt;Using FTP over SSL (FTPS)&lt;/H3&gt;
&lt;P&gt;The MOVEit Freely command-line FTP 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 one to use, but I generally use Explicit FTPS since Implicit FTPS should be considered obsolete. The SSL mode is specified using the "-e:" parameter on the command-line, and the 5.0.0.0 version of the MOVEit Freely command-line FTP supports the following values for that parameter:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="BORDER-RIGHT: #000000 1px solid; BORDER-TOP: #000000 1px solid; BORDER-LEFT: #000000 1px solid; BORDER-BOTTOM: #000000 1px solid; BORDER-COLLAPSE: collapse" cellSpacing=1 cellPadding=3 width=500 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Parameter&lt;/TH&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;FTPS Mode&lt;/TH&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Description&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;off&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;n/a&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies that no encryption will be used on either the control channel or data channel. 
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: This is the default behavior.&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;on&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;Explicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies that both the control channel and data channel will use encryption over an explicit FTPS connection. 
&lt;P&gt;&lt;B&gt;Notes&lt;/B&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;This uses the AUTH TLS, PBSZ 0, and PROT P commands when establishing a connection.&lt;/LI&gt;
&lt;LI&gt;You can use "prot on" and "prot off" to specify whether encryption will be used. (See Note 1 below.)&lt;/LI&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;on-ccc&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;Explicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies the control channel will use encryption over an explicit FTPS connection during login, but the control channel will switch to unencrypted after a login has been established. Data channel connections will still be encrypted. 
&lt;P&gt;&lt;B&gt;Notes&lt;/B&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;This uses the AUTH TLS, PBSZ 0, and PROT P commands to enable encryption when establishing a connection, then uses the CCC command after the username and password are successfully negotiated. (See Note 2 below.)&lt;/LI&gt;
&lt;LI&gt;The USER and PASS commands are the only commands that will be encrypted; all other FTP commands are unencrypted.&lt;/LI&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;tls-p&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;Explicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies that both control and data channel will use encryption over an explicit FTPS connection. 
&lt;P&gt;&lt;B&gt;Notes&lt;/B&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;This uses the AUTH TLS and PROT P commands when establishing a connection.&lt;/LI&gt;
&lt;LI&gt;You can use "prot on" and "prot off" to specify whether encryption will be used. (See Note 3 below.)&lt;/LI&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;tls-c&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;Explicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies that only the control connection will use encryption over an explicit FTPS connection. Data channel connections will be unencrypted. 
&lt;P&gt;&lt;B&gt;Notes&lt;/B&gt;: 
&lt;UL&gt;
&lt;LI&gt;This uses only the AUTH TLS to enable encryption when establishing a connection.&lt;/LI&gt;
&lt;LI&gt;You must manually send a PBSZ command before you can use the "prot on" and "prot off" to specify whether encryption will be used. (See Note 1 and Note 3 below.)&lt;/LI&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;tls-c-ccc&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;Explicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies that only the control connection will use encryption over an explicit FTPS connection during login, but the control channel will switch to unencrypted after a login has been established. Data connections will be unencrypted. 
&lt;P&gt;&lt;B&gt;Notes&lt;/B&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;This uses only the AUTH TLS to enable encryption when establishing a connection, then uses the CCC command after the username and password are successfully negotiated.&lt;/LI&gt;
&lt;LI&gt;The USER and PASS commands are the only commands that will be encrypted; all other FTP commands are unencrypted.&lt;/LI&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;implicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;Implicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies that both the control channel and data channel will use encryption over an implicit FTPS connection, which can only be on port 990 for the FTP7 service. 
&lt;P&gt;&lt;B&gt;Notes&lt;/B&gt;: 
&lt;UL&gt;
&lt;LI&gt;The implicit FTPS connection will encrypt both the control channel and data channel without the use of an AUTH command.&lt;/LI&gt;
&lt;LI&gt;You can use "prot on" and "prot off" to specify whether encryption will be used. (See Note 3 below.)&lt;/LI&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top noWrap align=left&gt;&lt;B&gt;implicit-ccc&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top noWrap&gt;&lt;B&gt;Implicit&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top&gt;Specifies that the control channel would use encryption over an implicit FTPS connection during login and switch the control channel to unencrypted after login, but this is &lt;B&gt;&lt;U&gt;not supported in FTP7&lt;/U&gt;&lt;/B&gt;. The implicit FTPS connection will succeed, but the FTP7 service will return an error when the CCC command is sent. You can ignore the error and continue to use the session. 
&lt;P&gt;&lt;B&gt;Notes&lt;/B&gt;: 
&lt;UL&gt;
&lt;LI&gt;Implicit FTPS connections require encryption for the command channel. (See Note 4 below.)&lt;/LI&gt;
&lt;LI&gt;You can use "prot on" and "prot off" to specify whether encryption will be used. (See Note 3 below.)&lt;/LI&gt;&lt;/UL&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The following notes should be considered:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Encryption of the data connection can be changed during the session with MOVEit Freely's "prot" command. You can use the "prot on" to specify that data connections will be encrypted, and "prot off" to specify that data connections will be unencrypted; these commands will respectively send the PROT P and PROT C commands over FTP.&lt;/LI&gt;
&lt;LI&gt;The "on-ccc", "tls-c-ccc", and "implicit-ccc" parameters are useful with firewalls that inspect FTP traffic. Switching the control channel back to unencrypted allows the firewall to inspect and possibly modify the FTP commands. For example, firewalls that are performing Network Address Translation (NAT) may need to modify the PORT and PASV commands.&lt;/LI&gt;
&lt;LI&gt;"RFC 2228 - FTP Security Extensions" states that FTP clients are required to send an FTP PBSZ command before sending an FTP PROT command, and unfortunately the MOVEit Freely 5.0.0.0 FTP client does not send this command, so you get a "503 Bad sequence of commands" error. You can work around this by issuing a literal command to the server using the FTP client's "quote" command, which appears to work. See the following example for more information. The following example shows what that might look like: 
&lt;BLOCKQUOTE&gt;&lt;I&gt;Note: I turned on debugging for this example with the "-d" option so you can see the sequence of commands.&lt;/I&gt; 
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" width=500 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;ftps.exe -e:tls-c -d ftp.example.com

220 Microsoft FTP Service
---&amp;gt; AUTH TLS
234 AUTH command ok. Expecting TLS Negotiation.
Connected to ftp.example.com.
User: administrator
---&amp;gt; USER administrator
331 Password required for administrator.
Password: ********
---&amp;gt; PASS (hidden)
230 User logged in.
---&amp;gt; SYST
215 Windows_NT
ftp&amp;gt; prot on
---&amp;gt; PROT P
503 Bad sequence of commands.
Data connections will still NOT be encrypted
ftp&amp;gt; quot PBSZ 0
---&amp;gt; PBSZ 0
200 PBSZ command successful.
ftp&amp;gt; prot on
---&amp;gt; PROT P
200 PROT command successful.
Data connections will be encrypted
ftp&amp;gt; bye
---&amp;gt; QUIT
221 Goodbye.

CMD&amp;gt;&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;&lt;/LI&gt;
&lt;LI&gt;The FTP7 service treats implicit FTPS connections as though the SSL policy for the control is set to "Require".&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;One last note about FTPS, if you are using a certificate with trust issues, you will see the following prompt displayed:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9286660/original.aspx"&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;You can get around this certificate prompt when writing scripts by using the "-z" switch. The following example shows what that might look like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;I&gt;Note: For this example I bypassed a certificate prompt with the "-z" switch, and I specified passive FTP with the "passive" command.&lt;/I&gt; 
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" width=500 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;ftps.exe -z -e:on ftp.example.com

220 Microsoft FTP Service
234 AUTH command ok. Expecting TLS Negotiation.
Connected to ftp.example.com.
User: administrator
331 Password required for administrator.
Password: ********
230 User logged in.
200 PBSZ command successful.
200 PROT command successful.
215 Windows_NT
ftp&amp;gt; passive
Passive mode On .
ftp&amp;gt; ls -l
227 Entering Passive Mode (192,168,0,1,224,97).
150 Opening ASCII mode data connection.
03-10-08 10:41AM &amp;lt;DIR&amp;gt; App_Data
09-04-08 11:41AM &amp;lt;DIR&amp;gt; aspnet_client
09-04-08 11:41AM &amp;lt;DIR&amp;gt; bin
12-17-02 11:47AM 2360 default.aspx
ftp: 128 bytes received in 0.03Seconds 83.25Kbytes/sec.
226 Transfer complete.
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;H3&gt;Using FTP Virtual Hosts&lt;/H3&gt;
&lt;P&gt;Since everything is happening from a command-line, you can use both FTP7's Virtual Hosts and the actual FTP HOST command. Once again, see my &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2007/08/28/virtual-hosts-and-host-names-in-ftp7.aspx" target=_blank&gt;Virtual Hosts and Host Names in FTP7&lt;/A&gt; blog post for more information about FTP Virtual Host Names and FTP True Host Names, and see &lt;A href="https://datatracker.ietf.org/drafts/draft-hethmon-mcmurray-ftp-hosts/"&gt;https://datatracker.ietf.org/drafts/draft-hethmon-mcmurray-ftp-hosts/&lt;/A&gt; for more information about status of the FTP HOST command.&lt;/P&gt;
&lt;P&gt;In any event, FTP7 virtual hosts are supported by using the "&lt;I&gt;ftp.example.com|username&lt;/I&gt;" 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. The following example shows what that might look like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" width=500 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;ftps.exe ftp.example.com

220 Microsoft FTP Service
Connected to ftp.example.com.
User: ftp.contoso.com|administrator
331 Password required for ftp.contoso.com|administrator.
Password: ********
230-Directory has 104,857,600 bytes of disk space available.
230 User logged in.
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;True FTP hosts can be used by specifying the FTP HOST command before the client sends the USER and PASS credentials. This is accomplished in two parts:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;You need to suppress the automatic username prompt MOVEit client by using the "-n" switch on the command-line.&lt;/LI&gt;
&lt;LI&gt;You need to specify the host name using the MOVEit client's "quote" command, which allows you to send custom FTP commands. The syntax for this would be "quote HOST ftp.example.com".&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The following example shows what that might look like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" width=500 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;ftps.exe -n ftp.example.com

220 Microsoft FTP Service
Connected to ftp.example.com.
ftp&amp;gt; quote HOST ftp.contoso.com
220 Host accepted.
ftp&amp;gt; USER administrator
331 Password required for administrator.
Password: ********
230-Directory has 104,857,600 bytes of disk space available.
230 User logged in.
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;H3&gt;Scorecard for the MOVEit Freely command-line FTP client&lt;/H3&gt;
&lt;P&gt;This concludes our quick look at some of the features that are available with the MOVEit Freely command-line FTP client, 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;&lt;A href="http://www.ipswitchft.com/" target=_blank&gt;MOVEit Freely 5.0.0.0&lt;/A&gt;&lt;/TD&gt;
&lt;TD class="" noWrap align=middle width=75&gt;n/a&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 when using the "quote HOST ftp.example.com" syntax.&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 the MOVEit Freely command-line FTP client provides - I'm just keeping the focus on those topic areas that apply to FTP7.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9286876" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>FTP Clients - Part 4: FileZilla</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2008/12/17/ftp-clients-part-4-filezilla.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2008/12/17/ftp-clients-part-4-filezilla.aspx</id><published>2008-12-17T23:25:00Z</published><updated>2008-12-17T23:25:00Z</updated><content type="html">&lt;P&gt;For this next installment in my FTP Clients series, I'd like to take a look at the FileZilla FTP client. For this blog post I was using FileZilla version 3.1.6.&lt;/P&gt;
&lt;P&gt;There are a lot of places where you can find FileZilla, but the best location is the official FileZilla web site at &lt;A href="http://filezilla-project.org/"&gt;http://filezilla-project.org/&lt;/A&gt;. The FileZilla FTP client is free, so you can't beat the price. ;-]&lt;/P&gt;
&lt;P&gt;The user interface is pretty 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://blogs.msdn.com/photos/robert_mcmurray/images/9232065/original.aspx" target=_blank&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9232065/598x480.aspx"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;FileZilla has a great Site Manager feature, which allows you to store commonly-used connections to FTP sites.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9232091/original.aspx"&gt;&lt;/P&gt;
&lt;H3&gt;Using FTP over SSL (FTPS)&lt;/H3&gt;
&lt;P&gt;When creating a connection to an FTPS server, FileZilla has two options: FTPS and FTPES. It's important to have this option configured 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;" blog post, 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 and you assign the FTP site to port 990, you are using &lt;B&gt;Implicit SSL&lt;/B&gt; - FileZilla refers to this as &lt;B&gt;FTPS&lt;/B&gt;.&lt;/LI&gt;
&lt;LI&gt;If you enable FTPS and you assign the FTP site to any port other than port 990, you are using &lt;B&gt;Explicit SSL&lt;/B&gt; - FileZilla refers to this as &lt;B&gt;FTPES&lt;/B&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9232117/original.aspx"&gt;&lt;/P&gt;
&lt;H3&gt;Using FTP Virtual Hosts&lt;/H3&gt;
&lt;P&gt;Because FileZilla's site manager allows you to specify the virtual host name as part of the user credentials, FileZilla works great with FTP7's virtual host names. All that you need to do is use the "&lt;I&gt;ftp.example.com|username&lt;/I&gt;" 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;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9232175/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;Unfortunately, even though FileZilla allows you to send custom commands, you cannot send custom commands outside of an established FTP session, so you can't send the FTP HOST command as part of your login, therefore true FTP hosts are not supported.&lt;/P&gt;
&lt;H3&gt;Directory Browsing&lt;/H3&gt;
&lt;P&gt;Using MS-DOS or UNIX directory listings in FTP7 didn't have any impact on whether FileZilla could render directory listings, nor did configuring any of the other options such as four-digit years, etc. When I create FTP connections in FileZilla's site manager it defaults to auto-detecting the FTP server type, which makes the directory browsing behavior transparent to the client. (Behind the scenes FileZilla is sending an FTP SYST command, which allows FileZilla to detect the operating system.)&lt;/P&gt;
&lt;P&gt;You can customize the server type in the advanced settings for your FTP connection, so you can match up your FTP7 directory listing options and the server type that FileZilla expects, but personally I have had no problems with auto-detection so I prefer to use that option.&lt;/P&gt;
&lt;P&gt;On a side note, if you intentionally misconfigure FileZilla's server type settings, you can cause FileZilla to behave strangely. For example, choosing a VMS server type and configuring FTP7 to use MS-DOS directory listings will not work, but then again - I wouldn't expect that to work. ;-]&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9232275/original.aspx"&gt;&lt;/P&gt;
&lt;H3&gt;Scorecard for FileZilla&lt;/H3&gt;
&lt;P&gt;So - that concludes our quick round-trip for some of FileZilla's features, and here's the scorecard results:&lt;/P&gt;
&lt;TABLE class="" 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;&lt;A href="http://filezilla-project.org/" target=_blank&gt;FileZilla 3.1.6&lt;/A&gt;&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;N&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: As with all of the FTP clients in this blog series, there are a great number of additional features that FileZilla provides - I'm just keeping the focus on a few specific topic areas that apply to FTP7.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9232415" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>FTP Clients - Part 3: Creating a Global Listener FTP Site</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2008/12/17/ftp-clients-part-3-creating-a-global-listener-ftp-site.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2008/12/17/ftp-clients-part-3-creating-a-global-listener-ftp-site.aspx</id><published>2008-12-17T22:02:00Z</published><updated>2008-12-17T22:02:00Z</updated><content type="html">&lt;P&gt;In my "&lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2008/09/24/ftp-clients-part-1-web-browser-support.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2008/09/24/ftp-clients-part-1-web-browser-support.aspx"&gt;FTP Clients - Part 1: Web Browser Support&lt;/A&gt;" blog post, I mentioned creating a secured Global Listener FTP Site when you're working with FTP virtual hosts, but I didn't really explain what I meant by that or why you would want to do this. With that in mind, today's blog post is to describe how and why you might want to create a Global Listener FTP Site.&lt;/P&gt;
&lt;P&gt;To start things off, the concept is really simple - a Global Listener FTP Site is an FTP site with no virtual host binding and anonymous access disabled. It's kind of like having a "Default FTP Site" with restricted access. Here's why this is a good idea when you're working with FTP virtual hosts - some clients default to anonymous, like web browsers, and if anonymous succeeds then the FTP client doesn't have the opportunity to enter the FTP virtual host name, so you can't get to the virtual host site.&lt;/P&gt;
&lt;P&gt;To refresh everyone's memory, there are two different methods for binding multiple FTP host names to IP addresses in FTP7:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;B&gt;FTP Virtual Host Names&lt;/B&gt; - This uses the "&lt;I&gt;ftp.example.com|username&lt;/I&gt;" syntax as part of the client login in order to route FTP requests to the correct FTP site. This syntax is compatible with FTP almost every FTP clients, and should be thought of as a backwards-compatible method for binding multiple FTP host names to a single IP address.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;FTP True Host Names&lt;/B&gt; - This uses the FTP HOST command, which is still only an IETF draft at the moment. In the future this may be the way that FTP clients and servers automatically communicate with each other, like the "Host: www.example.com" header does for HTTP, but that may still have a few years at the very least.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Unless your FTP client allows sending custom FTP commands, you won't be able to use FTP True Host Names, so if you want to host several FTP sites on the same IP address then your only option is to use FTP Virtual Host Names. The trouble is, as I mentioned earlier, that some FTP clients (like web browsers) try to log in using anonymous first. If all of your FTP sites are bound to a virtual host name, the FTP client will get a "550-No such host is known" error from the FTP server, because the anonymous user did not specify a virtual host name as part of the USER command. On some clients you could fix that by specifying "&lt;I&gt;ftp.example.com|anonymous&lt;/I&gt;" as your anonymous user name, but in most cases the login attempt will just fail.&lt;/P&gt;
&lt;P&gt;If you create an FTP site that has no virtual host name, then the FTP service will have some place to send these default anonymous requests. When this FTP site does not have anonymous access enabled, the client will be prompted for their username, which will allow you to enter the "&lt;I&gt;ftp.example.com|username&lt;/I&gt;" syntax to specify the virtual host name.&lt;/P&gt;
&lt;P&gt;Please note that creating a Global Listener FTP site is really more of a workaround for the way that some FTP clients behave - it's certainly not required, and it only applies to situations where you are using FTP Virtual Host Names. For example, if you are using user isolation to restrict users to specific paths on a single FTP site, the Global Listener FTP site would be completely unnecessary.&lt;/P&gt;
&lt;H4&gt;More Information&lt;/H4&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: See my &lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2007/08/28/virtual-hosts-and-host-names-in-ftp7.aspx" target=_blank&gt;Virtual Hosts and Host Names in FTP7&lt;/A&gt; blog post for more information about FTP Virtual Host Names and FTP True Host Names, and see &lt;A href="https://datatracker.ietf.org/drafts/draft-hethmon-mcmurray-ftp-hosts/"&gt;https://datatracker.ietf.org/drafts/draft-hethmon-mcmurray-ftp-hosts/&lt;/A&gt; for more information about status of the FTP HOST command.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9231929" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>FTP Clients - Part 2: Explicit FTPS versus Implicit FTPS</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2008/11/10/ftp-clients-part-2-explicit-ftps-versus-implicit-ftps.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2008/11/10/ftp-clients-part-2-explicit-ftps-versus-implicit-ftps.aspx</id><published>2008-11-10T17:46:00Z</published><updated>2008-11-10T17:46:00Z</updated><content type="html">&lt;P&gt;In part 2 of my series on FTP clients, I thought it would be best to have a discussion about the differences between &lt;I&gt;Implicit FTPS&lt;/I&gt; and &lt;I&gt;Explicit FTPS&lt;/I&gt;. In my recent "&lt;A href="http://blogs.msdn.com/robert_mcmurray/archive/2008/09/24/ftp-clients-part-1-web-browser-support.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2008/09/24/ftp-clients-part-1-web-browser-support.aspx"&gt;FTP Clients - Part 1: Web Browser Support&lt;/A&gt;" blog post, I referenced Implicit and Explicit FTPS with a link to my &lt;A href="http://go.microsoft.com/fwlink/?LinkId=89117" target=_blank mce_href="http://go.microsoft.com/fwlink/?LinkId=89117"&gt;Using FTP Over SSL&lt;/A&gt; walkthrough. But it occurred to me that some people may not understand the difference between the two, and my upcoming blog posts are going to build upon that knowledge, so I thought that a quick discussion of these two technologies would be prudent.&lt;/P&gt;
&lt;H3&gt;FTP over SSL (FTPS)&lt;/H3&gt;
&lt;P&gt;One of the many limitations of the File Transfer Protocol (FTP) is a general lack of security; e.g. user names and passwords are transmitted in clear text, data is transferred with no encryption, etc. In order to address this situation, FTP over SSL (FTPS) was introduced in Requests for Comments (RFC) article &lt;A href="http://www.ietf.org/rfc/rfc2228.txt" target=_blank mce_href="http://www.ietf.org/rfc/rfc2228.txt"&gt;2228 - &lt;I&gt;FTP Security Extensions&lt;/I&gt;&lt;/A&gt;, and expanded in RFC &lt;A href="http://www.ietf.org/rfc/rfc4217.txt" target=_blank mce_href="http://www.ietf.org/rfc/rfc4217.txt"&gt;4217 - &lt;I&gt;Securing FTP with TLS&lt;/I&gt;&lt;/A&gt; to address Transport Layer Security (TLS).&lt;/P&gt;
&lt;P&gt;Following up on these RFC articles, the &lt;A href="http://go.microsoft.com/fwlink/?LinkId=87847" target=_blank mce_href="http://go.microsoft.com/fwlink/?LinkId=87847"&gt;FTP service for Windows Server 2008&lt;/A&gt; added support for FTPS, and the FTP SSL Settings Feature in the IIS Manager allows you to configure your FTPS settings to allow or require SSL, enforce 128-bit SSL, or customize your control/data channel SSL settings.&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="FTP SSL Settings" src="http://learn.iis.net/file.axd?i=418" mce_src="http://learn.iis.net/file.axd?i=418"&gt;&lt;/P&gt;
&lt;H3&gt;Explicit FTPS&lt;/H3&gt;
&lt;P&gt;Explicit FTPS is really what RFCs 2228 and 4217 envisioned; basically the way this works is an FTP client connects over the control/command channel (usually on port 21), and then the client can negotiate SSL for either the command/control channel or the data channel using new FTP commands like AUTH, PROT, CCC, etc.&lt;/P&gt;
&lt;P&gt;The FTP service for Windows Server 2008 allows customized settings for both the command/control channel and the data channel through the Advanced SSL Policy dialog:&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="Advanced SSL Policy" src="http://learn.iis.net/file.axd?i=417" mce_src="http://learn.iis.net/file.axd?i=417"&gt;&lt;/P&gt;
&lt;P&gt;There are several ways that Explicit FTPS might be implemented depending on your business needs:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #000000; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #ffffff" cellSpacing=1 cellPadding=3 width="90%" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="" style="COLOR: #ffffff; BACKGROUND-COLOR: #000000" vAlign=top noWrap align=left&gt;Control Channel&lt;/TH&gt;
&lt;TH class="" style="COLOR: #ffffff; BACKGROUND-COLOR: #000000" vAlign=top noWrap align=left&gt;Data Channel&lt;/TH&gt;
&lt;TH class="" style="COLOR: #ffffff; BACKGROUND-COLOR: #000000" vAlign=top noWrap align=left&gt;Notes&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Allow&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Allow&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;This configuration allows the client to decide whether any part of the FTP session should be encrypted.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Require only&lt;BR&gt;for credentials&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Allow&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;This configuration protects your FTP client credentials from electronic eavesdropping, and allows the client to decide whether data transfers should be encrypted.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Require only&lt;BR&gt;for credentials&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Require&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;This configuration requires that the client's credentials must be secure, and then allows the client to decide whether FTP commands should be encrypted. However, all data transfers must be encrypted.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Require&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Require&lt;/B&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;This configuration is the most secure - the client must negotiate SSL using the FTPS-related commands before other FTP commands are allowed, and all data transfers must be encrypted.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Implicit FTPS&lt;/H3&gt;
&lt;P&gt;Implicit FTPS takes SSL one step further than simply requiring that SSL-related commands must be sent first like you can with Explicit SSL; with Implicit FTPS, an SSL handshake must be negotiated before &lt;I&gt;any&lt;/I&gt; FTP commands can be sent by the client. In addition, even though Explicit FTPS allows the client to arbitrarily decide whether to use SSL, Implicit FTPS requires that the entire FTP session must be encrypted. Basically the way that Implicit FTPS works is that an FTP client connects to the command/control channel, in this case using port 990, and immediately performs an SSL handshake; after SSL has been negotiated, additional FTP commands for the session can be sent by the FTP client.&lt;/P&gt;
&lt;P&gt;Using FTPS in &lt;A href="http://go.microsoft.com/fwlink/?LinkId=87847" target=_blank mce_href="http://go.microsoft.com/fwlink/?LinkId=87847"&gt;FTP service for Windows Server 2008&lt;/A&gt; follows the Internet Assigned Numbers Authority (IANA) specification that the Implicit FTPS command/control channel is on port 990 and the Implicit FTPS data channel is on port 989.&lt;/P&gt;
&lt;H3&gt;Using FTPS in Windows Server 2008&lt;/H3&gt;
&lt;P&gt;Here's the way that you specify which type of FTP over SSL (FTPS) that you are using in Windows Server 2008:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If you enable FTPS and you assign the FTP site to the default port of 21, you are using &lt;I&gt;&lt;B&gt;Explicit SSL&lt;/B&gt;&lt;/I&gt;.&lt;/LI&gt;
&lt;LI&gt;If you enable FTPS and you assign the FTP site to port 990, you are using &lt;I&gt;&lt;B&gt;Implicit SSL&lt;/B&gt;&lt;/I&gt;.&lt;/LI&gt;
&lt;LI&gt;In point of fact, if you enable FTPS and you assign the FTP site to any port other than port 990, you are always using &lt;I&gt;&lt;B&gt;Explicit SSL&lt;/B&gt;&lt;/I&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;B&gt;Note&lt;/B&gt;: If you are using FTP on any ports other than the defaults of 21/20 and 990/989, you &lt;U&gt;must make sure&lt;/U&gt; that those ports are not already assigned by IANA to another protocol. For more information, see the &lt;A href="http://www.iana.org/assignments/port-numbers" target=_blank mce_href="http://www.iana.org/assignments/port-numbers"&gt;list of assigned port numbers on IANA's web site&lt;/A&gt;.&lt;/P&gt;
&lt;H3&gt;Parting Thoughts&lt;/H3&gt;
&lt;P&gt;Choosing whether to use Explicit FTPS over Implicit FTPS is a personal choice, and generally this choice may depend on your business needs or your FTP client. In several FTP clients that I've tested, the FTP client chooses one form of FTPS over another as the default method, and the FTP client may require some manual configuration to use the other.&lt;/P&gt;
&lt;P&gt;Shortly after shipping the FTP service for Windows Server 2008 we discovered an issue where the FTP service was not cleaning up Implicit SSL connections properly, and we issued a hotfix rollup package for the FTP service that is discussed in &lt;A href="http://support.microsoft.com/kb/955136" target=_blank mce_href="http://support.microsoft.com/kb/955136"&gt;Microsoft Knowledge Base article 955136&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;I hope this helps to clear things up a bit. ;-]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9058628" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>Using Visual Studio 2008 on a 64-bit Computer to edit ApplicationHost.config</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2008/10/27/using-visual-studio-2008-on-a-64-bit-computer-to-edit-applicationhost-config.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2008/10/27/using-visual-studio-2008-on-a-64-bit-computer-to-edit-applicationhost-config.aspx</id><published>2008-10-28T00:49:00Z</published><updated>2008-10-28T00:49:00Z</updated><content type="html">&lt;H3&gt;Visual Studio 2008 as an XML Editor&lt;/H3&gt;
&lt;P&gt;Everyone seems to have their own favorite XML editor these days, and there are no shortages of XML editors in the marketplace. The being said, I tend to use Visual Studio 2008 for several reasons, and if you're using Windows notepad or some other editor, here are some of my reasons why you might consider switching:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;I've already bought a copy of Visual Studio for application development, so I don't need to purchase another utility. &lt;/LI&gt;
&lt;LI&gt;I'm already familiar with the Visual Studio interface and features, so I don't need to learn another user interface. &lt;/LI&gt;
&lt;LI&gt;Syntactical highlighting - Visual Studio makes it easy to see your XML in a user-friendly set of colors. If you already use Visual Studio for application development, then you're simply sticking to a paradigm that you're already familiar with. &lt;/LI&gt;
&lt;LI&gt;Auto-completion - as I create XML elements in Visual Studio I get all of the auto-completion features that you'd expect from an XML editor, which speeds up my configuration editing. &lt;/LI&gt;
&lt;LI&gt;Simple validation - Visual Studio lets me know when elements become mismatched or sections are not closed properly. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;But one of my personal favorites is &lt;STRONG&gt;&lt;EM&gt;change notifications&lt;/EM&gt;&lt;/STRONG&gt;. These are great, because I do some of my work in ApplicationHost.config directly, while other times I'm using AppCmd.exe or the IIS Manager to update my settings. If I leave Visual Studio open, it detects that the configuration file was changed externally and prompts me to reload.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/photos/robert_mcmurray/images/9019508/original.aspx" mce_src="http://blogs.msdn.com/photos/robert_mcmurray/images/9019508/original.aspx"&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This feature alone has probably saved me more times that I can imagine. &lt;IMG height=19 src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif" width=19 mce_src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;&lt;/P&gt;
&lt;H3&gt;The 32-bit Versus 64-bit Problem&lt;/H3&gt;
&lt;P&gt;All of the above information leads me to an interesting challenge - what do you do if you have Visual Studio 2008 installed on a 64-bit system? Visual Studio is a 32-bit application, and it runs just fine on a 64-bit system, but unfortunately 32-bit applications cannot open files that are kept in 64-bit-only file paths - and that includes ApplicationHost.config.&lt;/P&gt;
&lt;P&gt;Here's why this happens - ApplicationHost.config is physically located in the following 64-bit-only path:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;B&gt;&lt;CODE&gt;%SystemDrive%\Windows\System32\Inetsrv\config&lt;/CODE&gt;&lt;/B&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The problem is, 32-bit applications are "magically" redirected by the operating system to the following 32-bit file path:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;B&gt;&lt;CODE&gt;%SystemDrive%\Windows\SysWOW64\Inetsrv\config&lt;/CODE&gt;&lt;/B&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So what happens is that each 32-bit application &lt;EM&gt;thinks&lt;/EM&gt; that it's in the real System32 folder, so when you try to open ApplicationHost.config using &lt;B&gt;File » Open » File...&lt;/B&gt; in Visual Studio, you don't see ApplicationHost.config in the Inetsrv folder. If you attempt to outsmart the system by dragging-and-dropping ApplicationHost.config into Visual Studio from Windows Explorer it doesn't work; you don't get any errors, Visual Studio just sits there and stares back at you. &lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/angry_smile.gif" mce_src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/angry_smile.gif"&gt;&lt;/P&gt;
&lt;H3&gt;NTFS Symbolic Links to the Rescue&lt;/H3&gt;
&lt;P&gt;NTFS has had junction points around for some time now, but NTFS has added symbolic links starting with Windows Vista and Windows Server 2008. These are not Windows shortcuts - symbolic links appear to applications as actual files and folders. The great thing is - you can create a symbolic link from a 32-bit-only path to a 64-bit only-path, which is how you can get around the problem and use Visual Studio to edit ApplicationHost.config directly on a 64-bit system.&lt;/P&gt;
&lt;P&gt;The command that makes this possible is MKLINK, and if you enter that command at a command prompt you get the following help information:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;mklink /?
Creates a symbolic link.

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      Creates a directory symbolic link.  Default is a file
                symbolic link.
        /H      Creates a hard link instead of a symbolic link.
        /J      Creates a Directory Junction.
        Link    specifies the new symbolic link name.
        Target  specifies the path (relative or absolute) that the new link
                refers to.
CMD&amp;gt;&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Here's how you use this command on a 64-bit system:&lt;/P&gt;
&lt;P&gt;First of all, you need to open a 64-bit command prompt, because the steps won't work from a 32-bit command prompt. An easy way to find out whether you have a 64-bit or 32-bit command prompt is to use the following command:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;set | find "PROCESSOR_ARCHITECTURE"&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If the above command returns "&lt;B&gt;&lt;CODE&gt;PROCESSOR_ARCHITECTURE=x86&lt;/CODE&gt;&lt;/B&gt;", then you're using a 32-bit command prompt and you will need to close the command prompt and open a 64-bit command prompt. If you see something like "&lt;B&gt;&lt;CODE&gt;PROCESSOR_ARCHITECTURE=AMD64&lt;/CODE&gt;&lt;/B&gt;" then you're using a 64-bit command prompt and everything should be fine.&lt;/P&gt;
&lt;P&gt;Once you have a 64-bit command prompt, type the following commands:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;cd /d "%SystemDrive%\Windows\SysWOW64\inetsrv"

CMD&amp;gt;move Config Config.OLD

CMD&amp;gt;mklink /d Config "%SystemDrive%\Windows\System32\inetsrv\Config"&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;These commands perform the following actions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Change the command prompt working directory to the 32-bit folder for IIS. &lt;/LI&gt;
&lt;LI&gt;Rename the existing (and typically empty) 32-bit IIS configuration folder. &lt;SUP&gt;(See note below.)&lt;/SUP&gt; &lt;/LI&gt;
&lt;LI&gt;Create a directory symbolic link that replaces the 32-bit IIS configuration folder and points to the 64-bit IIS configuration folder. &lt;SUP&gt;(See note below.)&lt;/SUP&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;B&gt;Important Note&lt;/B&gt;: Something that you should consider - if your 32-bit IIS configuration folder is &lt;B&gt;&lt;I&gt;not&lt;/I&gt;&lt;/B&gt; empty, you will need to find out what is in that folder and whether it needs to be copied to the 64-bit folder. For example, the FTP 7 service for IIS 7 adds a schema file to the 32-bit configuration path, but it's just a copy of the file that resides in the 64-bit path, so it does not need to be copied. If an application exists that requires different files for 64-bit and 32-bit operation, then you cannot use this workaround.&lt;/P&gt;
&lt;P&gt;Once you have completed the above commands, you can check your directory listing from a 64-bit command prompt to make sure that your symbolic link has been created; you should see something like the following:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="COLOR: #ffffff; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;PRE&gt;CMD&amp;gt;cd /d "%SystemDrive%\Windows\SysWOW64\inetsrv"

CMD&amp;gt;dir /ad

Volume in drive C has no label.
Volume Serial Number is 426F-624D

Directory of C:\Windows\SysWOW64\inetsrv

10/20/2008 03:52 PM &amp;lt;DIR&amp;gt; .
10/20/2008 03:52 PM &amp;lt;DIR&amp;gt; ..
10/20/2008 03:52 PM &amp;lt;SYMLINKD&amp;gt; Config [C:\Windows\System32\inetsrv\Config]
04/18/2008 04:24 PM &amp;lt;DIR&amp;gt; Config.OLD
04/18/2008 02:55 PM &amp;lt;DIR&amp;gt; en
04/18/2008 03:47 PM &amp;lt;DIR&amp;gt; en-US
              0 File(s) 0 bytes
              6 Dir(s) 51,247,341,568 bytes free

CMD&amp;gt;&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Notice the &lt;B&gt;&amp;lt;SYMLINKD&amp;gt;&lt;/B&gt; entry in the directory listing - this shows that a symbolic link was created, and the target path is indicated in the directory listing next to the name of the symbolic link.&lt;/P&gt;
&lt;P&gt;You can now open ApplicationHost.config in Visual Studio 2008 on your 64-bit system with no problems, and still have features like change notifications.&lt;/P&gt;
&lt;H3&gt;Closing Thoughts&lt;/H3&gt;
&lt;P&gt;If you look at the help output for Mklink, you'll notice that you can also create symbolic links for files, not just directories. This leads to the question: why didn't I just create a file symbolic link for ApplicationHost.config instead of the folder symbolic link for the entire Config directory? &lt;IMG height=19 src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/72_72.gif" width=19 mce_src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/72_72.gif"&gt;&lt;/P&gt;
&lt;P&gt;The answer goes back to one of my favorite features: &lt;B&gt;change notifications&lt;/B&gt;, which are implemented at the folder-level, not the file-level. So you can create a file symbolic link for ApplicationHost.config and that will allow you to open the file, but you won't receive any change notifications, so if you update your settings using AppCmd.exe or IIS Manager, Visual Studio will be unaware of any changes and the next time you save ApplicationHost.config from Visual Studio you will overwrite your changes that were made using AppCmd.exe or IIS Manager. Needless to say - this is a bad thing, so you should always use the directory symbolic link.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9019529" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /></entry><entry><title>AppCmd 80070057 errors when configuring site-level settings</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/robert_mcmurray/archive/2008/10/02/appcmd-80070057-errors-when-configuring-site-level-settings.aspx" /><id>http://blogs.msdn.com/robert_mcmurray/archive/2008/10/02/appcmd-80070057-errors-when-configuring-site-level-settings.aspx</id><published>2008-10-02T17:20:00Z</published><updated>2008-10-02T17:20:00Z</updated><content type="html">&lt;P&gt;I had an interesting question from a coworker who was trying to use AppCmd to set the site-level SSL options for an FTP site. This should have been straightforward, and the syntax that he gave me looked correct:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;CODE&gt;appcmd.exe set config -section:system.applicationHost/sites -[name='Default FTP Site'].ftpServer.security.ssl.controlChannelPolicy:SslAllow /commit:apphost&lt;/CODE&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;That being said, whenever he or I ran the command we received the following cryptic error from AppCmd:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;CODE&gt;Failed to process input: The parameter 'Site'].ftpServer.security.ssl.controlChannelPolicy='SslAllow'' must begin with a / or - (HRESULT=80070057).&lt;/CODE&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The HRESULT=80070057 code can mean either "One or more arguments are invalid" or "The parameter is incorrect", which seemed wrong to me because the arguments looked correct. Based on the error message referring to the word 'Site', I retried the command using the site ID instead of the site name:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;CODE&gt;appcmd.exe set config -section:system.applicationHost/sites -[id='4'].ftpServer.security.ssl.controlChannelPolicy:SslAllow /commit:apphost&lt;/CODE&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This worked as expected, so I knew that somehow the problem was with the site name.&lt;/P&gt;
&lt;P&gt;I searched around and I found a &lt;A href="http://forums.iis.net/p/1148529/1865859.aspx" target=_blank mce_href="http://forums.iis.net/p/1148529/1865859.aspx"&gt;forum post on IIS.NET&lt;/A&gt; where Anil Ruia had stated that when the site name has a space in it you should enclose the entire parameter statement in quotes. Armed with that knowledge, I tried the following command:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;CODE&gt;appcmd.exe set config -section:system.applicationHost/sites "-[name='Default FTP Site'].ftpServer.security.ssl.controlChannelPolicy:SslAllow" /commit:apphost&lt;/CODE&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This fixed the problem and the command worked as I would have originally expected.&lt;/P&gt;
&lt;P&gt;By the way, in general you should be able use the following command to get the FTP syntax listing for an area:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;CODE&gt;appcmd.exe set config -section:system.applicationHost/sites -? | find /i "ftp"&lt;/CODE&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This wouldn't have helped my coworker identify the problem with the "name" parameter, but it would have helped by giving him the syntax for using the "id" parameter.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8974001" width="1" height="1"&gt;</content><author><name>robert_mcmurray</name><uri>http://blogs.msdn.com/members/robert_mcmurray.aspx</uri></author><category term="IIS Topics" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx" /><category term="FTP" scheme="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry></feed>