July, 2010

  • The Old New Thing

    How do I configure a Remote Desktop Connection shortcut to open on a specific monitor?

    • 21 Comments

    A customer wanted to know how to configure a Remote Desktop Connection shortcut so that the session appears on the monitor of choice. "I have two RDP shortcuts, and each one displays on a different monitor, but I want them all to display on my 20-inch monitor. How do I tell the bad shortcut, 'Hey, use that monitor over there please'?"

    Normal shell shortcuts (LNK files) do not encode monitor information. It is up to the application to decide where to display its windows. Many applications save the window position when you exit and restore it when you restart. If you have one of these types of programs, then the solution is simple: Move the window to where you want its position to be remembered, and then close it.

    In the case of RDP files, the window position is stored in the RDP file settings. The Terminal Services Team Blog tells you how.

    One thing I found interesting about that blog entry is that none of the comments is on topic. Well, okay maybe two of them.

  • The Old New Thing

    Crackpots in computer security: The neighbors are looking at me weird

    • 20 Comments

    The security team gets all sorts of email to report security issues. Nearly 200,000 each year. And of course the reports vary in quality greatly. The ones I'm fascinated by are the crackpots.

    Subject:  IMMEDIATE THREAT AND NW INTRUSION, SAME AS FRIDAY MM/DD/YY, TOWN NAME YR SOFTW STOPPEDM SOME BUT ACCESS IS STILL THEREN 1000 YD FROM MY HOUSE
    Importance:  High

    IMMEDIATE HELP NEEDED, PHONES  PHONE NUMBERS DELETED, EM XXXXXXXX@ GMAIL,HOTMAIL,LIVE,AOL.YAHOO. IM ALMOST POSITIVE HE IS USING BLUETOOTH.  BUT HE CAN INTRUDE AT WILL. HE COULD  BE VERY DANGEROUS. LAST FRIDAY YOUR DEPT HAS GPS SEARCHING, BUT THE HACKER CUT US OFF. THEN TRASHED 4 OF MY PCS.PLEASE ON CONTACT ME IMMEDEDIATLY, LOOK IN THE RECORDS.  HE MAY BE IN MY AREA, THE NEIGHB ORS ARE LOOKING AT ME WEIRD, AS THIS CANT BE DONE.  im NOT ON DRUGS.  JUST CONTACT ME. NAME AND ADDRESS DELETED

    Capitalization is preserved from the original, but identifying information has been deleted.

    It's possible that he's actually onto something. After all, just because you're paranoid doesn't mean they aren't out to get you.

  • The Old New Thing

    Hardware backward compatibility: The firmware that missed one tiny detail

    • 24 Comments

    The person responsible for the floppy disk driver in Windows 95 also was responsible for the low-level CD-ROM drivers. (Not to be confused with the CDFS file system, which was handled by the file system team, not the hardware driver folks.) And I remember a story about one particularly strange CD-ROM drive.

    This drive was produced by a name-brand manufacturer. The box that the drive comes in proudly announces that it is an IDE ATAPI drive. And they did a fantastic job. They implemented all the ATAPI commands that were defined at the time, with one tiny exception.

    They forgot to implement the "Are you an ATAPI drive?" command.

  • The Old New Thing

    One small silver lining of moving Boeing headquarters to Chicago

    • 18 Comments

    In 2001, Boeing moved their corporate headquarters from Seattle to Chicago. This resulted in much wailing and consternation in Seattle, where Boeing had been since its founding in 1915.

    But every cloud has a silver lining. Seattle is the home of Boeing's passenger jet division, and the presence of corporate executives had added an extra layer of management annoyance to the already-stressful job of building airplanes.

    As the story goes, one of the Corporate Vice Presidents from some other division of Boeing had an office that overlooked Boeing Field, giving him a vantage point from which to watch each airplane take off as it was delivered to the customer. Since he was a Corporate Vice President, he had access to the delivery schedule, so when the schedule said that an airplane was supposed to be delivered to XYZ Airlines today and he didn't see a plane take off, he knew something was wrong. And each time a plane didn't take off when it was supposed to, he called the guy responsible for passenger jet manufacturing to remind him that there was supposed to be a delivery today, and that the plane was late, and demand an explanation.

    Like that guy didn't already know that the plane was late. In fact, he's probably know this for the past several weeks if not months. He's been in countless meetings to figure out why the plane was late. He's been busting heads to get the plane back on schedule. He's been studying GANTT charts and PERT charts while sitting on the toilet. He'd even study Snellen charts if he thought it would help. He's the last person on the planet you need to remind that the plane is late.

    Imagine what it must be like to be that guy, and to have a Corporate Vice President call you and say, "Your plane is late." And then to have to spend time explaining why the plane is late, time that you should be spending finishing an airplane that is late.

    At least, now that all the Corporate Vice Presidents for other divisions have moved to Chicago, the passenger jet manufacturing guy doesn't have to take those annoying phone calls.

    I tell this story as a long response to Chad's comment that he didn't see what was wrong with that manager's email to everybody who has more than one bug. The people with more than one bug sure as heck know that they have more than one bug. As a deadline looms, everybody lives in the bug database. You know exactly how many issues are assigned to you, and you set up notifications so you are alerted the moment anybody assigns a new bug to you. Your manager (and probably your manager's manager) talk to you every day about your bug count and are always asking you what they can do to help. (The sentence "If you need help, then ask your manager" therefore gets things backwards: Your manager has been asking you if you need help.)

    The message from the senior manager was like the message from the Boeing Corporate Vice President: Reminding somebody already under a lot of stress that they are under a lot of stress.

    Clarification: I think everybody is missing the part of the story where I say that the Corporate Vice President is from a different division of the company. He is nowhere in the chain of command in the passenger jet division. He's just a nosy outsider. Why should the passenger jet production manager send regular project updates to the CVP of the Space Launch and Exploration division? Everybody inside the passenger jet division who needs to know about the revised plane delivery schedule already knows about the problem.

  • The Old New Thing

    The commutative law for postage and its limitations

    • 9 Comments

    The college professor who carried on a letter exchange with a kind pensioner who proved that the speed of light could be exceeded told me of another letter exchange, this time with another professional mathematician.

    The letter came from England, and it accompanied some sort of document or artifact that the correspondent wanted the college professor to look over and return. The mathematician took the effort of including a stamped return envelope with the remark, "By the commutative law for postage, I have placed the same amount of postage on the return envelope as I have on the outgoing envelope."

    The professor, however, could not use the return envelope the correspondent provided. He explained, "Unfortunately, the commutative law for postage does not apply to correspondence between the United States and the United Kingdom due to events of slightly more than 200 years ago."

  • The Old New Thing

    Instead of trying to figure out what shortcut class to use, just ask the shell to do it for you

    • 17 Comments

    If a shell namespace item has the SFGAO_LINK attribute, then it is a shortcut to another location. The most common type of shortcut is the .lnk file, which you can load by creating the CLSID_Shell­Link object and using IPersist­File::Load, but what if you have some other type of shortcut? How do you know what CLSID to use?

    Since anybody can create their own shortcut file types, a hard-coded list mapping file extensions to CLSIDs is not going to work for long. But fortunately, you don't have to know how to look up the CLSID for a particular shortcut; you can just ask the namespace to do it for you by asking for the IShell­Link UI object.

    #include <windows.h>
    #include <shlobj.h>
    #include <ole2.h>
    #include <stdio.h>
    #include <tchar.h>
    #include <shellapi.h>
    
    // GetUIObjectOfFile function incorporated by reference
    
    int __cdecl _tmain()
    {
      int argc;
      LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
      if (argv == NULL || argc != 2) return 0;
      if (SUCCEEDED(CoInitialize(NULL))) {
        IShellLink *psl;
        if (SUCCEEDED(GetUIObjectOfFile(NULL, argv[1], IID_PPV_ARGS(&psl)))) {
          TCHAR sz[MAX_PATH];
          if (SUCCEEDED(psl->GetPath(sz, MAX_PATH, NULL, 0))) {
            _tprintf(TEXT("-> %ls\n"), sz);
          }
          else _tprintf(TEXT("GetPath failed\n"));
          psl->Release();
         }
         else _tprintf(TEXT("GetUIObjectOf failed\n"));
        CoUninitialize();
      }
      LocalFree(argv);
      return 0;
    }
    

    I've limited myself to files here for simplicity of exposition, and I assume that you've passed a fully-qualified path on the command line. Of course, you can have shortcuts to non-file objects as well, and for those shortcuts, IShell­Link::Get­Path is unlikely to return an actual file path. (In fact, for things like shortcuts to the Control Panel, they're unlikely to return anything at all.) I've also used the Command­Line­To­ArgvW function instead of the built-in argc and argv because the Get­UI­Object­Of­File function wants a Unicode file name, but the C runtime's argv is a TCHAR * string, which might not be Unicode.

    Let's take this program for a spin.

    Warning: I am using hard-coded paths. In real life, you would use appropriate functions to obtain the paths to the files you care about. (Actually, in real life, you probably will have a pidl to the item rather than a path, so the issue of paths disappears.)

    >set STARTMENU=%APPDATA%\Microsoft\Windows\Start Menu\Programs
    >scratch "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\Calculator.lnk"
    -> C:\Windows\System32\calc.exe
    
    >scratch "%STARTMENU%\Internet Explorer.lnk"
    -> C:\Program Files\Internet Explorer\iexplore.exe
    

    Okay, these are your regular .lnk files, so there's nothing special going on here. Let's try something fancier, like a symbolic link.

    >echo > blah.txt
    >mklink other blah.txt
    symbolic link created for other <<===>> blah.txt
    
    >scratch "%CD%\other"
    -> C:\test\blah.txt
    

    Via the Add Network Location wizard, I created a network location (which is internally represented as a Folder Shortcut). Let's see what happens with that:

    > scratch "%APPDATA%\Microsoft\Windows\Network Shortcuts\Tools"
    -> \\live.sysinternals.com\tools
    

    How about Internet shortcuts?

    > scratch "%USERPROFILE%\Favorites\MSN Websites\MSN.url"
    -> http://go.microsoft.com/fwlink/?LinkId=54729
    

    OneClick shortcuts? (MS Space is an internal application which lets you view floor plans of every Microsoft building, book conference rooms, reserve touchdown space, that sort of thing.)

    > scratch "%STARTMENU%\MS Space.appref-ms"
    GetUIObjectOf failed
    

    Huh? What happened?

    It so happens that the people who wrote the shortcut handler for OneClick applications only bothered to implement the Unicode version of the IShell­Link interface. We built our application as ANSI, so our attempt to get the IShell­LinkA interface failed. But that's easily worked around:

    #define _UNICODE
    #define UNICODE
    #include <windows.h>
    #include <shlobj.h>
    #include <ole2.h>
    ...
    

    (In real life, your program would probably first ask for the Unicode interface, and if the call fails, then ask for the ANSI interface.)

    With the Unicode version of the program, the shortcut resolves:

    > scratch "%STARTMENU%\MS Space.appref-ms"
    -> C:\Users\...\MSSpaceDeploy.exe
    

    (I elided some of the ugly path because, well, it's ugly. The full unabbreviated path is 139 characters, most of which is just hex digits.)

    Anyway, the point for today wasn't the minutiae of obtaining shortcut targets from shell namespace items. It was the principle that if you want something from the shell namespace, the IShell­Folder::Get­UI­Object­Of method will often get it for you.

  • The Old New Thing

    What Raymond listens to: KCRW's The Business

    • 4 Comments

    KCRW's The Business reveals how the sausage of the entertainment industry is made. Here are some of my favorites:

  • The Old New Thing

    What is the lpClass member of SHELLEXECUTEINFO used for?

    • 14 Comments

    A customer reported problems launching the default Web browser with the Shell­Execute­Ex function:

    int _tmain(int argc, _TCHAR* argv[])
    {
      SHELLEXECUTEINFO sei = {0};
      sei.cbSize = sizeof(sei);
      sei.nShow = SW_SHOWNORMAL;
      sei.lpFile = TEXT("www.microsoft.com");
      sei.fMask = SEE_MASK_CLASSNAME;
      sei.lpVerb = TEXT("opennew");
      sei.lpClass = TEXT("htmlfile");
    
      ShellExecuteEx(&sei);
    
      return 0;
    }
    

    This fails with sei.hInstApp = SE_ERR_FNF.

    If you don't pass the SEE_MASK_CLASSNAME flag and leave lpClass = NULL, then the Shell­Execute­Ex function will try to figure out what your lpFile refers to, looking at the file extension, looking for the file on the PATH, and if all else fails, trying some autocorrection. In this case, the customer was relying on the autocorrection, since they left the http:// prefix off their URL. One of the default autocorrection rules is that if the item that couldn't be launched begins with www, then try again with http:// in front.

    On the other hand, if you pass an explicit lpClass, then no name resolution is performed on the lpFile. You're saying "Don't do any sniffing and poking and autocorrection. I have already determined that this item should be executed according to the rules specified for HKEY_CLASSES_ROOT\htmlfile, so just follow the rules and don't question me."

    No second-guessing means that the Shell­Execute­Ex function shrugged its shoulders and said, "Well, I don't see a file called www.microsoft.com in the current directory, so I will fail with a file-not-found error."

    If you pass an explicit class, then Shell­Execute­Ex will treat your lpFile as if it were a file of that type. If you have something and you want all the standard detection logic to kick in, then don't specify a class.

    Bonus reading: The above program is simplified to illustrate the topic. A real-life version of this program needs some other scaffolding.

Page 3 of 3 (28 items) 123