Credential Provider update–Windows 8 SDK breaks a few things…

You’ll recall that back in February of 2011, I wrote an article on implementing your first Credential Provider for Windows 7 / 8 / Server 2008 R2 / Server 2012 – and it’s been a fairly successful post on my blog.

Just recently, I received a report from one of my users that my version of this was no longer wrapping the password provider on Windows Server 2008 R2.

As you’ll remember from that earlier article, it’s a little difficult (but far from impossible) to debug your virtual machine to get information out of the credential provider while it runs.

Just not getting called

Nothing seemed to be obviously wrong, the setup was still executing the same way, but the code just wasn’t getting called. For the longest time I couldn’t figure it out.

Finally, I took a look at the registry entries.

My code was installing itself to wrap the password provider with CLSID “{60b78e88-ead8-445c-9cfd-0b87f74ea6cd}”, but the password provider in Windows Server 2008 R2 appeared to have CLSID “{6f45dc1e-5384-457a-bc13-2cd81b0d28ed}”. Subtle, to be sure, but obviously different.

I couldn’t figure out immediately why this was happening, but I eventually traced back through the header files where CLSID_PasswordCredentialProvider was defined, and found the following:

   1: EXTERN_C const CLSID CLSID_PasswordCredentialProvider;


   2:  


   3: #ifdef __cplusplus


   4:  


   5: class DECLSPEC_UUID("60b78e88-ead8-445c-9cfd-0b87f74ea6cd") 


   6: PasswordCredentialProvider; 


   7: #endif


   8:  


   9: EXTERN_C const CLSID CLSID_V1PasswordCredentialProvider;


  10:  


  11: #ifdef __cplusplus


  12:  


  13: class DECLSPEC_UUID("6f45dc1e-5384-457a-bc13-2cd81b0d28ed") 


  14: V1PasswordCredentialProvider; 


  15: #endif 


  16:  

As you can see, in addition to CLSID_PasswordCredentialProvider, there’s a new entry, CLSID_V1PasswordCredentialProvider, and it’s this that points to the class ID that Windows Server 2008 R2 uses for its password credential provider – and which I should have been wrapping with my code.

The explanation is obvious

It’s clear what happened here with a little research. For goodness-only-knows-what-unannounced-reason, Microsoft chose to change the class ID of the password credential provider in Windows 8 and Windows Server 2012. And, to make sure that old code would continue to work in Windows 8 with just a recompile, of course they made sure that the OLD name “CLSID_PasswordCredentialProvider” would point to the NEW class ID value. And, as a sop to those of us supporting old platforms, they gave us a NEW name “CLSID_V1PasswordCredentialProvider” to point to the OLD class ID value.

And then they told nobody, and included it in Visual Studio 2012 and the Windows 8 SDK.

In fact, if you go searching for CLSID_V1PasswordCredentialProvider, you’ll find there’s zero documentation on the web at all. That’s pretty much unacceptable behaviour, introducing a significantly breaking change like this without documentation.

So, how to support both values?

Supporting both values requires you to try and load each class in turn, and save details indicating which one you’ve loaded. I went for this rather simple code in SetUsageScenario:

   1: IUnknown *pUnknown = NULL;


   2: _pWrappedCLSID = CLSID_PasswordCredentialProvider;


   3: hr = ::CoCreateInstance(CLSID_PasswordCredentialProvider, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pUnknown));


   4: if (hr == REGDB_E_CLASSNOTREG)


   5: {


   6:     _pWrappedCLSID = CLSID_V1PasswordCredentialProvider;


   7:     hr = ::CoCreateInstance(CLSID_V1PasswordCredentialProvider, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pUnknown));


   8: }

Pretty bone-dead simple, I hope you’ll agree – the best code often is.

Of course, if you’re filtering on credential providers, and hope to hide the password provider, you’ll want to filter both providers there, too. Again, here’s my simple code for that in Filter:

   1: if (IsEqualGUID(rgclsidProviders[i], CLSID_PasswordCredentialProvider))


   2:     rgbAllow[i]=FALSE;


   3: if (IsEqualGUID(rgclsidProviders[i], CLSID_V1PasswordCredentialProvider))


   4:     rgbAllow[i]=FALSE;



If that wasn’t nasty enough…



Ironically, impacting the Windows XP version of the same package (which uses a WinLogon Notification Provider, instead of a Credential Provider), another thing that the Windows 8 SDK and Visual Studio 2012 did for me is that it disabled the execution of my code on Windows XP.



This time, they did actually say something about it, though, which allowed me to trace and fix the problem just a little bit more quickly.



The actual blog post (not official documentation, just a blog post) that describes this change is here:



Windows XP Targeting with C++ in Visual Studio 2012



What this blog indicates is that a deliberate step was taken to disable Windows XP support in executables generated by Visual Studio 2012. You have to go back and make changes to your projects in order to continue supporting Windows XP.



That’s not perhaps so bad, because really, Windows XP is pretty darn old. In fact, in a year from now it’ll be leaving its support lifecycle, and heading into “Extended Support”, where you have to pay several thousand dollars for every patch you want to download. I’d upgrade to Windows 7 now, if I were you.

2 thoughts on “Credential Provider update–Windows 8 SDK breaks a few things…”

  1. hi,

    thanks for giving information on credential provider ,but i don’t understand
    _pWrappedCLSID = CLSID_PasswordCredentialProvider;

    where i have to replace _pWrappedCLSID variable
    please tell me

    thanks in advance

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>