<?xml version="1.0" encoding="euc-kr" ?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<title>¢É Rustican.com - ÇÁ·Î±×·¡¹Ö ¹®¼­</title>
<link>http://www.rustican.com/board/zboard.php?id=paper</link>
<description>Life has more Imagination than we carry out... ÇÁ·Î±×·¡¹Ö ¹®¼­</description>
<image><title>[Rustican.com]</title><url>http://www.rustican.com/image/title_rss.gif</url><link>http://www.rustican.com</link><width>209</width><height>89</height><description>[Rustican.com]</description></image><link rel="shortcut icon" href="http://www.rustican.com/image/favicon.ico"></link>
<language>ko-KO</language>
<lastBuildDate>Sep, 09 2010 05:53:44 GMT</lastBuildDate>
<webMaster>hyun@rustican.com</webMaster>
<item>
<title>¸Å½¬¾÷(Mashup) µµ±¸</title>
<link>http://www.rustican.com/board/zboard.php?id=paper&amp;no=255</link>
<description>&lt;H2&gt;&lt;FONT size=3&gt;Yahoo Pipe&lt;/FONT&gt;&lt;/H2&gt;
&lt;DIV class=post_body&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href=&quot;http://pipes.yahoo.com/pipes/&quot;&gt;http://pipes.yahoo.com/pipes/&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;¼³¸í : &lt;A class=external title=http://en.wikipedia.org/wiki/Yahoo_Pipes href=&quot;http://en.wikipedia.org/wiki/Yahoo_Pipes&quot;&gt;http://en.wikipedia.org/wiki/Yahoo_Pipes&lt;/A&gt; , &lt;A class=external title=http://radar.oreilly.com/archives/2007/02/pipes-and-filters-for-the-inte.html href=&quot;http://radar.oreilly.com/archives/2007/02/pipes-and-filters-for-the-inte.html&quot;&gt;Pipes and Filters for the Internet&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;¿¹Á¦&lt;br /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class=external title=http://pipes.yahoo.com/pipes/pipe.info?_id=vvW1cD212xGMiR9aqu5lkA href=&quot;http://pipes.yahoo.com/pipes/pipe.info?_id=vvW1cD212xGMiR9aqu5lkA&quot;&gt;&amp;nbsp;New York Times thru Flickr&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;»ç¿ë¹ý&lt;br /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class=external title=http://usefulvideo.blogspot.com/2007/02/yahoo-pipes-tutorials.html href=&quot;http://usefulvideo.blogspot.com/2007/02/yahoo-pipes-tutorials.html&quot;&gt;Yahoo! Pipes tutorials&lt;/A&gt; &lt;A class=external title=http://www.jumpcut.com/fullscreen?id=C086AA92568811DCAB02000423CF381C&amp;amp;amp;type=movie href=&quot;http://www.jumpcut.com/fullscreen?id=C086AA92568811DCAB02000423CF381C&amp;amp;type=movie&quot;&gt;How to Translate a Feed Using Pipes&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class=external title=http://www.jumpcut.com/fullscreen?id=594F555C568011DC9D24000423CEF5B0&amp;amp;amp;type=movie href=&quot;http://www.jumpcut.com/fullscreen?id=594F555C568011DC9D24000423CEF5B0&amp;amp;type=movie&quot;&gt;Learn How to Build a Pipe in Just a Few Minutes&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class=external title=http://alexeysmirnov.name/blog/?page_id=198 href=&quot;http://alexeysmirnov.name/blog/?page_id=198&quot;&gt;Alexey's Yahoo Pipes tutorial&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;MS Popfly&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href=&quot;http://www.popfly.com/&quot;&gt;http://www.popfly.com/&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;¼³¸í : &lt;A href=&quot;http://en.wikipedia.org/wiki/Popfly&quot;&gt;http://en.wikipedia.org/wiki/Popfly&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Silverlight ±â¼ú¿¡ ±â¹Ý&lt;/LI&gt;
&lt;LI&gt;½Ã¿¬µ¿¿µ»ó : &lt;A class=external title=http://www.youtube.com/watch?v=hkTdJAYb--M href=&quot;http://www.youtube.com/watch?v=hkTdJAYb--M&quot;&gt;Three Minut Mashup - Microsoft Popfly&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;IBM lotus mashup&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href=&quot;http://www.ibm.com/lotus/mashups&quot;&gt;http://www.ibm.com/lotus/mashups&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;2008³â Áß¹Ý¿¡ °ø°³ ¿¹Á¤&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Google Mashup Editor&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href=&quot;http://www.googlemashups.com/&quot;&gt;http://www.googlemashups.com/&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;¼³¸í : &lt;A href=&quot;http://en.wikipedia.org/wiki/Google_Mashup_Editor&quot;&gt;&lt;FONT color=#810081&gt;http://en.wikipedia.org/wiki/Google_Mashup_Editor&lt;/FONT&gt;&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Intel Mash maker&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href=&quot;http://mashmaker.intel.com/web/&quot;&gt;http://mashmaker.intel.com/web/&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;À¥ºê¶ó¿ìÀú¿¡ È®ÀåµÈ ±â´ÉÀ» Á¦°øÇÏ´Â Çü½Ä&lt;/LI&gt;
&lt;LI&gt;½Ã¿¬µ¿¿µ»ó : &lt;A href=&quot;http://blip.tv/file/get/Intel_SW-IntelMashMakerOverviewVideo814.wmv&quot;&gt;http://blip.tv/file/get/Intel_SW-IntelMashMakerOverviewVideo814.wmv&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/DIV&gt;</description>
<author>ÓÞíâÏÚ úÜ</author>
<pubDate>May, 13 2008 01:11:01 GMT</pubDate>
<category>App</category>
</item>
<item>
<title>SQL 2005 Äõ¸® Æ©´× ÀÚ·á</title>
<link>http://www.rustican.com/board/zboard.php?id=paper&amp;no=254</link>
<description>file link 1 : &lt;a href=http://www.rustican.com/board/data/paper/1024HOL.zip target=_blank&gt; 1024HOL.zip&lt;/a&gt;&lt;br&gt;1024HOL.zip ÆÄÀÏ&lt;BR&gt;¿¹Á¦ ½ºÅ©¸³Æ®&lt;BR&gt;Performance Dashboard ¼³Ä¡ ÆÄÀÏ&lt;BR&gt;DMVStats ¼³Ä¡ÆÄÀÏ&lt;BR&gt;ClearTrace ¼³Ä¡ÆÄÀÏ &lt;BR&gt;Âü°íÀÚ·á(Wait and Queue ¹ø¿ªº») </description>
<author>ÓÞíâÏÚ úÜ</author>
<pubDate>Apr, 23 2008 09:12:11 GMT</pubDate>
<category>db</category>
</item>
<item>
<title>Work Items and Undo Support</title>
<link>http://www.rustican.com/board/zboard.php?id=paper&amp;no=253</link>
<description>&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table2&quot;&gt;
			&lt;tr&gt;
				&lt;td class=&quot;clsDocBody&quot;&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table3&quot;&gt;
					&lt;tr&gt;
						&lt;td class=&quot;clsDeck&quot; bgColor=&quot;#ffffcc&quot; colSpan=&quot;2&quot; height=&quot;20&quot;&gt;
						&lt;b&gt;Work Items and Undo Support&lt;/b&gt;&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#ffffff&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#336699&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table4&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;*&quot;&gt;
						&lt;div class=&quot;pd&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;a title=&quot;More articles by this author&quot; href=&quot;http://msdn.microsoft.com/msdnmag/find/?type=Au&amp;phrase=Brian%20A.%20Randell&amp;words=exact&quot;&gt;
							Brian A. Randell&lt;/a&gt;&lt;/div&gt;
						&lt;/td&gt;
						&lt;td width=&quot;175&quot;&gt;
						&lt;div id=&quot;menu_parent&quot; style=&quot;CURSOR: pointer&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
							&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;3&quot; border=&quot;0&quot; id=&quot;table5&quot;&gt;
								&lt;tr vAlign=&quot;bottom&quot; align=&quot;middle&quot;&gt;
									&lt;td&gt;
									&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;print=true&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;
									&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/rss/rss.aspx?Sub=Team%20System&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a onclick=&quot;return false;&quot; href=&quot;#&quot;&gt;more &lt;br /&gt;
									...&lt;/a&gt;&lt;/td&gt;
								&lt;/tr&gt;
							&lt;/table&gt;
						&lt;/div&gt;
						&lt;div style=&quot;FLOAT: right; WIDTH: 175px&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;div id=&quot;menu_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 5px; Z-INDEX: 100; VISIBILITY: hidden; PADDING-BOTTOM: 5px; BORDER-LEFT: #999999 1px solid; WIDTH: 175px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; BACKGROUND-COLOR: white; align: right&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
								&lt;table cellSpacing=&quot;3&quot; cellPadding=&quot;2&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table6&quot;&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot; width=&quot;30&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot; width=&quot;140&quot;&gt;
										&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;print=true&quot;&gt;
										Print&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										E-mail&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Add to Favorites&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Rate&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Team%20System&quot;&gt;
										RSS (Team System) &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/addtoany.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://www.addtoany.com/?linkname=Team%20System&amp;type=rss&amp;linkurl=http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Team%20System&quot;&gt;
										Add RSS to Any &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/library.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Related Articles&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/spaces.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://spaces.live.com/blogit.aspx?Title=Team System:+Work Items and Undo Support&amp;Description=Add support for work items to the Team Foundation Server version control add-in.&amp;SourceURL=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&quot;&gt;
										Live Spaces &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/digg.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://digg.com/submit?phase=2&amp;url=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&amp;title=Team System:+Work Items and Undo Support&amp;bodytext=Add support for work items to the Team Foundation Server version control add-in.&amp;topic=programming                &quot;&gt;
										Digg This &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/blogger.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://new.blogger.com/blog_this.pyra?t=Add support for work items to the Team Foundation Server version control add-in.&amp;u=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&amp;n='Team System:+Work Items and Undo Support,'bloggerForm','scrollbars=no,width=475,height=300,top=175,left=75,status=yes,resizable=yes&quot;&gt;
										BlogThis! &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/slashdot.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://slashdot.org/bookmark.pl?url=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&amp;title=Team System:+Work Items and Undo Support&quot;&gt;
										Slashdot &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/delicious.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://del.icio.us/post?url=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&amp;title=Team System:+Work Items and Undo Support&quot;&gt;
										del.icio.us &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/technorati.png&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://technorati.com/faves?add=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&quot;&gt;
										Technorati &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&quot;&gt;
										Explore &lt;/a&gt;the code. &lt;br&gt;
										&lt;br&gt;
										&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TeamSystem2007_09.exe&quot;&gt;
										Download &lt;/a&gt;the code. &lt;/td&gt;
									&lt;/tr&gt;
								&lt;/table&gt;
							&lt;/div&gt;
						&lt;/div&gt;
&lt;SCRIPT type=text/javascript xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
      at_attach(&quot;menu_parent&quot;, &quot;menu_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
    &lt;/SCRIPT&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
				&lt;span id=&quot;dl_parent&quot; style=&quot;CURSOR: pointer&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
				&lt;a id=&quot;Code&quot; href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&quot;&gt;
				&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;Get &lt;br /&gt;
				the sample code for this article. &lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
				&lt;div id=&quot;dl_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 0px; Z-INDEX: 100; VISIBILITY: hidden; PADDING-BOTTOM: 0px; BORDER-LEFT: #999999 1px solid; WIDTH: 500px; PADDING-TOP: 0px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; BACKGROUND-COLOR: white&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
					&lt;table style=&quot;background-image: url('http://msdn.microsoft.com/msdnmag/images/codebg.gif')&quot; cellSpacing=&quot;0&quot; cellPadding=&quot;20&quot; width=&quot;500&quot; border=&quot;0&quot; id=&quot;table7&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;&lt;b&gt;NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&quot;&gt;
							Explore &lt;/a&gt;the sample code online! &lt;/b&gt;&lt;br&gt;
							&lt;br&gt;
							- or - &lt;br&gt;
							&lt;br&gt;
							&lt;b&gt;Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TeamSystem2007_09.exe&quot;&gt;
							TeamSystem2007_09.exe&lt;/a&gt; (197KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
&lt;SCRIPT type=text/javascript&gt;
    at_attach(&quot;dl_parent&quot;, &quot;dl_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
  &lt;/SCRIPT&gt;
				&lt;br&gt;
				&lt;br&gt;
¡¡&lt;hr&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table8&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;50%&quot;&gt;
						&lt;img class=&quot;clsImgButton&quot; id=&quot;contentbtn&quot; onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; height=&quot;9&quot; alt=&quot;&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/minus.gif&quot; width=&quot;9&quot; align=&quot;absMiddle&quot; vspace=&quot;2&quot;&gt;&lt;a onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; name=&quot;contents&quot; href=&quot;#void&quot;&gt;&lt;b&gt;Contents&lt;/b&gt;&lt;/a&gt;&lt;br&gt;
¡¡&lt;div id=&quot;contentmenu&quot; style=&quot;MARGIN-TOP: 10px; DISPLAY: block; MARGIN-LEFT: 20px&quot;&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S1&quot;&gt;Changes&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S2&quot;&gt;Work Item Support&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S3&quot;&gt;Returning Work Item &lt;br /&gt;
							Queries&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S4&quot;&gt;Updating the Check-In &lt;br /&gt;
							Dialog&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S5&quot;&gt;Final Details&lt;/a&gt;&lt;br&gt;
¡¡&lt;/div&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;hr&gt;&lt;br&gt;
¡¡&lt;div class=&quot;articletext&quot;&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM001&quot;&gt;¡¡&lt;/p&gt;
					&lt;div class=&quot;dropcap&quot;&gt;
						I&lt;/div&gt;
					n the January 2007 installment of this column (&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/01/TeamSystem&quot;&gt;msdn.microsoft.com/msdnmag/issues/07/01/TeamSystem&lt;/a&gt;), &lt;br /&gt;
					I described how to build a Microsoft&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;
					Word 2003 add-in to work with the Team Foundation Server &lt;br /&gt;
					version control subsystem. In the April 2007 column (&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/04/TeamSystem&quot;&gt;msdn.microsoft.com/msdnmag/issues/07/04/TeamSystem&lt;/a&gt;), &lt;br /&gt;
					I drilled down into the work item tracking subsystem. In &lt;br /&gt;
					this month's column, I'll describe how you can add support &lt;br /&gt;
					for work items to the add-in. In addition, you'll learn how &lt;br /&gt;
					to add a feature that should have been in the first version &lt;br /&gt;
					of the add-in&amp;#8212;undo support.&lt;br /&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Changes&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM002&quot;&gt;In the first column describing the &lt;br /&gt;
					add-in, I used the beta release of Microsoft Visual Studio&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;
					2005 Tools for the 2007 Microsoft Office system (Visual &lt;br /&gt;
					Studio 2005 Tools for Office Second Edition, or VSTO 2005 SE &lt;br /&gt;
					for short). Since that time, Microsoft has released the &lt;br /&gt;
					final version, which supports building application add-ins &lt;br /&gt;
					for both Office 2003 and the 2007 Office system. Thus, if &lt;br /&gt;
					you're working along with the article, you need to upgrade &lt;br /&gt;
					the first &amp;quot;release&amp;quot; of the add-in to the RTM version. To do &lt;br /&gt;
					this, simply open the solution and recompile on a machine &lt;br /&gt;
					with VSTO 2005 SE installed. Once you've verified the new &lt;br /&gt;
					version works, the next step is to add undo pending changes &lt;br /&gt;
					support. This feature requires you modify the tfsvcUtil &lt;br /&gt;
					class and the ThisAddin class.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM003&quot;&gt;In tfsvcUtil, add &lt;br /&gt;
					a new shared method UndoPendingChanges that accepts the full &lt;br /&gt;
					path to the document currently being modified, and have it &lt;br /&gt;
					return a Boolean. It turns out the core functionality of &lt;br /&gt;
					this new method mimics the existing CheckInDocument method. &lt;br /&gt;
					The method checks to ensure a valid connection has been made &lt;br /&gt;
					to the Team Foundation Server and that a valid workspace is &lt;br /&gt;
					loaded. Once this is accomplished, it gets an array of &lt;br /&gt;
					PendingChanges objects for the passed-in document. Assuming &lt;br /&gt;
					a pending change is returned, the Undo method of the user's &lt;br /&gt;
					workspace is called, passing in the PendingChanges array. &lt;br /&gt;
					This method should return an integer value of 1. If it does, &lt;br /&gt;
					the method returns true, otherwise a tfsUtilException is &lt;br /&gt;
					thrown using the newly defined MSG_UNDO_NOT_ZERO constant.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig1'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;fig=true#fig1&quot;&gt;
					Figure&amp;nbsp;1&lt;/a&gt; provides the full method listing.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM004&quot;&gt;The changes you &lt;br /&gt;
					need to make to the ThisAddIn class are pretty &lt;br /&gt;
					straightforward. As before, due to space restrictions, I &lt;br /&gt;
					won't go into any great detail on the Word add-in specific &lt;br /&gt;
					code (you can compare this column's download to the previous &lt;br /&gt;
					version to see the changes). Needless to say, you will have &lt;br /&gt;
					to modify the class to add a new Undo Pending Changes button &lt;br /&gt;
					to the toolbar, add a click handler for the new button, and &lt;br /&gt;
					add additional code to handle state changes to control &lt;br /&gt;
					whether the button is enabled. Basically, the Undo Pending &lt;br /&gt;
					Changes button's enabled state should mirror that of the &lt;br /&gt;
					existing Check-in button.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Work Item Support&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM005&quot;&gt;Adding support for associating work &lt;br /&gt;
					items with a check-in requires three major sets of changes &lt;br /&gt;
					to take place. First, you need to modify the tfsvcUtil class &lt;br /&gt;
					to support connecting to the work item store. Second, you &lt;br /&gt;
					need to modify the CheckInDocument method to do the actual &lt;br /&gt;
					association of work items. Finally, you need to modify the &lt;br /&gt;
					existing frmCheckIn dialog to support listing work items for &lt;br /&gt;
					the user to select as part of check-in.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM006&quot;&gt;To program work &lt;br /&gt;
					items, you add a reference to the &lt;br /&gt;
					Microsoft.TeamFoundation.WorkItemTracking.Client.dll &lt;br /&gt;
					assembly from the TFSUtil project. As mentioned in earlier &lt;br /&gt;
					columns, Team Explorer installs its supporting assemblies in &lt;br /&gt;
					the Global Assembly Cache (GAC) by default. However, the &lt;br /&gt;
					installer does not register them to show up in the Visual &lt;br /&gt;
					Studio 2005 Add References dialog. You'll need to either &lt;br /&gt;
					modify your registry so the Add References dialog sees the &lt;br /&gt;
					assemblies or manually browse for the assemblies. You'll &lt;br /&gt;
					find the assemblies at %Program Files%Microsoft Visual &lt;br /&gt;
					Studio 8Common7IDEPrivateAssemblies.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM007&quot;&gt;Once you've added &lt;br /&gt;
					the reference, you need to modify the tfsvcUtil class and &lt;br /&gt;
					add an imports statement at the top of the source file as &lt;br /&gt;
					follows:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM008&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Imports Microsoft.TeamFoundation.WorkItemTracking.Client&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM009&quot;&gt;
					Currently when the add-in connects to the Team Foundation &lt;br /&gt;
					Server box, it only connects to the version control service. &lt;br /&gt;
					You could modify the existing connect method to also connect &lt;br /&gt;
					to the work item store. However, there might be times when &lt;br /&gt;
					the user of the add-in is not going to associate work items, &lt;br /&gt;
					and thus this would add unnecessary overhead to the connect &lt;br /&gt;
					method. Instead, you'll add a new method that is called &lt;br /&gt;
					separately to connect to the work item store. You'll make &lt;br /&gt;
					this method public; however, most of the time existing &lt;br /&gt;
					methods will call the method before doing any work &lt;br /&gt;
					item-related operations. If the connection to the work item &lt;br /&gt;
					store is already in place, then it effectively becomes a &lt;br /&gt;
					no-op.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM010&quot;&gt;You need to add a &lt;br /&gt;
					new shared method ConnectWIS to the tfsvcUtil class. This &lt;br /&gt;
					method accepts no parameters and returns nothing. The method &lt;br /&gt;
					body is simple. First, it checks to make sure a valid Team &lt;br /&gt;
					Foundation Server instance exists. If not, it throws an &lt;br /&gt;
					exception since the user needs to initiate the connection &lt;br /&gt;
					before this method is called. That said, you could modify &lt;br /&gt;
					the architecture of the add-in to support attempting to &lt;br /&gt;
					login to the user's default Team Foundation Server &lt;br /&gt;
					installation. If the server is available, a connection is &lt;br /&gt;
					made to the work item store using the GetServiceMethod of &lt;br /&gt;
					the m_tfs instance, typed as a TeamFoundationServer object:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM011&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Public Shared Sub ConnectWIS()&lt;br /&gt;
  If Not m_tfs Is Nothing Then&lt;br /&gt;
    If tfsvcUtil.m_tfsWIS Is Nothing Then&lt;br /&gt;
      tfsvcUtil.m_tfsWIS = CType( _&lt;br /&gt;
        m_tfs.GetService(GetType(WorkItemStore)), WorkItemStore)&lt;br /&gt;
    End If&lt;br /&gt;
  Else&lt;br /&gt;
    Throw New tfsUtilException(MSG_SERVER_NOT_VALIDATED)&lt;br /&gt;
  End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM012&quot;&gt;You'll note the &lt;br /&gt;
					work item store reference is cached in a class-level &lt;br /&gt;
					variable m_tfsWIS, typed as a WorkItemStore object. You'll &lt;br /&gt;
					need to add this variable to the class like this:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM013&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Private Shared m_tfsWIS As WorkItemStore = Nothing&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM014&quot;&gt;
					Once you've done this, you need to create an overloaded &lt;br /&gt;
					version of the CheckInDocument method so that it matches the &lt;br /&gt;
					existing version with an additional input parameter that &lt;br /&gt;
					accepts an array of WorkItemCheckinInfo instances. Next, cut &lt;br /&gt;
					the body from the existing method and paste it into your new &lt;br /&gt;
					method. Modify the original method so that it calls the new &lt;br /&gt;
					version, passing Nothing for the WorkItemCheckinInfo array. &lt;br /&gt;
					The modified version is now one line of code:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM015&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Return tfsvcUtil.CheckInDocument(docPath, comment, Nothing)&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM016&quot;&gt;Now you need to &lt;br /&gt;
					modify the code in CheckInDocument to see if any &lt;br /&gt;
					WorkItemCheckinInfo objects were passed into the method. If &lt;br /&gt;
					this is the case, the code calls the ConnectWIS method to &lt;br /&gt;
					ensure a connection to the work item store has been made. &lt;br /&gt;
					Once you've done that, you call the overloaded version of &lt;br /&gt;
					CheckIn that accepts an array of WorkItemCheckinInfo &lt;br /&gt;
					instances, passing Nothing for check-in notes and policy &lt;br /&gt;
					overrides.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig2'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;fig=true#fig2&quot;&gt;
					Figure&amp;nbsp;2&lt;/a&gt; provides the complete listing.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Returning Work Item Queries&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM017&quot;&gt;At this point, you've added work &lt;br /&gt;
					item association support to the check-in process. However, &lt;br /&gt;
					you need to enhance the tfsvcUtil class to support returning &lt;br /&gt;
					a list of work item queries for the current Team Project. In &lt;br /&gt;
					addition, you'll need a method that runs a query and returns &lt;br /&gt;
					the work items to the caller so that they can be displayed &lt;br /&gt;
					to the user as part of the integrated check-in experience.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM018&quot;&gt;To do this, add &lt;br /&gt;
					two methods. The first method, GetWIQ, returns a &lt;br /&gt;
					StoredQueriesCollection. The second method, RunWIQ, accepts &lt;br /&gt;
					a query name as string parameter and returns a &lt;br /&gt;
					WorkItemsCollection object. I detailed how to do this in the &lt;br /&gt;
					April 2007 edition of this column (&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/04/TeamSystem&quot;&gt;msdn.microsoft.com/msdnmag/issues/07/04/TeamSystem&lt;/a&gt;).&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt; provides the code you need.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Updating the Check-In Dialog&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM019&quot;&gt;Now that you've got the main code &lt;br /&gt;
					written to handle associating work items at check-in, you &lt;br /&gt;
					need to modify the existing check-in dialog to support work &lt;br /&gt;
					item association. Start by making the existing form larger, &lt;br /&gt;
					adjusting the size property to something like 640¡¿480 to &lt;br /&gt;
					give you room to adjust the layout. Next, add a panel &lt;br /&gt;
					control to the form and name it pnlComments. Then cut the &lt;br /&gt;
					existing textbox txtComment from the form and paste it into &lt;br /&gt;
					the new panel, setting the Dock property to Fill. You'll &lt;br /&gt;
					need to re-add a handles clause to the &lt;br /&gt;
					txtComment_TextChanged event handler because, when you cut &lt;br /&gt;
					the textbox, the existing clause is removed.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM020&quot;&gt;You'll need a &lt;br /&gt;
					GroupBox control called grpOptions added to the form on the &lt;br /&gt;
					left. Add two RadioButton controls into the group box and &lt;br /&gt;
					name them rdoComments and rdoWorkItems. Change their &lt;br /&gt;
					AutoSize property to False and their Appearance property to &lt;br /&gt;
					Button. Set the rdoComments radio button's Checked property &lt;br /&gt;
					to True. Finally, rearrange the form so that it resembles&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;4&lt;/span&gt;.&lt;/p&gt;
					&lt;div id=&quot;259605002&quot; style=&quot;DISPLAY: none; WIDTH: 605px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('259605002', '171400002');&quot;&gt;
						&lt;img height=&quot;259&quot; alt=&quot;Figure 4 Modified Check-In Dialog with Comments Page&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/fig04_L.gif&quot; width=&quot;605&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 4&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Modified &lt;br /&gt;
						Check-In Dialog with Comments Page (Click the image for &lt;br /&gt;
						a smaller view) &lt;/span&gt;&lt;/div&gt;
					&lt;div id=&quot;171400002&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 400px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('171400002', '259605002');&quot;&gt;
						&lt;img height=&quot;171&quot; alt=&quot;Figure 4 Modified Check-In Dialog with Comments Page&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/fig04.gif&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 4&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Modified &lt;br /&gt;
						Check-In Dialog with Comments Page (Click the image for &lt;br /&gt;
						a larger view) &lt;/span&gt;&lt;/div&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM021&quot;&gt;With the basic UI &lt;br /&gt;
					changes in place, you need to add support for showing work &lt;br /&gt;
					items in a grid when the Work Items toggle button is &lt;br /&gt;
					clicked. Add a panel control to the form called &lt;br /&gt;
					pnlWorkItems. Inside that panel, add two panels: pnlSQCombo &lt;br /&gt;
					and pnlGridHolder. Set pnlSQCombo's Dock property to Top and &lt;br /&gt;
					pnlGridHolder's to Fill. You then need to add a label and a &lt;br /&gt;
					combobox control to pnlSQCombo and a DataGridView control to &lt;br /&gt;
					pnlGridHolder. Name the combobox cboStoredQueries and the &lt;br /&gt;
					grid dgvWorkItems. Dock the grid within the panel control &lt;br /&gt;
					using the smart tag. Adjust the size and location of &lt;br /&gt;
					pnlWorkItems to match pnlComments and set its Visible &lt;br /&gt;
					property to False.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM022&quot;&gt;When the user &lt;br /&gt;
					clicks the Work Items toggle button, the click event handler &lt;br /&gt;
					will perform the work necessary to make the work items &lt;br /&gt;
					available. There's no point in adding the extra overhead to &lt;br /&gt;
					the form load time unless you know you'll always want work &lt;br /&gt;
					items associated with a document check-in. There's quite a &lt;br /&gt;
					bit of code that makes things happen, much of which is &lt;br /&gt;
					generic Windows&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt; Forms code &lt;br /&gt;
					necessary to set the UI correctly.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM023&quot;&gt;The order of &lt;br /&gt;
					operations when the Work Items toggle button is clicked is &lt;br /&gt;
					as follows: load the check-in action combobox data sources, &lt;br /&gt;
					define the grid's columns, load the stored queries, and then &lt;br /&gt;
					run the My Work Items query, binding the results of the &lt;br /&gt;
					query to the grid control.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig5'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;fig=true#fig5&quot;&gt;
					Figure&amp;nbsp;5&lt;/a&gt; lists the code that gets called when the user &lt;br /&gt;
					clicks the Work Items toggle button.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM024&quot;&gt;The &lt;br /&gt;
					rdoWorkItems_Click event handler calls a number of &lt;br /&gt;
					supporting procedures to do its work. &lt;br /&gt;
					LoadCheckInActionComboBox initializes the data sources for &lt;br /&gt;
					the check-in action combobox that will appear in the grid. &lt;br /&gt;
					If you examine the Microsoft check-in dialog, you'll note &lt;br /&gt;
					that, depending upon the type of work item being selected, &lt;br /&gt;
					the check-in action combobox will either show only the word &lt;br /&gt;
					Associate or it will show Associate and Resolve. Mimicking &lt;br /&gt;
					this behavior requires a bit of behind-the-scenes work in &lt;br /&gt;
					the form.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM025&quot;&gt;In order to make &lt;br /&gt;
					this work, your first step is to define two class-level &lt;br /&gt;
					arrays:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM026&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Private listAssociate(0) As String&lt;br /&gt;
Private listAssociateResolve(1) As String&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM027&quot;&gt;
					The next thing you'll do is swap the check-in action &lt;br /&gt;
					combobox's data source between these two arrays depending &lt;br /&gt;
					upon the type of work item selected. &lt;br /&gt;
					LoadCheckInActionComboBox loads the string values into the &lt;br /&gt;
					arrays.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM028&quot;&gt;The event handler &lt;br /&gt;
					then runs DefineWorkItemGrid to initialize the grid control. &lt;br /&gt;
					This method adds an unbound checkbox control, four &lt;br /&gt;
					data-bound text columns (Work Item Type, Work Item ID, &lt;br /&gt;
					Title, and State), and an unbound combobox control for the &lt;br /&gt;
					check-in action. Next, rdoWorkItems_Click calls &lt;br /&gt;
					LoadStoredQueries. This method calls the GetStoredQueries &lt;br /&gt;
					method you created earlier. It then data binds the results &lt;br /&gt;
					to the cboStoredQueries combobox control.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM029&quot;&gt;Back in the &lt;br /&gt;
					rdoWorkItems_Click method, the code walks the list of stored &lt;br /&gt;
					queries until it finds the My Work Items query. Once it &lt;br /&gt;
					finds this, the code sets that to be the currently selected &lt;br /&gt;
					query in the cboStoredQueries combobox control. Then the &lt;br /&gt;
					method executes LoadGridData, which retrieves the work items &lt;br /&gt;
					returned by the My Work Items query and binds the results to &lt;br /&gt;
					the grid. Finally, rdoWorkItems_Click hides the comments &lt;br /&gt;
					panel and shows the work items panel.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM030&quot;&gt;To make the grid &lt;br /&gt;
					work in a similar fashion to the Microsoft version, you need &lt;br /&gt;
					to write event handlers for two grid-related events. The &lt;br /&gt;
					first event is the CellFormatting. One of the columns &lt;br /&gt;
					displayed by the grid is the Type property from the WorkItem &lt;br /&gt;
					object. This property is typed as WorkItemType object. You &lt;br /&gt;
					want to display the Name property of this object in the &lt;br /&gt;
					grid. Unfortunately, when the ToString method is executed, &lt;br /&gt;
					the object returns its fully qualified type name, not its &lt;br /&gt;
					Name property. To display the Name property, you need to &lt;br /&gt;
					change the cell's value in the CellFormatting event handler. &lt;br /&gt;
					This code checks to see whether the column to format is the &lt;br /&gt;
					Work Item Type column:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM031&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Private Sub dgvWorkItems_CellFormatting(ByVal sender As Object, _&lt;br /&gt;
  ByVal e As DataGridViewCellFormattingEventArgs) _&lt;br /&gt;
  Handles dgvWorkItems.CellFormatting&lt;br /&gt;

  If e.ColumnIndex = typeColumnIndex Then&lt;br /&gt;
    If e.Value IsNot Nothing Then&lt;br /&gt;
      Dim wit As WorkItemType = CType(e.Value, WorkItemType)&lt;br /&gt;
      e.Value = wit.Name&lt;br /&gt;
      e.FormattingApplied = True&lt;br /&gt;
    End If&lt;br /&gt;
  End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM032&quot;&gt;
					If it is and the cell's value is not null, the code &lt;br /&gt;
					retrieves the WorkItemType instance from the cell and &lt;br /&gt;
					changes the value of the cell to the value of the Name &lt;br /&gt;
					property.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM033&quot;&gt;Next, you need to &lt;br /&gt;
					implement an event handler for the &lt;br /&gt;
					Current-CellDirtyStateChanged event. In this handler you're &lt;br /&gt;
					changing the data source of the check-in action combobox &lt;br /&gt;
					based upon the type of work item selected. Write the code so &lt;br /&gt;
					that it only executes when the checkbox column's state is &lt;br /&gt;
					changed.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM034&quot;&gt;To know what the &lt;br /&gt;
					data source should be, you need to access the WorkItem &lt;br /&gt;
					object that is bound to the current row. Once you have it, &lt;br /&gt;
					you call its GetNextState method passing in a string value &lt;br /&gt;
					of Microsoft.VSTS.Actions.Checkin. The code is checking to &lt;br /&gt;
					see if there's a valid state transition from a check-in. If &lt;br /&gt;
					there is, the code receives a valid string back that tells &lt;br /&gt;
					it that the combobox should display both Associate and &lt;br /&gt;
					Resolve. If a valid string is not retrieved, then only &lt;br /&gt;
					Associate should be available. In this way, the code sets &lt;br /&gt;
					the correct data source and then commits the current edit, &lt;br /&gt;
					changing the state of the checkbox.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM035&quot;&gt;The code then &lt;br /&gt;
					checks the value of the checkbox and, if it has been set to &lt;br /&gt;
					checked (True), the check-in action combobox is enabled and &lt;br /&gt;
					made the active control, and an edit is started. If the &lt;br /&gt;
					checkbox is returning to an unchecked state, the code resets &lt;br /&gt;
					the combobox.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig6'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;fig=true#fig6&quot;&gt;
					Figure&amp;nbsp;6&lt;/a&gt; provides the details.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM036&quot;&gt;The last bit of &lt;br /&gt;
					code you need to add to process work items is developed by &lt;br /&gt;
					creating an array of WorkItemCheckinInfo objects in the &lt;br /&gt;
					FormClosing event (see&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig7'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx?loc=&amp;fig=true#fig7&quot;&gt;
					Figure&amp;nbsp;7&lt;/a&gt;). You create this array by walking the rows of &lt;br /&gt;
					the grid, creating a WorkItemCheckinInfo instance if the &lt;br /&gt;
					checkbox column is checked. When you create a &lt;br /&gt;
					WorkItemCheckinInfo instance, you specify the check-in &lt;br /&gt;
					action. In addition to this method, you need to add a public &lt;br /&gt;
					property, WorkItems, to the form so that the array can be &lt;br /&gt;
					retrieved once the dialog is closed. You set this property &lt;br /&gt;
					at the end of the FormClosing method.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Final Details&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM037&quot;&gt;You'll find some additional code in &lt;br /&gt;
					the form to handle the stored queries combobox's &lt;br /&gt;
					SelectedValueChanged event. The only thing left to do for &lt;br /&gt;
					the add-in to support work items is to modify the &lt;br /&gt;
					cbbCheckInDoc_Click method of the ThisAddIn class in the &lt;br /&gt;
					Word add-in. The modified version simply checks to see if &lt;br /&gt;
					the new WorkItems property of the dialog has data. If it &lt;br /&gt;
					does, the new version of the CheckInDocument method is &lt;br /&gt;
					called. Otherwise, the old version is executed.&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;8&lt;/span&gt; displays the completed check-in experience &lt;br /&gt;
					working with work items.&lt;/p&gt;
					&lt;div id=&quot;304689004&quot; style=&quot;DISPLAY: none; WIDTH: 689px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('304689004', '176400004');&quot;&gt;
						&lt;img height=&quot;304&quot; alt=&quot;Figure 8 Completed Check-In Dialog with Work Item Support&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/fig08_L.gif&quot; width=&quot;689&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 8&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Completed &lt;br /&gt;
						Check-In Dialog with Work Item Support (Click the image &lt;br /&gt;
						for a smaller view) &lt;/span&gt;&lt;/div&gt;
					&lt;div id=&quot;176400004&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 400px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('176400004', '304689004');&quot;&gt;
						&lt;img height=&quot;176&quot; alt=&quot;Figure 8 Completed Check-In Dialog with Work Item Support&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/fig08.gif&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 8&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Completed &lt;br /&gt;
						Check-In Dialog with Work Item Support (Click the image &lt;br /&gt;
						for a larger view) &lt;/span&gt;&lt;/div&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007TEAMSYSTEM038&quot;&gt;At this point, if &lt;br /&gt;
					you run the add-in, you can add a document to source &lt;br /&gt;
					control, check it in with comments and associate work items, &lt;br /&gt;
					check it out, and even undo pending changes. By this time, a &lt;br /&gt;
					lot of work has been accomplished, but there's even more &lt;br /&gt;
					that can be done. In the next edition of this column, I'll &lt;br /&gt;
					look at adding check-in notes, policy support, and possibly &lt;br /&gt;
					other interesting features.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsGloss&quot;&gt;Send your questions and comments to&amp;nbsp;&lt;a href=&quot;mailto:mmvsts@microsoft.com&quot;&gt;mmvsts@microsoft.com&lt;/a&gt;.&lt;br /&gt;
					&lt;/span&gt;&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;5&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table9&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;
							&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;&lt;b&gt;
							NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/TeamSystem/default.aspx&quot;&gt;
							Explore&lt;/a&gt; the sample code online! &lt;/b&gt;- or - &lt;b&gt;
							Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TeamSystem2007_09.exe&quot;&gt;
							TeamSystem2007_09.exe&lt;/a&gt; (197KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
				&lt;hr&gt;&lt;span class=&quot;clsBio&quot;&gt;&lt;b&gt;Brian A. Randell&lt;/b&gt; is a senior &lt;br /&gt;
				consultant with MCW Technologies LLC. Brian spends his time &lt;br /&gt;
				speaking, teaching, and writing about Microsoft technologies. He &lt;br /&gt;
				is the author of Pluralsight's Applied Team System course and is &lt;br /&gt;
				a Microsoft MVP. Contact Brian via his blog at&lt;br /&gt;
				&lt;a href=&quot;http://mcwtech.com/cs/blogs/brianr&quot;&gt;mcwtech.com/cs/blogs/brianr&lt;/a&gt;.&lt;/span&gt;&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
<author>ÓÞíâÏÚ úÜ</author>
<pubDate>Sep, 04 2007 06:59:12 GMT</pubDate>
<category>¹æ¹ý·Ð</category>
</item>
<item>
<title>Exploring Claims-Based Identity</title>
<link>http://www.rustican.com/board/zboard.php?id=paper&amp;no=252</link>
<description>&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table2&quot;&gt;
			&lt;tr&gt;
				&lt;td class=&quot;clsDocBody&quot;&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table3&quot;&gt;
					&lt;tr&gt;
						&lt;td class=&quot;clsDeck&quot; bgColor=&quot;#ffffcc&quot; colSpan=&quot;2&quot; height=&quot;20&quot;&gt;
						&lt;b&gt;Exploring Claims-Based Identity&lt;/b&gt;&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#ffffff&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#336699&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table4&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;*&quot;&gt;
						&lt;div class=&quot;pd&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;a title=&quot;More articles by this author&quot; href=&quot;http://msdn.microsoft.com/msdnmag/find/?type=Au&amp;phrase=Keith%20Brown&amp;words=exact&quot;&gt;
							Keith Brown&lt;/a&gt;&lt;/div&gt;
						&lt;/td&gt;
						&lt;td width=&quot;175&quot;&gt;
						&lt;div id=&quot;menu_parent&quot; style=&quot;CURSOR: pointer&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
							&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;3&quot; border=&quot;0&quot; id=&quot;table5&quot;&gt;
								&lt;tr vAlign=&quot;bottom&quot; align=&quot;middle&quot;&gt;
									&lt;td&gt;
									&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;print=true&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;
									&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/rss/rss.aspx?Sub=Security%20Briefs&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a onclick=&quot;return false;&quot; href=&quot;#&quot;&gt;more &lt;br /&gt;
									...&lt;/a&gt;&lt;/td&gt;
								&lt;/tr&gt;
							&lt;/table&gt;
						&lt;/div&gt;
						&lt;div style=&quot;FLOAT: right; WIDTH: 175px&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;div id=&quot;menu_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 5px; Z-INDEX: 100; LEFT: 659px; VISIBILITY: hidden; PADDING-BOTTOM: 5px; BORDER-LEFT: #999999 1px solid; WIDTH: 175px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; TOP: 308px; BACKGROUND-COLOR: white; align: right&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot; at_timeout=&quot;357518659&quot;&gt;
								&lt;table cellSpacing=&quot;3&quot; cellPadding=&quot;2&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table6&quot;&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot; width=&quot;30&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot; width=&quot;140&quot;&gt;
										&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;print=true&quot;&gt;
										Print&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										E-mail&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Add to Favorites&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Rate&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Security%20Briefs&quot;&gt;
										RSS (Security Briefs) &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/addtoany.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://www.addtoany.com/?linkname=Security%20Briefs&amp;type=rss&amp;linkurl=http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Security%20Briefs&quot;&gt;
										Add RSS to Any &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/library.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Related Articles&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/spaces.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://spaces.live.com/blogit.aspx?Title=Security Briefs:+Exploring Claims-Based Identity&amp;Description=Keith Brown introduces you to the new identity model in the Microsoft .NET Framework 3.0.&amp;SourceURL=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&quot;&gt;
										Live Spaces &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/digg.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://digg.com/submit?phase=2&amp;url=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&amp;title=Security Briefs:+Exploring Claims-Based Identity&amp;bodytext=Keith Brown introduces you to the new identity model in the Microsoft .NET Framework 3.0.&amp;topic=programming                &quot;&gt;
										Digg This &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/blogger.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://new.blogger.com/blog_this.pyra?t=Keith Brown introduces you to the new identity model in the Microsoft .NET Framework 3.0.&amp;u=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&amp;n='Security Briefs:+Exploring Claims-Based Identity,'bloggerForm','scrollbars=no,width=475,height=300,top=175,left=75,status=yes,resizable=yes&quot;&gt;
										BlogThis! &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/slashdot.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://slashdot.org/bookmark.pl?url=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&amp;title=Security Briefs:+Exploring Claims-Based Identity&quot;&gt;
										Slashdot &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/delicious.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://del.icio.us/post?url=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&amp;title=Security Briefs:+Exploring Claims-Based Identity&quot;&gt;
										del.icio.us &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/technorati.png&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://technorati.com/faves?add=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&quot;&gt;
										Technorati &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&quot;&gt;
										Explore &lt;/a&gt;the code. &lt;br&gt;
										&lt;br&gt;
										&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/SecurityBriefs2007_09.exe&quot;&gt;
										Download &lt;/a&gt;the code. &lt;/td&gt;
									&lt;/tr&gt;
								&lt;/table&gt;
							&lt;/div&gt;
						&lt;/div&gt;
&lt;SCRIPT type=text/javascript xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
      at_attach(&quot;menu_parent&quot;, &quot;menu_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
    &lt;/SCRIPT&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
				&lt;span id=&quot;dl_parent&quot; style=&quot;CURSOR: pointer&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
				&lt;a id=&quot;Code&quot; href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&quot;&gt;
				&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;Get &lt;br /&gt;
				the sample code for this article. &lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
				&lt;div id=&quot;dl_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 0px; Z-INDEX: 100; VISIBILITY: hidden; PADDING-BOTTOM: 0px; BORDER-LEFT: #999999 1px solid; WIDTH: 500px; PADDING-TOP: 0px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; BACKGROUND-COLOR: white&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
					&lt;table style=&quot;background-image: url('http://msdn.microsoft.com/msdnmag/images/codebg.gif')&quot; cellSpacing=&quot;0&quot; cellPadding=&quot;20&quot; width=&quot;500&quot; border=&quot;0&quot; id=&quot;table7&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;&lt;b&gt;NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&quot;&gt;
							Explore &lt;/a&gt;the sample code online! &lt;/b&gt;&lt;br&gt;
							&lt;br&gt;
							- or - &lt;br&gt;
							&lt;br&gt;
							&lt;b&gt;Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/SecurityBriefs2007_09.exe&quot;&gt;
							SecurityBriefs2007_09.exe&lt;/a&gt; (206KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
&lt;SCRIPT type=text/javascript&gt;
    at_attach(&quot;dl_parent&quot;, &quot;dl_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
  &lt;/SCRIPT&gt;
				&lt;br&gt;
				&lt;br&gt;
¡¡&lt;hr&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table8&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;50%&quot;&gt;
						&lt;img class=&quot;clsImgButton&quot; id=&quot;contentbtn&quot; onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; height=&quot;9&quot; alt=&quot;&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/minus.gif&quot; width=&quot;9&quot; align=&quot;absMiddle&quot; vspace=&quot;2&quot;&gt;&lt;a onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; name=&quot;contents&quot; href=&quot;#void&quot;&gt;&lt;b&gt;Contents&lt;/b&gt;&lt;/a&gt;&lt;br&gt;
¡¡&lt;div id=&quot;contentmenu&quot; style=&quot;MARGIN-TOP: 10px; DISPLAY: block; MARGIN-LEFT: 20px&quot;&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S1&quot;&gt;Finding Common Ground&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S2&quot;&gt;Traditional &lt;br /&gt;
							Representation of Client Identity&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S3&quot;&gt;ClaimSets and Claims&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S4&quot;&gt;Claims Transformation &lt;br /&gt;
							and IAuthorizationPolicy&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S5&quot;&gt;Security Token Service&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S6&quot;&gt;Trust and Federated &lt;br /&gt;
							Identity&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S7&quot;&gt;Until Next Time&lt;/a&gt;&lt;br&gt;
¡¡&lt;/div&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;hr&gt;&lt;br&gt;
¡¡&lt;div class=&quot;articletext&quot;&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS001&quot;&gt;¡¡&lt;/p&gt;
					&lt;div class=&quot;dropcap&quot;&gt;
						M&lt;/div&gt;
					ost enterprise applications need some basic user security &lt;br /&gt;
					features. At a minimum, they need to authenticate their &lt;br /&gt;
					users, and many also need to authorize access to certain &lt;br /&gt;
					features so that only privileged users can get to them. Some &lt;br /&gt;
					apps must go further and audit what the user does. On &lt;br /&gt;
					Windows&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;, these features are &lt;br /&gt;
					built into the operating system and are usually quite easy &lt;br /&gt;
					to integrate into an application. By taking advantage of &lt;br /&gt;
					Windows integrated authentication, you don't have to invent &lt;br /&gt;
					your own authentication protocol or manage a user database. &lt;br /&gt;
					By using access control lists (ACLs), impersonation, and &lt;br /&gt;
					features such as groups, you can implement authorization &lt;br /&gt;
					with very little code. Indeed, this advice applies no matter &lt;br /&gt;
					which OS you are using. It's almost always a better idea to &lt;br /&gt;
					integrate closely with the security features in your OS &lt;br /&gt;
					rather than reinventing those features yourself.&lt;br /&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS002&quot;&gt;But what &lt;br /&gt;
					happens when you want to extend reach to users who don't &lt;br /&gt;
					happen to have Windows accounts? What about users who aren't &lt;br /&gt;
					running Windows at all? More and more applications need this &lt;br /&gt;
					type of reach, which seems to fly in the face of traditional &lt;br /&gt;
					advice. This column will introduce you to the new identity &lt;br /&gt;
					model in the Microsoft&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt; .NET &lt;br /&gt;
					Framework 3.0, which is designed to help address these and &lt;br /&gt;
					other problems.&lt;/p&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Finding Common Ground&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS003&quot;&gt;On Windows, the most common type &lt;br /&gt;
					of credential used to access an enterprise application is &lt;br /&gt;
					simply the user's domain account. An application that uses &lt;br /&gt;
					Windows integrated authentication receives a Kerberos ticket &lt;br /&gt;
					to represent a client. An application using SSL might &lt;br /&gt;
					instead receive an X.509 certificate for the client. A &lt;br /&gt;
					Kerberos ticket and an X.509 certificate are two very &lt;br /&gt;
					different beasts, and the code in the OS that parses, &lt;br /&gt;
					validates, and ultimately presents the data inside is very &lt;br /&gt;
					different. But if you take a step back and think about what &lt;br /&gt;
					they really represent, you'll see that these two credentials &lt;br /&gt;
					have a lot in common.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS004&quot;&gt;To make this &lt;br /&gt;
					discussion more concrete, and to help introduce what might &lt;br /&gt;
					be new terminology for some readers, let's imagine that &lt;br /&gt;
					Alice is a user who wants to access a purchasing service &lt;br /&gt;
					using her Windows domain account. Her domain controller &lt;br /&gt;
					authenticates her and creates a Kerberos ticket with a bunch &lt;br /&gt;
					of security identifiers (SIDs) in it. These SIDs represent &lt;br /&gt;
					Alice's user account as well as the domain groups in which &lt;br /&gt;
					she's a member, and they are embedded in the ticket along &lt;br /&gt;
					with a signature from the domain controller. In &lt;br /&gt;
					identity-speak, an issuer (the domain controller) has given &lt;br /&gt;
					a subject (Alice) a security token that she can use in order &lt;br /&gt;
					to prove her identity.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS005&quot;&gt;These same &lt;br /&gt;
					ideas apply when Alice uses a certificate instead. A &lt;br /&gt;
					certificate is just another type of security token. The &lt;br /&gt;
					issuer in this case is a certificate authority (CA) and the &lt;br /&gt;
					subject is Alice. Both the Kerberos ticket and the &lt;br /&gt;
					certificate are, in essence, signed statements by an issuer &lt;br /&gt;
					about a subject. These are just two different ways that a &lt;br /&gt;
					trusted authority can vouch for one of its subjects. Each &lt;br /&gt;
					signed statement can be thought of as a collection of &lt;br /&gt;
					claims. You should think of it this way: the domain &lt;br /&gt;
					controller is making claims about Alice's identity when it &lt;br /&gt;
					signs the list of SIDs in her ticket. Each SID becomes a &lt;br /&gt;
					claim. The certificate authority makes claims about Alice's &lt;br /&gt;
					identity when it signs her name and public key. The name and &lt;br /&gt;
					public key are examples of claims in the certificate.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS006&quot;&gt;If the &lt;br /&gt;
					terminology I'm using sounds a little academic, bear with me &lt;br /&gt;
					because these abstractions turn out to be incredibly useful &lt;br /&gt;
					in practice. In fact, the entire goal of this new identity &lt;br /&gt;
					model is to abstract identity in a way that reduces your &lt;br /&gt;
					dependency on specific types of credentials without &lt;br /&gt;
					compromising the security of your application. By coding to &lt;br /&gt;
					the identity model in the .NET Framework 3.0, you'll be able &lt;br /&gt;
					to process not only Kerberos tickets and certificates, but &lt;br /&gt;
					also Security Assertion Markup Language (SAML) tokens, which &lt;br /&gt;
					opens the door to some really interesting identity &lt;br /&gt;
					architectures, including federated identity.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Traditional Representation of &lt;br /&gt;
					Client Identity&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS007&quot;&gt;That's enough abstract talk; &lt;br /&gt;
					let's see this stuff in action. I'll start with a simple &lt;br /&gt;
					Windows Communication Foundation (WCF) service that accepts &lt;br /&gt;
					either Windows credentials or X.509 certificates from &lt;br /&gt;
					clients. It exposes a single method that takes no arguments, &lt;br /&gt;
					and when called by a client, it prints out details about the &lt;br /&gt;
					client's identity.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig1'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig1&quot;&gt;
					Figure&amp;nbsp;1&lt;/a&gt; shows this method, called Hello. In this &lt;br /&gt;
					version, it uses the traditional IIdentity interface &lt;br /&gt;
					introduced in the .NET Framework 1.0 to inspect the client's &lt;br /&gt;
					identity.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS008&quot;&gt;The first step &lt;br /&gt;
					here is to grab the ServiceSecurityContext for the call, &lt;br /&gt;
					which is how WCF communicates details of the client's &lt;br /&gt;
					identity to a service. I'm careful to check for null, which &lt;br /&gt;
					would indicate an anonymous client. Then I grab the &lt;br /&gt;
					PrimaryIdentity property and dump out its contents. Here's &lt;br /&gt;
					what the output looks like when I configure the sample to &lt;br /&gt;
					use Windows credentials:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS009&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Primary identity type: WindowsIdentity&lt;br /&gt;
AuthenticationType: NTLM&lt;br /&gt;
IsAuthenticated: True&lt;br /&gt;
Name: GROMITAlice&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS010&quot;&gt;The concrete &lt;br /&gt;
					type in this case is WindowsIdentity, which exposes a lot &lt;br /&gt;
					more information than IIdentity. By downcasting to &lt;br /&gt;
					WindowsIdentity, I'd be able to get a list of the groups of &lt;br /&gt;
					which Alice is a member, get her user SID and use that to &lt;br /&gt;
					look up her user record in Active Directory&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;, &lt;br /&gt;
					and I might even be able to impersonate her in some &lt;br /&gt;
					circumstances.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS011&quot;&gt;Now let's run &lt;br /&gt;
					this same example with a different WCF configuration. This &lt;br /&gt;
					time I'll have the client submit an X.509 certificate.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS012&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Primary identity type: X509Identity&lt;br /&gt;
AuthenticationType: X509&lt;br /&gt;
IsAuthenticated: True&lt;br /&gt;
Name: CN=SampleClient; 33BB8518E4B7¡¦&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS013&quot;&gt;The Name &lt;br /&gt;
					property in this case is a combination of the common name in &lt;br /&gt;
					the client certificate and its thumbprint. If you wanted &lt;br /&gt;
					further information, such as the issuer, expiration date, &lt;br /&gt;
					and so on, you might try downcasting to X509Identity, but &lt;br /&gt;
					you'd quickly find that this class is marked internal. But &lt;br /&gt;
					regardless of this limitation, even if you could downcast, &lt;br /&gt;
					you'd be dealing with an entirely different programming &lt;br /&gt;
					model from that in WindowsIdentity. This is one problem that &lt;br /&gt;
					the new identity model solves: it gives you a single &lt;br /&gt;
					programming model no matter what shape of client credential &lt;br /&gt;
					you get. In the next section, I've rewritten the Hello &lt;br /&gt;
					sample to be claims-aware. Read on and see what identity &lt;br /&gt;
					looks like through a claims-based lens.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;ClaimSets and Claims&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS014&quot;&gt;In&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig2'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig2&quot;&gt;
					Figure&amp;nbsp;2&lt;/a&gt;, you'll see a new version of Hello that's been &lt;br /&gt;
					rewritten using classes in System.IdentityModel, the new &lt;br /&gt;
					identity model introduced by the .NET Framework 3.0. This &lt;br /&gt;
					model steps back and treats identity using the abstractions &lt;br /&gt;
					of subject, issuer, and claim. Issuers make claims about &lt;br /&gt;
					their subjects and sign those claims to create security &lt;br /&gt;
					tokens. Each statement from any given issuer is modeled as a &lt;br /&gt;
					ClaimSet, which is a collection of Claim objects coupled &lt;br /&gt;
					with a property called Issuer, which is simply another &lt;br /&gt;
					ClaimSet.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS015&quot;&gt;Before &lt;br /&gt;
					drilling straight into the code, I want you to see some &lt;br /&gt;
					output so you can get a feeling for what a ClaimSet &lt;br /&gt;
					represents. Have a look at&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt;, which shows the output of the new Hello method &lt;br /&gt;
					when the client uses Windows credentials. The &lt;br /&gt;
					displayClaimSet helper method in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig2'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig2&quot;&gt;
					Figure&amp;nbsp;2&lt;/a&gt; pretty-prints the list of claims in the &lt;br /&gt;
					ClaimSet, and then recursively walks up the chain of &lt;br /&gt;
					issuers, printing their ClaimSets in turn. Not surprisingly, &lt;br /&gt;
					with Windows credentials, the ClaimSet mainly consists of &lt;br /&gt;
					SIDs. Looking a bit more closely at this output, we can see &lt;br /&gt;
					how System.IdentityModel represents claims.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS016&quot;&gt;The Claim &lt;br /&gt;
					class has three key properties: ClaimType, Right, and &lt;br /&gt;
					Resource. In&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt;, you can see two types of claims: a SID and a &lt;br /&gt;
					Name. The ClaimTypes for these are URIs, but I've &lt;br /&gt;
					abbreviated them in the displayClaim helper method by &lt;br /&gt;
					removing the first part of the URI, otherwise the output &lt;br /&gt;
					would be pretty tough to read.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS017&quot;&gt;While there is &lt;br /&gt;
					no centralized organization that defines all possible types &lt;br /&gt;
					of claims, we really don't need that. All we need is for the &lt;br /&gt;
					issuer to use claim types understood by the consumer (in &lt;br /&gt;
					this case, our Hello method). In practice, you'll see &lt;br /&gt;
					different claim types defined for use in different contexts. &lt;br /&gt;
					As an example, if you read the Information Card Profile, &lt;br /&gt;
					you'll see a dozen or so claim types defined for use with &lt;br /&gt;
					information cards.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS018&quot;&gt;Besides &lt;br /&gt;
					ClaimType, the Claim class also exposes a Right property &lt;br /&gt;
					that can often help you find a claim you need. Look once &lt;br /&gt;
					again at&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt; and note that of all the SIDs shown, only the &lt;br /&gt;
					first SID represents the subject's identity (Alice). The &lt;br /&gt;
					rest of them represent groups. The RIGHT column in the &lt;br /&gt;
					output shows the value of Claim.Right, which is technically &lt;br /&gt;
					a URI that is also abbreviated in the displayClaim routine. &lt;br /&gt;
					System.IdentityModel only defines two rights today: Identity &lt;br /&gt;
					and PossessProperty. You can see that WCF thinks that the &lt;br /&gt;
					user's SID in this example should be used as an identity &lt;br /&gt;
					claim. Of all the claims presented, it's the one you'd want &lt;br /&gt;
					to use to identify the user. All the other claims are &lt;br /&gt;
					PossessProperty claims.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS019&quot;&gt;Claim.Resource &lt;br /&gt;
					is the value of the claim. My claim dump code in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig2'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig2&quot;&gt;
					Figure&amp;nbsp;2&lt;/a&gt; has a helper method, stringizeResource, which &lt;br /&gt;
					pretty-prints these values along with their type names. You &lt;br /&gt;
					see, the Resource property is of type object, and can &lt;br /&gt;
					contain just about anything, depending on the type of the &lt;br /&gt;
					claim. For example, the SID claims you see in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt; are represented by instances of the &lt;br /&gt;
					SecurityIdentifier class introduced in the .NET Framework &lt;br /&gt;
					2.0.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS020&quot;&gt;In a nutshell, &lt;br /&gt;
					the Claim class tells you the type and value of the claim, &lt;br /&gt;
					and often gives you a hint as to whether the claim can be &lt;br /&gt;
					used to uniquely identify a subject or issuer. The ClaimSet &lt;br /&gt;
					is a collection of these Claim objects, coupled with a &lt;br /&gt;
					reference to the issuer's ClaimSet. In&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt;, note that the issuer is represented with a SID &lt;br /&gt;
					of S-1-5. That SID represents the &amp;quot;NT Authority,&amp;quot; which &lt;br /&gt;
					basically means the OS. Alice is using a local account in &lt;br /&gt;
					this example; otherwise the issuer would be identified by &lt;br /&gt;
					the SID of Alice's domain.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS021&quot;&gt;As you &lt;br /&gt;
					traverse up the chain of issuers, you'll eventually find one &lt;br /&gt;
					that is self-referential, that is, it points to its own &lt;br /&gt;
					ClaimSet. The displayClaimSet method in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig2'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig2&quot;&gt;
					Figure&amp;nbsp;2&lt;/a&gt; shows how you can check for this using &lt;br /&gt;
					Object.ReferenceEquals. This happens when you reach a root &lt;br /&gt;
					authority such as a domain controller or certificate &lt;br /&gt;
					authority. It's important to watch for this. Otherwise, if &lt;br /&gt;
					you are traversing up the issuer chain, you might just end &lt;br /&gt;
					up in an infinite loop when you reach the root issuer!&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS022&quot;&gt;Now have a &lt;br /&gt;
					look at&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig4'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig4&quot;&gt;
					Figure&amp;nbsp;4&lt;/a&gt;, which shows the output of Hello when Alice &lt;br /&gt;
					sends a certificate. In this case, WCF uses Claim.Right to &lt;br /&gt;
					hint that the certificate's thumbprint can be used to &lt;br /&gt;
					identify the client. And since I'm cheating by using &lt;br /&gt;
					self-signed certificates for my sample code, the Issuer &lt;br /&gt;
					property points to the subject's claim set, indicating that &lt;br /&gt;
					it was self-issued. Note that different classes are used to &lt;br /&gt;
					represent the claims, but the overall structure is very &lt;br /&gt;
					similar to the previous example.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS023&quot;&gt;Finally, if &lt;br /&gt;
					you look at&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig5'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=&amp;fig=true#fig5&quot;&gt;
					Figure&amp;nbsp;5&lt;/a&gt;, you'll see the output of Hello when the client &lt;br /&gt;
					uses an information card to authenticate with the service. &lt;br /&gt;
					In this case, the client's e-mail address and first name &lt;br /&gt;
					were sent as claims, and because a personal card was used, &lt;br /&gt;
					the issuer is identified with an RSA public key. If you want &lt;br /&gt;
					to know more about information cards and what these &lt;br /&gt;
					particular ClaimSets mean, read my two recent columns on &lt;br /&gt;
					Windows CardSpace&amp;#8482; in the October 2006 and May 2006 issues &lt;br /&gt;
					of MSDN&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt; Magazine (&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/06/10/SecurityBriefs&quot;&gt;msdn.microsoft.com/msdnmag/issues/06/10/SecurityBriefs&lt;/a&gt;&lt;br /&gt;
					and&lt;br /&gt;
					&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/06/05/SecurityBriefs&quot;&gt;
					msdn.microsoft.com/msdnmag/issues/06/05/SecurityBriefs&lt;/a&gt;).&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS024&quot;&gt;There are &lt;br /&gt;
					several advantages to building systems that use a &lt;br /&gt;
					claims-based lens to look at client identity. One obvious &lt;br /&gt;
					benefit is that you get a single programming model to &lt;br /&gt;
					inspect any kind of client identity. Just program against &lt;br /&gt;
					ClaimSet and you're all done, right? Well, in practice, if &lt;br /&gt;
					you're expecting a certificate, you're going to be looking &lt;br /&gt;
					for different types of claims than if you were expecting &lt;br /&gt;
					Windows credentials or a personal information card. In fact, &lt;br /&gt;
					there are classes that derive from ClaimSet, such as &lt;br /&gt;
					X509CertificateClaimSet and WindowsClaimSet, that can make &lt;br /&gt;
					things a little easier when you know what type of credential &lt;br /&gt;
					you are expecting. Having a single programming model is a &lt;br /&gt;
					good thing. But you'll discover the real power of claims &lt;br /&gt;
					once you realize that you can model just about any sort of &lt;br /&gt;
					authentication and authorization system using these concepts &lt;br /&gt;
					of subjects, issuers, and claims. And there's no better way &lt;br /&gt;
					to show this than through claims transformation.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Claims Transformation and &lt;br /&gt;
					IAuthorizationPolicy&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS025&quot;&gt;Imagine that you need to build a &lt;br /&gt;
					WCF service that accepts lots of different types of &lt;br /&gt;
					credentials, and you want to use roles to authorize access &lt;br /&gt;
					to features. If the user is in the Manager role, she will &lt;br /&gt;
					have access to more features than if she is only in the &lt;br /&gt;
					Clerk role, for example. You can model roles using claims, &lt;br /&gt;
					and you can use claims transformation to deal with the &lt;br /&gt;
					multitude of different credential formats you might accept.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS026&quot;&gt;
					System.IdentityModel has an interface that allows you to &lt;br /&gt;
					perform arbitrary claims transformation. It's called &lt;br /&gt;
					IAuthorizationPolicy, and its one key method is called &lt;br /&gt;
					Evaluate, which takes an instance of the following class as &lt;br /&gt;
					an argument:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS027&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;public abstract class EvaluationContext {&lt;br /&gt;
    // Methods&lt;br /&gt;
    protected EvaluationContext();&lt;br /&gt;
    public abstract void AddClaimSet(&lt;br /&gt;
        IAuthorizationPolicy policy, ClaimSet claimSet);&lt;br /&gt;
    public abstract void RecordExpirationTime(DateTime expirationTime);&lt;br /&gt;

    // Properties&lt;br /&gt;
    public abstract ReadOnlyCollection&amp;lt;ClaimSet&amp;gt; ClaimSets { get; }&lt;br /&gt;
    public abstract int Generation { get; }&lt;br /&gt;
    public abstract IDictionary&amp;lt;string, object&amp;gt; Properties { get; }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS028&quot;&gt;This context &lt;br /&gt;
					allows you to do a number of things, but what I care about &lt;br /&gt;
					here is that it allows you to examine the claim sets &lt;br /&gt;
					presented by a client, do some sort of mapping and then add &lt;br /&gt;
					your own claim set. Say, for example, the client submitted a &lt;br /&gt;
					certificate. Your authorization policy could map the subject &lt;br /&gt;
					name in the certificate onto a set of roles, and expose &lt;br /&gt;
					those roles as claims in a new ClaimSet that indicates your &lt;br /&gt;
					application as the issuer. If instead the user supplied a &lt;br /&gt;
					Windows credential, you could map her groups onto those same &lt;br /&gt;
					roles using a similar ClaimSet. Once this transformation &lt;br /&gt;
					occurs, your service simply needs to look for the ClaimSet &lt;br /&gt;
					issued locally, and then read the user's roles from there.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS029&quot;&gt;WCF has &lt;br /&gt;
					excellent support for this model. In your service's &lt;br /&gt;
					configuration file, you can wire up a ServiceAuthorization &lt;br /&gt;
					behavior that tells WCF to call your implementation of &lt;br /&gt;
					IAuthorizationPolicy before it calls your service's method &lt;br /&gt;
					(Hello, for example). This allows you to centralize the code &lt;br /&gt;
					that deals with the myriad of client credentials that your &lt;br /&gt;
					service accepts. Note that if you're planning to use &lt;br /&gt;
					role-based security, you can take this one step further and &lt;br /&gt;
					set the PrincipalPermissionMode attribute on the &lt;br /&gt;
					ServiceAuthorization behavior to Custom, and then supply an &lt;br /&gt;
					instance of IPrincipal that contains your roles via the &lt;br /&gt;
					evaluation context. This will allow you to use the &lt;br /&gt;
					PrincipalPermission attribute on your service's methods to &lt;br /&gt;
					grant access based on roles. Here's what this behavior looks &lt;br /&gt;
					like in config:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS030&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&amp;lt;serviceAuthorization principalPermissionMode=&amp;quot;Custom&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;authorizationPolicies&amp;gt;&lt;br /&gt;
    &amp;lt;add policyType=&amp;quot;MyAuthorizationPolicy, MyAssembly&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/authorizationPolicies&amp;gt;&lt;br /&gt;
&amp;lt;/serviceAuthorization&amp;gt;&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS031&quot;&gt;And here's how &lt;br /&gt;
					you communicate a custom principal to WCF using the &lt;br /&gt;
					evaluation context:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS032&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;string[] roles = lookupRolesForUser(evaluationContext);&lt;br /&gt;
GenericIdentity id = new GenericIdentity(clientName);&lt;br /&gt;
evaluationContext.Properties[&amp;quot;Principal&amp;quot;] =&lt;br /&gt;
    new GenericPrincipal(id, roles);&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS033&quot;&gt;WCF will then &lt;br /&gt;
					set up Thread.CurrentPrincipal with the supplied principal &lt;br /&gt;
					before calling into the service's method. I only mention &lt;br /&gt;
					this custom principal trick because a lot of people like &lt;br /&gt;
					using PrincipalPermission and they will find this to be &lt;br /&gt;
					handy. But let's get back to claims again, because that's &lt;br /&gt;
					really where the power lies. So, how would you go about &lt;br /&gt;
					creating your own ClaimSet to represent a set of roles? &lt;br /&gt;
					While a full example can be found in the sample code &lt;br /&gt;
					available with this column on the &lt;i&gt;MSDN Magazine&lt;/i&gt; Web &lt;br /&gt;
					site, here's an excerpt that shows how to do this:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS034&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;string clientName = getClientNameFromClaims(EvaluationContext);&lt;br /&gt;
Claim c1 = new Claim(ClaimTypes.Name, clientName, Rights.Identity);&lt;br /&gt;
Claim c2 = new Claim(&amp;quot;urn:role&amp;quot;, &amp;quot;foo&amp;quot;, Rights.PossessProperty);&lt;br /&gt;
Claim c2 = new Claim(&amp;quot;urn:role&amp;quot;, &amp;quot;bar&amp;quot;, Rights.PossessProperty);&lt;br /&gt;
ClaimSet newClaimSet = new DefaultClaimSet(&lt;br /&gt;
    DefaultClaimSet.System, c1, c2, c3);&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS035&quot;&gt;I used a &lt;br /&gt;
					well-known claim set called System to indicate that this is &lt;br /&gt;
					an internal claim set issued by my own code. The System &lt;br /&gt;
					claim set has nothing to do with the SYSTEM account in &lt;br /&gt;
					Windows. It's just a simple claim set that is easy to search &lt;br /&gt;
					for. Note that I add roles as PossessProperty claims, with a &lt;br /&gt;
					custom URI. You'll probably want to come up with something &lt;br /&gt;
					more elaborate than &amp;quot;urn:role&amp;quot; for the claim type URI, but &lt;br /&gt;
					since System.IdentityModel doesn't define a URI for a role &lt;br /&gt;
					claim, you can pick one that makes sense for your app.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS036&quot;&gt;Once you've &lt;br /&gt;
					created the new claim set, you can add it to the evaluation &lt;br /&gt;
					context via the AddClaimSet method. Now the code in your &lt;br /&gt;
					application simply needs to look for this ClaimSet you've &lt;br /&gt;
					issued, and it will get a list of roles for the user, &lt;br /&gt;
					regardless of whether she used a certificate or a Windows &lt;br /&gt;
					account to authenticate.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Security Token Service&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS037&quot;&gt;Imagine for a moment that you've &lt;br /&gt;
					taken the time to build a great implementation of &lt;br /&gt;
					IAuthorizationPolicy that maps different credential types &lt;br /&gt;
					onto a simple set of role-based claims as I described above. &lt;br /&gt;
					You may have lots of different services that need this &lt;br /&gt;
					feature. One approach to reuse this code would be to drop &lt;br /&gt;
					the class into its own assembly and wire it into every &lt;br /&gt;
					service that needs it.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS038&quot;&gt;A more &lt;br /&gt;
					interesting approach would be to issue your own security &lt;br /&gt;
					tokens by using your authorization policy as the basis for &lt;br /&gt;
					implementing a Security Token Service (STS), which issues &lt;br /&gt;
					security tokens via a Web service protocol known as &lt;br /&gt;
					WS-Trust. An STS can accept a security token of one type and &lt;br /&gt;
					issue a token of another type, and can deal with whatever &lt;br /&gt;
					claims transforms are necessary, such as mapping a client &lt;br /&gt;
					certificate onto a SAML token that contains a set of roles &lt;br /&gt;
					that an application understands. In this scenario, the &lt;br /&gt;
					applications in your enterprise would look for a ClaimSet &lt;br /&gt;
					issued (and signed) by your own STS.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS039&quot;&gt;As I am &lt;br /&gt;
					writing this in June 2007, implementing an STS is possible, &lt;br /&gt;
					but not very easy. (Microsoft is working on making this &lt;br /&gt;
					easier.) Regardless of whether or not you happen to &lt;br /&gt;
					implement your own STS, building a claims-aware application &lt;br /&gt;
					will make it easier for you to leverage one should it ever &lt;br /&gt;
					become available to you.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Trust and Federated Identity&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS040&quot;&gt;WCF and other communication &lt;br /&gt;
					frameworks use cryptography to ensure that the sender of a &lt;br /&gt;
					security token is indeed the subject and that the claims in &lt;br /&gt;
					the token were signed by the issuer named in the token. But &lt;br /&gt;
					all of this fancy plumbing doesn't have any idea how much &lt;br /&gt;
					you trust the issuer. If you don't trust him, you're not &lt;br /&gt;
					going to trust the claims he makes about his subjects! &lt;br /&gt;
					That's why the issuer is always identified when you receive &lt;br /&gt;
					a claim set, and it's the first thing you should look at &lt;br /&gt;
					when processing a claim set.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS041&quot;&gt;It's easy to &lt;br /&gt;
					write code that accepts tokens from a single trusted issuer. &lt;br /&gt;
					Just make sure the claim set you received was issued by the &lt;br /&gt;
					one authority you trust, and then you can use those claims &lt;br /&gt;
					to make security decisions. You've essentially delegated &lt;br /&gt;
					responsibility to the STS for doing the heavy lifting such &lt;br /&gt;
					as mapping users onto roles and dealing with different types &lt;br /&gt;
					of security tokens.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS042&quot;&gt;Now imagine &lt;br /&gt;
					you wanted to take this one step further. Instead of only &lt;br /&gt;
					accepting Windows credentials and X.509 certificates, what &lt;br /&gt;
					if your STS also accepted signed SAML tokens issued by an &lt;br /&gt;
					STS at a trusted partner? This leads to the realm of &lt;br /&gt;
					federated identity, which is very powerful. Instead of &lt;br /&gt;
					having to worry about managing user accounts for external &lt;br /&gt;
					users from partner companies, you can instead accept signed &lt;br /&gt;
					statements from those partners in the form of SAML tokens. I &lt;br /&gt;
					discuss the many benefits of automating these sorts of &lt;br /&gt;
					business-to-business trust relationships in my article on &lt;br /&gt;
					Active Directory Federation Services (&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/06/11/SingleSignOn&quot;&gt;msdn.microsoft.com/msdnmag/issues/06/11/SingleSignOn&lt;/a&gt;).&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS043&quot;&gt;Federated &lt;br /&gt;
					identity ultimately boils down to claims transformation, if &lt;br /&gt;
					you think about it. The partner's STS makes the client's &lt;br /&gt;
					life easy by accepting as input whatever credential is most &lt;br /&gt;
					natural for her, given her operating system and platform. &lt;br /&gt;
					For example, if the client is running Windows, the STS could &lt;br /&gt;
					use Kerberos to automatically authenticate her and issue a &lt;br /&gt;
					SAML token. Another partner company might run a completely &lt;br /&gt;
					different OS that uses other strong authentication &lt;br /&gt;
					protocols. But the STS at that company would use those &lt;br /&gt;
					protocols to seamlessly authenticate the user and issue a &lt;br /&gt;
					SAML token. Meanwhile, the user enjoys the benefits of &lt;br /&gt;
					single-sign on, even when using applications like yours from &lt;br /&gt;
					federated partner companies.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS044&quot;&gt;The STS in &lt;br /&gt;
					your organization makes life easy for your applications. &lt;br /&gt;
					Your STS will ensure that only SAML tokens from trusted &lt;br /&gt;
					partners are accepted, and will then issue a new token for &lt;br /&gt;
					use with your application. Your application can live a long &lt;br /&gt;
					and happy life simply looking for ClaimSets issued by your &lt;br /&gt;
					company's STS.&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;6&lt;/span&gt; shows the flow of messages in this federated &lt;br /&gt;
					system. The client first goes to her company's account STS &lt;br /&gt;
					to obtain a SAML token. She sends this token to the resource &lt;br /&gt;
					STS to obtain a new SAML token that the service will &lt;br /&gt;
					consume.&lt;/p&gt;
					&lt;div id=&quot;259400002&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 400px&quot;&gt;
						&lt;img height=&quot;259&quot; alt=&quot;Figure 6 Federated Authentication Message Flow&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/fig06.gif&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 6&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Federated &lt;br /&gt;
						Authentication Message Flow&lt;/span&gt;&lt;/div&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS045&quot;&gt;Security token &lt;br /&gt;
					services are designed to bridge the gap between security or &lt;br /&gt;
					technology realms. By transforming one token type into &lt;br /&gt;
					another, and at the same time transforming the claims inside &lt;br /&gt;
					those tokens, they are a great way to centralize &lt;br /&gt;
					authentication and authorization policies.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS046&quot;&gt;I plan on &lt;br /&gt;
					drilling deeper into these federated identity models in the &lt;br /&gt;
					future. For now I hope you'll trust me (pun intended) when I &lt;br /&gt;
					say that federated identity solutions are becoming more and &lt;br /&gt;
					more common, and you'll be able to fit into this model if &lt;br /&gt;
					you're building claims-aware applications today. Expect &lt;br /&gt;
					further innovation in this space in the future.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Until Next Time&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS047&quot;&gt;Building claims-aware &lt;br /&gt;
					applications will prepare you for the future of identity on &lt;br /&gt;
					the Windows platform. For example, you'll be able to accept &lt;br /&gt;
					not only traditional token formats such as Windows &lt;br /&gt;
					credentials or X.509 certificates, but you'll also be ready &lt;br /&gt;
					to accept information cards. You'll also be better prepared &lt;br /&gt;
					to implement federated identity when the time comes for &lt;br /&gt;
					that.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007SECURITYBRIEFS048&quot;&gt;The first step &lt;br /&gt;
					to learning about claims is to spend some time exploring &lt;br /&gt;
					System.IdentityModel, which is the new claims-based &lt;br /&gt;
					programming model introduced in the .NET Framework 3.0. Use &lt;br /&gt;
					the sample code with this column to get started and see how &lt;br /&gt;
					you can apply the power of claims-based identity in your own &lt;br /&gt;
					applications today.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsGloss&quot;&gt;Send your questions and comments for &lt;br /&gt;
					Keith to&amp;nbsp;&lt;a href=&quot;mailto:briefs@microsoft.com&quot;&gt;briefs@microsoft.com&lt;/a&gt;.&lt;br /&gt;
					&lt;/span&gt;&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;5&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table9&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;
							&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;&lt;b&gt;
							NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/SecurityBriefs/default.aspx?loc=en&quot;&gt;
							Explore&lt;/a&gt; the sample code online! &lt;/b&gt;- or - &lt;b&gt;
							Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/SecurityBriefs2007_09.exe&quot;&gt;
							SecurityBriefs2007_09.exe&lt;/a&gt; (206KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
				&lt;hr&gt;&lt;span class=&quot;clsBio&quot;&gt;&lt;b&gt;Keith Brown&lt;/b&gt; is a co-founder of &lt;br /&gt;
				Pluralsight, a premier Microsoft .NET training provider. Keith &lt;br /&gt;
				is the author of Pluralsight's Applied .NET Security course as &lt;br /&gt;
				well as several books, including The .NET Developer's Guide to &lt;br /&gt;
				Windows Security, which is available both in print and on the &lt;br /&gt;
				Web. Learn more at &lt;a href=&quot;http://www.pluralsight.com/keith&quot;&gt;
				www.pluralsight.com/keith&lt;/a&gt;&lt;/span&gt;&lt;br&gt;
¡¡&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
<author>ÓÞíâÏÚ úÜ</author>
<pubDate>Sep, 04 2007 06:57:54 GMT</pubDate>
<category>¹æ¹ý·Ð</category>
</item>
<item>
<title>AJAX Application Architecture, Part 1</title>
<link>http://www.rustican.com/board/zboard.php?id=paper&amp;no=251</link>
<description>&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table2&quot;&gt;
			&lt;tr&gt;
				&lt;td class=&quot;clsDocBody&quot;&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table3&quot;&gt;
					&lt;tr&gt;
						&lt;td class=&quot;clsDeck&quot; bgColor=&quot;#ffffcc&quot; colSpan=&quot;2&quot; height=&quot;20&quot;&gt;
						&lt;b&gt;AJAX Application Architecture, Part 1&lt;/b&gt;&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#ffffff&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#336699&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table4&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;*&quot;&gt;
						&lt;div class=&quot;pd&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;a title=&quot;More articles by this author&quot; href=&quot;http://msdn.microsoft.com/msdnmag/find/?type=Au&amp;phrase=Dino%20Esposito&amp;words=exact&quot;&gt;
							Dino Esposito&lt;/a&gt;&lt;/div&gt;
						&lt;/td&gt;
						&lt;td width=&quot;175&quot;&gt;
						&lt;div id=&quot;menu_parent&quot; style=&quot;CURSOR: pointer&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
							&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;3&quot; border=&quot;0&quot; id=&quot;table5&quot;&gt;
								&lt;tr vAlign=&quot;bottom&quot; align=&quot;middle&quot;&gt;
									&lt;td&gt;
									&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;print=true&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;
									&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/rss/rss.aspx?Sub=Cutting%20Edge&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a onclick=&quot;return false;&quot; href=&quot;#&quot;&gt;more &lt;br /&gt;
									...&lt;/a&gt;&lt;/td&gt;
								&lt;/tr&gt;
							&lt;/table&gt;
						&lt;/div&gt;
						&lt;div style=&quot;FLOAT: right; WIDTH: 175px&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;div id=&quot;menu_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 5px; Z-INDEX: 100; LEFT: 659px; VISIBILITY: hidden; PADDING-BOTTOM: 5px; BORDER-LEFT: #999999 1px solid; WIDTH: 175px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; TOP: 308px; BACKGROUND-COLOR: white; align: right&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot; at_timeout=&quot;357518641&quot;&gt;
								&lt;table cellSpacing=&quot;3&quot; cellPadding=&quot;2&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table6&quot;&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot; width=&quot;30&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot; width=&quot;140&quot;&gt;
										&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;print=true&quot;&gt;
										Print&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										E-mail&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Add to Favorites&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Rate&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Cutting%20Edge&quot;&gt;
										RSS (Cutting Edge) &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/addtoany.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://www.addtoany.com/?linkname=Cutting%20Edge&amp;type=rss&amp;linkurl=http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Cutting%20Edge&quot;&gt;
										Add RSS to Any &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/library.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Related Articles&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/spaces.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://spaces.live.com/blogit.aspx?Title=Cutting Edge:+AJAX Application Architecture, Part 1&amp;Description=In the first of a two-part column, Dino explains AJAX from an architectural standpoint to help developers, architects, designers, and administrators better understand the issues that affect their sites.&amp;SourceURL=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&quot;&gt;
										Live Spaces &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/digg.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://digg.com/submit?phase=2&amp;url=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&amp;title=Cutting Edge:+AJAX Application Architecture, Part 1&amp;bodytext=In the first of a two-part column, Dino explains AJAX from an architectural standpoint to help developers, architects, designers, and administrators better understand the issues that affect their sites.&amp;topic=programming                &quot;&gt;
										Digg This &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/blogger.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://new.blogger.com/blog_this.pyra?t=In the first of a two-part column, Dino explains AJAX from an architectural standpoint to help developers, architects, designers, and administrators better understand the issues that affect their sites.&amp;u=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&amp;n='Cutting Edge:+AJAX Application Architecture, Part 1,'bloggerForm','scrollbars=no,width=475,height=300,top=175,left=75,status=yes,resizable=yes&quot;&gt;
										BlogThis! &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/slashdot.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://slashdot.org/bookmark.pl?url=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&amp;title=Cutting Edge:+AJAX Application Architecture, Part 1&quot;&gt;
										Slashdot &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/delicious.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://del.icio.us/post?url=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&amp;title=Cutting Edge:+AJAX Application Architecture, Part 1&quot;&gt;
										del.icio.us &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/technorati.png&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://technorati.com/faves?add=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&quot;&gt;
										Technorati &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&quot;&gt;
										Explore &lt;/a&gt;the code. &lt;br&gt;
										&lt;br&gt;
										&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/CuttingEdge2007_09.exe&quot;&gt;
										Download &lt;/a&gt;the code. &lt;/td&gt;
									&lt;/tr&gt;
								&lt;/table&gt;
							&lt;/div&gt;
						&lt;/div&gt;
&lt;SCRIPT type=text/javascript xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
      at_attach(&quot;menu_parent&quot;, &quot;menu_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
    &lt;/SCRIPT&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
				&lt;span id=&quot;dl_parent&quot; style=&quot;CURSOR: pointer&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
				&lt;a id=&quot;Code&quot; href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&quot;&gt;
				&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;Get &lt;br /&gt;
				the sample code for this article. &lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
				&lt;div id=&quot;dl_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 0px; Z-INDEX: 100; LEFT: 196px; VISIBILITY: hidden; PADDING-BOTTOM: 0px; BORDER-LEFT: #999999 1px solid; WIDTH: 500px; PADDING-TOP: 0px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; TOP: 339px; BACKGROUND-COLOR: white&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot; at_timeout=&quot;357518645&quot;&gt;
					&lt;table style=&quot;background-image: url('http://msdn.microsoft.com/msdnmag/images/codebg.gif')&quot; cellSpacing=&quot;0&quot; cellPadding=&quot;20&quot; width=&quot;500&quot; border=&quot;0&quot; id=&quot;table7&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;&lt;b&gt;NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&quot;&gt;
							Explore &lt;/a&gt;the sample code online! &lt;/b&gt;&lt;br&gt;
							&lt;br&gt;
							- or - &lt;br&gt;
							&lt;br&gt;
							&lt;b&gt;Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/CuttingEdge2007_09.exe&quot;&gt;
							CuttingEdge2007_09.exe&lt;/a&gt; (333KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
&lt;SCRIPT type=text/javascript&gt;
    at_attach(&quot;dl_parent&quot;, &quot;dl_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
  &lt;/SCRIPT&gt;
				&lt;br&gt;
				&lt;br&gt;
¡¡&lt;hr&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table8&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;50%&quot;&gt;
						&lt;img class=&quot;clsImgButton&quot; id=&quot;contentbtn&quot; onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; height=&quot;9&quot; alt=&quot;&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/minus.gif&quot; width=&quot;9&quot; align=&quot;absMiddle&quot; vspace=&quot;2&quot;&gt;&lt;a onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; name=&quot;contents&quot; href=&quot;#void&quot;&gt;&lt;b&gt;Contents&lt;/b&gt;&lt;/a&gt;&lt;br&gt;
¡¡&lt;div id=&quot;contentmenu&quot; style=&quot;MARGIN-TOP: 10px; DISPLAY: block; MARGIN-LEFT: 20px&quot;&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S1&quot;&gt;AJAX to the Rescue&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S2&quot;&gt;The AJAX Architecture&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S3&quot;&gt;What's an AJAX &lt;br /&gt;
							Framework?&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S4&quot;&gt;ASP.NET AJAX Extensions&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S5&quot;&gt;A Look at Partial &lt;br /&gt;
							Rendering&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S6&quot;&gt;Anatomy of an AJAX &lt;br /&gt;
							Postback&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S7&quot;&gt;Optimization Techniques &lt;br /&gt;
							for Partial Rendering&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S8&quot;&gt;Weighing Partial &lt;br /&gt;
							Rendering&lt;/a&gt;&lt;br&gt;
¡¡&lt;/div&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;hr&gt;&lt;br&gt;
¡¡&lt;div class=&quot;articletext&quot;&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE001&quot;&gt;¡¡&lt;/p&gt;
					&lt;div class=&quot;dropcap&quot;&gt;
						W&lt;/div&gt;
					hether you're a system administrator, a designer, or a &lt;br /&gt;
					developer, your job will be significantly affected by AJAX. &lt;br /&gt;
					Administrators have to ensure that the security bar is still &lt;br /&gt;
					high enough to face new types of possible attacks. Intranet &lt;br /&gt;
					administrators have to guarantee that JavaScript is not &lt;br /&gt;
					disabled on any browsers. Web designers have new challenges &lt;br /&gt;
					to pursue due to features attainable with AJAX that were &lt;br /&gt;
					once impossible or impractical. And developers have a new &lt;br /&gt;
					API and a new overall approach to programming to become &lt;br /&gt;
					familiar with. All that said, what does AJAX mean for &lt;br /&gt;
					architects?&lt;br /&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE002&quot;&gt;AJAX applications &lt;br /&gt;
					are challenging because they introduce brand-new concepts &lt;br /&gt;
					and a new foundation. The role of the architect is essential &lt;br /&gt;
					because the AJAX paradigm straddles both the client and the &lt;br /&gt;
					server environments. A clear architectural vision is &lt;br /&gt;
					critical for determining what logic and processing happens &lt;br /&gt;
					on the client and what remains on the server, as well as &lt;br /&gt;
					what data objects the client and the server are able to &lt;br /&gt;
					exchange.&lt;/p&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;AJAX to the Rescue&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE003&quot;&gt;The Web was originally used to &lt;br /&gt;
					share static pages of information. Over just a few years, it &lt;br /&gt;
					evolved into a far more dynamic medium. Today, the Web is &lt;br /&gt;
					made up of extremely interactive pages; however, it still &lt;br /&gt;
					relies heavily on a paradigm that is based on full-page &lt;br /&gt;
					transitions. The more the user interacts with a page, the &lt;br /&gt;
					more frequently pages must be created and served back to the &lt;br /&gt;
					user's browser. There are many negative consequences that &lt;br /&gt;
					result from serving interactive pages in this manner, such &lt;br /&gt;
					as slow page refreshes and flickering. It's an inelegant &lt;br /&gt;
					solution that frequently leads to a poor user experience. &lt;br /&gt;
					AJAX brings about a much-desired shift in this paradigm that &lt;br /&gt;
					allows for cleaner Web applications and it lays the &lt;br /&gt;
					groundwork for a new generation of applications. AJAX is &lt;br /&gt;
					really about the end user. With AJAX features, a Web &lt;br /&gt;
					application is much more interactive, more responsive. It's &lt;br /&gt;
					faster and friendlier. The user is encouraged to do more &lt;br /&gt;
					with the page as interaction and responses (and feedback in &lt;br /&gt;
					case of slow operations) are all handled more elegantly. &lt;br /&gt;
					Overall, the user has a much better experience.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE004&quot;&gt;With AJAX, more &lt;br /&gt;
					code is executed on the browser and this requires more &lt;br /&gt;
					script being given to the client pages. But this leaves some &lt;br /&gt;
					big questions to be answered. What kind of script? Who will &lt;br /&gt;
					write this script? And what architectural principles and &lt;br /&gt;
					patterns will this script adhere to?&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE005&quot;&gt;In this column, &lt;br /&gt;
					I'll explain AJAX from an architectural standpoint and help &lt;br /&gt;
					you, the developers and architects, make thoughtful choices. &lt;br /&gt;
					At the same time, I'll give designers and administrators &lt;br /&gt;
					enough context information to help make their jobs easier. &lt;br /&gt;
					This is a pretty big topic, so I'm dividing it into two &lt;br /&gt;
					parts. Don't miss next month's column when I'll continue &lt;br /&gt;
					this discussion.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;The AJAX Architecture&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE006&quot;&gt;If you're considering AJAX, take a &lt;br /&gt;
					look at&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;1&lt;/span&gt;, which illustrates the architectural &lt;br /&gt;
					implications of such a move. A traditional Web application &lt;br /&gt;
					does everything on the server. Only occasionally does the &lt;br /&gt;
					application emit script code to run a task on the client&amp;#8212;for &lt;br /&gt;
					example, to handle data validation.&lt;/p&gt;
					&lt;div id=&quot;503600002&quot; style=&quot;DISPLAY: none; WIDTH: 600px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('503600002', '335400002');&quot;&gt;
						&lt;img height=&quot;503&quot; alt=&quot;Figure 1 Classic Web Paradigm versus AJAX Paradigm&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/fig01_L.gif&quot; width=&quot;600&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 1&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Classic &lt;br /&gt;
						Web Paradigm versus AJAX Paradigm (Click the image for a &lt;br /&gt;
						smaller view) &lt;/span&gt;&lt;/div&gt;
					&lt;div id=&quot;335400002&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 400px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('335400002', '503600002');&quot;&gt;
						&lt;img height=&quot;335&quot; alt=&quot;Figure 1 Classic Web Paradigm versus AJAX Paradigm&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/fig01.gif&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 1&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Classic &lt;br /&gt;
						Web Paradigm versus AJAX Paradigm (Click the image for a &lt;br /&gt;
						larger view) &lt;/span&gt;&lt;/div&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE007&quot;&gt;An AJAX &lt;br /&gt;
					application uses a client-side framework that takes care of &lt;br /&gt;
					issuing calls to the Web server. An AJAX server-side &lt;br /&gt;
					framework then takes care of the request and returns a data &lt;br /&gt;
					feed to the client. This will often be a JavaScript Object &lt;br /&gt;
					Notation (JSON) data stream, but other formats&amp;#8212;such as XML, &lt;br /&gt;
					RSS, and CSV&amp;#8212;can be used.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE008&quot;&gt;The client &lt;br /&gt;
					receives data feeds and updates the UI using JavaScript. The &lt;br /&gt;
					server responds to requests by returning raw data, encoded &lt;br /&gt;
					in a given format. Bandwidth consumption is minimized, the &lt;br /&gt;
					speed of the app increases since requests take less time to &lt;br /&gt;
					complete, and UI updates are able to take effect with no &lt;br /&gt;
					visible postback. But while this solves many problems, the &lt;br /&gt;
					increase in action on the client also brings about new &lt;br /&gt;
					issues, such as new coding practices, new security hazards, &lt;br /&gt;
					accessibility concerns, and so on.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;What's an AJAX Framework?&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE009&quot;&gt;To keep AJAX alive in a Web page, a &lt;br /&gt;
					few conditions must be met. First, you need JavaScript &lt;br /&gt;
					support from the browser. A full-time Internet connection is &lt;br /&gt;
					also required&amp;#8212;an AJAX application can't work offline. When &lt;br /&gt;
					all the requests are made at the page level, as they are &lt;br /&gt;
					with non-AJAX applications, the browser can offer to &lt;br /&gt;
					navigate through a cached set of these pages, and thus can &lt;br /&gt;
					proceed offline. This same behavior would have to be coded &lt;br /&gt;
					explicitly in the script-based framework that partners with &lt;br /&gt;
					the browser in an AJAX application. There's a lot going on &lt;br /&gt;
					in this area and some new tools to help are being developed. &lt;br /&gt;
					The ability to take AJAX applications offline is a challenge &lt;br /&gt;
					for many software vendors.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE010&quot;&gt;A special &lt;br /&gt;
					framework is required by any serious AJAX application. &lt;br /&gt;
					Usually the framework of choice is articulated in separate &lt;br /&gt;
					client and server parts.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE011&quot;&gt;There are two &lt;br /&gt;
					main types of script code in an AJAX page: system-level code &lt;br /&gt;
					from the framework of choice and user-level code that &lt;br /&gt;
					implements the page's expected behavior. The system-level &lt;br /&gt;
					code provides the engine used to send asynchronous requests &lt;br /&gt;
					to the Web server and process any responses. The user-level &lt;br /&gt;
					code updates the UI of the page, essentially using Document &lt;br /&gt;
					Object Model (DOM) scripting. So here's one of those &lt;br /&gt;
					questions I mentioned earlier: Who writes which? To discuss &lt;br /&gt;
					this, I'll focus on a particular AJAX framework&amp;#8212;ASP.NET AJAX &lt;br /&gt;
					Extensions.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;ASP.NET AJAX Extensions&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE012&quot;&gt;An extension to ASP.NET 2.0, &lt;br /&gt;
					ASP.NET AJAX Extensions provides AJAX capabilities to new &lt;br /&gt;
					and existing Web sites. There are two programming models for &lt;br /&gt;
					ASP.NET AJAX: partial rendering and remote services. They &lt;br /&gt;
					assume two radically different architectures in the &lt;br /&gt;
					application and consequently have different pros and cons. &lt;br /&gt;
					(You've probably already figured out that most features in &lt;br /&gt;
					AJAX involve trade-offs.)&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE013&quot;&gt;In brief, partial &lt;br /&gt;
					rendering allows you to maintain an architecture similar to &lt;br /&gt;
					a classic ASP.NET 2.0 application. It just provides you with &lt;br /&gt;
					a set of new server-side tools you can use to implement &lt;br /&gt;
					flicker-free page updates.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE014&quot;&gt;Remote services, &lt;br /&gt;
					on the other hand, involve a service-oriented back end &lt;br /&gt;
					invoked by a relatively script-heavy AJAX front end. Nearly &lt;br /&gt;
					all fundamental application processes&amp;#8212;including &lt;br /&gt;
					authentication, data paging, and sorting&amp;#8212;must be redesigned. &lt;br /&gt;
					Server-side code must be factored out to &lt;br /&gt;
					application-specific services and a format (such as JSON) &lt;br /&gt;
					must be selected for data exchange. Finally, a front end &lt;br /&gt;
					must be arranged, paying due attention to limit your coding &lt;br /&gt;
					to UI-level tasks and keeping most business logic off the &lt;br /&gt;
					client.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE015&quot;&gt;The remote &lt;br /&gt;
					services approach provides a more complete AJAX experience, &lt;br /&gt;
					while partial rendering offers a smoother transition with a &lt;br /&gt;
					progressive enhancement of the features already in your &lt;br /&gt;
					existing application.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE016&quot;&gt;The two &lt;br /&gt;
					approaches can be mixed to some extent. You can, for &lt;br /&gt;
					instance, keep the same traditional Web architecture, add &lt;br /&gt;
					some flicker-free updates here and there, and then take time &lt;br /&gt;
					to refactor some key features in a service-oriented manner. &lt;br /&gt;
					ASP.NET AJAX Extensions provides several key ingredients, &lt;br /&gt;
					but significant pieces of the work for creating great AJAX &lt;br /&gt;
					applications is still up to you.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig2'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;fig=true#fig2&quot;&gt;
					Figure&amp;nbsp;2&lt;/a&gt; shows the client and server components of the &lt;br /&gt;
					ASP.NET AJAX Extensions framework.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;A Look at Partial Rendering&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE017&quot;&gt;Jeff Prosise's June 2007 Wicked &lt;br /&gt;
					Code column (&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/WickedCode&quot;&gt;msdn.microsoft.com/msdnmag/issues/07/06/WickedCode&lt;/a&gt;) &lt;br /&gt;
					offers an excellent discussion about partial rendering with &lt;br /&gt;
					ASP.NET AJAX. From an architectural viewpoint, partial &lt;br /&gt;
					rendering doesn't add anything new. It's just a cool way of &lt;br /&gt;
					enhancing legacy applications with some AJAX &lt;br /&gt;
					capabilities&amp;#8212;the most important of which is flicker-free &lt;br /&gt;
					page updates.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE018&quot;&gt;Partial rendering &lt;br /&gt;
					doesn't require learning a lot of new skills, and it has a &lt;br /&gt;
					very limited impact on existing code. It also offers a &lt;br /&gt;
					straightforward fallback mechanism for aspects of an &lt;br /&gt;
					application that may suffer from the adoption of &lt;br /&gt;
					AJAX&amp;#8212;security and accessibility, for example. Basically, if &lt;br /&gt;
					in the upgrade process you get into trouble when turning &lt;br /&gt;
					certain parts of existing code into AJAX, you can just leave &lt;br /&gt;
					those code blocks as they were and move on.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE019&quot;&gt;A partial &lt;br /&gt;
					rendering request is often referred to as an AJAX postback. &lt;br /&gt;
					The term is quite appropriate, perfectly representing what &lt;br /&gt;
					really happens. An AJAX postback is like a classic ASP.NET &lt;br /&gt;
					postback, except that it is carried out by a piece of script &lt;br /&gt;
					code defined in the client-side ASP.NET AJAX library. &lt;br /&gt;
					Although dressed like a pure AJAX remote call, an AJAX &lt;br /&gt;
					postback looks like a regular postback request to the &lt;br /&gt;
					ASP.NET runtime components. Once on the server, the request &lt;br /&gt;
					goes through the typical lifecycle of postback requests and &lt;br /&gt;
					raises such events as Init, Load, and PreRender. On the &lt;br /&gt;
					server, an AJAX postback differs from a classic ASP.NET &lt;br /&gt;
					postback only in the algorithm it uses to render the final &lt;br /&gt;
					markup. The different algorithm is key to the improved &lt;br /&gt;
					performance and absence of page flickering. However, the &lt;br /&gt;
					application model remains the same as in ASP.NET.&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;3&lt;/span&gt; shows the modified lifecycle of an AJAX &lt;br /&gt;
					postback request.&lt;/p&gt;
					&lt;div id=&quot;1364400004&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 400px&quot;&gt;
						&lt;img height=&quot;1364&quot; alt=&quot;Figure 3 Lifecycle of an AJAX Postback&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/fig03.gif&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 3&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Lifecycle &lt;br /&gt;
						of an AJAX Postback&lt;/span&gt;&lt;/div&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE020&quot;&gt;Everything is the &lt;br /&gt;
					same in the AJAX and ASP.NET postbacks, except the &lt;br /&gt;
					implementation of the rendering stage. An AJAX postback &lt;br /&gt;
					still fires notification events, such as Load and PreRender, &lt;br /&gt;
					and it still processes viewstate information and raises &lt;br /&gt;
					state changed and postback events, such as TextChanged and &lt;br /&gt;
					Click.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE021&quot;&gt;An ASP.NET AJAX &lt;br /&gt;
					page must include one instance of the ScriptManager control. &lt;br /&gt;
					This control is the real nerve center of ASP.NET AJAX pages. &lt;br /&gt;
					It takes care of linking the page to any required framework &lt;br /&gt;
					script files and orchestrates partial rendering if it &lt;br /&gt;
					detects that an AJAX postback is occurring. The &lt;br /&gt;
					ScriptManager control checks an HTTP header in the request &lt;br /&gt;
					to determine whether the request is an AJAX postback. The &lt;br /&gt;
					following is an excerpt from the MicrosoftAjaxWebForms.js &lt;br /&gt;
					file that sets the HTTP header before triggering the AJAX &lt;br /&gt;
					request:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE022&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;   request.get_headers()['X-MicrosoftAjax'] = &lt;br /&gt;
       'Delta=true';&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE023&quot;&gt;To see what makes &lt;br /&gt;
					the rendering stage different for an AJAX postback, take a &lt;br /&gt;
					close look at the following excerpt from the &lt;br /&gt;
					System.Web.Extensions assembly:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE024&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;   protected override void OnPreRender(EventArgs&amp;#8201;e)&amp;#8201;{&lt;br /&gt;
       base.OnPreRender(e);&lt;br /&gt;
       if (IsInAsyncPostBack) &lt;br /&gt;
           PageRequestManager.OnPreRender();&lt;br /&gt;
   }&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE025&quot;&gt;
					In particular, the code snippet shown above comes from the &lt;br /&gt;
					ScriptManager control. As you can see, the script manager &lt;br /&gt;
					registers a pre-rendering event handler. When fired, the &lt;br /&gt;
					handler detects whether it is engaged in an AJAX postback &lt;br /&gt;
					and, if so, invokes a method from the PageRequestManager &lt;br /&gt;
					internal class. The OnPreRender method on the &lt;br /&gt;
					PageRequestManager class does the following:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE026&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;   internal void OnPreRender()&lt;br /&gt;
   {&lt;br /&gt;
       _owner.SetRenderMethodDelegate(&lt;br /&gt;
          new&amp;#8201;RenderMethod(this.RenderPageCallback));&lt;br /&gt;
   }&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE027&quot;&gt;Quite simply, the &lt;br /&gt;
					method sets a specific subroutine to render the markup for &lt;br /&gt;
					the current request. SetRenderMethodDelegate is a method &lt;br /&gt;
					defined on the System.Web.UI.Control class. Not intended for &lt;br /&gt;
					public use, this method basically assigns an event handler &lt;br /&gt;
					that the page or the control will use to render its &lt;br /&gt;
					contents. In the preceding code snippet, the method is &lt;br /&gt;
					invoked on the current page and ends up overriding the whole &lt;br /&gt;
					rendering process for the current request. The actual code &lt;br /&gt;
					responsible for the markup of an AJAX postback is therefore &lt;br /&gt;
					defined in the RenderPageCallback method&amp;#8212;an internal method &lt;br /&gt;
					in the PageRequestManager class. (For more information on &lt;br /&gt;
					the ScriptManager control, see the article by Ben Rush in &lt;br /&gt;
					this issue of MSDN&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt; Magazine.)&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE028&quot;&gt;Basically the &lt;br /&gt;
					modified rendering process for an AJAX postback loops &lt;br /&gt;
					through all updatable panels in the page that are involved &lt;br /&gt;
					with the postback and accumulates the markup of each. All &lt;br /&gt;
					markup chunks, along with hidden fields and any error &lt;br /&gt;
					information, are packed into a response stream and passed to &lt;br /&gt;
					the client. Now let's dissect a typical partial rendering &lt;br /&gt;
					call in the context of a sample page.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Anatomy of an AJAX Postback&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE029&quot;&gt;To make an ASP.NET page a partially &lt;br /&gt;
					rendered page, you must first add a script manager to the &lt;br /&gt;
					page and then define independently updatable regions by &lt;br /&gt;
					wrapping them with an UpdatePanel control. Here's an &lt;br /&gt;
					example:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE030&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:ScriptManager runat=&quot;server&quot; /&gt;
&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot;&gt;
   &lt;ContentTemplate&gt;
      &lt;%-- Markup of the region goes here --%&gt;
   &lt;/ContentTemplate&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE031&quot;&gt;
					The UpdatePanel control doesn't alter in any way the visible &lt;br /&gt;
					markup generated for the region. It simply adds a &lt;br /&gt;
					surrounding &lt;div&gt; tag to the original markup:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE032&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;div id=&quot;UpdatePanel1&quot;&gt;
      &lt;%-- Markup of the region goes here --%&gt;
&lt;/div&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE033&quot;&gt;What triggers an &lt;br /&gt;
					AJAX postback? How is it managed? And by whom? Whenever the &lt;br /&gt;
					script manager detects one or more UpdatePanel controls in &lt;br /&gt;
					the page, it emits the block of script as in the following:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE034&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;
Sys.WebForms.PageRequestManager._initialize('ScriptManager1', &lt;br /&gt;
        document.getElementById('form1'));&lt;br /&gt;
Sys.WebForms.PageRequestManager.getInstance()._updateControls(&lt;br /&gt;
    ['tUpdatePanel1','tUpdatePanel2'], [], [], 90);&lt;br /&gt;
&lt;/script&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE035&quot;&gt;
					The _initialize method is a static method on the client-side &lt;br /&gt;
					PageRequestManager object (see MicrosoftAjaxWebForms.js). It &lt;br /&gt;
					creates a global instance of the PageRequestManager class &lt;br /&gt;
					and initializes it. The class acts as a singleton and the &lt;br /&gt;
					only available instance can be retrieved later through the &lt;br /&gt;
					getInstance method. The second statement of the preceding &lt;br /&gt;
					snippet registers an array of UpdatePanel controls with the &lt;br /&gt;
					client framework. Each server-side UpdatePanel control is &lt;br /&gt;
					referenced through its ID.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE036&quot;&gt;The key action &lt;br /&gt;
					happening here is inside the _initialize method. As I said, &lt;br /&gt;
					after creating the singleton instance of the class, the code &lt;br /&gt;
					initializes it. At this time, among other things, a handler &lt;br /&gt;
					is registered for the submit event of the DOM form object. &lt;br /&gt;
					This means that whenever the page submits a form, the AJAX &lt;br /&gt;
					script kicks in and places the request using XMLHttpRequest &lt;br /&gt;
					instead of letting the request go through a normal browser &lt;br /&gt;
					postback. The original set of form fields is maintained and &lt;br /&gt;
					some extra information is appended for the convenience of &lt;br /&gt;
					the server-side script manager. Hence, an AJAX postback &lt;br /&gt;
					uploads a bit more information than a regular ASP.NET &lt;br /&gt;
					postback.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE037&quot;&gt;The viewstate, as &lt;br /&gt;
					well as any other hidden fields, are carried out and &lt;br /&gt;
					uploaded to the server with the request. On the way back, an &lt;br /&gt;
					updated viewstate is downloaded along with new hidden &lt;br /&gt;
					fields, if any, and a likely shorter markup. In particular, &lt;br /&gt;
					the response includes only the markup for the updatable &lt;br /&gt;
					regions that have been modified during the postback. The &lt;br /&gt;
					list includes the UpdatePanel control that triggered the &lt;br /&gt;
					postback (and any nested panels), any other UpdatePanel &lt;br /&gt;
					controls in the page that have the UpdateMode property set &lt;br /&gt;
					to Always, and any UpdatePanel control that is &lt;br /&gt;
					programmatically refreshed. The following code is an example &lt;br /&gt;
					of how to programmatically refresh a panel based on run-time &lt;br /&gt;
					conditions:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE038&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;   UpdatePanel1.Update()&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE039&quot;&gt;Consider the &lt;br /&gt;
					sample page shown in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig4'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;fig=true#fig4&quot;&gt;
					Figure&amp;nbsp;4&lt;/a&gt; and the response returned. You can use a &lt;br /&gt;
					variety of tools to monitor inbound and outbound HTTP &lt;br /&gt;
					packets. For this column, I used Nikhil Kothari's Web &lt;br /&gt;
					Development Helper tool, which you can download for free at&lt;br /&gt;
					&lt;a href=&quot;http://projects.nikhilk.net/Projects/WebDevHelper.aspx&quot;&gt;
					projects.nikhilk.net/Projects/WebDevHelper.aspx&lt;/a&gt;.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE040&quot;&gt;The response of &lt;br /&gt;
					an AJAX postback is a text stream that can be seen as a &lt;br /&gt;
					table of records with Size, Type, ID, and Content columns. &lt;br /&gt;
					Each record is referred to as a delta node.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig5'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;fig=true#fig5&quot;&gt;
					Figure&amp;nbsp;5&lt;/a&gt; shows the table you obtain for my sample page.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE041&quot;&gt;A delta node &lt;br /&gt;
					identifies a possible change that occurred during the AJAX &lt;br /&gt;
					postback. Not all responses feature the same set of delta &lt;br /&gt;
					nodes; it depends on what happens during the server &lt;br /&gt;
					lifecycle of the request and the structure of the original &lt;br /&gt;
					markup.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE042&quot;&gt;Figure 6 lists &lt;br /&gt;
					all currently supported delta nodes. The JavaScript code &lt;br /&gt;
					that is responsible for processing the delta table can be &lt;br /&gt;
					found in the MicrosoftAjaxWebForms.js file.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Optimization Techniques for Partial &lt;br /&gt;
					Rendering&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE043&quot;&gt;After examining&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig6'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;fig=true#fig6&quot;&gt;
					Figure&amp;nbsp;6&lt;/a&gt;, you'll note that the response is made up of &lt;br /&gt;
					two big blocks: markup and viewstate. Event validation data &lt;br /&gt;
					(a security-related feature of ASP.NET 2.0), custom hidden &lt;br /&gt;
					fields, scripts, and any other types of nodes usually take &lt;br /&gt;
					just a few dozen bytes all together. The size of the &lt;br /&gt;
					viewstate is an old problem for ASP.NET pages. Partial &lt;br /&gt;
					rendering with ASP.NET AJAX, unfortunately, does nothing to &lt;br /&gt;
					correct the problem. You still need to keep your viewstate &lt;br /&gt;
					lean and mean to improve download time. So what can you do &lt;br /&gt;
					to reduce the markup for a page? Essentially, you can have &lt;br /&gt;
					smaller panels that bring back just the minimum amount of &lt;br /&gt;
					markup you need for that particular click.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE044&quot;&gt;Look again at the &lt;br /&gt;
					code in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig4'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;fig=true#fig4&quot;&gt;
					Figure&amp;nbsp;4&lt;/a&gt;. The logic in the page is fairly simple, but it &lt;br /&gt;
					illustrates the point. Basically, when the user clicks the &lt;br /&gt;
					button, any content in the TextBox is used to update the &lt;br /&gt;
					label.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE045&quot;&gt;The page contains &lt;br /&gt;
					only one UpdatePanel control that wraps everything: textbox, &lt;br /&gt;
					button, separator, and label. Logically speaking, this may &lt;br /&gt;
					be acceptable. If you have to identify a region in the page &lt;br /&gt;
					to refresh autonomously, this is a valid option. Defined in &lt;br /&gt;
					this way, though, the region contains a significant portion &lt;br /&gt;
					of code that isn't updated across postbacks. The TextBox and &lt;br /&gt;
					Button controls, for instance, are not updated in this page &lt;br /&gt;
					and the &lt;hr&gt; separator is plain static text.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE046&quot;&gt;A better option &lt;br /&gt;
					would be to reduce the UpdatePanel to comprehend the sole &lt;br /&gt;
					Label control&amp;#8212;the unique server control that gets updated in &lt;br /&gt;
					any postback triggered by the button. In general, you should &lt;br /&gt;
					carefully identify postback relationships between &lt;br /&gt;
					controls&amp;#8212;basically examining which updates which&amp;#8212;and design &lt;br /&gt;
					updatable panels to include the minimum number of controls &lt;br /&gt;
					for a given user action. In the context of the sample shown &lt;br /&gt;
					in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig4'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=&amp;fig=true#fig4&quot;&gt;
					Figure&amp;nbsp;4&lt;/a&gt;, here's a better schema:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE047&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:TextBox runat=&quot;server&quot; ID=&quot;TextBox1&quot; /&gt;
&lt;asp:Button runat=&quot;server&quot; ID=&quot;Button1&quot; Text=&quot;Update&quot; &lt;br /&gt;
     OnClick=&quot;Button1_Click&quot; /&gt;
&lt;hr /&gt;
&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot;&gt;
   &lt;ContentTemplate&gt;
       &lt;asp:Label runat=&quot;server&quot; ID=&quot;Label1&quot; /&gt;
   &lt;/ContentTemplate&gt;
   &lt;Triggers&gt;
      &lt;asp:AsyncPostBackTrigger ControlID=&quot;Button1&quot; /&gt;
   &lt;/Triggers&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE048&quot;&gt;The UpdatePanel &lt;br /&gt;
					control now contains only the Label control. This means that &lt;br /&gt;
					no (unchanged) markup will be returned for the textbox and &lt;br /&gt;
					button controls. By default, an UpdatePanel control is &lt;br /&gt;
					refreshed when either one of its child controls causes a &lt;br /&gt;
					postback or another UpdatePanel in the page is refreshed. &lt;br /&gt;
					This behavior can be altered with some public &lt;br /&gt;
					properties&amp;#8212;namely UpdateMode, ChildrenAsTriggers, and &lt;br /&gt;
					Triggers.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE049&quot;&gt;In particular, &lt;br /&gt;
					UpdateMode determines whether the UpdatePanel is set to &lt;br /&gt;
					refresh unconditionally (the default) or only under certain &lt;br /&gt;
					conditions. If you want a conditional refresh&amp;#8212;a key setting &lt;br /&gt;
					for optimizing updatable panels&amp;#8212;start by setting UpdateMode &lt;br /&gt;
					to Conditional:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE050&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot; &lt;br /&gt;
     UpdateMode=&quot;Conditional&quot;&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE051&quot;&gt;
					Note, though, that conditional updates are relevant only if &lt;br /&gt;
					you have multiple panels in a page.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE052&quot;&gt;There might be &lt;br /&gt;
					situations where you find it difficult to split a page into &lt;br /&gt;
					a set of normalized panels. A technique that might help you &lt;br /&gt;
					in these cases is preventing children from triggering &lt;br /&gt;
					postbacks. The ChildrenAsTriggers property is a Boolean &lt;br /&gt;
					property (true by default) that determines whether child &lt;br /&gt;
					controls of a panel act as triggers of AJAX postback events. &lt;br /&gt;
					In the following snippet, the Button1 control doesn't cause &lt;br /&gt;
					a refresh of the panel:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE053&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot; &lt;br /&gt;
     ChildrenAsTriggers=&quot;false&quot;&gt;
   &lt;ContentTemplate&gt;
       &lt;asp:Button runat=&quot;server&quot; ID=&quot;Button1&quot; Text=&quot;Update&quot; &lt;br /&gt;
          OnClick=&quot;Button1_Click&quot; /&gt;
       &lt;asp:Label runat=&quot;server&quot; ID=&quot;Label1&quot; /&gt;
   &lt;/ContentTemplate&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE054&quot;&gt;
					When a child button is clicked in a panel configured like &lt;br /&gt;
					this, an AJAX postback still occurs to execute any postback &lt;br /&gt;
					code attached to the button&amp;#8212;for instance, the Button1_Click &lt;br /&gt;
					method&amp;#8212;but no markup is returned to refresh the panel.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE055&quot;&gt;The third &lt;br /&gt;
					property involved with conditional refreshing is Triggers. &lt;br /&gt;
					This is a collection property and lists control events that &lt;br /&gt;
					will command a refresh of the panel, like so:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE056&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot;&gt;
   &lt;ContentTemplate&gt;
       &lt;asp:Label runat=&quot;server&quot; ID=&quot;Label1&quot; /&gt;
   &lt;/ContentTemplate&gt;
   &lt;Triggers&gt;
      &lt;asp:AsyncPostBackTrigger ControlID=&quot;Button1&quot;&lt;br /&gt;
           EventName=&quot;Click&quot; /&gt;
   &lt;/Triggers&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE057&quot;&gt;
					In this case, the Click event on Button1 will refresh the &lt;br /&gt;
					panel. The Button1 control may be placed anywhere in the &lt;br /&gt;
					page. Note that I'm talking about server events. In other &lt;br /&gt;
					words, if you want to refresh a panel when the user changes &lt;br /&gt;
					the selection on a dropdown list, you must first add the &lt;br /&gt;
					AutoPostBack attribute to the dropdown list.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE058&quot;&gt;You can still &lt;br /&gt;
					configure a panel to refresh when a state-changed event &lt;br /&gt;
					occurs on the server during an AJAX postback. Consider the &lt;br /&gt;
					following code:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE059&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:TextBox runat=&quot;server&quot; ID=&quot;TextBox1&quot; /&gt;
&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot;&gt;
   &lt;ContentTemplate&gt;
       &lt;asp:Label runat=&quot;server&quot; ID=&quot;Label1&quot; /&gt;
   &lt;/ContentTemplate&gt;
   &lt;Triggers&gt;
      &lt;asp:AsyncPostBackTrigger&lt;br /&gt;
           ControlID=&quot;TextBox1&quot;&lt;br /&gt;
           EventName=&quot;TextChanged&quot; /&gt;
   &lt;/Triggers&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE060&quot;&gt;
					The label is refreshed whenever the content of TextBox1 &lt;br /&gt;
					changes:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE061&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _&lt;br /&gt;
Handles TextBox1.TextChanged&lt;br /&gt;
   Label1.Text = TextBox1.Text&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE062&quot;&gt;
					The TextChanged event, as well as other state-changed &lt;br /&gt;
					events, are server-side events that fire as a consequence of &lt;br /&gt;
					a postback. The page still needs a button, or an &lt;br /&gt;
					auto-postback control, to trigger the postback in order to &lt;br /&gt;
					update the label.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE063&quot;&gt;The chart in&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;7&lt;/span&gt; summarizes the potential benefits of &lt;br /&gt;
					applying optimization techniques to updatable panels. With &lt;br /&gt;
					partial rendering, the size of the request packet increases &lt;br /&gt;
					a bit, but even in the least optimized case the response you &lt;br /&gt;
					get back is smaller than in a classic ASP.NET scenario. And, &lt;br /&gt;
					of course, users won't experience flickering.&lt;/p&gt;
					&lt;div id=&quot;475700006&quot; style=&quot;DISPLAY: none; WIDTH: 700px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('475700006', '271400006');&quot;&gt;
						&lt;img height=&quot;475&quot; alt=&quot;Figure 7 Benefits of Optimizing Updatable Panels&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/fig07_L.gif&quot; width=&quot;700&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 7&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Benefits &lt;br /&gt;
						of Optimizing Updatable Panels (Click the image for a &lt;br /&gt;
						smaller view) &lt;/span&gt;&lt;/div&gt;
					&lt;div id=&quot;271400006&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 400px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('271400006', '475700006');&quot;&gt;
						&lt;img height=&quot;271&quot; alt=&quot;Figure 7 Benefits of Optimizing Updatable Panels&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/fig07.gif&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 7&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;Benefits &lt;br /&gt;
						of Optimizing Updatable Panels (Click the image for a &lt;br /&gt;
						larger view) &lt;/span&gt;&lt;/div&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE064&quot;&gt;I should warn &lt;br /&gt;
					you, though, that pages with a huge viewstate may not &lt;br /&gt;
					benefit much from partial rendering. You might save 5KB of &lt;br /&gt;
					markup, but that's faint relief if you have to carry 30KB of &lt;br /&gt;
					viewstate.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE065&quot;&gt;But sometimes, &lt;br /&gt;
					viewstate is only an innocent scapegoat for an issue that &lt;br /&gt;
					originated elsewhere. Imagine you have a calendar control in &lt;br /&gt;
					an ASP.NET page and you use updatable panels to keep the &lt;br /&gt;
					refresh smooth:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE066&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot;&gt;
   &lt;ContentTemplate&gt;
       &lt;asp:Calendar runat=&quot;server&quot; ID=&quot;Calendar1&quot; /&gt;
   &lt;/ContentTemplate&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE067&quot;&gt;The markup for &lt;br /&gt;
					this fragment is no less than 7KB and can grow up to 10KB if &lt;br /&gt;
					you add some styles. Now, if you disable the viewstate on &lt;br /&gt;
					the calendar, you save approximately 1KB of data, which is &lt;br /&gt;
					only about 10 percent of the total size. This is because the &lt;br /&gt;
					Calendar is a heavy control in terms of markup. The &lt;br /&gt;
					viewstate has little to do with it. An ASP.NET AJAX page &lt;br /&gt;
					shouldn't use a Calendar control for date-picking functions. &lt;br /&gt;
					Instead, the AJAX Control Toolkit provides an extender&amp;#8212;the &lt;br /&gt;
					CalendarExtender control&amp;#8212;that, when added to a plain &lt;br /&gt;
					TextBox, lets you pick dates, effectively saving 10KB of &lt;br /&gt;
					markup.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE068&quot;&gt;This code pops up &lt;br /&gt;
					a calendar whenever the textbox gets the input focus:&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE069&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;&lt;asp:textbox runat=&quot;server&quot; ID=&quot;TextBox1&quot; /&gt;
&lt;act:CalendarExtender ID=&quot;CalendarExtender1&quot; runat=&quot;server&quot;&lt;br /&gt;
    TargetControlID=&quot;TextBox1&quot;   &lt;br /&gt;
    OnClientDateSelectionChanged=&quot;updateLabel&quot;&lt;br /&gt;
    Format=&quot;dd/MM/yyyy&quot; /&gt;
&lt;br /&gt;
&lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;UpdatePanel1&quot; &lt;br /&gt;
     UpdateMode=&quot;Conditional&quot;&gt;
    &lt;ContentTemplate&gt;
        &lt;asp:label runat=&quot;server&quot; ID=&quot;Label1&quot; /&gt;
    &lt;/ContentTemplate&gt;
&lt;/asp:UpdatePanel&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE070&quot;&gt;
					The calendar is created entirely on the client and only &lt;br /&gt;
					requires a couple of small icons to be downloaded. The &lt;br /&gt;
					extender automatically writes the selected date to the &lt;br /&gt;
					companion TextBox. However, with a bit of JavaScript code, &lt;br /&gt;
					you can handle the client date selection event and do &lt;br /&gt;
					whatever you need.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Weighing Partial Rendering&lt;/span&gt;&lt;br&gt;
¡¡&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE071&quot;&gt;Partial rendering is the quickest &lt;br /&gt;
					way of spicing up an ASP.NET Web site with AJAX &lt;br /&gt;
					capabilities. It requires neither new skills nor a new &lt;br /&gt;
					architecture. Instead, it lends itself to progressively &lt;br /&gt;
					enhancing an existing Web site. But compared to a pure AJAX &lt;br /&gt;
					approach&amp;#8212;direct client calls to remote services&amp;#8212;partial &lt;br /&gt;
					rendering suffers from significant performance penalties.&lt;/p&gt;
					&lt;p xmlid=&quot;PARASEPTEMBER2007CUTTINGEDGE072&quot;&gt;As a rule of &lt;br /&gt;
					thumb, I recommend partial rendering as the best approach &lt;br /&gt;
					for building a rock-solid first AJAX version of a site. You &lt;br /&gt;
					can then progressively move away from the classic ASP.NET &lt;br /&gt;
					architecture and start building a set of back-end services &lt;br /&gt;
					and a thick presentation layer. In the next installment of &lt;br /&gt;
					Cutting Edge, I'll dive into the remote services approach to &lt;br /&gt;
					AJAX. It's neat, architecturally speaking, but it may &lt;br /&gt;
					require a complete redesign of your application and it &lt;br /&gt;
					raises a few new issues.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsGloss&quot;&gt;Send your questions and comments for &lt;br /&gt;
					Dino to&amp;nbsp;&lt;a href=&quot;mailto:cutting@microsoft.com&quot;&gt;cutting@microsoft.com&lt;/a&gt;.&lt;br /&gt;
					&lt;/span&gt;&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;5&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table9&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;
							&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;&lt;b&gt;
							NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/default.aspx?loc=en&quot;&gt;
							Explore&lt;/a&gt; the sample code online! &lt;/b&gt;- or - &lt;b&gt;
							Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/CuttingEdge2007_09.exe&quot;&gt;
							CuttingEdge2007_09.exe&lt;/a&gt; (333KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
				&lt;hr&gt;&lt;span class=&quot;clsBio&quot;&gt;&lt;b&gt;Dino Esposito&lt;/b&gt; is a mentor at &lt;br /&gt;
				Solid Quality Learning and the author of Programming Microsoft &lt;br /&gt;
				ASP.NET 2.0 (Microsoft Press, 2005). Based in Italy, Dino is a &lt;br /&gt;
				frequent speaker at industry events worldwide. Get in touch with &lt;br /&gt;
				Dino at &lt;a href=&quot;mailto:cutting@microsoft.com&quot;&gt;
				cutting@microsoft.com&lt;/a&gt; or join the blog at&lt;br /&gt;
				&lt;a href=&quot;http://weblogs.asp.net/despos&quot;&gt;weblogs.asp.net/despos&lt;/a&gt;.&lt;br /&gt;
				&lt;/span&gt;&lt;br&gt;
¡¡&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
<author>ÓÞíâÏÚ úÜ</author>
<pubDate>Sep, 04 2007 06:54:39 GMT</pubDate>
<category>.Net</category>
</item>
<item>
<title>Asynchronous Device Operations</title>
<link>http://www.rustican.com/board/zboard.php?id=paper&amp;no=250</link>
<description>&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table2&quot;&gt;
			&lt;tr&gt;
				&lt;td class=&quot;clsDocBody&quot;&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table3&quot;&gt;
					&lt;tr&gt;
						&lt;td align=&quot;middle&quot; bgColor=&quot;#003399&quot; colSpan=&quot;2&quot;&gt;
						&lt;img height=&quot;24&quot; alt=&quot;Concurrent Affairs&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/headers/concurrent.gif&quot; width=&quot;373&quot; vspace=&quot;5&quot;&gt;&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td class=&quot;clsDeck&quot; bgColor=&quot;#ffffcc&quot; colSpan=&quot;2&quot; height=&quot;20&quot;&gt;
						&lt;b&gt;Asynchronous Device Operations&lt;/b&gt;&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#ffffff&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td bgColor=&quot;#336699&quot; colSpan=&quot;2&quot; height=&quot;2&quot;&gt;¡¡&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table4&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;*&quot;&gt;
						&lt;div class=&quot;pd&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;a title=&quot;More articles by this author&quot; href=&quot;http://msdn.microsoft.com/msdnmag/find/?type=Au&amp;phrase=Jeffrey%20Richter&amp;words=exact&quot;&gt;
							Jeffrey Richter&lt;/a&gt;&lt;/div&gt;
						&lt;/td&gt;
						&lt;td width=&quot;175&quot;&gt;
						&lt;div id=&quot;menu_parent&quot; style=&quot;CURSOR: pointer&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
							&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;3&quot; border=&quot;0&quot; id=&quot;table5&quot;&gt;
								&lt;tr vAlign=&quot;bottom&quot; align=&quot;middle&quot;&gt;
									&lt;td&gt;
									&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;print=true&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;
									&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/rss/rss.aspx?Sub=Concurrent%20Affairs&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a onclick=&quot;return false;&quot; href=&quot;#&quot;&gt;more &lt;br /&gt;
									...&lt;/a&gt;&lt;/td&gt;
								&lt;/tr&gt;
							&lt;/table&gt;
						&lt;/div&gt;
						&lt;div style=&quot;FLOAT: right; WIDTH: 175px&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;div id=&quot;menu_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 5px; Z-INDEX: 100; VISIBILITY: hidden; PADDING-BOTTOM: 5px; BORDER-LEFT: #999999 1px solid; WIDTH: 175px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; BACKGROUND-COLOR: white; align: right&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
								&lt;table cellSpacing=&quot;3&quot; cellPadding=&quot;2&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table6&quot;&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot; width=&quot;30&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot; width=&quot;140&quot;&gt;
										&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;print=true&quot;&gt;
										Print&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										E-mail&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Add to Favorites&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Rate&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Concurrent%20Affairs&quot;&gt;
										RSS (Concurrent Affairs) &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/addtoany.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://www.addtoany.com/?linkname=Concurrent%20Affairs&amp;type=rss&amp;linkurl=http://msdn.microsoft.com/msdnmag/rss/rss.aspx?Sub=Concurrent%20Affairs&quot;&gt;
										Add RSS to Any &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/library.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Related Articles&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/spaces.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://spaces.live.com/blogit.aspx?Title=Concurrent Affairs:+Asynchronous Device Operations&amp;Description=Jeff Richter uses the AsyncResult&lt;TResult&gt; class to implement the  CLR%E2%80%99s Asynchronous Programming Model to perform hardware device operations asynchronously.&amp;SourceURL=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&quot;&gt;
										Live Spaces &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/digg.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://digg.com/submit?phase=2&amp;url=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&amp;title=Concurrent Affairs:+Asynchronous Device Operations&amp;bodytext=Jeff Richter uses the AsyncResult&lt;TResult&gt; class to implement the  CLR%E2%80%99s Asynchronous Programming Model to perform hardware device operations asynchronously.&amp;topic=programming                &quot;&gt;
										Digg This &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/blogger.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://new.blogger.com/blog_this.pyra?t=Jeff Richter uses the AsyncResult&lt;TResult&gt; class to implement the  CLR%E2%80%99s Asynchronous Programming Model to perform hardware device operations asynchronously.&amp;u=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&amp;n='Concurrent Affairs:+Asynchronous Device Operations,'bloggerForm','scrollbars=no,width=475,height=300,top=175,left=75,status=yes,resizable=yes&quot;&gt;
										BlogThis! &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/slashdot.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://slashdot.org/bookmark.pl?url=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&amp;title=Concurrent Affairs:+Asynchronous Device Operations&quot;&gt;
										Slashdot &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/delicious.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://del.icio.us/post?url=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&amp;title=Concurrent Affairs:+Asynchronous Device Operations&quot;&gt;
										del.icio.us &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/technorati.png&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://technorati.com/faves?add=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&quot;&gt;
										Technorati &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&quot;&gt;
										Explore &lt;/a&gt;the code. &lt;br&gt;
										&lt;br&gt;
										&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/ConcurrentAffairs2007_06.exe&quot;&gt;
										Download &lt;/a&gt;the code. &lt;/td&gt;
									&lt;/tr&gt;
								&lt;/table&gt;
							&lt;/div&gt;
						&lt;/div&gt;
&lt;SCRIPT type=text/javascript xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
      at_attach(&quot;menu_parent&quot;, &quot;menu_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
    &lt;/SCRIPT&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
				&lt;span id=&quot;dl_parent&quot; style=&quot;CURSOR: pointer&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
				&lt;a id=&quot;Code&quot; href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&quot;&gt;
				&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;Get &lt;br /&gt;
				the sample code for this article. &lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
				&lt;div id=&quot;dl_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 0px; Z-INDEX: 100; LEFT: 196px; VISIBILITY: hidden; PADDING-BOTTOM: 0px; BORDER-LEFT: #999999 1px solid; WIDTH: 500px; PADDING-TOP: 0px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; TOP: 337px; BACKGROUND-COLOR: white&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot; at_timeout=&quot;674554027&quot;&gt;
					&lt;table style=&quot;background-image: url('http://msdn.microsoft.com/msdnmag/images/codebg.gif')&quot; cellSpacing=&quot;0&quot; cellPadding=&quot;20&quot; width=&quot;500&quot; border=&quot;0&quot; id=&quot;table7&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;&lt;b&gt;NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&quot;&gt;
							Explore &lt;/a&gt;the sample code online! &lt;/b&gt;&lt;br&gt;
							&lt;br&gt;
							- or - &lt;br&gt;
							&lt;br&gt;
							&lt;b&gt;Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/ConcurrentAffairs2007_06.exe&quot;&gt;
							ConcurrentAffairs2007_06.exe&lt;/a&gt; (162KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
&lt;SCRIPT type=text/javascript&gt;
    at_attach(&quot;dl_parent&quot;, &quot;dl_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
  &lt;/SCRIPT&gt;
				&lt;br&gt;
				&lt;br&gt;
¡¡&lt;hr&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table8&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;50%&quot;&gt;
						&lt;img class=&quot;clsImgButton&quot; id=&quot;contentbtn&quot; onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; height=&quot;9&quot; alt=&quot;&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/minus.gif&quot; width=&quot;9&quot; align=&quot;absMiddle&quot; vspace=&quot;2&quot;&gt;&lt;a onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; name=&quot;contents&quot; href=&quot;#void&quot;&gt;&lt;b&gt;Contents&lt;/b&gt;&lt;/a&gt;&lt;br&gt;
¡¡&lt;div id=&quot;contentmenu&quot; style=&quot;MARGIN-TOP: 10px; DISPLAY: block; MARGIN-LEFT: 20px&quot;&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S1&quot;&gt;CreateFile and &lt;br /&gt;
							DeviceIoControl&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S2&quot;&gt;Win32 Device &lt;br /&gt;
							Communication&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S3&quot;&gt;Synchronous Device I/O &lt;br /&gt;
							in Managed Code&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S4&quot;&gt;Asynchronous Device I/O &lt;br /&gt;
							in Managed Code&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S5&quot;&gt;DeviceIoControl¡¯s &lt;br /&gt;
							Overlapped Parameter&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S6&quot;&gt;Opportunistic Locks&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S7&quot;&gt;Conclusion&lt;/a&gt;&lt;br&gt;
¡¡&lt;/div&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;hr&gt;&lt;br&gt;
¡¡&lt;div class=&quot;articletext&quot;&gt;
					&lt;p class=&quot;clsDropCap&quot; font=&quot;franklingothiccondensed&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS001&quot;&gt;
					In my last column, I demonstrated how to implement two base &lt;br /&gt;
					classes, AsyncResultNoResult and AsyncResult&lt;TResult&gt;. Both &lt;br /&gt;
					of these classes implement the IAsyncResult interface, which &lt;br /&gt;
					is at the core of the common language runtime (CLR) &lt;br /&gt;
					Asynchronous Programming Model (APM). In this column, I¡¯m &lt;br /&gt;
					going to use the AsyncResult&lt;TResult&gt; class to implement the &lt;br /&gt;
					APM in a way that allows you to perform hardware device &lt;br /&gt;
					operations asynchronously. Reading this column will also &lt;br /&gt;
					give you insight into how the Microsoft&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;
					.NET Framework itself performs asynchronous file and network &lt;br /&gt;
					I/O operations. All of this code resides in my Power &lt;br /&gt;
					Threading library, available from&lt;br /&gt;
					&lt;a href=&quot;http://www.wintellect.com&quot;&gt;wintellect.com&lt;/a&gt;.&lt;/p&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;CreateFile and DeviceIoControl&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS002&quot;&gt;In Win32&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;-based &lt;br /&gt;
					coding, when you want to work with a file, you open it by &lt;br /&gt;
					calling the Win32 CreateFile function and then perform &lt;br /&gt;
					operations on the file by calling functions such as &lt;br /&gt;
					WriteFile and ReadFile. Ultimately, when you¡¯re finished &lt;br /&gt;
					working with the file, you close it by calling the &lt;br /&gt;
					CloseHandle function.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS003&quot;&gt;
					In the .NET Framework, constructing a FileStream object &lt;br /&gt;
					internally calls CreateFile. Calling FileStream¡¯s Read and &lt;br /&gt;
					Write methods internally calls the Win32 WriteFile and &lt;br /&gt;
					ReadFile functions respectively. And Calling FileStream¡¯s &lt;br /&gt;
					Close or Dispose methods internally calls the Win32 &lt;br /&gt;
					CloseHandle function. When working with files, most &lt;br /&gt;
					applications just need to write data to and read data from &lt;br /&gt;
					the file and so the FileStream class offers most of the &lt;br /&gt;
					operations you need.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS004&quot;&gt;
					However, Windows&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt; actually &lt;br /&gt;
					offers many more operations that can be performed on a file. &lt;br /&gt;
					For the more common operations, Windows provides specific &lt;br /&gt;
					Win32 functions like WriteFile, ReadFile, FlushFileBuffers, &lt;br /&gt;
					and GetFileSize. However, for infrequently used operations, &lt;br /&gt;
					Win32 doesn¡¯t supply specific functions; instead, it offers &lt;br /&gt;
					one function, DeviceIoControl, that lets an application &lt;br /&gt;
					communicate directly with the device driver (such as the &lt;br /&gt;
					NTFS disk driver) responsible for manipulating the file. &lt;br /&gt;
					Examples of infrequently used file operations include &lt;br /&gt;
					opportunistic locking (&lt;a href=&quot;http://www.microsoft.com/msj/0100/win32/win320100.aspx&quot;&gt;microsoft.com/msj/0100/win32/win320100.aspx&lt;/a&gt;), &lt;br /&gt;
					manipulating the change journal (&lt;a href=&quot;http://www.microsoft.com/msj/0999/journal/journal.aspx&quot;&gt;microsoft.com/msj/0999/journal/journal.aspx&lt;/a&gt;), &lt;br /&gt;
					compressing disk volumes/files, creating junction points, &lt;br /&gt;
					formatting/repartitioning disks, and working with sparse &lt;br /&gt;
					files.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS005&quot;&gt;
					Furthermore, DeviceIoControl can be used by any application &lt;br /&gt;
					to communicate with any hardware device driver. Using &lt;br /&gt;
					DeviceIoControl, an application can query the computer¡¯s &lt;br /&gt;
					battery status, query or change the LCD¡¯s brightness, &lt;br /&gt;
					manipulate a CD or DVD changer, query and eject USB devices, &lt;br /&gt;
					and much more.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Win32 Device Communication&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS006&quot;&gt;Let¡¯s take a &lt;br /&gt;
					quick look at the Win32 way of having an application &lt;br /&gt;
					communicate with a device and then wrap this functionality &lt;br /&gt;
					so that it can be used from managed code.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS007&quot;&gt;
					In Win32, the way you open a device is by calling the &lt;br /&gt;
					CreateFile function. CreateFile¡¯s first argument is a string &lt;br /&gt;
					identifying the device to open. Normally, a path name is &lt;br /&gt;
					specified for the string causing CreateFile to open a file. &lt;br /&gt;
					However, you can pass special strings to CreateFile, causing &lt;br /&gt;
					it to open devices.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig1'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig1&quot;&gt;
					Figure&amp;nbsp;1&lt;/a&gt; shows some potential strings and describes the &lt;br /&gt;
					kind of device the string causes CreateFile to open. Be &lt;br /&gt;
					aware that some of these devices are restricted to the &lt;br /&gt;
					system or members of the Administrators group and so &lt;br /&gt;
					attempting to open some of these devices may fail unless &lt;br /&gt;
					your application is running with the required access &lt;br /&gt;
					permissions.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS008&quot;&gt;
					Now that you know how to open a device, let¡¯s look at the &lt;br /&gt;
					Win32 function DeviceIoControl:&lt;/p&gt;
					&lt;p font=&quot;mscoderegular&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS009&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;BOOL DeviceIoControl(&lt;br /&gt;
   HANDLE hDevice,           // Handle returned from CreateFile&lt;br /&gt;
   DWORD  dwIoControlCode,   // Operation control code&lt;br /&gt;
   PVOID  pInBuffer,         // Address of input buffer&lt;br /&gt;
   DWORD  nInBufferSize,     // Size, in bytes, of input buffer&lt;br /&gt;
   PVOID  pOutBuffer,        // Address of output buffer&lt;br /&gt;
   DWORD  nOutBufferSize,    // Size, in bytes, of output buffer&lt;br /&gt;
   PDWORD pBytesReturned,    // Gets number of bytes written to &lt;br /&gt;
                             // pOutBuffer&lt;br /&gt;
   POVERLAPPED pOverlapped); // For asynchronous operation&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS010&quot;&gt;
					When calling this function, the handle parameter refers to a &lt;br /&gt;
					file, directory, or device driver obtained by calling &lt;br /&gt;
					CreateFile. The dwIoControlCode parameter indicates the &lt;br /&gt;
					operation to perform on the device. Each operation is simply &lt;br /&gt;
					identified via this 32-bit integer code. If an operation &lt;br /&gt;
					requires arguments, then the arguments are placed in fields &lt;br /&gt;
					of a data structure and the address of the structure is &lt;br /&gt;
					passed for the pInBuffer parameter. The size of the &lt;br /&gt;
					structure is passed in the nInBufferSize parameter. &lt;br /&gt;
					Similarly, if the operation returns some data, then the &lt;br /&gt;
					output data is placed in a buffer, which must be allocated &lt;br /&gt;
					by the caller. The address of this buffer is passed in the &lt;br /&gt;
					pOutBuffer parameter. The size of this buffer is passed in &lt;br /&gt;
					the nOutBufferSize parameter. When DeviceIoControl returns, &lt;br /&gt;
					it writes the number of bytes actually written to the output &lt;br /&gt;
					buffer in the pBytesReturned parameter (which is passed by &lt;br /&gt;
					reference). Finally, when performing synchronous operations, &lt;br /&gt;
					NULL is passed for the pOverlapped parameter. But when &lt;br /&gt;
					performing an asynchronous operation, the address of an &lt;br /&gt;
					OVERLAPPED structure must be passed in. I¡¯ll explain this is &lt;br /&gt;
					great detail later in this column.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS011&quot;&gt;
					Now that you have a sense of how to communicate with devices &lt;br /&gt;
					via Win32, let¡¯s start writing a managed wrapper over these &lt;br /&gt;
					Win32 functions so that you can write managed code in a .NET &lt;br /&gt;
					language to communicate directly with hardware devices.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Synchronous Device I/O in Managed &lt;br /&gt;
					Code&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS012&quot;&gt;First, let¡¯s &lt;br /&gt;
					focus on how to perform synchronous device operations. &lt;br /&gt;
					Later, I¡¯ll add the code necessary to perform asynchronous &lt;br /&gt;
					operations. In C#, I have defined a static DeviceIO class &lt;br /&gt;
					that is a friendly wrapper around the Win32 CreateFile and &lt;br /&gt;
					DeviceIoControl functions.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig2'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig2&quot;&gt;
					Figure&amp;nbsp;2&lt;/a&gt; shows the public object model for this class.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS013&quot;&gt;
					In a managed application, you can call OpenDevice, passing &lt;br /&gt;
					in a string similar to those shown in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig1'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig1&quot;&gt;
					Figure&amp;nbsp;1&lt;/a&gt;, plus the desired access and sharing. &lt;br /&gt;
					OpenDevice will internally call CreateFile returning the &lt;br /&gt;
					handle to the device. The handle is actually returned &lt;br /&gt;
					wrapped in a SafeFileHandle object to ensure that it will &lt;br /&gt;
					ultimately be closed and to get the other benefits offered &lt;br /&gt;
					by way of all SafeHandle-derived classes. This &lt;br /&gt;
					SafeFileHandle object can be passed as the first argument to &lt;br /&gt;
					any of DeviceIO¡¯s other static methods and this is &lt;br /&gt;
					ultimately passed as the first argument when calling the &lt;br /&gt;
					Win32 DeviceIoControl function.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS014&quot;&gt;
					The second argument to all the other methods is a &lt;br /&gt;
					DeviceControlCode, a simple structure (value type) that &lt;br /&gt;
					contains just one private instance field, an Int32, that &lt;br /&gt;
					identifies a command code you want to send to a device. I &lt;br /&gt;
					found that wrapping the Int32 command code into its own type &lt;br /&gt;
					caused the code to read better, be more type-safe, and &lt;br /&gt;
					benefit from IntelliSense&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt; in &lt;br /&gt;
					Visual Studio&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;. Internally, the &lt;br /&gt;
					Int32 value contained inside a DeviceControlCode instance is &lt;br /&gt;
					passed as the second argument to the Win32 DeviceIoControl &lt;br /&gt;
					function.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS015&quot;&gt;
					Now, when examining device control codes, you¡¯ll detect that &lt;br /&gt;
					there are a few common patterns, and I decided to offer &lt;br /&gt;
					friendly methods to make working with these common patterns &lt;br /&gt;
					convenient. All of these methods execute the operation &lt;br /&gt;
					synchronously; that is, the calling thread will not return &lt;br /&gt;
					until the operation is complete. Also, when calling any of &lt;br /&gt;
					these methods, you must specify false for the useAsync &lt;br /&gt;
					argument when calling OpenDevice.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS016&quot;&gt;
					The Control method encapsulates a pattern where the control &lt;br /&gt;
					code you¡¯re sending to a device causes the device to perform &lt;br /&gt;
					some operation and the device has no resulting data to &lt;br /&gt;
					return. There is a Control method that takes just a &lt;br /&gt;
					SafeFileHandle and a control code and an overload that takes &lt;br /&gt;
					an additional Object argument. The additional Object &lt;br /&gt;
					argument allows you to pass some additional data to the &lt;br /&gt;
					device that it will use for an operation. When you look up &lt;br /&gt;
					control codes in the Win32 SDK documentation, the &lt;br /&gt;
					documentation will indicate what additional information (if &lt;br /&gt;
					necessary) you must pass for each control code. If you need &lt;br /&gt;
					additional data, you must define a managed type that is the &lt;br /&gt;
					equivalent of the Win32 data type, construct an instance of &lt;br /&gt;
					it, initialize its fields, and pass a reference to the &lt;br /&gt;
					instance for the inBuffer parameter.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS017&quot;&gt;
					The GetObject&lt;TResult&gt; method encapsulates a pattern where &lt;br /&gt;
					the control code you¡¯re sending to a device causes the &lt;br /&gt;
					device to return some data back to your application. To get &lt;br /&gt;
					this return data, you must define a managed type that is the &lt;br /&gt;
					equivalent of the Win32 data type, and specify this type as &lt;br /&gt;
					the generic type, TResult, when calling GetObject. &lt;br /&gt;
					Internally, GetObject will create an instance of this type &lt;br /&gt;
					(which is why the generic type has the new constraint &lt;br /&gt;
					applied to it), the device will initialize the fields inside &lt;br /&gt;
					the call to DeviceIoControl, and GetObject will return the &lt;br /&gt;
					initialized object back out to you. When calling GetObject, &lt;br /&gt;
					there are two overloads allowing you to optionally pass &lt;br /&gt;
					additional data to the device via the inBuffer parameter.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS018&quot;&gt;
					The GetArray&lt;TElement&gt; method encapsulates the last pattern &lt;br /&gt;
					where the control code you¡¯re sending to a device causes the &lt;br /&gt;
					device to return an array of elements to your application. &lt;br /&gt;
					To get these elements, you must define a managed type that &lt;br /&gt;
					is the equivalent of the data type of the Win32 element, and &lt;br /&gt;
					specify this type as the generic type, TElement, when &lt;br /&gt;
					calling GetArray. The managed data type must be defined as a &lt;br /&gt;
					structure (value type) so that the array¡¯s memory is laid &lt;br /&gt;
					out linearly as required by DeviceIoControl; this is why &lt;br /&gt;
					TElement is constrained to struct. Also, when calling &lt;br /&gt;
					GetArray, you must specify the maximum number of elements &lt;br /&gt;
					that you want returned from the device via the maxElements &lt;br /&gt;
					parameter.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS019&quot;&gt;
					Internally, GetObject will create an array of these elements &lt;br /&gt;
					and pass the address of the array to DeviceIoControl, which &lt;br /&gt;
					will initialize the individual array elements. When &lt;br /&gt;
					DeviceIoControl returns, it returns the number of bytes &lt;br /&gt;
					actually placed in the array. GetArray uses this value to &lt;br /&gt;
					shrink (if necessary) the array to the exact size so that &lt;br /&gt;
					the number of elements in the array is equal to the number &lt;br /&gt;
					of elements initialized. This is a big convenience as any &lt;br /&gt;
					code that uses this array (returned from GetArray) can &lt;br /&gt;
					simply query the array¡¯s Length property to get the number &lt;br /&gt;
					of items and use this value in its loop to process the &lt;br /&gt;
					returned elements.&lt;/p&gt;
					&lt;p font=&quot;franklingothiccondensed&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS020&quot;&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt; shows the managed equivalent of the Win32 &lt;br /&gt;
					DisplayBrightness structure and its helper DisplayPowerFlags &lt;br /&gt;
					enumerated type.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig4'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig4&quot;&gt;
					Figure&amp;nbsp;4&lt;/a&gt; shows an AdjustBrightness method that uses my &lt;br /&gt;
					static DeviceIO class to constantly adjust your LCD¡¯s &lt;br /&gt;
					brightness up and down. I must say that this is not a very &lt;br /&gt;
					useful application in real life, but it is a simple example &lt;br /&gt;
					that shows the basic concepts.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Asynchronous Device I/O in Managed &lt;br /&gt;
					Code&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS021&quot;&gt;Some device &lt;br /&gt;
					operations, like changing LCD brightness, are not really I/O &lt;br /&gt;
					operations and so it makes sense to call DeviceIoControl &lt;br /&gt;
					synchronously when performing these kinds of operations. &lt;br /&gt;
					However, most calls to DeviceIoControl result in I/O (hence &lt;br /&gt;
					the name of the function) and, therefore, it makes sense to &lt;br /&gt;
					execute these operations asynchronously. In this section, &lt;br /&gt;
					I¡¯ll explain how to P/Invoke from managed code out to the &lt;br /&gt;
					Win32 DeviceIoControl function in order to perform &lt;br /&gt;
					asynchronous I/O operations to files, disks, and other &lt;br /&gt;
					hardware devices.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS022&quot;&gt;
					My static DeviceIO class offers asynchronous versions of the &lt;br /&gt;
					Control, GetObject, and GetArray methods by way of the CLR¡¯s &lt;br /&gt;
					APM.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig5'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig5&quot;&gt;
					Figure&amp;nbsp;5&lt;/a&gt; shows the public methods (not shown earlier) of &lt;br /&gt;
					this class that support the APM.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS023&quot;&gt;
					As you can see, all the BeginXxx methods follow the CLR¡¯s &lt;br /&gt;
					APM pattern; that is, they all return an IAsyncResult and &lt;br /&gt;
					the last two parameters are an AsyncCallback and an Object. &lt;br /&gt;
					The additional parameters match those of each method¡¯s &lt;br /&gt;
					synchronous counterpart. Similarly, all the EndXxx methods &lt;br /&gt;
					accept a single parameter, an IAsyncResult, and each returns &lt;br /&gt;
					the same data type as each method¡¯s synchronous counterpart.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS024&quot;&gt;
					In order to call any of these asynchronous methods, two &lt;br /&gt;
					things must happen. First, you must tell Windows that you &lt;br /&gt;
					want to perform operations on the device asynchronously. &lt;br /&gt;
					This is accomplished by passing the FILE_FLAG_OVERLAPPED &lt;br /&gt;
					flag (which has a numeric value of 0x40000000) to the &lt;br /&gt;
					CreateFile function. The managed equivalent of this flag is &lt;br /&gt;
					FileOptions.Asynchronous (which, of course, also has a value &lt;br /&gt;
					of 0x40000000). Second, you have to tell the device driver &lt;br /&gt;
					to post operation completion entries into the CLR¡¯s thread &lt;br /&gt;
					pool. This is accomplished by calling ThreadPool¡¯s static &lt;br /&gt;
					BindHandle method, which takes one parameter, a reference to &lt;br /&gt;
					a SafeHandle-derived object.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS025&quot;&gt;
					DeviceIO¡¯s OpenDevice method performs both of these actions &lt;br /&gt;
					when you pass true for its useAsync parameter. Here is how &lt;br /&gt;
					my OpenDevice method is implemented:&lt;/p&gt;
					&lt;p font=&quot;mscoderegular&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS026&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;public static SafeFileHandle OpenDevice(String deviceName, &lt;br /&gt;
   FileAccess access, FileShare share, Boolean useAsync) {&lt;br /&gt;

   SafeFileHandle device = CreateFile(deviceName, access, share, &lt;br /&gt;
      IntPtr.Zero, FileMode.Open, &lt;br /&gt;
      useAsync ? FileOptions.Asynchronous : FileOptions.None, &lt;br /&gt;
      IntPtr.Zero);&lt;br /&gt;

   if (device.IsInvalid) throw new Win32Exception();&lt;br /&gt;
   if (useAsync) ThreadPool.BindHandle(device);&lt;br /&gt;

   return device;&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS027&quot;&gt;
					Now, let¡¯s take a look at how BeginGetObject and &lt;br /&gt;
					EndGetObject work internally. The other asynchronous methods &lt;br /&gt;
					work similarly and you will be able to understand how they &lt;br /&gt;
					work easily after walking through BeginGetObject and &lt;br /&gt;
					EndGetObject. All of the BeginXxx methods are very simple; &lt;br /&gt;
					they construct an object or array if the operation returns &lt;br /&gt;
					some return value or array of elements, and then they &lt;br /&gt;
					immediately call an internal helper method, AsyncControl, &lt;br /&gt;
					which is implemented as shown in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig6'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig6&quot;&gt;
					Figure&amp;nbsp;6&lt;/a&gt;.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS028&quot;&gt;
					When performing an operation, you can pass the address of a &lt;br /&gt;
					buffer containing additional input data to DeviceIoControl. &lt;br /&gt;
					If DeviceIoControl returns data, the memory for that data &lt;br /&gt;
					must be allocated before calling DeviceIoControl so that &lt;br /&gt;
					DeviceIoControl can initialize the data; the data is then &lt;br /&gt;
					examined when the operation completes. The problem is that &lt;br /&gt;
					the operation could theoretically take hours to complete and &lt;br /&gt;
					during this time garbage collections could occur that would &lt;br /&gt;
					move the data around. As a result, the addresses passed to &lt;br /&gt;
					DeviceIoControl would no longer refer to the desired buffers &lt;br /&gt;
					and memory corruption would occur.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS029&quot;&gt;
					You can tell the GC not to move an object around by pinning &lt;br /&gt;
					the object. My SafePinnedObject class is a helper class that &lt;br /&gt;
					pins an object in memory, preventing the GC from moving it. &lt;br /&gt;
					However, since the SafePinnedObject class is derived from &lt;br /&gt;
					SafeHandle, it comes with all the benefits you normally get &lt;br /&gt;
					with SafeHandle-derived types, including the assurance that &lt;br /&gt;
					the object will be unpinned at some point in the future.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig7'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig7&quot;&gt;
					Figure&amp;nbsp;7&lt;/a&gt; gives you an idea of how the SafePinnedObject &lt;br /&gt;
					class is implemented (I¡¯ve removed some validation code to &lt;br /&gt;
					save space). For more information about SafeHandle-derived &lt;br /&gt;
					types and about pinning objects in memory, see my book CLR &lt;br /&gt;
					via C# (Microsoft Press&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;, 2006).&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS030&quot;&gt;
					After pinning both the input and output buffers, &lt;br /&gt;
					AsyncControl constructs a DeviceAsyncResult&lt;TResult&gt; object &lt;br /&gt;
					passing into it the two SafePinnedObject objects, an &lt;br /&gt;
					AsyncCallback, and an Object. DeviceAsyncResult&lt;TResult&gt; is &lt;br /&gt;
					another type internal to my implementation. This type is &lt;br /&gt;
					derived from AsyncResult&lt;TResult&gt; (as discussed in my last &lt;br /&gt;
					column), which means this type implements the APM¡¯s &lt;br /&gt;
					IAsyncResult interface. When constructed, the &lt;br /&gt;
					DeviceAsyncResult object simply saves all the arguments &lt;br /&gt;
					passed to it in private fields and then returns.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;DeviceIoControl¡¯s Overlapped &lt;br /&gt;
					Parameter&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS031&quot;&gt;Now that all &lt;br /&gt;
					this prep work is complete, AsyncControl is ready to call &lt;br /&gt;
					DeviceIoControl. It does that by calling NativeControl &lt;br /&gt;
					passing it the device handle, the control code, the input &lt;br /&gt;
					buffer, the output buffer, and a reference to an Int32 &lt;br /&gt;
					bytesReturned variable (which will basically be ignored by &lt;br /&gt;
					the method since the method will return before the operation &lt;br /&gt;
					completes). The most important argument is the last one: &lt;br /&gt;
					when performing an asynchronous operation, DeviceIoControl &lt;br /&gt;
					must be passed the address of a NativeOverlapped structure &lt;br /&gt;
					(the equivalent of a Win32 OVERLAPPED structure). &lt;br /&gt;
					AsyncControl obtains this by calling a helper method, &lt;br /&gt;
					GetNativeOverlapped, defined in my DeviceAsyncResult class. &lt;br /&gt;
					This helper method is implemented as follows:&lt;/p&gt;
					&lt;p font=&quot;mscoderegular&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS032&quot;&gt;¡¡&lt;/p&gt;
					&lt;pre class=&quot;clsCode&quot;&gt;// Create and return a NativeOverlapped structure to be passed &lt;br /&gt;
// to native code&lt;br /&gt;
public unsafe NativeOverlapped* GetNativeOverlapped() {&lt;br /&gt;
   // Create a managed Overlapped structure that refers to our &lt;br /&gt;
   // IAsyncResult (this)&lt;br /&gt;
   Overlapped o = new Overlapped(0, 0, IntPtr.Zero, this);&lt;br /&gt;

   // Pack the managed Overlapped structure into a NativeOverlapped &lt;br /&gt;
   // structure&lt;br /&gt;
   return o.Pack(CompletionCallback, &lt;br /&gt;
      new Object[] { m_inBuffer.Target, m_outBuffer.Target });&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS033&quot;&gt;
					This method constructs an instance of the &lt;br /&gt;
					System.Threading.Overlapped class and initializes it. This &lt;br /&gt;
					is a managed helper class that lets you set up and &lt;br /&gt;
					manipulate an overlapped structure. However, you cannot pass &lt;br /&gt;
					a reference to this object to native code. Instead you must &lt;br /&gt;
					first pack the Overlapped object into a NativeOverlapped &lt;br /&gt;
					object; a reference to the resulting NativeOverlapped object &lt;br /&gt;
					can then be passed to native code. When you call Pack, you &lt;br /&gt;
					pass it a delegate referring to a callback method that a &lt;br /&gt;
					thread pool thread will execute when the operation &lt;br /&gt;
					completes. In my code, this is the CompletionCallback &lt;br /&gt;
					method.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS034&quot;&gt;
					Calling the Overlapped class¡¯s Pack method does several &lt;br /&gt;
					things. It allocates memory for a native OVERLAPPED &lt;br /&gt;
					structure from the managed heap and pins it, which ensures &lt;br /&gt;
					that the memory will not be moved should a GC occur. It then &lt;br /&gt;
					initializes the fields of the NativeOverlapped structure¡¯s &lt;br /&gt;
					field from the fields set in the managed Overlapped object. &lt;br /&gt;
					This includes creating a normal GCHandle for the &lt;br /&gt;
					IAsyncResult object that the Overlapped object refers to &lt;br /&gt;
					ensuring that the IAsyncResult object stays alive for the &lt;br /&gt;
					duration of the operation.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS035&quot;&gt;
					Pack then pins the callback method (CompletionCallback) &lt;br /&gt;
					delegate so that the fixed address can be passed to native &lt;br /&gt;
					code, thus allowing native code to call back to managed code &lt;br /&gt;
					when this operation completes. Pack also pins any additional &lt;br /&gt;
					objects referenced by its second parameter, an Object array. &lt;br /&gt;
					In my case, the inBuffer and outBuffer objects are already &lt;br /&gt;
					pinned because I wrapped them using my SafePinnedObject &lt;br /&gt;
					class. I need to pin them myself so that I can get their &lt;br /&gt;
					address by calling GCHandle¡¯s AddrOfPinnedObject method.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS036&quot;&gt;
					However, the Pack method pins them again, but in a special &lt;br /&gt;
					way. Normally, when an AppDomain is unloaded, the CLR &lt;br /&gt;
					automatically unpins any objects, allowing them to be &lt;br /&gt;
					collected and thus preventing a memory leak. But Pack pins &lt;br /&gt;
					the objects until the asynchronous operation completes. So &lt;br /&gt;
					if an asynchronous operation is started and then the &lt;br /&gt;
					AppDomain is unloaded, the Pack-pinned objects will not be &lt;br /&gt;
					unpinned. After the operation completes, the objects will be &lt;br /&gt;
					unpinned allowing them to be collected; this prevents memory &lt;br /&gt;
					corruption.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS037&quot;&gt;
					Pack also records which AppDomain called Pack to ensure that &lt;br /&gt;
					the thread pool thread that calls the CompletionCallback &lt;br /&gt;
					method executes in the same AppDomain. Finally, Pack &lt;br /&gt;
					captures the stack of code access security permissions so &lt;br /&gt;
					that when the callback method executes, it executes under &lt;br /&gt;
					the same security permissions that the code initiating the &lt;br /&gt;
					asynchronous operation was under. You can call the &lt;br /&gt;
					Overlapped class¡¯s UnsafePack method if you prefer not to &lt;br /&gt;
					propagate the stack of security permissions.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS038&quot;&gt;
					Pack returns the address of the pinned NativeOverlapped &lt;br /&gt;
					structure; this address can be passed to any native function &lt;br /&gt;
					that expects the address to a Win32 OVERLAPPED structure. In &lt;br /&gt;
					my AsyncControl method, the NativeOverlapped structure¡¯s &lt;br /&gt;
					address is passed to NativeControl (see&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig8'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig8&quot;&gt;
					Figure&amp;nbsp;8&lt;/a&gt;), which passes it to the Win32 DeviceIoControl &lt;br /&gt;
					function.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS039&quot;&gt;
					When performing an asynchronous operation, DeviceIoControl &lt;br /&gt;
					returns immediately and, ultimately, the DeviceAsyncResult &lt;br /&gt;
					object that implements the IAsyncResult interface is &lt;br /&gt;
					returned from DeviceIO¡¯s BeginObject&lt;TResult&gt; method.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS040&quot;&gt;
					When the operation completes, the device driver queues an &lt;br /&gt;
					entry in the CLR¡¯s thread pool. You¡¯ll recall that the &lt;br /&gt;
					driver knows to do this because DeviceIO¡¯s OpenDevice method &lt;br /&gt;
					internally calls ThreadPool¡¯s BindHandle method when the &lt;br /&gt;
					device is opened for asynchronous access. Eventually, a &lt;br /&gt;
					thread pool thread will extract this queued entry, adopt any &lt;br /&gt;
					saved permission sets, jump into the right AppDomain, and &lt;br /&gt;
					call the CompletionCallback method (see&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig9'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig9&quot;&gt;
					Figure&amp;nbsp;9&lt;/a&gt;). Don¡¯t forget that the CompletionCallback &lt;br /&gt;
					method is defined inside the DeviceAsyncResult&lt;TResult&gt;
					class, which is derived from the AsyncResult&lt;TResult&gt; class.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS041&quot;&gt;
					The first thing that the CompletionCallback method does is &lt;br /&gt;
					free the nativeOverlapped object. This is extremely &lt;br /&gt;
					important as it releases the GCHandle on the IAsyncResult &lt;br /&gt;
					object, unpins all the objects passed to the Overlapped &lt;br /&gt;
					class¡¯s Pack method, and also unpins the NativeOverlapped &lt;br /&gt;
					object itself allowing it to be GC¡¯d. Forgetting to free the &lt;br /&gt;
					NativeOverlapped object results in leaking several objects.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS042&quot;&gt;
					The rest of CompletionCallback¡¯s code is pretty &lt;br /&gt;
					straightforward. It is just a matter of recording in the &lt;br /&gt;
					AsyncResult&lt;T&gt; base class¡¯s state whether the operation &lt;br /&gt;
					failed or the result of the operation (adjusting the array &lt;br /&gt;
					size if DeviceIO¡¯s BeginGetArray was called to initiate the &lt;br /&gt;
					operation). In CompletionCallback¡¯s finally block, there is &lt;br /&gt;
					some code to dispose of the SafePinnedObject objects, &lt;br /&gt;
					ensuring that the input and output buffers are no longer &lt;br /&gt;
					pinned and allowing them to be compacted by the GC and &lt;br /&gt;
					ultimately have their memory reclaimed by the GC when the &lt;br /&gt;
					application no longer cares about these buffers.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS043&quot;&gt;
					At some point, the application code will call DeviceIO¡¯s &lt;br /&gt;
					EndControl, EndGetObject, or EndGetArray method, passing in &lt;br /&gt;
					the DeviceAsyncResult&lt;TResult&gt; object returned from the &lt;br /&gt;
					corresponding Begin method. Internally, all these End &lt;br /&gt;
					methods just call AsyncResult&lt;TResult&gt;¡¯s EndInvoke method, &lt;br /&gt;
					which either throws the exception set into it inside &lt;br /&gt;
					CompletionCallback or returns the value set into it.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Opportunistic Locks&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS044&quot;&gt;An &lt;br /&gt;
					opportunistic lock gives you a simple example that &lt;br /&gt;
					demonstrates an asynchronous device operation.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;fig=true#fig10'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=&amp;fig=true#fig10&quot;&gt;
					Figure&amp;nbsp;10&lt;/a&gt; shows a static OpLockDemo class whose Main &lt;br /&gt;
					method creates a file (using the FileOptions.Asynchronous &lt;br /&gt;
					flag). The SafeFileHandle embedded inside the FileStream is &lt;br /&gt;
					then passed to BeginFilter, which internally calls the &lt;br /&gt;
					DeviceIO¡¯s BeginControl method, passing the code that &lt;br /&gt;
					establishes a request filter opportunistic lock on the file. &lt;br /&gt;
					Now the file system device driver will watch to see if any &lt;br /&gt;
					other application attempts to open the file and, if so, the &lt;br /&gt;
					device driver will queue an entry to the CLR¡¯s thread pool. &lt;br /&gt;
					This will in turn call the anonymous method that sets the &lt;br /&gt;
					s_earlyEnd field to 1, which indicates that another &lt;br /&gt;
					application wants to access the file. The first application &lt;br /&gt;
					will then close the file allowing the other application to &lt;br /&gt;
					continue running with access to the file.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS045&quot;&gt;
					To test all of this, start the OpLockDemo application. Then &lt;br /&gt;
					go to your desktop and attempt to delete the &lt;br /&gt;
					FilterOpLock.dat file that the application creates. This &lt;br /&gt;
					will cause the anonymous method to get called, ending the &lt;br /&gt;
					sample application.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Conclusion&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJUNE2007CONCURRENTAFFAIRS046&quot;&gt;Windows and &lt;br /&gt;
					its device drivers offer many features that the .NET &lt;br /&gt;
					Framework class library does not wrap. Fortunately, though, &lt;br /&gt;
					the .NET Framework does provide the appropriate mechanisms &lt;br /&gt;
					allowing you to P/Invoke to gain access to these useful &lt;br /&gt;
					features. The fact that you can perform these operations &lt;br /&gt;
					asynchronously means you can build robust, reliable, and &lt;br /&gt;
					scalable applications that take advantage of these features.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsGloss&quot;&gt;Send your questions and comments for &lt;br /&gt;
					Jeffrey to &amp;nbsp;&lt;a href=&quot;mailto:mmsync@microsoft.com&quot;&gt;mmsync@microsoft.com&lt;/a&gt;.&lt;br /&gt;
					&lt;/span&gt;&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;5&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table9&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;
							&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;&lt;b&gt;
							NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/06/ConcurrentAffairs/default.aspx?loc=en&quot;&gt;
							Explore&lt;/a&gt; the sample code online! &lt;/b&gt;- or - &lt;b&gt;
							Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/ConcurrentAffairs2007_06.exe&quot;&gt;
							ConcurrentAffairs2007_06.exe&lt;/a&gt; (162KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
<author>ÓÞíâÏÚ úÜ</author>
<pubDate>Jul, 29 2007 04:33:55 GMT</pubDate>
<category>.Net</category>
</item>
<item>
<title>NTFS - Enhance Your Apps With File System Transactions</title>
<link>http://www.rustican.com/board/zboard.php?id=paper&amp;no=248</link>
<description>&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table2&quot;&gt;
			&lt;tr&gt;
				&lt;td class=&quot;clsDocBody&quot;&gt;&lt;span class=&quot;clsSmHead&quot;&gt;NTFS&lt;/span&gt;&lt;br /&gt;
				&lt;h1&gt;Enhance Your Apps With File System Transactions&lt;/h1&gt;
				&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table3&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;75%&quot;&gt;
						&lt;div class=&quot;pd&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;a title=&quot;More articles by this author&quot; href=&quot;http://msdn.microsoft.com/msdnmag/find/?type=Au&amp;phrase=Jason%20Olson&amp;words=exact&quot;&gt;
							Jason Olson&lt;/a&gt;&lt;/div&gt;
						&lt;/td&gt;
						&lt;td&gt;
						&lt;div id=&quot;menu_parent&quot; style=&quot;CURSOR: pointer&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
							&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;3&quot; border=&quot;0&quot; id=&quot;table4&quot;&gt;
								&lt;tr vAlign=&quot;bottom&quot; align=&quot;middle&quot;&gt;
									&lt;td&gt;
									&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;print=true&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;
									&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/rss/rss.aspx?current=true&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a href=&quot;#bottom&quot;&gt;
									&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/td&gt;
									&lt;td&gt;&lt;a onclick=&quot;return false;&quot; href=&quot;#&quot;&gt;more &lt;br /&gt;
									...&lt;/a&gt;&lt;/td&gt;
								&lt;/tr&gt;
							&lt;/table&gt;
						&lt;/div&gt;
						&lt;div style=&quot;FLOAT: right; WIDTH: 175px&quot; align=&quot;right&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
							&lt;div id=&quot;menu_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 5px; Z-INDEX: 100; VISIBILITY: hidden; PADDING-BOTTOM: 5px; BORDER-LEFT: #999999 1px solid; WIDTH: 175px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; BACKGROUND-COLOR: white; align: right&quot; at_parent=&quot;menu_parent&quot; at_child=&quot;menu_child&quot; at_position=&quot;y&quot;&gt;
								&lt;table cellSpacing=&quot;3&quot; cellPadding=&quot;2&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table5&quot;&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot; width=&quot;30&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_print.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot; width=&quot;140&quot;&gt;
										&lt;a id=&quot;Print&quot; onmouseover=&quot;window.status='Print This Page';return true&quot; title=&quot;Print a printer-friendly version of this page&quot; onclick=&quot;PrintButtonClick();return false;&quot; onmouseout=&quot;window.status='';return true&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;print=true&quot;&gt;
										Print&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_email.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										E-mail&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/rtg_save.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Add to Favorites&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rate.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Rate&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/rss.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/rss/rss.aspx?current=true&quot;&gt;
										RSS (Issues) &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/addtoany.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://www.addtoany.com/?linkname=MSDN+Magazine&amp;type=rss&amp;linkurl=http://msdn.microsoft.com/msdnmag/rss/rss.aspx?current=true&quot;&gt;
										Add RSS to Any &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icons/library.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;&lt;a href=&quot;#bottom&quot;&gt;
										Related Articles&lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/spaces.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://spaces.live.com/blogit.aspx?Title=NTFS:+Enhance Your Apps With File System Transactions&amp;Description=Presented here is an overview of Transactional NTFS and how it revolutionizes transactions.&amp;SourceURL=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&quot;&gt;
										Live Spaces &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/digg.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://digg.com/submit?phase=2&amp;url=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&amp;title=NTFS:+Enhance Your Apps With File System Transactions&amp;bodytext=Presented here is an overview of Transactional NTFS and how it revolutionizes transactions.&amp;topic=programming                &quot;&gt;
										Digg This &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/blogger.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://new.blogger.com/blog_this.pyra?t=Presented here is an overview of Transactional NTFS and how it revolutionizes transactions.&amp;u=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&amp;n='NTFS:+Enhance Your Apps With File System Transactions,'bloggerForm','scrollbars=no,width=475,height=300,top=175,left=75,status=yes,resizable=yes&quot;&gt;
										BlogThis! &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/slashdot.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://slashdot.org/bookmark.pl?url=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&amp;title=NTFS:+Enhance Your Apps With File System Transactions&quot;&gt;
										Slashdot &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/delicious.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://del.icio.us/post?url=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&amp;title=NTFS:+Enhance Your Apps With File System Transactions&quot;&gt;
										del.icio.us &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/interactive/technorati.png&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a target=&quot;_blank&quot; href=&quot;http://technorati.com/faves?add=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&quot;&gt;
										Technorati &lt;/a&gt;&lt;/td&gt;
									&lt;/tr&gt;
									&lt;tr&gt;
										&lt;td vAlign=&quot;center&quot; align=&quot;middle&quot;&gt;
										&lt;img alt=&quot;&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot;&gt;&lt;/td&gt;
										&lt;td vAlign=&quot;center&quot;&gt;
										&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&quot;&gt;
										Explore &lt;/a&gt;the code. &lt;br&gt;
										&lt;br&gt;
										&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TxF2007_07.exe&quot;&gt;
										Download &lt;/a&gt;the code. &lt;/td&gt;
									&lt;/tr&gt;
								&lt;/table&gt;
							&lt;/div&gt;
						&lt;/div&gt;
&lt;SCRIPT type=text/javascript xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
      at_attach(&quot;menu_parent&quot;, &quot;menu_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
    &lt;/SCRIPT&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;hr&gt;&lt;span class=&quot;clsSearchBox&quot;&gt;This article discusses:&lt;/span&gt;&lt;br /&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; border=&quot;0&quot; id=&quot;table6&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;55%&quot;&gt;
						&lt;div class=&quot;clsDiscuss&quot;&gt;
							&lt;ul&gt;
								&lt;li class=&quot;clsInfoBox&quot;&gt;The Kernel Transaction &lt;br /&gt;
								Manager &lt;br /&gt;
								&lt;/li&gt;
								&lt;li class=&quot;clsInfoBox&quot;&gt;The Distributed &lt;br /&gt;
								Transaction Coordinator &lt;br /&gt;
								&lt;/li&gt;
								&lt;li class=&quot;clsInfoBox&quot;&gt;Using Transactional NTFS &lt;br /&gt;
								from native code &lt;br /&gt;
								&lt;/li&gt;
								&lt;li class=&quot;clsInfoBox&quot;&gt;Using Transactional NTFS &lt;br /&gt;
								from managed code &lt;br /&gt;
								&lt;/li&gt;
							&lt;/ul&gt;
						&lt;/div&gt;
						&lt;/td&gt;
						&lt;td&gt;
						&lt;div class=&quot;clsInfoBox&quot;&gt;
							&lt;span class=&quot;clsSmWhite&quot;&gt;&lt;b&gt;This article uses the &lt;br /&gt;
							following technologies:&lt;/b&gt;&lt;br&gt;
							Windows Vista, .NET Framework &lt;/span&gt;&lt;br&gt;
¡¡&lt;/div&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;br&gt;
				&lt;span id=&quot;dl_parent&quot; style=&quot;FONT-SIZE: 100%; CURSOR: pointer&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
				&lt;a id=&quot;Code&quot; href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&quot;&gt;
				&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;Get &lt;br /&gt;
				the sample code for this article.&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
				&lt;div id=&quot;dl_child&quot; style=&quot;BORDER-RIGHT: #999999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #999999 1px solid; PADDING-LEFT: 0px; Z-INDEX: 100; VISIBILITY: hidden; PADDING-BOTTOM: 0px; BORDER-LEFT: #999999 1px solid; WIDTH: 500px; PADDING-TOP: 0px; BORDER-BOTTOM: #999999 1px solid; POSITION: absolute; BACKGROUND-COLOR: white&quot; at_parent=&quot;dl_parent&quot; at_child=&quot;dl_child&quot; at_position=&quot;y&quot;&gt;
					&lt;table style=&quot;background-image: url('http://msdn.microsoft.com/msdnmag/images/codebg.gif')&quot; cellSpacing=&quot;0&quot; cellPadding=&quot;20&quot; width=&quot;500&quot; border=&quot;0&quot; id=&quot;table7&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;&lt;b&gt;NEW:&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&quot;&gt;Explore&lt;/a&gt;&lt;br /&gt;
							the sample code online! &lt;/b&gt;&lt;br&gt;
							&lt;br&gt;
							- or - &lt;br&gt;
							&lt;br&gt;
							&lt;b&gt;Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TxF2007_07.exe&quot;&gt;
							TxF2007_07.exe&lt;/a&gt; (159KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
&lt;SCRIPT type=text/javascript&gt;
        at_attach(&quot;dl_parent&quot;, &quot;dl_child&quot;, &quot;hover&quot;, &quot;y&quot;, &quot;pointer&quot;);&lt;br /&gt;
      &lt;/SCRIPT&gt;
&lt;br /&gt;
				&lt;hr&gt;
				&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;0&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table8&quot;&gt;
					&lt;tr&gt;
						&lt;td width=&quot;50%&quot;&gt;
						&lt;img class=&quot;clsImgButton&quot; id=&quot;contentbtn&quot; onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; height=&quot;9&quot; alt=&quot;&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/minus.gif&quot; width=&quot;9&quot; align=&quot;absMiddle&quot; vspace=&quot;2&quot;&gt;&lt;a onclick=&quot;ToggleMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; name=&quot;contents&quot; href=&quot;#void&quot;&gt;&lt;b&gt;Contents&lt;/b&gt;&lt;/a&gt;&lt;br&gt;
¡¡&lt;div id=&quot;contentmenu&quot; style=&quot;MARGIN-TOP: 10px; DISPLAY: block; MARGIN-LEFT: 20px&quot;&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S1&quot;&gt;The Benefits of &lt;br /&gt;
							Transactional NTFS&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S2&quot;&gt;When to Avoid &lt;br /&gt;
							Transactional NTFS&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S3&quot;&gt;Getting Started&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S4&quot;&gt;Secondary Resource &lt;br /&gt;
							Managers&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S5&quot;&gt;Management&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S6&quot;&gt;What Happened to the &lt;br /&gt;
							Transacted Command Line?&lt;/a&gt;&lt;br&gt;
							&lt;a target=&quot;_self&quot; href=&quot;#S7&quot;&gt;In Closing&lt;/a&gt;&lt;br&gt;
¡¡&lt;/div&gt;
						&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;hr&gt;&lt;br&gt;
¡¡&lt;div class=&quot;articletext&quot;&gt;
					&lt;p class=&quot;clsNoIndent&quot; font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS001&quot;&gt;¡¡&lt;/p&gt;
					&lt;div class=&quot;dropcap&quot;&gt;
						I&lt;/div&gt;
					t¡¯s a revolutionary step for Windows&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;-based &lt;br /&gt;
					applications. And it can help you develop applications that &lt;br /&gt;
					are more robust than they could ever have been before. It¡¯s &lt;br /&gt;
					Transactional NTFS, also known as TxF. In this article, I &lt;br /&gt;
					explain Transactional NTFS, why it matters to developers, &lt;br /&gt;
					and how you can use this new technology in your &lt;br /&gt;
					applications.&lt;br /&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS002&quot;&gt;What is &lt;br /&gt;
					TxF? Conceptually, it is quite simple and can be expressed &lt;br /&gt;
					in a logical equation: Transactional NTFS = Transactions + &lt;br /&gt;
					NTFS. A new feature in Windows Vista&amp;#8482; and the next version &lt;br /&gt;
					of Windows Server&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;, code-named &lt;br /&gt;
					&amp;quot;Longhorn,&amp;quot; TxF introduces the concept of transacting file &lt;br /&gt;
					operations.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS003&quot;&gt;When I &lt;br /&gt;
					say transacted file operations, I am talking about &lt;br /&gt;
					transactions with fully ACID semantics that can be exposed &lt;br /&gt;
					directly to the developer. This means the ability to perform &lt;br /&gt;
					actions that are fully atomic, consistent, isolated, and &lt;br /&gt;
					durable is now enabled directly for file operations. These &lt;br /&gt;
					ACID capabilities are something that database developers &lt;br /&gt;
					have benefited from for years, and having this power for &lt;br /&gt;
					file operations is a very welcomed addition.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS004&quot;&gt;You¡¯re &lt;br /&gt;
					probably wondering if all these transactional capabilities &lt;br /&gt;
					have been built into NTFS, what is the performance overhead &lt;br /&gt;
					of Transactional NTFS? Well, TxF has a strictly pay-to-play &lt;br /&gt;
					model. If you aren¡¯t using transacted file operations, there &lt;br /&gt;
					is no overhead. And even if you are using transacted file &lt;br /&gt;
					operations, the overhead is pretty minimal (in the 1 to 2 &lt;br /&gt;
					percent range). For an application that is not I/O-bound, &lt;br /&gt;
					this performance impact probably would not even be &lt;br /&gt;
					noticeable.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS005&quot;&gt;Here¡¯s &lt;br /&gt;
					another aspect of performance to be aware of: Transactional &lt;br /&gt;
					NTFS is optimized for commit. When you write new pages to &lt;br /&gt;
					disk within a transaction, they are written directly in &lt;br /&gt;
					place while the previous pages are saved for retrieval by &lt;br /&gt;
					other readers if necessary. Because of this optimization, &lt;br /&gt;
					when the transaction is committed, the altered pages are &lt;br /&gt;
					already in place on disk. As a result, the overhead of &lt;br /&gt;
					committing the transaction is minimal.&lt;/p&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;The Benefits of Transactional NTFS&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS006&quot;&gt;Transactional NTFS sounds &lt;br /&gt;
					nice, in theory. But why should you, as a developer, use &lt;br /&gt;
					TxF? There are a number of distinct reasons. Specifically, &lt;br /&gt;
					TxF achieves three goals that help you develop powerful &lt;br /&gt;
					applications:&lt;/p&gt;
					&lt;p xmlid=&quot;PARAJULY2007NTFS007&quot;&gt;¡¡&lt;/p&gt;
					&lt;ul&gt;
						&lt;li&gt;Improved application stability&lt;br /&gt;
						&lt;/li&gt;
						&lt;li&gt;Improved platform stability&lt;br /&gt;
						&lt;/li&gt;
						&lt;li&gt;Increased innovation&lt;/li&gt;
					&lt;/ul&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;p class=&quot;clsNoIndent&quot; font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS008&quot;&gt;
					Let¡¯s take a closer look at how TxF achieves these goals.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS009&quot;&gt;
					Transactional NTFS enables better application stability by &lt;br /&gt;
					reducing or eliminating the amount of error-handling code &lt;br /&gt;
					that needs to be written and maintained for a given &lt;br /&gt;
					application. This ultimately reduces application complexity &lt;br /&gt;
					and makes the application easier to test. Say, for instance, &lt;br /&gt;
					you are developing a document management system where a SQL &lt;br /&gt;
					data source needs to be kept consistent with a file store on &lt;br /&gt;
					disk. Ensuring this consistency can be tricky and &lt;br /&gt;
					non-trivial in a non-transactional system. Without &lt;br /&gt;
					transactional file operations, it would be nearly impossible &lt;br /&gt;
					to account for every possible failure scenario, up to and &lt;br /&gt;
					including the operating system crashing at any imaginable &lt;br /&gt;
					point during the process.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS010&quot;&gt;One of &lt;br /&gt;
					the ways this was handled in the past was by storing the new &lt;br /&gt;
					version of the file with a temporary file name, writing the &lt;br /&gt;
					new data to the SQL database, and then renaming the &lt;br /&gt;
					temporary file to the real file name when committing the SQL &lt;br /&gt;
					transaction. But consider what happens if the application &lt;br /&gt;
					crashes or there is a power outage right after committing to &lt;br /&gt;
					the SQL database but before the file is renamed. Not only &lt;br /&gt;
					would you have an inconsistent data set, but you would also &lt;br /&gt;
					have an artifact on the file system that you would have to &lt;br /&gt;
					clean up at some point. As usual, the extremely difficult &lt;br /&gt;
					part lies in the details of how many different ways the &lt;br /&gt;
					process can fail.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS011&quot;&gt;Some &lt;br /&gt;
					solutions will implement their own entire two-phase commit &lt;br /&gt;
					protocol, which commits changes to the database and the file &lt;br /&gt;
					system at the same time. While this gets you a step closer &lt;br /&gt;
					to achieving the goal of application stability, implementing &lt;br /&gt;
					a custom two-phase commit system in your own application can &lt;br /&gt;
					be very difficult. And this requires code that you have to &lt;br /&gt;
					write, test, and maintain yourself.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS012&quot;&gt;Wouldn¡¯t &lt;br /&gt;
					it be better if transaction management was built into the &lt;br /&gt;
					platform rather than having to be implemented by each &lt;br /&gt;
					developer who needs this type of behavior? With the &lt;br /&gt;
					introduction of TxF in Windows Vista and Windows Server &lt;br /&gt;
					&amp;quot;Longhorn,&amp;quot; these capabilities are now built directly into &lt;br /&gt;
					the platform. And because Transactional NTFS is embedded in &lt;br /&gt;
					the system itself, it is capable of providing a level of &lt;br /&gt;
					integration that would not otherwise be possible for your &lt;br /&gt;
					applications.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS013&quot;&gt;One of &lt;br /&gt;
					the coolest parts about Transactional NTFS is that it can &lt;br /&gt;
					work with a large number of other transactional &lt;br /&gt;
					technologies. Because TxF uses the new Kernel Transaction &lt;br /&gt;
					Manager (KTM) features, and because the new KTM can work &lt;br /&gt;
					directly with the Microsoft&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;
					Distributed Transaction Coordinator (DTC), any technology &lt;br /&gt;
					that can work with DTC as a transaction coordinator can use &lt;br /&gt;
					transacted file operations within a single transaction. This &lt;br /&gt;
					means that you can now enlist transacted file operations &lt;br /&gt;
					within the same transaction as SQL operations, Web service &lt;br /&gt;
					calls via WS-AtomicTransaction, Windows Communication &lt;br /&gt;
					Foundation services via the OleTransactionProtocol, or even &lt;br /&gt;
					transacted MSMQ operations. You can even enlist transacted &lt;br /&gt;
					file operations directly with other technologies that are &lt;br /&gt;
					using XA-Transactions since DTC can also work with &lt;br /&gt;
					XA-Transactions. Simply put, if DTC can work with something, &lt;br /&gt;
					you can incorporate transacted file operations into it.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS014&quot;&gt;Using &lt;br /&gt;
					the document management example, how can you ensure &lt;br /&gt;
					consistency within a document management application more &lt;br /&gt;
					easily with TxF? This is where the DTC comes in handy. To &lt;br /&gt;
					absolutely ensure consistency between your SQL database and &lt;br /&gt;
					your file store, you can start a transaction, perform your &lt;br /&gt;
					SQL statements and file operations within that same &lt;br /&gt;
					transaction, and then commit or roll back the complete &lt;br /&gt;
					transaction based on the outcome. If your SQL call fails, &lt;br /&gt;
					your file will never be written. If your file system call &lt;br /&gt;
					fails, your SQL is rolled back. Everything remains &lt;br /&gt;
					consistent, and all of this is handled automatically by the &lt;br /&gt;
					platform since the operations are enlisted within a &lt;br /&gt;
					transaction.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS015&quot;&gt;When &lt;br /&gt;
					using this approach in my own application, I no longer have &lt;br /&gt;
					to worry about handling and accounting for every possible &lt;br /&gt;
					exception that could occur. I simply incorporate both &lt;br /&gt;
					operations within the same transaction, guaranteeing that if &lt;br /&gt;
					any exception is thrown, the platform will roll back the &lt;br /&gt;
					operations in question. Less code, more robust, very cool!&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS016&quot;&gt;That &lt;br /&gt;
					leaves two more goals. As for platform stability, this is &lt;br /&gt;
					achieved by some of the ways that Microsoft is using TxF in &lt;br /&gt;
					its own technologies. There are three core features in &lt;br /&gt;
					Windows Vista and Windows Server &amp;quot;Longhorn&amp;quot; that now make &lt;br /&gt;
					use of Transactional NTFS: Windows Update, System Restore, &lt;br /&gt;
					and Task Scheduler. All of these use TxF to write files to &lt;br /&gt;
					the file system within the scope of a transaction in order &lt;br /&gt;
					to handle rollback/commit in case of any exceptions, such as &lt;br /&gt;
					a system reboot due to a loss of power. If you¡¯ve ever &lt;br /&gt;
					experienced a loss of power right in the middle of Windows &lt;br /&gt;
					Update, you know this can leave your system dead and in need &lt;br /&gt;
					of a fresh installation. But now that Windows Update uses &lt;br /&gt;
					TxF, if this same situation occurs on your Windows Vista &lt;br /&gt;
					system, the computer can recover by rolling back the &lt;br /&gt;
					transaction when the system reboots. By adopting TxF &lt;br /&gt;
					internally, Microsoft has helped make its own operating &lt;br /&gt;
					system more stable.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS017&quot;&gt;Finally, &lt;br /&gt;
					TxF drives innovation by providing a framework for using &lt;br /&gt;
					transactions outside of SQL calls. Ultimately, Transactional &lt;br /&gt;
					NTFS can fundamentally change the way developers write &lt;br /&gt;
					applications, allowing them to build more robust code. By &lt;br /&gt;
					incorporating transactions into your design, you can write &lt;br /&gt;
					code without having to account for every single possible &lt;br /&gt;
					failure that can occur. The operating system will take care &lt;br /&gt;
					of those mundane details!&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;When to Avoid Transactional NTFS&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS018&quot;&gt;Despite all the benefits &lt;br /&gt;
					offered by TxF, there are some scenarios in which you should &lt;br /&gt;
					think about not using it. These are the same scenarios that &lt;br /&gt;
					are discussed when talking about avoiding traditional &lt;br /&gt;
					database transactional systems.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS019&quot;&gt;You &lt;br /&gt;
					shouldn¡¯t use TxF if you have a system that will have &lt;br /&gt;
					long-running transactions. The definition of &amp;quot;long-running&amp;quot; &lt;br /&gt;
					here is relative, however. A long-running transaction is any &lt;br /&gt;
					transaction that has been alive longer than many other &lt;br /&gt;
					transactions within the same log. This could mean a few &lt;br /&gt;
					seconds if there are thousands of transactions happening and &lt;br /&gt;
					lasting for very brief periods of time. On the other hand, a &lt;br /&gt;
					day or two might not be a long time if there are very few &lt;br /&gt;
					transactions happening in the system.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS020&quot;&gt;You &lt;br /&gt;
					should also be wary of using TxF if you are going to have &lt;br /&gt;
					multiple writers against the same file. Transacted file &lt;br /&gt;
					operations only allow for one writer at a time (even shared &lt;br /&gt;
					writers), meaning that a second writer won¡¯t be allowed to &lt;br /&gt;
					open the file while it is being held open by another writer, &lt;br /&gt;
					unless that second writer is within the same transaction. &lt;br /&gt;
					Because of this, TxF can introduce contention into a system &lt;br /&gt;
					that has multiple writers against a single file.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS021&quot;&gt;Finally, &lt;br /&gt;
					you need to be careful about auto-started services and &lt;br /&gt;
					mixing transaction resources. If the service is using &lt;br /&gt;
					Transactional NTFS and SQL, the files it needs access to &lt;br /&gt;
					could remain locked until recovery completes (since your &lt;br /&gt;
					service has a direct dependency on DTC and SQL, those &lt;br /&gt;
					services need to be started first, so you might not be able &lt;br /&gt;
					to fully recover your files until DTC and SQL finish &lt;br /&gt;
					recovering first).&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Getting Started&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS022&quot;&gt;Now let¡¯s take a look at &lt;br /&gt;
					how you can use TxF. If you are at all familiar with the &lt;br /&gt;
					existing file I/O Win32&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt; APIs, &lt;br /&gt;
					the Transactional NTFS APIs should come naturally. The new &lt;br /&gt;
					Transactional NTFS APIs are unchanged from their &lt;br /&gt;
					non-transacted counterparts aside from the addition of a &lt;br /&gt;
					couple of parameters at the end, which are specifically for &lt;br /&gt;
					transactions.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig1'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig1&quot;&gt;
					Figure&amp;nbsp;1&lt;/a&gt; gives some examples of Win32 file APIs and &lt;br /&gt;
					their transacted counterparts. The complete list is much &lt;br /&gt;
					longer; nearly every file API in Win32 has a corresponding &lt;br /&gt;
					transacted version.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS023&quot;&gt;From an &lt;br /&gt;
					application perspective, there are three primary vehicles &lt;br /&gt;
					you can use when developing a TxF-aware application. You can &lt;br /&gt;
					use the new KTM directly as the transaction coordinator. &lt;br /&gt;
					This lets you develop applications that are solely using TxF &lt;br /&gt;
					file operations within their transactions.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS024&quot;&gt;The &lt;br /&gt;
					second option is to use DTC as the transaction coordinator. &lt;br /&gt;
					When you use this method, you need to go through DTC to get &lt;br /&gt;
					the handle for the kernel-level transaction object that you &lt;br /&gt;
					can then pass into the Transacted APIs.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS025&quot;&gt;The &lt;br /&gt;
					third way is actually an extension to the second approach &lt;br /&gt;
					where you are using System.Transactions from managed code to &lt;br /&gt;
					make use of DTC (or just the Lightweight Transaction Manager &lt;br /&gt;
					if there is only a single durable enlistment). In a moment, &lt;br /&gt;
					I¡¯ll look at the challenges of this approach and what it &lt;br /&gt;
					really means to managed developers.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS026&quot;&gt;Right &lt;br /&gt;
					now, let¡¯s take a closer look at these three approaches.&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;2&lt;/span&gt; illustrates all the major moving parts in &lt;br /&gt;
					the transaction platform in Windows Vista and Windows Server &lt;br /&gt;
					&amp;quot;Longhorn.&amp;quot;&lt;/p&gt;
					&lt;div id=&quot;384524002&quot; style=&quot;DISPLAY: none; WIDTH: 524px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('384524002', '193263002');&quot;&gt;
						&lt;img height=&quot;384&quot; alt=&quot;Figure 2 The Transaction Platform&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/fig02_L.gif&quot; width=&quot;524&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 2&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;The &lt;br /&gt;
						Transaction Platform (Click the image for a smaller &lt;br /&gt;
						view) &lt;/span&gt;&lt;/div&gt;
					&lt;div id=&quot;193263002&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 263px&quot;&gt;
						&lt;a href=&quot;Javascript:ToggleImages('193263002', '384524002');&quot;&gt;
						&lt;img height=&quot;193&quot; alt=&quot;Figure 2 The Transaction Platform&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/fig02.gif&quot; width=&quot;263&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 2&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;The &lt;br /&gt;
						Transaction Platform (Click the image for a larger view)&lt;br /&gt;
						&lt;/span&gt;&lt;/div&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS027&quot;&gt;At the &lt;br /&gt;
					API level, there are three main interfaces into TxF. The &lt;br /&gt;
					first way is to go directly to KTM via the new ktmw32.h &lt;br /&gt;
					header file. At the most basic level, this contains the &lt;br /&gt;
					transaction coordinator Win32 calls for KTM: &lt;br /&gt;
					CreateTransaction, CommitTransaction, and &lt;br /&gt;
					RollbackTransaction. In this approach, you use these calls &lt;br /&gt;
					directly and have KTM itself do the transaction coordination &lt;br /&gt;
					if you are only doing transacted file operations within the &lt;br /&gt;
					single transaction (see&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig3'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig3&quot;&gt;
					Figure&amp;nbsp;3&lt;/a&gt;).&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS028&quot;&gt;The &lt;br /&gt;
					second interface is via DTC. With this approach, you use DTC &lt;br /&gt;
					as the transaction coordinator. To use TxF through DTC, you &lt;br /&gt;
					make use of COM and QueryInterface to grab the &lt;br /&gt;
					IKernelTransaction interface directly from DTC¡¯s &lt;br /&gt;
					ITransaction interface. Once you have a reference to the new &lt;br /&gt;
					IKernelTransaction COM interface, you can call its GetHandle &lt;br /&gt;
					method in order to retrieve the kernel-level transaction &lt;br /&gt;
					handle that can then be used to pass to the various &lt;br /&gt;
					Transacted APIs in Win32 (see&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig4'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig4&quot;&gt;
					Figure&amp;nbsp;4&lt;/a&gt;).&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS029&quot;&gt;If you &lt;br /&gt;
					are a managed developer, the solution isn¡¯t quite as &lt;br /&gt;
					elegant. Currently, to use TxF from managed code, you have &lt;br /&gt;
					to use P/Invoke and COM interop. Don¡¯t let that scare you &lt;br /&gt;
					away, though. For a large number of uses, the P/Invoke and &lt;br /&gt;
					COM interop code isn¡¯t too bad. If you¡¯re still too timid, &lt;br /&gt;
					you can grab some sample code from the MSDN&lt;sup class=&quot;clsSmall&quot;&gt;¢ç&lt;/sup&gt;
					Magazine Web site. The sample has a simple managed wrapper &lt;br /&gt;
					around Transactional NTFS that you can freely use in your &lt;br /&gt;
					own applications. (While you¡¯re playing with this sample &lt;br /&gt;
					code, you should also check out the&lt;br /&gt;
					&lt;a href=&quot;http://channel9.msdn.com/ShowPost.aspx?PostID=289816&quot;&gt;
					screencast&lt;/a&gt;. It demonstrates using TxF with just KTM, &lt;br /&gt;
					with SQL, and with Windows Communication Foundation.) In the &lt;br /&gt;
					short term, a more robust version of this wrapper will be &lt;br /&gt;
					included in an upcoming release of the Windows VistaBridge &lt;br /&gt;
					samples as part of the Windows SDK. In the longer term, the &lt;br /&gt;
					product team is currently working on a plan to integrate &lt;br /&gt;
					these APIs directly into the Microsoft .NET Framework.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS030&quot;&gt;To use &lt;br /&gt;
					TxF from managed code, you can continue to use the &lt;br /&gt;
					functionality of the System.Transactions namespace. To dig &lt;br /&gt;
					down into TxF, you are essentially following the same path &lt;br /&gt;
					that you would when using DTC in native code (see&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig4'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig4&quot;&gt;
					Figure&amp;nbsp;4&lt;/a&gt;), but with the managed code equivalents. From &lt;br /&gt;
					an object level, it looks something like&lt;br /&gt;
					&lt;span class=&quot;clsFigs&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot;&gt;
					Figure&amp;nbsp;5&lt;/span&gt;.&lt;/p&gt;
					&lt;div id=&quot;214280004&quot; style=&quot;DISPLAY: block; MARGIN: 5px 0px 10px 5px; WIDTH: 280px&quot;&gt;
						&lt;img height=&quot;214&quot; alt=&quot;Figure 5 TxF from Managed Code&quot; src=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/fig05.gif&quot; width=&quot;280&quot; border=&quot;0&quot;&gt;&lt;br&gt;
						&lt;span class=&quot;clsCap&quot;&gt;Figure 5&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;clsCaptxt&quot;&gt;TxF &lt;br /&gt;
						from Managed Code&lt;/span&gt;&lt;/div&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS031&quot;&gt;The &lt;br /&gt;
					first thing you need to do is grab the IDtcTransaction COM &lt;br /&gt;
					interface from the current Transaction (this can be done &lt;br /&gt;
					using the TransactionInterop helper class in &lt;br /&gt;
					System.Transactions). Once you have the IDtcTransaction, you &lt;br /&gt;
					can cast it to an IKernelTransaction COM interface, which &lt;br /&gt;
					under the hood will QueryInterface for the &lt;br /&gt;
					IKernelTransaction COM interface. Then, once you have a &lt;br /&gt;
					reference to the currently running kernel-level transaction &lt;br /&gt;
					via IKernelTransaction, you call GetHandle on it to get a &lt;br /&gt;
					handle that you can pass to the various new Transacted Win32 &lt;br /&gt;
					APIs. For example, you can pass this transaction handle to &lt;br /&gt;
					CreateFileTransacted in order to obtain a SafeFileHandle for &lt;br /&gt;
					a new file. This SafeFileHandle can then be passed to the &lt;br /&gt;
					constructor of the StreamWriter class, which is then used to &lt;br /&gt;
					write to the file (see&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig6'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig6&quot;&gt;
					Figure&amp;nbsp;6&lt;/a&gt;).&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS032&quot;&gt;You &lt;br /&gt;
					should also know that TxF has read-committed consistency. &lt;br /&gt;
					This has impact on both writing and reading a file &lt;br /&gt;
					transactionally. When writing a file, only a single &lt;br /&gt;
					transaction can be writing to the file (note that we are &lt;br /&gt;
					talking about a single transaction, not a single writer). &lt;br /&gt;
					Non-transacted writers are blocked by the transacted writer, &lt;br /&gt;
					even if opened with share-write access. Additionally, a &lt;br /&gt;
					non-transacted writer prevents any transacted reader or &lt;br /&gt;
					writer from being opened on the file.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS033&quot;&gt;When &lt;br /&gt;
					reading from a file transactionally, there is an isolated &lt;br /&gt;
					view of the file for the life of the file handle. This &lt;br /&gt;
					isolated view of the file is based on the most recent &lt;br /&gt;
					contents of the file when the file handle was created. If a &lt;br /&gt;
					transacted writer is in the middle of modifying the file, &lt;br /&gt;
					those modifications won¡¯t be picked up by a new transacted &lt;br /&gt;
					reader until the changes are actually committed. In &lt;br /&gt;
					addition, because of the read-committed consistency of &lt;br /&gt;
					Transactional NTFS, this isolated view of the transacted &lt;br /&gt;
					reader remains even if a transacted writer changes a file &lt;br /&gt;
					and commits those changes anytime during the life of the &lt;br /&gt;
					transacted reader. These transacted readers block &lt;br /&gt;
					non-transacted writers but only while their file handle is &lt;br /&gt;
					open. They do not block modification of the file for the &lt;br /&gt;
					life of the transaction. If you need a consistent view of &lt;br /&gt;
					the file throughout the life of the transaction, you need to &lt;br /&gt;
					keep the transacted reader¡¯s file handle open.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS034&quot;&gt;Finally, &lt;br /&gt;
					developers should be aware that when using file handles for &lt;br /&gt;
					transacted file operations, there is a distinct difference &lt;br /&gt;
					between transacted and non-transacted file operations with &lt;br /&gt;
					regard to file handles. If you get a file handle from one of &lt;br /&gt;
					the new Transacted APIs, the file handle could become &lt;br /&gt;
					invalid at any time, whether from a transaction committing &lt;br /&gt;
					or a transaction rolling back.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Secondary Resource Managers&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS035&quot;&gt;Secondary resource &lt;br /&gt;
					managers allow applications to manage their own resources &lt;br /&gt;
					running within a transaction, particularly their own &lt;br /&gt;
					transaction logs, as well as other possible file operations &lt;br /&gt;
					within a directory (and all subdirectories) specific to the &lt;br /&gt;
					application.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS036&quot;&gt;I have a &lt;br /&gt;
					good reason for discussing secondary resource managers in &lt;br /&gt;
					this article. When TxF was developed, there was an emphasis &lt;br /&gt;
					placed on availability over consistency. Since it is now &lt;br /&gt;
					possible within a transaction to modify files that are &lt;br /&gt;
					necessary to boot, the operating system has to guarantee &lt;br /&gt;
					that these files are always available. In order to guarantee &lt;br /&gt;
					these files are always available, the system drive¡¯s &lt;br /&gt;
					transaction manager is required to be the transaction &lt;br /&gt;
					coordinator. Because of this, you cannot use a different &lt;br /&gt;
					transaction coordinator, like DTC for instance, as the &lt;br /&gt;
					&amp;quot;root&amp;quot; or superior transaction coordinator for these files. &lt;br /&gt;
					As a result, a transaction that needs to use DTC with other &lt;br /&gt;
					resource managers (such as SQL) cannot use TxF on the system &lt;br /&gt;
					drive. This means that if you want to use Transactional NTFS &lt;br /&gt;
					on the system drive within the same transaction as &lt;br /&gt;
					operations against SQL Server&amp;#8482;, for example, you must use a &lt;br /&gt;
					different strategy.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS037&quot;&gt;The &lt;br /&gt;
					simplest way to get around this limitation is to place all &lt;br /&gt;
					of your data on a separate partition. If that is not &lt;br /&gt;
					possible, or you cannot guarantee that the data will be on a &lt;br /&gt;
					non-system partition, you can use a secondary resource &lt;br /&gt;
					manager. When using a secondary resource manager to manage &lt;br /&gt;
					transactional file operations for a given directory (and any &lt;br /&gt;
					subdirectories), you are informing KTM that the application &lt;br /&gt;
					will control resource management for any files residing &lt;br /&gt;
					there. This allows the default resource manager on the &lt;br /&gt;
					system volume to continue to be available and, hence, allows &lt;br /&gt;
					a transaction coordinator other than KTM to become the &lt;br /&gt;
					superior transaction coordinator.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS038&quot;&gt;At the &lt;br /&gt;
					command line, you can create and manage secondary resource &lt;br /&gt;
					managers using the FSUtil tool and the commands shown in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig7'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig7&quot;&gt;
					Figure&amp;nbsp;7&lt;/a&gt;. However, for applications that need to use a &lt;br /&gt;
					secondary resource manager, it is better to control the &lt;br /&gt;
					secondary resource manager programmatically. To do this, you &lt;br /&gt;
					can use the DeviceIoControl Win32 API with specific &lt;br /&gt;
					dwIoControlCodes, outlined in&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig8'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig8&quot;&gt;
					Figure&amp;nbsp;8&lt;/a&gt;.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS039&quot;&gt;When &lt;br /&gt;
					using secondary resource managers, the startup and recovery &lt;br /&gt;
					of the resource manager must be done by your application. &lt;br /&gt;
					The act of starting the resource manager creates the KTM &lt;br /&gt;
					objects to manage transactions, and opens up the Common Log &lt;br /&gt;
					File System (CLFS) log and metadata that is stored locally &lt;br /&gt;
					with your directories; the act of recovering the resource &lt;br /&gt;
					manager recovers all files to a consistent state within the &lt;br /&gt;
					secondary resource manager. The resource manager will stop &lt;br /&gt;
					when the last handle to the resource manager root goes away. &lt;br /&gt;
					As a result, files within a secondary resource manager are &lt;br /&gt;
					not automatically made consistent at system startup. &lt;br /&gt;
					Instead, that is done when your application starts and &lt;br /&gt;
					recovers the secondary resource manager. In addition, files &lt;br /&gt;
					are not automatically made consistent when the system is &lt;br /&gt;
					backed up with any software that uses the volume shadow copy &lt;br /&gt;
					service (VSS) unless you provide a VSS writer. Of course, if &lt;br /&gt;
					you restore an inconsistent secondary resource manager and &lt;br /&gt;
					then start and recover it, the files will be made &lt;br /&gt;
					consistent. Make sure that your backup software also backs &lt;br /&gt;
					up the TxF metadata using the &lt;br /&gt;
					FSCTL_TXFS_READ_BACKUP_INFORMATION and &lt;br /&gt;
					FSCTL_TXFS_WRITE_BACKUP_INFORMATION dwIoControlCodes.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS040&quot;&gt;As I &lt;br /&gt;
					mentioned, the use of secondary resource managers is only &lt;br /&gt;
					required if the files participating in the transaction are &lt;br /&gt;
					on the system drive and you want a technology other than KTM &lt;br /&gt;
					to be the superior transaction coordinator or you want to &lt;br /&gt;
					control the consistency and availability of the resource &lt;br /&gt;
					manager. Secondary resource managers become very powerful in &lt;br /&gt;
					this regard if you wish to have more direct control over the &lt;br /&gt;
					behavior of the resource manager in your application. If the &lt;br /&gt;
					files you are operating on are on a non-system drive, you do &lt;br /&gt;
					not need to worry about the use of secondary resource &lt;br /&gt;
					managers. We are currently working to lessen this &lt;br /&gt;
					restriction in Windows Server &amp;quot;Longhorn&amp;quot; so this requirement &lt;br /&gt;
					won¡¯t be applied to the entire system drive, but only to the &lt;br /&gt;
					parts of the system drive that Windows absolutely needs to &lt;br /&gt;
					boot.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;Management&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS041&quot;&gt;For any application that &lt;br /&gt;
					is going to live in a production environment, it is &lt;br /&gt;
					important to think about how the application will be &lt;br /&gt;
					managed. Therefore, you need to know how you can monitor TxF &lt;br /&gt;
					itself.&lt;br /&gt;
					&lt;a class=&quot;clsFigs&quot; onclick=&quot;OpenUrl('default.aspx?loc=&amp;amp;fig=true#fig9'); return false;&quot; target=&quot;_self&quot; xmlns:user=&quot;http://msdn.microsoft.com&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;fig=true#fig9&quot;&gt;
					Figure&amp;nbsp;9&lt;/a&gt; shows a list of control codes that can be used &lt;br /&gt;
					with DeviceIoControl to help you do just that.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS042&quot;&gt;Similar &lt;br /&gt;
					to the information on resource managers provided previously, &lt;br /&gt;
					you can get the same information as these control codes from &lt;br /&gt;
					the FSUtil command-line tool. The commands are as follows:&lt;/p&gt;
					&lt;p xmlid=&quot;PARAJULY2007NTFS043&quot;&gt;¡¡&lt;/p&gt;
					&lt;ul&gt;
						&lt;li&gt;fsutil transaction list&lt;br /&gt;
						&lt;/li&gt;
						&lt;li&gt;fsutil transaction fileinfo&lt;br /&gt;
						&lt;/li&gt;
						&lt;li&gt;fsutil transaction query&lt;/li&gt;
					&lt;/ul&gt;
					&lt;p&gt;¡¡&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;What Happened to the Transacted &lt;br /&gt;
					Command Line?&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS044&quot;&gt;If you were involved in &lt;br /&gt;
					the early betas for Windows Vista, you may recall seeing a &lt;br /&gt;
					transaction command available from the command line. This &lt;br /&gt;
					allowed an administrator to start a transaction from the &lt;br /&gt;
					command line and run an application, and then any file &lt;br /&gt;
					operations within that application would implicitly be &lt;br /&gt;
					transacted.&lt;/p&gt;
					&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS045&quot;&gt;While &lt;br /&gt;
					testing application compatibility in Windows Vista, the team &lt;br /&gt;
					found that this implicit model was difficult for COM+ and &lt;br /&gt;
					managed developers to use safely. As a result, the model was &lt;br /&gt;
					changed to be opt-in and explicit to avoid this confusion. &lt;br /&gt;
					The downside to this change is that if you wish to use TxF &lt;br /&gt;
					in your app, your code will have to change to call the new &lt;br /&gt;
					APIs.&lt;/p&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
					&lt;span class=&quot;clsSubhead&quot;&gt;In Closing&lt;/span&gt;&lt;br&gt;
¡¡&lt;p font=&quot;minionmmroman&quot; xmlid=&quot;PARAJULY2007NTFS046&quot;&gt;Transactional NTFS is a &lt;br /&gt;
					truly innovative technology. It helps developers create more &lt;br /&gt;
					reliable applications on a more powerful platform. With TxF, &lt;br /&gt;
					developers can have atomic file operations that result in &lt;br /&gt;
					consistent file data, easing the test burden by reducing the &lt;br /&gt;
					number of error conditions to test for, and assisting in &lt;br /&gt;
					multi-user environments by providing isolation via ACID &lt;br /&gt;
					transaction semantics. Consider using TxF when developing &lt;br /&gt;
					apps that target Windows Vista and Windows Server &lt;br /&gt;
					&amp;quot;Longhorn.&amp;quot; For more information, see the &amp;quot;Transaction &lt;br /&gt;
					Resources&amp;quot; sidebar.&lt;/p&gt;
					&lt;p font=&quot;minionmmitalic&quot; xmlid=&quot;PARAJULY2007NTFS047&quot;&gt;I would &lt;br /&gt;
					like to thank Dana Groff, Christian Allred, and Jon Cargille &lt;br /&gt;
					for their help with this article.&lt;/p&gt;
					&lt;div class=&quot;clsSideBox&quot; style=&quot;DISPLAY: block&quot;&gt;
						&lt;div class=&quot;clsSideBar&quot; onclick=&quot;ToggleMenu(SideButton, SideBox)&quot;&gt;
							&lt;img class=&quot;clsImgButton&quot; id=&quot;SideButton&quot; height=&quot;9&quot; alt=&quot;&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/minus.gif&quot; width=&quot;9&quot; align=&quot;middle&quot;&gt;&lt;a style=&quot;FONT-WEIGHT: bold; COLOR: #ffffff; TEXT-DECORATION: none&quot; onclick=&quot;return false&quot; target=&quot;_self&quot; name href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=&amp;side=true#&quot;&gt;Transaction &lt;br /&gt;
							Resources&lt;/a&gt;&lt;/div&gt;
						&lt;div id=&quot;SideBox&quot; style=&quot;PADDING-RIGHT: 5px; DISPLAY: block; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px; BACKGROUND-COLOR: #eeeeee&quot;&gt;
							Here¡¯s a list I¡¯ve compiled of resources relating to &lt;br /&gt;
							Transactional NTFS. I¡¯ll be updating this list over &lt;br /&gt;
							time to reflect new resources, so be sure to watch &lt;br /&gt;
							for updates on&lt;br /&gt;
							&lt;a href=&quot;http://www.managed-world.com/TransactionResourcesList.aspx&quot;&gt;
							my blog&lt;/a&gt;.&lt;br /&gt;
							&lt;p&gt;&lt;br&gt;
							&lt;span class=&quot;clsSubhead&quot;&gt;Web Sites:&lt;/span&gt;&lt;br&gt;
¡¡&lt;/p&gt;
							&lt;p&gt;¡¡&lt;/p&gt;
							&lt;ul&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=388&amp;SiteID=1&quot;&gt;
								Transactions Programming Forum&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://www.microsoft.com/windowsserver2003/appserver/transmgmt.mspx&quot;&gt;
								Transaction Management in Windows &lt;/a&gt;&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://msdn2.microsoft.com/aa365456&quot;&gt;
								Transactional NTFS (TxF)&lt;/a&gt;&lt;/li&gt;
							&lt;/ul&gt;
							&lt;p&gt;¡¡&lt;/p&gt;
							&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
								&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
								&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
							&lt;br&gt;
							&lt;span class=&quot;clsSubhead&quot;&gt;Blogs:&lt;/span&gt;&lt;br&gt;
¡¡&lt;p&gt;¡¡&lt;/p&gt;
							&lt;ul&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://www.pluralsight.com/blogs/jimjohn&quot;&gt;
								Jim Johnson &lt;/a&gt;&lt;/li&gt;
								&lt;li&gt;&lt;a href=&quot;http://blogs.msdn.com/florinlazar&quot;&gt;
								Florin Lazar &lt;/a&gt;&lt;/li&gt;
								&lt;li&gt;&lt;a href=&quot;http://www.managed-world.com&quot;&gt;Jason &lt;br /&gt;
								Olson&lt;/a&gt;&lt;/li&gt;
							&lt;/ul&gt;
							&lt;p&gt;¡¡&lt;/p&gt;
							&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
								&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
								&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
							&lt;br&gt;
							&lt;span class=&quot;clsSubhead&quot;&gt;Specific Blog Posts:&lt;/span&gt;&lt;br&gt;
¡¡&lt;p&gt;¡¡&lt;/p&gt;
							&lt;ul&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://www.pluralsight.com/blogs/jimjohn/archive/2006/09/01/36863.aspx&quot;&gt;
								An MSDTC Proxy Enhancement (MLTM)&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://www.pluralsight.com/blogs/jimjohn/archive/2006/08/31/36819.aspx&quot;&gt;
								Integration between System.Transactions and TxF&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://www.managed-world.com/WhatIsTxFAndWhyDoICare.aspx&quot;&gt;
								What Is TxF and Why Do I Care?&lt;/a&gt;&lt;/li&gt;
							&lt;/ul&gt;
							&lt;p&gt;¡¡&lt;/p&gt;
							&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
								&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
								&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
							&lt;br&gt;
							&lt;span class=&quot;clsSubhead&quot;&gt;Media:&lt;/span&gt;&lt;br&gt;
¡¡&lt;p&gt;¡¡&lt;/p&gt;
							&lt;ul&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://channel9.msdn.com/ShowPost.aspx?PostID=287192&quot;&gt;
								Transactional Vista: KTM and Friends&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://channel9.msdn.com/ShowPost.aspx?postID=142120&quot;&gt;
								Vista Transactional File System&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032294095&quot;&gt;
								The Revolutionary Vista TxF Infrastructure&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032313126&quot;&gt;
								Developing Applications for Windows Vista with &lt;br /&gt;
								Transactional NTFS&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://channel9.msdn.com/ShowPost.aspx?PostID=289816&quot;&gt;
								Developer, Meet Server #1&amp;#8212;Transactional NTFS&lt;/a&gt;&lt;br /&gt;
								&lt;/li&gt;
								&lt;li&gt;
								&lt;a href=&quot;http://channel9.msdn.com/ShowPost.aspx?PostID=296861&quot;&gt;
								Developer, Meet Server #2&amp;#8212;Transactional NTFS and &lt;br /&gt;
								WCF&lt;/a&gt;&lt;/li&gt;
							&lt;/ul&gt;
							&lt;p&gt;¡¡&lt;/p&gt;
							&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
								&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
								&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
							&lt;br&gt;
¡¡&lt;div style=&quot;MARGIN-TOP: -10px&quot; align=&quot;right&quot;&gt;
								&lt;a style=&quot;FONT-SIZE: 80%; TEXT-DECORATION: none&quot; onclick=&quot;ToggleMenu(SideButton, SideBox)&quot; target=&quot;_self&quot; href=&quot;#&quot;&gt;
								&lt;b&gt;Close [x]&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;
						&lt;/div&gt;
					&lt;/div&gt;
					&lt;div style=&quot;MARGIN-TOP: 5px&quot; align=&quot;right&quot;&gt;
						&lt;a class=&quot;clsSmall&quot; onclick=&quot;OpenMenu(contentbtn, contentmenu);&quot; target=&quot;_self&quot; href=&quot;#contents&quot;&gt;
						&lt;img style=&quot;MARGIN-LEFT: 5px&quot; height=&quot;8&quot; alt=&quot;Back to top&quot; src=&quot;http://msdn.microsoft.com/msdnmag/images/top.gif&quot; width=&quot;18&quot; align=&quot;bottom&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/div&gt;
					&lt;br&gt;
¡¡&lt;table cellSpacing=&quot;0&quot; cellPadding=&quot;5&quot; width=&quot;100%&quot; border=&quot;0&quot; id=&quot;table9&quot;&gt;
						&lt;tr&gt;
							&lt;td vAlign=&quot;top&quot;&gt;
							&lt;img style=&quot;BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px&quot; height=&quot;16&quot; alt=&quot;Download Image&quot; hspace=&quot;5&quot; src=&quot;http://msdn.microsoft.com/msdn-online/shared/graphics/icodownl.gif&quot; width=&quot;16&quot;&gt;&lt;b&gt;
							NEW:&lt;br /&gt;
							&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/code/?url=http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx?loc=en&quot;&gt;
							Explore&lt;/a&gt; the sample code online! &lt;/b&gt;- or - &lt;b&gt;
							Code download available at: &lt;/b&gt;
							&lt;a href=&quot;http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TxF2007_07.exe&quot;&gt;
							TxF2007_07.exe&lt;/a&gt; (159KB) &lt;/td&gt;
						&lt;/tr&gt;
					&lt;/table&gt;
				&lt;/div&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
<author>ÓÞíâÏÚ úÜ</author>
<pubDate>Jul, 29 2007 04:25:42 GMT</pubDate>
<category>App</category>
</item>
</channel>
</rss>
