<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fooling Around &#187; windows</title>
	<atom:link href="http://alax.info/blog/tag/windows/feed" rel="self" type="application/rss+xml" />
	<link>http://alax.info/blog</link>
	<description>// Software Production Line</description>
	<lastBuildDate>Wed, 02 May 2012 15:42:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Common Controls: Versions, Compatibility, WTL</title>
		<link>http://alax.info/blog/1306</link>
		<comments>http://alax.info/blog/1306#comments</comments>
		<pubDate>Sun, 30 Oct 2011 19:55:52 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[WTL]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[compatibility]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=1306</guid>
		<description><![CDATA[<a href="http://alax.info/blog/1306" title="Common Controls: Versions, Compatibility, WTL"></a>An application appears to be not working in Windows XP in a weird way: rebar control appeared to fail showing up. Where the application is expected to look much nicer with rebar control as a container for menu (implemented as &#8230;<p class="read-more"><a href="http://alax.info/blog/1306">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/1306" title="Common Controls: Versions, Compatibility, WTL"></a><p>An application appears to be not working in Windows XP in a weird way: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb774373%28v=vs.85%29.aspx">rebar control</a> appeared to fail showing up.</p>
<p><img class="alignnone size-full wp-image-1310" title="Rebar Failed" src="http://alax.info/blog/wp-content/uploads/2011/10/Image003.png" alt="" width="640" height="238" /></p>
<p>Where the application is expected to look much nicer with rebar control as a container for menu (implemented as command bar WTL control) and toolbar with buttons:</p>
<p><img class="alignnone size-full wp-image-1309" title="Rebar Succeeded" src="http://alax.info/blog/wp-content/uploads/2011/10/Image0022.png" alt="" width="640" height="238" /></p>
<p>A WTL sample project generated by a Visual Studio wizard would never give such effect, and the bug was a combination of factors:</p>
<ol>
<li>An application built with a newer version of Windows SDK, which includes support for features (Windows Vista+ Common Controls) that are more recent than production environment (Windows XP); the application targets to Windows Vista+ environment too (<em>_WIN32_WINNT</em> &gt;= <em>0&#215;0600</em>)</li>
<li>Compatibility issues of Common Controls library</li>
<li>WTL version (7.5), which did not yet include a workaround for the problem</li>
</ol>
<p>The problem, which caused the bug directly was the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb774393%28v=vs.85%29.aspx">REBARBANDINFO structure</a> and its use as an argument with Common Controls API. As MSDN shows, the structure was amended twice with additional fields.</p>
<p>One of the way to support multiple versions of the structure definition, and to resolve compatibility issues, is to embed structure size into structure payload. In fact, <em>REBARBANDINFO::cbSize</em> member is there exactly for this reason.</p>
<p>The application is normally filling <em>cbSize</em> with the maximal known structure size and fills the rest of the fields respectively. The API is expected to be checking <em>cbSize</em> member and be detecting API version compatibility scenarios:</p>
<ol>
<li><em>cbSize</em> holds exactly the value the API expects (that is, the maximal value known/defined to the API) &#8211; the simplest scenario where the API and the application are on the same page, both are using the same versions of the &#8220;protocol&#8221;/interface.</li>
<li><em>cbSize</em> is smaller than API can support &#8211; the API sees that it is dealing with a sort of legacy application which cannot utilize all available features, and the API acts respectively supporting the older part of the protocol, and keeping defaults or &#8220;old look&#8221; for the rest of implementation. This addresses backward compatibility: the newer API works with apps designed for older version of the API</li>
<li><em>cbSize</em> is greater then API can support &#8211; the API sees that the application is already aware of newer version API and is possibly requesting some of the missing features. The API might be ignoring the unsupported part in assumption that API evolution tool place keeping some compatibility in mind, and still do the best it can with the existing implementation. Or, the API might just fail to work.</li>
</ol>
<p>The latter item #3 is the scenario here with rebar control. The application is using Windows Vista version of <em>REBARBANDINFO</em> structure and Windows XP implementation choses to completely fail.</p>
<p>While it does not seem to be directly a bug, this attitude is definitely not developer friendly: there is no reason for the control to not work in its best and default way. Having API acting this way, each developer using the API needs to take care of the situation explicitly: whenever Windows Vista enabled application needs to be able to run in Windows XP system, the code around <em>REBARBANDINFO</em> would look like this:</p>
<pre style="color: #000000; background: #ffffff;">REBARBANDINFO BandInformation <span style="color: #808030;">=</span> <span style="color: #800080;">{</span> <span style="color: #800000; font-weight: bold;">sizeof</span> BandInformation<span style="color: #808030;">,</span> RBBIM_LPARAM <span style="color: #800080;">}</span><span style="color: #800080;">;</span>
<span style="color: #004a43;">#</span><span style="color: #004a43;">if</span><span style="color: #004a43;"> _WIN32_WINNT </span><span style="color: #808030;">&gt;</span><span style="color: #808030;">=</span><span style="color: #004a43;"> 0x0600</span>
<span style="color: #800000; font-weight: bold;">if</span><span style="color: #808030;">(</span>GetOsVersion<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">&lt;</span> <span style="color: #008000;">0x00060000</span> <span style="color: #808030;">|</span><span style="color: #808030;">|</span> GetCommCtrlVersion<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">&lt;</span> <span style="color: #008000;">0x00060000</span><span style="color: #808030;">)</span> <span style="color: #696969;">// pre-Vista, Common Controls pre-6.0</span>
    BandInformation<span style="color: #808030;">.</span>cbSize <span style="color: #808030;">=</span> REBARBANDINFO_V6_SIZE<span style="color: #800080;">;</span>
<span style="color: #004a43;">#</span><span style="color: #004a43;">endif</span><span style="color: #696969;">// _WIN32_WINNT &gt;= 0x0600</span>
<span style="color: #800000; font-weight: bold;">const</span> <span style="color: #603000;">BOOL</span> bGetBandInfoResult <span style="color: #808030;">=</span> Rebar<span style="color: #808030;">.</span>GetBandInfo<span style="color: #808030;">(</span><span style="color: #008c00;">0</span><span style="color: #808030;">,</span> <span style="color: #808030;">&amp;</span>BandInformation<span style="color: #808030;">)</span><span style="color: #800080;">;</span></pre>
<p>If the API was nicer to developers, the code would be plain and simple:</p>
<pre style="color: #000000; background: #ffffff;">REBARBANDINFO BandInformation <span style="color: #808030;">=</span> <span style="color: #800080;">{</span> <span style="color: #800000; font-weight: bold;">sizeof</span> BandInformation<span style="color: #808030;">,</span> RBBIM_LPARAM <span style="color: #800080;">}</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">const</span> <span style="color: #603000;">BOOL</span> bGetBandInfoResult <span style="color: #808030;">=</span> Rebar<span style="color: #808030;">.</span>GetBandInfo<span style="color: #808030;">(</span><span style="color: #008c00;">0</span><span style="color: #808030;">,</span> <span style="color: #808030;">&amp;</span>BandInformation<span style="color: #808030;">)</span><span style="color: #800080;">;</span></pre>
<p>To address this problem, <a href="http://wtl.sourceforge.net/">WTL</a> 8.0 comes up with <em>RunTimeHelper</em> namespace and its <em>SizeOf_REBARBANDINFO</em> function. It takes care of details for the developer choosing the proper size of the structure on runtime. The code is being taken back to a simpler shape:</p>
<pre style="color: #000000; background: #ffffff;">REBARBANDINFO BandInformation <span style="color: #808030;">=</span> <span style="color: #800080;">{</span> RunTimeHelper<span style="color: #800080;">::</span>SizeOf_REBARBANDINFO<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span> RBBIM_LPARAM <span style="color: #800080;">}</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">const</span> <span style="color: #603000;">BOOL</span> bGetBandInfoResult <span style="color: #808030;">=</span> Rebar<span style="color: #808030;">.</span>GetBandInfo<span style="color: #808030;">(</span><span style="color: #008c00;">0</span><span style="color: #808030;">,</span> <span style="color: #808030;">&amp;</span>BandInformation<span style="color: #808030;">)</span><span style="color: #800080;">;</span></pre>
<p>All in all:</p>
<ul>
<li>be aware of compatibility issues (same scenario exists with other SDK structures: <em>LVGROUP</em>, <em>LVTILEINFO</em>, <em>MCHITTESTINFO</em>, <em>NONCLIENTMETRICS</em> and other).</li>
<li>use latest version of WTL to have things worked around for you where Microsoft developers were not kid enough to provide perfect API</li>
<li>be aware and take advantage of WTL&#8217;s <em>RunTimeHelper</em> class</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/1306/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Booo SRW Locks</title>
		<link>http://alax.info/blog/1185</link>
		<comments>http://alax.info/blog/1185#comments</comments>
		<pubDate>Sun, 27 Mar 2011 16:13:04 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[slim]]></category>
		<category><![CDATA[SRW]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=1185</guid>
		<description><![CDATA[<a href="http://alax.info/blog/1185" title="Booo SRW Locks"></a>Windows Vista introduced new synchronization API: slim reader/writer (SRW) locks. Being already armed with critical sections, one perhaps would not desperately need an SRW lock, but still it offers a great option to provide both exclusive (critical section alike) mode &#8230;<p class="read-more"><a href="http://alax.info/blog/1185">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/1185" title="Booo SRW Locks"></a><p>Windows Vista introduced new synchronization API: slim reader/writer (SRW) locks. Being already armed with critical sections, one perhaps would not desperately need an SRW lock, but still it offers a great option to provide both exclusive (critical section alike) mode and shared mode when 2+ threads can enter protected section simultaneously. Some time earlier, I already touched <a href="http://alax.info/blog/1163">SRW lock recursion issue</a>.</p>
<p>This time it is more about performance. Let us suppose we have a code fragment:</p>
<pre style="color: #000000; background: #ffffff;"><span style="color: #800000; font-weight: bold;">static</span> <span style="color: #800000; font-weight: bold;">const</span> SIZE_T g_nCount <span style="color: #808030;">=</span> <span style="color: #008c00;">100000000</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">for</span><span style="color: #808030;">(</span>SIZE_T nIndex <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #800080;">;</span> nIndex <span style="color: #808030;">&lt;</span> g_nCount<span style="color: #800080;">;</span> nIndex<span style="color: #808030;">+</span><span style="color: #808030;">+</span><span style="color: #808030;">)</span>
<span style="color: #800080;">{</span>
    AcquireSRWLockShared<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_Lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    ReleaseSRWLockShared<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_Lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #800080;">}</span></pre>
<p>How fast is this? Provided that execution took <strong>1.6 ms</strong> on an idle lock variable, how fast it is going to be with another shared &#8220;reader&#8221; on another thread who acquired once access in shared mode? This part comes up confusing: it appears almost twice as slow: <strong>2.9 ms</strong>, with also a number of contentions (and context switches) on the way.</p>
<p>SRW lock is advertised as lightweight and fast API, no recursion, no extra features, no fool proof checks. So it could be assumed to get you top performance, but 50 lines of code class can definitely outperform it.</p>
<p>A perhaps simplest SRW lock can be backed on a LONG (or LONGLONG) volatile variable accessed with <a href="http://msdn.microsoft.com/en-us/library/ms684122%28VS.85%29.aspx">interlocked API functions</a>. The rules are simple:</p>
<ul>
<li>initial value of zero means idle state</li>
<li>shared &#8220;reader&#8221; enters incrementing by one, positive values indicates one ore more readers</li>
<li>exclusive &#8220;writer&#8221; enters decrementing by a hundred (well, this needs to be any value big enough to be less than minus maximal amount of simultaneous concurrent readers)</li>
<li>releasing acquired state the value is decremented (incremented) back</li>
<li>in case of contention thread <a href="http://msdn.microsoft.com/en-us/library/ms686352%28VS.85%29.aspx">yields execution</a> to continue later with possibly better luck with shared resource (option: implement spic count for several attempts in a row, which is better suitable for multi-processor systems)</li>
</ul>
<p>It is clear that concurrent readers touch value only once with a single increment only, leaving no opportunity to yield execution due to contention. How fast it can be?</p>
<pre style="color: #000000; background: #ffffff;"><span style="color: #800000; font-weight: bold;">static</span> <span style="color: #800000; font-weight: bold;">const</span> SIZE_T g_nCount <span style="color: #808030;">=</span> <span style="color: #008c00;">100000000</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">for</span><span style="color: #808030;">(</span>SIZE_T nIndex <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #800080;">;</span> nIndex <span style="color: #808030;">&lt;</span> g_nCount<span style="color: #800080;">;</span> nIndex<span style="color: #808030;">+</span><span style="color: #808030;">+</span><span style="color: #808030;">)</span>
<span style="color: #800080;">{</span>
    <span style="color: #800000; font-weight: bold;">while</span><span style="color: #808030;">(</span><span style="color: #400000;">InterlockedIncrement</span><span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_nNativeLock<span style="color: #808030;">)</span> <span style="color: #808030;">&lt;</span> <span style="color: #008c00;">0</span><span style="color: #808030;">)</span>
    <span style="color: #800080;">{</span>
        <span style="color: #400000;">InterlockedDecrement</span><span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_nNativeLock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        <span style="color: #400000;">SwitchToThread</span><span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800080;">}</span>
    <span style="color: #400000;">InterlockedDecrement</span><span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_nNativeLock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #800080;">}</span></pre>
<p>It is <strong>1.3 ms</strong> regardless whether there are any shared readers on concurrent threads. It appears that a simple custom SRW lock class is going to be superior to the API:</p>
<ul>
<li>faster due to zero API overhead (inline compiled code versus WINAPI convention functions)</li>
<li>faster in shared mode due to not being subject to additional overhead and contentions</li>
<li>flexible spin counts possible to tune performance for specific use</li>
<li>extensibility:
<ul>
<li>recursion is allowed shared mode</li>
<li>easy to implement upgrades and downgrades between shared and exclusive modes</li>
</ul>
</li>
</ul>
<p>Sample code is Visual Studio 2010 C++ project accessible from <a href="http://www.assembla.com/code/roatl-utilities/subversion/nodes/trunk/SrwLockTest02">SVN repository</a>.</p>
<p><strong>Update</strong>: Critical Section Test. This is how SRW lock API performance compares to entry/leaving critical section (provided that critical section is never locked at entry time). Critical section is about 15% slower to enter and leave.</p>
<pre>C:\Projects\...\SrwLockTest02\x64\Release&gt;SrwLockTest02.exe
API: 100M iterations, 1575 ms
API: 100M iterations, 2839 ms
Native: 100M iterations, 1311 ms
Native: 100M iterations, 1326 ms
<span style="text-decoration: underline;">Critical Section: 100M iterations, 1841 ms</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/1185/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recursive SRW Locks</title>
		<link>http://alax.info/blog/1163</link>
		<comments>http://alax.info/blog/1163#comments</comments>
		<pubDate>Tue, 30 Nov 2010 00:23:27 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[deadlock]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[slim]]></category>
		<category><![CDATA[SRW]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=1163</guid>
		<description><![CDATA[<a href="http://alax.info/blog/1163" title="Recursive SRW Locks"></a>Windows Vista added new synchronization API, Slim Reader/Writer (SRW) Locks, which is a powerful alternative to critical sections. The detailed description is, as always on MSDN, and what makes it really cool is simple: unlike critical sections, SRW Locks provide &#8230;<p class="read-more"><a href="http://alax.info/blog/1163">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/1163" title="Recursive SRW Locks"></a><p>Windows Vista added new synchronization API, <a href="http://msdn.microsoft.com/en-us/library/aa904937%28VS.85%29.aspx">Slim Reader/Writer (SRW) Locks</a>, which is a powerful alternative to <a href="http://msdn.microsoft.com/en-us/library/ms682530(VS.85).aspx">critical sections</a>. The detailed description is, as always on MSDN, and what makes it really cool is simple:</p>
<ul>
<li>unlike critical sections, SRW Locks provide reader and writer access synchronization making it possible for 2 and more reader to not block one another</li>
<li>SRW Locks do not reference any resources and have size of a pointer, which is the simplest possible scenario; as a result, they don&#8217;t need a destructor and their initialization is simple zeroing of memory/variable (for which you however should use <a href="http://msdn.microsoft.com/en-us/library/ms683483%28VS.85%29.aspx">InitializeSRWLock</a> API</li>
</ul>
<p>Being lightweight they are efficient. To understand how at all they can work, one can imagine that a reader might be trying to <a href="http://msdn.microsoft.com/en-us/library/ms683614%28VS.85%29.aspx">InterlockedIncrement</a> a synchronization variable. If result is positive, then it&#8217;s OK to go. Otherwise, reader should decrement it back, wait and retry. A writer, instead, does <a href="http://msdn.microsoft.com/en-us/library/ms683504%28VS.85%29.aspx">InterlockedAdd</a> with an argument of -0&#215;1000 and checks that result of the operation is exactly -0&#215;1000.</p>
<p>This post is about a trap one cat enter into by neglecting one of the SRW lock warnings:</p>
<blockquote><p><a href="http://msdn.microsoft.com/en-us/library/aa904937%28VS.85%29.aspx">&#8230; so SRW locks cannot be acquired recursively. In addition, a thread that  owns an SRW lock in shared mode cannot upgrade its ownership of the lock  to exclusive mode.</a></p></blockquote>
<p>SRW locks cannot be acquired recursively, but it is very easy to make a mistake. If you attempt to recursively acquire, you are likely to succeed, without a warning, error code, exception or assertion failure. You pass this point and you can write quite some code before you realize something is wrong.</p>
<p>It can be as simple as this:</p>
<p><span id="more-1163"></span></p>
<pre style="color: #000000; background: #ffffff;">SIZE_T GetCount<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">const</span> <span style="color: #800000; font-weight: bold;">throw</span><span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: #800080;">{</span>
    AcquireSRWLockShared<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_Lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">const</span> SIZE_T nCount <span style="color: #808030;">=</span> <span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #808030;">.</span><span style="color: #800080;">;</span>
    ReleaseSRWLockShared<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_Lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">return</span> nCount<span style="color: #800080;">;</span>
<span style="color: #800080;">}</span>
<span style="color: #603000;">BOOL</span> IsEmpty<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">const</span> <span style="color: #800000; font-weight: bold;">throw</span><span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: #800080;">{</span>
    AcquireSRWLockShared<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_Lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">const</span> <span style="color: #603000;">BOOL</span> bResult <span style="color: #808030;">=</span> GetCount<span style="color: #808030;">(</span><span style="color: #808030;">)</span> <span style="color: #808030;">&gt;</span> <span style="color: #008c00;">0</span><span style="color: #800080;">;</span>
    ReleaseSRWLockShared<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>m_Lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">return</span> bResult<span style="color: #800080;">;</span>
<span style="color: #800080;">}</span>
</pre>
<p>IsEmpty calls GetCount which again attempts to acquire lock.</p>
<p>In multit-hreaded environment the problem may come up in the following scenario: thread A acquires shared lock, thread B attempts to acquire exclusive lock, thread A attempts to re-acquire (recursively) shared lock again and both threads freeze at this point. Note that without thread B recursive locking succeeds on thread A.</p>
<p><a href="http://www.assembla.com/code/roatl-utilities/subversion/nodes/trunk/SrwLockTest01">SrwLockTest01</a> project provides a sample code to reproduce the deadlock around misused SRW Lock. <a href="http://www.assembla.com/code/roatl-utilities/subversion/nodes/trunk/SrwLockTest01/SrwLockTest01.cpp?rev=227#ln29">RecursiveSharedLock and ExclusiveLock thread functions</a> keep acquiring lock simultaneously, while main thread is monitoring current worker thread positions.</p>
<p>Shared access only worker thread, which does recursive lock, runs just fine alone, if the other concurrent thread is commented out:</p>
<pre style="color: #000000; background: #ffffff;">CHandle SharedLockThread<span style="color: #808030;">,</span> ExclusiveLockThread<span style="color: #800080;">;</span>
SharedLockThread<span style="color: #808030;">.</span>Attach<span style="color: #808030;">(</span>AtlCreateThread<span style="color: #800080;">&lt;</span>INT_PTR<span style="color: #800080;">&gt;</span><span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>RecursiveSharedLock<span style="color: #808030;">,</span> <span style="color: #008c00;">0</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #696969;">//ExclusiveLockThread.Attach(AtlCreateThread&lt;INT_PTR&gt;(&amp;ExclusiveLock, 0));</span>
</pre>
<pre>g_nRecursiveSharedLockLine 27, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 29, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 31, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 31, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 29, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 25, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 27, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 25, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 29, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 29, g_nExclusiveLockLine 0
g_nRecursiveSharedLockLine 33, g_nExclusiveLockLine 0</pre>
<p>Status output captures worker thread at random line, and CPU is maxed out on one of the cores.</p>
<p>With concurrent threads, a deadlock takes place very soon:</p>
<pre>g_nRecursiveSharedLockLine 35, g_nExclusiveLockLine 49
g_nRecursiveSharedLockLine 35, g_nExclusiveLockLine 49
g_nRecursiveSharedLockLine 35, g_nExclusiveLockLine 49
g_nRecursiveSharedLockLine 35, g_nExclusiveLockLine 49
g_nRecursiveSharedLockLine 35, g_nExclusiveLockLine 49
g_nRecursiveSharedLockLine 35, g_nExclusiveLockLine 49
g_nRecursiveSharedLockLine 35, g_nExclusiveLockLine 49</pre>
<p>CPU consumption for the process is nearly zero &#8211; threads are in deadlock: shared access thread is i nAPI call at <a href="http://www.assembla.com/code/roatl-utilities/subversion/nodes/trunk/SrwLockTest01/SrwLockTest01.cpp#ln36">line 36</a>, exclusive access thread is at <a href="http://www.assembla.com/code/roatl-utilities/subversion/nodes/trunk/SrwLockTest01/SrwLockTest01.cpp#ln50">line 50</a>.</p>
<p>As soon as the problem is clear, a reasonable safety measures are to be taken to avoid misuse. To use SRW Locks safely, it is suggested to use a wrapper class that asserts on misuse in debug builds (to be continued).</p>
<p>Sample code is Visual Studio 2010 C++ project accessible from <a href="http://www.assembla.com/code/roatl-utilities/subversion/nodes/trunk/SrwLockTest01">SVN repository</a>.</p>
<p>See also:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/aa904937%28VS.85%29.aspx">Slim Reader/Writer (SRW) Locks</a></li>
<li><a href="http://msdn.microsoft.com/en-us/magazine/cc163405.aspx">Synchronization Primitives New To Windows Vista</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/1163/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Combo Box selection, WM_SETREDRAW and CB_SETCURSEL</title>
		<link>http://alax.info/blog/994</link>
		<comments>http://alax.info/blog/994#comments</comments>
		<pubDate>Thu, 30 Jul 2009 12:04:05 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[WTL]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[CB_SETCURSEL]]></category>
		<category><![CDATA[combo box]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[WM_SETREDRAW]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=994</guid>
		<description><![CDATA[<a href="http://alax.info/blog/994" title="Combo Box selection, WM_SETREDRAW and CB_SETCURSEL"></a>Given the combo box initialization code: m_ComboBox.SetRedraw(FALSE); m_ComboBox.ResetContent(); for(INT nIndex = 0; nIndex &#60; 3; nIndex++) m_ComboBox.AddString(AtlFormatString(_T("Item %d"), nIndex + 1)); m_ComboBox.SetCurSel(1); m_ComboBox.SetRedraw(TRUE) How the combo box is going to look like? Here it goes: Combo box won&#8217;t repaint window &#8230;<p class="read-more"><a href="http://alax.info/blog/994">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/994" title="Combo Box selection, WM_SETREDRAW and CB_SETCURSEL"></a><p>Given the combo box initialization code:</p>
<pre>m_ComboBox<span style="color: #808030;">.</span>SetRedraw<span style="color: #808030;">(</span>FALSE<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
m_ComboBox<span style="color: #808030;">.</span>ResetContent<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">for</span><span style="color: #808030;">(</span><span style="color: #603000;">INT</span> nIndex <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #800080;">;</span> nIndex <span style="color: #808030;">&lt;</span> <span style="color: #008c00;">3</span><span style="color: #800080;">;</span> nIndex<span style="color: #808030;">+</span><span style="color: #808030;">+</span><span style="color: #808030;">)</span>
    m_ComboBox<span style="color: #808030;">.</span>AddString<span style="color: #808030;">(</span>AtlFormatString<span style="color: #808030;">(</span>_T<span style="color: #808030;">(</span><span style="color: #800000;">"</span><span style="color: #0000e6;">Item </span><span style="color: #0f69ff;">%d</span><span style="color: #800000;">"</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span> nIndex <span style="color: #808030;">+</span> <span style="color: #008c00;">1</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
m_ComboBox<span style="color: #808030;">.</span>SetCurSel<span style="color: #808030;">(</span><span style="color: #008c00;">1</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
m_ComboBox<span style="color: #808030;">.</span>SetRedraw<span style="color: #808030;">(</span>TRUE<span style="color: #808030;">)</span></pre>
<p>How the combo box is going to look like?</p>
<p><span id="more-994"></span>Here it goes:</p>
<p><img class="size-full wp-image-995 alignnone" title="ComboBoxSample01 #1" src="http://alax.info/blog/wp-content/uploads/2009/07/image001.png" alt="ComboBoxSample01 #1" width="300" height="129" /></p>
<p>Combo box won&#8217;t repaint window on SetRedraw(TRUE) AKA <a href="http://msdn.microsoft.com/en-us/library/dd145219%28VS.85%29.aspx">WM_SETREDRAW</a>. But once you move a mouse pointer over the control, or tab to focus it, the correct selection will be painted, &#8220;Item 2&#8243;:</p>
<p><img class="alignnone size-full wp-image-996" title="ComboBoxSample01 #2" src="http://alax.info/blog/wp-content/uploads/2009/07/image002.png" alt="ComboBoxSample01 #2" width="300" height="129" /></p>
<p>The control ignores the invalidation caused by <a href="http://msdn.microsoft.com/en-us/library/bb775899%28VS.85%29.aspx">CB_SETCURSEL</a> message while processing final SetRedraw message. To avoid GUI glitches, for example, a m_ComboBox.Invalidate() or <a href="http://msdn.microsoft.com/en-us/library/dd145002%28VS.85%29.aspx">InvalidateRect</a> might be called after SetRedraw(TRUE).</p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/994/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RegSetKeySecurity, CRegKey::SetKeySecurity and CSecurityDesc</title>
		<link>http://alax.info/blog/950</link>
		<comments>http://alax.info/blog/950#comments</comments>
		<pubDate>Mon, 22 Jun 2009 18:10:43 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[CRegKey]]></category>
		<category><![CDATA[CSecurityDesc]]></category>
		<category><![CDATA[registry]]></category>
		<category><![CDATA[RegSetKeySecurity]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SetKeySecurity]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=950</guid>
		<description><![CDATA[<a href="http://alax.info/blog/950" title="RegSetKeySecurity, CRegKey::SetKeySecurity and CSecurityDesc"></a>One thing is worth special mentioning in connection with previous post on DirectShow Filter Graph Spy on Microsoft Vista system: ATL&#8217;s CSecurityDesc class caused to waste some time. CRegKey Key; ATLENSURE_SUCCEEDED(HRESULT_FROM_WIN32(Key.Open(HKEY_CLASSES_ROOT, pszKeyName, READ_CONTROL &#124; WRITE_OWNER))); CSecurityDesc AdministratorsOwnerSecurityDescriptor; AdministratorsOwnerSecurityDescriptor.SetOwner(Sids::Admins()); ATLENSURE_SUCCEEDED(HRESULT_FROM_WIN32(Key.SetKeySecurity(OWNER_SECURITY_INFORMATION, &#38;AdministratorsOwnerSecurityDescriptor))); &#8230;<p class="read-more"><a href="http://alax.info/blog/950">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/950" title="RegSetKeySecurity, CRegKey::SetKeySecurity and CSecurityDesc"></a><p>One thing is worth special mentioning in connection with previous post on <a href="http://alax.info/blog/944">DirectShow Filter Graph Spy</a> on <a href="http://www.microsoft.com/windows/windows-vista/default.aspx">Microsoft Vista</a> system: ATL&#8217;s CSecurityDesc class caused to waste some time.</p>
<pre style="background: #ffffff none repeat scroll 0% 0%; color: #000000;">CRegKey Key<span style="color: #800080;">;</span>
ATLENSURE_SUCCEEDED<span style="color: #808030;">(</span>HRESULT_FROM_WIN32<span style="color: #808030;">(</span>Key<span style="color: #808030;">.</span>Open<span style="color: #808030;">(</span>HKEY_CLASSES_ROOT<span style="color: #808030;">,</span> pszKeyName<span style="color: #808030;">,</span> READ_CONTROL <span style="color: #808030;">|</span> WRITE_OWNER<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
CSecurityDesc AdministratorsOwnerSecurityDescriptor<span style="color: #800080;">;</span>
AdministratorsOwnerSecurityDescriptor<span style="color: #808030;">.</span>SetOwner<span style="color: #808030;">(</span>Sids<span style="color: #800080;">::</span>Admins<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
ATLENSURE_SUCCEEDED<span style="color: #808030;">(</span>HRESULT_FROM_WIN32<span style="color: #808030;">(</span>Key<span style="color: #808030;">.</span>SetKeySecurity<span style="color: #808030;">(</span>OWNER_SECURITY_INFORMATION<span style="color: #808030;">,</span> <span style="color: #808030;">&amp;</span>AdministratorsOwnerSecurityDescriptor<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span></pre>
<p>The code compiles fine, but on runtime it gives error <em>87</em> (<em>ERROR_INVALID_PARAMETER</em>, <em>E_INVALIDARG</em>) in the last line, returned from <a href="http://msdn.microsoft.com/en-us/library/aa379314(VS.85).aspx">RegSetKeySecurity</a> API call. My first guess was that ATL&#8217;s <a href="http://msdn.microsoft.com/en-us/library/k0c0e5w6.aspx">CSecurityDesc</a> class for some reason prepared wrong descriptor which resulted in rejecting it as an argument. From the first glance it looks (not sure) that this class deals, to some extent, with structures itself rather than using API functions, so it could be that it results in something looking differently from expected by API calls.</p>
<p>Still the problem is in class itself and its cast from <em>CSecurityDesc&amp;</em> to required <em>SECURITY_DESCRIPTOR*</em> type. The class only implements operator to automatically cast to <em><span style="color: #ff0000;">const</span> SECURITY_DESCRIPTOR*</em> type, so the following line would not be passed by compiler:</p>
<pre style="background: #ffffff none repeat scroll 0% 0%; color: #000000;">Key<span style="color: #808030;">.</span>SetKeySecurity<span style="color: #808030;">(</span>OWNER_SECURITY_INFORMATION<span style="color: #808030;">,</span> AdministratorsOwnerSecurityDescriptor<span style="color: #808030;">)</span></pre>
<p>However <em><span style="color: #ff0000;">&amp;</span>AdministratorsOwnerSecurityDescriptor</em> is another level of indirection and hence <em>SECURITY_DESCRIPTOR*</em><span style="color: #ff0000;">*</span> type, which is passed by compiler, but results in indeed invalid argument.</p>
<p>So in order to correctly convert <em>CSecurityDesc&amp;</em> to <em>SECURITY_DESCRIPTOR*</em> it can be done this way:</p>
<pre style="background: #ffffff none repeat scroll 0% 0%; color: #000000;">CRegKey Key<span style="color: #800080;">;</span>
ATLENSURE_SUCCEEDED<span style="color: #808030;">(</span>HRESULT_FROM_WIN32<span style="color: #808030;">(</span>Key<span style="color: #808030;">.</span>Open<span style="color: #808030;">(</span>HKEY_CLASSES_ROOT<span style="color: #808030;">,</span> pszKeyName<span style="color: #808030;">,</span> READ_CONTROL <span style="color: #808030;">|</span> WRITE_OWNER<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
CSecurityDesc AdministratorsOwnerSecurityDescriptor<span style="color: #800080;">;</span>
AdministratorsOwnerSecurityDescriptor<span style="color: #808030;">.</span>SetOwner<span style="color: #808030;">(</span>Sids<span style="color: #800080;">::</span>Admins<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
ATLENSURE_SUCCEEDED<span style="color: #808030;">(</span>HRESULT_FROM_WIN32<span style="color: #808030;">(</span>Key<span style="color: #808030;">.</span>SetKeySecurity<span style="color: #808030;">(</span>OWNER_SECURITY_INFORMATION<span style="color: #808030;">,</span> const_cast<span style="color: #808030;">&lt;</span><span style="color: #603000;">SECURITY_DESCRIPTOR</span><span style="color: #808030;">*</span><span style="color: #808030;">&gt;</span><span style="color: #808030;">(</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">const</span> <span style="color: #603000;">SECURITY_DESCRIPTOR</span><span style="color: #808030;">*</span><span style="color: #808030;">)</span> AdministratorsOwnerSecurityDescriptor<span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/950/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Downloading Windows 7 Beta 32-bit</title>
		<link>http://alax.info/blog/787</link>
		<comments>http://alax.info/blog/787#comments</comments>
		<pubDate>Mon, 02 Feb 2009 23:39:12 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[crap]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[seven]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=787</guid>
		<description><![CDATA[<a href="http://alax.info/blog/787" title="Downloading Windows 7 Beta 32-bit"></a>I decided to download a beta of Windows 7, so many people shared their positive impressions of. I am not quite sure I will have time to actually evaluate it, but for the case I would feel like, it is &#8230;<p class="read-more"><a href="http://alax.info/blog/787">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/787" title="Downloading Windows 7 Beta 32-bit"></a><p>I decided to download <a href="https://www.microsoft.com/betaexperience/productkeys/win7-32/enus/default.aspx">a beta of Windows 7</a>, so many people shared their positive impressions of. I am not quite sure I will have time to actually evaluate it, but for the case I would feel like, it is always nice to have the .ISO image ready for a try.</p>
<p>There was nothing worth a word until I reached the download screen which opened an extremely awful Java applet that pretended to be a download manager. It seemed to be a new spin of technology and sort of I don&#8217;t need a nice download manager anymore because direct HTTP links are out of fashion. It started pumping bytes (actually thanks for that) and I my attempt to copy/paste a direct link into my <a href="http://www.downthemall.net/">DownThemAll</a> <a href="http://mozilla.org">FireFox</a> plugin was vain.</p>
<p>At some 20% the download froze without a notice. The download did not even ungray the resume buttons before I restarted FireFox process and then any attempt to resume led to weird message boxes. Frankly at this point I almost lost the desire to actually complete the download. But left a last chance to have it completed by IE. Internet Explorer (expectedly!) preferred ActiveX control to Java applet. It&#8217;s GUI was a bit less scary and it took over incomplete download and&#8230;</p>
<p><a href="http://alax.info/blog/wp-content/uploads/2009/02/02-image001.png"><img class="alignnone size-medium wp-image-788" title="Window 7 Beta Download Manager Crash" src="http://alax.info/blog/wp-content/uploads/2009/02/02-image001-300x185.png" alt="" width="300" height="185" /></a></p>
<p>An attached debugger showed a call stack (oops, I did not save exact call stack) in Manager.exe process in C runtime module, in a CString class method&#8230; It went no further than this crashing at exactly the same point until I manually deleted the incomplete download, when it again repeated a weird message box and then finally restart the download from the start. That was enough for me and found a .torrent with the exactly the same file on <a href="http://thepiratebay.org">thepiratebay.org</a>, which I am quite sure will download without a problem.</p>
<p>Isn&#8217;t it incredibly stupid that significant amount of work was invested into unnecessary task, ugly user interface, buggy implementation (freeze, incapable download manager, weird messages, crash) with a solid residual of inability to conveniently download the thing, while the file could be just put onto regular MS download service?</p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/787/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Time Zone Information &amp; Monitor Information</title>
		<link>http://alax.info/blog/715</link>
		<comments>http://alax.info/blog/715#comments</comments>
		<pubDate>Sat, 22 Nov 2008 21:07:57 +0000</pubDate>
		<dc:creator>Roman</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[WTL]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://alax.info/blog/?p=715</guid>
		<description><![CDATA[<a href="http://alax.info/blog/715" title="Time Zone Information &amp; Monitor Information"></a>I am sharing a couple of utilities to be able to quick check system settings. TimeZoneInformation prints in a human friendly style TIME_ZONE_INFORMATION structure as reported by Windows through GetTimeZoneInformation API. TIME_ZONE_INFORMATION: .Bias: -120 .StandardName: FLE Standard Time .StandardDate: { &#8230;<p class="read-more"><a href="http://alax.info/blog/715">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://alax.info/blog/715" title="Time Zone Information &amp; Monitor Information"></a><p>I am sharing a couple of utilities to be able to quick check system settings. TimeZoneInformation prints in a human friendly style <a href="http://msdn.microsoft.com/en-us/library/ms725481(VS.85).aspx">TIME_ZONE_INFORMATION structure</a> as reported by Windows through <a href="http://msdn.microsoft.com/en-us/library/ms724421(VS.85).aspx">GetTimeZoneInformation</a> API.</p>
<pre>TIME_ZONE_INFORMATION:
.Bias: -120
.StandardName: FLE Standard Time
.StandardDate: { .wYear 0, .wMonth 10, .wDay 5, .wDayOfWeek 0, .wHour 4, .wMinute 0, .wSecond 0, .wMilliseconds 0 }
.StandardBias: 0
.DaylightName: FLE Daylight Time
.DaylightDate: { .wYear 0, .wMonth 3, .wDay 5, .wDayOfWeek 0, .wHour 3, .wMinute 0, .wSecond 0, .wMilliseconds 0 }
.DaylightBias: -60
[...]</pre>
<p><a href="http://alax.info/blog/wp-content/uploads/2008/11/22-image001.png"><img class="alignnone size-medium wp-image-716" title="TimeZoneInformation Screenshot" src="http://alax.info/blog/wp-content/uploads/2008/11/22-image001-300x211.png" alt="" width="300" height="211" /></a></p>
<p>A Visual C++ .NET 2008 source code <a href="http://trac2.assembla.com/roatl-utilities/browser/trunk/TimeZoneInformation">is available from SVN</a>, release binary <a href="http://trac2.assembla.com/roatl-utilities/browser/trunk/TimeZoneInformation/Release/TimeZoneInformation.exe?format=raw">included</a>.</p>
<p>And the second utility is MonitorInformation to print multi-monitor related information again as reported by Windows, <a href="http://msdn.microsoft.com/en-us/library/ms724385.aspx">GetSystemMetrics</a> and <a href="http://msdn.microsoft.com/en-us/library/ms534809(VS.85).aspx">EnumDisplayMonitors</a> APIs.</p>
<pre>System Metrics:
  SM_XVIRTUALSCREEN: 0
  SM_YVIRTUALSCREEN: 0
  SM_CXVIRTUALSCREEN: 1680
  SM_CYVIRTUALSCREEN: 1050
  SM_CMONITORS: 1
  SM_SAMEDISPLAYFORMAT: 1

Monitor 0 at (0, 0) - (1680, 1050):
  Coordinates (rcMonitor): (0, 0) - (1680, 1050)
  Work Area (rcWork): (0, 0) - (1680, 1026)
  Flags (dwFlags): 0x1
  Device Name (szDevice): \\.\DISPLAY1</pre>
<p><a href="http://alax.info/blog/wp-content/uploads/2008/11/22-image002.png"><img class="alignnone size-medium wp-image-717" title="MonitorInformation Screenshot" src="http://alax.info/blog/wp-content/uploads/2008/11/22-image002-300x226.png" alt="" width="300" height="226" /></a></p>
<p>A Visual C++ .NET 2008 source code is <a href="http://trac2.assembla.com/roatl-utilities/browser/trunk/MonitorInformation">available from SVN</a>, release binary <a href="http://trac2.assembla.com/roatl-utilities/browser/trunk/MonitorInformation/Release/MonitorInformation.exe?format=raw">included</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://alax.info/blog/715/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

