The Old New Thing

Practical development throughout the evolution of Windows.

Latest posts

Nov 18, 2013
Post comments count 0
Post likes count 1

How can I launch an unelevated process from my elevated process and vice versa?

Raymond Chen

Going from an unelevated process to an elevated process is easy. You can run a process with elevation by passing the verb to or . Going the other way is trickier. For one thing, it's really hard to munge your token to remove the elevation nature properly. And for another thing, even if you could do it, it's not the right thing to do, because the unelevated user may be different from the elevated user. Let me expand on that last bit. Take a user who is not an administrator. When that user tries to run a program with elevation, the system will display a prompt that says, "Hey, like, since you're not an ad...

Nov 15, 2013
Post comments count 0
Post likes count 1

Restoring symbols to a stack trace originally generated without symbols

Raymond Chen

Has this ever happened to you? Ugh. A stack trace taken without working symbols. (There's no way that is a deeply recursive 60KB function. Just by casual inspection, you know that the symbols are wrong.) To see how to fix this, you just have to understand what the debugger does when it has no symbols to work from: It uses the symbols from the exported function table. For every address it wants to resolve, it looks for the nearest exported function whose address is less than or equal to the target value. For example, suppose has the following exported symbols: Look at it this way: The debugger is gi...

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

Why is my FormatMessage call crashing trying to read my insertion parameter?

Raymond Chen

A customer was looking for assistance in debugging a crash in their product. The stack trace looked like this: The string being formatted is , and the insertion is a long (but valid) string. A unit test which passes a similarly long object name to does not crash. What is the problem? There are clues in the stack trace. The natural place to start is the function that calls to see what parameters are being passed in. And that's where you see something strange: (The clue in the stack trace was the word fallback in the function name, which suggests that if the formatting attempt fails, it'll try again som...

Nov 13, 2013
Post comments count 0
Post likes count 1

A possibly unbeatable record for the shortest amount of time between an email message and its resend

Raymond Chen

I occasionally bring up the issue of people who ask a question and then repeat the question, especially people who repeat the question with some impatience. At the time, the record for the shortest time between the message and its repeat was eight minutes. But I think I have something unbeatable. From: X To: ABC Team I hit this crash in ABC. Can somebody take a look at it? A half hour later, somebody replied: From: A To: X, ABC Team This looks like the problem is really in the DEF component. You should have the DEF team look at it. Person X waited a few hours, then got impatient. From: X T...

Nov 12, 2013
Post comments count 0
Post likes count 1

Microspeak: Spinning up or kicking off a build

Raymond Chen

Round and round.

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

How did Raymond discover his carrier-screaming talent? And his homemade Marauder's Map

Raymond Chen

George wonders, "I am curious how Raymond found about his talent. Maybe it will be an interesting post." This isn't like a superhero who discovers as a young adult that he has powers beyond that of mortal men. And there was no radioactive spider. It was a simple case of problem-solving. The basic way of checking whether the mainframe was up was to go into the lab and see if the terminals responded. But of course this meant having to hang around in the lab building all day. The next way of checking whether the mainframe was up was to stay in your dorm room doing some other work while listening to a portable ...

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

What's the point of the various …WhenCallbackReturns functions?

Raymond Chen

The thread pool provides a number of functions named . What's the point of all these functions? Why can't you just do the operation yourself immediately before returning? We saw last time. What's the point of the others? Basically, the same thing as . It's a way to release a resource after execution has left the function and the callback is marked as complete. In the case of a synchronization resource, that resource may be what's keeping somebody from unloading your DLL, or it might protect a race condition between the callback function and a function that tries to cancel the callback.

Nov 7, 2013
Post comments count 0
Post likes count 1

Partially eliminating the need for SetThreadpoolCallbackLibrary and reducing the cost of FreeLibraryAndExitThread

Raymond Chen

Update: Daniel points out that there is still a race condition here, so this trick won't work. Rats. The documentation for the says This prevents a deadlock from occurring when one thread in DllMain is waiting for the callback to end, and another thread that is executing the callback attempts to acquire the loader lock. If the DLL containing the callback might be unloaded, the cleanup code in DllMain must cancel outstanding callbacks before releasing the object. Managing callbacks created with a that specifies a callback library is somewhat processor-intensive. You should consider other options for en...

Nov 6, 2013
Post comments count 0
Post likes count 1

CoUninitalize will ask a DLL if it is okay to unload now, but the answer is a foregone conclusion

Raymond Chen

The entry point is exported by COM in-proc servers. COM host applications call periodically to ask COM to do DLL housecleaning, and in response, COM asks each DLL if it is okay to be unloaded. If so, then COM unloads the DLL. What is not well-known is that COM also does DLL housecleaning when you shut down the last apartment by calling . When that happens, COM will still go around asking each DLL whether it's okay to be unloaded, but the question is merely a formality, because regardless of your answer, COM will unload you anyway. The story here is that COM is being shut down for the process, so COM knows ...