• The Old New Thing

    What if two programs did this?


    The thought experiment "Imagine if this were possible" is helpful in thinking through whether Windows lets you do something or other. (A special case of this is "When people ask for security holes as features.") If the possibility leads to an obvious contradiction or the violation of generally-accepted rules of metaphysics, then you can be pretty sure that Windows doesn't support it. (Of course, the absence of such a contradiction doesn't prove that Windows does support it. But you can use it to rule out obvious bad ideas.)

    The question "What if two programs did this?" is also helpful in evaluating a feature or a design request. Combining this with "Imagine if this were possible" leads to an impressive one-two punch. Here are a few examples:

    "How do I create a window that is never covered by any other windows, not even other topmost windows?"

    Imagine if this were possible and imagine if two programs did this. Program A creates a window that is "super-topmost" and so does Program B. Now the user drags the two windows so that they overlap. What happens? You've created yourself a logical impossibility. One of those two windows must be above the other, contradicting the imaginary "super-topmost" feature.

    "How do I mark my process so that it always the first/last to receive the system shutdown notification? I want to do something before/after all other programs have shut down."

    Imagine if this were possible and imagine if two programs did this. You now have two programs both of which want to be first/last. But you can't have two first or two last things. One of them must lose. (This of course generalizes to other things people might want to be first or last.)

    "How do I make sure that my program is always the one that runs when the user double-clicks an .XYZ file?"

    Imagine if this were possible and imagine if two programs did this. Now the user double-clicks an .XYZ file. Which program runs?

    In this case, the solution is to leave the user in charge of their file associations; if they decide that they want your competitor's program to be used for .XYZ files, then that's their decision and you should respect it.

    My colleague Zeke [link fixed 11am], who is responsible, among other things, for the way file associations work in Explorer, provides a few alternatives:

    Here is the entry point in MSDN to the documentation on file associations in Explorer.

    For many of these "I want to be the X-est"-type questions, you can often come up with some sort of hack, where you run a timer that periodically checks whether you are still X, and if not, pushes you back into the X-position. And then you stop and think, "What if two programs did this?" and realize that it's a bad idea. At least I hope you do.

    Even with this explanation, some people still don't get it. I'll ask them to consider, "What if two programs did this? They'll be fighting back and forth," and the answer I get back is, "Then I can have the second program check if the first program is already running." They don't understand that they didn't write the second program.

    When two programs "duke it out" like this, you can't predict which one will win, but you can predict with 100% certainty who will lose: The user.

    I remember well when one of my colleagues called me into his office to show me two very popular commercial programs that both wanted to guarantee that they were the program that ran when the user double-clicked an .XYZ document. Since there is no such guarantee, they faked it with the timer hack.

    You installed the first program, it set itself as the .XYZ file handler, and everything seemed normal. You then installed the second program, it set itself as the new .XYZ file handler, and the first program noticed and said, "Uh-uh, I'm the program that runs .XYZ files", and changed things back. Then the second program said, "No way, I'm the program that runs .XYZ files" and set itself back.

    This childish game of "Nuh-uh/Yuh-huh!" went on while the user sat there dumbfounded and helpless, watching the icon for their .XYZ files flicker back and forth between the two programs, both of whom egotistically believed they were doing the user a "favor" by insisting on being the program that runs .XYZ files.

  • The Old New Thing

    Adam Felber teaches us how to avoid setting off motion detectors


    In a sidebar discussion on this week's episode of Wait Wait, Don't Tell Me, Adam Felber explains that "you can foil most motion detectors with a pair of insulated gloves, a piece of plywood, and a hat." [Windows Media] [RealPlayer]

  • The Old New Thing

    A quick puzzle about security and synchronization


    This quick puzzle floated past one of our internal discussion groups.

    // in process A
    hEventA = CreateEvent(NULL, FALSE, TRUE, TEXT("MyNamedEvent"));
    // in process B
    hEventB = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("MyNamedEvent"));
    WaitForSingleObject(hEventB, INFINITE);

    In Process B, the OpenEvent succeeds, but the WaitForSingleObject returns immediately instead of waiting. Explain.

    [Correction: I confused the matter by passing TRUE as the third parameter, thereby creating an event that is initially signalled. Change it to FALSE so that the event is created non-signalled, in which case the WaitForSingleObject would be expected to wait.]

  • The Old New Thing

    Why does Windows XP SP2 sometimes forget my CD autoplay settings?


    It didn't forget them; it's just double-checking with you.

    The developer responsible for CD autoplay in Windows XP SP2 explained it to me. There were two problems with the way Windows XP handled CD autoplay.

    First, when you installed a new program that included CD autoplay capability, many users didn't know where in the UI to go to select that new program as their default CD autoplay program. If they had previously selected a program and ticked "Always perform this action", there was no easily-discoverable way to undo the "always" flag to make the dialog reappeared and allow the user to select the new program instead.

    Second, many programs, upon installation, secretly hacked the undocumented CD autoplay settings in order to set themselves as the default CD autoplay handler, gleefully overriding the user's previously-stated preference. Because these programs egotistically believed themselves to be the coolest most amazing program ever written in the history of mankind.

    In other words, the two problems were, "I just installed this program and I want it to be the CD autoplay program" and its converse "I just installed this program and I don't want it to be the CD autoplay program".

    Windows XP SP2 introduced new behavior related to CD autoplay in an attempt to address these problems: When it sees that a new CD autoplay handler is available, it shows you the CD autoplay dialog one more time. This gives you a chance to (a) pick that new program you just installed, or (b) un-pick that program you just installed (if it was presumptuously rude enough to set itself as your default).

    The first time you insert a CD into your computer after upgrading to Windows XP SP2, you will also get the CD autoplay dialog. This is a "better late than never" dialog to cover for any handlers that were installed before you upgraded to Windows XP SP2.

    What's the moral of the story? Whereas in the old days, you only had to worry about helping other programmers interface with your feature, in the new software landscape, you also have to worry about stopping programmers who are trying to abuse your interface.

  • The Old New Thing

    The 2005 Seattle Chicken Tour


    Mark your calendars for the 2005 Seattle Chicken Tour, scheduled this year for July 16th.

    Seattle Tilths Annual City Chickens and Coop Tour July 16, 2005   10 am — 4 pm
    $10 per family or group of four

    Seattles city chickens owners invite you into their backyards for a first-hand look at raising chickens. Discover the variety of breeds that might be nesting in your neighborhood, learn about raising chickens, see how families integrate chickens into their organic gardening practices, as well as the ingenious coops that shelter these chickens. You will need a car to travel on this self-guided tour of over a dozen backyard chicken broods. Bring the whole family, and your out-of-town visitors, for this unique view of Seattles backyards.

    I am not certain whether advance registration is required, so if you're interested, you should contact Seattle Tilth sooner rather than later.

  • The Old New Thing

    If strncpy is so dangerous, why does Visual Studio 2005 still support it?


    In response to the news that strncpy is so dangerous, at least one person has called for Visual Studio to revoke support for such a dangerous function, considering the continued support for the function grounds for holding the compiler manufacturer liable for any defects in programs compiled with that compiler.

    Well, for one thing, while it's true that strncpy is dangerous if used improperly, it is still a valid function, and my original discussion explained the history behind strncpy and the very specific scenario in which it is still useful. It just so happens that most people don't use the function in the manner it was intended, but instead treat it as a sort of "copy string with a character limit" function, which it isn't really.

    For another thing, just because something is dangerous doesn't mean it shouldn't be supported. Pointers and casts are dangerous, but I don't see them disappearing from C or C++ any time soon.

    Third, support for strncpy is mandated by the C standard. If you removed it, you couldn't call yourself a C compiler any more. (Not to mention breaking compatibility with existing source code that uses the strncpy function. How would you like it if you bought a so-called C compiler and found that it couldn't compile a large class of valid C programs?)

  • The Old New Thing

    Why don't you ever see a rat vomiting?


    Okay, maybe you never wondered why you never saw a vomiting rat, but the intrepid researchers at the Annals of Improbable Research have discovered that there's a good reason, and Anne's rat page will explain in more detail than you probably wanted.

  • The Old New Thing

    Using /LARGEADDRESSAWARE on 64-bit Windows for 32-bit programs


    Probably the biggest advantage of 64-bit Windows is not the larger registers but rather the expansive 64-bit address space. Recall that even when the /3GB switch is set, 32-bit programs receive only 2GB of address space unless they indicate their willingness to cope with addresses above 2GB by passing the /LARGEADDRESSAWARE flag.

    This flag means the same thing on 64-bit Windows. But since 64-bit Windows has a much larger address space available to it, it can afford to give the 32-bit Windows program the entire 4GB of address space to use. This is mentioned almost incidentally in Knowledge Base article Q889654 in the table "Comparison of memory and CPU limits in the 32-bit and 64-bit versions of Windows".

    In other words, certain categories of 32-bit programs (namely, those tight on address space) benefit from running on 64-bit Windows machine, even though they aren't explicitly taking advantage of any 64-bit features.

  • The Old New Thing

    Using modular arithmetic to avoid timing overflow problems


    In an earlier article, I presented a simple way of avoiding timing overflows which seemed to create a bit of confusion.

    The short version: Given a starting time start, an ending time end and an interval interval, the way to check whether the interval has elapsed is to use the expression end - start >= interval. The naive expression end >= start + interval suffers from integer overflow problems.

    To simplify the discussion, let's operate in base-100 instead of base-232. The same logic works, but I think operating in base-100 will be easier to follow.

    Base-100 means that we remember only the last two digits of any number. Consider a starting time of start = 90 and an interval of interval = 10. Using the wrong expression yields end >= start + interval = 90+10 = 100 = 0. In other words, end >= 0 which is always true since end has the range 0...99. As a result, the wrong expression will think that the interval has expired prematurely.

    Using the correct expression, we have end - 90 >= 10. Of the numbers 0..99, the ones that give a difference less than 10 are 90 through 99. Once end = 0, the result is 0 - 90 = 10, which correctly indicates that 10 ticks have elapsed since 90 once the timer reaches 0.

    You can work through a similar mistake using start = 89 instead of start = 90; in this case, the wrong expression becomes end >= start + interval = 89 + 10 = 99, or in other words, end >= 99. This has the opposite problem from the previous case, namely that the expression will fail to detect that the interval has expired once the timer rolls over.

    But why does the end - start expression work? It's very simple: You just have to remember your rules of arithmetic from elementary school.

    (x - c) - (y - c) = x - c - y + c = x - y

    In other words, subtracting the same value from both terms of a difference does not affect the final value. This rule applies even to modular arithmetic (because, as the mathematicians like to say, the set of integers modulo n form an additive group).

    This rule is useful because it lets you delay the overflow as long as possible by subtracting the starting point from all your time markers; it has no effect upon time intervals. Wouldn't it be great if start = 0? Then the overflow won't happen for 100 ticks. Well, you can act "as if" the starting point were start = 0 by simply subtracting start from all your time markers.

    Those who prefer a graphical view can think of time passing as the hands around a clock (which wraps around at 60 minutes, say). When you decide to record your start point, rotate the clock so that the "12" precisely lines up with wherever the hand happens to be. You can now read off the elapsed time directly from your rotated clock. Rotating your clock is the same as subtracting (or adding) a constant to all time markers.

    Of course, this trick falls apart once you have to measure time intervals that come close to the wraparound time of your timer. In our 100-tick timer, for example, trying to measure the passage of 90 ticks is very difficult because there is only a 10-tick window where the inequality is satisfied. If we fail to catch the timer during that window, we miss it and have to wait another 90 ticks.

    So don't do that. In practical terms, this means that you shouldn't use GetTickCount to measure time intervals longer than 15 days.

  • The Old New Thing

    Shocked (shocked!) that patronage exists in Chicago politics


    NPR reported on a startling discovery in Chicago: That government jobs go not to those best qualified to perform them, but rather to those with the best connections. Who'd-a thunk it?

    Shocked by this discovery, the Daley administration vowed to end it.

    The City of Chicago's top lawyer Mara Georges told incredulous City Hall reporters yesterday that the hiring system will now be completely fair, objective, and free of political influence. "City hiring will be on the square, yes."

    The Associated Press notes that "City officials have long denied that political favoritism or patronage had anything to do with who got jobs." The Chicago Sun-Times captures the sentiment quite succinctly: Who knew politics as usual in Chicago is against the law?

Page 354 of 430 (4,293 items) «352353354355356»