The Old New Thing
Practical development throughout the evolution of Windows.
Latest posts

There's the interface contract, and there are the implementations of the interface contract

Ivo wants to know whether it is legal to use as the icon parameters to . The documentation says that the parameters are optional, but some shell folder implementations treat them as mandatory. Yes, the parameters are technically optional, but it's also the case that many people mess up their implementation of the interface and treat them as mandatory, either by crashing on a null pointer or by returning . Since is an extension interface, you are pretty much at the mercy of all the implementations of that extension. Welcome to the land of application compatibility, where you have to incorporate workarounds fo...

Registration-free COM the old-fashioned way: The car mp3 player

Windows XP introduced Registration-Free COM, permitting you to place your COM object registrations in a manifest rather than in the registry. Very handy when you want to support xcopy deployment or running directly off a thumb drive. And very much in keeping with the principle of not using a global solution for a local problem. (If you need your COM object to be used from other programs, then global registration is not unreasonable, but if the only client is another part of your program, then you have a local problem that should employ a local solution.) Here are some articles on the subject: Before man...

You can use an OVERLAPPED structure with synchronous I/O, too

Even if you didn't open a file with , you can still use the structure when you issue reads and writes. Mind you, the I/O will still complete synchronously, but you can take advantage of the other stuff that has to offer. Specifically, you can take advantage of the and members to issue the I/O against a file location different from the current file pointer. (This is a file pointer in the sense of and not in the sense of the C runtime .) If your program does a lot of reads and writes to random locations in a file, using the synchronous structure saves you a call to at each I/O. Let's illustrate this by ...

I totally presented to an executive the wrong way

Some time ago, Gray Knowlton wrote an article on how to present to an executive. As you might have guessed, I've done it completely the wrong way. Many years ago, I was part of a group presenting to a senior-level executive. I was the one who wrote the document establishing the background for the topic and laying out the various options with their pros and cons. I wasn't the one doing the actual presenting, but I was asked to attend anyway, just in case the senior executive had a question that the presenters couldn't answer. For the duration of the meeting, I sat in the back and knitted. As it turns out, I...

Introducing the unrolled-switch anti-pattern

Over the years, I've seen a bunch of coding anti-patterns. I figured maybe I'll share a few. Today, I'll introduce what I'm calling the unrolled-switch anti-pattern, also known as "Specialization is always faster, right?" As we all know, special-case code is faster than general-purpose code. Instead of writing slow general-purpose code: we unroll it into a switch statement, thereby generating highly-optimized special-purpose code, one for each axis. What makes this anti-pattern particularly frustrating is that you cannot tell at a glance whether all the cases really are the same (just with different axe...

If posting here is frequently frustrating and irritating, why do I keep doing it?

Appreciator wonders, if I find posting here frequently frustrating and irritating, why I keep doing it anyway? Imagine I announced one day, "This is too frustrating and annoying. I'm going to stop now." To the rest of the world, this would "mean something." People would discuss in hushed tones—and for the Internet, hushed tones means in a normal voice, or perhaps even louder than normal—what this "means" for blogging, for Microsoft, for whatever. People would start speculating as to what pushed me over the line, maybe muse about what this means for other bloggers, or question my actual motivations. ...

How do I perform shell file operations while avoiding shell copy hooks?

Okay, the subject line of the article gives away the answer to the puzzle, but here's the puzzle anyway: A customer reported a problem with the function: Consider the following program: If "a" is a file, then everything works fine, but if it's a directory, then Application Verifier raises the following error: Heap violation detected Memory access operation in the context of a freed block: reuse-after-delete or double-delete Can you help explain what we're doing wrong? So far as we can tell, all our parameters are correct. This is one of those "It doesn't work on my machine" issues, because the prov...

Why can't I delete a file immediately after terminating the process that has the file open?

A customer discovered a bug where terminating a process did not close the handles that the process had open, resulting in their emergency cleanup code not working: Their workaround was to insert a call to before deleting the file. The customer wanted to know whether they discovered a bug in , and they were concerned that their workaround could add up to a half second to their cleanup code, during which the end user is sitting there waiting for everything to clean up. As MSDN notes, TerminateProcess initiates termination and returns immediately. This stops execution of all threads within the process and r...

Converting to Unicode usually involves, you know, some sort of conversion

A colleague was investigating a problem with a third party application and found an unusual window class name: L"整瑳整瑳". He remarked, "This looks quite odd and could be some problem with the application." The string is nonsense in Chinese, but I immediately recognized what was up. Here's a hint: Rewrite the string as L"\x6574" L"\x7473" L"\x6574" L"\x7473" Still don't see it? How about looking at the byte sequence, remembering that Windows uses UTF-16LE. 0x74 0x65 0x73 0x74 0x74 0x65 0x73 0x74 Okay, maybe you don't have your ASCII table memorized. That's right, the app...