Windows 7 – Tales from the Crypto

Windows 7

Untrusting the Blue Coat Intermediate CA from Windows

So, there was this tweet that got passed around the security community pretty quickly:

Kind of confusing and scary if you’re not quite sure what this all means – perhaps clear and scary if you do.

BlueCoat manufactures “man in the middle” devices – sometimes used by enterprises to scan and inspect / block outbound traffic across their network, and apparently also used by governments to scan and inspect traffic across the network.

The first use is somewhat acceptable (enterprises can prevent their users from distributing viruses or engaging in illicit behaviour from work computers, which the enterprises quite rightly believe they own and should control), but the second use is generally not acceptable, depending on how much you trust your local government.

Filippo helpfully gives instructions on blocking this from OSX, and a few people in the Twitter conversation have asked how to do this on Windows.


Don’t do this on a machine you don’t own or manage – you may very well be interfering with legitimate interference in your network traffic. If you’re at work, your employer owns your computer, and may intercept, read and modify your network traffic, subject to local laws, because it’s their network and their computer. If your government has ruled that they have the same rights to intercept Internet traffic throughout your country, you may want to consider whether your government shouldn’t be busy doing other things like picking up litter and contributing to world peace.

The simple Windows way

As with most things on Windows, there’s multiple ways to do this. Here’s one, which can be followed either by regular users or administrators. It’s several steps, but it’s a logical progression, and will work for everyone.

Step 1. Download the certificate. Really, literally, follow the link to the certificate and click “Open”. It’ll pop up as follows:

5-26-2016 3-49-29 PM

Step 2. Install the certificate. Really, literally, click the button that says “Install Certificate…”. You’ll see this prompt asking you where to save it:

5-26-2016 3-49-41 PM

Step 3. If you’re a non-administrator, and just want to untrust this certificate for yourself, leave the Store Location set to “Current User”. If you want to set this for the machine as a whole, and you’re an administrator, select Local Machine, like this:

5-26-2016 3-49-50 PM

Step 4: Click Next, to be asked where you’re putting the certificate:

5-26-2016 3-50-02 PM

Step 5: Select “Place all certificates in the following store”:

5-26-2016 3-50-16 PM

Step 6: Click the “Browse…” button to be given choices of where to place this certificate:

5-26-2016 3-50-23 PM

Step 7: Don’t select “Personal”, because that will explicitly trust the certificate. Scroll down and you’ll see “Untrusted Certificates”. Select that and hit OK:

5-26-2016 3-50-35 PM

Step 8: You’re shown the store you plan to install into:

5-26-2016 3-50-47 PM

Step 9: Click “Next” – and you’ll get a final confirmation option. Read the screen and make sure you really want to do what’s being offered – it’s reversible, but check that you didn’t accidentally install the certificate somewhere wrong. The only place this certificate should go to become untrusted is in the Untrusted Certificates store:

5-26-2016 3-50-52 PM

Step 10: Once you’re sure you have it right, click “Finish”. You’ll be congratulated with this prompt:

5-26-2016 3-50-59 PM

Step 11: Verification. Hit OK on the “import was successful” box. If you still have the Certificate open, close it. Now reopen it, from the link or from the certificate store, or if you downloaded the certificate, from there. It’ll look like this:

5-26-2016 3-51-44 PM

The certificate hasn’t actually been revoked, and you can open up the Untrusted Certificates store to remove this certificate so it’s trusted again if you find any difficulties.

Other methods

There are other methods to do this – if you’re a regular admin user on Windows, I’ll tell you the quicker way is to open MMC.EXE, add the Certificates Snap-in, select to manage either the Local Computer or Current User, navigate to the Untrusted Certificates store and Import the certificate there. For wide scale deployment, there are group policy ways to do this, too.

OK, OK, because you asked, here’s a picture of how to do it by GPO:

5-26-2016 4-49-38 PM

UDP and DTLS not a performance improvement.

Saw this update in my Windows Update list recently:

As it stands right now, this is what it says (in part):


OK, so I started off feeling good about this – what’s not to like about the idea that DTLS, a security layer for UDP that works roughly akin to TLS / SSL for TCP, now can be made a part of Windows?

Sure, you could say “what about downstream versions”, but then again, there’s a point where a developer should say “upgrading has its privileges”. I don’t support Windows 3.1 any more, and I don’t feel bad about that.

No, the part I dislike is this one:

Note DTLS provides TLS functionalities that are based on the User Datagram Protocol (UDP) protocol. Because TLS is based on the Transmission Control Protocol (TCP) protocol, DTLS performs better than TLS.


That’s just plain wrong. Actually, I’m not even sure it qualifies as wrong, and it’s quite frankly the sort of mis-statement and outright guff that made me start responding to networking posts in the first place, and which propelled me in the direction of eventually becoming an MVP.


Yes, I was the nerdy guy complaining that there were already too many awful networking applications, and that promulgating stupid myths like “UDP performs better than TCP” or “the Nagle algorithm is slowing your app down, just disable it” causes there to be more of the same.

But I think that’s really the point – you actually do want nerds of that calibre writing your network applications, because network programming is not easy – it’s actually hard. As I have put it on a number of occasions, when you’re writing a program that works over a network, you’re only writing one half of the application (if that). The other half is written by someone else – and that person may have read a different RFC (or a different version of the protocol design), may have had a different interpretation of ambiguous (or even completely clear) sections, or could even be out to destroy your program, your data, your company, and anyone who ever trusted your application.

Surviving in those circumstances requires an understanding of the purity of good network code.

But surely UDP is faster?

Bicycle messengers are faster than the postal service, too. Fast isn’t always what you’re looking for. In the case comparing UDP and TCP, if it was just a matter of “UDP is faster than TCP”, all the world’s web sites would be running on some protocol other than HTTP, because HTTP is rooted in TCP. Why don’t they?

Because UDP repeats packets, loses packets, repeats packets, and first of all, re-orders packets. And when your web delivery over UDP protocol retransmits those lost packets, correctly orders packets, drops repeated packets, and thereby gives you the full web experience without glitches, it’s re-written large chunks of the TCP stack over UDP – and done so with worse performance.

Don’t get me wrong – UDP is useful in and of itself, just not for the same tasks TCP is useful for. UDP is great for streaming audio and video, because you’d rather drop frames or snippets of sound than wait for them to arrive later (as they would do with TCP requesting retransmission, say). If you can afford to lose a few packets here and there in the interest of timely delivery of those packets that do get through, your application protocol is ideally suited to UDP. If it’s more important to occasionally wait a little in order to get the whole stream, TCP will outperform UDP every time.

In summary…

Never choose UDP over TCP because you heard it goes faster.

Choose UDP over TCP because you’d rather have packets dropped at random by the network layer than have them arrive any later than the absolute fastest they can get there.

Choose TCP over UDP because you’d rather have all the packets that were sent, in the order that they were sent, than get most / many / some of them earlier.

And whether you use TCP or UDP, you can now add TLS-style security protection.

I await the arrival of encrypted UDP traffic with some interest.

Immutable Security Laws and Windows Sidebar Gadgets

Immutable Security Law number 1: If a bad guy can persuade you to run his program on your computer, it’s not your computer anymore

I love the Immutable Security Laws – they strike a chord deep within me, and they’re a “go to” resource every time I want to decide if I’m making a good security decision.

I also like my Windows Sidebar Gadgets. Not a whole lot of them, mind you, just one or two that I’ve written myself. And I can’t say that I’ve gone very deep in developing them.

So I’m deeply conflicted when I see “Microsoft Security Advisory (2719662) – Vulnerabilities in Gadgets Could Allow Remote Code Execution” – this seems to be saying that because there are a number of vulnerabilities in common Sidebar Gadgets, you should disable Sidebar Gadgets completely.

But the descriptions I see of Sidebar Gadgets and their security suggest that these Gadgets are exactly like other executables, in terms of the protection you get when running them (essentially, none).

So, in essence, this boils down to “a class of executables that you can download and run are known to have vulnerabilities. So we are disabling that class of executables.” And apparently, this isn’t an architectural flaw in Sidebar Gadgets, because the wording indicates only that a lot of Gadgets have common vulnerabilities – but not all of them.

Can you imagine if the same had been done for, say, Java? If all Java apps were disabled, not because of a flaw in Java, but because many Java developers had written poorly-secured code? What about other frameworks? C++? .NET? PHP?

Uh, yeah, OK, I can see it for PHP. I’m all for disabling PHP on the basis that [almost?] nobody seems able to reliably write secure code using it.

Obviously, I’m writing this from the perspective of someone who hasn’t seen information on the sort of vulnerabilities being described, so it’s entirely possible that there’s an actual architectural weakness that warrants disabling Gadgets completely. I’m just not reading that into what’s been said so far, and I’d like to think that we’re capable of making security decisions on the basis of security truth, rather than some random measure of “disable this framework, because it’s not that important, and many of its developers are writing bad code”.

Clearly I have to wait for the revelation at the BlackHat talk (I’m not going to BlackHat, but I’m on vacation right now – in Vegas) to see what the threat actually is, but I will state up front that I am confused.

2ndAuth released for Windows 7, Windows Server 2008 R2

I’ve given some hints at what we’ve been working on lately, by my choice of article topics.

Credential Providers have been my headache for a couple of months now, not least of which is because Microsoft haven’t quite provided all the working code they ought to have done for Windows Vista. Windows 7, now that works just fine. So that’s what we’re supporting – Windows 7 and Windows Server 2008 R2 (essentially Windows 7 Server) – with our new release of 2ndAuth.

[We’re still supporting 2ndAuth for Windows Server 2003 / Windows XP / Windows 2000, and will be releasing patches, new features and updates as necessary]

To whet your appetite, here’s a screen-shot of 2ndAuth at work on a Windows 7 system:


Notice that when 2ndAuth detects that you’ve selected to log on to a shared user (by a confusing coincidence, this one has a first name of “Shared”, and a last name of “User”), it prompts you for a second authentication (hence the name), which requires that the actual user enter another set of credentials (these should be their own credentials, and shared users cannot vouch for other shared users). This is then written to the Windows Event Log so that you can check who has been accessing which shared accounts and when.

Unauthenticated / failed attempts are also logged, but it’s difficult to say how useful it is to read that, since the failure could be with an invalid user name as much as an invalid password.

Terminal Services / Remote Desktop Connections are supported, too, as well as locking and unlocking the workstation (e.g. handing off to another user part way through a procedure).

The goal here is to acknowledge that sometimes you can’t help using a shared account, and the best thing to do is to provide a mechanism whereby you can discover who is responsible for the use of that account.

I’ll be adding a download link to our products page for 2ndAuth in a little while, but in the meantime, please feel free to ask me any questions about this service – either in the blog comments here, or by email to

Command Line MD5 hash

A colleague asked me the other day what the command-line tool was for calculating MD5 hashes in Windows.

In a moment of sanity, I told him that the usual tool was FCIV, the Microsoft File Checksum Integrity Verifier, but that you had to download it.

Then when he started making fun, and saying that Linux had a command-line tool built in, I went more towards insanity, and suggested the following for him:

[BitConverter]::ToString((new-object Security.Cryptography.MD5CryptoServiceProvider).ComputeHash((new-object IO.FileInfo("c:\windows\explorer.exe")).OpenRead())).Replace("-","").ToLower()

Sure, it’s PowerShell, but that’s been a part of Windows for some while now.

[If you really want to use the example, note that it calculates the hash for the file c:\windows\explorer.exe – change the string to change the file.]

More useful is to create a function:

function MD5 ($a) {[BitConverter]::ToString((new-object Security.Cryptography.MD5CryptoServiceProvider).ComputeHash((new-object IO.FileInfo($a)).OpenRead())).Replace("-","").ToLower();}

Then you can call this with MD5(“c:\windows\calc.exe”) to get a hash of the Calculator.

The meta-lesson

But this does draw out a distinction between operating systems – Linux has an MD5 hash calculator because you are expected to calculate MD5 hashes of files manually on a regular basis. Windows doesn’t have an MD5 hash calculator, because that’s generally done for you. Windows Update will check hashes on files it downloads before it applies them, for instance.

You can learn a lot about an operating system by looking at what is in its default deployment, and what is absent – and why it’s absent (which you can deduce from finding out what you’re supposed to do instead).

The power of stupidity

I just spent a couple of days trying to figure out why logon-related code that worked in Windows XP failed in Windows Vista and Windows 7.

hToken = NULL;
if ( LogonUser( g_sUser, bIsUPN ? NULL : g_sDomain, g_sPass, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken ) )
    // Re-populate the g_sUser and g_sDomain values from the token!
    TOKEN_USER tUser;
    DWORD nLength;
    // Get the user / domain information from the token.
    if (GetTokenInformation(hToken,TokenUser,&tUser,sizeof tUser,&nLength))
        SID_NAME_USE eUse;
        DWORD dwUserSize = _countof(g_sUser);
        DWORD dwDomainSize = _countof(g_sDomain);
            g_sUser, &dwUserSize,
            g_sDomain, &dwDomainSize,

[Note that some error handling has been removed for clarity and brevity.]

So what was going wrong? This totally used to work – it’s designed to validate the username and password, as well as to provide me with the canonical form of the user name.

I had a look through the APIs, and sure enough, there was a more up-to-date version of one of them – LogonUser has a colleague, LogonUserEx, and that function returns the Logon SID as well as verifying the logon works. Cool, I thought, I can get rid of GetTokenInformation, which seems to be failing anyway, and use LogonUserEx.

No dice.

LogonUserEx claimed to be working, and yet LookupAccountSid returned an error, signifying ERROR_NONE_MAPPED (1332 decimal, 0x534 in hex, “No mapping between account names and security IDs was done.”)

A little searching on ERROR_NONE_MAPPED led to a blog post by David LeBlanc, indicating that logon SIDs will cause this error, because they are entirely ephemeral SIDs, used mainly to protect securable items that should not be available to processes running outside of this logon session (and, by the same measure, allowing access to be provided, where appropriate, across different processes in the same logon session).

And then I realised, after a few hours of experimentation, the answer was staring me in the face, in the documentation – LogonUserEx returns the Logon SID in ppLogonSid, which is a Logon SID. Does not have a name, only a SID.

So, that explained the failure of LookupAccountSid with LogonUserEx, and I returned to using LogonUser – which left me with the conundrum of what was failing there.

It often turns out to be the simplest of things.

TOKEN_USER is a structure containing a pointer to the SID. As such, GetTokenInformation has to put the SID somewhere. Cleverly, it asks you to build your TOKEN_USER structure a little bit long, and places the SID at the end of the structure, before setting the pointer in the structure to point to the SID. So, sizeof(TOKEN_USER) is not big enough to pass to a GetTokenInformation call requesting a TokenUser.

The big question is, not why this failed, but why it worked ever at all! I’m not too fussed in finding that answer, because I’ve now changed my code to do it properly, and everything still works – on Windows Vista and XP. But I do feel stupid that debugging this code took me part of Sunday and a little of Monday evening.

Now the code looks like this (again, some error handling has been removed for brevity – don’t skimp in your production code!)

hToken = NULL;
if ( LogonUser( g_sUser, bIsUPN ? NULL : g_sDomain, g_sPass, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken ) )
    SecureZeroMemory(g_sPass,sizeof g_sPass);
    TOKEN_USER *ptUser;
    DWORD nLength;
    GetTokenInformation(hToken, TokenUser, NULL, 0, &nLength);
    ptUser = (TOKEN_USER*)new char[nLength];
    // Get the user / domain information from the token.
    if (GetTokenInformation(hToken,TokenUser,ptUser,nLength,&nLength))
        SID_NAME_USE eUse;
        DWORD dwUserSize = _countof(g_sUser);
        DWORD dwDomainSize = _countof(g_sDomain);
            g_sUser, &dwUserSize,
            g_sDomain, &dwDomainSize,
    delete [] (char *)ptUser;

Note that the fix is to request the length of the TOKEN_USER structure with an initial call to GetTokenInformation, followed by a second call to fill it in.

World IPv6 Day–some likely effects

Are you ignoring IPv6 for the moment, knowing it’s not going to affect you any time soon? I have news for you – you will be significantly affected in the next two months.

It seems that a large fraction of the world is really rather dismissive about the coming of IPv6, which is, after all, the best IPv.

But there are people who are intent on providing a move to the new world, and they’ve geared up to provide a “World IPv6 Day” on which they will be enabling IPv6 on their main sites. (There is an ever-increasing list of participants)

So what is going to happen when some web sites – some big web sites – turn on IPv6 for a day this June? And what will happen when IPv6 is turned on permanently at those sites?

For individuals – “Consumers”

Individual users are probably thinking “someone will make it all work for me” – and some of that is likely true, if you have someone managing your network for you. Your Internet Service Provider will eventually do what they can to provide IPv6 service to your home, and your employer’s IT department is probably thinking in some terms about what to do when they feel like it’s time to deploy IPv6 to the company. But most home routers are not currently able to provide native IPv6 service.

If your cable modem, DSL router, or other entry device is rented to you by the ISP, then you probably have nothing to worry about, they will eventually get replaced to support IPv6, when the ISP is ready to accept IPv6.

If you have bought your own entry device, or other routers (such as a wireless router), you will have to replace it to support IPv6. Don’t run out and get a new router yet – there are no home routers on the market that currently support IPv6 fully – or even enough to consider upgrading for that functionality. Those of us using IPv6 at home are generally using custom software that we have installed, not something the average consumer wants to do.

This means you are stuck on IPv4 for the foreseeable future, although your computer is most likely capable of using IPv6 when connected to a network that supports it. But you will still be affected – see the section below, “For Everyone” for more.

For businesses – management

If you’re not already engaged in some form of IPv6 project, you really should be.

If your IT department are telling you that IPv4 addresses have not run out, ask them “then why are we flailing around behind a NAT, and having to write or purchase software that specifically knows how to make its way out and back through a NAT?”

The fact is, IPv4 addresses ran out years ago, and we’re really only in this last couple of years in a situation where we can deploy IPv6 to fix the problem. Operating Systems for desktops and laptops now support IPv6, and usually have it enabled by default; business-class routers and switches are available with IPv6 support built in, and firmware for some not-so-new devices in that class is available to provide IPv6 support.

More than that, though, you have to make sure that you have staff on-hand who are trained to understand IPv6, because training your staff may be the investment that takes the longest to get right. When you read the section “For Everyone” below, consider what the impact will be to your support centres and to your customers when something breaks. Will you have to explain away broken links, images or even broken pages? [Any site that has previously seen broken pages because of inability to download ads should know how this comes about]

For businesses – IT

If you’re an IT department, you probably have some people on staff who are into new technology – the more they can get, the better. Quite frankly, everyone in an IT department should have something of that feel, or they’re in the wrong team. So, when you get management approval to start down the IPv6 road, it should be a simple matter of asking “who wants it?” and letting people sign up to work on learning the new technology and finding the solutions. Ideally, when your management asks “who’s the IPv6 guy”, you’ll be able to point him out right away.

You should obviously consider a staged roll-out of IPv6 technology, starting with internal networking, to make sure you have an infrastructure that supports it, and only later considering allowing incoming IPv6 to connect to your web site, or to other externally-facing systems.

As a part of enabling routing, make sure that you match, in your IPv6 environment, the protections you already have for IPv4. Do not try to match feature-for-feature, because of features like NAPT, where there is some accidental / incidental security protection from a feature that is essentially unavailable in IPv6. Match protection-for-protection – an IPv4 NAT’s security protection is that it is a firewall with no holes punched in it. So, its IPv6 equivalent protection is a default-deny firewall.

Consider grouping servers into subnets or address ranges based on their use, so that you can configure your firewall using contiguous ranges, rather than individual address assignments. This will make your IPv6 firewall fast – perhaps faster than when operating on its IPv4 rules – and simple.

For everyone

When external sites turn on IPv6, and start resolving their site names to IPv6 addresses as well as IPv4, there will be some users who have poorly-configured IPv6 installations. Their DNS name servers will say “here’s an IPv6 address”, their operating system and web browser will say “I understand IPv6, so let’s connect to that address!”, and some portion of their network will say “huh? What is this, the future or something? I’m still wearing shoulder-pads and leg-warmers and watching Dynasty, because it’s been the 1980s for the last several decades!”

What that user will see is that the IPv6-capable web site just dropped off the Internet. At best, it may simply cause a long delay (several seconds) in reaching the site, as the browser tries – and fails – to connect to IPv6, and then switches to IPv4. At worst, it will cause the big red X to appear, and sites to fail to load completely, as the browser (or other client software) gives up.

You can’t quit the game, either

Fine, so maybe all this means is that those sites who take part in World IPv6 Day will drop off the Internet for a day, to some of their users, and then the next day all will be just perfect.

Not quite.

You see, with “Web 2.0”, everything’s mashed up and interconnected. Google’s everywhere. So are some of the other participants in World IPv6 Day. Each one of those sites being unreachable could affect your favourite mashups, whether you are consumer or service provider. And what is an advertising-laden website if not a mashup of its advertising and its content?

Businesses – what if your adverts fail to load? What about that mapping site you use? Is your technical support ready for an estimated 0.1% of your customers calling in with failures on your site?

Consumers – are you ready to take these errors as a sign that you need to fix your network, or to bug your ISP, or are you going to insist, wrongly, that the problem is with the web sites participating in World IPv6 Day? At least, will you accept that these errors are a necessary part of learning how to move to IPv6?

ISPs – even if you have no plans for IPv6, are you ready for the technical support requests from people who have errors connecting to an IPv6-supporting site?

Quitting, or refusing to take part in the move to IPv6, is not an option. IPv6 will roll out. World IPv6 Day is only the FIRST of many shake-outs that will happen, as sites increasingly add support for IPv6 to their existing IPv4 lineup.

For a preview of what will happen to your machine, try connecting to a system that supports IPv6 and IPv4. The usual example is – it displays a picture of a turtle. The turtle dances for IPv6 users, and sits there doing nothing for IPv4 users (although your browser may choose to display the IPv4 version as its default even if you support IPv6).

If you are one of those rare individuals in an IPv6-capable network island that is unreachable by the IPv6 Internet, you will see an error.

Sadly, with new organisations joining World IPv6 Day every day, you can’t really predict what exactly will break – but you can predict how some of it will break, and train your staff to handle this, whether it is by deploying changes, or simply handling support calls.

I’d love to know what effects you’ve anticipated will come on World IPv6 Day, and what work you’ve done to mitigate these issues.

Starting to build your own Credential Provider

If you’re starting to work on a Credential Provider (CredProv or CP, for short) for Windows Vista, Windows Server 2008, Windows Server 2008 R2 or Windows 7, there are a few steps I would strongly recommend you take, because it will make life easier for you.

0. Read Dan Griffin’s article in MSDN Magazine.

The article, "Create Custom Login Experiences With Credential Providers For Windows Vista" by Dan Griffin in January 2007’s MSDN Magazine on Credential Providers is a truly excellent source of information, gleaned largely by the same exhaustive trial and error effort that you will be engaging in with your own CP.

0.1 Read it again.

0.2 And again, and again and again.

As you work on your CP, you will keep running into questions and new insights as to what it is that Dan was telling you in that article.

Keep a printed copy next to you when developing your CP, so that you can keep looking back to it.

If you have met Dan and asked his permission, keep him on speed-dial.

1. Test your Credential Provider in a Virtual PC environment.

You will screw something up, and when you do, the logon screen will most likely cycle over and over and over (what, Microsoft couldn’t provide a “this Credential Provider has failed eighteen times in a row and will be temporarily disabled” feature?), preventing you from logging back on to change out your broken CP. At this point, you really want to revert back to a previous working session.

To my mind, the easiest way to do this is to create one Virtual PC environment with a base Windows 7 system, patched up to current levels, and with a few test users installed. You can burn an MSDN licence up on this test installation, if you like, but quite frankly, I’m likely to want to refresh it from scratch every so often anyway, so the activation timeout is no big deal.

Once you have created this base image, create another virtual machine, based off the virtual hard disk (VHD) of the base image, and be sure to enable undo disks. This way, when things go wrong, you can shut down this second virtual machine, telling Virtual PC to discard the Undo Disk data, and you will be able to restart the machine immediately and continue to work on it.

2. Enable the kernel debugger against your VM.

This is a little tricky.

2.1 First, edit the settings on your VM.

Enable COM1 to point to a Named Pipe, such as “\\.\pipe\credprov”:


2.2 Now, enable kernel debugging on the VM itself

Log on to the VM, and use the bcdedit tool, from an Administrator Command Prompt to change the debugging option in the boot database. You can go the long way around, reading Microsoft’s instructions on how to do this, or you can simply use the following two commands:

bcdedit /dbgsettings serial debugport:1

bcdedit /debug {current} on


Notice that Microsoft suggests creating a separate environment for debugging on and off, but I don’t see that as being terribly useful. I will always be debugging this test environment, and it really doesn’t slow me down that much. You can always use “bcdedit /debug {current} off” to turn debugging off later.

This setting will take effect at the next reboot of the VM, but don’t reboot yet.

2.3 Enable the Debug Output Filter so OutputDebugString works.

Windows Vista and later don’t output debug messages to the kernel debugger by default. Those messages are filtered. You can spend a lot of time trying to figure out why you are staring at a blank screen when you have filled your code with OutputDebugString and/or TRACE calls. Or you can change the registry entry that controls the Output Debug Filter:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter\DEFAULT

Create the “Debug Print Filter” value, if it isn’t there, and then create the DEFAULT value as a DWORD, and set it to the value 8.


2.4 Save these settings

Since you’ll want these settings to come back after a restart, you’ll want to commit them to the VHD. Easily done, but takes some time. Shut down the VM, and when you are prompted what you want to do, select that you wish to commit changes to the virtual hard disk.


Expect this to take several long minutes. While you do that, go read Dan’s article again.

2.5 Create a shortcut to the debugger

I use WinDBG (is that pronounced “Windbag”?), and the shortcut I use points to:

"C:\Program Files\Debugging Tools for Windows (x64)\windbg.exe" -k com:port=\\.\pipe\credprov,baud=115200,pipe,reconnect,resets=10

Remember to start the VM before starting the WinDBG shortcut, so that the VM has a pipe for WinDbg to connect to.

3. Start from the CredProv samples

Play around with the credential provider sample, or samples, that are closest to your eventual design goal, and add features to move them towards your desired end-state, rather than building your own from scratch.

Don’t just play with the one sample – looking at, or testing, the other samples may give you a little more insight that you didn’t get from the sample you’re working with.

3.1 Build often, and test frequently

Random errors and occasional misunderstandings (“gee, I didn’t realise you can’t call SetFieldString from GetStringValue”) will cause you to crash often. A crash in your CP means an infinite loop, and some inventive use of Anglo-Saxon.

Building often, testing frequently, and backing out disastrous changes (use version control if you have it!) will lead to a better process.

3.2 Later, build your own CP

Once you have a good understanding of the Credential Provider and its mysterious ways, you may decide to throw out Microsoft’s code and build your own from scratch. Keep comparing against your modified sample to see why it isn’t working.

3.3 Before deployment, change the GUID!

The GUIDs used by the sample code are well-known, and will tie in some systems to other, more shoddy, developers’ versions of those samples. If you forget to change the GUID on your code, you will have a CP-fight.

4. Go back to Dan’s article every time you reach a bottleneck

Occasionally a twist of phrase, or a reinterpretation of a paragraph is all it takes to wring some more useful knowledge out of this article. Don’t forget to use the online help Microsoft provides, as well as searching the MSDN, but remember that this is not a very frequently-trod path. It may be that you are doing something the credential provider architects didn’t consider. In fact, it’s highly likely.

5. Stop mailing

Nobody monitors that email address any more, and there seems to be something of a black hole associated with questions related to Credential Providers in general. It’s as if nobody really truly understands them. A few of the MVPs (particularly Dan Griffin, Dana Epp, and perhaps myself) have a good understanding, so read their blogs, and perhaps post to the Microsoft Forums, if you can manage to do so.

6. Enumerate, and test, the scenarios your customers might run into

  • domain-joined and non-domain
  • administrator, non-administrator, guest
  • with and without user names being supplied (Secpol.msc –> Local Policies –> Security Options –> Interactive Logon: Do not display last user name)
  • default domain, other domain, local accounts
  • logon, switch user, unlock workstation, access from Remote Desktop Connection / MSTSC (as we old-timers call it)
  • change password
  • If you’re of a mind, test the credential user interface mode, too.

Weird virus / anti-virus behaviour

My wife and I pent a while this weekend trying to figure out how to rescue a Media Center that seemed to be going a little loopy.

The Windows Media Center application itself worked fine, as did Windows Media Player, Calc, etc.

Only Internet Explorer was failing.


If you press Ctrl-C from most Windows dialog boxes like the one above, it will copy the text of the dialog into the clipboard.

Here’s what I get if I do that (this is mostly aimed at people using search engines):

[Window Title]
C:\Program Files (x86)\Internet Explorer\iexplore.exe

C:\Program Files (x86)\Internet Explorer\iexplore.exe

The parameter is incorrect.


[Had the Media Center been on 32-bit Windows, those paths would simply be “C:\Program Files\Internet Explorer\iexplore.exe” – the error message would still be “The parameter is incorrect”]

So, what on earth does this mean?

It seems bizarre, partly because there isn’t a parameter I’m supplying to Internet Explorer, but mostly because it gives me chills whenever Internet Explorer dies so quickly – I’ve seen so many viruses that disable Internet Explorer (so you can’t download a fix), that an IE issue like this sends a shiver down my spine.

My wife had the first go at fixing this, trying not only removing and re-adding IE as a Windows Feature (in “Turn Windows Features On or Off”), but also reinstalling Windows 7 on top of itself, as a repair. No fix.

Meanwhile, I downloaded Mozilla Firefox and Google Chrome on a different computer, moved them over to this one, and installed them each.

Both of them, when I tried to run, came up with the same “The parameter is incorrect” message. Worrisome.

I fire up Regedit, which is almost always also disabled by viruses that want you not to fix them. Strangely enough, that works – but I’m not done with my virus theory.

I updated Microsoft’s Security Essentials – which is already running on this system. A Quick Scan finds nothing. Trend Micro’s HouseCall is another “download and run this” virus scanner, much like the Microsoft Malicious Software Removal Tool, which arrives monthly with your Windows Updates.

Still nothing detected.

I get by with a little help from my friends

Fortunately, my friend and fellow MVP, Susan Bradley, is online, and although I don’t think she has the bandwidth to answer everyone’s questions, I think I’m rather special, so I call on her time to see if she has any suggestions.

“try” she asks.

Sure enough, I hadn’t, and I know that several of the Consumer Security MVPs swear by it. So I download it and run it.

It finds four infections (I never get excited about the number of infections these tools find, because some of them are really aggressive as to what they think are “infections” – I’m one of those strange people that thinks tracking cookies are “mostly harmless”).

Reviewing what they are, I can see exactly how the behaviour comes about, but I’m still at a little of a loss as to how that happened.

The four entries it finds are under Registry settings, in the registry tree HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options, and under keys called “iexplore.exe”, “chrome.exe”, “firefox.exe” and “opera.exe” (Opera is another browser you can download).

The value, in each case, is as follows (using RegEdit to see):


The value name is “Debugger”, and although you can’t see it clearly there, the value is “ -sb” – that is a single space, followed, by a hyphen, and the two letters “sb”.

This is a variation on a classic method for killing Internet Explorer – or rather, for sidelining it, or prepending it with your own code. The functionality has a good purpose – for developers who want to run their debugger every time they open an application. I use it a lot myself.

I haven’t seen anyone do exactly this, though – it seems like they screwed up somehow.

The Fix

Fixing this is really simple. You just have to remove the value named “Debugger” from that key. Watch that you don’t make other changes, in case those cause other behaviours you don’t want. Oh, and do this as an administrator, or you won’t actually make any changes.

In my case, since this was the only value in the key for Internet Explorer, Firefox, Chrome and Opera, I deleted the keys themselves, just to be safe.

No reboot required – suddenly, I can start up my browsers – all of them. Thank you, Susan, and thank you, MalwareBytes!

The cause?

I’m always keen to find the cause of issues like this – especially since this could still be a virus that caused this, and if it is, I think the Microsoft Security Essentials team would like to know about it.

Searching leads repeatedly to the same possible target – a ROGUE antivirus program, which calls itself “AVG Antivirus 2011”, but which actually has nothing to do with the real AVG Antivirus. I’ve heard of this before, and I’ve seen it at a couple of sites I’ve visited for “research purposes”, but each time I’ve simply closed down IE before it had a chance to run its alleged scan.

[Hint: no web site should be scanning your computer and finding viruses. If a web site says it’s found a virus, it’s referring to the one it’s about to install on your system.]

So, it could have been me, it could have been a family member – but no real harm done. My guess is that it started to install itself, and Microsoft Security Essentials started to remove it, but didn’t quite manage to complete the job. That’s just a guess. I don’t have nearly the resources or the interest to try and re-stage the incident to test! I’m putting this blog entry out in the hope that it’ll be a search engine hit when someone else runs into the same issues.

Messing around with audio files

It’s Memorial Day weekend, so we’re doing a little relaxing.

What’s relaxing for me? Playing around with interesting random bits of code.

iFetch – suddenly slow

One piece of code that’s been interesting for a while, and very useful, is the iFetch program, which I use to download BBC Radio so that I can listen to it on my MP3 player on the bus. The iPlayer is nice, and all, but I can’t access it without an Internet connection, and the bus doesn’t have an Internet connection yet.

Lately, it seems like practically every show I’m fetching is coming down in WMA format. That wouldn’t generally be so bad, except that the WMA format streams at real-time using MPlayer, whereas the other formats stream as fast as the Internet can send them.

There’s a reason why I can only download WMAs now – the BBC recently made the choice to keep to only those formats that they feel they can adequately add DRM to. Which seriously limits your options as to what devices you can play it on. (Does that iPad do Flash? No. Does it do WMA? No idea.)

I haven’t yet figured out why there’s such a slowdown with WMAs in MPlayer, so if any readers have any ideas, please let me know.

Editing MP3 tags

Since I was unable to do much about the WMA slowness, I thought I’d look into what I can do about the MP3 files I’ve already collected – organising them by genre, broadcast date, etc.

So I looked into what I can do with MP3 tags.

Windows comes with the Windows Media Format SDK, which I thought I’d use. I’ve previously used it to set various values such as Title, Author, etc. Today’s game was to try and expand on that a little. One thing I wanted to look into was the use of various date fields. Date of recording, date of encoding – those seemed to be appropriate values.

The function to use is IWMHeaderInfo3::AddAttribute, but it just wouldn’t work for me. First I tried to use the “ID3/TDRC” tag. No dice. AddAttribute gives me error 0xc00d002b – that’s NS_E_INVALID_REQUEST. So I tried ID3/TDEN – again, c00d002b. That error is supposed to mean that I entered the wrong stream index – but I used stream zero, which is supposed to mean “this tag applies to the entire file”.

Perhaps the function doesn’t accept the ID3 tag names, and only accepts the WMA tag names, even though this is strictly an MP3 file that I’m working with.

No problem.

Next to try is WM/EncodingTime, which is supposed to translate to ID3/TDEN. No longer do I get NS_E_INVALID_REQUEST. No, this time I get 0xc00d0bd7 – NS_E_ATTRIBUTE_NOT_ALLOWED. Why not allowed? No idea. Perhaps the WMF SDK (WTF SDK, sometimes) thinks that the EncodingTime should only be set by the process that does the encoding? I kind of disagree with that, and clearly because I have so many files without the EncodingTime value set, it’s not the case that it gets set by the encoding tool. I tried various different settings – as a string, as a QWORD, even as binary, and didn’t really get anywhere.

Again, does anyone know how this should work?

A couple of other Zune notes

Finally, what’s new to complain about on the Zune?

Not much – I still really really like the device itself. A couple of minor issues that I am sure Microsoft could fix if they weren’t so busy getting rid of the people in charge of the Zune:

  • Why does the Zune list Podcasts in a different order from the Zune software?
    • Why can’t you make one match the other?
    • For what I mean, try putting MP3 files on your system with these titles: “(A grand time)”, “A boatload”, “The ark”. The Zune displays them “The Ark”, “A boatload”, “(A grand time)” – the PC displays them as “(A grand time)”, “A boatload”, “The ark”.
  • A few more apps wouldn’t go amiss.
  • Seriously, next device – put Bluetooth in the box.
  • Add some cards that read “Thank you for asking – it’s a Zune, and yes, it really is this good, and it really is from Microsoft. More details at”, so that I can hand them out.