The Old New Thing

Practical development throughout the evolution of Windows.

Latest posts

Notes on calculating constants in SSE registers
Dec 15, 2014
Post comments count 0
Post likes count 0

Notes on calculating constants in SSE registers

Raymond Chen
Raymond Chen

There are a few ways to load constants into SSE registers. Load them from memory. Load them from general purpose registers via . Insert selected bits from general purpose registers via . Try to calculate them in clever ways. Loading constants from memory incurs memory access penalties. Loading or inserting them from general purpose registers incurs cross-domain penalties. So let's see what we can do with clever calculations. The most obvious clever calculations are the ones for setting a register to all zeroes or all ones. These two idioms are special-cased in the processor and execute faster th...

Detecting whether a SID is well-known SID
Dec 12, 2014
Post comments count 0
Post likes count 0

Detecting whether a SID is well-known SID

Raymond Chen
Raymond Chen

You might think that the function would tell you whether a SID is well-known, but it doesn't. Rather, it tells you whether a SID exactly matches the well-known SID you specified. For example, you can ask, "Is this the Authenticated Users SID?" or "Is this the Everyone SID?" But you can't ask, "Is this any type of well-known SID?" I guess you could enumerate through all the well-known SIDs, and check if your SID matches any of them, but that's getting kind of ugly. If what you're interested in is whether this is a machine-relative SID (or a domain-relative SID, which is the special case where the machine is ...

What states are possible in a DRAWITEMSTRUCT structure?
Dec 11, 2014
Post comments count 0
Post likes count 0

What states are possible in a DRAWITEMSTRUCT structure?

Raymond Chen
Raymond Chen

The structure has an member which contains a number of bits describing the state of the item being drawn. How do those states map to the underlying control? Most of the states are rather obvious. For a list box item to be selected, it means that the item is part of the selection. But what does selected mean for a button? Since people like tables, I'll put the answer in a table: Okay, now that it's all in a table, how do I read the table? A box is blank if the corresponding flag is not currently used by the control type. (No guarantees about the future.) For example, as of this writing, button controls do ...

If you get a procedure address by ordinal, you had better be absolutely sure it's there, because the failure mode is usually indistinguishable from success
Dec 10, 2014
Post comments count 0
Post likes count 0

If you get a procedure address by ordinal, you had better be absolutely sure it's there, because the failure mode is usually indistinguishable from success

Raymond Chen
Raymond Chen

A customer reported that the function was behaving strangely. We have this code in one of our tests: Recently, this test started failing in bizarre ways. When we stepped through the code, we discovered that ends up calling instead of . The first time we try to test , we get stack corruption because has a different function prototype from , and of course on top of that the test fails horribly because it's calling the wrong function! When trying to narrow the problem, we found that the issue began when the test was run against a version of the DLL that was missing the function entirely. The line wa...

The psychology of confirmation, or something, I don't know what to call it
Dec 9, 2014
Post comments count 0
Post likes count 1

The psychology of confirmation, or something, I don't know what to call it

Raymond Chen
Raymond Chen

There is probably a name for this phenomenon. I will illustrate it below. "Is there a way to configure the system to do X?" — Go to the Y dialog and select Z. "It doesn't work." — I just tried it. It works for me. I'm using ⟨configuration details⟩. "Thanks. It's working."

Creating double-precision integer multiplication with a quad-precision result from single-precision multiplication with a double-precision result
Dec 8, 2014
Post comments count 0
Post likes count 0

Creating double-precision integer multiplication with a quad-precision result from single-precision multiplication with a double-precision result

Raymond Chen
Raymond Chen

Suppose you want to multiply two double-word values producing a quad-word result, but your processor supports only single-word multiplication with a double-word result. For concreteness, let's say that your processor supports 32 × 32 → 64 multiplication and you want to implement 64 × 64 → 128 multiplication. (Sound like any processor you know?) Oh boy, let's do some high school algebra. Let's start with unsigned multiplication. Let x = A × 2³² + B and y = C × 2³² + D, where A, B, C, and D are all in the range 0 … 2³² − 1. Each of the multiplications (not counting the power-of-two multiplications) is a 32 × 3...

Killing a window timer prevents the WM_TIMER message from being generated for that timer, but it doesn't retroactively remove ones that were already generated
Dec 5, 2014
Post comments count 0
Post likes count 0

Killing a window timer prevents the WM_TIMER message from being generated for that timer, but it doesn't retroactively remove ones that were already generated

Raymond Chen
Raymond Chen

Calling to cancel a window timer prevents messages from being generated for that timer, even if one is overdue. In other words, give this sequence of operations: no message is ever generated. Even though a timer became due during the , no timer message was generated during the sleep because timer messages are generated on demand, and nobody demanded one. Killing the timer then removes the ability to demand a timer message, and the result is that no message ever appears. In general, this means that once you kill a timer, you will not receive any messages for that timer. Unless you demanded one while ...

If my WM_TIMER handler takes longer than the timer period, will my queue fill up with WM_TIMER messages?
Dec 4, 2014
Post comments count 0
Post likes count 0

If my WM_TIMER handler takes longer than the timer period, will my queue fill up with WM_TIMER messages?

Raymond Chen
Raymond Chen

A customer was worried that they may have a problem with their message queue filling with messages. "If my handler takes longer than the timer period, will my queue fill up with messages?" As we should know by now, timer messages are generated on demand: The WM_TIMER message is a low-priority message. The Get­Message and Peek­Message functions post this message only when no other higher-priority messages are in the thread's message queue. Here's the basic algorithm. (I'm ignoring filtering and I'm assuming that messages are removed.) Notice that the generated messages are generated on demand ...

What happens if I don't paint when I get a WM_PAINT message?
Dec 3, 2014
Post comments count 0
Post likes count 0

What happens if I don't paint when I get a WM_PAINT message?

Raymond Chen
Raymond Chen

Suppose your window procedure doesn't paint when it gets a message. What happens? It depends on how you don't paint. If you have an explicit handler for the message that does nothing but return without painting, then the window manager will turn around and put a new message in your queue. "And try harder this time." Remember that the rules for the message are that the window manager will generate a message for any window that has a dirty region. If you fail to remove the dirty region in your message handler, well, then the rules state that you get another message. (The most common way of clearing the ...