<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>John's Blog</title><link>http://blogs.msdn.com/b/johnsheehan/</link><description /><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Automatically Launching Local Apps in a Virtual Environment</title><link>http://blogs.msdn.com/b/johnsheehan/archive/2009/10/08/automatically-launching-local-apps-in-a-virtual-environment.aspx</link><pubDate>Thu, 08 Oct 2009 17:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9904941</guid><dc:creator>jsheehan</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johnsheehan/rsscomments.aspx?WeblogPostID=9904941</wfw:commentRss><comments>http://blogs.msdn.com/b/johnsheehan/archive/2009/10/08/automatically-launching-local-apps-in-a-virtual-environment.aspx#comments</comments><description>&lt;P&gt;This article will describe a method for having a locally-installed process automatically launch inside a virtual environment. This method does not require publishing new shortcuts for the local application. &lt;/P&gt;
&lt;H2&gt;&lt;SPAN style="COLOR: #4f81bd"&gt;&lt;SPAN style="FONT-FAMILY: Cambria"&gt;Background&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;App-V customers often have interesting, advanced scenarios that require locally installed applications to run inside of a virtual environment. For example, let's say that the customer has a web application that requires an ActiveX control in order to function correctly. However, they don't want to allow their users to install / upgrade ActiveX controls for security reasons. And, they don't want other websites to have access to this ActiveX control, in case it has any security vulnerabilities that a malicious website could use to attack their enterprise. What can they do? How can they deploy / service this app's ActiveX control safely? At first glance, it may seem like App-V can't be helpful in this situation, since Internet Explorer is locally installed. &lt;/P&gt;
&lt;P&gt;It turns out that App-V can be used to help solve this deployment / servicing problem. This topic has already been covered in other articles. The basic technique is as follows: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create a sequencing that contains just the ActiveX control(s) &lt;/LI&gt;
&lt;LI&gt;Create an OSD for this package that launches Internet Explorer and takes the user directly to the web application's URL &lt;/LI&gt;
&lt;LI&gt;Publish a shortcut that the user clicks on when they want to run the web application &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;When the user clicks on the shortcut for the web application, Internet Explorer will launch inside the virtual environment of the ActiveX control and the web application will be fully functional. This approach has a few key benefits: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;It normalizes the deployment / servicing model for the enterprise, allowing ActiveX controls to be deployed and serviced just like standard applications. &lt;/LI&gt;
&lt;LI&gt;The user can run the application without having to be given permission to install ActiveX controls. &lt;/LI&gt;
&lt;LI&gt;Regular browser sessions cannot run the ActiveX control, preventing malicious websites from leveraging any security vulnerabilities that may exist in the control. &lt;/LI&gt;
&lt;LI&gt;It integrates the web application into Windows, making it seem more like a regular application. The user no longer needs to launch the browser and then browse to the app's URL. The shortcut that is published takes care of this when they click on it. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;With the advent of Dynamic Suite Composition in App-V 4.5, this approach has been pushed even further. Now, instead of having Internet Explorer launch in the Virtual Environment of a single package, some customers have started running IE run in a Virtual Environment that contains components from multiple App-V packages. The approach taken is similar to what was done previously, with a couple of additional steps. The basic technique is as follows: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create an empty sequencing that represents the settings for Internet Explorer. Have the OSD for this package launch Internet Explorer. This package will be the primary package that stores all of the settings for virtual Internet Explorer. &lt;/LI&gt;
&lt;LI&gt;Create additional sequencings, one for each IE plug-in you want to make available to your users. Make these packages optional secondary packages of the primary Internet Explorer package that you created in step 1. &lt;/LI&gt;
&lt;LI&gt;Use the standard entitlement mechanism in App-V to control which plug-ins are available for different users. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;This technique has all of the same benefits of the previous one, but provides additional entitlement and servicing granularity. However, some customers don't like having to publish a separate shortcut for the local application (in this case, Internet Explorer) in order to leverage it. In some cases, they don't want to have to train their users to click on a different shortcut. Or, in the case of complex applications, like Microsoft Office, there are just too many ways that the application can be launched other than through its shortcuts, such as the myriad file type associations that Office publishes. What they're looking for is the ability to express that a locally-installed application should always run inside of its virtual environment, regardless of how it gets launched. &lt;/P&gt;
&lt;P&gt;This article will describe how to accomplish this scenario. &lt;/P&gt;
&lt;H2&gt;&lt;SPAN style="COLOR: #4f81bd"&gt;&lt;SPAN style="FONT-FAMILY: Cambria"&gt;Overview&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;If you've ever been curious enough to look at the shortcuts that App-V publishes for virtual applications, you may have noticed something interesting. The shortcuts don't point directly to the app that is going to be launched. Rather, they point to App-V launcher process (sfttray.exe) and pass a parameter that tells the launcher which application should be launched. So, for example, let's say you have virtualized Microsoft Word 2007. If you look at the properties of the Microsoft Word shortcut, you might expect to see a path to the exe, something like: &lt;STRONG&gt;&lt;EM&gt;Q:\office\office12\winword.exe&lt;/EM&gt;&lt;/STRONG&gt;. However, instead, you will see something like: &lt;STRONG&gt;&lt;EM&gt;"C:\Program Files\Microsoft Application Virtualization Client\sfttray.exe" /launch "Microsoft Office Word 2007"&lt;/EM&gt;&lt;/STRONG&gt;. This is the mechanism that App-V uses to ensure that the Virtual Environment for the application gets set up before the process is launched. It is the only supported way for a non-virtual process to launch a process inside of a virtual environment. &lt;/P&gt;
&lt;P&gt;So, we need to find a way to have the launch of a local process trigger this mechanism, so that it will come up inside a virtual environment. To do this, we will need to leverage some developer-focused features of Windows and some custom C/C++ code. &lt;/P&gt;
&lt;H2&gt;&lt;SPAN style="COLOR: #4f81bd"&gt;&lt;SPAN style="FONT-FAMILY: Cambria"&gt;Intercepting Process Creation&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;To achieve our goal, the first thing we need to be able to do is to intercept local process creation and change what happens during launch. In order to do this, we can leverage a developer-focused feature of Windows called Image File Execution Options. If you're interested in reading more about Image File Execution Options, read this &lt;A href="http://msdn.microsoft.com/en-us/library/a329t4ed.aspx" mce_href="http://msdn.microsoft.com/en-us/library/a329t4ed.aspx"&gt;article&lt;/A&gt;. Basically, Image File Execution Options allows control over certain aspects of a process' launch. The option we're interested in using is the &lt;STRONG&gt;Debugger&lt;/STRONG&gt; option. This option is designed to allow developers to intercept the creation of a process and start the process in a debugging session. However, there is no reason that we can't leverage this mechanism to achieve our non-debugging goals. &lt;/P&gt;
&lt;H2&gt;&lt;SPAN style="FONT-FAMILY: Cambria; COLOR: #4f81bd"&gt;The Dangers of Infinite Recursion &lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;Before I discuss how to use the &lt;STRONG&gt;Debugger&lt;/STRONG&gt; option, I need to point out one danger with using it. The Debugger option will catch every process launch for a particular binary name (e.g. winword.exe) and replace the launch with another process. So, if I specify &lt;STRONG&gt;&lt;EM&gt;replace.exe&lt;/EM&gt;&lt;/STRONG&gt; as the Debugger for &lt;STRONG&gt;&lt;EM&gt;original.exe&lt;/EM&gt;&lt;/STRONG&gt;, when I try to launch &lt;STRONG&gt;&lt;EM&gt;original.exe&lt;/EM&gt;&lt;/STRONG&gt;, &lt;STRONG&gt;&lt;EM&gt;replace.exe&lt;/EM&gt;&lt;/STRONG&gt; will actually get launched instead. This may seem fine, since it is what we want to happen. But, what happens if &lt;STRONG&gt;&lt;EM&gt;replace.exe&lt;/EM&gt;&lt;/STRONG&gt; eventually tries to launch &lt;STRONG&gt;&lt;EM&gt;original.exe&lt;/EM&gt;&lt;/STRONG&gt;? You guessed it, &lt;STRONG&gt;&lt;EM&gt;replace.exe&lt;/EM&gt;&lt;/STRONG&gt; will actually get launched. And, if that instance of &lt;STRONG&gt;&lt;EM&gt;replace.exe&lt;/EM&gt;&lt;/STRONG&gt; eventually tries to launch &lt;STRONG&gt;&lt;EM&gt;original.exe&lt;/EM&gt;&lt;/STRONG&gt;, &lt;STRONG&gt;&lt;EM&gt;replace.exe&lt;/EM&gt;&lt;/STRONG&gt; will get launched again. In programming, this process of something calling itself is called &lt;EM&gt;recursion&lt;/EM&gt;. If it continues without stopping, it is called &lt;EM&gt;infinite recursion&lt;/EM&gt;. As you can probably guess, infinite recursion is usually a very bad thing. &lt;/P&gt;
&lt;P&gt;The reason that I bring up the concept of infinite recursion is that naïve usage of Debugger can result in infinite recursion and recovering from this can be a pain. In fact, the simplest way to recover is typically to reboot (there are more advanced ways of recovering, such as using pskill.exe from Sysinternals, but I'm not going to get into that in this article). &lt;/P&gt;
&lt;H3&gt;Avoiding Infinite Recursion &lt;/H3&gt;
&lt;P&gt;There are several ways to avoid this type of infinite recursion in practice. While most of them require you to write custom code, the way I'm going to demonstrate does not require any custom code to be written. Instead, it relies on App-V's Virtual Registry to hide the Debugger value inside the Virtual Environment, thereby breaking the recursion cycle. To do this, we simply add some elements to the OSD file for the primary package that tell App-V to hide Debugger value. Here is a sample that will hide the Debugger value for notepad.exe, which would be stored under the following registry key: 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe'. &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;lt;SOFTPKG …….&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;IMPLEMENTATION&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;VIRTUALENV …….&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;REGISTRY&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;REGKEY HIVE="HKLM" KEY="SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe"&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;REGVALUE NAME="Debugger" REGTYPE="REG_SZ"&amp;gt;&amp;lt;/REGVALUE&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/REGKEY&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/REGISTRY&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/VIRTUALENV&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/IMPLEMENTATION&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&amp;lt;/SOFTPKG&amp;gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;As you can see in this sample, a &amp;lt;REGISTRY&amp;gt; element was added under the existing &amp;lt;VIRTUALENV&amp;gt; element. Then, REGKEY and REGVALUE elements were added to set the appropriate value in the registry. Remember that the key is specific to the name of the binary being launched. So, if you wanted to change the binary in the local registry, you absolutely need to update the OSD file according and make sure that App-V gets receives the update by triggering a publish refresh operation. &lt;/P&gt;
&lt;H2&gt;&lt;SPAN style="COLOR: #4f81bd"&gt;&lt;SPAN style="FONT-FAMILY: Cambria"&gt;Setting the Debugger Value&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;Now that we have guarded against the danger of infinite recursion, it is time to set the Debugger value in the local registry. To set this value, you need two pieces of information: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The name of the exe that you want to intercept &lt;/LI&gt;
&lt;LI&gt;The name that you gave to the app in the OSD of the primary package &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;For our example, let's assume that we are trying to intercept &lt;STRONG&gt;&lt;EM&gt;notepad.exe&lt;/EM&gt;&lt;/STRONG&gt; and we want it to run inside the Virtual Environment represented by an app named "Virtual Office". To do this, we would create a key in the local registry named: 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\&lt;STRONG&gt;notepad.exe&lt;/STRONG&gt;'. Next, we would create a new String Value and name it Debugger. Then we would set the Debugger value to: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;sfttray.exe /exe sftlp.exe /launch "&lt;STRONG&gt;Virtual Office&lt;/STRONG&gt;" &lt;/P&gt;
&lt;P&gt;I'm not going to go into the details of what this command does. But, basically, it launches &lt;STRONG&gt;notepad.exe&lt;/STRONG&gt; in the Virtual Environment of the &lt;STRONG&gt;Virtual Office&lt;/STRONG&gt; app. &lt;/P&gt;
&lt;H2&gt;&lt;SPAN style="FONT-FAMILY: Cambria; COLOR: #4f81bd"&gt;Summary &lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;In summary, the steps you need to take to automatically launch a locally-installed app inside a virtual environment are: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create a sequencing that contains the virtual environment you want the local app to run inside of. Remember the name you gave the app (in the OSD). For our example, we called it &lt;STRONG&gt;Virtual Office&lt;/STRONG&gt;. &lt;/LI&gt;
&lt;LI&gt;Update the OSD with the correct REGISTRY tags to prevent infinite recursion. &lt;/LI&gt;
&lt;LI&gt;Create the appropriate &lt;STRONG&gt;Debugger&lt;/STRONG&gt; value in the local registry. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Once you have performed these steps, the app will always get created in the appropriate Virtual Environment. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9904941" width="1" height="1"&gt;</description></item><item><title>HTTP Publishing in App-V (Part 1)</title><link>http://blogs.msdn.com/b/johnsheehan/archive/2009/03/24/http-publishing-in-app-v-part-1.aspx</link><pubDate>Tue, 24 Mar 2009 07:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9503403</guid><dc:creator>jsheehan</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johnsheehan/rsscomments.aspx?WeblogPostID=9503403</wfw:commentRss><comments>http://blogs.msdn.com/b/johnsheehan/archive/2009/03/24/http-publishing-in-app-v-part-1.aspx#comments</comments><description>&lt;p&gt;With all the excitement around HTTP streaming in App-V 4.5, many people fail to realize HTTP Publishing has been a feature of App-V since…well…the very first release of SoftGrid. This series of articles will discuss how to build your own App-V publishing server. In this first article, I will go over how to create a very basic publishing server. In future articles, I will discuss advanced features that can be enabled using a custom HTTP publishing server. 
&lt;/p&gt;&lt;h2&gt;&lt;span style="color:#4f81bd; font-family:Cambria"&gt;Overview&lt;/span&gt;
	&lt;/h2&gt;&lt;p&gt;HTTP Publishing is a surprisingly powerful feature. It provides you with complete control over which applications are delivered to each user. The criteria that you choose to make this decision are completely up to you. For example, you could base it on the ACLs associated with the package files. With this strategy, if the user has access to package files, then the applications in the package are published to the user. This simple policy provides similar entitlement functionality that is available with the App-V Management Server. It is the one that will be demonstrated in this article. 
&lt;/p&gt;&lt;p&gt;Much more interesting policies are also possible. For example, entitlement could be based on information in the corporate HR database. Or, it could be based on some other attributes on the user's Active Directory object. Another option would be to query some custom SQL database to determine which applications the user is entitled to use. Which option you choose will depend on the needs of your particular scenario. 
&lt;/p&gt;&lt;h2&gt;&lt;span style="color:#4f81bd; font-family:Cambria"&gt;Publishing Architecture&lt;/span&gt;
	&lt;/h2&gt;&lt;p&gt;The publishing architecture in App-V is fairly simple. The client sends a request to the server asking for the list of applications for the user. This request is sent while impersonating the user, so that the server can access the user's token, if needed. 
&lt;/p&gt;&lt;p&gt;The server's response is a single XML file that contains the publishing information associated with each application, including its shortcuts, file type associations and DDE entries. The rest of this article describes how to generate this document in the appropriate format. 
&lt;/p&gt;&lt;h2&gt;&lt;span style="color:#4f81bd; font-family:Cambria"&gt;Generating the Publishing Document&lt;/span&gt;
	&lt;/h2&gt;&lt;p&gt;Prior to App-V 4.5, creating a Publishing Server was a reasonably complicated task. It required you to generate a properly formatted XML document describing all of the applications, shortcuts, file type associations and DDE entries for each package that a user was entitled to use. App-V 4.5 introduced the concept of package manifest files, which contains all of this information in the correct format. This makes creating an HTTP publishing server a much easier task. 
&lt;/p&gt;&lt;p&gt;The following is an example publishing document that contains the information for a single application. While it contains a lot of information, most of it comes directly from the package's manifest file. So, you will not have to deal with it directly. It is included purely for illustrative purposes.  &lt;em&gt;Click on the image to see a larger version.&lt;/em&gt;
	&lt;/p&gt;&lt;p&gt;&lt;a href="http://blogs.msdn.com/photos/johnsheehan/images/9503411/original.aspx"&gt;&lt;img src="http://blogs.msdn.com/photos/johnsheehan/images/9503411/500x336.aspx" alt="" border="0"/&gt;&lt;/a&gt; 
&lt;/p&gt;&lt;p&gt;As can be seen in this sample, the document element is called &amp;lt;DESKTOPCONFIG&amp;gt;. It contains two child elements, &amp;lt;POLICY&amp;gt; and &amp;lt;APPLIST&amp;gt;. The &amp;lt;POLICY&amp;gt; element has a &amp;lt;REFRESH&amp;gt; element that allows you to specify the Publishing Refresh frequency, in minutes and a boolean that determines if Publishing Refresh occurs when the user first logs in. 
&lt;/p&gt;&lt;p&gt;The &amp;lt;APPLIST&amp;gt; section is nothing but a concatenation of the &amp;lt;APPLIST&amp;gt; sections from each of the package manifests to which the user has access. The sample code that follows describes how to generate this list. 
&lt;/p&gt;&lt;p&gt;The following is the ASPX page that will be used in this sample. It contains the basic structure of the Publishing document. 
&lt;/p&gt;&lt;div&gt;&lt;table style="border-collapse:collapse" border="0"&gt;&lt;colgroup&gt;&lt;col style="width:638px"/&gt;&lt;/colgroup&gt;&lt;tbody valign="top"&gt;&lt;tr&gt;&lt;td vAlign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt"&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;Copyright (c) Microsoft Corporation.  All rights reserved.  For personal use only.  Provided AS IS and WITH ALL FAULTS.  
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="background-color:yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue"&gt;@&lt;/span&gt;
										&lt;span style="color:#a31515"&gt;Page&lt;/span&gt;
										&lt;span style="color:red"&gt;Language&lt;/span&gt;&lt;span style="color:blue"&gt;="C#"&lt;/span&gt;
										&lt;span style="color:red"&gt;AutoEventWireup&lt;/span&gt;&lt;span style="color:blue"&gt;="true"&lt;/span&gt;
										&lt;span style="color:red"&gt;CodeBehind&lt;/span&gt;&lt;span style="color:blue"&gt;="publishing.aspx.cs"&lt;/span&gt;
										&lt;span style="color:red"&gt;Inherits&lt;/span&gt;&lt;span style="color:blue"&gt;="appv_publishing_service.publishing"&lt;/span&gt;
										&lt;span style="color:red"&gt;ContentType&lt;/span&gt;&lt;span style="color:blue"&gt;="text/xml"&lt;/span&gt;
										&lt;span style="background-color:yellow"&gt;%&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;DESKTOPCONFIG&lt;/span&gt;&lt;span style="color:blue"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;POLICY&lt;/span&gt;
										&lt;span style="color:red"&gt;MANAGEDDESKTOP&lt;/span&gt;&lt;span style="color:blue"&gt;="TRUE"&lt;/span&gt;
										&lt;span style="color:red"&gt;REPORTING&lt;/span&gt;&lt;span style="color:blue"&gt;="FALSE"&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;REFRESH&lt;/span&gt;
										&lt;span style="color:red"&gt;ONLOGIN&lt;/span&gt;&lt;span style="color:blue"&gt;="TRUE"&lt;/span&gt;
										&lt;span style="color:red"&gt;PERIOD&lt;/span&gt;&lt;span style="color:blue"&gt;="60"/&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;POLICY&lt;/span&gt;&lt;span style="color:blue"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;APPLIST&lt;/span&gt;&lt;span style="color:blue"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="background-color:yellow"&gt;&amp;lt;%&lt;/span&gt;
										&lt;span style="color:blue"&gt;this&lt;/span&gt;.generate_app_xml(); &lt;span style="background-color:yellow"&gt;%&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;APPLIST&lt;/span&gt;&lt;span style="color:blue"&gt;&amp;gt; &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;DESKTOPCONFIG&lt;/span&gt;&lt;span style="color:blue"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;br/&gt;The &amp;lt;POLICY&amp;gt; section has already been described above. The &amp;lt;APPLIST&amp;gt; element is where all of the application-specific publishing information is placed. This information is taken directly from the manifest files that were generated by the Sequencer. In this sample ASPX page, the work of extracting the publishing information from the manifest files is delegated to a C# method in the CodeBehind file, named &lt;span style="font-family:Courier New"&gt;generate_app_xml()&lt;/span&gt;. The contents of the CodeBehind file are listed below. 
&lt;/p&gt;&lt;div&gt;&lt;table style="border-collapse:collapse" border="0"&gt;&lt;colgroup&gt;&lt;col style="width:638px"/&gt;&lt;/colgroup&gt;&lt;tbody valign="top"&gt;&lt;tr&gt;&lt;td vAlign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid black 0.5pt; border-left:  solid black 0.5pt; border-bottom:  solid black 0.5pt; border-right:  solid black 0.5pt"&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;Copyright © Microsoft Corporation.  All rights reserved.  For personal use only.  Provided AS IS and WITH ALL FAULTS.  
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color:green; font-family:Courier New"&gt;// CodeBehind File: publishing.aspx.cs &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System; &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System.Xml; &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System.IO; &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;namespace&lt;/span&gt; appv_publishing_service &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;{ &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;public&lt;/span&gt;
										&lt;span style="color:blue"&gt;partial&lt;/span&gt;
										&lt;span style="color:blue"&gt;class&lt;/span&gt;
										&lt;span style="color:#2b91af"&gt;publishing&lt;/span&gt; : System.Web.UI.&lt;span style="color:#2b91af"&gt;Page &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;{ &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;protected&lt;/span&gt;
										&lt;span style="color:blue"&gt;void&lt;/span&gt; generate_app_xml() &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;{ &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;string&lt;/span&gt; root_phys = MapPath(&lt;span style="color:#a31515"&gt;"."&lt;/span&gt;); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;string&lt;/span&gt;[] dirs = &lt;span style="color:#2b91af"&gt;Directory&lt;/span&gt;.GetDirectories(root_phys); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue"&gt;string&lt;/span&gt; dir &lt;span style="color:blue"&gt;in&lt;/span&gt; dirs) &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;{ &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color:blue; font-family:Courier New"&gt;try &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;{ &lt;span style="color:green"&gt;// Best effort. &lt;/span&gt;&lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;string&lt;/span&gt;[] manifests = &lt;span style="color:#2b91af"&gt;Directory&lt;/span&gt;.GetFiles(&lt;span style="color:#2b91af"&gt;Path&lt;/span&gt;.Combine(root_phys,dir), &lt;span style="color:#a31515"&gt;@"*_manifest.xml"&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;SearchOption&lt;/span&gt;.TopDirectoryOnly); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue"&gt;string&lt;/span&gt; filename &lt;span style="color:blue"&gt;in&lt;/span&gt; manifests) &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;{ &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:#2b91af"&gt;FileStream&lt;/span&gt; file = &lt;span style="color:#2b91af"&gt;File&lt;/span&gt;.OpenRead(filename); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:#2b91af"&gt;XmlDocument&lt;/span&gt; doc = &lt;span style="color:blue"&gt;new&lt;/span&gt;
										&lt;span style="color:#2b91af"&gt;XmlDocument&lt;/span&gt;(); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;doc.Load(file); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:#2b91af"&gt;XmlNode&lt;/span&gt; applist = doc.SelectSingleNode(&lt;span style="color:#a31515"&gt;@"/PACKAGE/APPLIST"&lt;/span&gt;); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;Response.Write(applist.InnerXml); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;} &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;} &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;&lt;span style="color:blue"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;Exception&lt;/span&gt; ex) &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;{ &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color:green; font-family:Courier New"&gt;// Output to log file &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;Response.AppendToLog(ex.Message); &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;} &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;} &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;} &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;} &lt;/span&gt;
								&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="font-family:Courier New"&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;The algorithm used by the &lt;span style="font-family:Courier New"&gt;generate_app_xml() &lt;/span&gt;method is pretty straightforward. It assumes that the packages are each stored in separate subdirectories under the current directory. Many other schemes are possible. This particular one was chosen for its simplicity. 
&lt;/p&gt;&lt;p&gt;The method begins by calling the &lt;span style="font-family:Courier New; font-size:10pt"&gt;MapPath()&lt;/span&gt; function to get the native file system path of the current directory. It then uses the &lt;span style="font-family:Courier New; font-size:10pt"&gt;GetDirectories()&lt;/span&gt; static method of the &lt;span style="color:#2b91af; font-family:Courier New; font-size:10pt"&gt;Directory&lt;/span&gt; object to get a list of all of the subdirectories under the current directory. Next, it enumerates the list of subdirectories so it can find the manifest file for each package. 
&lt;/p&gt;&lt;p&gt;My original implementation of this method attempted to just use the &lt;span style="font-family:Courier New; font-size:10pt"&gt;GetFiles()&lt;/span&gt; static method of the &lt;span style="color:#2b91af; font-family:Courier New; font-size:10pt"&gt;Directory&lt;/span&gt; object to get a list of all of the manifest files under the current directory. However, it turns out that &lt;span style="font-family:Courier New; font-size:10pt"&gt;GetFiles()&lt;/span&gt; has one particularly annoying characteristic (I'd call it a bug). If &lt;span style="font-family:Courier New; font-size:10pt"&gt;GetFiles()&lt;/span&gt; encounters a directory that it doesn't have access to during the search, it abandons the operation and throws an ACCESS_DENIED error. This severely limits the usefulness of this method. 
&lt;/p&gt;&lt;p&gt;To get around this limitation, the &lt;span style="font-family:Courier New; font-size:10pt"&gt;GetFiles()&lt;/span&gt; call is done in within a try…catch block. It is used to get a list of all of the manifest files under each subdirectory. Normally, we'd only expect there to be a single manifest file in each subdirectory. But, if there were more than one, this method would handle each one. If the user doesn't have access to the subdirectory, the exception thrown by &lt;span style="font-family:Courier New; font-size:10pt"&gt;GetFiles()&lt;/span&gt; is caught by the method, logged (for debugging purposes) and the enumeration continues. 
&lt;/p&gt;&lt;p&gt;The real work of this method is done with the inner &lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;foreach&lt;/span&gt;
		&lt;/span&gt;that processes the manifest files. Each manifest file is opened and loaded into an &lt;span style="color:#2b91af; font-family:Courier New; font-size:10pt"&gt;XmlDocument&lt;/span&gt; object. Next, the &lt;span style="color:#a31515; font-family:Courier New; font-size:10pt"&gt;"/PACKAGE/APPLIST" &lt;/span&gt;element is selected and its contents are written out to the response. 
&lt;/p&gt;&lt;p&gt;The end result of this processing is an XML document that contains all of the information for each package that the user has permission to use. Pretty simple, eh? To test your implementation, you can simply point your web browser at the publishing.aspx page and check out the results. Remember to enable Windows Integrated Authentication on the website and ACL the package directories appropriately. 
&lt;/p&gt;&lt;h2&gt;&lt;span style="color:#4f81bd; font-family:Cambria"&gt;Configuring the Client&lt;/span&gt;
	&lt;/h2&gt;&lt;p&gt;Once the publishing.aspx page is working correctly, all you need to do to use it is to configure the client to point at the page. Here is an example of how to correctly configure the client: 
&lt;/p&gt;&lt;p&gt;&lt;img src="http://blogs.msdn.com/photos/johnsheehan/images/9503415/original.aspx" alt=""/&gt;  
&lt;/p&gt;&lt;p&gt;In this example, the client will connect to the 'webserver.yourcompany.com' webserver over port 80 and retrieve the contents of the 'publishing.aspx' page. It will then process the XML document that is returned by the server. 
&lt;/p&gt;&lt;p&gt;Note that this example uses the standard HTTP protocol, which will not verify the identity of the webserver and will return the data unencrypted. This is only appropriate for scenarios that are inside the corporate firewall. If this were a public Internet scenario, you would use the HTTPS protocol to guard against man-in-the-middle attacks. 
&lt;/p&gt;&lt;h2&gt;&lt;span style="color:#4f81bd; font-family:Cambria"&gt;What's Next&lt;/span&gt;
	&lt;/h2&gt;&lt;p&gt;This simple implementation makes an assumption about the information that is in the manifest file. It assumes that the URLs for OSDs and icons in the manifest file point to the appropriate locations. In the next installment of this series, we'll see how to remove this assumption and have the code fix-up the locations before it returns them to the client. 
&lt;/p&gt;&lt;p&gt;In future installments, we'll also look at techniques that can be used to fix up the OSDs before they are returned to the client. This can be used to enable all kinds of advanced functionality. It can be used for simple things, like fixing up the SFT URLs in the OSD files so they point to the correct HTTP URL. And, it can be used for more advanced functionality, like automatically adding the proper Dynamic Suite Composition tags to the individual OSD files for a package. This can be used to eliminate the task of manually updating all of the OSD files with DSC tags. 
&lt;/p&gt;&lt;p&gt;Another important topic that isn't addressed in this first sample is performance. The sample code is inefficient, since it loads each of the manifest files into an &lt;span style="color:#2b91af; font-family:Courier New; font-size:10pt"&gt;XmlDocument&lt;/span&gt; object for every request it receives. There are many possible caching optimizations that could be added that would improve the performance of this code. We may cover some of them in future releases. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9503403" width="1" height="1"&gt;</description></item><item><title>Application Virtualization video on channel 9 - Part 2</title><link>http://blogs.msdn.com/b/johnsheehan/archive/2009/02/16/application-virtualization-video-on-channel-9-part-2.aspx</link><pubDate>Mon, 16 Feb 2009 04:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9425139</guid><dc:creator>jsheehan</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johnsheehan/rsscomments.aspx?WeblogPostID=9425139</wfw:commentRss><comments>http://blogs.msdn.com/b/johnsheehan/archive/2009/02/16/application-virtualization-video-on-channel-9-part-2.aspx#comments</comments><description>&lt;P&gt;A couple of&amp;nbsp;weeks ago I did a follow-up&amp;nbsp;interview with Charles Torre for Channel 9's Going Deep show.&amp;nbsp; This time we got to go a little deeper in the architecture.&amp;nbsp; Enjoy.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://channel9.msdn.com/shows/Going+Deep/John-Sheehan-Application-Virtualization-Redux-Inside-AppVirt-45/"&gt;http://channel9.msdn.com/shows/Going+Deep/John-Sheehan-Application-Virtualization-Redux-Inside-AppVirt-45/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;-John&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9425139" width="1" height="1"&gt;</description></item><item><title>Application Virtualization video on channel 9</title><link>http://blogs.msdn.com/b/johnsheehan/archive/2008/07/08/application-virtualization-video-on-channel-9.aspx</link><pubDate>Tue, 08 Jul 2008 07:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8706420</guid><dc:creator>jsheehan</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johnsheehan/rsscomments.aspx?WeblogPostID=8706420</wfw:commentRss><comments>http://blogs.msdn.com/b/johnsheehan/archive/2008/07/08/application-virtualization-video-on-channel-9.aspx#comments</comments><description>&lt;P&gt;A couple of months ago I did an interview with Charles Torre for Channel 9's Going Deep show.&amp;nbsp; Well, it finally got posted.&amp;nbsp; Let me know what you think.&amp;nbsp; Feel free to just post comments on the Channel 9 site and I'll monitor it and answer them.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://channel9.msdn.com/shows/Going+Deep/John-Sheehan-Inside-Application-Virtualization/"&gt;http://channel9.msdn.com/shows/Going+Deep/John-Sheehan-Inside-Application-Virtualization/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;John&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8706420" width="1" height="1"&gt;</description></item><item><title>Compile-time Binary Search</title><link>http://blogs.msdn.com/b/johnsheehan/archive/2008/07/06/compile-time-binary-search.aspx</link><pubDate>Sun, 06 Jul 2008 17:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8696961</guid><dc:creator>jsheehan</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johnsheehan/rsscomments.aspx?WeblogPostID=8696961</wfw:commentRss><comments>http://blogs.msdn.com/b/johnsheehan/archive/2008/07/06/compile-time-binary-search.aspx#comments</comments><description>&lt;SPAN style="FONT-SIZE: 1pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 'Times New Roman'; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" /&gt;&lt;w:sdtPr&gt;&lt;/w:sdtPr&gt;&lt;w:Sdt id=89512082 title="Post Title" StoreItemID="X_53B6CF23-D1B4-4BBC-8E2B-CF8D785B9386" Text="t" DocPart="C078EB9795BF440B82DE7B3AC66E11DD" Xpath="/ns0:BlogPostInfo/ns0:PostTitle"&gt;&lt;/SPAN&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt; 
&lt;P class=Publishwithline style="MARGIN: 0in 0in 0pt"&gt;&lt;/w:Sdt&gt;&lt;FONT face=Calibri size=3&gt;A while back I was writing a generic &lt;/FONT&gt;&lt;A href="http://en.wikipedia.org/wiki/B-tree" mce_href="http://en.wikipedia.org/wiki/B-tree"&gt;&lt;FONT face=Calibri size=3&gt;b-tree&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt; implementation that used a memory-mapped file for persisting / retrieving data.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I wanted it to be used in the same way that std::map is, like this:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Publishwithline style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;btree&amp;lt;key_t, value_t&amp;gt; b_tree;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;There are a bunch of other implementation details around specifying the file path for the backing store, etc.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, those aren’t particularly important.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The challenge I faced was figuring out how many elements I could store in a single node in the b-tree (if you need a refresher on b-trees, read the Wikipedia &lt;/FONT&gt;&lt;A href="http://en.wikipedia.org/wiki/B-tree" mce_href="http://en.wikipedia.org/wiki/B-tree"&gt;&lt;FONT face=Calibri size=3&gt;article&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;).&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Initially, the problem seems pretty simple.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Basically, there is some bookkeeping data, e.g. parent &amp;amp; child references (not actually pointers, since this is an on-disk structure), that are used for maintaining the b-tree’s structure and then there is an array of elements that use up the rest of the space in the node.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It looks something like this:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;template&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &amp;lt;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; key_t, &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; record_t, rec_count_t records_per_node&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;class&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; node &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// bookkeeping data&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;mmap_file&amp;lt;&amp;gt;* file_;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;node_index_t this_node_;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;node_index_t parent_node_;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;node_index_t larger_node_;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;rec_count_t record_count_;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// element array&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;entry_t entries_[records_per_node_];&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;So, all you have to do is figure out how much room that bookkeeping data takes up, subtract it from the total size of a node and use the remaining space for the element array.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Simple, right?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Well, it turns out to be slightly more complicated than that. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;When you declare classes in C++, the compiler is given leeway on how it lays out the individual members of the class.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It is allowed to rearrange them, add padding to properly align the items in memory, etc.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, just knowing the sizes of the individual members does not tell you how much space they will actually take up.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;I came up with many different ways to attempt to calculate how much free space was in the node.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, every technique I used was in some way making assumptions about how the compiler would lay out the class.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;I even considered using ‘#pragma pack’ to force the compiler to force the compiler not to put in any padding.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, this was a bad idea, since this is a generic data structure and I don’t know what type of data will be stored in it.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Having a huge array of misaligned elements could be catastrophic from a performance standpoint.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;At this point, I figured there had to be a simpler way.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In reality, what I was trying to calculate was pretty simple.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I just needed my class to fit into a node and stored as many elements as possible.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;All the information needed for making this decision is available at compile time.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;That’s when it dawned on me that this was a perfect situation for &lt;/FONT&gt;&lt;A href="http://en.wikipedia.org/wiki/Template_metaprogramming" mce_href="http://en.wikipedia.org/wiki/Template_metaprogramming"&gt;&lt;FONT face=Calibri size=3&gt;template metaprogramming&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If you haven’t used this programming paradigm before, I highly recommend reading Andre Alexandrescu ‘s excellent&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;book, &lt;/FONT&gt;&lt;A href="http://www.amazon.com/Modern-Design-Programming-Patterns-Depth/dp/0201704315/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1215352198&amp;amp;sr=8-1" mce_href="http://www.amazon.com/Modern-Design-Programming-Patterns-Depth/dp/0201704315/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1215352198&amp;amp;sr=8-1"&gt;&lt;FONT face=Calibri size=3&gt;Modern C++ Design&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Once you’ve read that, you should get familiar with &lt;/FONT&gt;&lt;A href="http://www.boost.org/" mce_href="http://www.boost.org/"&gt;&lt;FONT face=Calibri size=3&gt;Boost&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;’s &lt;/FONT&gt;&lt;A href="http://www.boost.org/doc/libs/1_35_0/libs/mpl/doc/index.html" mce_href="http://www.boost.org/doc/libs/1_35_0/libs/mpl/doc/index.html"&gt;&lt;FONT face=Calibri size=3&gt;MPL&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It is one of the most interesting libraries I have ever looked at.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It takes the STL concepts of containers, iterators, functors, etc. and applies them to metaprogramming.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Very interesting, indeed!&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="FONT-FAMILY: Wingdings; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin; mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;&lt;SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;OK, so I know that I want to be able to calculate at compile time how many elements can fit in a node.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, how do I accomplish that?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Actually, it is conceptually pretty simple. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;The &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;sizeof&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;()&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt; operator can be used at compile time to calculate the size of a particular type.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, all I need to do is find the largest number of elements where &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;sizeof&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;(node&amp;lt;key_t, record_t, records_per_node&amp;gt;) &lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;is greater than or equal to the maximum node size.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The pseudo-code looks something like this:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;// keep incrementing until it is just a bit too big&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;num_recs = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;while&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;(&lt;SPAN style="COLOR: blue"&gt;sizeof&lt;/SPAN&gt;(node&amp;lt;key_t,record_t,++num_recs&amp;gt;)&amp;lt;=max_size);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;// the previous one was the right size&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;--num_recs;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Now, in template metaprogramming, there are no loops.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, just like in functional languages, we have to use recursion, instead.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;I implemented the above algorithm using compile-time recursion.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;When I did, I found two things:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; LINE-HEIGHT: 115%; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;1.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;It was slow.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It turns out that the minimum page size for memory-mapped files is 64KB.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;That means that, for small record sizes, thousands of records fit in a single node.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For these cases, I noticed a considerable delay during compilation while this calculation was occurring.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 10pt 0.5in; TEXT-INDENT: -0.25in; LINE-HEIGHT: 115%; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;2.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;It caused the complier to crash with a stack overflow!&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;As you learn when you start doing template metaprogramming, you need to be careful about how much recursion you do, since the compiler’s stack is limited.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;There are lots of techniques for reducing the amount of recursion used during compilation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In my case, I decided to change my algorithm.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Instead of doing a linear scan of sizes, I decided to implement a binary search.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I will not go into the specifics of implementing a &lt;/FONT&gt;&lt;A href="http://en.wikipedia.org/wiki/Binary_search" mce_href="http://en.wikipedia.org/wiki/Binary_search"&gt;&lt;FONT face=Calibri size=3&gt;binary search&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;, since most people should be familiar with it.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;The resulting code was somewhat difficult to read.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, when writing a generic class that you expect to be used over-and-over again, you often sacrifice beauty for efficiency.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Overall, I think the code makes a lot of sense.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The only real confusing part of it is the use of &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;eval_if_c&amp;lt;&amp;gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt; to prevent the compiler from going into an infinite recursion.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Hopefully, with a little bit of inspection, the technique I used becomes apparent.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If anyone has any questions about how it works, please post questions and I will answer them.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;To use this class (see below), I just do the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;const&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; num_recs = node_max_sizer&amp;lt;&lt;BR&gt;key_t,record_t,max_size &amp;gt;::records_per_node_;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; PADDING-BOTTOM: 1pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; mso-border-bottom-alt: solid windowtext .75pt; mso-element: para-border-div"&gt;
&lt;P class=MsoNormal style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: medium none; PADDING-LEFT: 0in; PADDING-BOTTOM: 0in; MARGIN: 0in 0in 10pt; BORDER-LEFT: medium none; PADDING-TOP: 0in; BORDER-BOTTOM: medium none; mso-border-bottom-alt: solid windowtext .75pt; mso-padding-alt: 0in 0in 1.0pt 0in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;num_recs&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt; now contains the maximum number of elements that can fit in a node.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Here is the entire class:&lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;#include&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: #a31515"&gt;&amp;lt;boost/mpl/identity.hpp&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;#include&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: #a31515"&gt;&amp;lt;boost/mpl/comparison.hpp&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt; boost::mpl;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;// performs a binary search at compile time to find the largest number of records that fit&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;template&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; key_t, &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;class&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; record_t, &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;int&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; max_size, &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;int&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; records_per_node = max_size/2, &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;int&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; step = max_size/2, &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;bool&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; found = &lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;struct&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; node_max_sizer&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;typedef&lt;/SPAN&gt; impl_::node&amp;lt;key_t,record_t,records_per_node&amp;gt; this_t;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// cut the step size in half each time (can't be smaller than 1)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; step_ = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;if_c&amp;lt;step&amp;lt;=1, int_&amp;lt;1&amp;gt;, int_&amp;lt;step/2&amp;gt; &amp;gt;::type::value;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// calc the size of this and the next block&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; size_ = &lt;SPAN style="COLOR: blue"&gt;sizeof&lt;/SPAN&gt;(this_t);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; next_size_ =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;sizeof&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;(impl_::node&amp;lt;key_t,record_t,records_per_node+1&amp;gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// if we are at the largest size that fits, we have found what we're looking for&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; found_ = (size_&amp;lt;=max_size) &amp;amp;&amp;amp; (next_size_&amp;gt;max_size);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;typedef&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;typename&lt;/SPAN&gt; eval_if_c&amp;lt;found_, &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;this_t, &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;eval_if_c&amp;lt;(size_&amp;lt;max_size), &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;typename&lt;/SPAN&gt; identity&amp;lt;node_max_sizer&amp;lt;key_t,record_t,max_size,records_per_node+step_, step_, found_&amp;gt; &amp;gt;::type ,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;typename&lt;/SPAN&gt; identity&amp;lt;node_max_sizer&amp;lt;key_t,record_t,max_size,records_per_node-step_, step_, found_&amp;gt; &amp;gt;::type &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;gt; type;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; records_per_node_ = type::records_per_node_;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8696961" width="1" height="1"&gt;</description></item><item><title>When idle threads bugcheck</title><link>http://blogs.msdn.com/b/johnsheehan/archive/2007/12/19/when-idle-threads-bugcheck.aspx</link><pubDate>Wed, 19 Dec 2007 21:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6810526</guid><dc:creator>jsheehan</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johnsheehan/rsscomments.aspx?WeblogPostID=6810526</wfw:commentRss><comments>http://blogs.msdn.com/b/johnsheehan/archive/2007/12/19/when-idle-threads-bugcheck.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Or, when APCs attack&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;I style="mso-bidi-font-style: normal"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;REQUIRED DISCLAIMER:&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I’m the architect for the Microsoft Application Virtualization product (formerly known as SoftGrid).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, all information, opinions, anecdotes, facts, pseudo-facts, exaggerations and flat-out lies represent my personal view of the world and not those necessarily held by my team or Microsoft.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You’ve been warned.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;The Situation&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Several weeks ago, we were trying to ship the Microsoft Application Virtualization Beta when we encountered a very strange bugcheck in our File System.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It was one we had never seen before and the initial investigation didn’t look very promising.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Now, as anyone in software knows all too well, software products love to wait for these special moments to decide to blow up in new and interesting ways.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I personally believe that, just like disobedient children, they hate their parents and want to make them miserable.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Unfortunately, you can’t put your product in time-out.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;And, just as with children, beatings don’t really seem to accomplish much. &lt;/FONT&gt;&lt;SPAN style="FONT-FAMILY: Wingdings; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin; mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;&lt;SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Initial Analysis&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;When investigating an issue like this, you first start by trying to figure out what action caused the system to bugcheck.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You can then use this information to help reconstruct the situation that lead to the crash.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Normally, the first place you start is with the ‘!analyze –v’ command.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It does a basic analysis of the dump file and gives you its best guess at what caused the crash.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In this particular case, !analyze pointed its finger at our File System driver.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, not much else made sense.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Here is the stack that was output:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;ChildEBP RetAddr&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;a9750c80 806ffa16 nt!KiTrap0E+0x238&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;a9750d5c a9338ae2 hal!KeAcquireInStackQueuedSpinLock+0x26&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;a9750d6c a9339c79 sftfsXP!SoftFSProcessRequest+0x6c &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;a9750dac 80574128 sftfsXP!SoftFSQueueSyncWorker+0x39 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;a9750ddc 804ec781 nt!PspSystemThreadStartup+0x34&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;00000000 00000000 nt!KiThreadStartup+0x16&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;In this particular situation, the stack doesn’t seem to make a whole lot of sense.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It looks as if our File System is calling nt!KeAcquireInStackQueuedSpinLock.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Now, sometimes functions in the DDK are really macros for some internal function that you’ve never heard of.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, when we looked through the code in this function, this did not seem to be the case.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This was a very simple dispatch function that did very little.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, even though this was a release build and, therefore, was optimized, it still didn’t seem likely that the code could be calling nt!KeAcquireInStackQueuedSpinLock.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Could we be facing stack corruption?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Only time would tell.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;I style="mso-bidi-font-style: normal"&gt;NOTE:&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;At this point, lots of analysis of the dump file occurred.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Since none of it pointed to the culprit, I will omit the details to prevent this article from turning into a novel (which it is already in danger of becoming).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/I&gt;&lt;I style="mso-bidi-font-style: normal"&gt;&lt;SPAN style="mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri"&gt;I will also omit lots of other details that were uncovered during this long debugging session.&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/I&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;At this point, we figured we would try to catch the corruption in the act, so that we would have a live system to debug.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Here is what we learned:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;1.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;It only happened on a single test system, which happened to be running Windows XP&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;2.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;It did not happen with a checked build of the product&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;3.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;It did not happen if you had kernel mode debugging enabled&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;4.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;It did not happen on an identical hardware setup that was built using the same OS image&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;5.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;It only happened during the first launch of a package&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 10pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo1"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;6.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;If you rebooted after install, it did not occur&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;So, we’ve hit software’s equivalent of the &lt;/FONT&gt;&lt;A href="http://en.wikipedia.org/wiki/Observer_effect"&gt;&lt;FONT face=Calibri size=3&gt;Observer effect&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Calibri size=3&gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Basically, the Observer effect states that the act of observing the phenomenon changes the phenomenon being observed.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This usually points to some kind of timing issue that only occurs when the system is running at full speed.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Given all of the other caveats around the issue, this certainly appears to be a timing issue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The fact that it happens on one system and not another (practically identical) system points to some kind of environmental issue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Unfortunately, it is impossible to tell at this point whether it is a hardware or software difference.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In my experience, it is almost always a software difference when you are dealing with identically configured system (software just varies so much more readily than hardware).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, it looks like we’ll have to continue our investigation using the crash dump that we started with.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;At this point, reports started coming in from some of our TAP customers who had started playing with a Beta build.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;They were seeing the same issue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In every case, it happened on XP.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Vista did not seem to be vulnerable to this particular race.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Debugging the Issue&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Even though the stack didn’t make complete sense, it did give up some clues as to the scenario that was causing the bugcheck.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The thread in question was a kernel thread that was part of a pool of worker threads that our File System uses to perform any deferred work that it needs to accomplish.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This actually complicates things, since this one thread could have been performing one of over a dozen of different operations.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, all was not lost.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We knew that this bugcheck occurred during the very first launch of a virtual application.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We also knew that this worker pool was primarily used during initialization / shutdown of virtual application volumes.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Since these requests all come from our NT service (named sftlist.exe), this is a good place to look for the initial request that this thread was processing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;After all, it isn’t likely that this thread decided to do work all on its own.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;A quick scan of the threads in our NT service found the following interesting stack (using the command ‘!process 0 F sftlist.exe’):&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ChildEBP RetAddr&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;a9fe5904 804e1bd2 nt!KiSwapContext+0x2f&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;a9fe5910 804e1c1e nt!KiSwapThread+0x8a&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;a9fe5938 a9339042 nt!KeWaitForSingleObject+0x1c2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;a9fe5964 a933985e sftfsXP!SoftFSInsertQueueItem+0x12a &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;a9fe5984 a93149bb sftfsXP!SoftFSVolMngrGlobalPackageInitRequest+0x88&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;a9fe59e8 a9340b0b sftfsXP!SoftFSConnectSession+0x33d&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Here, a thread has just posted a job to our thread pool using sftfsXP!SoftFSInsertQueueItem and is awaiting the response.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Now, this does not absolutely prove that the thread in question was performing this task.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, it does strongly point in that direction.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Ideally, we would be able to correlate the request objects in both threads.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, in this case, the other thread’s stack was not intact enough to perform this analysis.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Unfortunately, this thread pool also does some periodic work that could be the culprit.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;(We actually went down that path, at one point.)&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, given the strong correlation between the two events, we proceeded with the assumption that these were related.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This is one of the techniques you need to use when doing post-mortem debugging.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Sometimes you just have to create a hypothesis and then follow it to its logical conclusion.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The key to being a good debugger is to come up with solid hypotheses that can be proven / disproven quickly.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If you can figure out you’re wrong quickly, you can move on to another hypothesis.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Rinse…repeat.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;If we look at all of the work that this type of request does, it is a little disheartening.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This is the most complicated request that this worker thread can perform.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The code path represents several thousand lines (if you follow all of the different potential branches).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, code review does not seem to be the quickest route to finding the issue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Still, it is good to at least familiarize yourself with the code to help inform the various hypotheses you will come up with during the debugging process.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This particular code did the following operations (this is an incomplete list):&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;1.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Creates the global package volume files, if they do not already exist (there are two)&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;2.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Ensures there is space in the cache for the package, pre-allocating if necessary&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;3.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Registers the global package volume in the file system cache structures&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;4.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Create the temporary working versions of the volumes, copying the existing ones, if necessary&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 10pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;5.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Initialize the volumes with package data, if they have not yet been initialized&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Wow.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, there is a lot going on in this one request.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Each of these operations represents many sub-operations, any one of which could be the culprit of the bugcheck.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Logging to the Rescue&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Since we have a system where we can reproduce the issue, we decided to add some logging to see what requests the worker pool was handling during the reproduction run.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Choosing what information to log is the key to success.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You need to log enough information to further guide your debugging.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, if you log too much, you can change the timing of the system sufficiently to prevent the reproduction from being success (another form of the Observer effect).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For this scenario, we decided to log each job that was submitted to the worker pool, including:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpFirst style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l2 level1 lfo3"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;1.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;The type of request being handled&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l2 level1 lfo3"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;2.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Its basic parameters&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpMiddle style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l2 level1 lfo3"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;3.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;Which thread it was running on&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoListParagraphCxSpLast style="MARGIN: 0in 0in 10pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l2 level1 lfo3"&gt;&lt;SPAN style="mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"&gt;&lt;SPAN style="mso-list: Ignore"&gt;&lt;FONT face=Calibri size=3&gt;4.&lt;/FONT&gt;&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;The return code of the operation (after it was done being handled)&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;We also logged some basic information about each thread state change, such as when it went to sleep to wait for new requests, when it was woken up to do some work, etc.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;One very appealing aspect of this approach is that it should tell us which type of request was in process when the bugcheck occurred.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;With the logging in place, we reproduced the issue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;To our utter amazement, there were no requests in process when the bugcheck occurred!&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;At first, we didn’t believe it.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Since we use WMI logging in our driver, we assumed that the log messages for the running thread were just in the memory buffer and hadn’t been written to disk yet.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;To check this, we used the ‘!wmitrace.logdump’ command to dump the contents of the in-memory buffer.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;To our surprise, there were no other logging events in our buffer.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;All of the requests appear to have been complete.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If fact, the thread that bugchecked logged a message a full minute before the crash stating that it was going to wait on the job queue for the next job.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The next line of code after the log message was:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'"&gt;KeWaitForSingleObject(queueEvent, Executive, KernelMode, FALSE, 0);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;The line after this line was another log message stating that the thread had woken up.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, to our disbelief, the thread in question had gone to sleep on an event and, a minute after sleeping, had bugchecked without ever waking up.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;To double-check, we verified that no jobs had been put in the queue since this last job succeeded.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Sure enough, this was the last job put in the queue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, this thread really did bugcheck a minute after going to sleep without ever being woken up.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;What was going on here?!!!&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Making Sense of the Results&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;The only way that a sleeping thread can execute code without being woken up is if an Asynchronous Procedure Call (APC) is posted to it.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, if you look at the parameters that were passed to the KeWaitForSingleObject call, you will see that the Alertable parameter was set to FALSE.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, we shouldn’t be woken up, right?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We’ll soon see.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;If we go back to the original stack that we saw at the beginning of the investigation, we can try to gather some more information.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Debuggers (e.g. kd, windbg) do their best to reconstruct the thread’s stack based on what information is available.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Since they are working with imperfect information, they don’t always get it right.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If you are concerned that the stack being displayed is not correct, you can attempt to walk it yourself to gather more information.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;A great command for this is the ‘kd’ command.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;‘Kd’ outputs the raw stack with each DWORD on a separate line.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For each line, it attempts to locate any symbol information for the location, effectively doing an ‘ln’ on each DWORD.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This is a great way to get detailed information about the stack.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Here is the output of ‘kd’ for the dump in question.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I have removed all of the lines that did not resolve to a particular symbol to make it easier to read.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750c84&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;806ffa16 hal!KeAcquireInStackQueuedSpinLock+0x26&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750c90&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;804f2bb5 nt!IopCompleteRequest+0x32f&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750cac&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;a9330d77 sftfsXP!SoftFSReleaseSoftVolume+0x33 &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750cd0&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;804e0030 nt!VdmFixEspEbp+0x60&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750ce8&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;806ffa16 hal!KeAcquireInStackQueuedSpinLock+0x26&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750cf4&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;804f2dc4 nt!KiDeliverApc+0xc2&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750cfc&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;806ff410 hal!KfLowerIrql&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750d18&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;804f2a72 nt!IopCompleteRequest&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750d30&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;804f2df4 nt!KiSwapThread+0xa8&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750d48&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;804e1c1e nt!KeWaitForSingleObject+0x1c2&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750d60&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;a9338ae2 sftfsXP!SoftFSProcessRequest+0x6c &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750d70&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;a9339c79 sftfsXP!SoftFSQueueSyncWorker+0x39 &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750da0&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;a9346b72 sftfsXP!except_handler3&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750da4&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;a9373e70 sftfsXP!__safe_se_handler_table+0x910&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT face=Calibri size=3&gt;a9750db0&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;80574128 nt!PspSystemThreadStartup+0x34&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;As we can see from this listing, it looks like an APC is being delivered to our thread, which is currently sleeping in nt!KeWaitForSingleObject.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This lines-up with the rest of the data we have gathered so far.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, the next question is:&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;where is this APC coming from?&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Finding the APC&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;From the stack, it appears that a Completion Request is being delivered to this thread.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;That’s strange.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;All IRPs that we send to other drivers during processing, such as to read / write a volume file, are done by the same routine, which waits for IRPs to be completed before continuing processing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, it doesn’t seem like we should be getting any APCs on this thread.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Another interesting data point is that this started happening fairly recently (on the order of months).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We would like to be able to do a binary search of mainline builds to determine which build introduced the issue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Unfortunately, there were other issues blocking this test during the period of time that this issue was introduced.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, we cannot determine which build introduced the issue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, we knew the changes made to our File System during this time.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This vastly reduced the amount of code that would need to be reviewed. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;Therefore, we went back and looked at the changes. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;Most of them seemed pretty straightforward.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, there was one change that looked a little different from the rest.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Tracking Down the Culprit&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;As I mentioned previously, our File System creates an IRP when it wants to read / write from a volume file on disk.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This common code has been around for years and seems to work fine.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It ensures that the request is complete before it returns to the caller.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;While doing our targeted code review, we found one place where this common function was not being used.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In this one case, ZwWriteFile was being used to write to the file.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This function was writing a single NUL byte past the current end of the file in order to extend its length.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Now, upon first examination, nothing seemed strange.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Here is the basic signature of the call that was made:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;IO_STATUS_BLOCK iosb;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;status = ZwWriteFile(file, NULL, NULL, NULL, &amp;amp;iosb, buffer, length, offset,0);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;if (NT_ERROR(status)) …// handle error&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNoSpacing style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;This particular call is setting all of the APC parameters to NULL, since it does not want to handle this call asynchronously.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The code expects that the call will complete before returning.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;(This assumption is the heart of the problem.)&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Unfortunately, the code used the NT_ERROR macro to determine if the ZwWriteFile call succeeded.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Although not completely clear in the documentation, it turns out that ZwWriteFile can return STATUS_PENDING if the call has not yet completed.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Since STATUS_PENDING is a success code, the caller missed the fact that the call hadn’t completed yet.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Another issue with this code is the return code of ZwWriteFile is not the return code of the file operation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;To determine if a file operation succeeded, you need to check the Status member of the IO_STATUS_BLOCK structure.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Even if the code had detected that the request was still pending, there is no way for it to determine when it is done, since it did not pass in an Event that the underlying driver could signal when it was done.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;I found it a little strange that the FS was willing to pend the request, even though there was no way for it to communicate the completion of the request back to the caller (since all parameters that could be used for this purpose were NULL).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, I guess users of the NTAPI are supposed to know what they’re doing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In particular, the file handle being used to make this write call was not opened for synchronous operations (i.e. none of the FILE_SYNCHRONOUS_IO_* flags were set in the ZwCreateFile call).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Therefore, the user of this handle had specifically stated that they were willing to handle asynchronous operations.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;There is one other piece of the puzzle that we need to understand.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;What was the completion routine doing that was causing the bugcheck?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The answer is right in the code that calls ZwWriteFile.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Can you spot it?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Final Cause Analysis&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;In the final analysis, it turns out that we were running into a form of stack corruption, albeit not the one we originally thought we were.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The IO_STATUS_BLOCK that is handed into ZwWriteFile is used by the underlying file system driver to save the status of the write operation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The IO_STATUS_BLOCK handed in by the code above was on the stack.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Once this function returns, this stack location is no longer valid. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;The stack location will eventually get reused by the next function call that extends this far down the stack.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It turns out that the IoCompletion routine of the file system driver was writing its final status onto the stack at a location that was now being used for something else (in this case, an In-Stack Queued SpinLock).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This corrupted the stack and caused the bugcheck.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Once you figure out what is happening, it makes so much sense.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;Conclusion&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;Well, at least we now know what is going on.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;While implementing a new feature that pre-allocated cache space for a virtual application, we triggered a situation where, under certain conditions, the file extension request could not be finished synchronously and was being pended.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The code in question was not ready to handle this situation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, it ended up assuming that the operation was complete and went back to sleep.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;When the IoCompletion routine was later triggered for the request, it attempted to write the status of the write operation onto a stack location that was no longer valid, causing stack corruption.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;The solution to the fix was easy.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;All we had to do was call the same write function that we use everywhere else in our code.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This was sufficient to prevent the situation from occurring.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The one nagging issue was why we didn’t see this issue on other test systems and why customers were able to catch it so quickly.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;After a little more digging, we believe we discovered why the two almost-identical systems had such different behavior.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It turns out that the system that experienced the issue had a hard drive that was highly fragmented.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The system that could not reproduce the issue had very little fragmentation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, our hypothesis is that NTFS was able to complete the call synchronously if it could find a single range to handle the extension.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If the drive was highly fragmented, the request would take a long time and would end up getting pended.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This may also explain why we did not see this on Vista machines, since Vista automatically defrags the hard drive on a regular basis. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;B style="mso-bidi-font-weight: normal"&gt;&lt;SPAN style="FONT-SIZE: 12pt; LINE-HEIGHT: 115%"&gt;&lt;FONT face=Calibri&gt;Lessons Learned&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;FONT face=Calibri size=3&gt;I think the biggest lesson to be gained from this experience is that, when using the NTAPI to write to files in kernel mode, you either need to specify one of the FILE_SYNCHRONOUS_IO_* flags when creating / opening the file or you need to pass in an Event object and handle the case where file operations return STATUS_PENDING.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Doing neither of these leads to disaster (and long nights).&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6810526" width="1" height="1"&gt;</description></item><item><title>A Very PowerShell Thanksgiving</title><link>http://blogs.msdn.com/b/johnsheehan/archive/2007/11/27/a-very-powershell-thanksgiving.aspx</link><pubDate>Wed, 28 Nov 2007 01:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6561010</guid><dc:creator>jsheehan</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johnsheehan/rsscomments.aspx?WeblogPostID=6561010</wfw:commentRss><comments>http://blogs.msdn.com/b/johnsheehan/archive/2007/11/27/a-very-powershell-thanksgiving.aspx#comments</comments><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;I had the week of Thanksgiving off.&amp;nbsp; So, what better time to learn a new technology.&amp;nbsp; And, since I spend more time in the command prompt than anywhere else on my system, I figured I should get with the times and learn PowerShell.&amp;nbsp; So, I grabbed Bruce Payette's 'Windows PowerShell in Action' and got to work.&amp;nbsp; &lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Let me first say that this is a really well written book.&amp;nbsp; Bruce explains not only the what, but also the why.&amp;nbsp; I find it easier to understand a technology when I understand why the decisions were made by the team in the first place.&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;It didn't take long before I was up and running in a PowerShell prompt.&amp;nbsp; It turns out that this was the perfect technology to learn on my vacation.&amp;nbsp; I really didn't want to spend much time on it, as I have been neglecting my family trying to get our Beta shipped and traveling.&amp;nbsp; PowerShell and Bruce's book were the perfect combination for learning something in short bursts.&amp;nbsp; I was able to play with my daughter, spend time with my wife and fit in a little learning in the odd moments I had to myself.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;I'm very impressed with PowerShell.&amp;nbsp; It is a simple, logical language and shell environment.&amp;nbsp; My test for a new language is whether it is cohesive.&amp;nbsp; In other words, does it make sense.&amp;nbsp; If it makes sense, I won't have to keep referring to documentation to get stuff done.&amp;nbsp; PowerShell makes sense.&amp;nbsp; The commands are small, simple and consistent.&amp;nbsp; The PowerShell team did a great job.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Whenever I pick up a new language, I always choose a project that I want to do and see how well I can do it with the language in question.&amp;nbsp; For example, when I learned Ruby, I decided to create a Sudoku solver.&amp;nbsp; Ruby was so easy to learn and consistent that I finished the solver in&amp;nbsp;two hours after reading only part of a book.&amp;nbsp; That is still a record for me.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;For PowerShell, I decided to choose a project that fell into the systems management area.&amp;nbsp; Rather than doing some boring file processing project, I figured I would try to replicate a utility I had previously written in C++.&amp;nbsp; Our Test team has some automated tests that exercise Microsoft Office on a Terminal Server to test the scalability overhead of SoftGrid (ahem, Microsoft Application Virtualization).&amp;nbsp; Occasionally, they run into an issue where an Office process will just start chewing up 100% cpu on a processor.&amp;nbsp; It is unclear what is going on with Office, but since it happens without SoftGrid, it isn't something that they worry about.&amp;nbsp; The one problem is that this issue can skew their results.&amp;nbsp; So, they were constantly monitoring their test rigs so they could kill any processes that had "run away".&amp;nbsp; Since I figured these guys had better things to do with their time, I wrote them a small utility that would monitor processes and kill any that had "run away".&amp;nbsp; It allowed them to configure the parameters that defined what it meant to run away.&amp;nbsp; The utility worked out great. It saved them from having to manually monitor these systems and made their results much more predictable.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;This sounded like the perfect project for learning PowerShell.&amp;nbsp; It was a pretty narrow problem.&amp;nbsp; And, I figured PowerShell would be good at solving it.&amp;nbsp; Boy, was I right.&amp;nbsp; After reading half of Bruce's book (I have to admit, I still haven't completely finished it, my daughter took precedence &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: Wingdings; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;&lt;SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;) I was able to solve the problem quickly and easily.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Now, I’m not a PowerShell Ninja yet.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, I was able to code together a reasonable solution in about 40 minutes with 20+ lines of PowerShell code.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This included time for getting the syntax right and figuring out one weird issue with the Process object.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;To solve this particular problem, I just created a hashtable of Process objects retrieved from the Get-Process command, indexed by their process id.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Then, I took another snapshot of processes after a configurable period and calculate how much CPU they had used.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Simple.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, when I first tried this, it didn’t work.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The reason is that the CPU property on the Process object is dynamic.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It is not a snapshot in time.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Each time you query it, it gives you the latest amount of CPU used for the process in question.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;So, I had to store the current value somewhere.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Luckily, PowerShell allows you to attach properties (it calls them ‘notes’) to an existing object.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This made my life much easier, since it meant I didn’t have to invent a new object to store the Process object and my custom property.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Also, since I wanted to have multiple samples before I killed a process, I needed to keep track of how long the process had been “in violation” of the policies handed into the script.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Again, PowerShell’s notes came to the rescue.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I could store the number of times a process was in violation and only kill it after it had violated the threshold number of cycles in violation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;In the end, I added a couple of other small features to the script.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For one, I decided to make it configurable whether it would kill the process or just lower its priority to Idle.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This seemed more useful for regular situations where you might not want to kill the process, but still want your system to be responsive.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I also added an exclusion for processes running in Session 0.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This made sense, since only Services and System processes should be running in Session 0 (at least, on Vista).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Here is the output of the tool, with an example process that was taking up too much CPU (given the name of it, no wonder).&amp;nbsp; One thing you'll note is the initial error message that I get when I launch PowerShell.&amp;nbsp; Every time I launch PowerShell, I get the following error:&amp;nbsp; "Attempting to perform the InitializeDefaultDrives operation on the 'FileSystem' provider failed."&amp;nbsp; It turns out that this error occurs when PowerShell attempts to access a drive which it doesn't have permission to.&amp;nbsp; Now, this is a very atypical case.&amp;nbsp; In my case, it is because I have Microsoft Application Virtualization installed and the drive is not accessible from this particular PowerShell process.&amp;nbsp; So, I get the error.&amp;nbsp; PowerShell is still functional.&amp;nbsp; And, I have a feeling it will be fixed in the future.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;A href="http://blogs.msdn.com/photos/johnsheehan/picture6561277.aspx" target=_blank&gt;&lt;/A&gt;&lt;IMG title="PowerShell Screenshot" style="WIDTH: 640px; HEIGHT: 190px" height=190 alt="PowerShell Screenshot" src="http://blogs.msdn.com/photos/johnsheehan/images/6561277/640x190.aspx" width=640 mce_src="http://blogs.msdn.com/photos/johnsheehan/images/6561277/640x190.aspx"&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Anyway, below is the script I finally came up with.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Now, as I said, I still haven’t reach Ninja status in PowerShell.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I’m sure that it looks too much like a C++ code and there are probably tons of things that a seasoned PowerShell programmer would do differently.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Still, it solved my problem quickly and efficiently.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Isn’t that the point of scripting languages? &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: Wingdings; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;&lt;SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I considered commenting the code to help you understand what is going on.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But, I decided to leave it as is.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In its own way, I think it is beautifully simple.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It is surely much simpler than the C++ code that it replace.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Happy PowerShelling.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; VERTICAL-ALIGN: top; LINE-HEIGHT: normal"&gt;&lt;SPAN style="FONT-SIZE: 8.5pt; COLOR: black; FONT-FAMILY: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;param([int] $period=5, [int] $maxCpu=$period*0.9, [int] $threshold=5, [bool] $kill=$false)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;$procs = @{}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;while($true) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;# Create hash table of processes, hashed by process id&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$new_procs = @{}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;foreach ($proc in Get-Process) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;add-member -in $proc noteproperty periodsAboveMaxCpu 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;add-member -in $proc noteproperty cpuUsageSnapshot $proc.cpu&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$old_proc = $procs[$proc.id]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;if($old_proc -ne $null) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$proc.periodsAboveMaxCpu = $old_proc.periodsAboveMaxCpu&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;if(($proc.cpuUsageSnapshot - $old_proc.cpuUsageSnapshot) -gt $maxCpu){&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$proc.periodsAboveMaxCpu++&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;} else {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$proc.periodsAboveMaxCpu = 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$new_procs[$proc.id] = $proc&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$procs = $new_procs&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$bad_procs = $procs.keys | foreach{$procs[$_]} | where {$_.periodsAboveMaxCpu -gt 0}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$bad_procs&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;foreach ($proc in $bad_procs) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;if(($proc.periodsAboveMaxCpu -gt $threshold) -and ($proc.SessionId -gt 0)) { &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;if($kill) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;write-output "Killing $proc" &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$proc.Kill()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;} else {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;write-output "Dropping priority of $proc to idle" &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;$proc.PriorityClass = [System.Diagnostics.ProcessPriorityClass]::Idle&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;sleep($period)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;SPAN style="FONT-SIZE: 8pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 8pt; LINE-HEIGHT: 115%"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6561010" width="1" height="1"&gt;</description></item></channel></rss>