SCODE GadgetProvider::CreateInstanceEnumAsync(
    const BSTR className,
    long flags,
    IWbemContext* context,
    IWbemObjectSink FAR* handler)
{
    // Check credentials:

    HRESULT hr = CoImpersonateClient();

    if (FAILED(hr))
    {
        handler->SetStatus(0, hr, NULL, NULL);
        return hr;
    }

    if (_impersonateLevel() < RPC_C_IMP_LEVEL_IMPERSONATE)
    {
        CoRevertToSelf();
        hr = WBEM_E_ACCESS_DENIED;
        handler->SetStatus(0, hr, NULL, NULL);
        return hr;
    }

    // Check parameters:

    if (!handler || !_nameSpace)
    {
        return WBEM_E_INVALID_PARAMETER;
    }

    if (_equal(className, L"Gadget"))
    {
        for (size_t i = 0; i < _numDefs; i++)
        {
            IWbemClassObject FAR* newInstance = NULL;

            SCODE sc = _makeGadget(
                _nameSpace,
                _defs[i].key,
                _defs[i].value,
                &newInstance,
                className,
                context);

            if (sc != S_OK)
            {
                handler->SetStatus(0,sc,NULL, NULL);
                return sc;
            }

            handler->Indicate(1, &newInstance);
            newInstance->Release();
        }
    }

    // Set status

    handler->SetStatus(0, S_OK, NULL, NULL);
    return S_OK;
}
/*static*/ bool VirtualBoxSDS::i_getClientUserSid(com::Utf8Str *a_pStrSid, com::Utf8Str *a_pStrUsername)
{
    bool fRet = false;
    a_pStrSid->setNull();
    a_pStrUsername->setNull();

    CoInitializeEx(NULL, COINIT_MULTITHREADED); // is this necessary?
    HRESULT hrc = CoImpersonateClient();
    if (SUCCEEDED(hrc))
    {
        HANDLE hToken = INVALID_HANDLE_VALUE;
        if (::OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE /*OpenAsSelf*/, &hToken))
        {
            CoRevertToSelf();

            union
            {
                TOKEN_USER  TokenUser;
                uint8_t     abPadding[SECURITY_MAX_SID_SIZE + 256];
                WCHAR       wszUsername[UNLEN + 1];
            } uBuf;
            RT_ZERO(uBuf);
            DWORD cbActual = 0;
            if (::GetTokenInformation(hToken, TokenUser, &uBuf, sizeof(uBuf), &cbActual))
            {
                WCHAR *pwszString;
                if (ConvertSidToStringSidW(uBuf.TokenUser.User.Sid, &pwszString))
                {
                    try
                    {
                        *a_pStrSid = pwszString;
                        a_pStrSid->toUpper(); /* (just to be on the safe side) */
                        fRet = true;
                    }
                    catch (std::bad_alloc &)
                    {
                        LogRel(("i_GetClientUserSID: std::bad_alloc setting rstrSid.\n"));
                    }
                    LocalFree((HLOCAL)pwszString);

                    /*
                     * Get the username too.  We don't care if this step fails.
                     */
                    if (fRet)
                    {
                        WCHAR           wszUsername[UNLEN * 2 + 1];
                        DWORD           cwcUsername = RT_ELEMENTS(wszUsername);
                        WCHAR           wszDomain[UNLEN * 2 + 1];
                        DWORD           cwcDomain = RT_ELEMENTS(wszDomain);
                        SID_NAME_USE    enmNameUse;
                        if (LookupAccountSidW(NULL, uBuf.TokenUser.User.Sid, wszUsername, &cwcUsername,
                                              wszDomain, &cwcDomain, &enmNameUse))
                        {
                            wszUsername[RT_ELEMENTS(wszUsername) - 1] = '\0';
                            wszDomain[RT_ELEMENTS(wszDomain) - 1] = '\0';
                            try
                            {
                                *a_pStrUsername = wszDomain;
                                a_pStrUsername->append('/');
                                a_pStrUsername->append(Utf8Str(wszUsername));
                            }
                            catch (std::bad_alloc &)
                            {
                                LogRel(("i_GetClientUserSID: std::bad_alloc setting rStrUsername.\n"));
                                a_pStrUsername->setNull();
                            }
                        }
                        else
                            LogRel(("i_GetClientUserSID: LookupAccountSidW failed: %u/%x (cwcUsername=%u, cwcDomain=%u)\n",
                                   GetLastError(), cwcUsername, cwcDomain));
                    }
                }
                else
                    LogRel(("i_GetClientUserSID: ConvertSidToStringSidW failed: %u\n", GetLastError()));
            }
            else
                LogRel(("i_GetClientUserSID: GetTokenInformation/TokenUser failed: %u\n", GetLastError()));
            CloseHandle(hToken);
        }
        else
        {
            CoRevertToSelf();
            LogRel(("i_GetClientUserSID: OpenThreadToken failed: %u\n", GetLastError()));
        }
    }
    else
        LogRel(("i_GetClientUserSID: CoImpersonateClient failed: %Rhrc\n", hrc));
    CoUninitialize();
    return fRet;
}