Saturday, 28 August 2004

Run Elevated - part 1

[Let's see if I finish this series...]

Last week I wrote about running with reduced privileges. In that post I talked about using the LsaLogonUser API to create a new token, adding additional SIDs, and writing a service that would do this. In this post, I'm going to talk about some design aspects.

Let's summarize the requirements:

  • We want an API for creating a process with additional SIDs;
  • The user should, if permitted, be able to perform this operation by supplying a single password at most;
  • Administrators will be able to allow use of this service in two ways:
    • Define somehow a set of users who can always use this service - perhaps different sets for upgrading to Administrators access and for upgrading to Power Users;
    • Allow anyone by also supplying credentials to override the above - typically this will be any member of the Administrators group, but we should make it configurable;
  • This API will use some form of remote call into a service due to the privilege requirements of LsaLogonUser;
  • The created token must have the ability to interact with the caller's login session;
  • The created process must appear on the appropriate user's desktop (incl. Terminal Services sessions).

Let's look at how we do this. For authorization, we should leverage the existing security APIs as far as possible - this allows us to use the standard security dialogs which administrators are already familiar with. Therefore, we'll use the AccessCheck API to check ACLs that we store somewhere in order to check whether the user's authorised, or whether the override credentials they present (option 2 above) are authorised to override.

For consistency, even though we'll have the user's alleged password, we'll have the service impersonate its client to do access checks. We'll therefore be using their existing token, not any changes that have been made to the token since they logged on.

The right place to store the ACLs is probably somewhere in the registry; I'm going to store them in the service's Parameters key. Let's choose a name for the service: I'll call it RunElSvc. This makes our Parameters key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RunElService\Parameters. We'll put an ACL on this key itself so Administrators and LocalSystem have Full Control, and no one else has any permissions. Note that this is exactly what the SCM does - the Security key under the service contains a security descriptor (in binary format) and the key itself has an ACL as above.

I'm not sure whether it will be possible for a domain administrator to control this through Group Policy - something to look into later!

We'll also need to define the security mask bits for the ACL - the specific bits and the mapping of the generic bits. Ironically here the standard bits (DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER and SYNCHRONIZE) don't mean a lot for this 'object'. So I think we just define bit 0 to mean 'can' if set and 'can't' if not, and map GENERIC_EXECUTE and GENERIC_ALL to set bit 0 if they're set. Actually, we could use a single security descriptor with multiple bits (one each for 'can raise to Administrators', 'can raise to PU', 'can override other bits') rather than multiple SDs.

We want the actual API to seem familiar, so starting from CreateProcessWithLogonW is probably a good idea.

BOOL CreatePrivilegedProcessW(
  LPCWSTR lpPassword,
  LPCWSTR lpOverrideUsername,
  LPCWSTR lpOverrideDomain,
  LPCWSTR lpOverridePassword,
  LPCWSTR lpApplicationName,
  LPWSTR lpCommandLine,
  DWORD dwCreationFlags,
  LPVOID lpEnvironment,
  LPCWSTR lpCurrentDirectory,
  LPSTARTUPINFOW lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInfo
);

Internally the service will call CreateProcessAsUser once it's got a token. We'll have to do a bit of copying to ensure the right environment, etc., is used rather than the service's environment.

This wouldn't be complete if we didn't think about what possible threats there will be. The major one is probably remote exploitation, which we'll mitigate by using the ncalrpc protocol. We do have to watch for the possibility that some other protocol is used, if our service ends up sharing a process, since RPC allows the union of all protocols registered by all endpoints in the process. My initial plan is for the service to run in its own process, but eventually it might run in a svchost (thanks for the comment, Larry!)

I'll have to admit I don't have experience of threat modelling.

Friday, 27 August 2004

Aspects of CS not taught at Uni

Eric Sink has just started a series of articles on Source Control: an introduction for SCM novices. In his introduction, he writes:

"My goal for this series of articles is to help people learn how to do source control.  I work for SourceGear, a developer tools ISV.  We sell an SCM tool called Vault.  Through the experience of selling and supporting this product, I have learned something rather surprising: Nobody is teaching people how to do source control.

"Our universities don't teach people how to do source control, or at least mine didn't.  We graduate with Computer Science degrees.  We know more than we'll ever need to know about discrete math, artificial intelligence and the design of virtual memory systems.  But many of us enter the workforce with no knowledge of how to use any of the basic tools of software development, including bug-tracking, unit testing, code coverage, source control, or even IDEs."

Coincidentally, I also saw Jim Gries' Debugging Glossary post when reading through the blogs.msdn.com feed (actually I read this through the browser rather than either of my aggregators), in which he says:

"[D]uring a recent UI meeting here at work, one of our PM's (Habib Heydarian) mentioned that while at Tech Ed, he was shocked at just how many developers don't have an understanding of the terms used while debugging, let alone how to use a debugger effectively."

In my final year at Aston, the CS department were looking for ways to improve the performance of the Combined Honours students taking the Introduction to Systematic Programming course (no longer on the website; since I wrote my last post on the subject, the site has been updated, and now the initial programming course [PDF] is taught in Java). Formerly, lab sessions were run by either the lecturers or by post-graduate students, many of whom were unfamiliar in Ada, the language taught. That year, the department decided to ask final-year undergraduate students who had scored highly in ISP to assist with lab sessions. I was one of those people. The hours weren't onerous (two or three one-hour sessions per week) and the pay reasonable at £8 per hour, which helped a little.

By this point I'd bought and read, on Ian's recommendation, Steve Maguire's classic Writing Solid Code, in which he recommends single-stepping through every new piece of code you write using an online interactive debugger. Doing this as a matter of course opened my eyes - desk-checking a program is all very well, but you run into the problem where you think you know what the code does. You miss the bugs because you're not looking for them. There's no substitute for actually running the program and seeing what it does, and if you single-step, you find out exactly what code is hit and what your variable values were.

When we were asked for suggestions for the course, I suggested including a session on using the debugger. We were limited of course by the available tool suite: using GNAT as the compiler and hence GDB as the debugger (actually the gdbtk GUI front-end). However, any debugger is still better than trying to debug through print statements. The edit/compile/run cycle to add a new statement to print some variable you missed last time distracts from the sessions.

This suggestion was radical because many lecturers were of the opinion that online interactive debuggers are useless; after all, you've formally proved your specification, used a CASE tool to generate your code and desk-checked any hand-written code - how can there possibly be bugs after that?

Over here in the real world we know that formal proof works only for really small systems and takes a really long time and therefore costs a lot. We also know that a CASE tool can only really generate programs that the CASE tool's designer intended it to build - novelty is heavily restricted with these tools.

CS course designers: do your students a favour by learning how to use a debugger, then teach your students. If you need a resource, or a course textbook, try John Robbins' Debugging Applications for Microsoft .NET and Microsoft Windows. Yes, it's Windows-centric. Yes, it's far more than just an introduction to debugging - it even has some material on optimising your working set toward the end. But the first three chapters (part 1 - The Gestalt Of Debugging) are a must-read for all developers, on any platform, with any language, using any debugger.

Thursday, 26 August 2004

A useful resource for service information

I've found TheElderGeek.com's guide to services useful.

My definition of svchost.exe is that it's a process which supports plug-in service DLLs. You see multiple svchost processes to mitigate the effects if one service running in a host process crashes, and so that different services can run using different credentials (and hence privileges).

Currently I have six svchosts running, three of which run as LocalSystem, two as Network Service and one as Local Service. One of the LocalSystem hosts is running Terminal Services and DCOM Launcher; another is running HTTP SSL for the HTTP.SYS driver (new in Server 2003 and XP SP2); the third runs most other services. One of the Network Service hosts runs RPCSS, the Remote Procedure Call subsystem while the other runs DNS Client. Finally the Local Service host runs the TCP NetBIOS Helper, the Remote Registry service, the Universal Plug-and-Play listener, and the WebDAV client.

'Scuse me, just going to turn off Remote Registry, I don't need that.

Do Scheduled Tasks need the Task Scheduler service?

After the last entry and discovering that the at trick still works, I asked myself this question: do tasks created through Control Panel > Scheduled Tasks need the Task Scheduler service?

Sadly, they do.

However, I don't currently have any scheduled tasks, so I've disabled the service. If you want to do the same, either use the Services MMC snap-in, or you can use sc...

sc config schedule start= disabled

Edit (2004-09-02): OK, I've re-enabled it. A number of readers (I have readers?!?) mentioned that a number of system optimisation features also run using the Schedule service, something I confirmed with Filemon. Obviously the ability to create a job that starts as LocalSystem is a bit disconcerting, but it seems that this can only be done locally by an authenticated administrator. I'd prefer to have a separate optimisation service, but you can't have everything.

Wednesday, 25 August 2004

I knew something was bugging me...

The Register: Windows XP SP2 features security crater - report

Basically, a malicious program can add a new WMI provider to the root\SecurityCenter namespace - an instance of AntiVirusProduct or FirewallProduct. Windows XP SP2's Security Center may then report that an anti-virus product or firewall product is installed and working correctly, even when one is not.

The mitigation, though, is that WMI is indeed read-write - for Administrators. PC Magazine's original article (attributed to eWeak by The Register's pet hack) makes this clear.

I was thinking along the lines of changing the ACL on this namespace so that only LocalSystem is able to create new providers, but failed since the ACLs are inherited - but you can't clear the inheritance in the MMC WMI Control snap-in (it's in the Computer Management console). However, this would only add a small hindrance since by default on XP SP2, at.exe still exists and still allows you to do

at 23:39 /interactive cmd

to get a command interpreter running as LocalSystem:

C:\>dumptoken
Process primary token
This is a unrestricted token
Token type: primary
Token ID: 0x25066b9
Authentication ID: 0x3e7
Token's owner: BUILTIN\Administrators (alias)
Token's source: *SYSTEM* (0x0)
Token's user: NT AUTHORITY\SYSTEM (user)
Token's primary group: NT AUTHORITY\SYSTEM (user)
[...]

(dumptoken from w00w00.org)

This only works if you're an administrator, of course.

And if you think about it, most WMI providers get registered with WMI by an installer, running as an administrator. I'm not too sure about the default ACL for the root namespace which allows Everyone to modify provider information, though.

Anyway, what's the point of misreporting the firewall or antivirus status? A program running using a token containing the Administrators group SID (or, loosely, running as an administrator) can punch a hole in the firewall using the firewall administration API - how many users will regularly check the list of exceptions? It can normally install a device driver. It could install a file-system filter driver below the anti-virus filter driver in the disk driver stack and remove any trace of its own code (you'd probably need to add another one above to add the code back in so it could run).

The true mitigation, as for most things, is to run as a regular user. Don't run as a member of the Administrators group.

Friday, 20 August 2004

Heap in NT can use a lot of virtual addresses

Raymond Chen has recently been writing about the /3GB switch, virtual memory and physical memory. If you don't understand what virtual memory is, go there now.

Back? Good. I want to talk about a situation where you might run out of virtual address space a long time before you run out of RAM. Exchange's documentation recommends that if you have more than 1GB of memory you should enable the /3GB switch. As Raymond notes, basically the STORE.EXE process, due to inefficiencies, uses more virtual address space than actual RAM.

In a comment on Carmen Crincoli's blog, Larry Osterman mentioned that the NT heap manager expands the virtual address space for a heap in powers of two. Note that this doesn't mean the physical memory used goes up like that - Windows will only allocate physical memory to a process on demand and only up to its maximum working set size, unless memory is more abundant than that. However, you can get into a situation where your heap's virtual address space resembles a Swiss cheese - there's plenty of free memory, but it's all in small free blocks. To allocate a large block, Windows has to expand the heap's address space, which it does by allocating a new chunk of address space twice the current size of the heap. It must be possible for this to be multiple chunks - this algorithm would start running into problems at around 512MB or so of virtual addresses if it allocated a single contiguous block...

What's the initial size of the heap? It's marked in the executable's header - the default generated by the MS linker is 1MB.

Note that Windows supports multiple heaps. The recommended practice is actually to have one heap for each distinct type (or at least size) of object; I think I've written about this before. Unfortunately many APIs don't give you a choice where something is allocated - they just dump it on the default heap.

[Edit: I knew something was bothering me about the original title - I confused VM with virtual addresses - as we know, they're not the same thing...]

A horde of whiny bastards

...have taken over the Channel 9 forums. You can tell that few of them have ever run a server OS for anything real, and have swallowed the Unix pill whole (although I suspect some have taken it as a suppository - there's certainly something stuck up their arse...) Few of the developers seem to have actually shipped a product and have any understanding of what it actually takes to maintain software and provide compatibility between versions - nor that users need compatibility between versions, or that MS might have, you know, done some research.

It's a shame because C9 was getting something of a conversation going between Microsoft users (as opposed to abusers) and the product teams. I'm still going to watch the videos, though.

In other news, I see that the horde now seem to have got bored with trying to bait the IE blog.

Sunday, 15 August 2004

Running with reduced privileges

I know I have to get to it sometime. In the current climate, anything you can do to mitigate the effects of a successful attack is worthwhile - and there's no sign of things letting up.

So I've taken my normal user account out of the Administrators group - I'm just a user again.

Now, clearly, as a power user, a developer, an occasional gamer and the machine owner, I still need to be able to launch programs as an Administrator. The runas tool is helpful here! However, there are times when you want a program to run with elevated privileges, but in your own context.

Aaron Margosis, a Microsoft consultant, has come up with a couple of useful tools. The first is a batch file which automates the process of adding your account to the Administrators group, creating a new shell, then removing the account again. The second is a toolbar which shows how privileged you are, in IE and Explorer.

If you're familiar with how Windows authorization works, feel free to skip this paragraph. Windows authorizes users against resources by comparing access control lists against the SIDs (Security IDs - internal representations of user accounts or security groups) in your token. The token can either be a primary token or an impersonation token. You typically get a primary token by logging on; servers can temporarily assume another identity by impersonating their client. Also included in your token are your privileges - actions you're allowed to take which may override the ACLs or allow other actions (e.g. shutting down the system). Privileges are orthogonal to access rights. The token is a cached copy of what you were allowed when you logged on - it contains the SIDs for all groups you were a member of and the privileges assigned to all SIDs.

Adding yourself to the Administrators group therefore has no effect until you next log on. Aaron's batch file gets round this by using runas to create a new logon session and hence a new token. You cannot replace the primary token for a running process - you can only create a process with a different token by calling CreateProcessAsUser.

The downsides to Aaron's batch file are two: one, that it requires you to type both the Administrator and your own password; two, that there's a window where your account is explicitly in the Administrators group (between typing the Administrator's password and typing your own).

This second one is possibly a risk. If your system crashes at this point, you're likely to still be in the Administrators group when you restart. If a service running with your credentials starts in this window, it will have privileges you didn't expect. A network logon with these credentials will also gain administrative privileges.

Can we do better? I think so. The LsaLogonUser function takes a TOKEN_GROUPS parameter which allows us to arbitrarily add groups to the new token, assuming successful authentication. The spike I put together over the last two days suggests that any privileges awarded to the (enabled) SIDs added to the token are also added to the token. This only requires us to supply the user's password - we don't need the administrator's. We can't totally automate it because Windows doesn't store the authenticated password in plain text - unless we circumvent things further, e.g. by adding a 'network provider' so that NPLogonNotify gets called with the plain-text password, and storing this somewhere. This would of course be a very bad idea, enabling the possibility that the plain-text password could be disclosed.

Lest you think this is a horrible hole in the NT security model, I'll point out that to do this, you must have a trusted connection to the Local Security Authority. To get one of these, you must call LsaRegisterLogonProcess, which requires the 'Act as part of the operating system' (SE_TCB_NAME) privilege (see what I mean about privileges being different from access rights?). In essence, that means running under the LocalSystem security context.

So where from here? Basically, I need to write a service which will listen for local requests (probably through RPC) and use the supplied credentials to create a token then create the appropriate process. This is going to be an adventure because before yesterday I'd never written a service! I'll be writing it in C++ because quite frankly there'd be no benefit in using C# due to the amount of P/Invoke marshalling required. I'll have to learn how to write RPC servers and clients, work out which logon provider to call (obviously the same one that the user used!) and how to write events to the event log. I'll also need to design access control so administrators can control who gets to do this.

Saturday, 14 August 2004

SP2 Torrent site gets DMCA cease-and-desist

I see from comments on Robert Scoble's blog that Downhill Battle have been asked to remove the SP2 torrent links. The reason is apparently that they don't want things to be downloaded from other sites. I suppose it prevents MS monitoring how many people have actually downloaded it - but how can they guess how many times a particular download, particularly of the network install, has been used?

BitTorrent has mechanisms to check that the download was received correctly: the Torrent file includes precomputed hashes for each block so that the client can determine whether it has received that block successfully. These hashes use the SHA1 algorithm. The whole download is also hashed - a download can be made up of multiple files. This hash is used to locate the peers.

In the particular case of SP2, the file is also digitally signed by Microsoft. This ensures that it really is the genuine release, or at least that the file hasn't been modified since it was signed and it was signed by an organisation claiming to be Microsoft. It appears to have had the right effects, so I'm sticking with it.

Interestingly, though, Microsoft haven't tried to take down the tracker. Clearly there's a lack of understanding in how BitTorrent really works.

I'm trying to decide whether to host the .torrent file myself. I'm still hosting the torrent itself - upload rate currently 24KB/s.

Thursday, 12 August 2004

XP SP2 limits Raw Sockets

Ian Griffiths: Raw Sockets Gone in XP SP 2.

Michael Howard: A little more info on raw sockets and Windows XP SP2.

I think what Michael's basically saying is that data sent through a raw socket is parsed by the stack, any packets with protocol 6 (TCP) are discarded, and any packets with protocol 17 (UDP) must have an outgoing IP address matching one of the interfaces or it's dropped. This prevents programs using raw sockets to disguise what they're up to using the standard Internet protocols - hopefully preventing zombies from disguising the origins of their packets.

If you really need to do this, you can still use a device driver which avoids the Microsoft TCP/IP stack entirely, such as WinPcap. Dana Epp's already produced a patch for nmap which causes it to revert to using WinPcap (it's a two-line patch!)

This probably means, of course, that new zombie programs will just come with WinPcap, because I don't think SP2 limits driver loading (aside from it being limited to users/groups with the Load or unload device drivers privilege, granted to the Administrators group by default).

Say 'No' to IL in silicon

Ian Griffiths wrote an interesting article. However, I have to take issue with a bit of it:

"A clear example of where general purpose CPUs have become fast enough to render special purpose chips obsolete is in mobile phones. (Or 'cellphones', as I believe they're usually called in the USA.) A few years ago, all digital mobile phones had two processors in them: a general purpose one to handle the signalling protocol and user interface, and a specialised digital signal processor (DSP). [...] Having these two processors was a problem. The extra processor made phones bigger, shortened battery life, and decreased reliability as a result of the increased component count. But it was necessary because only a specialised DSP was fast enough to perform the necessary processing, while a general purpose CPU was required to handle the signalling protocol and user interface. But a few years ago, the performance of low-power embedded CPUs (and in particular the ARM CPU) got to the point where one general purpose CPU could do all of the work."

My understanding is that the DSP is in fact still used - but it's no longer a separate chip. Instead it's been absorbed as an 'IP core' into the same chip which houses the display controller, keyboard controller, serial interface controllers, memory controller and the CPU core. It's still loosely labelled the 'CPU' but to reflect the changed role it's now sometimes called an 'application processor'.

See, the way chips are designed has changed quite a bit. When I was at University, and still studying Electronics, we were taught how to use a language known as VHDL. Originally this language was used for simulating circuits before producing them, but a changeover was in progress for instead synthesizing circuits: getting a compiler to generate code for programming a programmable logic chip, and eventually actual masks for producing silicon.

This has lead to a market in, essentially, source code for circuits: the ability to buy in IP cores for a dedicated chip. By combining IP cores a single chip to run a device can be produced - if you're producing millions of them, you can save a heck of a lot. A major reason ARM have been so successful is that they've licensed their processor cores, in addition to manufacturing their own CPUs - basically the core connected directly to the pins. Almost every ARM-compatible application processor out there - Texas Instruments, Samsung, whoever - is basically a licensed ARM core - an actual ARM design - decorated with whatever other cores the ODM (Original Design Manufacturer) decided to throw in.

Take my new Dell Axim X30. It features an Intel PXA270 processor. This single chip has the latest XScale core (Intel's design implementing the ARM5 instruction set - Intel actually design their own cores, rather than using ARM's design), a memory controller capable of controlling SDRAM, Static RAM and Flash ROM, an LCD controller with 256KB of on-board RAM, a USB host controller, a camera capture interface, Smart Digital media I/O controller, a SIM card interface, keypad controller, 3 standard UARTs (serial devices), audio controller, CompactFlash controller, and USB client implementation. Some of these parts are probably licensed cores (although Intel do have the resources to design their own).

[Edit] I need to review these things before posting them. I forgot to add this bit:

Recent ARM cores do have Java bytecode interpreters apparently in hardware - ARM call this Jazelle. However, it must be remembered that Java was originally designed to be interpreted. CIL was not - it was designed to be JIT compiled. Eventually even Sun had to realise that JIT-compiling Java produced far better-performing programs than interpretation ever could.

Tuesday, 10 August 2004

Cache management

I'm sticking it out with IE after what I discovered about the current state of FireFox security. Unfortunately, in SP2, it seems as though the cache bugs are still there.

So I've started using CacheSentry, a free program for monitoring and cleaning up your cache. And I think I'll be sticking with the free version: the (proposed) UI for CacheSentry Pro is close on the verge of a submission to The Daily WTF or This Is Broken.

Slight disadvantages are that CacheSentry's limit for cache size is 700MB, and IE doesn't behave quite right when it hits CacheSentry's limit - I started getting stylesheet-missing problems again. However, dropping the limit to 500MB then expanding it again seems to have worked for the moment.

The author has documented some bugs in IE's cache mechanism. I say IE's - I should say WinInet's, as that's the component that does the caching.

How does TransmitFile actually work?

Last week, Larry Osterman blogged a little about TransmitFile. I was sure I'd read somewhere that it was implemented entirely in kernel mode, but I couldn't find that assertion.

So I pulled out DUMPBIN. This is what I found, after writing a little test server I call Really Simple File Transfer Protocol - it listens on a socket, then when a client connects it dumps a file down the connection; like I said, Really Simple. It's so simple it doesn't allow concurrent connections.

The TransmitFile function in MSWSOCK.DLL is a simple wrapper around a call to WSAIoctl using the SIO_GET_EXTENSION_FUNCTION_POINTER control code, then calling the result (if WSAIoctl does not return SOCKET_ERROR). For a standard TCP socket using Microsoft's stack, the WSAIoctl call returns the address of mswsock!MSAFD_TransmitFile (an internal function, you won't see it in the export table). In turn, this function does a bit of checking then calls ntdll!NtDeviceIoControlFile, then waits for an object to be signalled and returns. NtDeviceIoControlFile is the underlying NT function called by DeviceIoControl - MSWSOCK.DLL is calling into the TCP device driver, MSAFD.SYS.

I decided to stop there, as I already had enough of a headache from reading x86 disassembly...

How does Explorer know which zone a file was downloaded from?

In this post, I showed a screenshot of the 'Open File - Security Warning' dialog. But how does Explorer know to show this dialog - and how could you make it show in your own application, or write out the information from your own download application?

When Internet Explorer, Outlook Express, or Windows Messenger in XP SP2 write a downloaded file, they use the IAttachmentExecute interface (I think - the documentation is obscure). This writes an Alternate Data Stream on an NTFS drive, which is named 'Zone.Identifier'. For the HS5Setup program I took the screenshot for, it contains:

[ZoneTransfer]
ZoneId=3

(information captured with 'more' - 'type' wouldn't show the stream's contents)

When you open a file (I assume of a limited set of types, but I can't find any configuration for it) Windows checks for the Zone.Identifier stream, and if it finds it, and it's an Internet zone, you get the attachment security dialog.

Get XP SP2 on a Torrent

54 KiB/s

Download links at sp2torrent.com. I decided not to wait for Automatic Updates to kick in, even if RC2 users will get the update first.

Since I started writing this post, it's downloaded another 13MB.

Sunday, 8 August 2004

XP SP2 *will* be distributed through Automatic Updates

This is a scary prospect - Microsoft have confirmed it.

I suggest that companies not using Software Update Services either start doing so or set Automatic Updates to advise of new downloads only. I could cope with our developers making the switch one-by-one - they can handle any errors that result - but I think we need to manage our salesmen more closely. Specifically, we need to test that SP2 works properly with our VPN software and with their new laptops.

You can configure Automatic Updates through Group Policy without having to touch every computer, if you have an Active Directory-based domain.

Ironically I'm more worried about getting the salesmen updated ASAP than the developers, because I think the salesmen are less likely to practise safe computing. But it has to be organised.

Friday, 6 August 2004

Tim Bray weighs in on Linux and patents

http://tbray.org/ongoing/When/200x/2004/08/05/LinuxPatents.

I find this comment interesting:

"Second, the Linux community would—after some pain—figure out a way to route around the litigation; it would be real work, but it would happen."

OK, Tim, but you just wrote:

"The Lesson In software, assume that everything is already patented. You can't build anything, no matter how new it is, without infringing someone's patent."

You've got a vicious circle: in any attempt to avoid this patent (which you may not be able to do anyway, since the patent covers the method of implementation, not the actual code implementation itself) you may well end up infringing others. Remember Microsoft's proposed solution to the Eolas patent: don't perform the infringing operation (automatically scripting binary controls loaded into a page).

[Edit: Fixed nasty double-encoding error, sigh]

No XP SP2 yet

...but I did just get a new version of Windows Update v5.

It looks to me as though MS is going to push SP2 through Automatic Updates. I'm not sure this is a good idea. Yes, everyone should have SP2 - but only under their control, and only when they ask for it. This isn't a small patch - the RC2 download was 200MB or so. Even though Windows Installer 3.0 allegedly supports differential binary patching, if everything has been recompiled with the latest /GS implementation, a heck of a lot will have changed.

I just hope I won't have to uninstall RC2 before installing the RTM version.

Tuesday, 3 August 2004

Odd PC behaviour? Run a memory tester

MS has written one, which can be booted from either a floppy disk (what's one of those? ) or a CD: download.

(via Dr. HardwareBlog)

It was twenty years ago today...

...well, OK, it was nine years ago some time this week, I forget exactly.

When I was at school, around Christmas 1994, I joined a band with a few friends. In August of 1995, we recorded a number of songs we'd written (mostly by David Kane, our guitarist, often with Roger Barden, the keyboard player, although I and the drummer, Chris Velvick, also have writing credits). Since David is now getting married (in Toppenish, Washington, USA - he's marrying an American girl) in September, and I have some free time () I thought I'd get the demos onto CD. The master is a standard, albeit very expensive, audio cassette - it uses different material to get very low noise.

I also converted the songs to MP3. I thought I could actually upload all of them to my Demon web space, but it's only 20MB, and I encoded them (all 4+ minutes, we were a little long-winded) at 192kbps. There's arrogance. So there's only space for one, really. I've chosen one of my favourites: Survivor.

Oh, my part? I do the vocals. That's it. While I now play a bit of guitar - and Survivor is one of the few things I can play - I couldn't at the time.

As for what happened to the band - we found that our final Upper Sixth year was a lot harder than the previous one and didn't find a lot of time for rehearsing, let alone writing and recording new material. David continued with his Music A-level; David and Roger then took a year out travelling (Japan and the Amazon) before going to University to study Music at Bangor and History at Exeter (I think) respectively, starting in 1997. Christian studied Chemistry and drinking at Edinburgh, while I went to Aston (which I've written about before).

David is now studying for a PhD at SOAS having completed his MA in Ethnomusicology and I believe is still planning to visit Bangladesh again some time in the winter. Roger is with some kind of missionary organisation in Leeds, last I heard. Christian is some kind of high-powered recruitment consultant recruiting middle managers, somewhere in the Thames Valley - I last saw him a year ago at Roger's pre-wedding meal (you can't really call that a stag night ).

And I'm muddling along as - mainly - a Pocket PC C/C++/C# developer working for 5D / Mnetics. It's a little unclear right now, actually - I answer the phone as Mnetics, but still officially work for 5D, which is now owned by Mnetics as of a couple of weeks ago.

[Update: I forgot to link to Audacity, the software I used to capture and manipulate the tracks.]

Saturday, 31 July 2004

Violence in video games

Well, I don't know about you, but I don't think video game violence actually has that much effect IRL. I mean, it's had no effect on me. I'm absolutely fine  

Anyway, it appears that Halo 2 (not mentioned by the Daily Mail, apparently) will be rated 16+ in the UK:

"The VSC was totally unconcerned with the murderization of Covenant forces. Apparently, if the game didn’t allow you to turn on your allies, we’d have gotten the UK equivalent of a PG, regardless of the galloons of alien blood we had flooded the Galaxy with. Britain is now completely unconcerned with bad language, as I discovered watching BBC TV in the hotel that night. Just as well, since every other word out of our game seemed to be bastard., asshole or bullshit.

"I did point out that technically, you can kill tens of thousands of Grunts, Elites, Brutes, Jackals and “others” while playing a typical game. “No problem, as long as they don’t look human,” said one of the chaps." -- Bungie Weekly Update 30/7/2004

Friday, 30 July 2004

It takes *how* long?

Download size: 7MB, NaN minutes

For those not versed in floating point representations, NaN means 'Not a Number' - typically the result of division by zero.

(Windows Update v5, BTW)

Friday, 23 July 2004

Daily WTF

...is a blog containing code (and sometimes other things) that make geeks go, WTF??

Today's horror just looks like a random jumble of appending constants that probably didn't need to be constants. Until you look more closely, and you realise it's constructing XML. Except there's a bug: tags are being closed with a backslash - \ - rather than the correct slash - /.

Just in case anyone needs the hint:

private static string FormatData( SqlDataReader dr )
{
   using ( StringWriter sw = new StringWriter() )
   {
      XmlTextWriter tw = new XmlTextWriter( sw );

      tw.Formatting = Formatting.Indented;
      tw.WriteStartElement( "Items" );
               
      while ( dr.Read() )
      {
         tw.WriteStartElement( "Item" );
         tw.WriteAttributeString( "key", (string)dr[0] );
         tw.WriteString( (string)dr[1] );
         tw.WriteEndElement();
      }

      tw.WriteEndElement();

      return sw.ToString();
   }
}

If you need to write XML, use an XmlTextWriter. The code is shorter and clearer, and is more likely to work, considering cases like escaping invalid characters. Also note that I got it to indent the XML for me. Running this on a reader containing the results of SELECT emp_id, lname FROM employee on SQL Server's pubs database, we get:

<Items>
  <Item key="A-C71970F">Cruz</Item>
  <Item key="AMD15433F">Devon</Item>
  <Item key="A-R89858F">Roulet</Item>
  <Item key="ARD36773F">Domingues</Item>
  <Item key="CFH28514M">Hernadez</Item>
  <Item key="CGS88322F">Schmitt</Item>
  <Item key="DBT39435M">Tonini</Item>
  <Item key="DWR65030M">Roel</Item>
  <Item key="ENL44273F">Lincoln</Item>
  <Item key="F-C16315M">Chang</Item>
  <Item key="GHT50241M">Thomas</Item>
  <Item key="HAN90777M">Nagy</Item>
  <Item key="HAS54740M">Snyder</Item>
  <Item key="H-B39728F">Bennett</Item>
  <Item key="JYL26161F">Labrune</Item>
  <Item key="KFJ64308F">Josephs</Item>
  <Item key="KJJ92907F">Jablonski</Item>
  <Item key="LAL21447M">Lebihan</Item>
  <Item key="L-B31947F">Brown</Item>
  <Item key="MAP77183M">Paolino</Item>
  <Item key="MAS70474F">Smith</Item>
  <Item key="MFS52347M">Sommer</Item>
  <Item key="MGK44605M">Karttunen</Item>
  <Item key="MJP25939M">Pontes</Item>
  <Item key="M-L67958F">Larsson</Item>
  <Item key="MMS49649F">Saveley</Item>
  <Item key="M-P91209M">Pereira</Item>
  <Item key="M-R38834F">Rance</Item>
  <Item key="PCM98509F">McKenna</Item>
  <Item key="PDI47470M">Ibsen</Item>
  <Item key="PHF38899M">Franken</Item>
  <Item key="PMA42628M">Accorti</Item>
  <Item key="POK93028M">Koskitalo</Item>
  <Item key="PSA89086M">Afonso</Item>
  <Item key="PSP68661F">Parente</Item>
  <Item key="PTC11962M">Cramer</Item>
  <Item key="PXH22250M">Henriot</Item>
  <Item key="RBM23061F">Muller</Item>
  <Item key="R-M53550M">Mendel</Item>
  <Item key="SKO22412M">Ottlieb</Item>
  <Item key="TPO55093M">O'Rourke</Item>
  <Item key="VPA30890F">Ashworth</Item>
  <Item key="Y-L77953M">Latimer</Item>
</Items>

Wednesday, 21 July 2004

Changes to Win32 API in Longhorn - Windows Base APIs

From WinBase.h:

  • New system exception type EXCEPTION_POSSIBLE_DEADLOCK. Is the OS detecting deadlocks for us?
  • New CreateFile flags: FILE_FLAG_MUI_REDIRECT, FILE_FLAG_MUI_FALLBACK, FILE_FLAG_COPY_TEMPLATE_METADATA - used by the loader?
  • CopyFileEx flag COPY_FILE_COPY_LINK. Symbolic links in the filesystem at last? Yes: CreateSymbolicLinkW.
  • GetQueuedCompletionStatusEx function and new structure OVERLAPPED_ENTRY. Apparently able to remove multiple requests from a completion port in one call.
  • CreateIoCompletionPortEx, takes an additional ObjectFlags DWORD over CreateIoCompletionPort.
  • New I/O completion/asynchronous APIs SetFileCompletionNotificationModes and SetFileIoOverlappedRange.
  • Kernel-level reader-writer locks and condition variables, more like POSIX threads. The relative weakness of the Event has been a long-held criticism of the Windows threading model.
  • Encode/Decode{System}Pointer APIs. I could have sworn I'd seen this documented somewhere, but Google can't find it now. I think the idea is to protect an in-memory pointer to a sensitive structure until required, as a security measure.
  • NUMA support for virtual memory allocation with VirtualAllocExNuma - allocate memory with affinity to one or more nodes. New flag NUMA_NO_PREFERRED_NODE. You can also create file mappings on specific nodes using CreateFileMappingNuma, MapViewOfFileExNuma.
  • INHERIT_CALLER_PRIORITY flag (CreateProcess?)
  • JIT_DEBUG_INFO structure (with 32- and 64-bit variants) which may go along with a new IDebugSymbols3 interface declared in DbgEng.h.
  • New OpenFile flags? OF_MUI_REDIRECT, OF_MUI_FALLBACK. OF_ flags are also used by LZOpenFile and AVIFileOpen.
  • Acquire and Release (memory fence) versions of InterlockedIncrement, Decrement, Exchange, CompareExchange.
  • 32-bit versions of InterlockedAnd, Or, Xor. More Interlocked bitwise operations.
  • Ability to push a whole list onto an interlocked singly-linked list (InterlockedPushListSList).
  • Guaranteed thread stack sizes: new API SetThreadStackGuarantee.
  • Ability to explicitly set thread priority: SetThreadActualPriority. Can query with GetThreadActualPriority.
  • GetThreadStartInformation - find out where any thread started executing, and what the lpParameter parameter passed to CreateThread was.
  • 64-bit tick counter: GetTickCount64. Either higher resolution or greater range (or both?)
  • SetEndOfFileEx. Now you can just say how long the file is, you don't need to SetFilePointer first (and you can also keep your place...)
  • Walk and delete file-system trees: WalkTreeW and DeleteTreeW.
  • Transactional file-system backup semantics: BACKUP_TXFS_DATA used with BackupRead/BackupWrite.
  • Enhanced mutexes: CreateMutexEx{A/W}. You can now use some object flags and specify what access you want to the mutex (perhaps you only need to know it exists, rather than being able to SYNCHRONIZE?) Ditto CreateEventEx, CreateSemaphoreEx, CreateWaitableTimerEx.
  • New Reserve object. Some kind of kernel object (like a job??) to which you can join threads and associate processes, then later 'disjoin' and disassociate them. You can set the bandwidth for the reserve... this must be the resource reservation API, to provide guaranteed QoS to threads and applications. No more choppy Media Player?
  • NeedCurrentDirectoryForExePath API. Takes a string parameter called ExeName and returns a BOOL. A get-out clause for the post- XP SP1 LoadLibrary behaviour?
  • EnumResourceTypesEx - look for resources in MUI DLLs with specific languages? Also EnumResourceNamesEx and EnumResourceLanguagesEx. Updating resources also extended: BeginUpdate/Update/EndUpdateResourceEx.
  • 64-bit systems Windows-on-Win64 file system redirection using Wow64EnableWow64FsRedirection.
  • GetFileAttributesEx new flag GetFileExInfoNoReparse - prevent walking through symlinks?
  • 'Fast' search for FindFirstFileEx: new flag FindExInfoFast.
  • Enhanced I/O cancellation: cancel synchronous I/O occurring on another thread with CancelSynchronousIo, and possibly find out how much data was already transferred on an asynchronous I/O using CancelIoEx, which takes a pointer to an OVERLAPPED structure.
  • Explicit thread pooling: CreateThreadpool, SetThreadpoolThreadMinimum/Maximum, Pause, Resume, CreateThreadpoolGang(?), Timers, Waits.
  • A bit of diagnostics: GetOSProductName.
  • Transactions (transactional file data support?): SetCurrentTransaction, GetCurrentTransaction.

That's a lot of new capabilities right there.

Sunday, 18 July 2004

Academic biography and C++ parsing

Of course, due to my peculiar route through university, I ended up studying both the C and C++ courses twice, which tended to reinforce the principles - then for my final year project, I got very familiar with the C++ syntax and semantics. My friends already know my background, but I've had a few comments from people who don't, so here we go:

I entered Aston in September 1996 to study for an M.Eng in Electronic Systems Engineering - a four year full-time course. For any foreigners, a normal Bachelor's first degree in the UK has three years of full-time study, often optionally with an additional year spent on industrial placement. Normally, a Master's degree is postgraduate study, but M.Eng is atypical - it's a four-year first degree. When I started, you were supposed to get industrial placement work during summer vacations, but this rule was relaxed when it became clear that there weren't any placements available.

I attended that course for three years, scraping passes after resitting exams in both the first and second years (in one resit exam, my grade shot up from a failing grade to over 80%). In the third year a combination of factors (illness, extensive involvement in Entertainments, increasing complexity of mathematics) led to my deferring the exams. Over that summer I questioned my future direction and decided to apply for a transfer to Computing Science, which was granted. The departments accepted that my studies so far had covered all the material necessary to proceed directly to year 2. I completed year 2 with decent grades, then completed the final year fairly well, graduating with Lower Second-Class Honours (a 2:2, or Desmond).

The main thing that dragged my final Honours grade down was my final-year project. I'd decided to tackle a program to diagram the static structure of a program, with C++ as the source language. I got totally bogged down in the syntax and semantics of C++, and basically failed to complete the project. I don't do things by halves - I was trying to persuade a variety of parser generator tools to interpret standard C++ correctly. I suppose that I was taken in by my Programming Language Implementation lecturer, who claimed that parsing was the bit of CS that could be called 'science', because we know how to do it.

Not for C++, we don't. The commercial C++ parsers are either hand-written recursive-descent parsers which don't really follow any 'scientific' method (Visual C++), or based on yacc/bison with so much feedback between parser and lexer stages, and with so many bizarre actions in the middle of rules, that you can't call them LALR(1) any more (GCC).

Yes, I could have adapted GCC to handle the parsing. But quite frankly I didn't want to spend three months or more understanding how to hook into it.

The problem with C++ is just that it's hugely ambiguous and overloaded, with the distinguishing symbols - if any - an indeterminate distance from the beginning of a clause. This makes it great to write, IMO, and it's OK for humans to read given that we can see the whole line, but very hard to write a parser for. The syntax actually allows a great deal more expression than most programmers ever use, but the parser really has to accept all of it.

C++ really requires a stronger parsing method: LR(k). I now recommend that people look at Elkhound if they want to parse C++ and don't want to use an available parser.

What I should have done was to use Visual C++'s CL and BSCMAKE tools to generate the source browser files and then use the Browser Toolkit to interpret the BSC file, and generate diagrams from that. But I don't think I knew it existed at the time.

CS at Aston no longer offers C

...or any unmanaged programming, for that matter, apart from a small amount of assembler in year 1. It looks like the dedicated academics have won out over the practical people.

I was involving myself in a conversation on CodeProject about college courses (a US-based individual noted that their college offered COBOL!) and wanted to link to my old BSc Computing Science course (which I graduated from back in 2001). Then I noticed something horrible...

Java has taken over, at least above first year (Introduction to Systematic Programming is still taught in Ada). Object-Oriented Programming is now taught in Java (when I took the course, it was C++) and a new course, Internet Programming with Java, takes the place of the C course, Software for Systems Programming.

Now I'll admit that a lot of my fellow students didn't 'get' OOP because they got bogged down in the ugly mechanics of C++. The lecturer wasn't too hot, IMO, and wasn't properly focused on the OOP mechanisms of C++. Also, at the time, the course compiler was GCC 2.x which didn't do templates and the standard C++ library very well, so we were using a lot of the C subset of the language.

It looks like the Computer Graphics course might still be taught in C, but there you have another problem - in spending time teaching the language, you lose time to teach the actual meat of the course.

But how can you send out new graduates with no practical knowledge of low-level systems programming? If you have to break out of the cosy managed environment, how will you cope? Someone still has to write the VM and runtime, after all, and the system dependencies. Are we failing to train our software engineers to write the next generation of VMs?

Tuesday, 13 July 2004

Adapting to the executing platform

A standard way of using features not supported by your baseline platform but supported by later versions is to use the LoadLibrary and GetProcAddress routines to get a handle to a DLL, then get the address of the function, if it's present.

You can do this in .NET by using [DllImport], calling the function, then handling the MissingMethodException that results. However, throwing an exception is a relatively lengthy operation.

Junfeng Zhang reports that a new method GetDelegateForFunctionPointer has been added to the System.Runtime.InteropServices.Marshal class in .NET 2.0. You can now LoadLibrary and GetProcAddress, then construct a delegate from the resulting function pointer.

Changes to Win32 API in Longhorn - Update Delayed

Nothing to see here, move along...

I haven't quite had the energy to do the next stage. I'm thinking about tackling winuser.h and wingdi.h next, plus probably the GDIPlus headers.

In mitigation, yesterday I watched Coupling for half an hour and spent a long time investigating the ListView.Click issue, which was originally raised on CodeProject's C# forum. Guess what the second response was? "TreeView.Click doesn't work either!" Sheesh...

Tonight I got home pretty late anyway, then my wireless connection stopped working after I read the blog collection and checked for updates. I decided to apply the firmware update to the router, but that didn't solve it, so I hit Disconnect on the View Available Wireless Networks window, then hit Refresh Network List - and nothing appeared. I ended up uninstalling the Virtual PC Network Switch driver and the IPv6 stack (which I'd been looking into a while back) which didn't help, then punching in the SSID and WPA keys again - still nothing.

OK, I thought, let's reboot. After rebooting, the network had disappeared from the Advanced Settings screen. Great - I enter it again, and it works (I can't just click on it in Available Wireless Networks because the router's set to not broadcast the SSID).

I've found that XP SP2 wireless + my card's drivers + Virtual PC Network Switch don't work together anyway. If you have VPCNS enabled on the wireless connection, nothing happens: any packets directed at the connection disappear into a black hole. Disabling VPCNS on the connection sorts it out, although I found I had to Disconnect and Connect in Available Wireless Networks before it would work again.

Anyway, that and normal routine household tasks took up most of the evening. Hopefully I'll get to it tomorrow.

Now I read that back, I realise that I've probably spent as much time writing up the excuse as I would have just writing it. Oh well.

[Edit:]

I need to state that actually, VPCNS works fine on the wireless connection - it was the action of installing it which caused the stack to go bonkers. Disconnecting then reconnecting sorted out the stack. I'd been having weirdo problems with it not working properly when resuming from Hibernate - again, disconnect and connect sorted it out. Let's see if it stays sorted - OK so far.

Because I hibernate this machine (it's a guzunder - it goes-under the desk) uptime doesn't have a lot of meaning. I use hibernate rather than power off because it hibernates faster than it shuts down, it resumes faster than it starts up, and I don't lose my context if I was working on something. We're talking < 10 seconds from press-power-switch to unlocking the console. Also, because of the way it works (dump physical pages to disk) I think the disk cache also remains 'hot'.

Linking it together

Or rather, following the links.

The Brothers Chaps, at homestarrunner.com (rss) have uploaded a new video, for the new song Experimental Film by They Might Be Giants. I still remember TMBG best from "Birdhouse In Your Soul" and "Istanbul (not Constantinople)", dating back to 1990.

This spurred off a link in my head to one of my favourite bands, The Presidents of the United States of America (or PUSA, to most fans). I searched for their site and discovered that they're releasing a new album in August! Unfortunately, the new single is only currently available on iTunes. Er, sorry, but I don't want to give Apple any money.

Their last album, "Freaked Out and Small" was released on the MusicBlitz website, then as a CD. I found out about this one through a link from one of the webcomics I read, which linked to a great animated video by Chris Maguire for the song "Meanwhile Back In The City". The animation is totally unofficial - from the link, it looks like it was undergraduate project work. Still cool, though.

Get patching

This month's Microsoft Security Bulletins (rss) have been released. I suggest applying the patches reasonably quickly. Of seven bulletins, one applies only to IIS 4.0 on NT 4.0 (to which I must ask why have you not upgraded??), one applies to the POSIX subsystem on NT 4.0 and 2000 (not included in XP and 2003), and one to the Utility Manager in Windows 2000.

I'm hoping that the dead silence in the bulletins regarding XP SP2, and Windows Update v5 not showing anything, means that these issues are already fixed in SP2. It looks like all the binaries on my machine have later build dates and build numbers.

Monday, 12 July 2004

Public Service Blogging: ListView.ItemActivate

The ListView.Click event works in the desktop .NET Framework. It doesn't work in the Compact Framework, even in the beta SP3: it doesn't fire.

Nor does it fire in .NET Compact Framework 2.0 Beta 1, which I've been looking at this evening, a bit. You get a warning when you compile:

warning VSD101: Members not supported by the Device platform should not be called: System.Windows.Forms.ListView.add_Click is not a supported method in this platform

It turns out that you're not supposed to use Click - you're supposed to use the overarching ItemActivate event, which is fired when either you click, or double-click depending on configuration, or when you activate the item with the keyboard. I suppose this makes sense for Smartphone, since you can't 'click', the screen not being touch-sensitive.

You configure whether ItemActivate fires on single- or double-click by setting the Activation property on the control.

Note the nice bit of abstraction leakage in the warning message: the line of code reads:

listView1.Click += new EventHandler(listView1_Click);

Er, where did I call the method add_Click? Answer, it's lurking behind that nice += syntax.

OK, so I'm using the wrong semantics; it should still work.

Sunday, 11 July 2004

Changes to Win32 API in Longhorn - Common Controls

The Common Controls API is largely implemented in commctrl.h. Let's see what's new (note, of course, everything is subject to change; documentation for these functions and flags isn't yet written).

  • New Histogram control: ICC_HISTOGRAM_CLASS flag for InitCommonControlsEx, many structures, messages, notifications, flags etc
  • Notification message on font change: NM_FONTCHANGED
  • New custom draw flags CDRF_DOERASE, CDRF_SKIPPOSTPAINT (marked internal)
  • New message NM_GETCUSTOMSPLITRECT and accompanying structure
  • New flag ILC_ORIGINALSIZE for ImageList_Create
  • New flag ILD_ASYNC for ImageList_Draw
  • New flags ILS_EMBOSS, ILS_REFLECT, ILS_INVERT for ImageList_DrawIndirect
  • Reference to SparseImageList (value HBITMAP_CALLBACK - enables image to be supplied on demand, dynamic images in ListViews?)
  • Checkboxes and non-resizable columns in Header controls (HDS_CHECKBOXES, HDS_NOSIZING)
  • Data filtering by date (HDFT_ISDATE used with HDITEM structure)
  • Hit testing header-items can report On Item State Icon (HHT_ONITEMSTATEICON)
  • Header state icons: new macros Header_GetStateImageList and Header_SetStateImageList
  • Ability to use accelerator keys with a header control (?): HDM_TRANSLATEACCELERATOR
  • Item notifications: HDN_BEGINFILTEREDIT, HDN_ENDFILTEREDIT, HDN_ITEMSTATEICONCLICK, HDN_ITEMKEYDOWN
  • Oddly extended toolbar class: "ToolbarWindow32_Mil"
  • Callback image labels in a toolbar: TBSTYLE_EX_CALLBACKIMAGELABELS
  • "Use CustomDrawColors to RenderText regardless of VisualStyle": TBCDRF_USECDCOLORS for toolbar custom draw
  • Transparent, splitter rebars: RBS_EX_TRANSPARENT, RBS_EX_SPLITTER
  • Notification of rebar splitter drag: RBN_SPLITTERDRAG
  • Tooltip can have a preview bitmap: new member hbmp on TOOLINFO structure
  • 'Themed' hyperlinks in tooltips: TTS_USEVISUALSTYLE style flag
  • Animated progress bars (?): PBM_ANIMATE, PBM_TRANSITIONTOPOS messages
  • New List View style flags LVSIL_GROUPHEADER, LVSIL_IMAGETITLE (draw your own conclusions - groups of items in a list view?)
  • List View item flags LVIF_IMAGETITLE, LVIF_TASKS, LVIF_COLFMT, structure LVTASKS and corresponding fields in LVITEM
  • New list view item search flags for LVM_GETNEXTITEM message: LVNI_VISIBLEORDER, LVNI_PREVIOUS, LVNI_VISIBLEONLY, LVNI_SAMEGROUPONLY
  • New flag for LVM_GETITEMRECT: LVIR_NUMORDER
  • Hit test flags for ListView groups: group header, footer, expand/collapse button, background, state icon, contents.
  • New macro ListView_HitTestEx to support group flags
  • Additional flags for controlling ListView column formats
  • ListView extended styles: Justify Columns, Transparent Background, Transparent Shadow Text, Show Numeric Order, Auto Auto Arrange (Icons automatically arrange if no icon positions have been set), Show Header in all modes, Auto Check Select (?), Auto Size Columns
  • Alpha-blend background images: LVBKIF_ALPHABLEND
  • New ListView views: Carousel, Panorama
  • New options for ListView groups (different from above groups? LVGROUP structure extended) and new styles
  • ListView Tile View 'extended' size flag: LVTVIF_EXTENDED
  • Column formats for tile info columns
  • Bitmaps on ListView infotips
  • Is a list item visible? ListView_IsItemVisible macro
  • NMLVLINK structure: links in a ListView? Also LVN_LINKCLICK notification
  • LVN_ORDERCHANGED notification
  • Async drawing of ListViews
  • Enhancements to Animation control: ACM_OPENXFILE, ACM_SETTEXTURE messages
  • Split buttons: a host of new messages, styles, flags, structures and notifications. I assume this is like the Open button in VS2003.
  • Edit control: Set Highlight, Get Highlight messages
  • Unknown flags: DCHF_TOPALIGN, DCHF_HORIZONTAL, DCHF_HOT, DCHF_PUSHED, DCHF_FLIPPED, DCHF_TRANSPARENT, DCHF_INACTIVE, DCHF_NOBORDER. Might be related to:
  • DrawScrollArrow API

Of course, it's possible that a lot of this is to support the sample UI in current Longhorn builds, and might disappear before the final software is released. Heck, it could disappear before the next build is released.

Changes to Win32 API in Longhorn

Joel Spolsky's post How Microsoft Lost the API War has had a fair amount of press, and has got a number of developers running scared - some even talking about switching to Linux development. A common theme is that Microsoft won't be advancing the state of the existing API: all new features are going into Avalon/WinFX. People seem to have implied from this that they'll have to rewrite all their apps from scratch, which should not be the case at all.

I wrote a message on the CodeProject forums yesterday which I'll include here:

Don [Box]'s blog post Teaching COM made it pretty clear that Microsoft are extending COM for the Longhorn generation.

They've previously said that the Win32 stack will continue to be present in Longhorn and demonstrated old DOS apps running on Longhorn builds. I don't have a Longhorn SDK handy, so I can't tell you how much Win32 is being enhanced. The new window management and drawing APIs will be exposed through managed interfaces only, I believe, but your UI and data are abstracted, aren't they? Joe Beda, an Avalon architect, talks about this in a Channel 9 video.

Managed C++ or the new C++/CLI syntax should allow you to build a new front end to your existing C++ code.

I seem to recall that Avalon architect Chris Anderson has talked about being able to host Win32 GDI+USER content in an Avalon application, and being able to host Avalon controls in a Win32 application. Windows Forms is just a special case: a Win32 application written in managed code.

Visual Studio 2005 comes with new versions of MFC and ATL, version 8.0. See Visual C++ 2005 Libraries Features for a list of the changes: note that MFC can now host Windows Forms controls, for example.

Remember that Microsoft's platforms and developer tools division's first customer is their applications division. These guys aren't going to want to rewrite Word: there's twenty years of code in there. Rick Schaut, a Mac Word developer, talks about analysing a bug which caused Mac Word to complain "Disk is Full" when trying to save.

They're not going to throw that fix away. They're going to write a new rendering layer, to render to Avalon, new frame UI code targetting Aero, then compile the rest of the monster using CL.EXE's /clr switch. I seem to recall that one of the targets for /clr was that the compiler had to be able to compile Word. I'd expect Microsoft to compile the whole of Word to IL, rather than native code, for future generations so that the same binary runs on both 32-bit and 64-bit machines. Of course, there's always P/Invoke if a component truly can't be compiled to IL.

Anyway, I've now downloaded the Platform SDK for XP SP2 and the Longhorn SDK, and I'm running a diff between the Include directory of the LHSDK and the version that ships with VS2003. Bizarrely, Microsoft have built the XP SP2 SDK from the XP SDK, which means it's impossible to build programs which use features new to Windows Server 2003 using this SDK - those features are missing. Thanks a bunch.

I plan to add new posts covering various areas of the SDK that have been updated. I'll add links to this post as I post them.

Tuesday, 6 July 2004

Jumping the hurdles: how Download.Ject infected

I thought I'd take a look at how Download.Ject infected, and the security barriers it managed to breach. I've gathered this together from what analysts have hinted at, so some information may be wrong.

Firstly, the attacker had to infect the web server. IIS has a feature which allows you to set a footer to be appended to every page. Internet Explorer parses content outside the <html> tags - but so does Firefox. Try this file:

<html>
<head>
<title>Test Page</title>
</head>
<body>
<p>Body</p>
</body>
</html>
<script language="javascript">window.alert( "Hello" );</script>

Opening this in a local file on XP SP2 gives you the Information Bar again; the Local Machine Zone has been locked down. You don't get the popup. Firefox gives you the popup.

Download.Ject exploited the Private Communications Transport (a secure sockets channel) flaw reported in MS04-011 to upload and execute arbitrary code. This uploaded code manipulated the metabase to add a footer containing a script.

The script in the footer, if run on Internet Explorer, exploited a vulnerability reported in MS04-013 which allows code to run in the Local Machine zone. It also repurposed the ADODB.Stream class, which is marked safe for scripting, to download files from the attacker's server to the victim's computer. The download was necessary to get code loaded into another process on the victim's computer. The effect of SP2's Local Machine Zone lockdown is that the script forced into the LMZ couldn't run. Note that no vulnerability in ADODB.Stream was exploited: it simply permits something that in retrospect is too permissive.

So the attacker had to have worked out how to exploit PCT, how to get arbitrary code running on the system with the user's full privileges, and how to get extra files downloaded onto the user's system. Administrators could have prevented the first by applying a megapatch; users the second by applying a patch.

Techworld.com - Browser rival to ActiveX in the offing

Techworld.com - Browser rival to ActiveX in the offing

And as a follow-up to the last post on browsers, the Other Browser Group (everyone who makes a commercial web browser, that isn't just a wrapper for one or more rendering engine, barring Microsoft) announce that they're going to extend scriptability on binary plugins. These binary plugins will be built using a C-based unmanaged API. Here's what they have to say about security:

"The security model for making calls through this API is much like the general same-origin security model enforced by the browser. That means that script from an origin other than the origin of the page that loaded the plugin is not able to access methods and properties on the plugin. The same thing applies the other way too, the plugin can reach only JavaScript objects in the same origin as the page that loaded the plugin.

"In addition to this, a further extension to this API is being discussed that would give a plugin greater flexibility by letting the plugin control the origin of the calling code, so that the plugin can specify the origin of calls that come from internally loaded code from other origins. This way such code can be executed with only the privileges of the origin of the code, and not the privileges of the plugin page's origin."

They've essentially described denying cross-site scripting. This is all very well, but if there's a flaw in the implementation, you still have XSS attacks. There's no sandboxing, no requirement to mark components safe for scripting or initialization, no way for the user to limit which sites can and cannot use script. It's all or nothing. IE has all the above (and the cross-site scripting restrictions).

Fundamentally, with the ability to load unmanaged components, the code can do anything at all. They don't describe any way for components to be recognised as written by a particular publisher or to limit the user's ability to download unsigned controls (possible through Group Policy for IE). The slight limitation is that of course the browser can only load components which conform to the required interface; there are many fewer of those for the Netscape plug-in API than there are COM components.

Let's look at how things work on XP SP2. In Firefox, say I want to watch Strong Bad's latest e-mail and I don't have the Flash player. Clicking that link gives me a big blank area saying 'Click here to get the plugin'. Clicking that gives me a lengthy dialog with a Get the Plug-in and a Cancel button, which doesn't mention security at all. Clicking Get the Plug-in button takes me to Macromedia's download page, so I click Download Now. I get a dialog asking me to save the installer. Once it's downloaded I open the installer, and step through the wizard, which shuts down the browser.

It appears that Firefox can load plugins on the fly, but Flash doesn't bother - it just restarts the browser. The suggestion seems to be that this will become easier - plugins could be downloaded after prompting the user. Netscape 4.x supported SmartUpdate, which does have code-signing, but this required LiveConnect, not present in Firefox. Firefox already supports XPCOM, XPInstall and XPConnect. The first allows binary extensions, the second allows extensions to be installed on demand, and the third allows those extensions to be scripted.

You can get an XPCOM extension which loads ActiveX controls. As a demo, in the download section, click one of the Click Here links. Firefox pops up a dialog:

Note "Install Now" is the default, although it is initially disabled for two seconds. I didn't hit Install Now because firstly I don't want it and secondly it doesn't work in Firefox at present.

Let's try the equivalent on IE. Remember this is SP2. First I have to persuade IE that Flash doesn't exist by deleting it from the registry. Now we go again to Homestarrunner.com. I get the information bar:

Clicking the bar and selecting "Install ActiveX Control" reloads the page and brings up the new security dialog:

Hitting Install downloads and installs the player, then loads the content straight away. Note that "Don't Install" is the default. IE also watermarks files that it downloaded: when you try to open one, you get this dialog:

I suspect the next generation of IE will support .NET-based plug-ins which use the .NET code access security model. It'll probably still support loading ActiveX controls, though.

Sunday, 4 July 2004

IE 6.0 SP2 forthcoming?

Previously, Microsoft have said that the IE security changes in XP SP2 won't be released for other OSs. However, I was just skimming PressPass and saw this quote:

"In addition to this configuration change, which will protect customers against the immediate reported threats, Microsoft is working to provide a series of security updates to Internet Explorer in coming weeks that will provide additional protections for our customers.

"Later this summer, Microsoft will release Windows XP Service Pack 2, which includes the most up-to-date network, Web browsing and e-mail features designed to help protect against malicious attacks and reduce unwanted content and downloads. A comprehensive update for all supported versions of Internet Explorer will be released once it has been thoroughly tested and found to be effective across a wide variety of supported versions and configurations of Internet Explorer."

(from Microsoft Statement Regarding Configuration Change to Windows in Response to Download.Ject Security Issue)

Does this mean they've changed their minds? Will a separate IE 6.0 SP2 be released? I hope so.

Download.Ject patch

There's now a patch available for the Download.Ject trojan - or rather, one of the holes it used (since the site hosting the code was taken down last week).

The Register: Microsoft half fixes serious IE vuln

The Register get it wrong again, of course: I anticipate that this is the full and final patch for this issue. The ADODB.Stream vulnerability is simply that a feature - the ability to write to a file anywhere on the hard disk - was made available to the web. The patch sets the 'kill bit' in the registry, preventing this control from being directly loaded from IE, as detailed in KB 870669. MS have clearly decided that compatibility and functionality have to be sacrificed on the altar of security.

A naive user reading that could argue that IE's security model is the wrong way round - instead of killing known unsafe controls, only known safe controls should be permitted. It actually does work that way, for most zones: controls must be marked 'safe for scripting' to be scripted and 'safe for initialization' to load parameters from the web page. The Local Machine Zone is different; that will be, by default, locked down in XP SP2 RC2. The 'kill bit' is for this situation - a control marked safe is in fact unsafe in a particular scenario.

The other vulnerabilities exploited were already patched in MS04-013 (client-side) and MS04-011 (server-side). If admins had applied the 04-011 patch rather than being scared off by adverse media reports, this wouldn't have happened. It's an admin's responsibility to not be an attack vector, as well as protecting their own systems. The Internet users may even have been collateral damage - IIS 5.0 is used much more widely in intranets. Of course there were incompatibilities with this patch, largely due to a new kernel binary being released for Windows 2000. We needed a hotfix and got stuck in the Product Support queue behind a bunch of the problem reports.

Yes, this exploit is a side-effect of IE being able to load and script any COM component in the local machine zone - get over it. As I say above, this will be locked down in XP SP2 (and already is in RC2). IE's come a long way since the bad days of IE 3.0, which didn't do any checking. It's also a side-effect of the user running as an Administrator, which we all know is a bad thing. If you're not running as Admin, I suspect that Download.Ject couldn't actually install the backdoor components.

Note that Firefox has the XPConnect module, which allows XPCOM plug-ins to be scripted, potentially leading to the exact same problems for any installed extensions. It's just no-one's found any vulnerabilities yet.

[Edit] That's a bit strong, really. It will only apply to Firefox extensions, not every control/component installed on the user's system. Still, that's probably enough scope, since almost everyone will have Flash installed. [/Edit]

True Lies

Just finished watching True Lies. Hard to believe it's ten years old, actually. For a Governator picture, it's pretty good, but then the supporting cast is bloody good: Jamie Lee Curtis, Tia Carrera, Art Malik, and a certain Eliza Dushku (better known as Faith from Buffy).

Even at age 14 she was cute, although to be honest the role's fairly small.

Art Malik is currently wasting himself in Holby City.

Around this time, Hollywood had a real habit of casting Islamic/Arabic villains such as the 'Crimson Jihad' in this one. I wonder if the perception of the faces of terrorism (i.e. the predominant nationality/worldview of the terrorists) is in fact based on this, rather than on fact? Wikipedia's list of terrorist groups is only about 25% Islamist.

Saturday, 3 July 2004

Freedom!

Well, of a sort. I went out and bought a wireless LAN ADSL router and a wireless card, so I now have Internet access at home from my own PC. I'm already running XP SP2 RC2, so firewalling is covered (and I'm free of Norton Internet Security, yay).

I'll admit to being sorely tempted by a wireless adapter for my Xbox (which is in yet another room) but I could only find an 802.11b one - maybe I'll order a g version from somewhere else.

Anyway I'm now patching Office (2000 SR-1a - ouch) and getting files off the other PC. Which is a story in itself - the network setup wizard in XP Home SP1 is, er, a bit broken (yes, dammit, I want to call the workgroup something other than MSHOME, thank you so very much) and NIS is getting in the way somewhere still, I think. I can see the other PC and mine in Network (My Network Places, for those who don't habitually delete My from every profile they create) but from their computer - nothing at all.

The subtext is that I want to download Whidbey beta 1 but don't want to actually write CDs for it - and anyway the other CD writer is a touch incompatible.

Tuesday, 29 June 2004

Are Pocket PC and Windows CE the same thing?

This is a FAQ on almost every Pocket PC and/or Windows CE development site and forum. This time I found the question on www.pocketpcdn.com.

Windows CE (.NET if a 4.x version, version 5.0 loses the .NET and is just Windows CE again) is a collection of pieces of an operating system, referred to as components. Each component is identified as belonging to Windows CE of a particular version and many of them are specifically written for Windows CE. An OEM, another third-party, or Microsoft themselves, can define a platform - a specific selection of those components to run on a particular device or compatible devices. A platform is a specialisation of the general set of components. Some of the components build on top of each other, others are completely independent, and others are mutually exclusive (e.g. you can only have one of the COM or DCOM runtimes).

Pocket PC is a platform defined by Microsoft; the 2000 and 2002 versions are based (loosely!) on Windows CE 3.0 while the 2003 versions are based on CE 4.2. Any OEM willing to license the software platform from Microsoft can do so, but must satisfy certain constraints (I believe) on screen size, application keys, and third-party components.

The tool for building your own platform comes in the Windows CE box and is called Platform Builder. You can find some videos demonstrating Platform Builder for Windows CE 5.0 at Channel 9. CE 5.0 will be released soon with a new Pocket PC version to follow later in the year, we believe. Once you've designed, built, and shipped your platform, you can generate an SDK from Platform Builder for use with (currently) eVC 4.0. A platform build consists of both compiling some components from source and linking other binaries together from supplied object libraries.

So, while Pocket PC includes many Windows CE components, some components of Pocket PC - notably the shell and messaging applications - are only available on that platform. It's possible to write programs which are source-compatible between Pocket PC and other Windows CE-based platforms, and even binary compatible, if you stick to components which are available on both platforms. So I guess the answer is really yes and no.

Saturday, 19 June 2004

Windows Driver Foundation

Microsoft have decided to do something about the relative instability of Windows device drivers. They are, by all accounts, very hard to write.

Introduction to the Windows Driver Foundation

Interesting point: the Kernel-Mode Driver Framework will be supported in Windows 2000 and later (i.e. a lot of it will be compiled into/linked into the driver binary). I also see that USB device drivers will be moving into user-mode for Longhorn.

I recently had to update a CE device's OS image using a special download program and the device's Initial Program Loader, over a USB connection. The device required a special driver - which promptly crashed my PC (with a KMODE_EXCEPTION_NOT_HANDLED fault). I suspect a possible incompatibility with XP SP1 with the MS04-011 patch. Using an unpatched Windows 2000 SP4 box worked. Of course, I couldn't use Virtual PC, because it doesn't virtualise USB controllers, hubs or devices.

Tuesday, 15 June 2004

I can hear that cable!

Science and Subjectivism in Audio

A nice link posted to the comments of Tony Schreiner's post Breaking-in Electronics.

When working in Ents you got the occasional person who was fully willing to accept that there was no need for special cables in live audio mixing and power amplification - but was fully kitted out at home. I guess that PA equipment doesn't require that level of quality (?!)

Thursday, 10 June 2004

The randomly-occurring bug

Rick Schaut, a developer on Mac Office, has posted a couple of articles about the biology of a difficult-to-reproduce software bug. Interesting reading.

Anatomy of a Software Bug

Repro, Man

Tuesday, 8 June 2004

What's it called, again?

As I think I've mentioned before, I've become the Exchange administrator at work. To understand what's going on better, and to keep up with developments, I've subscribed to Microsoft's Exchange Team blog (aka You Had Me At EHLO, a terrible pun).

Yesterday's entry covers installing the administrative tools (Exchange Manager and the Exchange Tasks for the Active Directory Users and Computers snap-in) on a server that doesn't have Exchange installed. The thing that caught my eye is that the entry is inconsistent about the naming of Windows Server 2003 - referring to it as both ".NET Windows" and "Windows 2003 Server".

Make your minds up!

Something that makes me a little uneasy is that the admin tools install a new service 'Microsoft Exchange Management.' Why??

Sunday, 30 May 2004

Death of the NDR

NDR = Non-Delivery Report

If I send you mail, but for whatever reason it doesn't get delivered, your server, or an intermediate server, may send an NDR. If this happens, I'll never know about it. My SpamBayes configuration now considers 100% of email sent by postmaster@ to be spam.

Mail from postmaster@ can now be broken down into four categories:

  • Spam posing as NDRs to persuade users to read it, and to slip through anti-spam barriers;
  • Viruses posing as NDRs to get you to open the attachments, and for the reasons above;
  • Bounce messages from other domains where people have sent spam using your email address or, in my case, anything with my domain - my mail ISP, Demon, gives a child domain of demon.co.uk to each subscriber; I can use anything I like before the @;
  • Genuine failures to deliver a message.

However, I don't actually send all that much email. I tend to receive notifications of comments to this blog, mailing list mail, and notification of replies to comments on web sites such as CodeProject. There's a little personal mail but not much.

I've recently become the Exchange administrator at work (an entirely new installation - we've only just got an Active Directory domain going and moved everyone to that). It doesn't look like you can configure it not to send a copy of the failed message back to the sender - should I configure it not to send NDRs at all?

However, if we did that, perhaps almighty fuck-ups like the one that happened last week - where we asked to begin the process of transferring a domain, and the ISP went ahead and did the whole transfer, rewriting the MX records to point to the Exchange server - wouldn't be detected as quickly.

Saturday, 29 May 2004

Korby reckons Windows will use VS Team System

"For larger teams and those who require integrated work item tracking and other software configuration management features, we've got a shiny, new Team Foundation server that we think you (AND the Microsoft Windows development team) will be using for many years to come." -- Korby Parnell.

Actually, the post was mainly about Visual SourceSafe, a product I cannot in conscience recommend to anyone. Any tool whose Best Practice guide recommends that you run a scheduled repair utility, so that the database corruption doesn't grow excessive, is just poor - particularly one you're relying on for your core business assets. Now, in fairness, a lot of the corruption experienced by many people is down to the usual culprits: flaky hardware, bad implementations of network file sharing in Windows 9x. Fundamentally, though, you have multiple remote clients modifying the same files - which has traditionally also caused problems for Microsoft Access - with no decent blocking lock support.

We know that Microsoft were using an internal system before Windows 2000 that basically forced a serialised development style; when it went into the final stabilisation stage, and the team were beginning to look towards Whistler (eventually Windows XP/Server 2003), they started to use a new internal system called SourceDepot (Source: Mark Lucovsky's USENIX presentation "Windows: A Software Engineering Odyssey" [PPT, HTML version]). Rumour has it (never officially confirmed) that SourceDepot is derived from a Perforce source-code license. It's a pretty good bet that Microsoft aren't allowed to sub-license their mods to anyone else.

VS Team System's version control component (code-name Hatteras) looks surprisingly (but no doubt superficially) like SourceGear Vault, from a descriptive point-of-view. Eric Sink (CEO of SourceGear) indicates the impact he thinks this will have on Vault (basically, innocent bystander caught in the cross-fire between IBM's ClearCase and Microsoft). So MS may be continuing in their long-standing tradition of dog-fooding - or Windows may have again grown out of its source control solution.

However, the future looks decidedly dim for SourceGear's SourceOffSite - similar features appear to be destined to appear in VSS 2005.

The Ten Bugs in the Known Universe

http://www.multimedia-people.co.uk/misc/bugs.html (originally by Andy Lowe, apparently MIA).

How did I get here? Let's follow the trail backwards:

John Robbins' Bugslayer column tips
Scott Hanselman's Blog
John Lam's Blog
Don Box

Sometimes I need a breadcrumb indicator in IE.

Thursday, 27 May 2004

Eric Lippert on marshal-by-reference vs marshal-by-value

Eric uses the .NET term for marshal-by-value: Serialization.

1) Build a telephone system between Seattle and Hong Kong.  I get a telephone receiver with "CLIENT PROXY" written on it. You get a telephone receiver with "SERVER STUB" written on it.  Instead of talking to you, I talk into Proxy.  Proxy talks to Stub somehow -- I really don't care how the phone system works, so long as it does -- Stub talks to you.  We get the illusion that we're actually talking to each other, when we're actually talking to hunks of plastic, but the information content is the same, so who cares?  Maybe there is some delay and expense, but the proxy does a good enough job of sending and receiving messages that we can communicate across the barrier.

2) Sequence your DNA into a string.  Run your brain through a Molecular Neuron Defrobnicator that extracts all your memories and saves them to disk.  Put the DNA string and memory data onto CD-ROMs, and FedEx the box of CD-ROMs to Seattle.  Once I get them in Seattle, I rebuild your DNA from the sequence information using nanorobots. I inject the rebuilt DNA into an egg cell.  We use the egg cell to grow a copy of you in the lab.  When the brain is developed enough, I use my Molecular Neuron Refrobnicator to insert your memories into the clone's brain.

Marshal-by-ref versus Serializable Objects

Wednesday, 26 May 2004

This is great beer, where did I leave my head?

Currently drinking: Young's Special London Ale @ 6.4% by vol.

Nice.

Shame I can't type, really...

New element discovered!

Probably a repost...

A major research institution has recently announced the discovery of the heaviest chemical element yet known to science. The new element has been named "Governmentium". Governmentium has 1 neutron, 12 assistant neutrons, 75 deputy neutrons, and 111 assistant deputy neutrons, giving it an atomic mass of 312.

These 312 particles are held together by forces called morons, which are surrounded by vast quantities of lepton-like particles called peons. Since governmentium has no electrons, it is inert. However, it can be detected as it impedes every reaction with which it comes into contact. A minute amount of governmentium causes one reaction to take over 4 days to complete when it would normally take less than a second.

Governmentium has a normal half-life of 2 to 6 years; it does not decay, but instead undergoes a reorganization in which a portion of the assistant neutrons and deputy neutrons exchange places. In fact, governmentium's mass will actually increase over time, since each reorganization causes some morons to become neutrons, forming isodopes. This characteristic of moron-promotion leads some scientists to speculate that governmentium is formed whenever morons reach a certain quantity in concentration. This hypothetical quantity is referred to as "Critical Morass".

Thanks to Roger Allen, who posted this on CodeProject.