Tips/Support

  • The Old New Thing

    The Visual Effects dialog box just tells you what you want to hear

    • 21 Comments

    The Visual Effects dialog box has three options, "Let Windows choose what's best for my computer," "Adjust for best appearance," and "Adjust for crappiest appearance best performance." Some people have discovered the registry key where the Visual Effects dialog box remembers which radio button was most recently checked, but they found that when they programmatically manipulate the registry key, there is no effect on the actual visual settings.

    What's going on?

    What's going on is that the registry key is just there to tell you what you want to hear. It remembers which radio button you clicked, so that when you reopen the dialog box, the same radio button will be selected by default.

    The actual work of changing the setting happens when you click the OK or Apply button. The registry key is just for show.

    If you want to change a Visual Effects setting programmatically, you need to make the corresponding API call for that visual effect. For example, you might call System­Parameters­Info with the SPI_SET­NON­CLIENT­ANIMATION flag to programmatically enable or disable non-client animation.

    Note of course that by doing this you are using a global solution to a local problem. The user's visual effects preferences should be modified by the user, not by a program.

  • The Old New Thing

    How do I hit the Win+PrintScreen hotkey if my tablet doesn't have a PrtSc key?

    • 30 Comments

    Windows 8 added a new hotkey: Win+PrtSc takes a snapshot of your screen and puts it into the Screenshots folder of your Pictures library. But what if you are on a tablet with no PrtSc key?

    On tablets, you can perform the same operation by pressing Windows button + Volume down. Both of these are the hardware buttons on the tablet, not on any keyboard.

  • The Old New Thing

    The case of the mysterious Alternate Data Stream query

    • 12 Comments

    A customer was running Windows Server 2003 ("Still in support until 2015!") and they have some custom application that monitors all disk accesses. They noticed that there were a lot of failed Alternate Data Stream queries coming from Explorer, and that was causing the custom application's logs to fill with largely useless information.

    These Alternate Data Stream queries are being made in order to extract file metadata for the pop-up infotip. (Windows later abandoned the use of Alternate Data Streams for file metadata since Alternate Data Streams were so fragile and were easily damaged or lost.)

    The customer found that if they unchecked Show pop-up description for folder and desktop items, this solved the problem on some of their machines, but not all of them. They asked the Explorer team what else needs to be done to stop the ADS queries.

    The piece they were missing was the status bar. If the status bar is enabled, then it shows the same information that would have appeared in the infotip.

    Turning off the status bar fixed their problem.

  • The Old New Thing

    Why doesn't the New Folder command work in the root of a redirected drive resource in a Remote Desktop session?

    • 27 Comments

    When you connect to another computer via Remote Desktop, you have the option of injecting your local drives into the remote computer, known as Device and Resource Redirection. These injected drives are available under the UNC \\tsclient\X where X is a drive letter on the local machine.

    The name TSCLIENT combines a bunch of internal technical terminology, so it makes perfect sense to the people who wrote it, but not as much to outsiders. (They may have chosen this name just to make themselves look smart.) The letters TS stand for Terminal Services, which was the former name of the technology now known as Remote Desktop. And the word client refers to the local computer, the one that is connected to the remote computer. In Terminal Services terminology, the machine you are connect from is the client, and the machine you are connecting to is the server.

    There's another level of confusion in the name of the feature. People often call these \\tsclient\X thingies Redirected Drives, which collides with the existing name for local drive letters that have been mapped to a network resource. In the user interface, these are usually called Mapped Network Drives. From the command line, you create these things via the NET USE command.

    Okay, enough with the confusing terminology. For today, we're talking about Remote Desktop Device Redirection, where the redirected device is a drive letter.

    If you open My Computer and look under Other, you'll see those drives which were injected from the local computer. Your first tip-off that there's something funny about these drives: They don't show up in the Network Location section like other mapped drives; instead they show up under the rather generic-sounding Other.

    That's because these drives aren't really drives. They are folder shortcuts, a special type of shortcut that grafts one part of the shell namespace into another. The ones created by Remote Desktop Device Redirection are shell instance objects, which is a way of creating certain types of shell extensions using just a handful of registry keys.

    Since they aren't really drives, some things that work for real drives don't work for these fake drives. And one of those things is that Explorer thinks that they don't support the New Folder command because when Explorer asks, "Do you support IStorage?" (because that's the interface that Explorer uses to create new folders), the answer is "No, you silly rabbit. I'm an Other!"

    Now, it turns out that the Terminal Services folks could've customized their Other to say, "Actually, yeah, I do support IStorage." You do this by setting the bit 0x00000008 in the Attributes value of the ShellFolder key when you registered your instance object. The Terminal Services folks forgot to set that bit, and the result is no New Folder button.

    Sorry about that.

    As a workaround, you can create your new folder by typing \\tsclient\X into the address bar. That folder is the thing that the folder shortcut is pointing to (so it's just another name for the same thing), but since it's the real thing, it correctly reports the SFGAO_STORAGE flag, and the New Folder button appears.

  • The Old New Thing

    How do I configure the timeout used by UI0Detect (Interactive Services Detection service)?

    • 10 Comments

    Windows Vista introduced Session 0 Isolation which enforces the rule that services should not display UI. If a service tries to display UI, another service known as the Interactive Services Detection service detects this situation and signals the user that a service wants to display UI and gives the user an opportunity to switch to the service desktop, respond to the UI, and then switch back. If the user ignores the service for about one minute, it switches back automatically, on the assumption that something went bad with the detection and the service is actually finished with its UI. (That way, the user doesn't get stuck staring at session 0 forever.)

    More than one customer wanted to know how to configure this one minute timeout.

    The correct solution to the problem is not to configure Interactive Services Detection but rather to fix your service so it doesn't show UI in session 0.

    It's like saying, "When I mail a letter and get the postal code wrong, the letter reaches the destination eventually, but it takes much longer than a letter sent with the correct postal code. How can I get letters sent with the incorrect postal code to reach their destination faster?"

    The answer is to stop putting the incorrect postal code on your letters.

    In other words, stop throwing garbage on the sidewalk.

    Bonus reading: Troubleshooting Interactive Services Detection.

  • The Old New Thing

    Why don't all of my documents show up when I arrange my Documents library by Name?

    • 29 Comments

    A customer reported that when they opened their Documents library on Windows 7, some files were missing if they selected Arrange by: Name or Arrange by: Author or in fact any arrangement other than Arrange by: Folder. What's going on?

    When you arrange the Documents library by anything other than Folder, the Documents library uses the content indexer to obtain results quickly, rather than kicking off a recursive disk search (ugh). (The Folder arrangement does not require a recursive search, so it can use the traditional Find­First­File/Find­Next­File loop to get the results.

    A member of the search indexer team suggested that a common cause for items being missing from the index is if they have the FILE_ATTRIBUTE_TEMPORARY attribute set. The indexer ignores temporary files because the creator of the file said, "Don't worry about me, this is just a temporary file that I will be deleting as soon as I close the handle." No point indexing a file that is going to be deleted soon.

    You can check whether the file has the Temporary attribute by viewing its Properties and going to the Details tab. If the file is marked Temporary, the Attributes will include the letter T. (Note that the attrib program does not report the Temporary flag.)

    Sure enough, the customer found that the files which were mysteriously missing from the view were all marked as Temporary files. This allowed the customer to proceed to the next step of the investigation, which is figuring out why those files were being marked Temporary in the first place.

  • The Old New Thing

    Wait, so does moving a file recalculate inherited permissions or doesn't it?

    • 15 Comments

    A customer had a question about whether moving a file recalculated inherited permissions. They found that on their Windows Server 2008 R2 machine, if they moved a file between directories with different inheritable ACEs, then the security descriptor is recalculated to match the destination folder, if they perform the move from the machine itself. The same thing happens if they go to a machine running Windows 7, However, if they repeat the experiment from a machine running Windows XP or Windows Server 2003, then the security descriptor is preserved across the move.

    The customer is confused. Why does the behavior change based on the version of Windows running on the client, even though the files themselves are kept on the same server?

    The explanation is given in a few places:

    Even with these explanations, the customer remained confused.

    "Why does the permission depend on the operating system running on the client? The files are on the server, so regardless of the client operating system, it should be following the rules which apply to the server, right?"

    There are two different operations here.

    Suppose I told you, "When you buy clothes from the store, it will have the store sticker on it. You must remove the sticker yourself, and you should also wash the clothes before wearing it the first time, because the store puts powder in the bag to keep the clothes from getting moldy."

    You then say, "That is not true. When I go to my closet to get clothes I recently bought from the store, the store stickers are already gone, and there is no powder."

    That's because you live with your parents, and your mother takes your clothes, removes the stickers, washes the clothes, and then hangs them up in your closet.

    The underlying file system "move" operation preserves the ACLs from the source.

    On the other hand, if you use Explorer to move the files, then you are not using the underlying file system "move" operation directly. Your mother is moving the files. And when mother Explorer moves the files, she also edits the ACLs based on the nature of the source and destination folders, as described in the aforementioned Knowledge Base articles. Furthermore, different versions of mother Explorer edit the ACLs in different ways.

    That is why the behavior is dependent upon the client operating system. When you move the file from a client machine connected to the server, the client machine asks the server to move the files (which preserve the ACLs since that's what the low-level "move" operation does), and then the client machine goes back in and edits the ACLs in a client-specific way.

    It is therefore the client operating system which controls how the ACL editing is performed, because it is the client operating system which is editing the ACLs.

  • The Old New Thing

    How permanent is the "Remove from this list" action on the Start menu?

    • 22 Comments

    From Windows XP to Windows 7, the Start menu showed the programs it thinks you've run most frequently, by employing a conceptually simple but complicated-in-practice algorithm. You can right-click an item on the menu and select Remove from this list. What exactly does this option do? Does it reset the points back to zero, or does it ban the program from the Start menu for all eternity, or something in between?

    It resets the points back to zero and marks the program as has never been run by the user.

    This causes it to vanish from the frequently-used list, but if you start running it, it will start earning points again, and if you keep running it enough, it will claw its way back onto your frequently-used list.

    If you want to ban a program, you can mark it as No­Start­Page.

  • The Old New Thing

    How can I find out which process and user is modifying a file?

    • 26 Comments

    When troubleshooting a problem, you may discover that a file is being modified that shouldn't, and you figure out would be nice if there were some way of finding out which process is modifying the file (so you can get it to stop).

    Enter the security auditing system.

    Every securable object has an associated system access control list (SACL) which controls what audit events are raised when a request is made to access the object. You can say, for example, "Log an event in the security event log if somebody tries to open this file for writing but is denied access," or "Log an event in the security event log if somebody successfully creates a new file in this directory."

    Here's how it works. Let's say that you want to access successful requests from any user to write to a particular file.

    View the Properties of the file, go to the Security tab, and click Advanced, then go to the Auditing tab and elevate to administrator if necessary.

    Next, click Add. What happens next depends on what version of Windows you're using, since the interface varies slightly (but the basic idea remains the same). When asked for the security principal, set the Location to the local computer and use the object name Everyone.

    Older vesions of Windows will give you a grid of options. Look for the row corresponding to the operation you want to audit and check the box under Successful if you want to audit successful accesses or the box under Failed to audit failed accesses. (Or check both to audit both successful and failed accesses.) Repeat for each access you want to audit. In our case, we would check the Create files / write data and Create folders / append data boxes under the Successful column.

    Newer versions of Windows break the grid up into two questions. The first is whether you want to audit Success, Fail, or All access. In our case, we want to audit Success. The next question is what type of access you want to audit, and in our case we would check Write. (Or for finer control, click Show advanced permissions and check Create files / write data and Create folders / append data.)

    OK your way out of all the dialog boxes to save the changes.

    All right, let's take this thing out for a spin. Open the file in Notepad, make some change, and then Save them. Now open the Event Viewer and go to the Security event log.

    And... no log entry.

    That's because I forgot a step: You have to enable object access auditing.

    Open the Control Panel and look in the Administrative Tools folder. From there, you can run the Local Security Policy snap-in. If you are a command line nerd, you can run secpol.msc.

    Under Local Policies, Audit Policy set the Audit object access policy to enable global auditing of successful or failed accesses, depending on what you need.

    Okay, let's try it again. Modify the file and save it. Now go back to the security event viewer and you'll see audit success events in your log. Again, depending on what version of Windows you're using, the successful audit event will appear differently. For example, older versions of Windows might show

    Event Type: Success Audit
    Event Source: Security
    Event Category: Object Access
    Event ID: 567
    Date: ...
    Time: ...
    User: ...
    Computer: ...
    Description:
    Object Access Attempt:
    Object Server: Security
    Handle ID: 208
    Object Type: File
    Process ID: 1964
    Image File Name: C:\WINDOWS\system32\notepad.exe
    Access Mask: WriteData (or AddFile)
    AppendData (or AddSubdirectory or CreatePipeInstance)

    whereas newer versions might show

    Keywords: Audit Success
    Date and Time: ...
    Source: Microsoft Windows security auditing
    Event ID: 4663
    Task Category: File System
    An attempt was made to access an object.
    Subject:
    Security ID: computer\user
    Account Name: user
    Account Domain: computer
    Logon ID: 0x27ADB
    Object:
    Object Server: Security
    Object Type Name: File
    Object Name: C:\test.txt
    Handle ID: 0x15c
    Resource Attributes: S:AI
    Process Information:
    Process ID: 0xdb0
    Process Name: C:\Windows\System32\notepad.exe
    Access Request Information:
    Accesses: WriteData (or AddFile)
    AppendData (or AddSubdirectory or CreatePipeInstance)
    Access Mask: 0x6

    Either way, you can see which process obtained write access to the file, running as what user, at what time.

    Newer versions of Windows include a bit more information in the event log entry to make it easier to find the access request you're looking for as well as chase the access further. (For example, from the Logon ID, you can figure out which logon session modified the file.)

    This feature has been around since the beginning of Windows NT, but it seems that very few people know about it. Whenver I point it out to people, they say, "Hey, that's cool. How long has that feature been there?"

    Now you too can look smart.

  • The Old New Thing

    Why doesn't the "Automatically move pointer to the default button in a dialog box" work for nonstandard dialog boxes, and how do I add it to my own nonstandard dialog boxes?

    • 30 Comments

    The Mouse control panel has a setting called Automatically move pointer to the default button in a dialog box, known informally as Snap to default button or simply Snap To. You may have discovered that it doesn't work for all dialog boxes. Why not?

    The Snap To feature is implemented by the dialog manager. When the window is shown and the setting is enabled, it will center the pointer on the default button. If your application does not use the dialog manager but instead creates its own custom dialog-like windows, then naturally the code in the standard dialog manager will not run.

    If you want your nonstandard dialog box to support the Snap To feature, you get to implement it yourself.

    Here's a Little Program that creates a window with a default pushbutton inside it, and which centers the mouse on the button when the window is shown. Start with our scratch program and make these changes:

    POINT GetRectCenter(LPCRECT prc)
    {
      POINT pt = {
        prc->left + (prc->right - prc->left) / 2,
        prc->top + (prc->bottom - prc->top) / 2
      };
      return pt;
    }
    

    The Get­Rect­Center helper function calculates center of a rectangle.

    BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
    {
      CreateWindow(TEXT("button"),
                   TEXT("Button 1"),
                   WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
                   0, 0, 200, 50,
                   hwnd,
                   (HMENU)1,
                   g_hinst,
                   0);
      return TRUE;
    }
    

    When our main window is created, we put a default button inside it.

    #define WM_CHECKSNAPDEFBUTTON WM_APP
    
    void OnShowWindow(HWND hwnd, BOOL fShow, UINT status)
    {
      if (fShow && status == 0)
      {
        PostMessage(hwnd, WM_CHECKSNAPDEFBUTTON, 0, 0);
      }
    }
    
    void OnCheckSnapDefButton(HWND hwnd)
    {
      BOOL fSnapToDefButton;
      if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0,
                               &fSnapToDefButton, 0) &&
                               fSnapToDefButton &&
                               hwnd == GetForegroundWindow())
      {
        RECT rcButton;
        GetWindowRect(GetDlgItem(hwnd, 1), &rcButton);
        POINT ptCenter = GetRectCenter(&rcButton);
        SetCursorPos(ptCenter.x, ptCenter.y);
      }
    }
    

    When the window is shown, we post a message to check the Snap To setting after things have settled down. Once things settle down, we check the Snap To setting, and if it's enabled, and if our window is still the foreground window, then we center the cursor on our button.

    It's important to check that our window is still the foreground window, because it would be rude to move the cursor to our button even if we opened in the background.

    That's why we need to post a message to perform the check later. The WM_SHOW­WINDOW message is sent early in the Show­Window calculations, before the activation actually changes. If we performed the check then, the answer would always be, "No, you're not the foreground window," and we would always back off.

    Naturally, we need to hook up our new messages.

      HANDLE_MSG(hwnd, WM_SHOWWINDOW, OnShowWindow);
      case WM_CHECKSNAPDEFBUTTON: OnCheckSnapDefButton(hwnd); break;
    

    And there you have it, a program that honors the Automatically move pointer to the default button in a dialog box setting in its custom nonstandard dialog.

    Exercise: What assumptions are made about the rectangle by the Get­Rect­Center function? How do they differ from the assumptions made by this alternate version:

    POINT GetRectCenter(LPCRECT prc)
    {
      POINT pt = {
        (prc->left + prc->right) / 2,
        (prc->top + prc->bottom) / 2
      };
      return pt;
    }
    
Page 4 of 26 (257 items) «23456»