# June, 2011

• #### You'd think that with the name scratch, people wouldn't expect it to be around for a long time

There is a server run by the Windows team called scratch. Its purpose is to act as a file server for storing files temporarily. For example, if you want to send somebody a crash dump, you can copy it to the scratch server and send the person a link. The file server is never backed up and is not designed to be used as a permanent solution for anything.

The Windows team likes to use the server to test various file server features. For example, the scratch server uses hierarchical storage management and migrates files to tape relatively aggressively, so that the HSM development team can get real-world usage of their feature.

The file system team will occasionally wipe the hard drives on the server and reformat them with a new version of NTFS, so that they can put the new file system driver through its paces in a situation where it is under heavy load.

When these sort of "mass extinction events" takes place, you can count on somebody sending out email saying, "Hey, what happened to the sprocket degreaser? It was on \\scratch\temp\sprocket_degreaser, but now I can't find it. I have an automated test that relies on the sprocket degreaser as well as some data files on \\scratch\temp\foobar_test_data, and they're all gone!"

Um, that's a scratch machine. Why would you put important stuff on it?

Okay, well before we reformatted the hard drive, we copied the data to \\scratch2\save, so try looking there. But remember, the scratch server is for temporary file storage and comes with no service level agreement.

"Oh, phew, thanks."

You'd think that with the name scratch, people wouldn't expect it to be around for a long time. Maybe they could call it can_be_reformatted_at_any_time.

[Raymond is currently on his way to sunny Hawaii; this message was pre-recorded. Mahalo.]

• #### In Windows, the directory is the application bundle

Aaargh! wonders why Windows doesn't just steal the concept of bundles from Apple and package up each application with all its libraries and everything else it needs into a single directory.

This is such a great idea, it's been around since the early 1990's. It's just that Windows didn't give it a cute named like bundle. It just gave it the boring name directory. In other words, it's a victim of bad marketing. Maybe we should have given it a cute name like... elfgrass.

The first directory searched by the LoadLibrary function is the directory containing the application. If you put all your supporting libraries in the same directory as your EXE, and if you access non-library data via paths relative to your application directory, then then you have successfully packaged up your application with all its libraries and everything else it needs into a single directory. Congratulations, you pre-invented the bundle.

Indeed, Microsoft's guidance for over a decade has been to discourage copying files into the System32 directory.

If this facility has been around for nearly twenty years, why do people still copy files into the System32 directory?

Probably inertia. "We've always installed that way, and we're not changing it because we don't know what would stop working."

There may be some people concerned about disk space. "We have a bunch of applications which share some common libraries, and by putting the common libraries in a shared location (instead of in the application directory), we avoid wasting the user's disk space." Which raises the troublesome question: Is disk space still an issue nowadays?

Some people would say that no, disk space is no longer an issue. Hard drives are hundreds of gigabytes in size. Increasing the size of each application by a few dozen megabytes is just noise.

Other people would say that yes, disk space is still an issue. (Note how many people got excited when Snow Leopard took up less disk space.) Solid-state hard drives are still limited in size, and even for people with large hard drives, you see them freaking out about the disk space used by things like Windows Update, volume snapshot services, and System Restore. (Nevermind that at least for volume snapshots and System Restore, the disk space is automatically released when disk space starts to run low. It's like getting upset that the disk cache uses so much of your memory even though the computer is not under any memory pressure.)

Bonus reading: Disk space and Windows 7.

• #### How to get Windows Media Player to single-step a video

I always forget how to do this, so I'm going to write it down so I can look it up later.

When a video is playing, right-click the volume control slider and select Enhancements, then Play speed settings. (Actually, it also works if you right-click the speaker icon, the Stop button, the Replay button, or the Shuffle button, but the volume control slider is the biggest target.)

On the Play speed settings dialog, the single-step controls are at the bottom; they look like triangles.

Update: There's an even easier way.

• #### How do I compress files (via NTFS compression) from the command line?

A customer wanted to know whether there was a way to compress files and directories (in the sense of NTFS compression) from a script or from the command line. They knew about the Properties dialog, but they wanted something scriptable.

The command-line tool for this is COMPACT.EXE. Type compact /? for usage information.

The customer liaison was grateful for this information.

Thanks for the prompt response, and yes, this will meet our customer's need to compress specific files such as *.docx under a particular directory and all its subdirectories.

Um, *.docx files are already compressed. Compressing them again gains you nothing.

Bonus reading: Functions for manipulating documents which follow the Open Package Conventions are available in both managed and unmanaged versions. Check out the Packaging Team Blog for more information, including a comparison of the managed and unmanaged versions.

• #### How do I control X-Mouse settings (active window tracking)?

For quite some time, Windows has had a setting officially called active window tracking but which informally goes by the name X-Mouse, because that was the name of the PowerToy which first exposed the feature. (The PowerToy was in turn so-named because it made the mouse behave in a manner similar to many X window managers.) The setting is exposed to end users in Windows 7 on Make the mouse easier to use under Activate a window by hovering over it with the mouse.

If you want to write your own PowerToy to control this setting, you can do so by calling the SystemParametersInfo function. There are three settings which collectively control the X-Mouse feature:

1. SPI_SETACTIVEWINDOWTRACKING: This is the master switch which enables the behavior.
2. SPI_SETACTIVEWNDTRKZORDER: This controls whether the window is brought to the top when it is activated by active window tracking.
3. SPI_SETACTIVEWNDTRKTIMEOUT: This controls how long the mouse has to be in a window before it is auto-activated.

Note that X-Mouse is a user preference. Applications should not change the setting without the user's permission.

• #### Why doesn't my MessageBox wrap at the right location?

A customer reported that the MessageBox function was wrapping text "at the wrong location."

Our program displays a message with the MessageBox function, and we use the '\n' character to force line breaks at positions we choose. But we've found that starting in Windows Vista, the line breaks we placed are not working. The MessageBox function is inserting its own line breaks, which interferes with our custom text layout. It used to be that the width of the message box would expand to fit the longest line in the message.

The MessageBox function is one of those "leave the driving to us" type of functions. You give it a string to display, select which buttons you want, and sit back and relax while the MessageBox function does the work. The trade-off for the simplicity is that you also lose control over the experience. The MessageBox function decides where to place the dialog and how big to make it, which in turn determines where the line breaks go.

The algorithm used by MessageBox to determine the size of the message box has changed many times over the lifetime of Windows. In Windows 3.1, it was the width of the longest line, or 5/8 of the width of the screen, whichever was smaller. Windows 95 chose the smallest of the following which resulted in a dialog box that fit inside the working area:

• the width of the longest line,
• 5/8 of the width of the working area,
• 3/4 of the width of the working area,
• 7/8 of the width of the working area,

Notice that even in Windows XP, the dialog box was not guaranteed to be the width of the longest line. If the longest line was more than 5/8 of the width of the working area, the MessageBox is probably going to insert its own line breaks beyond ones you inserted explicitly.

Windows Vista changed the algorithm again, in recognition of two things. First, monitors are now much larger than they were in 1995. And second, the consequence of these larger monitors is that the 7/8 rule resulted in message boxes that were unreadable because they were 10 inches wide and half an inch tall. The old algorithm did not age well, but then again, it was written back in the days when the really cool kids had 1024×768 screens. Nowadays, even the kids from the wrong side of the tracks have screens that are regularly 1400 or even 1600 pixels wide.

The new algorithm merely adds another option to the table of choices:

• the width of the longest line,
• 278 DLU,
• 5/8 of the width of the working area,
• 3/4 of the width of the working area,
• 7/8 of the width of the working area,

Note that the details of the MessageBox line breaking algorithm are provided for historical purposes only. Do not write code which relies on them, because who knows, they may change again in the next version of Windows.

The algorithm was changed at the request of the visual design team; after all, it's the job of the visual design team to make these sorts of visual design decisions. If you don't want some black-turtleneck-wearing designer in Redmond to decide where your line breaks go, then don't use MessageBox. And you don't have to go and convert every single message box to its own dialog template; just write a function called MessageBoxWithLineBreaksExactlyWhereIPutThem function that takes the same parameters as MessageBox but lays out the text exactly the way you want it. (The DT_CALCRECT flag will be useful here.)

• #### PE resources must be 4-byte aligned, but that doesn't stop people from trying other alignments

Resources in PE-format files must be stored at offsets which are a multiple of four. This requirement is necessary for platforms which are sensitive to data alignment.

That doesn't stop people from breaking the rules anyway. After all, it sort of works anyway, as long as you're careful. I mean, sure maybe if somebody running a non-x86 version of Windows tries to read your resources, they will crash, but who uses non-x86 versions of Windows, right?

In Windows Vista SP1, additional hardening was added to the resource parsing code to address various security issues, but the one that's important today is that tests were made to verify that the data were properly aligned before accessing it. This prevents a file with a misaligned version resource from crashing any program that tried to read its resources. In particular, it is common for programs to read the version resources of arbitrary files—for example, Explorer does it when you view the file's properties or if you turn on the Description column in Details view—so enforcing alignment on resources closes that avenue of remote denial of service.

And then the bug reports came in. "Program XYZ fails to install" because the program tries to read its own version resources and cannot, because the tool they used to build the program cheated on the alignment requirement and stored the resources at offsets that aren't multiples of 4. "I mean, come on, that wastes like three bytes per resource. Everything still worked when we removed the alignment padding, so we went ahead and shipped it that way."

Another example of a program that stopped working when the alignment rules were enforced was a computer game expansion pack which could not install because the code that tried to verify that you had the base game found itself unable to read its version resources.

Multiple programs refused to run, preferring to display the error message "AppName is not a valid Win32 application." Presumably, as part of initialization, they tried to read their own version resources, which failed with ERROR_BAD_EXE_FORMAT, which they then showed to the user.

The fix was to relax the enforcement of the rules back to the previous level, and impose the stricter requirements only on architectures which raise exceptions on misaligned data. It does mean that you can have a program whose resources can be read on one machine but not on the other, but that was deemed a lesser evil than breaking all the programs which relied on being able to misalign their data without consequence.

[Raymond is currently away; this message was pre-recorded.]

• #### What happens when applications try to copy text by sending Ctrl+C

I'm stealing this story from one of my colleagues.

I remember one app from a long time ago that had a feature where you could hit a global short cut key (or something like that) to launch the dictionary. It was also smart in that it would detect the current selected text and immediately search the dictionary for that term.

One day I was running a Perl script that took several hours to run. It was nearly done and for whatever I decided to launch the dictionary. It sent a Ctrl+C to my Perl script and killed it.

And that's why you don't send Ctrl+C to arbitrary applications.

Active Accessibility gives you access to the text under the cursor. There's also a newer interface known as UI Automation which has a handy method called IText­Provider::Get­Selection. (On the managed side, you have System.Windows.Automation.Text­Pattern.Get­Selection.)

Update: Commenter parkrrrr points out the IText­Provider::Get­Selection. is the provider-side interface. The interface for applications wishing to read the selected text is IUI­Automation­Text­Pattern.

• #### How do I prevent users from pinning my program to the taskbar?

A customer wanted to prevent users from pinning their application to the taskbar.

I have an application that is launched as a helper by a main application. Users shouldn't be launching it directly, but rather should be launching the main application. But since the helper shows up in the taskbar, users may be tempted to right-click on the taskbar icon and select "Pin to taskbar." Unfortunately, this pins the helper program to the taskbar instead of the main application, and launching the helper program directly doesn't work. Is there a way I can prevent users from pinning the helper program?

It so happens that there are a number of ways of marking your helper program as Don't pin me. Given the description above, the most direct way is probably to set the System.App­User­Model.Prevent­Pinning property on the window created by the helper program.

Take our scratch program and make the following changes:

#include <shellapi.h>
#include <propsys.h>
#include <propkey.h>

HRESULT MarkWindowAsUnpinnable(HWND hwnd)
{
IPropertyStore *pps;
HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr)) {
PROPVARIANT var;
var.vt = VT_BOOL;
var.boolVal = VARIANT_TRUE;
hr = pps->SetValue(PKEY_AppUserModel_PreventPinning, var);
pps->Release();
}
return hr;
}

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
MarkWindowAsUnpinnable(hwnd);
return TRUE;
}


I set the PROP­VARIANT manually instead of using Init­Prop­Variant­From­Boolean just to emphasize that the boolVal must be VARIANT_TRUE and not TRUE. In real life, I probably would have used Init­Prop­Variant­From­Boolean.

Run this program and observe that "Pin this program to taskbar" does not appear on the menu when you right-click on the taskbar button.

Even better would be to permit pinning, but set the System.App­User­Model.Relaunch­Command, .Relaunch­Display­Name­Resource and optionally .Relaunch­Icon­Resource properties so that if the user tries to pin the helper, it actually pins the main application.

#include <shellapi.h>
#include <propsys.h>
#include <propkey.h>
#include <propvarutil.h>

HRESULT IPropertyStore_SetValue(IPropertyStore *pps,
REFPROPERTYKEY pkey, PCWSTR pszValue)
{
PROPVARIANT var;
HRESULT hr = InitPropVariantFromString(pszValue, &var);
if (SUCCEEDED(hr))
{
hr = pps->SetValue(pkey, var);
PropVariantClear(&var);
}
return hr;
}

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
IPropertyStore *pps;
HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr)) {
IPropertyStore_SetValue(pps,
PKEY_AppUserModel_ID, L"Contoso.Scratch");
IPropertyStore_SetValue(pps,
PKEY_AppUserModel_RelaunchCommand,
IPropertyStore_SetValue(pps,
PKEY_AppUserModel_RelaunchDisplayNameResource,
L"C:\\full\\path\\to\\scratch.exe,-1");
// optionally also set PKEY_AppUserModel_RelaunchIconResource
pps->Release();
}
return TRUE;
}

// resource file
STRINGTABLE BEGIN
1 "Open system.ini"
END



I'm pulling a fast one here and pretending that Notepad is my main application. Obviously you'd use your actual main application. (I'm also hard-coding the path to my scratch program.)

When you run this program, right-click on the taskbar button. Observe that the option to run a new copy of the program is called Open system.ini and if you pick it (or use the middle-mouse-button shortcut), Notepad runs. If you pin the program, the pinned icon runs Notepad.

Even if you don't need to redirect the pinned item to another program, you can use this second technique to pass a custom command line for the pinned icon.

• #### Why do Group Policy settings require me to have a degree in philosophy?

Josh points out that Group Policy settings often employ double-negatives (and what's the difference between turning something off and not configuring it)?

Group Policy settings are unusual in that they are there to modify behavior that would continue to exist without them. They aren't part of the behavior but rather a follow-on. Suppose that the default behavior is to do XYZ automatically, but due to requests from corporate customers, a Group Policy is added to alter this behavior. The Group Policy for this might look like this:

Don't do XYZ automatically

The template for boolean Group Policy settings is

Blah blah blah

Consequently, every boolean Group Policy setting is forced into the above format, even if the setting is reverse-sense, as our sample one is. In general, the three settings for a Group Policy mean

 Enabled Change the behavior as described in the title of the group policy. Disabled Do not change the behavior and continue with the default behavior. Not configured Let somebody else decide.

The difference between Disabled and Not configured is that when you disable a Group Policy, then you're saying "Restore default behavior." On the other hand, if you don't configure a Group Policy setting, then you're saying "I have no opinion about whether this Group Policy should be enabled or disabled, so keep looking, because there might be another Group Policy Object that does express an opinion."

Recall that multiple Group Policy Objects can apply to a specific user. For example, a typical user may be subject to a Local Group Policy, a Non-Administrator Local Group Policy, a series of other Group Policies depending on what security groups the user belongs to, and then a User-Specified Group Policy. You can use the Resultant Set of Policy snap-in to see how all these different Group Policy Objects interact.

The upshot of this is that Group Policy settings often end up using double negatives if the policy is to disable a default behavior. You "Enable" the setting to disable the default behavior, you "Disable" the setting to enable the default behavior, and you leave the setting "Not configured" if you want to let some other Group Policy Object decide. Even when there is a more clever way of wording the options to avoid the double negative, the people who write Group Policy descriptions are so used to double-negatives that it doesn't even occur to them that a particular setting setting permits an optimization. (Either that, or they figure that system administrators are so used to seeing double-negatives, that when it's not there, they get confused!)

Page 1 of 3 (25 items) 123