<?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>The Old New Thing - Dreamcatcher Edition</title>
	<atom:link href="https://devblogs.microsoft.com/oldnewthing/feed" rel="self" type="application/rss+xml" />
	<link>https://devblogs.microsoft.com/oldnewthing</link>
	<description>Practical development throughout the evolution of Windows.</description>
	<lastBuildDate>Mon, 14 Sep 2026 14:17:26 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2021/03/Microsoft-Favicon.png</url>
	
  <title>The Old New Thing - Dreamcatcher Edition</title>
	<link>https://devblogs.microsoft.com/oldnewthing</link>
	<width>32</width>
	<height>32</height>
</image> 
	
  <item>
    <title>Why didn&#8217;t Read&#173;Directory&#173;ChangesW provide a way to correlate the two sides of a rename operation?</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260914-00/?p=112696</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260914-00/?p=112696#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Mon, 14 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[Other]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112696</guid>
    <content:encoded><![CDATA[<p>Brian Dellisanti asked <a href="https://devblogs.microsoft.com/oldnewthing/20260508-00/?p=112310&amp;commentid=144190#comment-144190"> why <code>Read­Directory­ChangesW</code> didn&#8217;t provide a way to correlate the two sides of a rename operation</a>.</p>
<p>I wasn&#8217;t there, but I can guess.</p>
<p>My guess is that the implementation always generated the two events one right after the other, so &#8220;obviously&#8221; the way you correlate them is to save the old name when you see the <code>FILE_<wbr />ACTION_<wbr />RENAMED_<wbr />OLD_<wbr />NAME</code>, and when the <code>FILE_<wbr />ACTION_<wbr />RENAMED_<wbr />NEW_<wbr />NAME</code> comes immediately after, you have your two sides.</p>
<p>But they never wrote down that the two events always occur in direct succession. Which meant that when new file systems came along, they might not honor the unwritten rule. If two files are being renamed at the same time, is it possible that the two sets of rename events end up interleaved? There was nothing written down to forbid it, so I guess it&#8217;s possible.</p>
<p>Note that I don&#8217;t know whether any file systems actually break this unwritten rule. From what I can tell, they do generate the two events in rapid succession, but rapid succession doesn&#8217;t <i>a priori</i> guarantee that they will come directly one after the other, particularly if there is a lot of concurrent disk activity going on.</p>
<p>In practice, I couldn&#8217;t find a lot of code tracking renames anyway. They generally treated the <code>FILE_<wbr />ACTION_<wbr />RENAMED_<wbr />OLD_<wbr />NAME</code> as a deletion and the <code>FILE_<wbr />ACTION_<wbr />RENAMED_<wbr />NEW_<wbr />NAME</code> as a creation. And the ones that did track renames assumed that renames did not interleave. (Not that they had much choice.)</p>
<p>I don&#8217;t think that providing the file IDs for the two sides of a rename operation was the purpose of <code>Read­Directory­Changes­ExW</code>&#8216;s <code>Read­Directory­Notify­Extended­Information</code>. It was just a happy side effect that the extra information in the <code>Read­Directory­Notify­Extended­Information</code> also gives you the pieces needed to connect the dots reliably.</p>
<p>I thought you might appreciate me pointing out the trick, that&#8217;s all.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260914-00/?p=112696">Why didn&#8217;t &lt;CODE&gt;Read&shy;Directory&shy;ChangesW&lt;/CODE&gt; provide a way to correlate the two sides of a rename operation?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260914-00/?p=112696/feed</wfw:commentRss>
    <slash:comments>6</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>How can I remove the Close button from my window caption?</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260911-00/?p=112691</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260911-00/?p=112691#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Fri, 11 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112691</guid>
    <content:encoded><![CDATA[<p>Occasionally, somebody wants to create a window without a Close button.</p>
<p>The only way to get rid of the Close button is not to have a System menu at all: Remove the <code>WS_<wbr />SYS­MENU</code> style from the window. But that also gets rid of the Minimize and Maximize buttons, so it&#8217;s kind of drastic.</p>
<p>If you want a System menu, or if you want Minimize and Maximize buttons, you can at least disable the Close button by disabling the <code>SC_CLOSE</code> menu item.</p>
<pre>HMENU menu = GetSystemMenu(hwnd, FALSE);
EnableMenuItem(menu, SC_CLOSE, MF_DISABLED);
</pre>
<p>Of course, you could use the nuclear option and implement your own custom title bar. Then you can do whatever you want. But most people are probably not willing to take things to such an extreme.</p>
<p>But really, try not to hide or disable the Close the button at all. End users don&#8217;t like it. It makes them feel trapped.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260911-00/?p=112691">How can I remove the Close button from my window caption?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260911-00/?p=112691/feed</wfw:commentRss>
    <slash:comments>5</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>Why is the x86 undefined instruction called ud2? Why 2?</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260910-00/?p=112689</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260910-00/?p=112689#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Thu, 10 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[Other]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112689</guid>
    <content:encoded><![CDATA[<p>If you look at x86 compiler output (or if, like me, you&#8217;re looking at a crash caused by some software that tried to detour an API), you may see an instruction <code>ud2</code>. What&#8217;s up with that?</p>
<p>The <code>ud2</code> instruction is an architecturally undefined instruction, guaranteed to raise an &#8220;invalid opcode&#8221; exception. Some compilers generate it to mark &#8220;unreachable&#8221; code, so that if execution somehow manages to reach it, you get a crash rather than executing random instructions. For example, if a function marked <code>[[noreturn]]</code> somehow returns, the compiler will put a <code>ud2</code> after the call so that the program crashes instead of falling through to the next function.</p>
<p>Anyway, why is this instruction called <code>ud2</code> instead of just <code>ud</code>? Was there a <code>ud1</code>? What was so wrong about <code>ud1</code> that we had to make a <code>ud2</code>?</p>
<p>I think I can reconstruct what happened.</p>
<p>Originally, there was no architecturally undefined instruction on x86. So people who wanted to force an invalid opcode exception went looking for some byte sequence that reliably raised the invalid opcode exception when executed.</p>
<p>Somebody found that the <code>0F FF</code> sequence led to an invalid opcode exception. Though, for whatever reason, the instruction internally decoded as if it took two parameters, a register destination and a register-or-memory source. The parameters aren&#8217;t actually used because the invalid opcode exception gets raised before anything else can happen.</p>
<p>Meanwhile, somebody else found that the <code>0F B9</code> sequence also had the same properties. So you now had two factions, the <code>0F FF</code> believers and the <code>0F B9</code> adherents. There really wasn&#8217;t much of a battle between them, because both techniques seemed to work, and it&#8217;s not like one was coming at the detriment of the other.</p>
<p>Intel then worked on their next processor, and maybe they made some changes that resulted in <code>0F FF</code> no longer raising an invalid opcode exception. Maybe they tried introducing a new instruction that uses <code>0F FF</code>. Or maybe it was still undefined but just performed some random operation instead of raising the invalid opcode instruction. And when they started running software on their new processor, they found that some programs stopped working, and after laborious investigation, they discovered that the programs were relying on <code>0F FF</code> being an invalid opcode.</p>
<p>In other words, they ran into <a href="https://www.hyrumslaw.com/">Hyrum&#8217;s Law</a>: With a sufficient number of users, all observable behaviors will be depended upon by somebody. <a href="https://xkcd.com/1172/">Obligatory XKCD</a>.</p>
<p>A similar discovery was made with <code>0F B9</code>.</p>
<p>Now that they realized that people wanted a reliable way to trigger an invalid opcode exception, the folks at Intel decided to make it official, and they created an actual supported permanently-invalid instruction and called it <code>ud2</code>.</p>
<p>It&#8217;s called <code>ud2</code> because the <code>0F FF</code> variant was retroactively named <code>ud0</code>, and the <code>0F B9</code> variant was retroactively named <code>ud1</code>, leaving <code>ud2</code> as the recommended undefined opcode.</p>
<p>One advantage of <code>ud2</code> is that it is a two-byte instruction with no parameters, so you don&#8217;t have to deal with the random decoded-but-unused source and destinations.</p>
<p><b>Bonus chatter</b>: But why do we care about the unused parameters to <code>ud0</code> and <code>ud1</code>? Can&#8217;t we just say that <code>ud0</code> and <code>ud1</code> are also two-byte invalid opcodes? I mean, sure, there&#8217;s a third byte, or possibly more if the memory operand has an offset or a scaled index, but the processor doesn&#8217;t use it.</p>
<p>It matters, because even though the processor doesn&#8217;t use it, it still <i>decodes</i> it. And if the decoding of the instruction crosses into a not-present page, you don&#8217;t get an invalid opcode exception at all. You get an access violation.</p>
<p><b>Bonus bonus chatter</b>: Except that some older processors raised the invalid opcode instruction as soon as they decoded the <code>0F FF</code> without checking whether the rest of the instruction decoded properly. So if your <code>0F FF</code> is at the end of a page, and the next page is not present, you sometimes got an invalid opcode exception and you sometimes got an access violation.</p>
<p>Better to stick with <code>ud2</code>. Its behavior is consistent and architecturally guaranteed.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260910-00/?p=112689">Why is the x86 undefined instruction called &lt;CODE&gt;ud2&lt;/CODE&gt;? Why 2?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260910-00/?p=112689/feed</wfw:commentRss>
    <slash:comments>9</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>What algorithm did Windows XP use to choose your initial user picture?</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260909-00/?p=112683</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260909-00/?p=112683#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Wed, 09 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[History]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112683</guid>
    <content:encoded><![CDATA[<p>I noted some time ago that <a title="The martial arts logon picture" href="https://devblogs.microsoft.com/oldnewthing/20040401-00/?p=39933"> Windows XP chose your initial picture at random</a> from among the pictures in the <tt>%ALLUSERSPROFILE%\<wbr />Application Data\<wbr />Microsoft\<wbr />User Account Pictures\<wbr />Default Pictures</tt> directory. But it seems people want to know more.</p>
<blockquote class="twitter-tweet">
<p dir="ltr" lang="en">Has anyone attempted to figure out the RNG for how Windows XP determines what profile picture is used on first account creation?</p>
<p>— Xeno (@XenoPanther) <a href="https://twitter.com/XenoPanther/status/1999217479923413284">December 11, 2025</a></p></blockquote>
<p><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>The random number generator is our friend <code>RtlRandomEx</code>, using the current value of <code>GetTickCount()</code> as the initial seed.</p>
<p>The function uses a one-pass random selection algorithm. I can immediately think of two benefits of this decision. First, compared to the naïve two-pass algorithm of counting up all the items, then randomly picking a number from 1 to <var>n</var>, and then iterating a second time to find the item at that index, it&#8217;s more efficient because it reduces the amount of calls into the file system, which is where the bottleneck is. Furthermore, the one-pass algorithm avoids complications if the number of files in the directory changes while the code is running.</p>
<p>The one-pass algorithm is a special case of <a href="https://en.wikipedia.org/wiki/Reservoir_sampling"> reservoir sampling</a>, where <var>k</var> is 1. This special case permits a tailored algorithm that is much simpler.</p>
<pre>selectRandomFromIterator(iterator)
{
    var count = 0;
    var winner = null;

    while (iterator.moveNext()) {
        ++count;
        if (uniform_random(min: 1, max: count) == count) {
            winner = iterator.current();
        }
    }

    return winner;
}
</pre>
<p>The way this algorithm works is by observing that in a collection of <var>n</var> items, the last item has a 1/<var>n</var> chance of being randomly selected. If it isn&#8217;t selected, then you need to select randomly from the first <var>n</var> − 1 items, which you can solve recursively.</p>
<p>Playing the recursion forward, you start with the base case which is that if you have a list of 1 item, then your only choice is to chose that item. Otherwise, if you have a list of <var>n</var> items, first choose an item randomly from the first <var>n</var> − 1, and then switch to the <var>n</var>th item with a 1/<var>n</var> probability.</p>
<p>As a final safety check, the code stops after sampling 100 pictures. This avoids pathological behavior if somebody puts a million files in the <tt>Default Pictures</tt> directory.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260909-00/?p=112683">What algorithm did Windows XP use to choose your initial user picture?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260909-00/?p=112683/feed</wfw:commentRss>
    <slash:comments>8</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>A sample use of the winstart.bat file in Windows 95</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260908-00/?p=112679</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260908-00/?p=112679#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Tue, 08 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[History]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112679</guid>
    <content:encoded><![CDATA[<p>In my earlier discussion of <a title="The little-known winstart.bat batch file" href="https://devblogs.microsoft.com/oldnewthing/20260811-00/?p=112605"> the the litte-known <code>winstart.bat</code> batch file in Windows 3.1 and Windows 95</a>, Danielix Klimax wondered <a href="https://devblogs.microsoft.com/oldnewthing/20260811-00/?p=112605&amp;commentid=144575#comment-144575"> whether it was useful in Windows 95, or whether it was primarily used only in Windows 3.x</a>.</p>
<p>I found a reference to <code>winstart.bat</code> in <a title="Q83502: SETUP.TXT from Windows 3.1 Part A" href="https://jeffpar.github.io/kbarchive/kb/083/Q83502/"> the Windows 3.1 <code>SETUP.TXT</code> file</a>:</p>
<pre>Using the TIGA Display Driver
-------------------------------
If you are using the TIGA display driver, you must load the TIGACD.EXE
MS-DOS driver manually before running Setup to upgrade Windows.
Otherwise, Windows will not upgrade your system properly.

After successfully setting up Windows, you can increase the amount of
conventional memory available to non-Windows applications when Windows
is running in 386 enhanced mode by loading TIGACD.EXE from the
WINSTART.BAT file. The WINSTART.BAT file runs only in 386 enhanced
mode. If you want to run Windows in standard mode, you must load
TIGACD.EXE manually. For more information, see the README.WRI online
document.
</pre>
<p>TIGA is the <a href="https://en.wikipedia.org/wiki/Texas_Instruments_Graphics_Architecture"> Texas Instruments Graphics Architecture</a>, a standard for high-resolution graphics modes on PCs. It held some sway for a while but ultimately fell to competing standards like VESA and SuperVGA.</p>
<p>The <tt>TIGACD.EXE</tt> program is the TIGA Communications Driver which seems to be the program which implements the TIGA APIs for a particular class of video cards. You need to run this TSR so that the Windows TIGA driver can use these TIGA APIs to run the video cards in resolutions higher than standard VGA, like (gasp) 800×600.</p>
<p>But on the other hand, it&#8217;s probably the case that only Windows needs to be able to use the video card at such high resolution. Your MS-DOS programs will just use the standard VGA resolution, if they use graphics mode at all!</p>
<p>In fact, MS-DOS programs <i>cannot</i> use the TIGA modes. The graphics card vendors wrote 16-bit Windows graphics drivers, which teach 16-bit Windows how to draw graphics with those modes. But they did not write 32-bit Windows virtual display drivers, which teach the 32-bit Windows virtual machine manager how to give each virtual machine their own virtual TIGA video card, each of which could be in a different TIGA mode. For example, this 32-bit driver has to save the video card state and memory when the user switches out of a full-screen MS-DOS program, and then restore it when the user switches back. In other words, they did not provide the necessary support for multitasking TIGA graphics among Windows and MS-DOS sessions. TIGA can be used in only one virtual machine, and the obvious choice is to let Windows use it.</p>
<p>This was the recommendation from Microsoft in Windows 3.1, and it appears that <a href="https://support.industry.siemens.com/cs/document/114145/tiga-driver-under-win-95?dti=0&amp;lc=en-AO"> the recommendation was extended by Siemens to cover Windows 95 as well</a>.</p>
<p>So at least one vendor continued to use it in Windows 95. I wouldn&#8217;t be surprised if there were others that also used it, but we simply don&#8217;t see them because they have such small audiences.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260908-00/?p=112679">A sample use of the &lt;CODE&gt;winstart.bat&lt;/CODE&gt; file in Windows 95</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260908-00/?p=112679/feed</wfw:commentRss>
    <slash:comments>2</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>Why don&#8217;t we allow stacks to be sparse, instead of forcing them to be contiguous?</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260907-00/?p=112677</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260907-00/?p=112677#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Mon, 07 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[Code]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112677</guid>
    <content:encoded><![CDATA[<p>When I discussed <a title="Why don't we just make the entire stack out of guard pages?" href="https://devblogs.microsoft.com/oldnewthing/20260713-00/?p=112528"> why we don&#8217;t just make the entire stack out of guard pages</a>, <a href="https://devblogs.microsoft.com/oldnewthing/20260713-00/?p=112528&amp;commentid=144516#comment-144516"> commenter BCS wondered</a>, &#8220;Why require that the stack use contiguously mapped pages? What would break if only touched pages got mapped in? That could actually be a good thing for example with a function that wanted to <code>alloca</code> 512MB on the stack but only read/writes a few pages.&#8221;</p>
<p>So the question is asking why the stack must be contiguous. Why not let it be sparse and fault in only the pages that are touched?</p>
<p>The first issue is that the stack check code would have to include an explicit check against the stack limit, instead of just walking down the stack a page at a time. This explicit check is needed to avoid security vulnerabilities if somebody manages to <code>alloca</code> a buffer so large that it goes past the end of the stack reservation entirely. If you go a single page at a time, you will eventually hit the no-access page that marks the end of the stack. But if you can leap over multiple pages at a time without touching them, you might leap so far past the end of the stack that you land somewhere else and start corrupting that other memory because you&#8217;re using it as a stack. In linux circles, this vulnerability is nicknamed &#8220;<a href="https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt">Stack Clash</a>&#8220;¹ and goes more formally by &#8220;<a href="https://lwn.net/Articles/725832/">stack guard-page hopping</a>.&#8221;²</p>
<p>After fixing that issue, you have another problem: How would you report a failure to commit a page in the middle of the stack?</p>
<pre>void dosomething()
{
    void* buffer = NULL;
    __try {
        buffer = alloca(65536);
    } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW) {
        if (!_resetstkoflw()) __fastfail(FAST_FAIL_FATAL_APP_EXIT);
    }

    if (buffer != NULL) {
        ⟦ use the buffer ⟧
    }
}
</pre>
<p>If you allowed sparse stacks, then the memory for the <code>buffer</code> would not actually be committed until the code used it. But the point the code uses the buffer is <i>outside</i> the exception handler for the failed <code>alloca()</code>. The code assumes, not unreasonably, that if <code>alloca</code> succeeds, then the memory is indeed allocated.</p>
<p>I guess you could fix this by committing the memory without making it present. That would mean making a call to <code>Virtual­Alloc</code> to expand the stack rather than just accessing the memory. Not only would this make the stack expansion code more complicated, particularly since <a title="Windows stack limit checking retrospective, follow-up" href="https://devblogs.microsoft.com/oldnewthing/20260617-00/?p=112436"> you have to preserve all the registers that might possibly be used by any calling convention</a>, but you also have to make sure that the <code>Virtual­Alloc</code> function itself doesn&#8217;t allocate too much stack!</p>
<p>Now, you can still tweak the x86-32 stack prober to avoid <a href="https://devblogs.microsoft.com/oldnewthing/20260311-00/?p=112134&amp;commentid=143917#comment-143917"> pete.d</a>&#8216;s problem, where a large stack frame is made completely present, with the resulting page-ins creating noticeable performance issues. The x86-32 prober could short-circuit the stack probe (<a title="Windows stack limit checking retrospective: arm64, also known as AArch64" href="https://devblogs.microsoft.com/oldnewthing/20260320-00/?p=112154">like the MIPS and other processors listed in the table on this page</a>) so that the page-ins occur only when the stack is actually expanding.</p>
<p>¹ Bonus reading about Stack Clash:</p>
<ul>
<li><a href="https://developers.redhat.com/blog/2017/09/25/stack-clash-mitigation-gcc-background"> Stack Clash Mitigation in GCC &#8212; Background</a></li>
<li><a href="https://developers.redhat.com/blog/2019/04/30/stack-clash-mitigation-in-gcc-why-fstack-check-is-not-the-answer"> Stack Clash mitigation in GCC: Why -fstack-check is not the answer</a></li>
<li><a href="https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3"> Stack clash mitigation in GCC, Part 3</a></li>
</ul>
<p>² Some systems mitigate stack guard-page hopping by creating a really large no-access region beyond the end of the stack. However, this isn&#8217;t a fix; just a mitigation. It just makes people have to leap further to clear the no-access region. If you already have this vulnerability, it&#8217;s probably because an attacker can control the size of the allocation, in which case you didn&#8217;t really slow them down by much; they just have to put a bigger number in their attack payload.</p>
<p>Other systems address this more thoroughly by (surprise) probing each page of the stack in sequence.</p>
<p>Stack Clash continues to be a problem even though gcc had a solution in 2020. <a href="https://app.opencve.io/cve/CVE-2026-77658"> Here&#8217;s CVE-2026-77658 from just a few days ago</a>.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260907-00/?p=112677">Why don&#8217;t we allow stacks to be sparse, instead of forcing them to be contiguous?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260907-00/?p=112677/feed</wfw:commentRss>
    <slash:comments>3</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>What happens if you change a window class&#8217;s GCL_CB&#173;WND&#173;EXTRA?</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260904-00/?p=112675</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260904-00/?p=112675#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Fri, 04 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[Code]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112675</guid>
    <content:encoded><![CDATA[<p>After my historical look back on <a title="The evolution of system-windows window and class extra bytes" href="https://devblogs.microsoft.com/oldnewthing/20260629-00/?p=112484"> the evolution of system-windows window and class extra bytes</a>, I noted that <a title="A compatibility note on the abuse of extra bytes" href="https://devblogs.microsoft.com/oldnewthing/20260630-00/?p=112488"> there was one application that expected to be able to modify <code>GWW_<wbr />CB­CLS­EXTRA</code></a>.</p>
<p>It turns out that there are even more applications that expect to be able to modify <code>GWW_<wbr />CB­WND­EXTRA</code>. So many that it wasn&#8217;t worth creating an application compatibility exception for them.</p>
<p>So what happens when you modify <code>GWW_<wbr />CB­WND­EXTRA</code>, or its modern equivalent, <code>GWL_<wbr />CB­WND­EXTRA</code>?</p>
<p>The change in window extra bytes takes effect, but not retroactively.</p>
<p>Windows that are created after you change <code>CB­WND­EXTRA</code> receive the updated number of extra bytes, but windows that already exist are not modified. They still have the number of extra bytes that were assigned when the window was created.</p>
<p>Specifically to deal with people who change the number of window extra bytes on the fly, the system keeps track of what the number of extra bytes was <i>at the time the window was created</i>, and those are the bytes you get to access from that window. If you try to access the nonexistent bytes, you are told <code>ERROR_<wbr />INVALID_<wbr />INDEX</code>.</p>
<p>This does mean that you can get into a strange situation where <code>Get­Class­Long(hwnd, <wbr />GCL_<wbr />CB­WND­EXTRA)</code> tells you that you have 8 extra bytes, say, but if you use <code>Get­Window­Long(hWnd, 0)</code>, which asks for the <code>LONG</code> represented by bytes 0–3, you are told &#8220;Sorry, that&#8217;s out of range.&#8221; As far as you can tell, it is well within range. What you don&#8217;t know is that the window was created back when the <code>GCL_<wbr />CB­WND­EXTRA</code> was less than 4.</p>
<p>There is no way to ask a window, &#8220;How many extra bytes do you <i>really</i> have?&#8221; I mean, why the system go out its your way to improve the lives of people who are abusing it?</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260904-00/?p=112675">What happens if you change a window class&#8217;s &lt;CODE&gt;GCL_&lt;WBR&gt;CB&shy;WND&shy;EXTRA&lt;/CODE&gt;?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260904-00/?p=112675/feed</wfw:commentRss>
    <slash:comments>2</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>The case of the progress callback that never got called when progress happened</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260903-00/?p=112672</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260903-00/?p=112672#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Thu, 03 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[Code]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112672</guid>
    <content:encoded><![CDATA[<p>A colleague was trying to figure out why their progress handler wasn&#8217;t being called.</p>
<pre>// C#

async Task&lt;bool&gt; DownloadItemAsync(string id)
{
    var op = item.DownloadAsync(id);
    op.Progress += (s, pct) UpdateProgress(pct);
    var result = await op;
    ClearProgress();
    return result;
}
</pre>
<p>This is pretty standard stuff. Start the operation, hook up the progress, and then wait for the operation to complete. But they never got any progress.</p>
<p>I asked them to check if maybe the item was downloading so fast that they missed all the progress. But no, even if the download takes a long time, they never get any progress.</p>
<p>I suggested that they step through the <code>Download­Async</code> method to see where it raises progress, and then follow the execution to the point where the progress callback is supposed to be invoked, to see why it didn&#8217;t make it. (To be fair, this is a cross-language debugging problem, so it&#8217;s harder than it looks. I suggested just focusing on the C++ side: Wait for the COM-callable wrapper to be generated and set as the progress callback, and then set a breakpoint on that wrapper. If that breakpoint gets hit, but the C# code doesn&#8217;t run, then there is a problem in the projection. If the breakpoint never gets hit, then the problem is on the C++ side.)</p>
<p>My colleague came back with the answer. Here&#8217;s the code for <code>Download­Async</code>:</p>
<pre>// C++/WinRT

winrt::IAsyncOperationWithProgress&lt;bool, double&gt;
    AggregateSource::DownloadAsync(winrt::hstring id)
{
    std::wstring_view idview { id };
    auto pos = idview.find(L':');
    if (pos == std::wstring_view::npos) {
        co_return false;
    }

    auto providerId = Unescape(idview.substr(0, pos - 1));

    auto provider = GetProvider(providerId);
    if (!provider) {
        co_return false;
    }

    auto providerItemId = Unescape(idview.substr(pos + 1));
    co_return co_await provider.DownloadAsync(providerItemId);
}
</pre>
<p>The <code>Aggregate­Source</code> gathers items from multiple providers. The format of the <code>id</code> is a provider, a colon, and then an ID. (The provider ID and item ID are escaped, just in case they themselves happen to contain a colon.)</p>
<p>We look up the provider, and then ask the provider to download the item.</p>
<p>Do you see the problem?</p>
<p>The <code>Download­Async</code> does not generate any progress reports!</p>
<p>It never calls <code>co_await winrt::get_progress_token()</code>, much less call the token with a progress value to generate a progress report.</p>
<p>It&#8217;s apparent that what the code wants to do when it attaches the progress callback is to receive callbacks from the <i>inner</i> operation, the one that comes from the provider. However, the only <code>IAsync­Operation­With­Progress</code> that it has access to is the one returned by the <code>Aggregate­Source::<wbr />Download­Async</code> method.</p>
<p>The easy solution here is to get rid of the middle man and just return the provider&#8217;s <code>IAsync­Operation­With­Progress</code>. That way, the caller can connect to the underlying operation&#8217;s progress.</p>
<pre>winrt::IAsyncOperationWithProgress&lt;bool, double&gt;
    AggregateSource::DownloadAsync(winrt::hstring id)
{
    std::wstring_view idview { id };
    auto pos = idview.find(L':');
    if (pos == std::wstring_view::npos) {
        <span style="border: solid 1px currentcolor;">return <a title="Creating an already-completed asynchronous activity in C++/WinRT, part 8" href="https://devblogs.microsoft.com/oldnewthing/20240718-00/?p=109977">completed_async</a>(false);</span>
    }

    auto providerId = Unescape(idview.substr(0, pos - 1));

    auto provider = GetProvider(providerId);
    if (!provider) {
        <span style="border: solid 1px currentcolor;">return completed_async(false);</span>
    }

    auto providerItemId = Unescape(idview.substr(pos + 1));
    <span style="border: solid 1px currentcolor;">return provider.DownloadAsync(providerItemId);</span>
}
</pre>
<p>If you don&#8217;t believe in <code>completed_<wbr />async</code>, you can just write</p>
<pre>        return [] -&gt; winrt::IAsyncOperationWithProgress&lt;bool, double&gt; {
            return false;
        }();
</pre>
<p>I said that this is the easy solution. There&#8217;s also a hard solution, which we will have to look at later because I haven&#8217;t written it up yet.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260903-00/?p=112672">The case of the progress callback that never got called when progress happened</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260903-00/?p=112672/feed</wfw:commentRss>
    <slash:comments>2</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>The perils of binding to value types in XAML</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260902-00/?p=112668</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260902-00/?p=112668#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Wed, 02 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[Code]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112668</guid>
    <content:encoded><![CDATA[<p>A colleague ran into trouble with their XAML program. They were using a <code>FlipView</code> control to bind to a collection, but when the user tried to navigate the <code>FlipView</code> using an assistive technology tool, there were cases where the navigation failed.</p>
<p>Some time later, they came back with the solution to the mystery.</p>
<p>The team noticed that their data model consisted only of strings and other value types, so they decided to declare their data model as a <code>struct</code> rather than a full <code>runtimeclass</code>, thereby avoiding a lot of boilerplate typing.</p>
<p>If defined as a <code>runtimeclass</code>:</p>
<pre>// MyComponent.idl
runtimeclass MyPageContent
{
    String Title { get; };
    String Description { get; };
    String LinkUri { get; };
    Boolean IsNew{ get; };
}

// MyPageContent.h

namespace winrt::MyComponent
{
    struct MyPageContent : implements&lt;MyPageContent&gt;
    {
        MyPageContent(hstring const&amp; title,
                    hstring const&amp; description,
                    hstring const&amp; link,
                    bool isNew) :
            <span style="border: solid 1px currentcolor; border-bottom: none;">m_title(title),            </span>
            <span style="border: 1px currentcolor; border-style: none solid;">m_description(description),</span>
            <span style="border: 1px currentcolor; border-style: none solid;">m_link(link),              </span>
            <span style="border: solid 1px currentcolor; border-top: none;">m_isNew(isNew) {}          </span>

        hstring Title() const { return m_title; }
        hstring Description() const { return m_description; }
        hstring Link() const { return m_link; }
        bool IsNew() const { return m_isNew; }

    private:
        hstring m_title;
        hstring m_description;
        Windows::Foundation::Uri m_link;
        bool m_isNew;
    };
}

// Consumer.cpp

m_pages.Append(winrt::make&lt;MyPageContent&gt;(
                    title, description, link, isNew));
</pre>
<p>But if you define it as a <code>struct</code>, then most of this code isn&#8217;t necessary:</p>
<pre>// MyComponent.idl
<span style="border: solid 1px currentcolor;">struct</span> MyPageContent
{
    String Title;
    String Description;
    String Link;
    Boolean IsNew;
}

// <span style="text-decoration: line-through;">MyPageContent.h</span> not needed

// Consumer.cpp

m_pages.Append(MyPageContent(title, description, link, isNew));
</pre>
<p><a href="https://en.wikipedia.org/wiki/Miller_Lite#Advertising">Tastes great, less filling</a>.</p>
<p>Now, the thing that makes value types value types is that they are copy-by-value, not copy-by-reference. This means that when XAML calls <code>GetAt(n)</code> on the <code>m_pages</code> to get the <var>n</var>th item, it gets a <i>copy</i> of the <code>MyPageContent</code> and binds to the copy.</p>
<p>And that&#8217;s the source of the problem.</p>
<p>When the code wants to navigate to a specific item at the request of the assistive technology tool, it passes the <code>MyPageContent</code> to navigate to, but that&#8217;s just another copy because value types are always passed by copy. XAML says, &#8220;I don&#8217;t have that guy&#8221; and fails the navigation. (XAML doesn&#8217;t realize that it has a guy who <i>looks just like</i> that guy. Not that it matters, because it&#8217;s not the same guy.)</p>
<p>The clever shortcut turned out to be the problem.</p>
<p>Now, while it&#8217;s true that there&#8217;s a bunch of typing needed to implement a C++/WinRT runtime class, there are helpers to reduce the amount of typing required. In the Windows Implementation Library (wil), the <code>cppwinrt_authoring.h</code> header contains classes to simplify the implementation of events and properties. It exploits CRTP <a title="Exploiting C++/WinRT CRTP: Property and event declarations" href="https://devblogs.microsoft.com/oldnewthing/20230317-00/?p=107946"> in the same way I discussed some time ago</a>.</p>
<pre>// MyPageContent.h

namespace winrt::MyComponent
{
    struct MyPageContent : implements&lt;MyPageContent&gt;
    {
        MyPageContent(hstring const&amp; title,
                    hstring const&amp; description,
                    hstring const&amp; link,
                    bool isNew) :
            <span style="border: solid 1px currentcolor; border-bottom: none;">Title(title),            </span>
            <span style="border: 1px currentcolor; border-style: none solid;">Description(description),</span>
            <span style="border: 1px currentcolor; border-style: none solid;">Link(link),              </span>
            <span style="border: solid 1px currentcolor; border-top: none;">IsNew(isNew) {}          </span>

        <span style="border: solid 1px currentcolor; border-bottom: none;">wil::single_threaded_property&lt;hstring&gt; Title;      </span>
        <span style="border: 1px currentcolor; border-style: none solid;">wil::single_threaded_property&lt;hstring&gt; Description;</span>
        <span style="border: 1px currentcolor; border-style: none solid;">wil::single_threaded_property&lt;hstring&gt; Link;       </span>
        <span style="border: solid 1px currentcolor; border-top: none;">wil::single_threaded_property&lt;bool&gt; IsNew;         </span>
    };
}
</pre>
<p>We can get away with using a <code>single_<wbr />threaded_<wbr />property</code> because the properties are written only at construction, so concurrent reads are not going to cause problems.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260902-00/?p=112668">The perils of binding to value types in XAML</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260902-00/?p=112668/feed</wfw:commentRss>
    <slash:comments>6</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
		
  <item>
    <title>Microspeak: Funded / unfunded</title>
    <link>https://devblogs.microsoft.com/oldnewthing/20260901-00/?p=112662</link>
    <comments>https://devblogs.microsoft.com/oldnewthing/20260901-00/?p=112662#comments</comments>
    <dc:creator><![CDATA[Raymond Chen]]></dc:creator>
    <pubDate>Tue, 01 Sep 2026 14:00:00 +0000</pubDate>
    <category><![CDATA[Old New Thing]]></category>
    <category><![CDATA[Microspeak]]></category>
    <category><![CDATA[Other]]></category>
    <guid isPermaLink="false">https://devblogs.microsoft.com/oldnewthing/?p=112662</guid>
    <content:encoded><![CDATA[<p>Recall that Microspeak is not merely for jargon exclusive to Microsoft, but it&#8217;s jargon that you need to know to survive at Microsoft.</p>
<p>In business, <i>funding</i> usually refers to having enough money to pay for ongoing operations.</p>
<p>In Microsoft engineering groups, it doesn&#8217;t mean that.</p>
<p>In Microspeak, <i>funding</i> refers to having enough <i>people</i> available to work on a feature. A feature that has adequate people assigned to work on it is considered to be <i>funded</i>, or for emphasis, <i>fully funded</i>, whereas a feature that does not have people working on it is <i>unfunded</i>.</p>
<p>Of course, you can have intermediate states, like <i>partially funded</i>, to say that some people have been assigned to it, but not enough to finish the work in time for a specific requested completion date.</p>
<p>Here are some citations I found.</p>
<blockquote class="q"><p>Funding for this feature is being worked through.</p></blockquote>
<p>This is another way of saying, &#8220;We are working on finding people to work on this feature.&#8221; This might come at the cost of <i>defunding</i> whatever feature those people had previously been assigned to.</p>
<blockquote class="q"><p>The path for getting out of red involves closing on funding gaps.</p></blockquote>
<p>In other words, there is a color-coded dashboard on which a feature is currently listed as red. There are currently some shortfalls in staffing (<i>funding gaps</i>), and we will have to resolve (<i>close on</i>) those shortfalls in order to get out of red to a more favorable color.</p>
<blockquote class="q"><p>X said that they do not have engineering resources to fund the Y updates.</p></blockquote>
<p>In a larger discussion about updating components throughout the system to support the Y feature, person X said that they do not have any people available who can do the Y work for their component.</p>
<p>Note that a feature that is <i>unfunded</i> is not <i>cut</i>. The feature is still planned. It&#8217;s just that there is nobody available to do it right now. If funding cannot be obtained soon, the feature will have to be delayed to a later release.</p>
<p><b>Bonus chatter</b>: Software engineers are not fungible. If you take a developer who works on the taskbar and reassign them to the window manager they won&#8217;t be as effective as someone who normally works on the window manager. Furthermore, reassigning a developer across teams involves the receiving team having an <a title="Microspeak: Headcount, req, and related personnel terms" href="https://devblogs.microsoft.com/oldnewthing/20150317-00/?p=44453"> open <i>req</i></a>, and reqs are generally difficult to come by since they are subject to all sorts of business constraints.</p>
<p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260901-00/?p=112662">Microspeak: Funded / unfunded</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
]]></content:encoded>
    <wfw:commentRss>https://devblogs.microsoft.com/oldnewthing/20260901-00/?p=112662/feed</wfw:commentRss>
    <slash:comments>3</slash:comments>
    <image type="image/png" url="https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2025/10/banner-oldnewthing-blue.webp"/>
  </item>
	</channel>
</rss>
