WinRT CryptographicBufferStatics

#include <Windows.h>
#include <roapi.h>
#include <winstring.h>

#pragma comment(lib, "runtimeobject.lib")

typedef GUID IID;

enum BinaryStringEncoding : int
{
    BinaryStringEncoding_Utf8 = 0,
    BinaryStringEncoding_Utf16LE = 1,
    BinaryStringEncoding_Utf16BE = 2,
};

MIDL_INTERFACE("905a0fe0-bc53-11df-8c49-001e4fc686da")
IBuffer : public IInspectable
{
public:
    virtual HRESULT STDMETHODCALLTYPE get_Capacity(PUINT32) = 0;
    virtual HRESULT STDMETHODCALLTYPE get_Length(PUINT32) = 0;
    virtual HRESULT STDMETHODCALLTYPE put_Length(UINT32) = 0;
};
const __declspec(selectany) IID& IID_IBuffer = __uuidof(IBuffer);

MIDL_INTERFACE("320b7e22-3cb0-4cdf-8663-1d28910065eb")
ICryptographicBufferStatics : public IInspectable
{
public:
    virtual HRESULT STDMETHODCALLTYPE Compare(IBuffer*, IBuffer*, PBYTE) = 0;
    virtual HRESULT STDMETHODCALLTYPE GenerateRandom(UINT32, IBuffer**) = 0;
    virtual HRESULT STDMETHODCALLTYPE GenerateRandomNumber(PUINT32) = 0;
    virtual HRESULT STDMETHODCALLTYPE CreateFromByteArray(UINT32, PBYTE, IBuffer**) = 0;
    virtual HRESULT STDMETHODCALLTYPE CopyToByteArray(IBuffer*, PUINT32, PBYTE*) = 0;
    virtual HRESULT STDMETHODCALLTYPE DecodeFromHexString(HSTRING, IBuffer**) = 0;
    virtual HRESULT STDMETHODCALLTYPE EncodeToHexString(IBuffer*, HSTRING*) = 0;
    virtual HRESULT STDMETHODCALLTYPE DecodeFromBase64String(HSTRING, IBuffer**) = 0;
    virtual HRESULT STDMETHODCALLTYPE EncodeToBase64String(IBuffer*, HSTRING*) = 0;
    virtual HRESULT STDMETHODCALLTYPE ConvertStringToBinary(HSTRING, BinaryStringEncoding, IBuffer**) = 0;
    virtual HRESULT STDMETHODCALLTYPE ConvertBinaryToString(BinaryStringEncoding, IBuffer*, HSTRING*) = 0;
};
const __declspec(selectany) IID& IID_ICryptographicBufferStatics = __uuidof(ICryptographicBufferStatics);

DWORD Win32FromHResult(_In_ HRESULT Result)
{
	if ((Result & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0))
		return HRESULT_CODE(Result);

	if (Result == S_OK)
		return ERROR_SUCCESS;

	return ERROR_CAN_NOT_COMPLETE;
}

SIZE_T StringLengthW(_In_ LPCWSTR String)
{
	LPCWSTR String2;

	for (String2 = String; *String2; ++String2);

	return (String2 - String);
}

INT main(VOID)
{
	HRESULT Result = S_OK;
	HSTRING Class = NULL;
	ICryptographicBufferStatics* Statics = NULL;
  UINT32 Random = 0;

	Result = RoInitialize(RO_INIT_MULTITHREADED);
	if (!SUCCEEDED(Result))
		return Win32FromHResult(Result);

	Result = WindowsCreateString(L"Windows.Security.Cryptography.CryptographicBuffer", (UINT32)StringLengthW(L"Windows.Security.Cryptography.CryptographicBuffer"), &Class);
	if (!SUCCEEDED(Result) || Class == NULL)
		goto EXIT_ROUTINE;
	
    Result = RoGetActivationFactory(Class, __uuidof(ICryptographicBufferStatics), (PVOID*)&Statics);
    if (!SUCCEEDED(Result))
        goto EXIT_ROUTINE;

    Result = Statics->GenerateRandomNumber(&Random);
    if (!SUCCEEDED(Result))
        goto EXIT_ROUTINE;

EXIT_ROUTINE:

    if (Class)
        WindowsDeleteString(Class);

    if(Statics)
        Statics->Release();

	  RoUninitialize();

    return (!SUCCEEDED(Result) ? Win32FromHResult(Result) : ERROR_SUCCESS);
}

Last updated