The Most Complex SAL annotation

While working on "Writing Secure Code for Windows Vista" I spent a good deal of time spelunking the new crypto stuff, CNG.

One of the APIs is BCryptResolveProviders, and the last argument is pretty complex:

  • If you pass NULL, it fails and tells you the amount of space required.
  • If you pass a pointer to NULL it allocates the space for you.
  • If you pass a pointer to a buffer it tries to use that space.

In my opinion, this really should have been a couple of function calls, rather than one, I'm not a fan of functions with complex arguments. But that's just me.

But this got me thinking, if this is a new API, and the we're using SAL all over the place, then this argument must be annotated, right? Indeed it is. I open up bcrypt.h, and here is the function prototype, including SAL annotations.

NTSTATUS WINAPI

BCryptResolveProviders(

    __in_opt LPCWSTR pszContext,

    __in_opt ULONG dwInterface,

    __in_opt LPCWSTR pszFunction,

    __in_opt LPCWSTR pszProvider,

    __in ULONG dwMode,

    __in ULONG dwFlags,

    __inout ULONG* pcbBuffer,

     __deref_opt_inout_bcount_part_opt(*pcbBuffer, *pcbBuffer) PCRYPT_PROVIDER_REFS *ppBuffer);

I had one of the SAL architects review it, and it's correct!