The Old New Thing

Practical development throughout the evolution of Windows.

Latest posts

Jan 14, 2013
Post comments count 0
Post likes count 1

How can I write a script that finds my top-rated photos?

Raymond Chen

I'm not sure if I'll be able to keep it up, but I'm going to see if I can make Monday "Little Programs" day, where I solve simple problems with little programs. Today's little program is a script that goes through your Pictures folder and picks out your top-rated photos. The key step here is extracting the rating, which goes by the name System.Rating in the shell property system. The method which does the extraction is Shell­Folder­Item.Extended­Property. var shell = new ActiveXObject("Shell.Application"); var picturesFolder = shell.Namespace(39); // CSIDL_MYPICTURES var items = picturesFolde...

Jan 11, 2013
Post comments count 0
Post likes count 1

Understanding errors in classical linking: The delay-load catch-22

Raymond Chen

Wrapping up our week of understanding the classical model for linking, we'll put together all the little pieces we've learned this week to puzzle out a linker problem: The delay-load catch-22. You do some code cleanup, then rebuild your project, and you get LNK4199: /DELAYLOAD:SHLWAPI ignored; no imports found from SHLWAPI What does this error mean? It means that you passed a DLL via the /DELAYLOAD command line switch which your program doesn't actually use, so the linker is saying, "Um, you said to treat this DLL special, but I don't see that DLL." "Oh, right," you say to yourself. "I got rid of a c...

Jan 10, 2013
Post comments count 0
Post likes count 1

Understanding the classical model for linking: Sometimes you don’t want a symbol to come along for a ride

Raymond Chen

Continuing our study of the classical model for linking, let's take another look at the trick of taking symbols along for the ride. The technique of taking symbols along for the ride is quite handy if that's what you want, but sometimes you don't actually want it. For example, a symbol taken along for the ride may create conflicts or create unwanted dependencies. Here's an example: Suppose you have a library called stuff.lib where you put functions that are used by various modules in different projects. One of the files in your library might look like this: // filedatestuff.cpp BOOL GetFileCreationTimeW(...

Jan 9, 2013
Post comments count 0
Post likes count 0

The enduring cultural fascination with Queen’s Bohemian Rhapsody

Raymond Chen

Bohemian Rhapsody was not part of my world growing up, so I view the continuing cultural fascination with the piece with detached confusion. The hallmark of cultural preoccupation is the fact that the Wikipedia entry deconstructs the piece moment by moment, clocking in at over 2000 words, far in excess of the Wikipedia recommendation of a 60-word summary for a 6-minute piece (10 words per minute). And longer than the entire Wikipedia page for Ruth Bader Ginsburg.

Jan 9, 2013
Post comments count 0
Post likes count 1

Understanding the classical model for linking: You can override an LIB with another LIB, and a LIB with an OBJ, but you can’t override an OBJ

Raymond Chen

If you study the classical model for linking, you'll see that OBJ files provided directly to the linker have a special property: They are added to the module even if nobody requests a symbol from them. OBJs bundled into a library are pulled into the module only if they are needed to resolve a needed symbol request. If nobody needs a symbol in the OBJ, then the OBJ doesn't get added to the module. On the other hand, OBJs handed directly to the linker get added to the module whether anybody wants them or not. Last time, we learned about the along for the ride technique which lets you pull components into a modu...

Jan 8, 2013
Post comments count 0
Post likes count 1

Understanding the classical model for linking: Taking symbols along for the ride

Raymond Chen

Last time, we learned the basics of the classical model for linking. Today, we'll look at the historical background for that model, and how the model is exploited by libraries. In the classical model, compilers and assemblers consume source code and spit out an OBJ file. They do as much as they can, but eventually they get stuck because they don't have the entire module at their disposal. To record the work remaining to be done, the OBJ file contains various sections: a data section, a code section (historically and confusingly called text), an uninitialized data section, and so on. The linker resolves symbol...

Jan 7, 2013
Post comments count 0
Post likes count 2

Understanding the classical model for linking, groundwork: The algorithm

Raymond Chen

The classical model for linking goes like this: Each OBJ file contains two lists of symbols. Provided symbols: These are symbols the OBJ contains definitions for. Needed symbols: These are symbols the OBJ would like the definitions for. (The official terms for these are exported and imported, but I will use provided and needed to avoid confusion with the concepts of exported and imported functions in DLLs, and because provided and needed more clearly captures what the two lists are for.) Naturally, there is other bookkeeping information in there. For example, for provided symbols, not only is the...

Jan 4, 2013
Post comments count 0
Post likes count 1

What’s the guidance on when to use rundll32? Easy: Don’t use it

Raymond Chen

Occasionally, a customer will ask, "What is Rundll32.exe and when should I use it instead of just writing a standalone exe?" The guidance is very simple: Don't use rundll32. Just write your standalone exe. Rundll32 is a leftover from Windows 95, and it has been deprecated since at least Windows Vista because it violates a lot of modern engineering guidelines. If you run something via Rundll32, then you lose the ability to tailor the execution environment to the thing you're running. Instead, the environment is set up for whatever Rundll32 requests. You get the idea. Note also that Rundll32 ass...

Jan 3, 2013
Post comments count 0
Post likes count 1

Why does my program run really slow or even crash (or stop crashing, or crash differently) if running under a debugger?

Raymond Chen

More than once, a customer has noticed that running the exact same program under the debugger rather than standalone causes it to change behavior. And not just in the "oh, the timing of various operations changed to hit different race conditions" but in much more fundamental ways like "my program runs really slow" or "my program crashes in a totally different location" or (even more frustrating) "my bug goes away". What's going on? I'm not even switching between the retail and debug versions of my program, so I'm not a victim of changing program semantics in the debug build. When a program is running under ...