VBoxCredential.cpp revision d2236df2116a3cbe8b17c567f4a9c2281733a956
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// PARTICULAR PURPOSE.
//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
//
// Modifications (c) 2009 Sun Microsystems, Inc.
//
#ifndef WIN32_NO_STATUS
#include <ntstatus.h>
#define WIN32_NO_STATUS
#endif
#include "VBoxCredential.h"
#include "guid.h"
{
Log(("VBoxCredential::VBoxCredential\n"));
DllAddRef();
}
{
Log(("VBoxCredential::~VBoxCredential\n"));
Reset();
for (int i = 0; i < ARRAYSIZE(m_rgFieldStrings); i++)
{
}
DllRelease();
}
void VBoxCredential::Reset(void)
{
if (m_rgFieldStrings[SFI_PASSWORD])
{
// CoTaskMemFree (below) deals with NULL, but StringCchLength does not.
{
SecureZeroMemory(m_rgFieldStrings[SFI_PASSWORD], lenPassword * sizeof(*m_rgFieldStrings[SFI_PASSWORD]));
}
else
{
// TODO: Determine how to handle count error here.
}
}
/** @todo securely clear other fields (user name, domain, ...) as well. */
}
const char *pszPw,
const char *pszDomain)
{
/* Convert credentials to unicode. */
Log(("VBoxCredential::Update: user=%ls, pw=%ls, domain=%ls\n",
return S_OK;
}
// Initializes one credential with the field information passed in.
// Set the value of the SFI_USERNAME field to pwzUsername.
// Optionally takes a password for the SetSerialization case.
const FIELD_STATE_PAIR* rgfsp)
{
/* Copy the field descriptors for each field. This is useful if you want to vary the
* field descriptors based on what Usage scenario the credential was created for. */
{
m_rgFieldStatePairs[i] = rgfsp[i];
}
/* Fill in the default value to make winlogon happy. */
return S_OK;
}
/* LogonUI calls this in order to give us a callback in case we need to notify it of anything.
* Store this callback pointer for later use. */
{
Log(("VBoxCredential::Advise\n"));
if (m_pCredProvCredentialEvents != NULL)
return S_OK;
}
/* LogonUI calls this to tell us to release the callback. */
{
Log(("VBoxCredential::UnAdvise\n"));
Reset();
return S_OK;
}
// LogonUI calls this function when our tile is selected (zoomed).
// there's no need to do anything here - you can set that up in the
// field definitions. But if you want to do something
// more complicated, like change the contents of a field when the tile is
// selected, you would do it here.
{
Log(("VBoxCredential::SetSelected\n"));
/* Don't do auto logon here because it would retry too often with
* every credential field (user name, password, domain, ...) which makes
* winlogon wait before new login attempts can be made.
*/
*pbAutoLogon = FALSE;
return S_OK;
}
// Similarly to SetSelected, LogonUI calls this when your tile was selected
// and now no longer is. The most common thing to do here (which we do below)
// is to clear out the password field.
{
Log(("VBoxCredential::SetDeselected\n"));
if (m_rgFieldStrings[SFI_PASSWORD])
{
// CoTaskMemFree (below) deals with NULL, but StringCchLength does not.
{
SecureZeroMemory(m_rgFieldStrings[SFI_PASSWORD], lenPassword * sizeof(*m_rgFieldStrings[SFI_PASSWORD]));
}
{
}
}
return hr;
}
// Gets info for a particular field of a tile. Called by logonUI to get information to
// display the tile.
{
Log(("VBoxCredential::GetFieldState: dwFieldID=%ld, pcpfs=%p, pcpfis=%p\n", dwFieldID, pcpfs, pcpfis));
&& pcpfs
&& pcpfis)
{
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
// Sets ppwsz to the string value of the field at the index dwFieldID.
{
// Check to make sure dwFieldID is a legitimate index.
{
// Make a copy of the string and return that. The caller
// is responsible for freeing it.
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
// Sets pdwAdjacentTo to the index of the field the submit button should be
// adjacent to. We recommend that the submit button is placed next to the last
// field which the user is required to enter information in. Optional fields
// should be below the submit button.
{
// Validate parameters.
{
// pdwAdjacentTo is a pointer to the fieldID you want the submit button to appear next to.
Log(("VBoxCredential::GetSubmitButtonValue: dwFieldID=%ld, *pdwAdjacentTo=%ld\n", dwFieldID, *pdwAdjacentTo));
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
// Sets the value of a field which can accept a string as a value.
// This is called on each keystroke when a user types into an edit field.
{
// Validate parameters.
{
}
else
{
hr = E_INVALIDARG;
}
return hr;
}
// The following methods are for logonUI to get the values of various UI elements and then communicate
// to the credential about what the user did in that field. However, these methods are not implemented
// because our tile doesn't contain these types of UI elements
/* Gets the image to show in the user tile */
{
/* We don't do own bitmaps */
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
// Collect the username and password into a serialized credential for the correct usage scenario
// back to the system to log on.
{
Log(("VBoxCredential::GetSerialization: pcpgsr=%p, pcpcs=%p, ppwszOptionalStatusText=%p, pcpsiOptionalStatusIcon=%p\n",
{
/* Is a domain name missing? Then use the name of the local computer. */
else
/* Fill in the username and password. */
{
{
{
// Allocate copies of, and package, the strings in a binary blob
{
{
// At this point the credential has created the serialized credential used for logon
// By setting this to CPGSR_RETURN_CREDENTIAL_FINISHED we are letting logonUI know
// that we have all the information we need and it should attempt to submit the
// serialized credential.
}
}
}
}
}
}
else
{
}
return hr;
}
struct REPORT_RESULT_STATUS_INFO
{
};
static const REPORT_RESULT_STATUS_INFO s_rgLogonStatusInfo[] =
{
};
// ReportResult is completely optional. Its purpose is to allow a credential to customize the string
// and the icon displayed in the case of a logon failure. For example, we have chosen to
// being disabled.
{
// Look for a match on status and substatus.
{
if (s_rgLogonStatusInfo[i].ntsStatus == ntsStatus && s_rgLogonStatusInfo[i].ntsSubstatus == ntsSubstatus)
{
dwStatusInfo = i;
break;
}
}
{
{
}
}
/* Try to lookup a text message for error code */
if (hMod)
{
hMod,
0,
NULL);
}
Log(("VBoxCredential::ReportResult: ntsStatus=%ld, ntsSubstatus=%ld, ppwszOptionalStatusText=%p, pcpsiOptionalStatusIcon=%p, dwStatusInfo=%ld, Message=%ls\n",
ntsStatus, ntsSubstatus, ppwszOptionalStatusText, pcpsiOptionalStatusIcon, dwStatusInfo, lpMessageBuffer ? lpMessageBuffer : L"none"));
if (lpMessageBuffer)
// Since NULL is a valid value for *ppwszOptionalStatusText and *pcpsiOptionalStatusIcon
// this function can't fail.
return S_OK;
}