February, 2010

  • The Old New Thing

    What is the maximum length of an environment variable?

    • 25 Comments

    A customer noticed that environment variables were being truncated at 2047 characters and wanted to know what the maximum length of an environment variable is.

    This is one of those cases where you can answer the customer's question or you can try to answer the question the customer is really asking. If you just answer the question, you're doing the customer a disservice.

    The theoretical maximum length of an environment variable is around 32,760 characters. However, you are unlikely to attain that theoretical maximum in practice.

    All environment variables must live together in a single environment block, which itself has a limit of 32767 characters. But that count is the sum over all environment variable names and values, so you could, I guess, hit that theoretical maximum length if you deleted all the environment variables and then set a single variable called X with that really huge 32,760-character value. In practice, of course, you have to share the environment block with all the other variables in the block, so your random call to SetEnvironmentVariable with a 32,760-character string is unlikely to succeed.

    But that's not your only practical limit.

    It also depends on how you're setting the variable; i.e., the code that your environment-variable-setting technique passes through before it gets to the SetEnvironmentVariable call. If you're using a batch file, then you're constrained by the maximum command line length since the environment variable needs to fit into the command line buffer of the batch processor. On the other hand, maybe you're setting the Environment registry key, in which case you run into a 2048-character limit in the code that parses that registry key and builds an environment block out of it. There's also a limitation in the dialog box for interactively setting environment variables, the numeric value of which I don't happen to know off the top of my head.

    This is one of those skills you have to develop when answering questions from customers: Taking the customer's question and trying to figure out what their real question is.

  • The Old New Thing

    No matter what you do, someone will call you an idiot, part 2

    • 41 Comments

    There was quite a bit of reaction to what I thought was a simple "Hey, here's what's going on" article from last year, specifically on how the Adaptive Display Timeout means that Windows doesn't always start the screen saver exactly on time. As you may recall, this feature adjusts the time it takes for the screen saver to activate if the user keeps dismissing it immediately after it starts. One of those small things that makes the computer adapt to you rather than vice versa, and an adaptation that you probably don't even notice when it happens.

    I think these two responses below summarize the extremes of the types of reactions this feature generated.

    • Vista/W7 has some nice touches too. http://is.gd/2FgKv Such little things is what we love about Macs.

    • Ich finde das erstaunlich. In einem Linux-System kann man soetwas relativ leicht selber scripten, und sich z.B. einen Button erzeugen, der den Bildschirmschoner kurzzeitig ganz ausschaltet. Sowas geht unter Windows freilich auch, aber kaum ein User kennt das System hinreichend gut. Deshalb stellen sich dort solche Probleme. Erstaunlich.

      Translation: This is incredible. On Linux, you can script this yourself relatively easily and create, for example, a button which completely disables the screen saver for a short time. Admittedly, you can also do this on Windows, but hardly any users know the system that well. And therefore we have these types of problems. Incredible.

    On the one hand, the feature is something so cool, it must have been stolen from a Mac.

    On the other hand, this feature shows everything that is wrong with Windows. I mean, on Linux, you can solve this problem by simply writing a script!

  • The Old New Thing

    How do I get information about the target of a symbolic link?

    • 26 Comments

    Functions like GetFileAttributes and FindFirstFile, when asked to provide information about a symbolic link, returns information about the link itself and not the link destination. If you use the FindFirstFile function, you can tell that you have a symbolic link because the file attributes will have the FILE_ATTRIBUTES_REPARSE_POINT flag set, and the dwReserved0 member will contain the special value IO_REPARSE_TAG_SYMLINK.

    Okay, great, so now I know I have a symbolic link, but what if I want information about the link target? For example, I want to know the size of the link target, its last-modified time, and its name.

    To do this, you open the symbolic link. The I/O manager dereferences the symbolic link and gives you a handle to the link destination. You can then call functions like GetFileSize, GetFileInformationByHandleEx, or GetFinalPathNameByHandle to obtain information about the symbolic link target.

    Exercise: If the field is called dwReserved0, shouldn't it be off limits? Why isn't the field called dwReparsePointType?

  • The Old New Thing

    It looks a little like CMD except there is white on the background

    • 27 Comments

    Surely by now you've seen the video where NextGenHacker101 shows you how to use the "Tracer T" program to view "how many IP's are looking at Google", their name, and connection speed (to then to then to then). (And commenter squizz explains why it "worked" in spite of the http prefix.)

    But more awesome is the fact that somebody ported the video to linux!

    Bonus video craziness: It's in Korean but somehow that just adds to the insanity. (Warning: Five minutes of your life you will never get back.)

    The comments on the YouTube video identify the song as "Bo Peep Bo Peep <- possibly the most addictive/annoying song ever."

  • The Old New Thing

    How many servings are there in a single-serve cup? The answer might surprise you

    • 42 Comments

    I was in the grocery store, and there was a sign advertising a new product.

    Delight in a cup
    Your favorite XYZ Ice Cream
    Now in convenient single-serve cups.

    I took a look at the cup. Seemed kind of big for a single serving. I picked one up to read the nutritional information.

    Servings per container: 2
  • The Old New Thing

    Advocating the overthrow of the government of the United States by force or subversion

    • 43 Comments

    It has been widely reported that South Carolina now requires "subversive groups" to register with the Secretary of State (and pay a $5 filing fee).

    Curiously, the list of organizations which must register include "an organization subject to foreign control." I wonder if this means that all consulates have to register, and that when any foreign dignitary visits South Carolina, they have to pay a $5 filing fee. (Not to mention all foreign-owned companies like Shell Oil.)

    Actually, it has been pointed out that a "subversive organization" includes one which advocates, teaches, or practices the propriety of controlling the government of the United States. I guess this means all political parties are subversive organizations. (Something most of us knew already.)

    And apparently, in your registration, you also have to include the bylaws or minutes of meetings from the last year. I wonder whether you have to resubmit the minutes each year. I'm sure somebody could keep a government bureaucrat busy for a long time by submitting hundreds of pages of "minutes".

    Anyway, this is a long and largely superfluous set-up for a different story. The mother of a colleague of mine came to visit from Canada. For some reason, the United States requires visitors to fill out a questionnaire asking them whether they are a drug dealer, whether they are a Nazi war criminal, and this question:

    Do you advocate the overthrow of the United States government by force or subversion?

    The sweet old lady studied the question for a while, then circled force.

    Bonus weirdness: On the form, it also says "Answering Yes will not necessarily exclude you from admission to the United States."

  • The Old New Thing

    Microwave popcorn enthusiast proudly proclaims, "I *am* popcorn!"

    • 19 Comments

    Oscar Night is a few weeks away, but when you settle in to watch the show with your bowl of popcorn, please be aware that inhaling deeply from the fumes of a freshly-opened bag of microwave popcorn is not the greatest decision you can make from a health standpoint. (Then again, you probably ought to reconsider eating microwave popcorn in the first place, but let's leave that aside.)

    A disease informally known as popcorn lung afflicts people who work in popcorn factories and has been known since 2002. But in 2007, doctor diagnosed the first case of popcorn lung in an end-user. The risk is not from eating the popcorn but from breathing it. "This patient described enjoying the smell so much he was actually inhaling the steam." The best part of the article was when the patient was asked, "Are you around a lot of popcorn?"

    The response: "I am popcorn."

    Update: Oscar Night is not actually this weekend. That's what happens when you schedule your blog entries over a year in advance and have to guess when Oscar Night is coming.

  • The Old New Thing

    For better performance, set all your monitors to the same color format

    • 29 Comments

    Pplu wonders why programs run more slowly when the system is running with multiple monitors.

    Well, for one thing, of course, when you have more than one monitor, there's more stuff on the screen for the system to keep track of. It's the same reason that programs run more slowly on a large monitor than on a small monitor.

    And if there's only one monitor, then functions like MonitorFromPoint become trivial if the flag is something like MONITOR_DEFAULTTONEAREST, because when there's only one monitor, answering questions like "What monitor is closest to this point"? becomes very easy.

    If your two monitors are not the same dimensions, then the union of the two monitors will not be rectangular, which makes clipping against the union of all monitors more complicated.

    But I suspect the big penalty for multiple monitors kicks in if you make the mistake of setting your monitors to different color formats, for example, if you set one monitor to 565 format and set another to 24bpp.

    If the two monitors do not use the same color format, then programs will be forced to use DIBs instead of DDBs for screen bitmaps, in case a window is moved to a window with a different color format (or worse, is positioned so it straddles two monitors with different color formats). In principle, programs need only use the "worst-case" DIB; for example, if one monitor is 555 and the other is 565, then a 565 DIB will suffice. In practice, however, most programs just fall back to a 24bpp or 32bpp DIB when faced with monitors with different color formats.

    (You query whether all monitors have the same color format by calling GetSystemMetrics(SM_SAMEDISPLAYFORMAT).)

    Since a format conversion takes place when a DIB is blitted to a device with a different color format, forcing a program to retain its bitmaps as DIBs means that for at least one of the monitors (and probably both), you're going to undergo a format conversion when that DIB is drawn to the screen. There are also a few miscellaneous optimizations which are disabled when not all your monitors use the same color format because the cost of using DIBs outweighs the savings from the optimization.

    So if you haven't already, go into your display settings and check that you set all your monitors to the same color depth. If you don't do this, then a large class of graphics optimizations is lost.

  • The Old New Thing

    A simple Venn diagram teaches you the difference between Norway and Sweden

    • 12 Comments

    Not sure it helps, though.

  • The Old New Thing

    Don't forget to double-null-terminate those strings you pass to SHFileOperation

    • 30 Comments

    About once every two months for the past six months (I stopped checking further back), somebody reports a problem with the SHFileOperation function. Often, they don't include very much information at all. They just say, "I call the function and it doesn't work." Here's an example:

    I'm hitting a problem with SHFileOperation when using it to frob files in the gonzo directory when the user's SID ends in an odd number.

        //
        // Delete the file.
        // szDeletePath contains the full path to the file.
        //
        shFileOp.hwnd = NULL;
        shFileOp.wFunc = FO_DELETE;
        shFileOp.pFrom = szDeletePath;
        shFileOp.pTo = NULL;
        shFileOp.fFlags = FOF_NO_UI;
        iRet = SHFileOperation( &shFileOp );
    

    The function returns file not found, but the file is definitely there.

    If you read the variable names carefully, you can see the problem.

    The pFrom and pTo members of the SHFILEOPSTRUCT structure are double-null-terminated strings. (There's even a callout box for this in the MSDN documentation.) But a variable named szDeletePath is probably a single-null-terminated string. (The name for a double-null-terminated string would be szzDeletePath.)

    My psychic powers tell me that szDeletePath is not double-null-terminated.

    So far, my psychic powers haven't failed.

    Now, you might say that the fact that people make this mistake so often is a sign that the function is flawed. And if the function were designed today, I would agree with you. But this function in its public form is over fifteen years old (and in its private form, is around 20 years old), and back in those days, programmers were assumed to have the time to understand the subtleties of what they were doing.

Page 1 of 4 (35 items) 1234