September, 2008

  • The Old New Thing

    For a place that's supposed to be full of doctors, they sure don't look like doctors


    Anthony Edwards is returning for a guest spot on his old series ER. I don't watch ER, but when I happen to stumble across it, the thing that strikes me most is that for a where most of the characters are supposed to be doctors, they sure don't look like doctors. They look like models who have been forced to wear scrubs and white lab coats.

    Except for Anthony Edwards. He actually looks like a doctor.

    One of my cousins is a doctor, and for some reason, we were watching an episode of ER in which the medical student was put in charge of a patient and made a bad medical decision. My cousin's reaction: "There's no way you would leave a med student alone with a patient, much less put them in charge. And never, ever pay any attention to a med student's diagnosis. If you ask med students for a diagnosis, they will tell you that the patient has whatever disease they studied last week."

    (Yes, I'm recycling a story, but I like that story, so nyeah.)

  • The Old New Thing

    Suggestion Box 3, short answers (part 2 of who knows how many)


    Another round of short answers to questions in the suggestion box.

    How does Windows choose the monitor a window maximizes to?

    The window maximizes to the monitor selected by MonitorFromWindow. The algorithm the MonitorFromWindow uses to select the monitor is documented in MSDN.

    How do you make your Win32 application safe from keyloggers?

    You can't. In the battle between kernel mode and user mode, user mode loses. That's why we have a distinction between kernel mode and user mode in the first place.

    Why should you ever call MessageBox from inside a message handler that is re-entrant? "I'm having a hard time explaining to people that it isn't a blocking call."

    I don't even understand the question. And it is a blocking call. The function doesn't return until the user responds to the message box.

    What happens when you pass NULL to ShellExecute, like you did in one of your articles? "Is UI suppressed if I pass NULL?"

    The window handle is used as the parent for any dialogs or messages that the ShellExecute function may need to display. If you pass NULL, then you get the same effect as if you had passed NULL to, say, MessageBox. In the article, the thread has no UI active, so any error messages displayed by the ShellExecute function will appear as top-level unowned windows. I discussed this issue in detail a few years ago. If you want to suppress UI, then pass the SEE_MASK_FLAG_NO_UI flag to ShellExecuteEx.

    Is there some way to use Explorer's filename sort function?

    It's called StrCmpLogical. Michael Kaplan discussed this function two years ago with a follow-up last year. Of course, if you want to mimic Explorer exactly, you also need to respect the REST_NOSTRCMPLOGICAL policy.

    Is there a way to sleep for less than one millisecond?

    I don't know either. I've never needed to do that. (I try to get eight hours each night.)

    Why are notification icons limited to 16 colors in Windows 95 and 2000?

    They were limited to 16 colors on Windows 95 to conserve memory. Windows 2000 inherited that code and by default, each version of Windows works the same as the previous one. There are millions of lines of code in the shell. It's not like somebody goes through every single one of them and says, "Gosh, should we change this line in the next version of Windows?"

    Does Raymond use _alloca?

    Nope. It wasn't in K&R C, so it's not part of my world view. And incautious use of _alloca can result in security vulnerabilities.

    Windows can only handle 64 threads.

    This statement is patently false. We've seen that even without taking any special precautions, we were able to pack about 2000 threads into a process before running out of address space. What the person probably meant to write is that 32-bit Windows supports a maximum of 32 processors. The reason is that the functions that manage sets of processors (such as SetThreadAffinity) use a 32-bit value to represent processor masks. Note that for 64-bit Windows, these masks were expanded to 64-bit integers, so 64-bit Windows supports up to 64 processors in principle.

    How does that Temporary Internet Files thing work?

    It's a shell namespace extension junction point.

    Why are some count parameters declared as signed integers?

    I don't think there's a profound reason for it. Each API designer is empowered to decide how their functions will work. After all, the original strlen function returned a signed integer, too. You might want to ask Brian Kernighan; he was doing it before Windows. (Signed integers do have the slight advantage of being resilient to integer underflow. If a and b are both non-negative integers, then a - b will never underflow.)

    Why does the desktop lose track of icons, so it has to refresh them?

    I'm not sure what you mean by "lose track of icons". Maybe you're asking about lost change notifications (in which case redirected folders can cause problems with lost network notifications). Or maybe you're talking about icon repositioning (maybe the previous icon locations weren't saved).

    Questions about DLL imports, exports, and cross-module memory

    I inadvertently answered this question in a rather long series of articles on DLL imports and exports, and a discussion of cross-module memory allocation.

    I want to see your blog stats.

    I thought that too, until I saw them. When you get over a million hits a month, a list of all the referrals is just a giant pile of noise. I haven't bothered analyzing the referrals because I have other things to do in my spare time that are more interesting.

    I'd love to see a series of things that are obvious to you but not obvious to everyone.

    How do I know what is obvious to me and not obvious to everyone?

    The next category is, of course, the people who ask questions on things that I listed as topics I am not inclined to cover.

    I have a problem (describes problem).

    I don't think your problem really is of general interest. But it's clear that you're not respecting the modality of the window.

    I'm trying to improve the performance of my specific scenario.

    This doesn't strike me as a topic of general interest.

    What are your thoughts on this research project? What are your thoughts on this Microsoft product?

    I think you confused me with Robert Scoble.

    I have a problem (describes problem).

    This doesn't strike me as a topic of general interest.

    Why does Internet Explorer do X?

    Internet Explorer is explicitly on the list of things I am unlikely to cover.

    Or the people who ask questions I've already answered or questions I've chosen to answer elsewhere.

    Help me modify files that I didn't write.

    Doing this breaks servicing.

    What is the long pause after listing a directory the first time?
    Answered in A brief and incomplete history of FAT32.

    And then there are the questions I can't or choose not to answer.

    Why does the window manager force windows fully on-screen when the workstation is unlocked?

    I don't know either. It makes sense to force windows on-screen after a change in resolution, but if the resolution didn't change between the lock and the unlock, there's really no need to go around "fixing up" window positions.

    What did Apple copy from Microsoft and vice versa?

    I'm not going to touch this one. I don't see any upside to my answering it, only downside, and I don't welcome the flamewar that will doubtless ensue.

    Do you know anything about this?


    Something about defragmenting.

    I have no special knowledge about defragmentation. Try The Filing Cabinet. They answered a few questions in one blog entry and even have a Defrag FAQ. Personally, I've been happy with Dave Whitney's defragmenter to defragment specifically-targeted files. (I don't defragment my entire drive because it seems like a waste of time.)

    A question about Aero glass

    I have no special knowledge about Aero glass.

    How about an under-the-hood look at the Windows Vista Start menu?

    I didn't work on the Windows Vista Start menu, so I don't know how it works.

    Do you have any insights into the evolution of WinHelp?

    Sorry, I'm an outsider just like you when it comes to help technologies.

    Long rambling question about ACCESS_DENIED

    I quickly lost interest.

    Please explain the subtleties of the ScrollWindowEx function when scrolling child windows.

    I don't know the answer and I don't feel like doing the research necessary to find out. Sorry. The fact that I left it unanswered from the previous suggestion box should have been a clue.

    That's all for this year.

  • The Old New Thing

    And now, your moment of reflection


    Master storyteller Ira Glass teaches us how to tell a story, and the importance of the moment of reflection. (In the third video he explains why when you are trying to do something creative you always suck, and that's okay.)

    And once you've soaked up Ira's advice, you can admire Kasper Hauser's parodies: Going Postal and Phantom High School.

  • The Old New Thing

    What were ShellExecute hooks designed for?


    Windows 95 introduced (and Windows Vista removed) the concept of ShellExecute hooks. These are objects which implemented the IShellExecuteHook interface. That interface had just one method: IShellExecuteHook::Execute, which took a SHELLEXECUTEINFO structure and returned S_OK to indicate that the item was executed, S_FALSE to allow processing to continue, and an error code to halt processing.

    The intended purpose of the shell execute hook was to allow you to extend the set of strings that can be executed. For example, Internet Explorer 1 used a shell execute hook so that you could type into the Run dialog and invoke the Web browser. This was necessary because the original version of Windows 95 had no special knowledge of URLs. Without the hook, typing a URL into the Run dialog would have generated an error.

    Let's look at those return values again. The simplest return value is S_FALSE, which means that you didn't recognize the item and wish to continue normal processing. Returning S_OK means that you recognized the item and successfully executed it. Returning an error code means that you recognized the item but an error occurred when you tried to execute it. Returning an error stops further processing, which is important in this case, because you do want to stop processing: You recognized what the user was trying to do and you couldn't do it. If you had returned S_FALSE, then the shell (and other shell execute hooks) would take their shot at executing the item. Since it's something only you recognize, they would fail, and the user would get some sort of error like "File not found" instead of an error that accurately describes why you couldn't execute the item.

    That's the theory, but I've seen a few applications that use shell execute hooks for completely different purposes. And they are doomed to failure. One application installs a shell execute hook in order to implement some sort of weird concept of "security". When their hook is called, they check whether the user is "allowed" to run the program; if allowed, they return S_FALSE and if blocked, they return E_ACCESSDENIED. Another application uses their hook to log all the programs that the user runs, presumably so the logs can be inspected for auditing purposes. After logging the action, they return S_FALSE to allow normal execution to continue.

    Both of these methods are really an abuse of the shell execute hook model since they aren't extending the set of items that can be executed by the shell. They're just using the hook model to sneak some code into the execute path. But that's also the problem.

    First, they are intercepting only actions that go through the ShellExecuteEx function. If somebody just calls CreateProcess directly, then the shell execute hooks won't run, and whoever it is just snuck past your "security" and "auditing" system.

    Second, these hooks both assume that they are the only shell execute hook in the system. (Remember, there can be more than one.) Suppose there are three hooks installed, the hook installed by Internet Explorer to handle URLs, the "auditing" hook, and the "security" hook, and suppose that the shell decides to invoke them in that order. (The order in which hooks are executed is unspecified because, if you use them as intended, the order doesn't matter.) If the user types a URL into the Run dialog, the URL hook launches the Web browser and returns S_OK to say, "I took care of this one." Your "auditing" hook never got to see the URL, and your "security" hook never got a chance to reject the operation. Hooks that sit ahead of the "security" hook not only get to bypass security, but they also elude the "auditing" hook.

    So much for "auditing" and "security".


    Since shell execute hooks effectively become part of the ShellExecute function, they are unwittingly subject to all the application compatibility constraints that ShellExecute must follow. Welcome to the operating system. Your world has just gotten a lot more complicated.

    There is no "list of application compatibility constraints" (oh how life would be simple if there were); basically, anything that ShellExecute did in the past is a de facto compatibility constraint. Some programs crash if you create a worker thread inside ShellExecute; other programs crash if you call PeekMessage inside ShellExecute. Some programs call ShellExecute and immediately exit, which means that your shell execute hook had better not return before its work is done (or at least before the work has been given to another process to finish). Some programs call ShellExecute on an unusually small stack, so you have to watch your stack usage. And even though it is called out in the documentation that programs should not call shell functions from inside DllMain, that doesn't stop people from trying, anyway. Your shell execute hook had better behave in a sane manner when called under such "impossible" conditions.

  • The Old New Thing

    If you use an absurd signature, I might end up sending it back to you


    Despite my previous rant, absurdly elaborate email signatures are still common at Microsoft, and I'm not just talking about the ones that contain information that may be required by department policy. I'm talking about signatures that use bright colors, large fonts, maybe a bitmap or two, sometimes even a photo of the sender! I will sometimes mention in my reply, "Please consider making your signature less eye-catching. It distracts from the text of your message." But other times, I just incorporate it in to the reply more directly:

    From: John Doe

    Blah blah blah question blah blah blah.

    John Doe
    Technical Liaison

    telephone: 425-555-1212
    mobile: [available upon request]
    Make sure to visit my blog!

    My reply might go like this:

    To: John Doe

    Hi, John Doe.

    Blah blah blah answer blah blah blah.

  • The Old New Thing

    I'll see (some of) you in Los Angeles, but this time it'll be October


    (It was September last time.)

    I've been asked to step in as a replacement speaker for the 2008 PDC. The details of the talk are not yet publically available, but what I can say is that the topic will be in the category of Win32 programming.

    Disclaimers: Information was believed to be accurate at press time. Speakers subject to change. Talk may be changed or cancelled for reasons outside my control, or possibly even reasons within my control. This posting is provided as is with no warranties, and confers no rights. Not recommended for children. Some settling may occur during shipping. If symptoms persist, see a doctor.

  • The Old New Thing

    QueryPerformanceCounter counts elapsed time, not CPU cycles


    An anonymous coward asks whether the QueryPerformanceCounter function counts elapsed time or CPU cycles.

    It counts elapsed time. It has to, since its value is governed by the QueryPerformanceFrequency function, which returns a number specifying the number of units per second, and the frequency is spec'd as not changing while the system is running.

    For CPUs that can run at variable speed, this means that the HAL cannot use an instruction like RDTSC, since that does not correlate with elapsed time. Commenter "A" appears to have found a buggy HAL that failed to take this into account and returns values that do not correlate with elapsed time.

    What would it take to create a counter that was tied to CPU cycles? Well, first, you'd have to come up with some definition of "CPU cycles" that is architecture-neutral. Maybe you'd say that it's a 64-bit value that increments at a rate proportional to the amount of work the CPU has done. And then you have to come up with some sort of definition of what should happen on multi-processor machines. What if you have two CPUs, one of which has gone into a HLT state (not running), while the other is busy doing work? Should the "cycle counter" run at half speed, since only half of the CPUs are running at full speed? What about hyperthreaded processors? It's all so confusing.

    As a final remark, commenter Ulric wanted to know what I meant when I wrote, "Throw in a handful of workarounds for known buggy hardware." What I meant was that the people who write HALs are aware of various types of buggy hardware and added code to detect that buggy hardware and work around the problems.

  • The Old New Thing

    Tales from the interview: Anticipating your own incompetence is not a good interview strategy


    Some years ago, there was a candidate who was interviewing for a programming position in my group. The first interviewer asked the candidate about career plans with that old standby, "Where do you see yourself in five years?"

    — In five years, I see myself in program management.

    This is a fair answer. Many people see programming as a stepping stone to management. It doesn't have to be, but it's certainly a career path more than one person has taken.

    My colleague decided to probe further. "What is it about program management that appeals to you?"

    — Well, after five years, all the kids graduating from college will be so much smarter than me, and they'll know all about the latest technologies, so I won't be able to cut it as a programmer any more. I'd have to go into management.

    It's bad enough that your career plan includes never developing any new skills and "failing upward" into management. It's another thing to anticipate it in your interview.

  • The Old New Thing

    Tales from the interview: Lunch is not a competition, episode 2


    Last time, we saw the consequences of failing to recognize that lunch is not a competition. Today we'll see an even more unfortunate result.

    One candidate went to lunch with my colleague the economist. (Claim to fame: "Jenna von Oÿ is my cousin!") They went to a local Thai restaurant, Thai being a very popular cuisine here in the Seattle area. The afternoon interviews showed a marked change for the worse from the morning interviews, and the afternoon interviewers began to ask, "What happened at lunch? The candidate was doing really well in the morning, but in the afternoon, had difficulty concentrating and didn't look all that well."

    My colleague fessed up. "Yeah, sorry about that. We went to a Thai restaurant, and for some reason, ordering lunch turned into a competition. I'm not really that good with spicy food, and obviously neither is the candidate, but somehow our competitive natures took over and we ended up trying to one-up each other with how spicy we could order the dishes, and, well, you can see what happened. If it's any consolation, I'm not feeling all that great either."

    I don't know what the resolution to the situation was, but I hope the candidate was given a second chance.

    Remember, folks, lunch is not a competition. You will not be evaluated on the strength of your stomach lining.

  • The Old New Thing

    Tales from the interview: Lunch is not a competition


    One thing that many interview candidates fail to comprehend is that lunch is not a competition. You're not auditioning for Fear Factor. No matter how many times we explain this, candidates don't believe it.

    One of my colleagues took a candidate to lunch. As is typical, the candidate is asked whether there was any particular preference or phobia, and as is also typical, the candidate expressed no preference (trying not to look difficult). My colleague explained, "Okay, well, I like sushi, but please, if you don't like sushi, please just say so, and we can go to an Italian or Mexican place or even just grab a burger."

    — No, sushi is fine was the response.

    My colleague hesitantly took the candidate to a local sushi place. The two were seated and the wait staff came to take their order. From the way the candidate nervously read the menu, my colleague began to suspect that the candidate had never had sushi before.

    "Okay, now remember, you can order whatever you want. You don't have to order the sushi. They have all sorts of cooked food on the menu, too. Just order whatever you would like to have for lunch. I'm going to have (among other things) the salmon roe with raw quail egg, but please, that's just my personal preference."

    — Um, okay, yeah, I'll have the same thing.

    "Are you sure?"

    — Yeah.

    The food was delivered, and the interview candidate sort of started at it suspiciously.

    Fortunately, my colleague realized that without remedial action, somebody at the lunch table was going to starve and convinced the candidate to order some veggie yakisoba.

    Disclaimer: This story is a reconstruction from a conversation from over two years ago. Some details may be incorrect. I can't believe I had to write this, but apparently some people carefully deconstruct every word of these stories in order to call out any flaws or weaknesses.

Page 3 of 4 (33 items) 1234