VBoxCredProv.cpp revision dee9dd86962066a952b5343dc01f59328f532138
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end//
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd// PARTICULAR PURPOSE.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end//
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end//
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end// Modifications (c) 2009-2010 Oracle Corporation
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc//
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end#include <credentialprovider.h>
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
2e545ce2450a9953665f701bb05350f0d3f26275nd#include <iprt/err.h>
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen#include <VBox/VBoxGuestLib.h>
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end#include "VBoxCredProv.h"
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end#include "VBoxCredential.h"
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen#include "guid.h"
3f08db06526d6901aa08c110b5bc7dde6bc39905nd
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1endVBoxCredProv::VBoxCredProv(void) :
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_cRef(1),
3f08db06526d6901aa08c110b5bc7dde6bc39905nd m_pPoller(NULL),
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCred(NULL),
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCredProvEvents(NULL),
053bfa8a288528fafab2b7a032c15116bb5de711nd m_fGotCredentials(false)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end{
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end LONG l = DllAddRef();
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end int rc = RTR3Init(); /* Never terminate the runtime! */
253547fb9cc7986e84ff68aef076f664fc4169dctakashi if (RT_FAILURE(rc))
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end LogRel(("VBoxCredProv: Could not init runtime! rc = %Rrc\n", rc));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end rc = VbglR3Init();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (RT_FAILURE(rc))
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end LogRel(("VBoxCredProv: Could not init guest library! rc = %Rrc\n", rc));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (l == 1) /* First instance? */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end LogRel(("VBoxCredProv: Loaded.\n"));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Log(("VBoxCredProv: DLL refcount (load) = %ld\n", l));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end}
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedoohVBoxCredProv::~VBoxCredProv(void)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end{
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Log(("VBoxCredProv::~VBoxCredProv\n"));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (m_pCred != NULL)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCred->Release();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCred = NULL;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (m_pPoller != NULL)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pPoller->Shutdown();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end delete m_pPoller;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pPoller = NULL;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end LONG lRefCount = DllGetRefCount();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (lRefCount == 1) /* First (=last) instance unloaded? */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end LogRel(("VBoxCredProv: Unloaded.\n"));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Log(("VBoxCredProv: DLL refcount (unload) = %ld\n", lRefCount));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end VbglR3Term();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end DllRelease();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end}
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end/*
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * SetUsageScenario is the provider's cue that it's going to be asked for tiles
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * in a subsequent call. This call happens after the user pressed CTRL+ALT+DEL
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * and we need to handle the CPUS_LOGON event.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1endHRESULT VBoxCredProv::SetUsageScenario(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpUsageScenario,
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end DWORD dwFlags)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end{
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end UNREFERENCED_PARAMETER(dwFlags);
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end HRESULT hr;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_cpUsageScenario = cpUsageScenario;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end /* Decide which scenarios to support here. Returning E_NOTIMPL simply tells the caller
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * that we're not designed for that scenario. */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end switch (m_cpUsageScenario)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end case CPUS_LOGON:
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end case CPUS_UNLOCK_WORKSTATION:
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (m_pPoller == NULL)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pPoller = new VBoxCredPoller();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Assert(m_pPoller);
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (false == m_pPoller->Initialize(this))
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Log(("VBoxCredProv::SetUsageScenario: Could not initialize credentials poller thread!\n"));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (m_pCred == NULL)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCred = new VBoxCredential(this);
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end /* All stuff allocated? */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (m_pCred != NULL)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end hr = m_pCred->Initialize(m_cpUsageScenario,
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end s_rgCredProvFieldDescriptors,
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end s_rgFieldStatePairs);
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end else
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end hr = E_OUTOFMEMORY;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Log(("VBoxCredProv::SetUsageScenario: Out of memory!\n"));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end else
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end /* All set up already! */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end hr = S_OK;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end /* If we did fail -> cleanup */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (FAILED(hr))
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end if (m_pCred != NULL)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end {
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCred->Release();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCred = NULL;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end break;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end case CPUS_CHANGE_PASSWORD:
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end case CPUS_CREDUI:
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end case CPUS_PLAP:
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end hr = E_NOTIMPL;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end break;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end default:
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end hr = E_INVALIDARG;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end break;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end }
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end Log(("VBoxCredProv::SetUsageScenario returned 0x%08x (cpUS: %d, Flags: %ld)\n", hr, cpUsageScenario, dwFlags));
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end return hr;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end}
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end/*
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * SetSerialization takes the kind of buffer that you would normally return to LogonUI for
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * an authentication attempt. It's the opposite of ICredentialProviderCredential::GetSerialization.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * GetSerialization is implement by a credential and serializes that credential. Instead,
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * SetSerialization takes the serialization and uses it to create a credential.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end *
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * SetSerialization is called for two main scenarios. The first scenario is in the credUI case
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * where it is prepopulating a tile with credentials that the user chose to store in the OS.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * The second situation is in a remote logon case where the remote client may wish to
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * prepopulate a tile with a username, or in some cases, completely populate the tile and
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * use it to logon without showing any UI.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end */
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1endSTDMETHODIMP VBoxCredProv::SetSerialization(const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpCredentialSerialization)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end{
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end UNREFERENCED_PARAMETER(pcpCredentialSerialization);
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end return E_NOTIMPL;
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end}
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end/*
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * Called by LogonUI to give you a callback. Providers often use the callback if they
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * some event would cause them to need to change the set of tiles (visible UI elements)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end * that they enumerated.
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end */
053bfa8a288528fafab2b7a032c15116bb5de711ndHRESULT VBoxCredProv::Advise(ICredentialProviderEvents *pcpEvents,
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end UINT_PTR upAdviseContext)
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end{
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung Log(("VBoxCredProv::Advise\n"));
727872d18412fc021f03969b8641810d8896820bhumbedooh
0d0ba3a410038e179b695446bb149cce6264e0abnd if (m_pCredProvEvents != NULL)
727872d18412fc021f03969b8641810d8896820bhumbedooh m_pCredProvEvents->Release();
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh
0d0ba3a410038e179b695446bb149cce6264e0abnd m_pCredProvEvents = pcpEvents;
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh Assert(m_pCredProvEvents);
727872d18412fc021f03969b8641810d8896820bhumbedooh m_pCredProvEvents->AddRef();
0d0ba3a410038e179b695446bb149cce6264e0abnd
0d0ba3a410038e179b695446bb149cce6264e0abnd /*
0d0ba3a410038e179b695446bb149cce6264e0abnd * Save advice context for later use when binding to
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh * certain ICredentialProviderEvents events.
0d0ba3a410038e179b695446bb149cce6264e0abnd */
0d0ba3a410038e179b695446bb149cce6264e0abnd m_upAdviseContext = upAdviseContext;
0d0ba3a410038e179b695446bb149cce6264e0abnd return S_OK;
727872d18412fc021f03969b8641810d8896820bhumbedooh}
0d0ba3a410038e179b695446bb149cce6264e0abnd
0d0ba3a410038e179b695446bb149cce6264e0abnd
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh/* Called by LogonUI when the ICredentialProviderEvents callback is no longer valid. */
205f749042ed530040a4f0080dbcb47ceae8a374rjungHRESULT VBoxCredProv::UnAdvise()
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen{
0d0ba3a410038e179b695446bb149cce6264e0abnd Log(("VBoxCredProv::UnAdvise\n"));
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd if (m_pCredProvEvents != NULL)
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd {
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd m_pCredProvEvents->Release();
63f06dce77bb2d9b1c5aa5deeb47a1069987fd1end m_pCredProvEvents = NULL;
}
return S_OK;
}
/*
* Called by LogonUI to determine the number of fields in your tiles. This
* does mean that all your tiles must have the same number of fields.
* This number must include both visible and invisible fields. If you want a tile
* to have different fields from the other tiles you enumerate for a given usage
* scenario you must include them all in this count and then hide/show them as desired
* using the field descriptors.
*/
HRESULT VBoxCredProv::GetFieldDescriptorCount(DWORD *pdwCount)
{
Assert(pdwCount);
*pdwCount = SFI_NUM_FIELDS;
Log(("VBoxCredProv::GetFieldDescriptorCount: %ld\n", *pdwCount));
return S_OK;
}
/* Gets the field descriptor for a particular field. */
HRESULT VBoxCredProv::GetFieldDescriptorAt(DWORD dwIndex,
CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **ppcpFieldDescriptor)
{
/* Verify dwIndex is a valid field */
HRESULT hr;
if ( dwIndex < SFI_NUM_FIELDS
&& ppcpFieldDescriptor)
{
hr = FieldDescriptorCoAllocCopy(s_rgCredProvFieldDescriptors[dwIndex], ppcpFieldDescriptor);
}
else
{
hr = E_INVALIDARG;
}
Log(("VBoxCredProv::GetFieldDescriptorAt: hr=0x%08x, index=%ld, ppcpfd=%p\n",
hr, dwIndex, ppcpFieldDescriptor));
return hr;
}
/*
* Sets pdwCount to the number of tiles that we wish to show at this time.
* Sets pdwDefault to the index of the tile which should be used as the default.
*
* The default tile is the tile which will be shown in the zoomed view by default. If
* more than one provider specifies a default tile the behavior is the last used cred
* prov gets to specify the default tile to be displayed
*
* If *pbAutoLogonWithDefault is TRUE, LogonUI will immediately call GetSerialization
* on the credential you've specified as the default and will submit that credential
* for authentication without showing any further UI.
*/
HRESULT VBoxCredProv::GetCredentialCount(DWORD *pdwCount,
DWORD *pdwDefault,
BOOL *pbAutoLogonWithDefault)
{
Assert(pdwCount);
Assert(pdwDefault);
Assert(pbAutoLogonWithDefault);
bool fGotCredentials = false;
/* Poller thread create/active? */
if ( m_pPoller
&& m_pCred)
{
fGotCredentials = m_pPoller->QueryCredentials(m_pCred);
}
if (fGotCredentials)
{
*pdwCount = 1; /* This provider always has the same number of credentials (1). */
*pdwDefault = 0; /* The credential we provide is *always* at index 0! */
*pbAutoLogonWithDefault = TRUE; /* We always at least try to auto-login (if password is correct). */
}
else
{
*pdwCount = 0;
*pdwDefault = CREDENTIAL_PROVIDER_NO_DEFAULT;
*pbAutoLogonWithDefault = FALSE;
}
Log(("VBoxCredProv::GetCredentialCount: *pdwCount=%ld, *pdwDefault=%ld, *pbAutoLogonWithDefault=%s\n",
*pdwCount, *pdwDefault, *pbAutoLogonWithDefault ? "true" : "false"));
return S_OK;
}
/*
* Returns the credential at the index specified by dwIndex. This function is called by logonUI to enumerate
* the tiles.
*/
HRESULT VBoxCredProv::GetCredentialAt(DWORD dwIndex,
ICredentialProviderCredential **ppCredProvCredential)
{
HRESULT hr;
Log(("VBoxCredProv::GetCredentialAt: Index=%ld, ppCredProvCredential=%p\n", dwIndex, ppCredProvCredential));
if (m_pCred == NULL)
{
Log(("VBoxCredProv::GetCredentialAt: No credentials available.\n"));
return E_INVALIDARG;
}
/* Validate parameters (we only have one credential). */
if( dwIndex == 0
&& ppCredProvCredential)
{
hr = m_pCred->QueryInterface(IID_ICredentialProviderCredential,
reinterpret_cast<void**>(ppCredProvCredential));
}
else
{
Log(("VBoxCredProv::GetCredentialAt: More than one credential not supported!\n"));
hr = E_INVALIDARG;
}
return hr;
}
/* Do a credential re-enumeration if we got the event to do so. */
void VBoxCredProv::OnCredentialsProvided()
{
Log(("VBoxCredProv::OnCredentialsProvided\n"));
if (m_pCredProvEvents != NULL)
m_pCredProvEvents->CredentialsChanged(m_upAdviseContext);
}
/* Creates our provider. This happens *before* CTRL-ALT-DEL was pressed! */
HRESULT VBoxCredProv_CreateInstance(REFIID riid, void** ppv)
{
HRESULT hr;
VBoxCredProv* pProvider = new VBoxCredProv();
if (pProvider)
{
hr = pProvider->QueryInterface(riid, ppv);
pProvider->Release();
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}