<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Tone Poem</title><subtitle type="html">Listen to your heart</subtitle><id>http://blogs.msdn.com/b/mattn/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/mattn/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2006-02-24T23:40:00Z</updated><entry><title>Cannot Install Windows SDK :(</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2012/06/27/cannot-install-windows-sdk.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2012/06/27/cannot-install-windows-sdk.aspx</id><published>2012-06-27T16:11:27Z</published><updated>2012-06-27T16:11:27Z</updated><content type="html">&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You try to install latest Windows SDK and it does not work.&lt;/p&gt;  &lt;p&gt;If you look at the setup log file and you see:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;8:58:43 AM Wednesday, June 27, 2012:&lt;/strong&gt; &lt;strong&gt;C:\WinSDK\Setup\SFX\vcredist_x64.exe installation failed with return code 5100&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Reason for this is you have a newer C++ runtime installed on your machine, for example by Visual Studio 2012.&amp;#160; The dumb Windows SDK installer will not install ANYTHING (even the simplest thing that does not depend on C runtime) if newer C++ runtime is installed.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Fix #1:&amp;#160; Install Windows SDK on clean machine and copy files over (if you just want the tools like me).&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Fix #2:&amp;#160; Uninstall Microsoft Visual Studio C++ 2012 runtime (both x86 and x64 versions, then install Windows SDK&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10324584" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Windows Diagnostics with Windows Azure Issue</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2012/06/27/windows-diagnostics-with-windows-azure-issue.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2012/06/27/windows-diagnostics-with-windows-azure-issue.aspx</id><published>2012-06-27T15:48:00Z</published><updated>2012-06-27T15:48:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;Windows Azure Diagnostics does not work,&amp;nbsp;you see following in the Compute Emulator =&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;[Diagnostics]: Error starting diagnostics:&lt;br /&gt; &lt;strong&gt;System.FormatException: Invalid account string.&lt;/strong&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; at Microsoft.WindowsAzure.CloudStorageAccount.&amp;lt;Parse&amp;gt;b__0(String err)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; at Microsoft.WindowsAzure.CloudStorageAccount.ParseStringIntoSettings(String s, Action`1 error)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; at Microsoft.WindowsAzure.CloudStorageAccount.TryParse(String s, CloudStorageAccount&amp;amp; accountInformation, Action`1 error)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; at Microsoft.WindowsAzure.CloudStorageAccount.Parse(String value)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; at Microsoft.WindowsAzure.Plugins.Diagnostics.DiagnosticsAgentManager.&amp;lt;StartAgent&amp;gt;b__0()&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;Reason?&amp;nbsp; The reason is a connecting string parsing bug in Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString =&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;&amp;lt;ConfigurationSettings&amp;gt;&lt;br /&gt; &amp;lt;Setting &lt;br /&gt;&amp;nbsp;&amp;nbsp; name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString"&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;&amp;nbsp; value="DefaultEndpointsProtocol=https;AccountName=aaa;AccountKey=bbb&lt;span style="font-size: x-large;" size="6"&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;" /&amp;gt;&lt;br /&gt; &amp;lt;/ConfigurationSettings&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;strong&gt;Fix: Remove the trailing semi-colon at the end of the configuration string =&amp;gt;&lt;/strong&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;&amp;lt;ConfigurationSettings&amp;gt;&lt;br /&gt;&amp;lt;Setting &lt;br /&gt; name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString"&lt;br /&gt; value="DefaultEndpointsProtocol=https;AccountName=aaa;AccountKey=bbb" /&amp;gt;&lt;br /&gt;&amp;lt;/ConfigurationSettings&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10324568" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Enabling Advanced Driver Tracing for the SQL Native Client ODBC Drivers</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2012/05/15/enabling-advanced-driver-tracing-for-the-sql-native-client-odbc-drivers.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2012/05/15/enabling-advanced-driver-tracing-for-the-sql-native-client-odbc-drivers.aspx</id><published>2012-05-15T19:48:00Z</published><updated>2012-05-15T19:48:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you are using the SQL Native Client ODBC driver, there is built-in high performance very detailed driver tracing, here is how you use it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;#1. Create batch file to start tracing (this traces for all three versions of SQL Native Client ODBC Driver) named StartSNACTrace.cmd:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="mysql"&gt;@echo off &lt;br /&gt; echo Starting SNAC tracing... &lt;br /&gt; echo {BA798F36-2325-EC5B-ECF8-76958A2AF9B5} 0xFFFFFFFF 128 SQLNCLI &amp;gt; providers.txt &lt;br /&gt; echo {A9377239-477A-DD22-6E21-75912A95FD08} 0xFFFFFFFF 128 SQLNCLI10 &amp;gt;&amp;gt; providers.txt &lt;br /&gt; echo {2DA81B52-908E-7DB6-EF81-76856BB47C4F} 0xFFFFFFFF 128 SQLNCLI11 &amp;gt;&amp;gt; providers.txt &lt;br /&gt; reg add HKLM\SOFTWARE\Microsoft\BidInterface\Loader /v :Path /t REG_SZ /d "%systemroot%\system32\msdadiag.dll" /f &lt;br /&gt; del /Q *.etl &lt;br /&gt; logman create trace -n SnacTrace -ct perf -pf providers.txt -bs 10000 -nb 10000 50000 -o SnacTrace.etl -max 100 -cnf 00 &lt;br /&gt; logman start -n SnacTrace &lt;br /&gt; echo Run StopSnacTrace.cmd to stop tracing.&lt;/code&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Note, replace &lt;strong&gt;0xFFFFFFFF&lt;/strong&gt; with &lt;strong&gt;0x00000000&lt;/strong&gt; to do minimum tracing.&amp;nbsp; The number 128 indicates save trace data as ANSI, which reduces by about 1/2 the space for the ETL files.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note you MUST start the tracing before the process that uses the SQL Native Client ODBC driver starts (this is VERY IMPORTANT).&amp;nbsp;&amp;nbsp; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Start the tracing then start the process that is using the SQL Native Client ODBC driver.&amp;nbsp;&amp;nbsp; You can stop tracing at any time, even before the process exits.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;#2. Create this batch file named StopSnacTrace.cmd to stop the tracing:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="mysql"&gt;@echo off &lt;br /&gt; echo Stopping SNAC tracing... &lt;br /&gt; logman stop -n SnacTrace &lt;br /&gt; logman delete -n SnacTrace &lt;br /&gt; reg delete HKLM\SOFTWARE\Microsoft\BidInterface\Loader /v :Path /f &lt;br /&gt; echo SNAC tracing stopped&lt;/code&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The above settings will create a new trace file of maximum size 100MB numbered SnacTrace_000001.etl, SnacTrace_000002.etl, etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;#3.&amp;nbsp; To process the trace files, you need to register a special mof file on the trace processing machine (you do not have to do this on the trace gathering machine)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;#4&lt;/strong&gt;. &lt;strong&gt;Download and register the&amp;nbsp;all.mof file&lt;/strong&gt; from "&lt;strong&gt;Data Access Tracing in SQL Server 2012" &lt;/strong&gt;MSDN article (last time I checked the URL is here &lt;a href="http://technet.microsoft.com/en-us/library/hh880086"&gt;http://technet.microsoft.com/en-us/library/hh880086)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There is a section in this article that says "&lt;strong&gt;Download Sample and MOF Files". &lt;/strong&gt; This file is named &lt;strong&gt;Setup.zip.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Download this file to some temporary folder and extract the files.&amp;nbsp; You will see a folder named &lt;strong&gt;MOF_Files&lt;/strong&gt;, go into this folder and locate the snac*.mof files&lt;strong&gt;, &lt;/strong&gt;then on the client machine where you want to do tracing,&lt;/p&gt;
&lt;p&gt;run the following &lt;strong&gt;from an elevated command prompt&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code class="mysql"&gt;C:\&amp;gt;&lt;strong&gt;mofcomp all.mof&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class="mysql"&gt;Microsoft (R) MOF Compiler Version 6.1.7600.16385&lt;br /&gt;Copyright (c) Microsoft Corp. 1997-2006. All rights reserved.&lt;br /&gt;Parsing MOF file: all.mof&lt;br /&gt;MOF file has been successfully parsed&lt;br /&gt;Storing data in the repository...&lt;br /&gt;Done!&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will register all the providers so you can now see them with logman, to verify they are registered, run:&lt;/p&gt;
&lt;p&gt;C:\&amp;gt;&lt;strong&gt;logman query providers | findstr SQL&lt;/strong&gt;&lt;br /&gt;SQLNCLI.1&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;&amp;nbsp;&amp;nbsp; {BA798F36-2325-EC5B-ECF8-76958A2AF9B5}&lt;br /&gt;SQLNCLI10.1&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; {A9377239-477A-DD22-6E21-75912A95FD08}&lt;br /&gt;SQLNCLI11.1&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; {2DA81B52-908E-7DB6-EF81-76856BB47C4F}&lt;/p&gt;
&lt;p&gt;You should see all 3 SNAC driver versions in the output.&amp;nbsp; You are now ready to process the&amp;nbsp;traces (the *.etl files generated)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;#5.&amp;nbsp;&amp;nbsp;To process the traces to extract the data to CSV file, use&amp;nbsp;tracerpt tool (comes with Windows) or LogParser (you need to download this tool).&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run following from a command prompt:&lt;/p&gt;
&lt;p&gt;&lt;code class="mysql"&gt;tracerpt SnacTrace_000001.etl -of CSV -en ANSI -gmt -o SnacTrace_000001.csv&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note I find the LogParser tool (you can download from Microsoft) provides a nicer, more compact log file, try this command:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LogParser.exe "select eventnumber, eventname, timestamp, userdata into SnacTrace_000001.csv from SnacTrace_000001.etl" &lt;br /&gt; -i:ETW -o:CSV -oTsFormat:"yyyy-MM-dd hh:mm:ss.n" -headers:off&lt;/p&gt;
&lt;p&gt;This will give you a really nice looking trace file output, and LogParser is also very fast to process large traces.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10305526" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>PowerShell Command Separator Is ; and Not &amp;</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2012/04/28/powershell-command-separator-is-and-not-amp.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2012/04/28/powershell-command-separator-is-and-not-amp.aspx</id><published>2012-04-28T16:02:41Z</published><updated>2012-04-28T16:02:41Z</updated><content type="html">&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Ahh PowerShell, I still cannot fully embrace your powerful weirdness.&lt;/p&gt;  &lt;p&gt;With normal NT command prompt I can restart my SQL Server by running =&amp;gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;net stop mssqlserver&amp;#160; &amp;amp; net start mssqlserver&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This does not work in PowerShell, you get the usual cryptic, nonsensical and useless error message:&lt;/p&gt;  &lt;p&gt;PS C:\&amp;gt; net stop mssqlserver &amp;amp; net start mssqlserver   &lt;br /&gt;&lt;strong&gt;Ampersand not allowed. The &amp;amp; operator is reserved for future use; use &amp;quot;&amp;amp;&amp;quot; to pass ampersand as a string.     &lt;br /&gt;At line:1 char:23      &lt;br /&gt;+ net stop mssqlserver &amp;amp; &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;#160; net start mssqlserver      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; + CategoryInfo&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : ParserError: (:) [], ParentContainsErrorRecordException      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; + FullyQualifiedErrorId : AmpersandNotAllowed&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Personally, I would change this error message to:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Ampersand not allowed.&amp;#160; You can use the semi-colon instead for a command separator in PowerShell.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Ok, given this logic, then I try:&lt;/p&gt;  &lt;p&gt;PS C:\&amp;gt; net stop mssqlserver &amp;quot;&amp;amp;&amp;quot; net start mssqlserver   &lt;br /&gt;&lt;strong&gt;The syntax of this command is:&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;&lt;/strong&gt;  &lt;p&gt;&lt;strong&gt;NET STOP     &lt;br /&gt;service      &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Ok, I give up.&amp;#160; Time to search the internet.&lt;/p&gt;  &lt;p&gt;Found some mention of an &lt;strong&gt;undocumented semi-colon&lt;/strong&gt; &lt;strong&gt;as command separator&lt;/strong&gt;, this works =&amp;gt;&lt;/p&gt;  &lt;p&gt;PS C:\&amp;gt; net stop mssqlserver ; net start mssqlserver   &lt;br /&gt;&lt;strong&gt;The SQL Server (MSSQLSERVER) service is stopping.     &lt;br /&gt;The SQL Server (MSSQLSERVER) service was stopped successfully.&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;&lt;/strong&gt;  &lt;p&gt;&lt;strong&gt;The SQL Server (MSSQLSERVER) service is starting.     &lt;br /&gt;The SQL Server (MSSQLSERVER) service was started successfully.&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10298729" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Disabling =&gt; CLRDLL: No CLR image loaded (i.e. mscorwks.dll)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2012/04/26/disabling-gt-clrdll-no-clr-image-loaded-i-e-mscorwks-dll.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2012/04/26/disabling-gt-clrdll-no-clr-image-loaded-i-e-mscorwks-dll.aspx</id><published>2012-04-26T19:55:40Z</published><updated>2012-04-26T19:55:40Z</updated><content type="html">&lt;p&gt;I’m debugging using the Debugging Tools For Windows (WinDbg).&amp;#160; Debugging a native C++ process (no CLR loaded).&lt;/p&gt;  &lt;p&gt;I find with every debugger command I run, I get annoying amounts of debugger logging spew saying “&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)”.&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;For example, when I dump a call stack I see:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; kC&lt;/p&gt;  &lt;p&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/p&gt;  &lt;p&gt;KERNELBASE!RaiseException&lt;/p&gt;  &lt;p&gt;myapp!_CxxThrowException&lt;/p&gt;  &lt;p&gt;..&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;CLRDLL: No CLR image loaded (i.e. mscorwks.dll)&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;WARNING: Stack unwind information not available. Following frames may be wrong.&lt;/p&gt;  &lt;p&gt;Etc…&lt;/p&gt;  &lt;p&gt;The fix to disable this spew is running:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;.cordll –vd&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;The reason I saw this in my debugger is I have a startup script that runs:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;.cordll -ve -u –l&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;This &lt;strong&gt;–ve&lt;/strong&gt; means “enable vebose logging for CLR”.&amp;#160; Internally the debugger is trying to load CLR debugging support over and over and this is failing.&amp;#160; Running .cordll –vd disables the extended logging.&lt;/p&gt;  &lt;p&gt;Note you can disable CLR integration with debugger to speed up the debugger command execution when debugging native code by running:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;.cordll -d -u -vd&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Read help on .cordll for details.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10298189" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Calculating read_only_routing_url for AlwaysOn</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2012/04/25/calculating-read-only-routing-url-for-alwayson.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2012/04/25/calculating-read-only-routing-url-for-alwayson.aspx</id><published>2012-04-25T21:29:54Z</published><updated>2012-04-25T21:29:54Z</updated><content type="html">&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;When setting up read-only routing for SQL Server AlwaysOn, you have to configure each availability replica with a read-only routing URL.&lt;/p&gt;  &lt;p&gt;The read-only routing URL is just a “pointer” to the replica and determines what the replica will report back to the client driver when routing to the replica.&lt;/p&gt;  &lt;p&gt;Suppose you have an AlwaysOn cluster with 3 cluster nodes, Node1, Node2, and Node3.&amp;#160;&amp;#160; On each of these nodes you will have a SQL Server instance running.&amp;#160;&amp;#160; For very simple configurations there will be one default SQL Server instance listening on tcp port 1433 on each node.&amp;#160; With a more complex configuration you may have clustered SQL Server instances on these nodes.&lt;/p&gt;  &lt;p&gt;Read-only routing uses the following algorithm to locate a readable secondary:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Client connects to an Availability Group listener endpoint.&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Note this endpoint always points to the primary replica for the availability group&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Client specifies ApplicationIntent=ReadOnly in the connection string, this is transmitted to the server during login&lt;/li&gt;    &lt;li&gt;On server side, server checks that incoming connection is using an Availability Group listener endpoint&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Otherwise, read-only routing is disabled&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Server checks the target database and determines if it is in an availability group&lt;/li&gt;    &lt;li&gt;If database is in an availability group, we check if the read_only_routing_list is set on the primary replica&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;If list is not set, routing is disabled&lt;/li&gt;      &lt;li&gt;If list is set, then routing is enforced&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Server then enumerates the replicas in the read_only_routing_list and checks each replica in the list&lt;/li&gt;    &lt;li&gt;First replica it finds that is synchronizing and accepts readers (allow_connections=read_only or all) is the routing target&lt;/li&gt;    &lt;li&gt;Server next reads the read_only_routing_url from this replica and sends this response to the client&lt;/li&gt;    &lt;li&gt;Client reads routing URL and re-directs to the readable secondary instance&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Given above, you need to ensure that the read_only_routing_url is properly set for each replica when enabling read-only routing, otherwise the client will be redirected to the wrong instance.&lt;/p&gt;  &lt;p&gt;I created a T-SQL script that you can run against any instance and it will tell you what the appropriate read_only_routing_url is for the instance.&amp;#160;&amp;#160; The script will detect if the instance is clustered or not an generate appropriate URL.&amp;#160;&amp;#160; Script is included below, enjoy!&amp;#160; =&amp;gt;&lt;/p&gt;  &lt;p&gt;-- Read-only routing url generation script.   &lt;br /&gt;-- Connect to each replica in your AlwaysOn cluster and run this script to get the read_only_routing_url for the replica.    &lt;br /&gt;-- Then set this to the read_only_routing_url for the availability group replica =&amp;gt;    &lt;br /&gt;--&amp;#160;&amp;#160;&amp;#160; alter availability group MyAvailabilityGroup modify replica on N'ThisReplica' with (secondary_role(read_only_routing_url=N'&amp;lt;url&amp;gt;'))    &lt;br /&gt;print 'Read-only-routing url script v.2012.1.24.1'&lt;/p&gt;  &lt;p&gt;print 'This SQL Server instance version is [' + cast(serverproperty('ProductVersion') as varchar(256)) + ']'&lt;/p&gt;  &lt;p&gt;if (ServerProperty('IsClustered') = 1)    &lt;br /&gt;begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is a clustered SQL Server instance.'    &lt;br /&gt;end    &lt;br /&gt;else    &lt;br /&gt;begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is a standard (not clustered) SQL Server instance.'&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;end&lt;/p&gt;  &lt;p&gt;if (ServerProperty('IsHadrEnabled') = 1)    &lt;br /&gt;begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is enabled for AlwaysOn.'    &lt;br /&gt;end    &lt;br /&gt;else    &lt;br /&gt;begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is NOT enabled for AlwaysOn.'    &lt;br /&gt;end&lt;/p&gt;  &lt;p&gt;-- Detect SQL Azure instance.   &lt;br /&gt;declare @is_sql_azure bit    &lt;br /&gt;set @is_sql_azure = 0&lt;/p&gt;  &lt;p&gt;begin try   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @is_sql_azure = 1    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; exec('declare @i int set @i = sql_connection_mode()')    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is a Sql Azure instance.'    &lt;br /&gt;end try    &lt;br /&gt;begin catch    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @is_sql_azure = 0    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is NOT a Sql Azure instance.'    &lt;br /&gt;end catch&lt;/p&gt;  &lt;p&gt;-- Check that this is SQL 11 or later, otherwise fail fast.   &lt;br /&gt;if (@@microsoftversion / 0x01000000 &amp;lt; 11 or @is_sql_azure &amp;gt; 0)    &lt;br /&gt;begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance does not support read-only routing, exiting script.'    &lt;br /&gt;end    &lt;br /&gt;else    &lt;br /&gt;begin -- if server supports read-only routing&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Fetch the dedicated admin connection (dac) port.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- Normally it's always port 1434, but to be safe here we fetch it from the instance.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- We use this later to exclude the admin port from read_only_routing_url.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @dac_port int    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @reg_value varchar(255)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; exec xp_instance_regread     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'HKEY_LOCAL_MACHINE',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'SOFTWARE\Microsoft\Microsoft SQL Server\\MSSQLServer\SuperSocketNetLib\AdminConnection\Tcp',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'TcpDynamicPorts',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @reg_value output&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; set @dac_port = cast(@reg_value as int)&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance DAC (dedicated admin) port is ' + cast(@dac_port as varchar(255))   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (@dac_port = 0)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print 'Note a DAC port of zero means the dedicated admin port is not enabled.'    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Fetch ListenOnAllIPs value.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- If set to 1, this means the instance is listening to all IP addresses.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- If set to 0, this means the instance is listening to specific IP addresses.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @listen_all int    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; exec xp_instance_regread     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'HKEY_LOCAL_MACHINE',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'SOFTWARE\Microsoft\Microsoft SQL Server\\MSSQLServer\SuperSocketNetLib\Tcp',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'ListenOnAllIPs',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @listen_all output&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; if (@listen_all = 1)   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is listening to all IP addresses (default mode).'    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is listening to specific IP addresses (ListenOnAllIPs is disabled).'    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Check for dynamic port configuration, not recommended with read-only routing.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @tcp_dynamic_ports varchar(255)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; exec xp_instance_regread     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'HKEY_LOCAL_MACHINE',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'SOFTWARE\Microsoft\Microsoft SQL Server\\MSSQLServer\SuperSocketNetLib\Tcp\IPAll',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; N'TcpDynamicPorts',    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @tcp_dynamic_ports output&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; if (@tcp_dynamic_ports = '0')   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is listening on a dynamic tcp port, this is NOT A RECOMMENDED CONFIGURATION when using read-only routing, because the instance port can change each time the instance is restarted.'    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance is listening on fixed tcp port(s) (it is not configured for dynamic ports), this is a recommended configuration when using read-only routing.'    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Calculate the server domain and instance FQDN.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- We use @server_domain later to build the FQDN to the clustered instance.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @instance_fqdn varchar(255)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @server_domain varchar(255)&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Get the instance FQDN using the xp_getnetname API   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- Note all cluster nodes must be in same domain, so this works for calculating cluster FQDN.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @instance_fqdn = ''    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; exec xp_getnetname @instance_fqdn output, 1 &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Remove embedded null character at end if found.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @terminator int     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @terminator = charindex(char(0), @instance_fqdn) - 1     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (@terminator &amp;gt; 0)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @instance_fqdn = substring(@instance_fqdn, 1, @terminator)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Build @server_domain using @instance_fqdn.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @server_domain = @instance_fqdn&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Remove trailing portion to extract domain name.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @terminator = charindex('.', @server_domain)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (@terminator &amp;gt; 0)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @server_domain = substring(@server_domain, @terminator+1, datalength(@server_domain))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance resides in domain ''' +&amp;#160; @server_domain + ''''&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; if (ServerProperty('IsClustered') = 1)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -- Fetch machine name, which for a clustered SQL instance returns the network name of the virtual server.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -- Append @server_domain to build the FQDN.    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set @instance_fqdn = cast(serverproperty('MachineName') as varchar(255)) + '.' + @server_domain    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; declare @ror_url varchar(255)   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @instance_port int&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; set @ror_url = ''&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Get first available port for instance.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; select     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; top 1&amp;#160;&amp;#160;&amp;#160; -- Select first matching port    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @instance_port = port    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; from sys.dm_tcp_listener_states     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; where     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; type=0 -- Type 0 = TSQL (to avoid mirroring endpoint)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; and     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; state=0&amp;#160;&amp;#160;&amp;#160; --&amp;#160; State 0 is online&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; and     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; port &amp;lt;&amp;gt; @dac_port -- Avoid DAC port (admin port)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; and     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- Avoid availability group listeners    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ip_address not in (select ip_address from sys.availability_group_listener_ip_addresses agls)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; group by port&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; order by port asc&amp;#160; -- Pick first port in ascending order&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- Check if there are multiple ports and warn if this is the case.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; declare @list_of_ports varchar(max)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; set @list_of_ports = ''&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; select    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; @list_of_ports = @list_of_ports +    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; case datalength(@list_of_ports)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; when 0 then cast(port as varchar(max))    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else ',' +&amp;#160; cast(port as varchar(max))    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; end    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; from sys.dm_tcp_listener_states     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; where     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; type=0&amp;#160;&amp;#160;&amp;#160; --&amp;#160;&amp;#160;&amp;#160;&amp;#160; Type 0 = TSQL (to avoid mirroring endpoint)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; and     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; state=0&amp;#160;&amp;#160;&amp;#160; --&amp;#160; State 0 is online&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; and     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; port &amp;lt;&amp;gt; @dac_port -- Avoid DAC port (admin port)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; and     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -- Avoid availability group listeners    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ip_address not in (select ip_address from sys.availability_group_listener_ip_addresses agls)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; group by port&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; order by port asc&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance FQDN (Fully Qualified Domain Name) is ''' + @instance_fqdn + ''''   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'This SQL Server instance port is ' + cast(@instance_port as varchar(10))&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; set @ror_url = 'tcp://' + @instance_fqdn + ':' + cast(@instance_port as varchar(10))&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; print '****************************************************************************************************************'   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print 'The read_only_routing_url for this SQL Server instance is ''' + @ror_url + ''''    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print '****************************************************************************************************************'&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; -- If there is more than one instance port (unusual) list them out just in case.   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (charindex(',', @list_of_ports) &amp;gt; 0)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print 'Note there is more than one instance port, the list of available instance ports for read_only_routing_url is (' + @list_of_ports + ')'    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print 'The above URL just uses the first port in the list, but you can use any of these available ports.'    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; end&lt;/p&gt;  &lt;p&gt;end -- if server supports read-only routing   &lt;br /&gt;go&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10297801" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Tracking Handle Misuse Using Application Verifier and Windbg</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2009/09/08/tracking-handle-misuse-using-application-verifier-and-windbg.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2009/09/08/tracking-handle-misuse-using-application-verifier-and-windbg.aspx</id><published>2009-09-08T20:26:44Z</published><updated>2009-09-08T20:26:44Z</updated><content type="html">&lt;p&gt;In a recent MSDN forum post &lt;a title="Connection Pooling randomly throwing COM exceptions" href="http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/b5b7a179-3737-4380-b6cf-843f3e71b317"&gt;Connection Pooling randomly throwing COM exceptions&lt;/a&gt; I uncovered an issue where some code inside the process was closing handles owned by our pooling code.&amp;#160; This caused our pooling code to get into a bad state triggering a SemaphoreFullException every single time a caller attempted to open a connection from the pool.&lt;/p&gt;  &lt;p&gt;The root cause of this problem was code calling the Win32 API CloseHandle on a handle that it did not own.&amp;#160;&amp;#160; Since Windows can aggresively reuse handle values, it’s possible to hit a situation like below:&lt;/p&gt;  &lt;p&gt;Thread1: CreateFile –&amp;gt; Get handle #1.&lt;/p&gt;  &lt;p&gt;Thread1: CloseHandle(#1)&lt;/p&gt;  &lt;p&gt;Thread2: CreateFile –&amp;gt; Get handle #1, store in member variable.&lt;/p&gt;  &lt;p&gt;Thread1: CloseHandle (#1) &amp;lt;- Mistake in code.&lt;/p&gt;  &lt;p&gt;Thread1: CreateEvent –&amp;gt; Get handle #1.&lt;/p&gt;  &lt;p&gt;Now my code on Thread2 thinks it has a file handle, but it has an event handle!&amp;#160;&amp;#160; Thread2 did not make any coding mistake, the Thread1 code corrupted Thread2’s handle value.&lt;/p&gt;  &lt;p&gt;This is an inherent issue when using handles, they are inherently dangerous you have to be very careful to only call CloseHandle 1 time.&amp;#160; Now the operating system could mitigate this by handling out random values for handles, but in general the operating system does not always do this for performance reasons.&amp;#160; The tradeoff is fast performance for all applications that behave correctly.&lt;/p&gt;  &lt;p&gt;Now if you have a process where you suspect handles are getting misused (leaked or double closed), you can use Application Verifier to help track this down very quickly, this is what I want to talk about.&lt;/p&gt;  &lt;p&gt;First download both &lt;strong&gt;Microsoft Application Verifier&lt;/strong&gt; and &lt;strong&gt;Debugging Tools for Windows&lt;/strong&gt;, both are free downloads from Microsoft.&amp;#160; I would provide links but these always change, get the latest versions of both.&amp;#160; Get the version that matches your operating system bitness as well for best results.&lt;/p&gt;  &lt;p&gt;Install Microsoft Application Verifier and Debugging Tools for Windows on the machine where you have the problem.&amp;#160; Both are very clean installers and remove easily so don’t worry about installing on production machine, they are easy to remove and don’t require any reboot during removal.&amp;#160;&amp;#160; If you are really worried you can install them on a separate machine and xcopy the files to the production machine, this works as well.&lt;/p&gt;  &lt;p&gt;Next, figure out what process you want to debug.&amp;#160; If you are running IIS application with .NET, most likely this is the w3wp.exe process.&amp;#160; You don’t need the process ID yet.&lt;/p&gt;  &lt;p&gt;First run Application Verifier to setup handle tracking, it looks like below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_thumb.png" width="244" height="146" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Not too fancy.&amp;#160; :)&amp;#160; You want to create the entry for the process name next, select File | Add Application.&amp;#160;&amp;#160; Let’s do the demonstration using notepad.exe for now.&amp;#160;&amp;#160; Just type in notepad.exe and click Open.&amp;#160; You do not have to find and select the correct binary, just typing in the process name is sufficient, it does not need the full path:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_thumb_1.png" width="244" height="193" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now that you’ve added the process, go to the right and select ONLY handles under the Basics options, like below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_thumb_2.png" width="244" height="146" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The reason I only select handles here is to reduce the performance implications of all the other tracking inside the process.&amp;#160; I just want to track handles, this is all.&lt;/p&gt;  &lt;p&gt;Once you’ve selected handles only, click Save, then close Application Verifier.&amp;#160; You will see this message:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_thumb_3.png" width="244" height="95" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is fine, we will do this work later on (attach debugger).&amp;#160; Click OK and exit App Verifier.&lt;/p&gt;  &lt;p&gt;Now, VERY IMPORTANT!&amp;#160; Re-open App Verifier.&amp;#160; Verify you see your process name correctly and you see only Handles is checked.&amp;#160; Do this step as a sanity check to ensure you selected the right thing AND it was saved correctly to registry.&lt;/p&gt;  &lt;p&gt;Exit App Verifier again.&lt;/p&gt;  &lt;p&gt;If your process is currently running,&lt;strong&gt; stop and restart the process&lt;/strong&gt;.&amp;#160;&amp;#160; If for example you are using IIS, you want to run iisreset at this point to restart IIS.&amp;#160; This step is required as the process reads the Application Verifier flags ONLY during startup.&lt;/p&gt;  &lt;p&gt;In our case we are debugging notepad, so lets startup an instance of notepad.exe at this point (Start|Run –&amp;gt; Notepad.exe)&lt;/p&gt;  &lt;p&gt;Now open Windbg.exe (from Debugging Tools For Windows install).&amp;#160; Select File | Attach To Process…&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;VERY IMPORTANT!&amp;#160; First thing to do is check the Non-invasive check box on the Attach to Process dialog, as below:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_10.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_thumb_4.png" width="179" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You should ALWAYS check this when doing handle tracking work because this allows you to attach to the process in a special mode called non-invasive mode.&amp;#160; This allows the debugger to be later detached and the process will continue normally.&amp;#160; If you don’t check this checkbox, the debugger will fully attach to the process and you cannot shut down the debugger without terminating the process.&lt;/p&gt;  &lt;p&gt;Next, locate your process, you will see here my process is notepad.exe, select this process:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_12.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/TrackingHandleMisuseUsingApplicationVeri_92C5/image_thumb_5.png" width="180" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Click OK to attach the debugger non-invasively.&amp;#160;&amp;#160; Once you are attached, go to the command window (select View|Command) and run the following commands:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; &lt;strong&gt;!htrace -enable&lt;/strong&gt;    &lt;br /&gt;Handle tracing enabled.    &lt;br /&gt;Handle tracing information snapshot successfully taken.&lt;/p&gt;  &lt;p&gt;This command is required to enable the tracing of handles.&amp;#160; Once this is set, you can exit the debugger by running the q (quit) command:&lt;/p&gt;  &lt;p&gt;0:000:&amp;gt; &lt;strong&gt;q&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;At this point handle tracking is enabled for the process.&amp;#160; For this experiment, now go to notepad and open a single text file but do not exit notepad.exe yet.&lt;/p&gt;  &lt;p&gt;Now we want to see what handle tracking can do for us.&amp;#160; Startup Windbg.exe again and attach to notepad again in &lt;strong&gt;non-invasive mode&lt;/strong&gt;.&amp;#160; Run the following commands:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; &lt;strong&gt;.dump /ma c:\temp\notepad.dmp     &lt;br /&gt;&lt;/strong&gt;Creating c:\temp\notepad.exe - mini user dump    &lt;br /&gt;Dump successfully written&lt;/p&gt;  &lt;p&gt;Note the command is .dump /ma &amp;lt;filename&amp;gt; where &amp;lt;filename&amp;gt; can be anything you want here.&amp;#160; I called my dump file c:\temp\notepad.dmp.&lt;/p&gt;  &lt;p&gt;This creates a dump of the process.&amp;#160; Now again run &lt;strong&gt;q &lt;/strong&gt;(quit) command to exit debugger.&lt;/p&gt;  &lt;p&gt;Re-open Windbg again, we are next going to examine the dump file.&lt;/p&gt;  &lt;p&gt;In Windbg select File | Open Crash Dump… and select c:\temp\notepad.dmp and click Open.&lt;/p&gt;  &lt;p&gt;In the command window, run the following 2 commands to load symbols:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; &lt;strong&gt;.sympath srv*&lt;/strong&gt;&lt;a href="http://msdl.microsoft.com/download/symbols"&gt;&lt;strong&gt;http://msdl.microsoft.com/download/symbols&lt;/strong&gt;&lt;/a&gt;    &lt;br /&gt;Symbol search path is: srv*&lt;a href="http://msdl.microsoft.com/download/symbols"&gt;http://msdl.microsoft.com/download/symbols&lt;/a&gt;    &lt;br /&gt;Expanded Symbol search path is: srv*&lt;a href="http://msdl.microsoft.com/download/symbols"&gt;http://msdl.microsoft.com/download/symbols&lt;/a&gt;    &lt;br /&gt;0:000&amp;gt; &lt;strong&gt;.reload /f     &lt;br /&gt;&lt;/strong&gt;..........................................*** ERROR: Symbol file could not be found.&amp;#160; Defaulted to export symbols for AvCheck.dll -     &lt;br /&gt;.....    &lt;br /&gt;Loading unloaded module list&lt;/p&gt;  &lt;p&gt;Note you may see errors here, this is fine for now.&lt;/p&gt;  &lt;p&gt;Now we want to see a trace of our handle activity, run the !htrace command with no arguments:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt;&lt;strong&gt; !htrace&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Next you will see tons of debugger spew like below:&lt;/p&gt;  &lt;p&gt;--------------------------------------   &lt;br /&gt;Handle = 0x00000000000002f0 - OPEN    &lt;br /&gt;Thread ID = 0x0000000000001390, Process ID = 0x0000000000000b6c &lt;/p&gt;  &lt;p&gt;0x0000000077835e3a: ntdll!ZwDuplicateObject+0x000000000000000a   &lt;br /&gt;0x00000000776148a8: kernel32!DuplicateHandle+0x0000000000000055    &lt;br /&gt;0x000007fefe6cb435: rpcrt4!THREAD::THREAD+0x00000000000000b5    &lt;br /&gt;0x000007fefe6cb35c: rpcrt4!ThreadSelfHelper+0x0000000000000028    &lt;br /&gt;0x000007fefe77444c: rpcrt4!NdrpClientCall2+0x0000000000000698    &lt;br /&gt;0x000007fefe774ddd: rpcrt4!NdrClientCall2+0x000000000000001d    &lt;br /&gt;0x000007fefe4c0e9a: ole32!BulkUpdateOIDs+0x000000000000008a    &lt;br /&gt;0x000007fefe4c0d89: ole32!CRpcResolver::BulkUpdateOIDs+0x0000000000000109    &lt;br /&gt;0x000007fefe4c0c36: ole32!CROIDTable::ClientBulkUpdateOIDWithPingServer+0x0000000000000224    &lt;br /&gt;0x000007fefe4c94c3: ole32!CROIDTable::WorkerThreadLoop+0x0000000000000057    &lt;br /&gt;0x000007fefe4c9406: ole32!CRpcThread::WorkerLoop+0x000000000000001e    &lt;br /&gt;0x000007fefe4c9682: ole32!CRpcThreadCache::RpcWorkerThreadEntry+0x000000000000001a    &lt;br /&gt;0x000000007761466d: kernel32!BaseThreadInitThunk+0x000000000000000d    &lt;br /&gt;0x0000000077818791: ntdll!RtlUserThreadStart+0x000000000000001d    &lt;br /&gt;--------------------------------------    &lt;br /&gt;Handle = 0x000000000000031c – OPEN&lt;/p&gt; …  &lt;p&gt;This shows you all the handle activity in the process.&lt;/p&gt;  &lt;p&gt;You can locate a double close by searching for the CLOSE lines:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Handle = 0x000000000000033c - CLOSE&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This will also have the stack trace of the code that closed the handle.&lt;/p&gt;  &lt;p&gt;Now in my case what I did was gather a dump when some error case occurred in my process, then I examined the dump to determine what handle my code was using and then used !htrace to find out who closed it.&amp;#160; All of the information is kept in the crash dump nicely for you.&lt;/p&gt;  &lt;p&gt;You can also pass a parameter to !htrace to dump activity for a single handle, like below:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; &lt;strong&gt;!htrace 33c&lt;/strong&gt;     &lt;br /&gt;--------------------------------------    &lt;br /&gt;Handle = 0x000000000000033c - CLOSE    &lt;br /&gt;Thread ID = 0x0000000000000744, Process ID = 0x0000000000000b6c &lt;/p&gt;  &lt;p&gt;0x0000000077835faa: ntdll!ZwTerminateThread+0x000000000000000a   &lt;br /&gt;0x000000007780b508: ntdll!RtlExitUserThread+0x0000000000000048    &lt;br /&gt;0x000000007780b8a7: ntdll!TppWorkerThread+0x0000000000000a23    &lt;br /&gt;0x000000007761466d: kernel32!BaseThreadInitThunk+0x000000000000000d    &lt;br /&gt;0x0000000077818791: ntdll!RtlUserThreadStart+0x000000000000001d    &lt;br /&gt;--------------------------------------    &lt;br /&gt;Handle = 0x000000000000033c - OPEN    &lt;br /&gt;Thread ID = 0x0000000000000744, Process ID = 0x0000000000000b6c &lt;/p&gt;  &lt;p&gt;0x000000007773d57a: user32!ZwUserCallOneParam+0x000000000000000a   &lt;br /&gt;0x000000007773d95f: user32!RealMsgWaitForMultipleObjectsEx+0x00000000000000b3    &lt;br /&gt;0x000000007773da2e: user32!MsgWaitForMultipleObjectsEx+0x0000000000000046    &lt;br /&gt;0x0000000077732af4: user32!MsgWaitForMultipleObjects+0x0000000000000020    &lt;br /&gt;0x000007fef5fbb198: browseui!CShellTaskScheduler::_TT_MsgWaitForMultipleObjects+0x0000000000000038    &lt;br /&gt;0x000007fef5fbb11d: browseui!CShellTaskScheduler::TT_TransitionThreadToRunningOrTerminating+0x00000000000000a1    &lt;br /&gt;0x000007fef5fbaea1: browseui!CShellTaskThread::ThreadProc+0x0000000000000076    &lt;br /&gt;--------------------------------------&lt;/p&gt;  &lt;p&gt;You will notice a specific handle is closed and reopened many times over a period of time, this is normal.&amp;#160; What you want to look for is cases where CLOSE is called 2 times in a row to find cases of handle misuse.&amp;#160; Likewise if a handle is leaked you will not see a final CLOSE called, the last trace will be an OPEN.&lt;/p&gt;  &lt;p&gt;Now, when you are finished debugging, &lt;strong&gt;BE ABSOLUTELY SURE&lt;/strong&gt; to start App Verifier again and &lt;strong&gt;DELETE&lt;/strong&gt; the process entry for your process!&amp;#160; You want to always do this since the App Verifier settings are persisted in the registry, they will survive even a server reboot.&amp;#160; Right click on the Image Name and select “Delete Application”.&amp;#160; Then click Save and close and re-open App Verifier to ensure that the entry is gone.&amp;#160; As well if you are debugging some service you want to restart the service to stop the tracking, run iisreset for example again to reset IIS to normal state if you are debugging IIS.&lt;/p&gt;  &lt;p&gt;Hope this helps you debug the next handle misuse case you encounter, have fun!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9892699" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Nice day</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2009/02/10/nice-day.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2009/02/10/nice-day.aspx</id><published>2009-02-11T08:30:01Z</published><updated>2009-02-11T08:30:01Z</updated><content type="html">&lt;p&gt;Yes.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/Herelelrer_12E44/IMG_9487.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IMG_9487" border="0" alt="IMG_9487" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/Herelelrer_12E44/IMG_9487_thumb.jpg" width="244" height="164" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9412085" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>How to tell if binary is x86 or amd64?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/11/25/how-to-tell-if-binary-is-x86-or-amd64.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/11/25/how-to-tell-if-binary-is-x86-or-amd64.aspx</id><published>2008-11-25T20:17:59Z</published><updated>2008-11-25T20:17:59Z</updated><content type="html">&lt;p&gt;First get dumpbin tool, ships with any Windows SDK.&lt;/p&gt;  &lt;p&gt;Run dumpbin /headers on the binary, then look at the &lt;strong&gt;magic number&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This is an amd64 binary:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;c:\&amp;gt;dumpbin /headers c:\amd64\msvcr100.dll | findstr magic   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 20B magic # &lt;strong&gt;(PE32+)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This is a 32-bit binary:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;c:\DPMedusa1&amp;gt;dumpbin /headers c:\x86\msvcr100.dll | findstr magic   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 10B magic # (&lt;strong&gt;PE32&lt;/strong&gt;)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;dumpbin also works on executables, for example on my amd64 machine:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;c:\&amp;gt;dumpbin /headers c:\Windows\System32\calc.exe | findstr magic   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 20B magic # (PE32+)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;c:\&amp;gt;dumpbin /headers c:\Windows\SysWOW64\calc.exe | findstr magic   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 10B magic # (PE32)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9142399" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>TrustedInstaller</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/10/07/trustedinstaller.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/10/07/trustedinstaller.aspx</id><published>2008-10-08T00:09:52Z</published><updated>2008-10-08T00:09:52Z</updated><content type="html">&lt;p&gt;Just a note to self, when typing in TrustedInstaller into security dialogs in Vista/Windows 2008, be sure to prefix with:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; NT SERVICE\TrustedInstaller&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;C:\Windows&amp;gt;icacls c:\windows\winsxs   &lt;br /&gt;c:\windows\winsxs &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NT SERVICE\TrustedInstaller:(OI)(CI)(F)   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BUILTIN\Administrators:(OI)(CI)(RX)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NT AUTHORITY\SYSTEM:(OI)(CI)(RX)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BUILTIN\Users:(OI)(CI)(RX)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The security UI dialogs do not recognize TrustedInstaller just by itself (don't know why).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8987557" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>What is mscorwks_ntdef.dll?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/10/06/what-is-mscorwks-ntdef-dll.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/10/06/what-is-mscorwks-ntdef-dll.aspx</id><published>2008-10-07T03:55:01Z</published><updated>2008-10-07T03:55:01Z</updated><content type="html">&lt;p&gt;Ok, file this one under debugger trivia.&amp;#160; &lt;/p&gt;  &lt;p&gt;If you are debugging a 32-bit CLR process from a 64-bit native (Windbg) debugger, you will notice:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;0:040&amp;gt; lmvm mscorwks_ntdef     &lt;br /&gt;start&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; end&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; module name      &lt;br /&gt;00000000`69480000 00000000`69a10000&amp;#160;&amp;#160; mscorwks_ntdef&amp;#160;&amp;#160; (deferred)&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Image path: mscorwks_ntdef.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Image name: mscorwks_ntdef.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Timestamp:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Fri Jul 25 06:58:48 2008 (4889DC18)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CheckSum:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 00597CC4      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ImageSize:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 00590000      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File version:&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2.0.50727.3053      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Product version:&amp;#160; 2.0.50727.3053      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File flags:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0 (Mask 3F)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File OS:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 4 Unknown Win32      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File type:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2.0 Dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File date:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 00000000.00000000      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Translations:&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0409.04b0      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CompanyName:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Microsoft Corporation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProductName:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Microsoft&amp;#174; .NET Framework      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; InternalName:&amp;#160;&amp;#160;&amp;#160;&amp;#160; mscorwks.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; OriginalFilename: mscorwks.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProductVersion:&amp;#160;&amp;#160; 2.0.50727.3053      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FileVersion:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2.0.50727.3053 (netfxsp.050727-3000)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FileDescription:&amp;#160; Microsoft .NET Runtime Common Language Runtime - WorkStation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; LegalCopyright:&amp;#160;&amp;#160; &amp;#169; Microsoft Corporation.&amp;#160; All rights reserved.      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Comments:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Flavor=Retail&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;What is this mscorwks_ntdef?&amp;#160; It is debugger hocus pocus due to a bug.&amp;#160; Run this command to make it go away:&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;0:040&amp;gt; .reload /s     &lt;br /&gt;.....      &lt;br /&gt;Loading Wow64 Symbols      &lt;br /&gt;................................................................      &lt;br /&gt;................................................................      &lt;br /&gt;................................................................&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Now you will see the correct output for mscorwks module:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;0:040&amp;gt; lmvm mscorwks_ntdef     &lt;br /&gt;start&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; end&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; module name      &lt;br /&gt;0:040&amp;gt; lmvm mscorwks      &lt;br /&gt;start&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; end&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; module name      &lt;br /&gt;00000000`69480000 00000000`69a10000&amp;#160;&amp;#160; mscorwks&amp;#160;&amp;#160; (deferred)&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Image path: C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Image name: mscorwks.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Timestamp:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Fri Jul 25 06:58:48 2008 (4889DC18)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CheckSum:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 00597CC4      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ImageSize:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 00590000      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File version:&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2.0.50727.3053      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Product version:&amp;#160; 2.0.50727.3053      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File flags:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0 (Mask 3F)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File OS:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 4 Unknown Win32      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File type:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2.0 Dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; File date:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 00000000.00000000      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Translations:&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0409.04b0      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CompanyName:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Microsoft Corporation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProductName:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Microsoft&amp;#174; .NET Framework      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; InternalName:&amp;#160;&amp;#160;&amp;#160;&amp;#160; mscorwks.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; OriginalFilename: mscorwks.dll      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProductVersion:&amp;#160;&amp;#160; 2.0.50727.3053      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FileVersion:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2.0.50727.3053 (netfxsp.050727-3000)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; FileDescription:&amp;#160; Microsoft .NET Runtime Common Language Runtime - WorkStation      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; LegalCopyright:&amp;#160;&amp;#160; &amp;#169; Microsoft Corporation.&amp;#160; All rights reserved.      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Comments:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Flavor=Retail&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;However, try to load sos and it will fail:&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;0:040&amp;gt; .loadby mscorwks sos     &lt;br /&gt;Unable to find module 'sos'&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;0:040&amp;gt; .load C:\Windows\Microsoft.NET\Framework64\v2.0.50727\sos.dll     &lt;br /&gt;0:040&amp;gt; !dumpstack -EE      &lt;br /&gt;Failed to load data access DLL, 0x80004005      &lt;br /&gt;Verify that 1) you have a recent build of the debugger (6.2.14 or newer)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2) the file mscordacwks.dll that matches your version of mscorwks.dll is       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; in the version directory      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 3) or, if you are debugging a dump file, verify that the file       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mscordacwks_&amp;lt;arch&amp;gt;_&amp;lt;arch&amp;gt;_&amp;lt;version&amp;gt;.dll is on your symbol path.      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 4) you are debugging on the same architecture as the dump file.      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; For example, an IA64 dump file must be debugged on an IA64      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; machine. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;You can also run the debugger command .cordll to control the debugger's     &lt;br /&gt;load of mscordacwks.dll.&amp;#160; .cordll -ve -u -l will do a verbose reload.      &lt;br /&gt;If that succeeds, the SOS command should work on retry. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;If you are debugging a minidump, you need to make sure that your executable     &lt;br /&gt;path is pointing to mscorwks.dll as well.      &lt;br /&gt;0:040&amp;gt; .cordll -ve -u -l      &lt;br /&gt;CLRDLL: LoadLibrary(C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscordacwks.dll) failed, Win32 error 193      &lt;br /&gt;CLRDLL: Unable to find mscordacwks_AMD64_x86_2.0.50727.3053.dll by mscorwks search      &lt;br /&gt;CLRDLL: Unable to find 'mscordacwks_AMD64_x86_2.0.50727.3053.dll' on the path      &lt;br /&gt;CLRDLL: Unable to get version info for 'c:\syms\mscorwks.dll\4889DC18590000\mscordacwks_AMD64_x86_2.0.50727.3053.dll', Win32 error 0n87      &lt;br /&gt;CLRDLL: ERROR: Unable to load DLL mscordacwks_AMD64_x86_2.0.50727.3053.dll, Win32 error 0n87      &lt;br /&gt;CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_x86_2.0.50727.3053.dll, Win32 error 0n87&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary: Sos debugger extension will not work in &amp;quot;mixed bitness&amp;quot; debugging scenarios.&amp;#160; &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You must debug 32-bit CLR process using 32-bit native debugger in order to get sos to work properly.&lt;/p&gt;  &lt;p&gt;Likewise if you are debugging 64-bit CLR process, use 64-bit debugger and 64-bit sos.dll.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8980327" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>How To Read Data From AD LDS Into Java</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/09/23/how-to-read-data-from-ad-lds-into-java.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/09/23/how-to-read-data-from-ad-lds-into-java.aspx</id><published>2008-09-23T19:49:02Z</published><updated>2008-09-23T19:49:02Z</updated><content type="html">&lt;p&gt;Just helping out the next person, this code took me all day to cobble together.&lt;/p&gt; &lt;p&gt;Key tricky part was how to connect to AD using an NT security account from Java.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div&gt; &lt;div class="csharpcode"&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;String &lt;/span&gt;ReadBindingInfoFromAd() throws NamingException
{  
    Hashtable env = &lt;span style="color: blue"&gt;new &lt;/span&gt;Hashtable();   
    env.put(Context.INITIAL_CONTEXT_FACTORY, &lt;span style="color: #a31515"&gt;"com.sun.jndi.ldap.LdapCtxFactory"&lt;/span&gt;);   
    env.put(Context.PROVIDER_URL, &lt;span style="color: #a31515"&gt;"LDAP://MyLdapServer:389"&lt;/span&gt;);
    env.put(Context.SECURITY_AUTHENTICATION, &lt;span style="color: #a31515"&gt;"DIGEST-MD5"&lt;/span&gt;); &lt;span style="color: green"&gt;// Use DIGEST-MD5, it works with Windows.
    &lt;/span&gt;env.put(Context.SECURITY_PRINCIPAL, &lt;span style="color: #a31515"&gt;"MyNtDomain\\MyNtUser"&lt;/span&gt;);  &lt;span style="color: green"&gt;// This is your nt domain and user.
    &lt;/span&gt;env.put(Context.SECURITY_CREDENTIALS, &lt;span style="color: #a31515"&gt;"MyPassword"&lt;/span&gt;);    &lt;span style="color: green"&gt;// Nt user account's password.
    &lt;/span&gt;DirContext context = &lt;span style="color: blue"&gt;new &lt;/span&gt;InitialDirContext(env); 
    
    SearchControls ctrl = &lt;span style="color: blue"&gt;new &lt;/span&gt;SearchControls();
    ctrl.setCountLimit(1);  &lt;span style="color: green"&gt;// This is a good idea, limits result size. 
    &lt;/span&gt;ctrl.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    ctrl.setReturningAttributes(&lt;span style="color: blue"&gt;new &lt;/span&gt;String [] {&lt;span style="color: #a31515"&gt;"serviceBindingInformation"&lt;/span&gt;});
    
    NamingEnumeration enumeration = context.search(&lt;span style="color: #a31515"&gt;"CN=MyServer,CN=MyContainer"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"(objectclass=serviceConnectionPoint)"&lt;/span&gt;, ctrl);
    
    &lt;span style="color: green"&gt;// My search should only return one value.
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(enumeration.hasMore())
    {
        SearchResult result = (SearchResult) enumeration.next();
        Attributes attribs = result.getAttributes();
        NamingEnumeration values = ((BasicAttribute) attribs.get(&lt;span style="color: #a31515"&gt;"serviceBindingInformation"&lt;/span&gt;)).getAll(); 
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(values.hasMore())
        {
            &lt;span style="color: blue"&gt;return &lt;/span&gt;values.next().toString();
        }
    }
    &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;""&lt;/span&gt;;  
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;pre class="alt"&gt;Same code from C# is not as bad because it leverages current user's context:&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static string &lt;/span&gt;ReadBindingInfoFromAd()
{
    &lt;span style="color: blue"&gt;using &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DirectoryEntry &lt;/span&gt;root = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DirectoryEntry&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"LDAP://MyLdapServer:389/CN=MyServer,CN=MyContainer"&lt;/span&gt;))
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;)root.Properties[&lt;span style="color: #a31515"&gt;"serviceBindingInformation"&lt;/span&gt;].Value;
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8962464" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Chicken + Egg Problem With Hyper-V</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/09/14/chicken-egg-problem-with-hyper-v.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/09/14/chicken-egg-problem-with-hyper-v.aspx</id><published>2008-09-14T19:11:25Z</published><updated>2008-09-14T19:11:25Z</updated><content type="html">&lt;p&gt;When we neglect to port an old and crusty feature, one will always wave a few hands and say it's better in the end for the customer.&amp;#160; But sometimes it becomes a sticking point.&amp;#160; Today I am trying to setup VMs using Hyper-V on Windows 2008 and by default Hyper-V does not allow mouse to work with VMs over remote desktop &lt;strong&gt;unless&lt;/strong&gt; you install VM additions on guest OS.&amp;#160; Virtual PC did not have this requirement, the mouse would work but in a horribly wild and wacky way, skittering left and right across the screen until you installed VM additions.&amp;#160; In most cases this was not a problem for me except for today, I'm working from home and I just need to send ONE mouse click in order to log into the guest OS to install VM additions.&amp;#160; The old wild and crazy VPC mouse click would suffice here!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/ChickenEggProblemWithHyperV_812E/HyperV_4.jpg"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="HyperV" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/ChickenEggProblemWithHyperV_812E/HyperV_thumb_1.jpg" width="518" height="461" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Arg.&amp;#160; I cannot log in because of one mouse click.&amp;#160;&amp;#160; I will try rebooting.&lt;/p&gt;  &lt;p&gt;Rebooted, managed to type in password behind SCM message box, and logged in.&lt;/p&gt;  &lt;p&gt;Next my NIC does not work.&amp;#160; Ok, I cannot configure hyper-v over remote desktop and the NIC does not work by default.&lt;/p&gt;  &lt;p&gt;Ok, fixed NIC, user error, I had to setup Legacy mode on the NIC, got this working.&lt;/p&gt;  &lt;p&gt;Attempted to install hyper-v extensions, this failed with &amp;quot;An error has occurred:&amp;#160; The specified program requires a newer version of Windows.&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/ChickenEggProblemWithHyperV_812E/hyperv2_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="hyperv2" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/ChickenEggProblemWithHyperV_812E/hyperv2_thumb.jpg" width="356" height="95" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Arg again.&amp;#160; I have to install Windows 2003 SP2 I suppose.&amp;#160; Trying this now.&lt;/p&gt;  &lt;p&gt;What I need to do is create isos for Windows 2003 and Windows 2003 SP2, this would help speed things along.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8951766" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>SqlClient Timeouts Revealed</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/08/29/sqlclient-timeouts-revealed.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/08/29/sqlclient-timeouts-revealed.aspx</id><published>2008-08-30T03:33:51Z</published><updated>2008-08-30T03:33:51Z</updated><content type="html">&lt;p&gt;Just some notes from recent discussions internal and external of how timeouts work with SqlClient.&amp;#160; First a classification of where timeouts can occur with SqlClient:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;When attempting to get a connection from the SqlClient connection pool&lt;/li&gt;    &lt;li&gt;When attempting to create a new fresh connection to server (not getting one from pool)&lt;/li&gt;    &lt;li&gt;When sending a command explicitly to the server&lt;/li&gt;    &lt;li&gt;When sending commands with &amp;quot;context connection=true&amp;quot;&lt;/li&gt;    &lt;li&gt;When sending commands implicitly (under the covers) to the server&lt;/li&gt;    &lt;li&gt;When executing asynchronous commands (BeginExecute...)&lt;/li&gt;    &lt;li&gt;When waiting for attention acknowledgement from server (special rare case)&lt;/li&gt;    &lt;li&gt;When sending TM commands&lt;/li&gt;    &lt;li&gt;When fetching rows&lt;/li&gt;    &lt;li&gt;When uploading rows using bulk copy&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I hope I did not miss a class of timeout here, if so, let me know.&lt;/p&gt;  &lt;p&gt;First, the majority of these above listed timeouts leverage SqlConnection.ConnectionString's &amp;quot;Connect Timeout&amp;quot; and SqlCommand.CommandTimeout values in a logical and sensible manner.&lt;/p&gt;  &lt;h3&gt;Login Timeouts&lt;/h3&gt;  &lt;p&gt;For example 1 and 2 use &amp;quot;Connect Timeout&amp;quot;, this makes sense to me.&amp;#160; We could have created a separate &amp;quot;get a live connection timeout&amp;quot; versus a &amp;quot;get connection from the pool timeout&amp;quot; but the utility of this does not over-ride the added complexity of having 2 timeouts here.&amp;#160; But say for example you happen to have an old ancient lost to the ages SQL Server that takes 1 minute to open a connection to over a slow WAN.&amp;#160; But once connections are in the pool you want to pull these out in a rapid fashion.&amp;#160;&amp;#160; Ahh, it's just not worth it to add this feature for such an edge case.&lt;/p&gt;  &lt;p&gt;With Connect Timeout, a value of 0 means &amp;quot;infinite&amp;quot; wait.&amp;#160; It's not truely infinite of course 0 is mapped to UInt32.MaxValue milliseconds underneath which is about 49 days.&amp;#160; Hope you don't have to wait that long for SQL to respond.&lt;/p&gt;  &lt;p&gt;If the connection pool is full, attempts to get a connection from the pool will block until Connect Timeout expires, this makes sense.&lt;/p&gt;  &lt;p&gt;If you have to open a new connection, there are many activities that occur underneath that could take time.&amp;#160; We have to open a socket to the server, this could be blocked by networking layer for a long time.&amp;#160; Next we have to send prelogin packet to server to negotiate packet size and get server version, and here we wait for a prelogin response from the server.&amp;#160; Once we process prelogin, we then have to send a login packet and this can get complicated.&amp;#160; First we have to negotiate with SQL Server to get SSL setup for encrypting the login packet.&amp;#160; Once we have SSL setup, which can entail multiple trips back and forth to server,&amp;#160; we can then send the login packet.&amp;#160; If you use integrated authentication, we also have to setup the SSPI channel and this could take a few round trips as well.&amp;#160; Ok, once all this is done we get a login acknowledgement from the server and we are &amp;quot;logged in&amp;quot; and hand back control to the caller.&amp;#160; All of this occurs under Connect Timeout period of time during SqlConnection.Open, if any leg in the process takes too long, the timeout expires and exception is thrown.&lt;/p&gt;  &lt;p&gt;Note if you do get lots of login timeout failures, this can be indicative of poor pooling performance.&amp;#160; Logins can timeout due to high CPU on server side as well -- if for example the server just does not have enough CPU to process the login quickly enough.&amp;#160; In any case Connect Timeout in SqlClient controls this timeout.&lt;/p&gt;  &lt;p&gt;Logins are slightly more complicated when you are connecting to a mirrored SQL Server.&amp;#160; If you are doing this you will have &amp;quot;Failover Partner&amp;quot; specified in the ConnectionString.&amp;#160; When connecting to a mirrored server we alternately attempt to open connections to primary and secondary back and forth until timeout expires.&amp;#160; Overall the same timeout provided by &amp;quot;Connect Timeout&amp;quot; applies in the end.&lt;/p&gt;  &lt;h3&gt;Explicit Command Execution Timeouts&lt;/h3&gt;  &lt;p&gt;When executing commands using SqlCommand, the CommandTimeout is used.&amp;#160; A CommandTimeout of 0 means &amp;quot;infinite&amp;quot; again (a.k.a 49 days).&amp;#160; If you don't set CommandTimeout, a default of 30 seconds is used.&lt;/p&gt;  &lt;p&gt;Looks simple on the surface but now the fun begins.&amp;#160; What precisely does &amp;quot;the command completed&amp;quot; really mean?&amp;#160; Does it mean the server processed the query and sent back the first byte of response?&amp;#160; Does it mean the time until the entire response is drained?&amp;#160; The help topic for SqlCommand.CommandTimeout indicates:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;This property is the cumulative time-out for all network reads during command execution or processing of the results. A time-out can still occur after the first row is returned, and does not include user processing time, only network read time. &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This can be important if you are reading millions of rows using a SqlDataReader.&amp;#160; As you read more and more rows you are chewing away at this cumulative time, and the time can run out in theory.&amp;#160; &lt;/p&gt;  &lt;p&gt;Note that when reading data from the server, SqlClient reads data in packets (called TDS packets) and these are 8000 bytes each by default.&amp;#160; We don't do any readahead, we just read 8K at a time.&amp;#160; Hence reading a series of rows in a resultset in turn reads a series of 8K packets from the server.&amp;#160; If you are curious about this you can use SQL Server Management Studio and turn on the &amp;quot;Include Client Statistics&amp;quot; feature (it's on the toolbar):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/SqlClientTimeouts_C29D/clientstats_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="clientstats" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/SqlClientTimeouts_C29D/clientstats_thumb.jpg" width="244" height="181" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You can see here I read 1000 rows, 1306 TDS packets (8000 bytes each) and total of 4MB of data.&amp;#160; This boils down to 1306 network reads of 8K.&amp;#160; In most cases the network reads are very fast, however you could hit one or more locked rows half-way through reading the results which could accumulate more time.&amp;#160; A locked row means the client blocks waiting for the row lock to become available, eating up more of your CommandTimeout.&lt;/p&gt;  &lt;p&gt;Hence CommandTimeout covers all the time spend making all these 8k reads, including the first 8K read which is most likely the longest wait as it's waiting for the server to process the query and send back the first bytes of response.&lt;/p&gt;  &lt;p&gt;Some customers have complained about this behavior, they think that once the initial read completes then subsequent row fetches should not time out.&amp;#160; The command has completed in other words, why time out reading rows?&amp;#160; In reality, the command may or may not be completed when the first 8K read is returned to the client.&amp;#160; For example you could send a batch of commands and the first command may be completed but subsequent commands in the batch have not even started executing yet.&amp;#160; I suppose we could have a row read timeout and a command timeout to allow more granular control here, but it is really such an edge case that it's not worth cluttering the API with multiple and thus more confusing timeout settings (most customers would never need to set RowReadTimeout).&lt;/p&gt;  &lt;h3&gt;SqlConnection and &amp;quot;context connection=true&amp;quot;&lt;/h3&gt;  &lt;p&gt;If you never write CLR code that runs &lt;strong&gt;inside&lt;/strong&gt; SQL Server, you can skip this section.&amp;#160; If you do write code that runs inside SQL Server (CLR stored procedures or functions) then there is a feature called &amp;quot;context connection=true&amp;quot; that allows you to open a loopback SqlConnection to current SQL Server database.&amp;#160; This loopback connection ignores all command timeouts since it is running in the context of a sql batch already and the client controls the timeout. &lt;/p&gt;  &lt;h3&gt;Implicit Command Timeouts&lt;/h3&gt;  &lt;p&gt;In some rare cases SqlClient code needs to execute internal commands behind the scenes to fetch metadata etc..., these are &amp;quot;implicit commands&amp;quot;.&amp;#160; Some cases of SqlConnection implicit commands:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;SqlConnection.GetSchema - Internally creates a SqlCommand and executes a metadata query.&lt;/li&gt;    &lt;li&gt;SqlConnection.ChangeDatabase - Sends a &amp;quot;use [&amp;lt;databasename&amp;gt;]&amp;quot; command under the covers.&lt;/li&gt;    &lt;li&gt;SqlConnection.BeginTransaction - Sends a &amp;quot;begin transaction&amp;quot; command or other transaction manager command under the covers.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These SqlConnection methods don't have access to any pre-existing SqlCommand object to obtain a CommandTimeout, hence they were written to use Connect Timeout.&amp;#160; Ok, to be honest I am not sure if this makes total sense, but this is how we did it.&amp;#160; Think of &amp;quot;Connect Timeout&amp;quot; as the timeout that applies to all things SqlConnection (login, implicit commands) then it makes sense.&amp;#160;&amp;#160; Big note: SqlConnection.GetSchema currently has a bug where it uses a hard-coded 180 second timeout,the plan is to fix this to be consistent and use Connect Timeout some time in the future.&lt;/p&gt;  &lt;p&gt;Now SqlCommand does not have any implicit commands it runs, but if it did, it would use CommandTimeout.&lt;/p&gt;  &lt;p&gt;SqlDataReader does have an implicit command --&amp;gt; SqlDataReader.GetSchemaTable.&amp;#160; GetSchemaTable uses the CommandTimeout from it's parent SqlCommand object since SqlDataReader does not have a settable timeout.&lt;/p&gt;  &lt;p&gt;I classify TM commands as another form of implicit command executed by the driver under the covers.&amp;#160; What is a TM command?&amp;#160; TM stands for transaction manager.&amp;#160; A TM command is a special command sent to SQL Server to request changes in transaction state from the client.&amp;#160; Commands like SqlConnection.BeginTransaction and SqlConnection.EnlistTransaction and SqlConnection.EnlistDistributedTransaction send these TM commands.&amp;#160; All of these use the parent SqlConnection's &amp;quot;Connect Timeout&amp;quot;.&lt;/p&gt;  &lt;h3&gt;Asynchronous Command Execution Timeout&lt;/h3&gt;  &lt;p&gt;SqlClient does not enforce any timeouts on asynchronously executed commands.&amp;#160; They can run forever in theory.&amp;#160; Note this is not the 49 day forever but the real forever.&amp;#160; Asynchronous commands include SqlCommand.BeginExecuteReader, BeginExecuteNonQuery, and BeginExecuteReader.&lt;/p&gt;  &lt;p&gt;Ok, you might be a little shocked by this behavior, but this is how it works.&amp;#160; The idea of asynchronous command execution is you send off the command and then are notified via an event when it completes.&amp;#160; You can implement your own timeout if needed, for example you could start a timer that checks if the command is completed after a period of time and if not then cancels it.&lt;/p&gt;  &lt;p&gt;The bottom line is IF we wanted to implement CommandTimeout in this case we would just do the same thing, spin up a timer with a handle to the executing command and cancel it if the timer expires and the command has not completed.&amp;#160; &lt;/p&gt;  &lt;h3&gt;Cancel Timeout (attention acknowledgement timeout)&lt;/h3&gt;  &lt;p&gt;Ok, this is a very rare edge case, you can probably forget about this one, but if you are really bored, read on.&amp;#160; Suppose you execute a command, then the command times out.&amp;#160; When this happens the SqlClient driver sends a special&amp;#160; 8 byte packet to the server called an attention packet.&amp;#160; This tells the server to stop executing the current command.&amp;#160; When we send the attention packet, we have to wait for the attention acknowledgement from the server and this can in theory take a long time and time out.&amp;#160; You can also send this packet by calling SqlCommand.Cancel on an asynchronous SqlCommand object.&amp;#160; This one is a special case where we use a 5 second timeout.&amp;#160; In most cases you will never hit this one, the server is usually very responsive to attention packets because these are handled very low in the network layer.&lt;/p&gt;  &lt;p&gt;Now there is a really rare edge case where you send an attention but the server has already completed the operation.&amp;#160; What happens in this case?&amp;#160; In this case SqlClient just drains the response for you silently and still throws the timeout exception.&amp;#160; This brings up a good point -- there is a slim sliver of a possibility if you cancel a command or it times out it may actually complete on the server side prior to the attention signal, please keep this in mind.&amp;#160;&amp;#160; This is a small gotcha that exists when using automatic transactions and a timeout or cancel occurs.&amp;#160; If you use a manual transaction then you can always roll back after handing the timeout exception to ensure you get into a consistent state.&lt;/p&gt;  &lt;h3&gt;Summary&lt;/h3&gt;  &lt;p&gt;In general the parent objects timeout is used in most cases, this is the easiest thing to remember.&amp;#160; If parent is SqlConnection then Connect Timeout is used, if the parent object is SqlCommand or SqlDataReader, then the SqlCommand.CommandTimeout is used.&amp;#160;&amp;#160; There are a few minor exceptions that don't really add up to much for most scenarios.&lt;/p&gt;  &lt;p&gt;If I missed anything here, let me know.&amp;#160; Matt&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8907568" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Why Can't I Log Into SQL Server?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/08/27/why-can-t-i-log-into-sql-server.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/08/27/why-can-t-i-log-into-sql-server.aspx</id><published>2008-08-28T03:17:32Z</published><updated>2008-08-28T03:17:32Z</updated><content type="html">&lt;p&gt;Even though I've been working on the SQL Server protocol layer for the past 3 years I still have those days where I scratch my head because I cannot connect to my SQL Server.&amp;#160;&amp;#160; I have to agree it can be frustrating sometimes.&amp;#160; Usually, once you get it working, it stays working, which is a good thing.&amp;#160;&amp;#160; If any of you out there hit any other &amp;quot;head smacking&amp;quot; gotchas, let me know.&lt;/p&gt;  &lt;h3&gt;1. SSL Self-Signed Cert Does Not Work When Forcing Encryption From Client&lt;/h3&gt;  &lt;p&gt;Today I forgot that I checked the &amp;quot;Encrypt Connection&amp;quot; checkbox in SQL Server Management Studio while trying to verify that an SSL certificate I installed on a SQL 2000 box a day before was working.&amp;#160; Then I attempted to connect to my SQL 2008 server that is using self-signed certificate (which is default behavior in SQL 2005 and later).&amp;#160; When you do this, you get the following error:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;quot;A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.) (Microsoft SQL Server, Error: -2146893019)&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;This error makes sense if you realize that a self-signed certificate does not have a trusted root (everyone knows this, right?).&amp;#160; Anyway, if you see this one, now you will remember.&amp;#160; This can occur with SQL 2005 and SQL 2008, both of these will load a self-signed certificate during startup time if an appropriate SSL certificate is not setup on the machine.&lt;/p&gt;  &lt;p&gt;Thing to remember:&amp;#160; If you want full client side forced SSL encryption to work properly with SQL Server, you need to configure a real SSL certificate that the client trusts.&amp;#160;&amp;#160; The self-signed cert is only useful for encrypting login packets and is not fully trusted by the client since it does not have a trusted root authority.&lt;/p&gt;  &lt;h3&gt;2. I'm A Vista Admin But Cannot Login To My Local SQL Server&lt;/h3&gt;  &lt;p&gt;Another good one:&amp;#160; Attempt to login to your local SQL Server on Vista from non-elevated command prompt or non-elevated SSMS.&amp;#160; Login failed for user domain\username!&amp;#160; But I'm logged in as an admin!&amp;#160; You are not admin if you don't elevate.&amp;#160; This one get's me about once every 3 months or so.&lt;/p&gt;  &lt;h3&gt;3. Cannot Connect To A Clustered SQL Server Named Instance From A Vista Client (submitted by Andy Babiec, thanks!)&lt;/h3&gt;  &lt;p&gt;This is technically speaking not a Vista specific issue, but it is seen more often on Vista clients because of it's advanced (a.k.a. more secure) firewall configuration.&lt;/p&gt;  &lt;p&gt;The basic problem is when the client needs to determine the port of any SQL Server named instance, it will send a UDP packet on port 1434 to the target server and then wait for a response on UDP 1434.&amp;#160; The response packet will have instance name and port number.&amp;#160; Now the issue arises with Windows Cluster where our SQL Browser service gets the incoming&amp;#160; UDP packet then posts a response.&amp;#160; The incoming UDP packet comes in on the virtual cluster IP, but when we send a response, the packet is tagged with the local machine's IP.&amp;#160; Hence a more aggressive client firewall may block the response UDP packet since it has a different IP from the outbound request packet.&lt;/p&gt;  &lt;p&gt;This can cause clients on Vista such as SQL Server Management Studio and also Sql Profiler to fail to connect to the clustered named instance.&lt;/p&gt;  &lt;p&gt;There are various workarounds, one is to add SSMS.exe and SqlProfiler.exe to firewall exclusion list.&amp;#160; Another is to specify the tcp port in the connection string when connecting.&amp;#160; I tend towards the latter, but then again I am a protocols geek and I setup my servers with known port numbers.&amp;#160; We're working with the Windows Cluster team for a solution to this one.&amp;#160; Here is a more detailed blog on the subject from Xinwei, one of our protocols guru:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/sql_protocols/archive/2006/02/27/unable-to-connect-to-a-sql-server-named-instance-on-a-cluster.aspx"&gt;http://blogs.msdn.com/sql_protocols/archive/2006/02/27/unable-to-connect-to-a-sql-server-named-instance-on-a-cluster.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt; 4. User Does Not Have Right To Log Into Their Default Database&lt;/h3&gt;  &lt;p&gt;I have seen this a few times on the newsgroups, so adding this one too.&amp;#160; When you create new users in SQL Server, be sure to allow them access to their designated default database, otherwise they cannot log in!&amp;#160; &lt;/p&gt;  &lt;p&gt;For example, create a junk1 user like so:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;use master     &lt;br /&gt;go      &lt;br /&gt;create database junk1      &lt;br /&gt;go      &lt;br /&gt;use junk1      &lt;br /&gt;go      &lt;br /&gt;create login junk1 with password=N'junk1',       &lt;br /&gt;default_database=junk1, check_expiration=off, check_policy=off      &lt;br /&gt;go&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now attempt to log in using osql:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;C:\&amp;gt;osql -Ujunk1 -Pjunk1 -S.     &lt;br /&gt;Login failed for user 'junk1'.      &lt;br /&gt;Cannot open user default database. Login failed.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you examine the errorlog in SQL 2008, you see:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Error: 18456, Severity: 14, State: 40.     &lt;br /&gt;Login failed for user 'junk1'. Reason: Failed to open the database specified in the login properties. [CLIENT: 123.23.123.12]&lt;/strong&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;We actually did a ton of work in SQL 2008 to make these 18456 login errorlog messages more human understandable in SQL 2008, so this is nice feature for dba who is wondering &amp;quot;who is trying to log into my server?&amp;quot;.&amp;#160; In SQL 2005 you need the special 18456 decoder ring:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/WhyCantILogIntoSQLServer_F327/secretcodering_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="secretcodering" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/WhyCantILogIntoSQLServer_F327/secretcodering_thumb.jpg" width="244" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8902013" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Sharing IE Links With Live Mesh</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/06/04/sharing-ie-links-with-live-mesh.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/06/04/sharing-ie-links-with-live-mesh.aspx</id><published>2008-06-04T19:35:12Z</published><updated>2008-06-04T19:35:12Z</updated><content type="html">&lt;p&gt;In case you have not heard the buzz, we have this new thing called &lt;a href="http://www.mesh.com/"&gt;Live Mesh&lt;/a&gt; that is pretty awesome.&amp;#160; I found out about it whist trying to figure out how to share my Links (c:\users\...\Favorites\Links) folders across multiple machines.&amp;#160; I talked to one of my IE buds and he indicated Live Mesh might be the ticket.&lt;/p&gt;  &lt;p&gt;With Live Mesh you can add each computer as a node in your mesh.&amp;#160; Then you can share folders from your computer into the mesh (and it shares these across all your computers).&lt;/p&gt;  &lt;p&gt;To share my Links, I had to play some tricks with Live Mesh, but nothing too serious.&lt;/p&gt;  &lt;p&gt;I setup Live Mesh on multiple computers, then on primary computer right clicked on C:\Users\MattN\Favorites\Links and shared it to the Mesh (note these computers are Vista, Live Mesh works on Vista and XP for now).&amp;#160; On XP this would be C:\Documents And Settings\MattN\Favorites\Links.&amp;#160; I shared my Links folder on one and only one machine (and also at this point consolidated all my actual links on the one primary machine).&lt;/p&gt;  &lt;p&gt;Next on secondary machines what will happen is a new shortcut named Links will appear on your desktop once Live Mesh syncs up.&lt;/p&gt;  &lt;p&gt;I then closed all IE instances on secondary machines, renamed existing Links to Links1.&lt;/p&gt;  &lt;p&gt;Then go to link on desktop, right click and select Live Mesh Options... Change Sync Settings...&lt;/p&gt;  &lt;p&gt;This will give you an option on where you want the link to reside, change it to C:\Users\Mattn\Favorites\Links, the folder will move automatically and now you have a shared Links folder, pretty cool!&lt;/p&gt;  &lt;p&gt;Going to let this run for a few weeks and see how it works out.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8573588" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Finding Locals In CLR</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/05/29/finding-locals-in-clr.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/05/29/finding-locals-in-clr.aspx</id><published>2008-05-30T07:25:36Z</published><updated>2008-05-30T07:25:36Z</updated><content type="html">&lt;p&gt;Today I'm looking at a few Watson dumps trying to determine why SqlConnection is failing to connect to SQL Server and hanging.&lt;/p&gt;  &lt;p&gt;I see stack like below:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; k   &lt;br /&gt;0021dc5c 79f40778 kernel32!SleepEx+0x62    &lt;br /&gt;0021dc90 7a0561d7 mscorwks!EESleepEx+0xa3    &lt;br /&gt;0021dc9c 7a12fc71 mscorwks!CExecutionEngine::ClrSleepEx+0xd    &lt;br /&gt;0021dcac 7a0e4d7c mscorwks!ClrSleepEx+0x13    &lt;br /&gt;0021dce8 7a082a5f mscorwks!Thread::UserSleep+0x63    &lt;br /&gt;0021dd88 652e94cd mscorwks!ThreadNative::Sleep+0xce    &lt;br /&gt;0021ddc8 652e9283 System_Data_ni!System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover    &lt;br /&gt;0021de20 652e83ff System_Data_ni!System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I need to look at CLR locals in SqlClient.SqlInternalConnectionTds.LoginNoFailover, and these locals are intrinsic CLR type long (Int64).&lt;/p&gt;  &lt;p&gt;Where does CLR hide these frame local long values?&lt;/p&gt;  &lt;p&gt;Using the sos extension I see !dso does not dump intrinsic locals.&lt;/p&gt;  &lt;p&gt;!clrstack, wow the output is completely wrong and bizarre.&lt;/p&gt;  &lt;p&gt;!dumpstack, !dumpstack -EE, broken.&lt;/p&gt;  &lt;p&gt;kP works, somewhat reasonably.&lt;/p&gt;  &lt;p&gt;Time to get ugly.&lt;/p&gt;  &lt;p&gt;Ok, I locate start of assembly for SqlInternalConnectionTds.LoginNoFailover in debugger and just dump the raw assembly.&lt;/p&gt;  &lt;p&gt;I know my variable is passed into function ADP.TimerRemainingMilliseconds, so my plan is to locate this call in unassembly and see how the assembly code packs the value passed to this function, this will give me a clue on where the value is held.&lt;/p&gt;  &lt;p&gt;I find it here:&lt;/p&gt;  &lt;p&gt;652e942f ff75d8&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; dword ptr [ebp-28h]   &lt;br /&gt;652e9432 ff75d4&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; push&amp;#160;&amp;#160;&amp;#160; dword ptr [ebp-2Ch]    &lt;br /&gt;652e9435 e8d2c3f3ff&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; call&amp;#160;&amp;#160;&amp;#160; System_Data_ni!System.Data.Common.ADP.TimerRemainingMilliseconds(Int64) (6522580c)&lt;/p&gt;  &lt;p&gt;Good, I see ebp-offset, this looks like stack local.&amp;#160; I use kvn to get frame number.&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; &lt;strong&gt;kvn&lt;/strong&gt; 10    &lt;br /&gt; # ChildEBP RetAddr&amp;#160; Args to Child&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;...    &lt;br /&gt;07 0021dd88 652e94cd 06bf6a58 06bf3f90 06bf67cc mscorwks!ThreadNative::Sleep+0xce (FPO: [Non-Fpo]) (CONV: fastcall) [f:\whidbeyrtmlhs\ndp\clr\src\vm\comsynchronizable.cpp @ 964]    &lt;br /&gt;&lt;strong&gt;08&lt;/strong&gt; 0021ddc8 652e9283 00000000 00000000 00000000 System_Data_ni!System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(System.String, System.String, Boolean, System.Data.SqlClient.SqlConnection, System.Data.SqlClient.SqlConnectionString, Int64)+0x215 (Managed) [f:\WhidbeyRTMlhs\ndp\fx\src\Data\System\Data\SqlClient\SqlInternalConnectionTds.cs @ 862]&lt;/p&gt;  &lt;p&gt;Set the frame:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; .frame 8   &lt;br /&gt;08 0021ddc8 652e9283 System_Data_ni!System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(System.String, System.String, Boolean, System.Data.SqlClient.SqlConnection, System.Data.SqlClient.SqlConnectionString, Int64)+0x215 [f:\WhidbeyRTMlhs\ndp\fx\src\Data\System\Data\SqlClient\SqlInternalConnectionTds.cs @ 862]&lt;/p&gt;  &lt;p&gt;I then look at registers for frame 8:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; r   &lt;br /&gt;Last set context:    &lt;br /&gt;eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=0021dc38 edi=00000000    &lt;br /&gt;eip=77520f34 esp=0021dbf4 ebp=&lt;strong&gt;0021dc5c&lt;/strong&gt; iopl=0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nv up ei pl nz na po nc    &lt;br /&gt;cs=001b&amp;#160; ss=0023&amp;#160; ds=0023&amp;#160; es=0023&amp;#160; fs=003b&amp;#160; gs=0000&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; efl=00200202    &lt;br /&gt;ntdll!KiFastSystemCallRet:    &lt;br /&gt;77520f34 c3&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ret&lt;/p&gt;  &lt;p&gt;Ok, then &lt;strong&gt;0021dc5c&lt;/strong&gt; -28 and &lt;strong&gt;0021dc5c&lt;/strong&gt; -2c should be the 2 DWORDs that compose my Int64 value:&lt;/p&gt;  &lt;p&gt;0:000&amp;gt; dd 0021dc5c-2c   &lt;br /&gt;0021dc30&amp;#160; &lt;strong&gt;76f16110 00000000&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;For real?&amp;#160; I am really not sure.&amp;#160; I'll try it on a live debug to be sure.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8561535" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Connection Pooling, ADO.NET, SPIDs</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/05/08/connection-pooling-ado-net-spids.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/05/08/connection-pooling-ado-net-spids.aspx</id><published>2008-05-09T01:53:54Z</published><updated>2008-05-09T01:53:54Z</updated><content type="html">&lt;p&gt;If you have pooling issues with ADO.NET (leaking connections, pool size exceeded, etc...) one way to slice and dice these with SQL 2005 is to use the SQL 2005 system DMVs.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You can locate leaked connections like so:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;select&lt;/span&gt; 
session_id, 
datediff(s,last_read,getdate()) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; SecondsSinceLastRead,
datediff(s,last_write,getdate()) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; SecondsSinceLastWrite,
(&lt;span style="color: #0000ff"&gt;select&lt;/span&gt; text &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; sys.dm_exec_sql_text(&lt;span style="color: #0000ff"&gt;dec&lt;/span&gt;.most_recent_sql_handle)) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; LastSqlStatment
&lt;span style="color: #0000ff"&gt;from&lt;/span&gt; sys.dm_exec_connections dec&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The idea being if the connection is properly pooled then last_read and last_write should always be active.&amp;#160; Leaked connections will go into garbage collector and sit there for a while still open but not reading and writing.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Next suppose you find leaked ones, how can you correlate these with client code?&amp;#160; Here is one way:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
  &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;select&lt;/span&gt; 
session_id &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Spid, 
(&lt;span style="color: #0000ff"&gt;select&lt;/span&gt; login_name &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; sys.dm_exec_sessions &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; session_id=&lt;span style="color: #0000ff"&gt;dec&lt;/span&gt;.session_id) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; UserName,
datediff(s,last_read,getdate()) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; SecondsSinceLastRead,
datediff(s,last_write,getdate()) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; SecondsSinceLastWrite,
text &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; LastSqlStatment
&lt;span style="color: #0000ff"&gt;from&lt;/span&gt; sys.dm_exec_connections &lt;span style="color: #0000ff"&gt;dec&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;cross&lt;/span&gt; apply sys.dm_exec_sql_text(&lt;span style="color: #0000ff"&gt;dec&lt;/span&gt;.most_recent_sql_handle)&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This will dump out each SPID and also the last TSQL statement to run on the SPID.&amp;#160; Then search your source code for the TSQL to locate which part of your code leaked the connection.&amp;#160; Not a perfect solution but should get you pretty close.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Suppose you are really stumped and cannot correlate the TSQL.&amp;#160;&amp;#160; You can get a full memory dump of the client process (I'm assuming like an ASP.NET application here) and then dig through this using the sos debugger extension.&amp;#160; I'll post on this later.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8475248" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Debugging .NET Code</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/04/22/debugging-net-code.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/04/22/debugging-net-code.aspx</id><published>2008-04-23T06:32:00Z</published><updated>2008-04-23T06:32:00Z</updated><content type="html">&lt;p&gt;Some days I wonder how customers debug .NET code.&lt;/p&gt;  &lt;p&gt;I've been debugging CLR for many years using a mix of techniques (VS.NET debugger and Windbg and logging of course).&amp;#160; To be honest I hate debugging in VS.NET, the debugger just annoys me to no end except for very simple debugging scenarios.&amp;#160; Once you go Windbg it is hard to go back.&lt;/p&gt;  &lt;p&gt;But Windbg and CLR debugging are not a match made in heaven.&amp;#160; They work together like Frankenstein's monster and the angry mob work together.&lt;/p&gt;  &lt;p&gt;Today I am debugging System.Data.SqlClient and transaction behavior inside CLR stored procedures and TDS protocol.&lt;/p&gt;  &lt;p&gt;I know that transaction state flows over TDS protocol using a combination of TDS ENVCHANGE tokens (server-&amp;gt;client) plus TDS mars header (client -&amp;gt; server).&lt;/p&gt;  &lt;p&gt;What I see is proper setup of transaction state here:&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;- Tds: Response from server, Version=7.2    &lt;br /&gt;&amp;#160; + TDSHeaderFirst: 0x1    &lt;br /&gt;&amp;#160; - TDSServerResponseData:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TokenType: ENVCHANGE    &lt;br /&gt;&amp;#160;&amp;#160; - TokenData:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Length: 11 (0xB)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnvChangeType: Begin Transaction    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NewValueLength: 8 (0x8)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NewValue: 223338299393 (&lt;strong&gt;0x3400000001&lt;/strong&gt;)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OldValueLength: 0 (0x0)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TokenType: DONE    &lt;br /&gt;&amp;#160;&amp;#160; + TokenData: &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;0x3400000001&lt;/strong&gt; is my transaction id (descriptor).&amp;#160; I see it going out on the next request:&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;- Tds: Query, Version=7.2    &lt;br /&gt;&amp;#160; + TDSHeaderFirst: 0x1    &lt;br /&gt;&amp;#160; - SqlBatchData:     &lt;br /&gt;&amp;#160;&amp;#160; - AllHeadersData:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TotalLength: 22 (0x16)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HeaderLength: 18 (0x12)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HeaderType: MARS Header    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TransactionDescriptor: 223338299393 (&lt;strong&gt;0x3400000001&lt;/strong&gt;)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OutstandingRequestCount: 1 (0x1)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SQLText: exec ClrProc2 N'123'&lt;/p&gt;  &lt;p&gt;Next my CLR sproc inserts data into a table which in turn fires a trigger which in turn rolls back the transaction -&amp;gt;&lt;/p&gt;  &lt;p&gt;create trigger trig1 on t1 for insert, update as   &lt;br /&gt;begin    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; insert t2 (f1) values (1)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; select * from t2    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; rollback tran    &lt;br /&gt;end&lt;/p&gt;  &lt;p&gt;It is not recommended to do this in a trigger of course!&amp;#160; This is only my little test to see TDS protocol behavior.&amp;#160; The CLR sproc is supposed to surpress TDS tokens for internally run commands, which is a nice feature.&amp;#160; But how does it do this and keep transaction state consistent with client?&amp;#160; I expected it to send back a rollback transaction state ENVCHANGE.&amp;#160; I don't see it over the wire.&lt;/p&gt;  &lt;p&gt;I do see an ERROR token of state 16 coming back and I suspect this is telling SqlClient to reset transaction state.&lt;/p&gt;  &lt;p&gt;Ok, back to debugging CLR.&amp;#160; I need to know when this TDS response comes back, how it resets the transaction internal state of SqlClient.&amp;#160; I know little to nothing about the internals of how it works, but need to figure it out and debug it quickly without wasting time.&amp;#160; Via some digging I found this _currentTransaction was getting set and reset when the ENVCHANGEs come in.&lt;/p&gt;  &lt;p&gt;Now, how do I set a breakpoint on the change of _currentTransaction in VS.NET debugger?&lt;/p&gt;  &lt;p&gt;Let the fun begin.&lt;/p&gt;  &lt;p&gt;First, note that I have a debug version of SqlClient that I just freshly built out of my enlistment and shoved into the GAC.&amp;#160; This is one important way to please the temperamental gremlin living inside VS.NET debugger.&amp;#160; Ok, crank up debugger.&lt;/p&gt;  &lt;p&gt;Ok, get to my code, try to step into SqlCommand.ExecuteNonQuery.&amp;#160;&amp;#160; Debugger does not step into it.&lt;/p&gt;  &lt;p&gt;Tools | Options... Debugging | General-&amp;gt; &amp;quot;Enable Just My Code&amp;quot; checkbox is clear.&amp;#160; Why does it not step in?&lt;/p&gt;  &lt;p&gt;Ok, the gremlin does not like my System.Data.dll.&amp;#160; VS.NET cannot find the symbols for a dll I just build on my local machine.&amp;#160; The trick to fix this is to place the symbols right next to the dll so that the debugger does not have to look too hard for symbols. Or you can modify symbol path in VS.NET.&amp;#160; I choose to place symbols next to dll, the reload symbols from module window.&lt;/p&gt;  &lt;p&gt;Cool, got it working.&amp;#160; Now how do I set a bp on change of _currentTransaction?&amp;#160; This seems to be the tricky part in CLR.&amp;#160; In Windbg I would locate address of _currentTransaction and set a ba w4 &amp;lt;address&amp;gt; on it and call it a day.&amp;#160; In CLR there is no equivalent as far as I can tell.&amp;#160; Yes, I suppose I can manually set breakpoints on every method of the class that _currentTransaction uses in hopes that the methods are used but this is difficult to do in CLR as well (in Windbg I can set breakpoint on all class methods using a wildcard in one command).&amp;#160; It is time to go beg the VS.NET debugger gurus to see if they can help me.&lt;/p&gt;  &lt;p&gt;Not yet.&amp;#160; Let me try this VS.NET 2008 immediate window, I have been meaning to give it a try.&lt;/p&gt;  &lt;p&gt;!help   &lt;br /&gt;'!help': not available while Managed only debugging.&lt;/p&gt;  &lt;p&gt;Arg.&amp;#160; I found a few basic commands that work, but most Windbg commands don't work:&lt;/p&gt;  &lt;p&gt;?_currentTransaction   &lt;br /&gt;null    &lt;br /&gt;?poi(_currentTransaction)    &lt;br /&gt;The name 'poi' does not exist in the current context&lt;/p&gt;  &lt;p&gt;Ok, I give up for now. I talked to CLR folks and they indicated VS.NET does not have data breakpoints for managed code yet.&amp;#160; Bummer.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8417900" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Writing CLR Stored Procedures</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/04/22/writing-clr-stored-procedures.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/04/22/writing-clr-stored-procedures.aspx</id><published>2008-04-22T23:08:12Z</published><updated>2008-04-22T23:08:12Z</updated><content type="html">&lt;p&gt;I'm trying to write some CLR sprocs to test out the TDS behavior of CLR sprocs versus T-SQL sprocs for TDS protocol documentation purposes.&amp;#160; If you are not aware, we now have the TDS protocol spec on MSDN for your bedtime reading:&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/cc448435.aspx"&gt;http://msdn2.microsoft.com/en-us/library/cc448435.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Note I'm also finishing up a full blown netmon parser for TDS as part of the protocol documentation effort.&amp;#160; To ensure this works well I'm investigating the dusty corners of TDS protocol stream behavior to ensure we have it properly spec' d and my parser works too.&lt;/p&gt;  &lt;p&gt;On to CLR sprocs topic.&amp;#160; First thing I did was crank up VS.NET 2008 and try to create a database project so I can upload some test CLR sprocs.&amp;#160; It doesn't work because VS.NET 2008 is smart and detects the target SQL Server is 2008 and not 2005 so it refuses to co-operate and create a nice little CLR project for me.&amp;#160; I suppose I could use a 2005 server but I'm lazy.&lt;/p&gt;  &lt;p&gt;No worries, I know how to manually upload CLR sprocs with all the magic T-SQL incantations.&lt;/p&gt;  &lt;p&gt;Next I do this:&lt;/p&gt;  &lt;p&gt;create assembly ClrTestJunkAssembly from N'C:\Project\ADONet\TranStress\bin\Debug\TranStress.exe' WITH PERMISSION_SET=SAFE    &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 10301, Level 16, State 1, Line 1      &lt;br /&gt;Assembly 'TranStress' references assembly 'system.enterpriseservices, version=2.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a.', which is not present in the current database. SQL Server attempted to locate and automatically load the referenced assembly from the same location where referring assembly came from, but that operation has failed (reason: 2(The system cannot find the file specified.)). Please load the referenced assembly into the current database and retry your request.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Note yes I am really really lazy and don't want to create a separate clean library project with my CLR stored proc in it.&amp;#160; I just want to upload my test client exe that also just happens to have the sproc class in it and get on with my life.&amp;#160; My other non-sproc test code happens to ref System.EnterpriseServices.&amp;#160; Arg.&lt;/p&gt;  &lt;p&gt;Can I just shovel EnterpriseServices in?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;create assembly EnterpriseServicesAssemblyForSQLServerWhoIsTooLazyToLookInGac from N'e:\WINNT\Microsoft.NET\Framework\v2.0.50727\System.EnterpriseServices.dll' WITH PERMISSION_SET=EXTERNAL_ACCESS      &lt;br /&gt;go&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;font color="#000000"&gt;Warning: The Microsoft .Net frameworks assembly 'system.enterpriseservices, version=2.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a, processorarchitecture=x86.' you are registering is not fully tested in SQL Server hosted environment.        &lt;br /&gt;Warning: The Microsoft .Net frameworks assembly 'system.directoryservices, version=2.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a, processorarchitecture=msil.' you are registering is not fully tested in SQL Server hosted environment.         &lt;br /&gt;&lt;/font&gt;Msg 6218, Level 16, State 2, Line 1       &lt;br /&gt;CREATE ASSEMBLY for assembly 'System.EnterpriseServices' failed because assembly 'System.DirectoryServices' failed verification. Check if the referenced assemblies are up-to-date and trusted (for external_access or unsafe) to execute in the database. CLR Verifier error messages if any will follow this message       &lt;br /&gt;[ : System.DirectoryServices.DirectorySearcher::SetSearchPreferences][mdToken=0x60000f8][offset 0x0000050E][found address of value 'System.DirectoryServices.Interop.AdsSortKey'] Expected numeric type on the stack.       &lt;br /&gt;[ : System.DirectoryServices.SearchResultCollection::RetrieveDirectorySynchronizationCookie][mdToken=0x60001c6][offset 0x00000023][found address of value 'System.DirectoryServices.Interop.AdsSearchColumn'] Expected numeric type on the stack.       &lt;br /&gt;[ : System.DirectoryServices.SearchResultCollection::RetrieveVLVResponse][mdToken=0x60001c7][offset 0x00000023][found address of value 'System.DirectoryServices.Interop.AdsSearchColumn'] Expected numeric type on the stack.       &lt;br /&gt;[ : System.DirectoryServices.SearchResultCollection+ResultsEnumerator::GetCurrentResult][mdToken=0x60001d4][offset 0x00000033][found address of Native Int] Expected numeric type on the stack.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Arg,&amp;#160; you don't have to tell me everything twice, work with me brother.&amp;#160; Ok, I didn't like System.EnterpriseServices anyway, it was highly over-rated, so I removed it from my other code (I wasn't using it anymore anyway).&lt;/p&gt;  &lt;p&gt;create assembly ClrTestJunkAssembly from N'C:\Project\ADONet\TranStress\bin\Debug\TranStress.exe' WITH PERMISSION_SET=SAFE    &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6212, Level 16, State 1, Line 1      &lt;br /&gt;CREATE ASSEMBLY failed because method 'Main' on type 'TranStress.Program'&amp;#160; in safe assembly 'TranStress' is storing to a static field. Storing to a static field is not allowed in safe assemblies.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ok, ok, SQL, I know this game.&amp;#160; I'm starting to get offended.&lt;/p&gt;  &lt;p&gt;create assembly ClrTestJunkAssembly from N'C:\Project\ADONet\TranStress\bin\Debug\TranStress.exe' WITH PERMISSION_SET=UNSAFE    &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 10327, Level 14, State 1, Line 1      &lt;br /&gt;CREATE ASSEMBLY for assembly 'TranStress' failed because assembly 'TranStress' is not authorized for PERMISSION_SET = UNSAFE.&amp;#160; The assembly is authorized when either of the following is true: the database owner (DBO) has UNSAFE ASSEMBLY permission and the database has the TRUSTWORTHY database property on; or the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ok, let me try this but it makes me feel strange:&lt;/p&gt;  &lt;p&gt;alter database transtress set trustworthy on    &lt;br /&gt;go     &lt;br /&gt;create assembly ClrTestJunkAssembly from N'C:\Project\ADONet\TranStress\bin\Debug\TranStress.exe' WITH PERMISSION_SET=UNSAFE     &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Ahh!&amp;#160; Now that was easy.&amp;#160; Next, I have to expose my function as a stored proc.&amp;#160; I created my CLR proc like so:&lt;/p&gt;  &lt;p&gt;class CLRTestJunk    &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Microsoft.SqlServer.Server.SqlProcedure]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public static void ClrProc1(string param1)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; using(SqlConnection conn = new SqlConnection(&amp;quot;Context Connection=true;&amp;quot;))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; conn.Open();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; using (SqlCommand cmd = conn.CreateCommand())     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int v = -1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int.TryParse(param1, out v);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters.Add(&amp;quot;@p1&amp;quot;, SqlDbType.Int);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.Parameters[0].Value = v;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.CommandText = &amp;quot;insert t1 (f1) values (@p1)&amp;quot;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cmd.ExecuteNonQuery();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;Next I run this:&lt;/p&gt;  &lt;p&gt;create procedure ClrProc1 as external name ClrTestJunkAssembly.CLRTestJunk.ClrProc1    &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6505, Level 16, State 2, Procedure ClrProc1, Line 1      &lt;br /&gt;Could not find Type 'CLRTestJunk' in assembly 'TranStress'.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ok, now what?&amp;#160; I crank up reflector to see if it's there, yes it's there.&lt;/p&gt;  &lt;p&gt;Maybe because I forgot to add the param:&lt;/p&gt;  &lt;p&gt;create procedure ClrProc1(@param1 varchar(max)) as external name ClrTestJunkAssembly.CLRTestJunk.ClrProc1    &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6505, Level 16, State 2, Procedure ClrProc1, Line 1      &lt;br /&gt;Could not find Type 'CLRTestJunk' in assembly 'TranStress'.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;No. no. no.&amp;#160; I'm not beaten yet.&amp;#160; Go search around web for 6505, try this:&lt;/p&gt; create procedure ClrProc1(@param1 varchar(max)) as external name [TranStress.ClrTestJunkAssembly].CLRTestJunk.ClrProc1   &lt;br /&gt;go  &lt;p&gt;No dice.&amp;#160; Ok SQL CLR, you win, I strip out a separate library class with my code.&amp;#160; Same problem:&lt;/p&gt;  &lt;p&gt;create assembly ClrClassLibraryAssembly from N'C:\Project\ADONet\ClrClassLibrary\bin\Debug\ClrClassLibrary.dll' WITH PERMISSION_SET=SAFE   &lt;br /&gt;go    &lt;br /&gt;create procedure ClrProc1 as EXTERNAL NAME ClrClassLibraryAssembly.ClrClassLibrary.ClrProc1    &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6505, Level 16, State 2, Procedure ClrProc1, Line 1     &lt;br /&gt;Could not find Type 'ClrClassLibrary' in assembly 'ClrClassLibrary'.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ok, SQL CLR you are making me feel stupid, I thought I was a kick butt dba until today, now you are just mocking me, thanks a ton.&amp;#160; I found another newsgroup entry that gave me an idea:&lt;/p&gt;  &lt;p&gt;create procedure ClrProc1 as EXTERNAL NAME ClrClassLibraryAssembly.[ClrClassLibrary.ClrClassLibrary].ClrProc1   &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6576, Level 16, State 4, Procedure ClrProc1, Line 1     &lt;br /&gt;Type 'ClrClassLibrary.ClrClassLibrary' in assembly 'ClrClassLibrary' is not public.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ohhh!&amp;#160; I am getting closer.&amp;#160; Here is my class now for reference:&lt;/p&gt;  &lt;p&gt;namespace ClrClassLibrary   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; class ClrClassLibrary    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Microsoft.SqlServer.Server.SqlProcedure]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public static void ClrProc1(string param1)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;  &lt;p&gt;To reference this in SQL Server I have to say ClrClassLibraryAssembly.[ClrClassLibrary.ClrClassLibrary].ClrProc1, not bloody intuitive but ok, I can guess why we did it this way (SQL Server's 4 part naming convention probably won out over CLR).&lt;/p&gt;  &lt;p&gt;Ok, make my class public and away I go:&lt;/p&gt;  &lt;p&gt;create procedure ClrProc1 as EXTERNAL NAME ClrClassLibraryAssembly.[ClrClassLibrary.ClrClassLibrary].ClrProc1   &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6550, Level 16, State 2, Procedure ClrProc1, Line 1     &lt;br /&gt;CREATE PROCEDURE failed because parameter counts do not match.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ok, I forgot to add back my param:&lt;/p&gt;  &lt;p&gt;create procedure ClrProc1(@param1 varchar(max)) as EXTERNAL NAME ClrClassLibraryAssembly.[ClrClassLibrary.ClrClassLibrary].ClrProc1   &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6552, Level 16, State 3, Procedure ClrProc1, Line 1     &lt;br /&gt;CREATE PROCEDURE for &amp;quot;ClrProc1&amp;quot; failed because T-SQL and CLR types for parameter &amp;quot;@param1&amp;quot; do not match.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ok, I think I have performed full code coverage for all CLR error messages by now, one more try, the winner is:&lt;/p&gt;  &lt;p&gt;create procedure ClrProc1(@param1 nvarchar(max)) as EXTERNAL NAME ClrClassLibraryAssembly.[ClrClassLibrary.ClrClassLibrary].ClrProc1   &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;Yes!&amp;#160; Now to call my CLR stored procedure:&lt;/p&gt;  &lt;p&gt;exec ClrProc1 N'123'&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Msg 6263, Level 16, State 1, Line 1     &lt;br /&gt;Execution of user code in the .NET Framework is disabled. Enable &amp;quot;clr enabled&amp;quot; configuration option.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Whoops.&amp;#160; Ok, need to enable CLR:&lt;/p&gt;  &lt;p&gt;sp_configure 'clr enabled',1   &lt;br /&gt;go    &lt;br /&gt;reconfigure with override    &lt;br /&gt;go&lt;/p&gt;  &lt;p&gt;Ok, one more time:&lt;/p&gt;  &lt;p&gt;exec ClrProc1 N'123'&lt;/p&gt;  &lt;p&gt;Works!&amp;#160; Looks like VS.NET does quite a bit of nasty CLR grunt work for me.&amp;#160; But overall what have we learned about CLR stored procedures?&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Make sure your class is public.&lt;/li&gt;    &lt;li&gt;Avoid references to CLR modules like System.EnterpriseServices, try to keep your code as reference free as possible.&lt;/li&gt;    &lt;li&gt;Avoid namespaces.&lt;/li&gt;    &lt;li&gt;Ensure you enable CLR on the server.&lt;/li&gt;    &lt;li&gt;Probably best to have it in it's own class library to keep things as simple as possible.&lt;/li&gt;    &lt;li&gt;Don't change versions of SQL Server or VS.NET will no longer work.&lt;/li&gt;    &lt;li&gt;Always learn how to do it using T-SQL versus rely on VS.NET if you want it to work anyway.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;You can always sniff the TSQL that VS.NET uses to configure your CLR sproc using SQL Profiler and save this.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8417162" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Why does Windows Always Want To Hide Things From Me?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/04/15/why-does-windows-always-want-to-hide-things-from-me.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/04/15/why-does-windows-always-want-to-hide-things-from-me.aspx</id><published>2008-04-16T06:10:53Z</published><updated>2008-04-16T06:10:53Z</updated><content type="html">&lt;p&gt;Over the years, I find more and more of the Windows UI is designed to hide things like where the files are coming from, file extensions, etc... from me. Why is this?&amp;#160; I want to see this stuff.&amp;#160; &lt;/p&gt;  &lt;p&gt;For example, why can't I get the full path to a file easily?&amp;#160; I have to open Run box, then drag and drop file into the Run box, then select file name, then copy it, then go paste it where I need it.&amp;#160;&amp;#160; I've probably done this a million times in my life.&lt;/p&gt;  &lt;p&gt;I found in Vista recently that drag+drop to a console window no longer works, I was heart broken, this saves me tons of time.&amp;#160; But I found a cool feature in Vista that makes up for it.&lt;/p&gt;  &lt;p&gt;Hold down shift key and right-click on file and you will see a few new options on the menu bar.&amp;#160; See the Copy as Path below, this is the one you want.&amp;#160; Saves you having to pop the Run menu, very nice!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/WhydoesWindowsAlwaysWantToHideThingsFrom_11BC4/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="284" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/WhydoesWindowsAlwaysWantToHideThingsFrom_11BC4/image_thumb.png" width="167" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Hey, I was excited. :)&lt;/p&gt;  &lt;p&gt;I found on Vista that whenever I had a networking problem, the Vista UI was trying very hard to hide all networking information from me.&amp;#160; The best it can muster is this insult to my networking abilities:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/WhydoesWindowsAlwaysWantToHideThingsFrom_11BC4/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="133" alt="image" src="http://blogs.msdn.com/blogfiles/mattn/WindowsLiveWriter/WhydoesWindowsAlwaysWantToHideThingsFrom_11BC4/image_thumb_1.png" width="453" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Why? This is all you have for me Vista, I ask?&amp;#160; I want to see random Matrix like diagnostic spew and perl scripts scrolling across the screen like in the Hollywood movies.&amp;#160; This will tell me Vista is doing something purposeful.&amp;#160; Maybe next version.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8398565" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>High Performance Help In VS.NET 2008</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/03/28/high-performance-help-in-vs-net-2008.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/03/28/high-performance-help-in-vs-net-2008.aspx</id><published>2008-03-28T10:05:46Z</published><updated>2008-03-28T10:05:46Z</updated><content type="html">&lt;p&gt;Don't know about you, but some days I'm so busy I don't have time to wait while VS.NET spawns dexplore.exe over DCOM and makes bunch of SOAP calls to MSDN to then find the MSDN url to pop context sensitive help for a keyword (yes I debugged it).&amp;#160; Don't get me started about updating help topics please wait 5 minutes.&lt;/p&gt;  &lt;p&gt;I don't need more proof VS.NET help thinks Moore's Law is a challenge one should take very seriously.&lt;/p&gt;  &lt;p&gt;Hence I wrote this VS.NET macro to speed things up for me.&amp;#160; Assigned keyboard Alt-F1 to fire off this ReallyFastHelp macro below.&lt;/p&gt;  &lt;p&gt;Ok, agreed it's a bit primitive, I haven't written any VB.NET code in years, but it get's the job done.&amp;#160; Feel free to spruce it up.&amp;#160; The cool thing is it automagically opens a new tab in IE7 for me each time I shell it, leaving a nice tab for each search.&amp;#160; Now if I can just figure out how to make VS.NET 2008 remember my keyboard shortcuts after I close and re-open it.&amp;#160; Grrrr.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;Imports System     &lt;br /&gt;Imports EnvDTE      &lt;br /&gt;Imports EnvDTE80      &lt;br /&gt;Imports EnvDTE90      &lt;br /&gt;Imports System.Diagnostics &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;Public Module Module1     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Sub ReallyFastHelp()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim selection As String      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim shellObject As Object      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim shellUrl As String &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; selection = DTE.ActiveDocument.Selection.Text     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If String.IsNullOrEmpty(selection) Then      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; shellUrl = &amp;quot;&lt;/font&gt;&lt;a href="http://msdn.microsoft.com""&gt;&lt;font face="Courier New" size="2"&gt;http://msdn.microsoft.com&amp;quot;&lt;/font&gt;&lt;/a&gt;    &lt;br /&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Else     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; selection = Uri.EscapeUriString(selection)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; shellUrl = &amp;quot;&lt;/font&gt;&lt;a href="http://search.live.com/results.aspx?q=""&gt;&lt;font face="Courier New" size="2"&gt;http://search.live.com/results.aspx?q=&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New" size="2"&gt; &amp;amp; selection     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; End If &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim psi As ProcessStartInfo     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dim startInfo As New System.Diagnostics.ProcessStartInfo(shellUrl)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Diagnostics.Process.Start(startInfo) &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&amp;#160;&amp;#160; End Sub     &lt;br /&gt;End Module&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8341159" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>MacGruber Transactions</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2008/03/26/macgruber-transactions.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2008/03/26/macgruber-transactions.aspx</id><published>2008-03-26T11:03:23Z</published><updated>2008-03-26T11:03:23Z</updated><content type="html">&lt;p&gt;Found an interesting bit of code on the newsgroups the other day .... what I like to call &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PageIndex=1&amp;amp;SiteID=1&amp;amp;PageID=1&amp;amp;PostID=3055387"&gt;MacGruber&lt;/a&gt; transactions.&amp;#160; If you are a fan of SNL you know the story.&lt;/p&gt;  &lt;p&gt;With System.Data.SqlClient.SqlConnection in .NET 2.0 we added a new connection string attribute named &amp;quot;Transaction Binding&amp;quot; to alter the behavior of how SqlConnection interacts with System.Transaction.&lt;/p&gt;  &lt;p&gt;One might believe a transaction always spans a TransactionScope block, this is technically true but the transaction can rollback at any point inside the block.&amp;#160; The transaction is still there but it's state has changed.&lt;/p&gt;  &lt;p&gt;With SqlClient our default behavior is to use Transaction Binding=Implicit Unbind which means we auto unbind from the transaction scope if the transaction rolls back and switch back to standard SQL auto-commit mode.&lt;/p&gt;  &lt;p&gt;Hence work inside the TransactionScope could be half rolled back and half committed if for example the transaction times out half way through the code block.&amp;#160; I recommend using Transaction Binding=Explicit Unbind since this gives you deterministic behavior.&amp;#160; We are thinking about changing the default to this in future releases of System.Data.SqlClient driver let me know what you think.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8337420" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Easy Way To Debug SSL Issues With Web Services (Including SQL Server 2005 SOAP Endpoints)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2006/03/13/550559.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2006/03/13/550559.aspx</id><published>2006-03-13T20:08:00Z</published><updated>2006-03-13T20:08:00Z</updated><content type="html">&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;Here is a nice easy way to debug SSL issue with Windows 2003 that I discovered while working on SOAP projects.&amp;nbsp; I think this works on XP SP2&amp;nbsp;as well have not tested this.&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;1. Create batch file c:\ssltrace.cmd with following contents:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;logman start http_ssl_trace -pf c:\guids.txt -o out.etl -ets&lt;BR&gt;pause&lt;BR&gt;logman stop http_ssl_trace -ets&lt;BR&gt;tracerpt /y out.etl&lt;BR&gt;notepad dumpfile.csv&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;2. Create file c:\guids.txt with following contents:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;{1fbecc45-c060-4e7c-8a0e-0dbd6116181b} 0x000000FF&amp;nbsp; 5&amp;nbsp;&amp;nbsp; IIS: SSL Filter&lt;BR&gt;{dd5ef90a-6398-47a4-ad34-4dcecdef795f} 0x000000FF&amp;nbsp; 5&amp;nbsp;&amp;nbsp; HTTP Service Trace&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;3. On the web service machine run c:\ssltrace.cmd to start tracing, then hit your web service with your POST.&amp;nbsp; Once you are finished testing press the spacebar to in the ssltrace.cmd command window to stop tracing and display the trace file.&amp;nbsp; You should see everything coming in and going out along with error codes, etc...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;If you are even more ambitious and want to see the innards of NTLM and Kerberos and LSA chatter, add this to guids.txt -&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;{C92CF544-91B3-4dc0-8E11-C580339A0BF8} 0x000000FF&amp;nbsp; 5&amp;nbsp;&amp;nbsp; NTLM Security Protocol&lt;BR&gt;{cc85922f-db41-11d2-9244-006008269001} 0x000000FF&amp;nbsp; 5&amp;nbsp;&amp;nbsp; Local Security Authority (LSA)&lt;BR&gt;{bba3add2-c229-4cdb-ae2b-57eb6966b0c4} 0x000000FF&amp;nbsp; 5&amp;nbsp;&amp;nbsp; Active Directory: Kerberos&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=550559" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Debugging SQL Connectivity 101</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/mattn/archive/2006/02/24/539088.aspx" /><id>http://blogs.msdn.com/b/mattn/archive/2006/02/24/539088.aspx</id><published>2006-02-25T10:40:00Z</published><updated>2006-02-25T10:40:00Z</updated><content type="html">&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;Note to self:&amp;nbsp; Things to remember to check next time I can't connect to SQL...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;1. Is SQL started?&amp;nbsp; Yes.&amp;nbsp; Is the instance I'm trying to connect to started?&amp;nbsp; Yes.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;2. Run netstat -aon on sql box, do I see something bound to 1433 or say my instance port 5555?&amp;nbsp; For example do I see 0.0.0.0:1433 bound? Does the pid match with pid for SQL Server?&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;3. If I run &amp;gt;&amp;nbsp;telnet servername 1433 &amp;lt;, does this connect?&amp;nbsp; I usually try this one first it is easy and tells you if you have a firewall problem right away.&amp;nbsp; Oh Windows Firewall, you have made my life in SQL Protocols such fun.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;4. Try the osql connection test using hard coded protocol and&amp;nbsp;port:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;osql -E -Stcp:mysql,5555&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;5. Hey, try the admin port, does this work?&amp;nbsp;&amp;nbsp; Why does admin port not work with osql?&amp;nbsp; We call this progress my friend.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;sqlcmd -E -Sadmin:127.0.0.1&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;6. Maybe I have a machine with IPv6?&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sqlcmd -E -Sadmin:::1&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;Not even sure if this works, but ::1 is loopback for ipv6, good to know.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;7. Did I check SQL SAC?&amp;nbsp;&amp;nbsp; The SQL Server Surface Area Configuration tool can totally block remote connectivity, go check it.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;8. Is the SQL Browser service started?&amp;nbsp; Run -&amp;gt; net start sqlbrowser.&amp;nbsp; This service helps the client locate the proper port for named instances.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;9. Did I change the port for my default instance from 1433 to something else?&amp;nbsp; Client is not smart enough to figure this out sometimes.&amp;nbsp; Check the ERRORLOG and see what port SQL is binding to.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;10. Is IPSec services enabled?&amp;nbsp; This can break connectivity within a domain.&amp;nbsp; Run -&amp;gt;&amp;nbsp;net start policyagent.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;11. Check SQL Server Configuration Manager and determine what ports you are really binding to.&amp;nbsp; Please forgive us for the funky GUI here, I agree it is confusing.&amp;nbsp; Read it carefully is my best advice.&amp;nbsp; I find it easier to look at the ERRORLOG to be honest that this GUI.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;12. Am&amp;nbsp;I using a clustered instance of SQL?&amp;nbsp; With clustered SQL, the only thing that might throw you off is that you can connect to the&amp;nbsp;virtual ip as well as locally bound ips.&amp;nbsp; It can get confusing.&amp;nbsp; Avoid the local ips and use the clustered ips you see in Cluster Admistrator.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;13. Did someone install a virus scanner on your SQL box recently?&amp;nbsp; Maybe it decided to block SQL from talking to the internet by blocking all sockets.&amp;nbsp; Oh yes I've seen this many times.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;14. Running any unusual xprocs in SQL lately?&amp;nbsp; I have seen xprocs close our socket handles in the past, CloseHandle is a dangerous API, it does not preclude you from putting in some random value that is somebody else's handle.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;15. Rootkits.&amp;nbsp; Did you know that a rootkit can piggyback the same ports you use for normal applications such as IIS and SQL and use these ports while you are also using these ports for normal activities?&amp;nbsp; And everything works fine for both your app and the rootkit? &amp;nbsp;This is exceedingly rare however, but does make a good case for regular network sniffing and intrusion checking.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;I'm sure I can think of more of these, later!&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=539088" width="1" height="1"&gt;</content><author><name>Matt Neerincx [MSFT]</name><uri>http://blogs.msdn.com/MattN/ProfileUrlRedirect.ashx</uri></author></entry></feed>