Free Newsletters

   All InfoWorld Newsletters
Strategic Developer | Martin Heller » TAG: Windows

July 03, 2008 | Comments: (0)

Loading a Direct3D mesh from a resource

Why is it that trivial things become hard so often, especially when you're doing API-level C++ programming? Here's an example:

I needed to convert a Windows Direct3D benchmark from loading its textures and meshes from files to loading them from resources, to simplify the installation of the benchmark as an ActiveX control. This should have been trivial: just change the D3DXCreateTextureFromFile calls to D3DXCreateTextureFromResource calls and the D3DXLoadMeshFromX calls to D3DXLoadMeshFromXResource calls, and Bob's your Uncle.

Not so fast.

The textures loaded fine from resources once I plugged g_HInstance in as the hSrcModule and MAKEINTRESOURCEA(iResourceID) as the pSrcResource in the following prototype:

HRESULT D3DXCreateTextureFromResource(
  LPDIRECT3DDEVICE9 pDevice,
  HMODULE hSrcModule,
  LPCTSTR pSrcResource,
  LPDIRECT3DTEXTURE9 * ppTexture
);

So the actual code became something like:

D3DXCreateTextureFromResourceA(eng->getD3DDevice(), g_hInstance, MAKEINTRESOURCEA(texNum), &texture );

This worked without a hitch. On the other hand, loading a mesh gave me fits. The prototype is:

HRESULT D3DXLoadMeshFromXResource(
  HMODULE Module,
  LPCSTR Name,
  LPCSTR Type,
  DWORD Options,
  LPDIRECT3DDEVICE9 pD3DDevice,
  LPD3DXBUFFER * ppAdjacency,
  LPD3DXBUFFER * ppMaterials,
  LPD3DXBUFFER * ppEffectInstances,
  DWORD * pNumMaterials,
  LPD3DXMESH * ppMesh
);

I tried "X" for the Type, but the mesh didn't load. What to do?

The documentation for the March 2008 DirectX SDK has the promising explanation of the second through fourth parameters:

See Find Resource to find out more about the Module, Name and Type parameters.

While that link works today, when I was trying to solve the problem it brought up an error page in Japanese. Go figure. If you follow the Resource Types link in the Find Resource page, you'll get to a table of standard resource types (which I also couldn't find when I actually had the problem): the one we want is RT_RCDATA, since meshes aren't covered by any of the other standard resource types. (At the time, it took a Google Code search to find this.)

In fact, using that value didn't work for me: RT_RCDATA is not really the enum value you'd expect, but is actually a macro that resolves to the highly intuitive MAKEINTRESOURCE(10). My ActiveX control was compiled for Unicode, so MAKEINTRESOURCE resolved to MAKEINTRESOURCEW, which returns a pointer to a wide character string. Unfortunately, D3DXLoadMeshFromXResource has a LPCSTR for the Type parameter, not a LPTSTR, so it needs an ANSI string, not a Unicode string. What I really needed there was MAKEINTRESOURCEA(10). The final call looked something like:

D3DXLoadMeshFromXResource(g_hInstance, MAKEINTRESOURCEA(meshNum), MAKEINTRESOURCEA(10),
usageFlag, d3dDevice, NULL, NULL, NULL, &dwNumber, &pMesh );

And that worked. Whew!

Posted by Martin Heller on July 3, 2008 12:37 PM



May 20, 2008 | Comments: (0)

Ruby on Rails IDEs

I'm gearing up to write a comparative, multi-platform review of Rails IDEs. Before I freeze the list, I'd like to know what other people are using themselves to develop Rails sites.

Currently I'm considering these 8:

  • Ruby in Steel
  • Aptana RadRails
  • Komodo
  • 3rdRail
  • NetBeans
  • SciTE
  • TextMate
  • jEdit with Ruby plugin

Do you have experience with any of these you'd like to share?

Do you use something else for Rails development?

What are the strengths and weaknesses of the Rails IDEs you use yourself?

Posted by Martin Heller on May 20, 2008 11:16 AM



May 15, 2008 | Comments: (0)

Avoiding Vista?

InfoWorld recently ran an article by Eric Lai of our sister publication ComputerWorld called Developers explain why they're avoiding Vista. I'm afraid that for me, and probably for most of you, this falls in the "D'oh" department.

The subhead of the article is "Fewer than 1 in 12 programmers is currently writing applications targeting Microsoft's Vista operating system." Again, "D'oh."

If I'm going to develop a product, I want someone to pay for it. That can be the company that wants it, or end users, or both. (OK, I've occasionally been suckered into developing for equity, but the equity never materializes, and I'd better stop here before I say something that would upset IDG's lawyers.)

Here's the current overall Windows market share picture, as tracked by PC Pitstop:

That's not yet a compelling case for writing software that requires Windows Vista: 80% of the total market wouldn't or couldn't run it. I would expect the situation to be worse for business, and it is:

So over 90% of the business market couldn't or wouldn't run a Vista application.

The new technology introduced with Windows Vista is seriously cool, and I'm learning about it all the time. But there has to be a market before I'll devote large chunks of my time to developing for it, unless the technology makes something possible that was previously impossible, or makes something easy that was previously prohibitively time-consuming.

What do you think? Are you developing with Vista technologies?

Posted by Martin Heller on May 15, 2008 11:07 AM



February 29, 2008 | Comments: (0)

Your friendly local computer support person

Like many people who write about or work with computers for a living, I often get computer support requests from relatives, friends, and people I happen to meet. I'm starting to have some sympathy for doctors. ("You're a doctor? I have this pain...")

At Comdex (1995?)

A memorable instance of this happened at Comdex in Las Vegas, around 1995. I was completely stressed out and in a lot of pain, so I scheduled a massage at the Las Vegas Hilton spa before my daily round of vendor meetings and booth visits. I sat in the steam room for 15 minutes to loosen up a little, and then lay down on the massage table.

"So," asked the masseur as he worked my knotted traps. "What do you do?"

"I'm an editor for Windows Magazine."

"You're a computer guy? I have this problem with my computer..."

As it turned out, he'd bought a large hard disk that his computer wasn't recognizing. It was a common problem at the time: the usual fix was either to update the BIOS or install a disk driver. I told him that, and eventually got to relax.

The other evening...

I've mentioned my oldest daughter several times, for example here. Her husband called me the other evening with a problem. He had been attempting to look up an Optometry journal article from his Windows XP laptop, and mistyped the URL. As a result, he got a junk page. As soon as the page opened, a drive-by download started:

"Warning! Your computer is infected with spyware! We are now downloading a fix!"

His first reaction was a good one: his gut told him that something was wrong, and he said "Oh no you're not!" and killed the download. Then, naturally, he started to panic.

He ran a full test at PC Pitstop, and also downloaded and ran Exterminate to check for spyware. Then he called me for support. Yes indeed, I told him, that warning you saw is from some nasty malware trying to get you to let it install itself while masquerading as a cure.

The full test didn't find any malware running, and Exterminate only found a few moderate threats on his disk. Did he have the "Install AntiSpyware" tip from the full scan? Yes, he did.

As it happens, I wrote that tip, so I pointed him at the bottom of the page where I'd given links to the free antispyware programs that I recommend: Windows Defender, Ad-Aware, Spybot Search and Destroy, and Spyware Blaster. I left him to download one or all of them and disinfect his computer.

Then it was back to NCIS for me.

Posted by Martin Heller on February 29, 2008 07:37 AM



February 25, 2008 | Comments: (0)

Leaving Windows 9x behind to move forward

Last August I wrote about maintaining backward compatibility to versions of Windows from 15 years ago while supporting new features of Windows Vista. Several of you had trouble believing I would continue to go to all that trouble.

I have finally given up, although not voluntarily.

As it happens, I had to merge some code from a program into an ActiveX control. The program is compiled with Visual Studio 2005 (VS05), maintained by another developer, and runs on Windows 2000, XP, 2003 and Vista. We haven't yet tested it on Windows Server 2008.

The ActiveX control was compiled with Visual Studio .NET 2003 (VS03) and ran on Windows 95 and up. When I tried adding the new code and compiling in VS03, it was clear that I'd have my work cut out trying to remove all the calls to new library functions to get it to compile without errors. Then I'd have to face updating my branched code every time the developer did a maintenance release. There was too much code for me to go the conditional compilation route and get this working in a reasonable amount of time.

I tried upgrading the project to Visual Studio 2008 (VS08). The new code compiled without warnings, but my old code had bunches of errors and warnings. Fortunately, the errors were all from duplicate definitions, and it was easy enough to remove the inline definitions that were now coming from the default SDK. The warnings were mostly to get me to update to "safe" string functions: that can wait until I have time, since this code has been heavily tested over many years.

I got the new code working and tied into the proper ActiveX interfaces, and started testing it on my array of Windows computers and virtual PC images. When I got to the Windows 98 SE Virtual PC, I discovered that the control wouldn't load.

I explored the DLL with "depends" and discovered that the new code uses five kernel functions that weren't introduced until Windows 2000. Using my standard techniques, I wrote a dynaload class for those five functions and modified the code to use them.

The control still wouldn't load in Windows 98.

To make a long story (think days of failed experiments) short, we discovered that VS08 no longer targets Windows 9x. Apparently VS05 doesn't, either. There are a couple of kernel functions called by the C++ libraries that require later versions of Windows. In order to get this control built in VS08 to work on Windows 9x, I'd have to make custom modifications to the C++ libraries and link to them. I'd also have to reapply my changes every time Microsoft updated the libraries.

That was the last straw for me. I reverted to the version of the control without the last group of dynaloads, and I now plan to leave Windows 9x behind. There's no real business reason to keep supporting it, and now there would substantial costs in attempting to do so.

I might wish that Microsoft had continued to target Windows 9x in VS05 and VS08, but I can't really blame them. They, too, need to leave the past behind in order to move forward.

Posted by Martin Heller on February 25, 2008 01:12 PM



February 22, 2008 | Comments: (0)

Open Microsoft APIs and Formats a Mixed Blessing

Be careful what you ask for: you might get it.

That goes double when you ask Microsoft to release its internal APIs, protocols, and file formats. It has happened, as reported here. The E.U.'s reaction was guarded. Analysts speculated that this move might help Microsoft repair its reputation. Savio wonders whether Microsoft is borrowing the "anti-lock-in" argument from the open-source software movement's playbook. Zach says he's "optimistic."

After reading some of the material about Office file formats on the Microsoft interoperability site and a little of the open protocol material on MSDN, I wonder whether releasing 30K pages of such material is actually such a good thing.

I agree that it's good in principle for Microsoft to be more open. It's certainly a good thing for people who build open-source alternatives to Microsoft's products, and products that interoperate with Microsoft's.

I'm not so sure it's a good thing for me. Frankly, I was already overwhelmed trying to keep up with the explosion of APIs and classes coming out of Microsoft. And those were the ones that were designed to be used by mere mortals.

Isn't someone going to provide me with a telephone booth and a SuperProgrammer costume?

Posted by Martin Heller on February 22, 2008 07:59 AM



February 13, 2008 | Comments: (0)

Rained Five Days

Last Friday I mentioned that I was singing the Update Blues. My version was too scatological to print, so I challenged you readers to write your own.

What did I get? Limericks. Feh!

The horrible weather we're having on the East Coast reminds me of a classic 12-bar Delta blues number. Was it Blind Lemon who sang it?

It rained five days and the sky was dark as night
Oh, it rained five days and the sky was dark as night
But my mama's in the kitchen so's I know everythin's alright.

By the way, this month's Tuesday Windows and Office updates were even more annoying than I expected. Not as annoying as the iTunes update du jour, but still not the seamless automatic process one might hope would happen in the wee hours, with the exception of just one of my Windows Vista machines.

Rained five days.

Posted by Martin Heller on February 13, 2008 02:16 PM



February 08, 2008 | Comments: (0)

Singing the Update Blues

Today it was Firefox. Yesterday it was QuickTime. Next Tuesday it'll be Windows, Office, and Internet Exporer.

I'm talking about critical bug fixes. It's worse for me than for a lot of people because I personally have 6 Windows computers and a bunch of Windows Virtual PCs that I have to keep up-to-date for software testing.

Now, I used to think this was just a Windows issue. Then I started reviewing Linux systems: Red Hat, Fedora, Debian, Mandriva, SuSE, Xandros, and so on. Every one of those systems needs frequent critical bug fixes, and most of them need more of them than Windows XP. Fedora may well be the worst distro I have for the number of critical bug fixes that need to be installed, but maybe that makes it the most secure day-to-day: I don't know.

Meanwhile, it's hard to get any real work done if you spend all your time updating your computers.

I'm singing the blues about this, but the words aren't suitable for publication. Do you have a verse to offer on the subject that could be printed in a family magazine?

Posted by Martin Heller on February 8, 2008 08:08 AM



February 06, 2008 | Comments: (0)

Writing Secure ActiveX Controls

This recent news story touches on a long-standing problem:

Attackers zero in on Yahoo Jukebox's ActiveX flaw | InfoWorld | News | 2008-02-06 | By Robert McMillan, IDG News Service

The fact is, writing secure ActiveX controls is an art, not a science. To succeed, a software developer has to look beyond the intended purposes of the interfaces, to other purposes for which they might be used.

Say, for instance, that I wrote an interface to upload files to a site, intended to be run on a well-known safe site. If I had written it in a broad way so that it could be used to silently upload any file to any site, then a malicious site could detect the control and use it to upload Quicken files to steal peoples' financial information.

One safeguard is to be noisy about what you're doing. My ActiveX controls pop up simple OK/Cancel permission dialogs the first time they are invoked in a browser session; the dialogs say what they are going to do and what sites they were intended to work on. That's simple, and only mildly annoying. Of course, users tend to get jaded and accept such dialogs without thinking, but darkening the screen and sounding the klaxon horn of doom probably won't help in the long term.

Another safeguard is to actually check the site currently in use. That's a little harder, but it's possible. Internet Explorer supports a service called IWebBrowser2, which has an interface called get_LocationURL. This returns the URL of the calling page as a BSTR, and you can then use InternetCrackUrl from the wininet library to extract the domain and see if it's on your white list of safe or licensed domains.

A third safeguard is to restrict the functionality of the interface. Perhaps I want the control to upload images. If that's the case, I could restrict the file types it will upload to .GIF, .JPG, .PNG, and .TIFF. The control could also double check that the files were valid before uploading them: there's a reason that .TIFF files all have the number 42 in a specific place.

And yes, 42 is the answer to "life, the universe, and everything."

Do you write ActiveX controls? If so, how do you protect them from malicious use?

If you write Flash controls, how do you protect them?

Posted by Martin Heller on February 6, 2008 07:10 AM



December 03, 2007 | Comments: (0)

Lies, Damned Lies and Benchmarks, Yet Again

I've noticed (well, who wouldn't?) that Randall Kennedy (RCK) is in a kerfuffle about Nick White, a Microsoft Vista Product Manager, who blogged a relatively mild discussion of "The right time to assess Windows Vista's performance." So, at the risk of antagonizing everyone involved for no benefit whatsoever, let me offer another perspective.

RCK wrote the benchmarks used by www.xpnet.com. Recently that organization compared release candidates of Windows XP SP3 and Windows Vista SP1, and found Vista lacking. That shouldn't really come as a surprise to anyone, but I'm not sure that it's the issue here.

Nick White's blog post points out that Microsoft only publicly benchmarks products once they have been released to manufacturing; that has been true to my knowledge for at least 20 years. When beta testers had to sign a non-disclosure agreement to work with pre-release Microsoft products, one of the key terms of the agreement was always a ban on publishing performance numbers prior to product release.

I can remember lots of products that had performance issues right up to the final release candidate that testers got to see, but were fine when released to manufacturing. So Nick has a point: a release candidate is not the right build to benchmark if you want to understand the performance of an OS. You need to wait for the RTM bits.

RCK commented to Nick's blog in high dudgeon, about being attacked. But was he attacked? Nick never mentioned xpnet or OfficeBench or RCK in his post, so I'd say no.

RCK certainly interpreted the post as an attack. I read the posting more as being a little defensive, but hardly an attack.

Nick talked a lot about Principled Technologies, which did some Vista benchmarks for Microsoft last year, and Nick suggested that their benchmarks had been done properly. I'm not so sure about that: when you know the results your client wants to get, it's easy to pick tests that will produce those results, whether you consciously mean to or not. Given the variance in results between the two sets of benchmarks, I'm not surprised that RCK feels defensive.

As a benchmark writer myself (I'm responsible for the WinTune and PC Pitstop benchmarks), I'm here to tell you that no single set of benchmarks can ever tell the whole story. My benchmarks sure can't, and I've really worked at them over the years; I rather suspect that neither OfficeBench nor the Principled Technologies benchmarks can either.

So can everybody please chill?

Posted by Martin Heller on December 3, 2007 02:40 PM



November 21, 2007 | Comments: (0)

WMI Weirdness

After a snipe hunt to determine why the WMI Win32_StartupCommand class would return thousands of entries, most of which look like device drivers, Dave Methvin found a Web page with a fix here.

The problem happens when the Windows registry string value "Startup" located at the key "HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" has no value or points to a non-existent folder. Filling the value with "C:\Documents and Settings\Default User\Start Menu\Programs\Startup" fixes the problem on Windows XP.

The next interesting question is why this happens. Currently I suspect a bug in msconfig, but I have no proof.

Posted by Martin Heller on November 21, 2007 02:24 PM



October 12, 2007 | Comments: (0)

Selkie Rescue

Selkie RescueOne of my favorite techniques for rescuing Windows systems that won't boot normally or in safe mode is to try booting them from a CD-ROM, because what I care about most at this point is the data on the system. Sometimes I use a Windows CD, especially when I think the problem is corrupted system software that can be repaired with a reinstall without affecting the data files; sometimes I use one of the Linux Live CDs I keep around. Depending on how badly the system has been hosed, I can often boot from a CD and read the data from the hard disk, even though I can't boot from the hard disk. This isn't always easy, though.

For $100 you can buy Selkie Rescue, which is basically a stripped-down Linux Live CD that has been tailored for the purpose of creating readable Samba shares to the system's hard disks. How is it better than a free Linux Live CD? I asked that very question and got this answer from Jonathan Lyster, CTO of Tugboat Enterprises.

Linux live CDs are designed to demo Linux on a functioning computer; they are not meant to work on a computer that has begun to fail. As such, they have limitations:

  • They use the full resources of a video card; if a video card has begun to fail, for example the components which enable the full color set and high resolution, a typical live CD will fail.
  • Selkie was deliberately built to avoid using any components which don't have a direct bearing on copying files safely to a recovery computer. This means a computer failure caused by a bad audio chip on the motherboard will not affect Selkie. (Selkie doesn't include audio components.)
  • Most live CDs can be booted to a command prompt -- but at this point the user requires technical knowledge of Linux in order to use the disc.

Selkie was designed with ultimate simplicity in mind. The user doesn't need any knowledge of computers or networking -- Selkie handles all of it. Selkie can literally be brought from boot-up being making all files available to the network in as little as three taps of the ENTER key.

I tried booting a Selkie CD in the oldest machine that still lives in my office, a 333 MHz Celeron box with 64 MB of RAM that runs Windows NT 4.0 Workstation SP6. I rarely bother to boot it up: it's only still here for an occasional software compatibility test. The Selkie CD came right up, and as Jonathan said it took 3 taps of the Enter key and a couple of minutes, and then I had shares on my network, in the correct workgroup, that showed me the files on the box from my other computers. I could also see a log of the hardware detected by Selkie, and a log of Selkie system messages.

Very impressive. In fact, there was nothing wrong with that box: I had no trouble rebooting it to Windows NT, and seeing the same disks on the network. But it's still nice to know that I have an easy way to get at the data on any of my systems if they ever become unbootable.

I didn't use it, but the Selkie Rescue box also contains a Cat 5 crossover cable. That's handy if you don't have a network hub, but do have another computer with an Ethernet port. There's also a manual in the box, but I didn't use that, either. Even I can press Enter three times.

Posted by Martin Heller on October 12, 2007 02:20 PM



August 22, 2007 | Comments: (0)

Process Monitor

Procmon As long as I'm giving away my secret weapons, I should probably mention Process Monitor, by Mark Russinovich and Bryce Cogswell. There are lots of times when I need to figure out how Windows, IE, Firefox, or some application does something, or where the app in question stores a configuration setting. These days, the first diagnostic tool I reach for in those situation is Process Monitor (Procmon). Procmon is also useful for system troubleshooting and malware hunting.

The official introduction to Procmon is:

Process Monitor is an advanced monitoring tool for Windows that shows real-time file system, Registry and process/thread activity. It combines the features of two legacy Sysinternals utilities, Filemon and Regmon, and adds an extensive list of enhancements including rich and non-destructive filtering, comprehensive event properties such session IDs and user names, reliable process information, full thread stacks with integrated symbol support for each operation, simultaneous logging to a file, and much more. Its uniquely powerful features will make Process Monitor a core utility in your system troubleshooting and malware hunting toolkit.

Process Monitor runs on Windows 2000 SP4 with Update Rollup 1, Windows XP SP2, Windows Server 2003 SP1, and Windows Vista as well as x64 versions of Windows XP, Windows Server 2003 SP1 and Windows Vista.

Posted by Martin Heller on August 22, 2007 07:49 AM



August 17, 2007 | Comments: (0)

Windows Version Trends

In the comments to my posting yesterday about maintaining backward compatibility, I was induced to reference the graph of Windows versions over time that PC Pitstop generates every month at http://www.pcpitstop.com/research/os.asp. Here it is:

PC Pitstop no longer worries about Windows 95 compatibility, because according to its own numbers nobody really cares any more.

Posted by Martin Heller on August 17, 2007 05:37 PM



August 16, 2007 | Comments: (0)

Maintaining Backward Compatibility

Dependency WalkerOne of the banes of my existence is maintaining backward compatibility to versions of Windows from 15 years ago while supporting new features of Windows Vista. It's quite a juggling act.

I use three tactics. The first is pre-emptive: every time I write new code that includes Windows APIs, I double-check the requirements of the APIs on MSDN. Often I'll find that I want to use an API that doesn't work on Windows 9X systems, or that only works in Windows Vista and above.

The second tactic is adaptive: I dynamically load the DLLs and entry points that aren't compatible with all the systems my software supports. This is a real pain in the neck, but I have some class libraries that make it less painful than writing all the Windows API calls and C++ type casts that would otherwise be needed.

The third tactic is one of testing. I have five computers in my office that cover a range of Windows versions, and one of them has Virtual PCs that cover most of the other Windows versions, plus a bunch of Linux versions. When I create a new build, I test on all the Windows versions I have covered.

When there's a problem loading the software on one or more systems, I run the Microsoft dependency walker tool depends.exe against the software on those systems. Usually, that's enough to help me locate the problem or problems, although sometimes I have to go back to MSDN and read the API descriptions again, carefully. Sometimes there are obscure notes about #include files or libraries that need to be used for compatibility with older systems; using these workarounds generally fixes the problems. It's still a pain in the neck, however.

Q: How did God create the world in seven days?

A: He didn't have an installed base.

Posted by Martin Heller on August 16, 2007 09:33 AM



July 23, 2007 | Comments: (0)

Wireshark

WiresharkWhen I needed a Network Protocol Analyzer last week, I realized that I had recently uninstalled one (I think it was NetSniffer), in a fit of tidiness. It was several years old, and I hadn't used it in over a year, so it seemed reasonable to nuke it at the time. I should have known that deleting it would be the computer equivalent of putting my snow boots away in early spring.

I tried using Fiddler2 to capture Web service traffic, but it couldn't: Fiddler hooks into WinInet, but Microsoft's implementation of Web services in C# and C++ works at a lower level. I thought of the open source Ethereal project, but the latest release was over a year old.

Dave Methvin pointed me at Wireshark, which is the current name for Ethereal: it was renamed in May 2006. Wireshark did indeed show me the Web service traffic I needed to monitor, along with a whole bunch of other network traffic that I didn't care about.

Wireshark depends on the WinPcap driver on Windows. On Linux, where Wireshark comes as a standard package, it hooks into the system drivers. Wireshark isn't the easiest software in the world to learn or use, but it works nicely, and the price is right.

Posted by Martin Heller on July 23, 2007 07:50 AM



June 18, 2007 | Comments: (0)

Accessing the 64-bit Registry

I knew there had to be a way for a 32-bit application to access the 64-bit registry on a 64-bit system, and I finally found it. Don't ask me what I think of the way Live Search works on the MSDN site, however: the answer would curl your hair.

What I needed to know is mostly buried in an MSDN article called Accessing an Alternate Registry View, which is in the MSDN tree under MSDN / MSDN Library / Win32 and COM Development / Development Guides /Programming Guide for 64-bit Windows / Running 32-bit Applications.

Normally, a 32-bit application only sees the 32-bit registry, and a 64-bit application sees the whole registry. The 32-bit registry is filed under the Wow6432Node key. Looking under the Wow6432Node key is bad practice, however, since that location may change in the future.

Basically, if an application that wants to scan the whole registry detects that it is running on 64-bit Windows, it needs to scan the registry twice: once to get the 32-bit registry keys, and once to get the 64-bit registry keys. Two flags apply:

Flag name Value Description
KEY_WOW64_64KEY 0x0100 Access a 64-bit key from either a 32-bit or 64-bit application.
KEY_WOW64_32KEY 0x0200 Access a 32-bit key from either a 32-bit or 64-bit application.

These flags can be specified in the samDesired parameter of the following registry functions:

Once you have opened a key with one of these flags, subsequent enumeration of the registry continues from the key you opened. Your application does have to be careful to be consistent: if a 32-bit application decides to delete a key that it found using the KEY_WOW64_64KEY flag, it had better use the same flag on the RegDeleteKeyEx call.

By the way, you can simulate the registry view of a 32-bit application for yourself. On a 64-bit system, there are two copies of Regedit. Running "regedit" launches the 64-bit version. Running "c:\Windows\syswow64\regedit.exe –m" lets you launch the 32-bit version. The "-m" flag allows multiple instances of the Registry Editor to be open.

Posted by Martin Heller on June 18, 2007 06:00 AM



June 15, 2007 | Comments: (0)

Help, I know I saved that file!

My oldest daughter emailed me with a Windows Vista/Excel 2007 problem:

I am so frustrated, and maybe you can shed some light on this mystery.  For the second time this week, a file that I had saved has disappeared.  Today I downloaded results from Survey Monkey, opened them in excel, went to SAVE AS, renamed it and saved as an excel 97 -2003 file (which is compatible with SPSS), then re-coded all my data.

I saved it again multiple times, as I am paranoid about losing work, and then closed it so that I could re-open it with SPSS.  Except that it is no where to be found.  I looked where I thought saved it, I looked in all my files, I went to recent items, I opened excel to look for it under those recent documents --- i looked everywhere it could be.  Nothing.  2 hrs of work, gone.

My first reaction was this note:

Don't panic.

By default, Office 2007 on Vista saves documents in a weird place, <username>\appdata\roaming\. Documents should show up in Recent Items from the Windows menu, however, no matter where they were saved. They should also show up if you use the search window at the bottom of the Windows menu, i.e. to search for "*.xls". They may not show up by default from Excel if you saved them in XLS format, but they will show up if you change the file type that Excel is seeking to All Excel Documents.

Unfortunately, that wasn't quite enough to turn up the missing file. On the other hand, she tried to replicate what she'd done to download, open and save the original file, and saw the file she wanted hiding in a temp directory, but couldn't find a way to open it.

Of course! If she downloaded the original file and opened it directly rather than save it and open it in a separate step, it would be placed in a temp directory, and if she didn't change directories when she saved as XLS, that would also be in a temp directory. Windows Vista, in its infinite wisdom, does not index temp directories, so their contents will not show up in a normal search.

We did finally find the file by going to Search Results in Everywhere, enabling Advanced Search, checking "include non-indexed, hidden, and system files (might be slow)", and looking for "*.xls". It didn't take that long, and she was then able to open the file and save it in her Documents directory.

Posted by Martin Heller on June 15, 2007 06:00 AM



June 11, 2007 | Comments: (0)

Stupid 64-bit Laptop Tricks

As I mentioned Friday, I now have a laptop on which I have installed Windows Vista Ultimate for x64. It's a Compaq Presario V6000, and it's not what I would have chosen for myself, but it was available for me to use, and the price was right. Why? Rob Cheng at PC Pitstop did a study of the bloatware on new laptop PCs from eight major manufacturers, and couldn't return most of them because of the manufacturers' very short return periods. (I recommend viewing the video Rob made and listening to his NPR interview.)

I actually got two of those leftovers for testing, a Sony Vaio with an Intel T2060 (Core Duo) CPU and this one, which has an AMD Turion 64 X2 TL-50 CPU. The Intel T2000 series CPUs don't support 64-bit mode, but I had some other debugging to do on the Sony. Using the machine as delivered gave me fits: not only was the installed bloatware constantly popping up and being annoying, but I was never able to get the networking working properly. I eventually had to use an SD card as a "sneaker net" to load the software I wanted to test onto the Sony, and got the software fixed after a couple of iterations.

After I sent the Sony off to the poor lucky person who bought it (cheap), I tried booting up the Presario, and found its bloatware just as annoying as the Vaio's had been. I rebooted the Compaq and used its F11 boot option to format and reload the main disk partition, hoping that it would offer me the option to choose a 32- or 64-bit system. It didn't, but I let it go ahead and reinstall 32-bit Windows Vista Home Premium anyway.

The bloatware was just as annoying after a fresh install, but at least the networking worked properly, both at my office and at home. I also gained some confidence that as long as I didn't mess with the D: disk partition, I'd be able to get the computer back to its "out of the box" state in an hour or so. Knowing that, I felt pretty good about booting from a Vista x64 DVD and installing Windows Vista Ultimate for x64.

That was fairly straightforward, although I did have some panicky moments when I thought I would have to go trolling the Internet for drivers. Eventually, the system found all the drivers it needed by itself, except for the HP Deskjet 3915 driver needed to print on my home network: apparently, HP hasn't yet gotten around to the Vista drivers for that little consumer printer. C'est la vie. I also had some panicky moments when the networking misbehaved, but it mysteriously started working on its own.

Most of the software I have installed on the 64-bit system so far works. The software I'm developing has issues, but that was the point of getting the system here in the first place. Windows Live Writer beta 2 also has issues, but I'm working with that team at Microsoft to track them down. Meanwhile, I'm blogging from Word 2007, and fixing up the categories online, since Word doesn't seem to know how to download categories from a blog.

On the other hand, Second Life works fine on this laptop. And, of course, so do the all-important solitaire games. J

Posted by Martin Heller on June 11, 2007 06:00 AM



June 08, 2007 | Comments: (0)

Wow64: A Blessing and a Curse

I mentioned a couple of weeks ago that applications certified to run on Windows Vista must run on x64 as well as 32-bit Vista. Wow64 makes this easy for most 32-bit Windows applications: they automatically run in a 32-bit compatibility environment and never know the difference unless they check the IsWow64Process API.

I said then that a tester had found that merely running certain applications would screw up the keyboard and mouse on Vista for x64. This report turned out to be irreproducible: as far as we can tell, it was a matter of a bad driver installation for a wireless mouse and keyboard. When I tried the same application on a laptop with Vista for x64 installed, I couldn't make the problem happen. When the tester scrubbed his system and reinstalled everything from scratch, the problem went away.

Testing the application on 64-bit Vista made it clear that Wow64 is not an unalloyed blessing. For a system utility, the sandboxes drastically reduce what the program can do. A 32-bit program scanning the 64-bit registry can only see the registry hives under Wow6432Node. A 32-bit program scanning for running programs can only see itself and any other 32-bit programs running in the Wow64 environment.

Next week I'm probably going to have to build a 64-bit version of this C++ application. Based on what I went through 15 years ago making 16-bit Windows programs work on 32-bit Windows, I'm not looking forward to the exercise.

Posted by Martin Heller on June 8, 2007 06:00 AM



May 25, 2007 | Comments: (0)

A Comedy of Errors

Martin's picture ~1994On the day before WinHEC, the marketing VP of one of my smaller clients asked me to fix a problem with one of their applications. The CTO was in a plane on his way to WinHEC; the developer who used to own the project had left for another job; and the new developer was in the middle of a major modification to the program that wasn't in a buildable state. "Just take the current sources, drop in this one revised C++ file that the new developer sent me, and build it. The current version won't run at all on Windows 2000, and I've got customers that need it now."

What could be bad? It sounded like a five-minute job. Of course, let's not forget that everything is easy for someone who doesn't have to do it.

I checked the project out of the repository. There were two branches in the tree, marked 1.0 and 1.1, so I checked out the most current sources from 1.1. There were no tagged versions. The CTO was the only one who would know which branch I should use, and he was on a plane. I promptly forgot that I'd guessed at the correct branch.

I dropped in the new file, and tried to build the sources with Visual Studio .NET 2003, which was the IDE the previous developer had used. There was a problem: a source file that had nothing whatsoever to do with the issue being fixed wouldn't compile on my installation of Visual Studio 2003. I tried a bunch of things over the next several hours, and the next day I sent an email off to the marketing VP, the new developer, and the CTO (who was at WinHEC and off email):

I can't build the  project in Visual Studio 2003: it looks like it needs the current Platform SDK, which I don't have installed on the machine with Visual Studio 2003 because I think it will break another project. I can't build it in Visual Studio 2005, either: it has 12 errors and 198 warnings.

It was becoming a case of not being able to drain the swamp because of the alligators. Eventually, I fixed that problem, and sent off another email to the same people:

I have managed to build the project in Visual Studio 2003 by removing the reference to wincred.h. It appears to have been unused.

I tested the new build on a Windows 2000 Virtual PC, and it loaded and ran fine, so I checked in the sources, and sent the new setup file to the marketing VP for broader testing. Running on one Virtual PC image isn't much of a test, and I wanted to make sure that fixing one problem hadn't introduced others.

The following week, the testers came back with a bunch of errors. Some of them were errors that had been fixed by the version that broke compatibility with Windows 2000. I suspected that I hadn't built from the most current sources, and that the former developer hadn't checked in his latest changes. Fortunately, by then the CTO was back from WinHEC and had caught up on his email: he contacted the former developer, who claimed that the repository was up to date.

The two of us got on the phone, and looked through the source history together trying to figure out what was wrong. Finally, the CTO remembered that the previous production version had been built from the 1.0 directory of the repository: the 1.1 directory was intended as an experimental development branch. D'oh.

We're going to restructure the repository with trunk, branches, and tags directories so that this doesn't happen again. Meanwhile, don't let this happen to you.

Posted by Martin Heller on May 25, 2007 06:00 AM



May 23, 2007 | Comments: (0)

64-Bit Compatibility

Windows VistaIt turns out that one of the requirements for software to earn either the Works with Windows Vista Logo or the stricter Certified for Windows Vista Logo is that the software support x64 versions as well as 32-bit versions of Windows Vista. You would think from Microsoft's documentation that avoiding 16-bit components would be enough for most applications to run in the WOW64 emulator, but that doesn't seem to be the case in real life.

I'm responsible for getting an application certified as Vista compatible, and our lead tester has found that just running this 32-bit application on 64-bit Vista causes weird things to happen on the desktop. Double-clicking on desktop icons opens their page properties instead of launching their applications. Some keyboard functions get reassigned. It all goes back to normal after a reboot, fortunately.

Unless someone can set me on the right path, I'm going to have to debug the application on a 64-bit Vista system to diagnose the problem. I wouldn't be at all surprised if I had to rebuild the application as 64-bit to fix all the problems.

Unfortunately, I don't have even one 64-bit CPU in my office or at home: I have six desktop systems, but the newest is a three-year-old system with a 3.2 GHz Pentium 4 with HT, and the oldest is a ten-year-old system with a 450 MHz Pentium III. My oldest daughter has a Turion 64 X2-based laptop, but she lives 40 minutes away, and uses the machine heavily.

I have no real choice but to get a new machine in here, one way or another. Ideally, the machine would come with 64-bit Windows Vista already installed by the manufacturer. Ideally, it would be a laptop powerful enough to run Visual Studio.

There are two issues to think about for 64-bit compatibility in a PC. The big issue is of course whether the CPU supports 64-bit operation. Newer AMD CPUs that do have x64 support typically have "64" in their name. Intel CPUs aren't that clearly marked, but the newest higher-end chips do support 64-bit operation. For example, in the Centrino processor family, CPUs numbered T5000 or greater support 64-bit operation; the T2000-series processors you typically see in low-end laptops do not.

The second issue, and one that's much harder to answer unless the manufacturer has done the testing, is whether all the other equipment on the PC has signed 64-bit Vista drivers. Imagine trying to use Windows on a computer that didn't have a working driver for its pointing device. Even better, imagine trying to use a computer that didn't have a working driver for its disk controller, or its networking controller. It's a nightmare.

I went to my friendly local CompUSA store, and the salesman who helped me didn't know what x64 meant. When I asked again, this time saying "64-bit Vista" instead of "Vista for x64," he knew what I meant, but didn't know if any of the machines they had on display supported it. When I pointed to the laptop right in front of us and asked if it supported 64-bit Vista, he didn't know, and went to the back of the store to find out.

In his absence, I brought up the system information, and discovered that it was already running 64-bit Vista Ultimate. Another somewhat more knowledgeable salesman said that, oh yes, all of the Ultimate systems on display were running 64-bit.

Unfortunately, the system I wanted, an HP dv9225us, on sale for $1,399, was out of stock. Would they call me when they got one in? No, but I could check their stock online. The other notebook systems running Ultimate in the store were over $2,000, out of my price range. No sale.

I'm still looking, but now I'm looking online. If you have suggestions, please let me know.

Posted by Martin Heller on May 23, 2007 06:00 AM



May 18, 2007 | Comments: (0)

Backup Blues

Like every experienced developer I know, I tend to be a little obsessive about backups. OK, more than a little. The trouble is, most backup applications are flawed.

Backups are a form of insurance. You keep hoping you'll never need to use them; when the time comes that you need to restore a file or an image, however, you may be in for a nasty surprise. I have a bunch of horror stories along those lines, but this is not the time to tell them.

Currently, I'm using a combination of manual file backups to multiple locations, source control with Visual SourceSafe and Subversion, and three backup applications run on different schedules: Acronis True Image, EMC Retrospect, and Buffalo Easy Backup. I have backups on CD-RW, in email, on other computers, on external hard drives, on network attached storage, and on remote servers.

I have tried and discarded several other backup applications. For instance, Memeo AutoBackup slowed my computer to a crawl, and wouldn't back up my Outlook mail stores no matter what I did. Other backup applications that I discarded would either keep too many copies of things I didn't care about or too few copies of things I did care about.

I think the best backup system I ever used was Palindrome, but as far as I know Backup Director disappeared after Seagate bought Palindrome, Veritas bought the Seagate software assets, and Symantec bought Veritas. I still have the SCSI DAT drive I used for Palindrome in a closet, and my DAT tapes in a drawer, but they are basically just taking up space at this point.

What prompted me to post about backups is that my EMC Retrospect catalog got corrupted last week. It took a couple of days for me to notice that the nightly backups were failing, and a couple more days before I had the time to trace the cause back to the catalog from the grooming failure that was actually reported. Once I did figure out the problem, it took Retrospect about 6 hours to rebuild the catalog for its 200 GB archive on a Buffalo NAS drive.

Is there a backup application that actually works day in and day out without a lot of fuss?

Posted by Martin Heller on May 18, 2007 06:00 AM



May 07, 2007 | Comments: (0)

Vista Compatibility

My oldest daughter just went through "a circle of Dante's hell" trying to get SPSS 15 to run on Windows Vista. Eventually, she was able to create a login on the SPSS site and download their recent Vista compatibility patch, which did work well, but they sure didn't make it easy to get that far.

I have to be sympathetic to all sides here. Microsoft broke more than the usual number of applications and device drivers with the changes to the Windows Vista system, in the interest of improving security and creating a more robust system. While there's a Microsoft effort that's supposed to help vendors achieve Vista compatibility, they sure haven't made it easy to find them or to go through the process.

The Vista compatibility information on MSDN is only the beginning. There's additional information at www.InnovateOnWindowsVista.com. I recommend following both "find out more" links and downloading all the requirements documents.

Works with Windows Vista logoThere are actually two Vista certification programs: the Work with Windows Vista initiative and the Certified for Windows Vista initiative. What's the difference? The Works with Windows Vista Logo is a free self-testing program, intended to get XP applications over the basic hurdles of running on Vista. Once you do the required testing on 32-bit and 64-bit Vista and make any necessary changes, you can get this logo within a few days of submission.

Certified for Windows Vista logoThe Certified for Windows Vista logo requirements are much more stringent. Your application doesn't just have to work: it and all its components have to be digitally signed, and need to have a Vista manifest. You must install using MSI. There are 32 test cases to pass. And you have to pay a third party to test your application. Supposedly, it takes about a month. Software vendors who need to do this should join the Microsoft Partner Program and register with Windows Quality Online Services.

A word to the wise: do all the testing and make all necessary changes yourself, before submitting your application. Every time you submit an application for testing, you have to pay a sizable fee.

Posted by Martin Heller on May 7, 2007 07:24 AM



April 20, 2007 | Comments: (0)

Detecting Vista Integrity, for Real

On April 6th and 9th I presented some sample C++ code I found on a Microsoft site for detecting whether IE is in protected mode and detecting the integrity of a Windows Vista process. In fact, as I found out when I went to implement it, that code doesn't even compile unless you have the Vista SDK installed.

With a little work, I was able to extract the essential symbols from the version of WinNT.h in the Vista SDK, and make the code compile in a normal environment. I also added some code to detect whether Windows Vista is running, and bail if it is not. I'm not quite sure what would happen if you called GetTokenInformation with a flag of TokenIntegrityLevel on an operating system that doesn't have that value defined, and I'd rather not find out.

//from Vista WinNT.h
typedef struct _TOKEN_MANDATORY_LABEL {
    SID_AND_ATTRIBUTES Label;
} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
#define SECURITY_MANDATORY_UNTRUSTED_RID            (0x00000000L)
#define SECURITY_MANDATORY_LOW_RID                  (0x00001000L)
#define SECURITY_MANDATORY_MEDIUM_RID               (0x00002000L)
#define SECURITY_MANDATORY_HIGH_RID                 (0x00003000L)
#define SECURITY_MANDATORY_SYSTEM_RID               (0x00004000L)
#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID    (0x00005000L)
#define TokenIntegrityLevel (TOKEN_INFORMATION_CLASS)25

// 0 if it fails, 1 if low, 2 if medium, 3 if high
STDMETHODIMP CIE::get_Integrity(BYTE* pVal)
{
    *pVal=0;

    //return if not Windows Vista or later
    OSVERSIONINFO osvi = {0};
    osvi.dwOSVersionInfoSize=sizeof(osvi);
    GetVersionEx (&osvi);
    if(osvi.dwMajorVersion<6)
        return S_OK;

    HANDLE hToken;
    HANDLE hProcess;

    DWORD dwLengthNeeded;
    DWORD dwError = ERROR_SUCCESS;

    PTOKEN_MANDATORY_LABEL pTIL = NULL; //nb: Vista SDK definition
    DWORD dwIntegrityLevel;

    hProcess = GetCurrentProcess();
    if (OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &hToken)) //nb: Win NT+ only, not Win9x
    {
        // Get the Integrity level.
        if (!GetTokenInformation(hToken, TokenIntegrityLevel,  //nb: Win NT+ only, not Win9x
            NULL, 0, &dwLengthNeeded))
        {
            dwError = GetLastError();
            if (dwError == ERROR_INSUFFICIENT_BUFFER)
            {
                pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, 
                    dwLengthNeeded);
                if (pTIL != NULL)
                {
                    if (GetTokenInformation(hToken, TokenIntegrityLevel, 
                        pTIL, dwLengthNeeded, &dwLengthNeeded))
                    {
                        dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, //nb: Win NT+ only, not Win9x
                            (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid)-1));

                        if (dwIntegrityLevel < SECURITY_MANDATORY_MEDIUM_RID) //nb: Vista SDK definition
                        {
                            // Low Integrity
                            *pVal=1;
                        }
                        else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && 
                            dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
                        {
                            // Medium Integrity
                            *pVal=2;
                        }
                        else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
                        {
                            // High Integrity
                            *pVal=3;
                        }
                    }
                    LocalFree(pTIL);
                }
            }
        }
        CloseHandle(hToken);
    }
    return S_OK;
}

Posted by Martin Heller on April 20, 2007 06:00 AM



April 18, 2007 | Comments: (0)

Road bumps for a new Vista User

As I mentioned last Wednesday, my oldest daughter bought a new HP laptop running Vista Business the previous Thursday. We visited her that Sunday, and she was just starting to get the computer set up.

Like many people with home wireless routers, she had all her computers configured to use the network strictly to get to the Internet. "You mean I have a network?" When I enabled file sharing and created an appropriate password-protected share on her old laptop, she was able to start copying her documents and music to the new laptop.

She had already removed most of the "craplets" that HP had preloaded on the machine, and was beginning to get used to the UAC prompts she encountered every time she installed or uninstalled software. I explained my rule of thumb for security prompts: if you started the action that requires privilege elevation, it's OK. If it wasn't you, you'd better find out who or what's trying to get privilege before granting it.

It's like airline security: Did you pack your own bags? Do you know where they've been? Are you carrying packages for people you don't know?

Running programs list Her biggest complaint at that point was that the computer was slow to boot. I ran the machine through PC Pitstop, running IE as Adminstrator, so that I could see what programs were running (see figure): nothing really jumped out at me for elimination. My only suggestion was to hibernate the computer between uses rather than shut it down completely, which got me a funny look.

It turns out that the off switch on the computer is set to initiate hibernation, and my daughter had to work pretty hard to get it to shut down completely. Old habits die hard: she grew up with older systems, and had probably never considered that a laptop would be designed to hibernate.

The next issue came up via email a few days later, but by then her mood was a bit more upbeat:

Hi Dad,

So, I love my new computer.  And, my Word 2007 Pro is awesome as well.

I just have one issue. The computer is obsessed with making back-ups, and every time I try to do a full back up, it fails saying that "this is already in use by another program." I got 6 CDs into the backup when it failed.  Grrrr. I've tried shutting down all the running programs, but still it fails. Any ideas?

After a telephone conversation, I think I understand the problem, which seems to be two-fold. First, HP seems to have installed a control panel that nags when Windows Vista Backup and Restore has not made a successful backup. Second, the backup process can't get at all the files on the PC.

Can that be right? Isn't the Vista backup function supposed to use a shadow copy? I've never tried that function myself: I'd be interested to hear from someone who has encountered the same problem and overcome it.

I've reassured my daughter that she's in good shape for backups even without the failed set, and that the failed set is probably still useful. Her absolute worst case after a disaster is that she'll have to restore her computer to as-shipped condition from DVD and/or the image on her D: drive, scrub the "craplets," reinstall Office 2007, copy her old files over the network, and copy her recent files from her CD-R and/or flash drive backups.

Meanwhile, she's going to find out if HP tech support is helpful.

Posted by Martin Heller on April 18, 2007 06:00 AM



April 16, 2007 | Comments: (0)

Windows PowerShell: An Introduction

One of the hazards that Microsoft groups face when they launch their products is competition for attention from other Microsoft groups with bigger marketing budgets. Think about the poor Windows PowerShell team, who basically launched at about the same time as Windows Vista and Office 2007. It was no contest.

If you haven't already heard about Windows PowerShell by that name, you may have heard of it by its rather pretentious code name, Monad, or its temporary name Microsoft Shell, abbreviated MSH. I'm sure that Jeffrey Snover and the PowerShell team wanted "Monad" to convey the unified interface they were building.

Then why do I think Monad was a pretentious choice? It's the other meanings of the term. In philosophy, the term Monad, meaning the "ultimate, indivisible unit" goes back to Pythagoras, and was used by Plato, Aristotle, the neo-Platonists, Liebniz, and the Theosophists to describe some rather lofty concepts, often verging on the divine. In mathematics, a monad is a type of functor in category theory. In functional programming languages, for example Haskell, a monad is a rather complicated implementation of sequential functors.

So, what is Windows PowerShell? It's a command line shell, a programming language, and a unified interface; it's not your father's command line shell. From the Windows PowerShell Getting Started Guide:

Windows PowerShell is a new Windows command-line shell designed especially for system administrators. The shell includes an interactive prompt and a scripting environment that can be used independently or in combination.

Unlike most shells, which accept and return text, Windows PowerShell is built on top of the .NET common language runtime (CLR) and the .NET Framework, and accepts and returns .NET objects. This fundamental change in the environment brings entirely new tools and methods to the management and configuration of Windows.

Windows PowerShell introduces the concept of a cmdlet (pronounced "command-let"), a simple, single-function command-line tool built into the shell. You can use each cmdlet separately, but their power is realized when you use these simple tools in combination to perform complex tasks. Windows PowerShell includes more than one hundred basic core cmdlets, and you can write your own cmdlets and share them with other users.

Like many shells, Windows PowerShell gives you access to the file system on the computer. In addition, Windows PowerShell providers enable you to access other data stores, such as the registry and the digital signature certificate stores, as easily as you access the file system.

I have found PowerShell to be extremely useful for exploring the operating system. One of the data stores it supports is WMI, Windows Management Instrumentation, which is a wrapper for many system structures, so you can use PowerShell to dig into the guts of things like Win32 processes, add-remove program lists, and system hardware. It also supports COM, so you can use it to script all sorts of applications and controls that expose COM interfaces.

I was under the mistaken impression that PowerShell would ship with Windows Vista. In fact, you need to download and install PowerShell separately; make sure that you get the right version for your operating system (Vista, XP, Windows Server 2003, or Longhorn Server) and locale, and that you have .NET Framework 2.0 installed before you install PowerShell.

Windows PowerShell in Action The documentation that comes with the Windows PowerShell download will get you started. However, I have found Windows PowerShell in Action, by Bruce Payette (Manning, 2007, 576 pp, ISBN 1-932394-90-7, $44.99) to be an excellent supplement. Payette is a co-designer of the PowerShell language and the principal author of the language implementation. His book not only tells you all the secrets of PowerShell, it tells you what the team was thinking when they designed and implemented the language.

Posted by Martin Heller on April 16, 2007 06:00 AM



April 11, 2007 | Comments: (0)

The Vista Backups That You Can't Have

Source: PC Pitstop Tech Notes

Dave Methvin points out that the Previous Versions feature of Windows Vista has been left out of the Home Basic and Home Premium editions. That wouldn't be so bad, except that the backups are still being made: you just can't get at them.

Need that backup? You'll have to upgrade. "Windows Vista Document Ransom Edition," anyone?

Posted by Martin Heller on April 11, 2007 08:05 AM



April 11, 2007 | Comments: (0)

Shopping for a Laptop: Best Buy 0, CompUSA 1

I took my oldest daughter shopping for a new laptop last Thursday, as her old Compaq laptop is on its last legs. She's a married graduate student who often commutes to school and work on the T (Boston's subway system), so she wanted something that would be light and fit into her satchel. She uses her computers for email, Web browsing, and storing her music library, as well as to write papers, prepare presentations, design Web surveys, and to analyze big data sets with SPSS. Clearly, she needed plenty of RAM and disk space. She doesn't care much about using her laptop for gaming or entertainment: my son-in-law has the games installed on his laptop, and they have a DVD player and a TiVo box connected to their TV. She had a budget of $1,000.

We decided to start at Best Buy, since they've been advertising heavily in the local papers. I picked out half a dozen interesting models for her, after eliminating the junky units that could barely run Windows Vista Home Basic and the units that were out of her price range, and she narrowed them down to two or three candidates. I felt that she should test the models out herself before she bought one, but the laptops were all locked down and running demo software, so we went looking for sales help.

The sales help at Best Buy couldn't be bothered to talk to us, so after a while we walked out. CompUSA was just across the parking lot, so we went there, even though there has recently been speculation in the press that they're having trouble competing with the big box stores.

We found a much larger selection of laptops at CompUSA than we'd seen at Best Buy. We also found plenty of sales help in the computer department, who waited until we were ready to talk to them, and then helped us without pushing too hard.

There was also a Sony salesman in the store, who explained the Vaio product line and showed us how Sony laptops are better constructed than HP, Toshiba, and Acer laptops. He was fairly convincing. However, the model he recommended to my daughter not only was out of her price range, it wasn't yet in stock at that CompUSA store, and she wanted to go home with a new laptop rather than order one and wait. I was amused that he broke the first rule of technology sales: "Never sell tomorrow's product."

My daughter wasn't interested in looking at a Mac, even after I explained about Boot Camp and Parallels. She wasn't especially impressed with the Acer or Toshiba laptops, and started leaning towards HP when I explained that HP and Compaq had merged.

HP Pavilion dv2221Ultimately, she went home with a 5.4 pound laptop made by HP that has a reasonably high-end AMD dual-core mobile processor, 2 GB of RAM, 160 GB of disk space, and a 14.1" 1280x800 screen, running Windows Vista Business. She also picked up a 4 GB thumb drive, which I'm hoping will be fast enough to use for ReadyBoost; if not, she and her husband will still be able to use it to carry big files back and forth to work. After rebates, she pretty much hit her budget. I'm pretty sure it'll meet her needs for at least the next three years.

I really hope that CompUSA can stay afloat. I do a lot of my computer buying online or at small local white-box shops, but for someone like my daughter CompUSA offers just about the right selection and a palatable sales experience.

Posted by Martin Heller on April 11, 2007 06:00 AM



April 09, 2007 | Comments: (0)

Detecting IE7 Protected Mode, Take 2

On Friday, I posted one method that an ActiveX control or IE toolbar can use to determine whether IE 7 is running in Protected Mode. After thinking about this some more, I realized that there are many other ways to accomplish the same goal.

Much of the primary information on IE7 Protected Mode can be found in an MSDN article, Understanding and Working in Protected Mode Internet Explorer. That article mentions the IEIsProtectedModeProcess function I talked about on Friday, but it also explains some of the other characteristics of Protected Mode and Vista UAC mode. For example, Protected Mode modifies IE's environment, so that the Windows GetTempPath() API will return the value of %Temp%\Low rather than the value of %Temp% when Protected Mode is active.

Later in the article, the authors give a code sample, ShowProcessIntegrityLevel(), shown below, that looks at the current process token and determines its integrity level. The integrity level actually tells us more than just whether Protected Mode is enabled.

If we are in Protected Mode, the process integrity will be Low; if we are running as a normal user or running in UAC mode, the process integrity will be Medium; and if we are running as Administrator, the process integrity will be High. An ActiveX control that wants to expose the integrity level to JavaScript through a COM interface could run a variation on this code and return a short integer that is 0 for Low Integrity (Protected Mode), 1 for Medium Integrity (Normal User/UAC mode), and 2 for High Integrity (Administrator).

I really wish this was already built into IE 7, but it'll do.

void ShowProcessIntegrityLevel()
{
  HANDLE hToken;
  HANDLE hProcess;

  DWORD dwLengthNeeded;
  DWORD dwError = ERROR_SUCCESS;

  PTOKEN_MANDATORY_LABEL pTIL = NULL;
  LPWSTR pStringSid;
  DWORD dwIntegrityLevel;
 
  hProcess = GetCurrentProcess();
  if (OpenProcessToken(hProcess, TOKEN_QUERY | 
        TOKEN_QUERY_SOURCE, &hToken)) 
  {
    // Get the Integrity level.
    if (!GetTokenInformation(hToken, TokenIntegrityLevel, 
           NULL, 0, &dwLengthNeeded))
    {
      dwError = GetLastError();
      if (dwError == ERROR_INSUFFICIENT_BUFFER)
      {
        pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, 
                  dwLengthNeeded);
        if (pTIL != NULL)
        {
          if (GetTokenInformation(hToken, TokenIntegrityLevel, 
                 pTIL, dwLengthNeeded, &dwLengthNeeded))
          {
            dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, 
               (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid)-1));
 
            if (dwIntegrityLevel < SECURITY_MANDATORY_MEDIUM_RID)
            {
              // Low Integrity
              wprintf(L"Low Process");
            }
            else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && 
                     dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
            {
              // Medium Integrity
              wprintf(L"Medium Process");
            }
            else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
            {
              // High Integrity
              wprintf(L"High Integrity Process");
            }
          }
          LocalFree(pTIL);
        }
      }
    }
    CloseHandle(hToken);
  }
}

Posted by Martin Heller on April 9, 2007 06:00 AM



April 06, 2007 | Comments: (0)

Detecting IE7 Protected Mode

I have been wondering if there's a way that a Web page can tell if it's running in IE7 Protected Mode on Windows Vista. It turns out that yes, there is, but it's not as simple as I'd like.

My hope was that there would be flags that a page could check from JavaScript: ideally, a flag that says either

  • "I'm in Protected Mode"
  • "I've got normal privilege", or
  • "I'm running as Administrator".

I didn't find anything like that, even though IE 7 displays the Protected Mode status to the user. What I did find is an IE API, the IEIsProtectedModeProcess Function, which can tell a caller whether or not IE is a Protected Mode process by setting a BOOL parameter TRUE or FALSE.

It's in ieframe.dll, but only for IE 7 or later. And it is only supported in Microsoft Windows Vista or later. If you call it from earlier versions of Microsoft Windows, this function returns E_NOTIMPL as its HRESULT.

So, if I have this right, I could call this function from an ActiveX control or an IE toolbar, after first dynamically loading it from ieframe.dll. If I called it from an ActiveX control, then the ActiveX control could in turn expose a COM property to JavaScript. I know how to do that.

This seems like scratching your left ear with your right hand, doesn't it? But it should work.

Now I have to figure out how to safely tell if the IE process is running as Administrator. Somehow, I don't think trying to reformat the system drive would be an ideal test.

Posted by Martin Heller on April 6, 2007 06:00 AM



March 26, 2007 | Comments: (0)

A Sad Realization

Dave Methvin, Rob Cheng and I founded PC Pitstop in 1999. From the beginning, it was a classic Windows DNA site: we wove together an ActiveX control, quite a bit of client-side JavaScript, ASP server code also written in JavaScript, and a SQL Server database. The idea was to quickly and automatically diagnose most common PC ailments.

If I remember correctly, we started out supporting Windows 95 and Windows 98, then added Windows NT and Windows 2000. Over the years we kept updating the site to do more and to support new systems as they were released. I stopped working on it full time after the dot-com bust and terrorist attacks of 2001, which together ruined the market for banner advertising. I continued to consult for the site on and off, and became more active again last summer.

Because PC Pitstop tests tens of thousands of computers every month, we have a pretty good idea about industry trends. We try to anticipate them a little when we think they'll need new code for proper support, but we also find out rather quickly when there are breaking changes from new hardware or new systems.

Last week I finally bit the bullet and started trying to fix the tests that didn't work properly on Windows Vista. There were 8 problems that we were able to identify when people came to the site with Internet Explorer 7 in the default Protected Mode on Windows Vista:

  1. The CPU Load was not tested
  2. Running Programs only listed one: IE
  3. All outgoing pings were lost
  4. Disk fragmentation was not tested on C:
  5. Disk speed was not tested on C:
  6. No CD or DVD drives were detected
  7. Could not obtain monitor information
  8. Got incorrect results for the size of the junk files

I tracked down the C++ code in the ActiveX control that does each of these tests, and realized that some of the failing tests were trying to do things that require Administrator privilege on Windows Vista, but that others were doing things that only require normal privilege. IE didn't even have normal privilege, however, because it was running in Protected Mode, which flags itself as a low integrity process.

Windows Vista elevation promptThe whole point of Protected Mode is that sites can't use it to install malware without your permission: if they try, you'll get an elevation prompt that you'll find it hard to ignore. The whole point of PC Pitstop is that we're the good guys, trying to detect suboptimal system settings, low performance, and malware that is already on your computer.

I did three experiments. I verified that all 8 issues happen in Protected Mode. I determined that three problems go away, two completely and one partially, with IE's Protected Mode off. And finally I determined that all tests run correctly when IE is run with Administrator privilege.

I looked at alternative ways to execute the tests that might work with Protected Mode enabled, because I really wanted the site to work that way. I found a way to detect CD and DVD drives using WMI, but the information returned isn't as complete as we get by using the low-level SCSI and ASPI interfaces, so I think that's just a back-up plan. I found a simple way to fix the disk speed problem that I think will be fine on most systems, which involves putting the test file into the temporary directory if the temp directory is on the drive being tested.

There were so many issues that I couldn't fix, however, that I came to a sad realization: PC Pitstop will only run properly on Windows Vista if the browser has Administrative privilege. Like the janitor in your building, we can't clean up after you unless we have the keys to the office.

Posted by Martin Heller on March 26, 2007 06:00 AM



March 23, 2007 | Comments: (0)