Commit 34548a8e authored by Tien Mai's avatar Tien Mai Committed by Commit Bot

[GCPW] Create bitmap version of profile picture used for reauth

- Linked agains gdi+ to use their image converting tools.
- Now when downloading the profile picture, the largest downloaded
picture will also be converted into .bmp and saved into the same
directory.
- Override the GetBitmapValue of the credential to read this bmp
file and return it.

Bug: 936847
Change-Id: Ie36b99e167c828ed7b46b88c400465f5fca44fd2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1497192
Commit-Queue: Tien Mai <tienmai@chromium.org>
Reviewed-by: default avatarRoger Tawa <rogerta@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638212}
parent f843ae38
...@@ -141,6 +141,7 @@ config("gaiacp_config") { ...@@ -141,6 +141,7 @@ config("gaiacp_config") {
"advapi32.lib", # For LookupAccountSid() "advapi32.lib", # For LookupAccountSid()
"credui.lib", # For CredPackAuthenticationBufferW() "credui.lib", # For CredPackAuthenticationBufferW()
"crypt32.lib", # For CryptProtectData() "crypt32.lib", # For CryptProtectData()
"gdiplus.lib", # To convert profile pictures to bmp.
"netapi32.lib", # For NetUserXXX() "netapi32.lib", # For NetUserXXX()
"userenv.lib", # For GetUserProfileDirectoryW() "userenv.lib", # For GetUserProfileDirectoryW()
"winhttp.lib", # For WinHttpXXX() "winhttp.lib", # For WinHttpXXX()
......
...@@ -590,6 +590,23 @@ HRESULT CGaiaCredentialBase::GetStringValueImpl(DWORD field_id, ...@@ -590,6 +590,23 @@ HRESULT CGaiaCredentialBase::GetStringValueImpl(DWORD field_id,
return hr; return hr;
} }
HRESULT CGaiaCredentialBase::GetBitmapValueImpl(DWORD field_id,
HBITMAP* phbmp) {
HRESULT hr = E_INVALIDARG;
switch (field_id) {
case FID_PROVIDER_LOGO:
*phbmp = ::LoadBitmap(CURRENT_MODULE(),
MAKEINTRESOURCE(IDB_GOOGLE_LOGO_SMALL));
if (*phbmp)
hr = S_OK;
break;
default:
break;
}
return hr;
}
void CGaiaCredentialBase::ResetInternalState() { void CGaiaCredentialBase::ResetInternalState() {
LOGFN(INFO); LOGFN(INFO);
username_.Empty(); username_.Empty();
...@@ -910,19 +927,7 @@ HRESULT CGaiaCredentialBase::GetStringValue(DWORD field_id, wchar_t** value) { ...@@ -910,19 +927,7 @@ HRESULT CGaiaCredentialBase::GetStringValue(DWORD field_id, wchar_t** value) {
} }
HRESULT CGaiaCredentialBase::GetBitmapValue(DWORD field_id, HBITMAP* phbmp) { HRESULT CGaiaCredentialBase::GetBitmapValue(DWORD field_id, HBITMAP* phbmp) {
HRESULT hr = E_INVALIDARG; return GetBitmapValueImpl(field_id, phbmp);
switch (field_id) {
case FID_PROVIDER_LOGO:
*phbmp = ::LoadBitmap(CURRENT_MODULE(),
MAKEINTRESOURCE(IDB_GOOGLE_LOGO_SMALL));
if (*phbmp)
hr = S_OK;
break;
default:
break;
}
return hr;
} }
HRESULT CGaiaCredentialBase::GetCheckboxValue(DWORD field_id, HRESULT CGaiaCredentialBase::GetCheckboxValue(DWORD field_id,
......
...@@ -125,6 +125,10 @@ class ATL_NO_VTABLE CGaiaCredentialBase ...@@ -125,6 +125,10 @@ class ATL_NO_VTABLE CGaiaCredentialBase
// Gets the string value for the given credential UI field. // Gets the string value for the given credential UI field.
virtual HRESULT GetStringValueImpl(DWORD field_id, wchar_t** value); virtual HRESULT GetStringValueImpl(DWORD field_id, wchar_t** value);
// Can be overridden to change the icon used for anonymous tiles when they are
// shown in the selection list on the side and when they are selected.
virtual HRESULT GetBitmapValueImpl(DWORD field_id, HBITMAP* phbmp);
// Resets the state of the credential, forgetting any username or password // Resets the state of the credential, forgetting any username or password
// that may have been set previously. Derived classes may override to // that may have been set previously. Derived classes may override to
// perform more state resetting if needed, but should always call the base // perform more state resetting if needed, but should always call the base
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <ntsecapi.h> // For LsaLookupAuthenticationPackage() #include <ntsecapi.h> // For LsaLookupAuthenticationPackage()
#include <sddl.h> // For ConvertSidToStringSid() #include <sddl.h> // For ConvertSidToStringSid()
#include <security.h> // For NEGOSSP_NAME_A #include <security.h> // For NEGOSSP_NAME_A
#include <shlobj.h> // For SHGetKnownFolderPath()
#include <wbemidl.h> #include <wbemidl.h>
#include <atlbase.h> #include <atlbase.h>
...@@ -45,6 +46,9 @@ ...@@ -45,6 +46,9 @@
namespace credential_provider { namespace credential_provider {
const wchar_t kDefaultProfilePictureFileExtension[] = L".jpg";
const wchar_t kCredentialLogoPictureFileExtension[] = L".bmp";
namespace { namespace {
constexpr char kSentinelFilename[] = "gcpw_startup.sentinel"; constexpr char kSentinelFilename[] = "gcpw_startup.sentinel";
...@@ -634,6 +638,29 @@ base::string16 GetStringResource(int base_message_id) { ...@@ -634,6 +638,29 @@ base::string16 GetStringResource(int base_message_id) {
return localized_string; return localized_string;
} }
HRESULT GetUserAccountPicturePath(const base::string16& sid,
base::FilePath* base_path) {
DCHECK(base_path);
base_path->clear();
LPWSTR path;
HRESULT hr = ::SHGetKnownFolderPath(FOLDERID_PublicUserTiles, 0, NULL, &path);
if (FAILED(hr)) {
LOGFN(ERROR) << "SHGetKnownFolderPath=" << putHR(hr);
return hr;
}
*base_path = base::FilePath(path).Append(sid);
::CoTaskMemFree(path);
return S_OK;
}
base::FilePath GetUserSizedAccountPictureFilePath(
const base::FilePath& account_picture_path,
int size,
const base::string16& picture_extension) {
return account_picture_path.Append(base::StringPrintf(
L"GoogleAccountPicture_%i%ls", size, picture_extension.c_str()));
}
base::string16 GetSelectedLanguage() { base::string16 GetSelectedLanguage() {
return GetLanguageSelector().matched_candidate(); return GetLanguageSelector().matched_candidate();
} }
......
...@@ -54,6 +54,17 @@ constexpr int kMaxUsernameAttempts = 10; ...@@ -54,6 +54,17 @@ constexpr int kMaxUsernameAttempts = 10;
// already exists. // already exists.
constexpr int kInitialDuplicateUsernameIndex = 2; constexpr int kInitialDuplicateUsernameIndex = 2;
// Default extension used as a fallback if the picture_url returned from gaia
// does not have a file extension.
extern const wchar_t kDefaultProfilePictureFileExtension[];
// Required extension for the picture that will be shown by the credential on
// the login screen. Windows only supports .bmp files for the images shown by
// credentials.
extern const wchar_t kCredentialLogoPictureFileExtension[];
constexpr int kLargestProfilePictureSize = 448;
// Because of some strange dependency problems with windows header files, // Because of some strange dependency problems with windows header files,
// define STATUS_SUCCESS here instead of including ntstatus.h or SubAuth.h // define STATUS_SUCCESS here instead of including ntstatus.h or SubAuth.h
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
...@@ -200,6 +211,20 @@ void DeleteStartupSentinel(); ...@@ -200,6 +211,20 @@ void DeleteStartupSentinel();
// Gets a string resource from the DLL with the given id. // Gets a string resource from the DLL with the given id.
base::string16 GetStringResource(int base_message_id); base::string16 GetStringResource(int base_message_id);
// Fills |base_path| with the path where user profile pictures are stored for
// user with |sid|. This function can fail if the known folder
// FOLDERID_PublicUserTiles cannot be found.
HRESULT GetUserAccountPicturePath(const base::string16& sid,
base::FilePath* base_path);
// Returns the full path to a user profile picture of a specific |size| and
// |picture_extension|. |account_picture_path| is path filled in by a call to
// GetUserAccountPicturePath.
base::FilePath GetUserSizedAccountPictureFilePath(
const base::FilePath& account_picture_path,
int size,
const base::string16& picture_extension);
// Gets the language selected by the base::win::i18n::LanguageSelector. // Gets the language selected by the base::win::i18n::LanguageSelector.
base::string16 GetSelectedLanguage(); base::string16 GetSelectedLanguage();
......
...@@ -4,8 +4,12 @@ ...@@ -4,8 +4,12 @@
#include "chrome/credential_provider/gaiacp/reauth_credential_anonymous.h" #include "chrome/credential_provider/gaiacp/reauth_credential_anonymous.h"
#include "base/files/file_util.h"
#include "chrome/credential_provider/common/gcp_strings.h"
#include "chrome/credential_provider/gaiacp/gcp_utils.h"
#include "chrome/credential_provider/gaiacp/logging.h" #include "chrome/credential_provider/gaiacp/logging.h"
#include "chrome/credential_provider/gaiacp/os_user_manager.h" #include "chrome/credential_provider/gaiacp/os_user_manager.h"
#include "chrome/credential_provider/gaiacp/reg_utils.h"
namespace credential_provider { namespace credential_provider {
...@@ -37,4 +41,37 @@ HRESULT CReauthCredentialAnonymous::GetStringValueImpl(DWORD field_id, ...@@ -37,4 +41,37 @@ HRESULT CReauthCredentialAnonymous::GetStringValueImpl(DWORD field_id,
return ::SHStrDupW(fullname.c_str(), value); return ::SHStrDupW(fullname.c_str(), value);
} }
HRESULT CReauthCredentialAnonymous::GetBitmapValueImpl(DWORD field_id,
HBITMAP* phbmp) {
if (field_id == FID_PROVIDER_LOGO) {
base::FilePath account_picture_path;
HRESULT hr = GetUserAccountPicturePath(OLE2W(get_os_user_sid()),
&account_picture_path);
if (SUCCEEDED(hr)) {
base::FilePath target_picture_path = GetUserSizedAccountPictureFilePath(
account_picture_path, kLargestProfilePictureSize,
kCredentialLogoPictureFileExtension);
if (base::PathExists(target_picture_path)) {
*phbmp = static_cast<HBITMAP>(
::LoadImage(nullptr, target_picture_path.value().c_str(),
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
if (*phbmp) {
return S_OK;
} else {
hr = HRESULT_FROM_WIN32(::GetLastError());
LOGFN(ERROR) << "Failed load image at='"
<< target_picture_path.value() << "' hr=" << putHR(hr);
}
} else {
LOGFN(ERROR) << "Required picture at='" << target_picture_path.value()
<< "' does not exist.";
}
} else {
LOGFN(ERROR) << "Failed to get account picture known folder hr="
<< putHR(hr);
}
}
return CReauthCredentialBase::GetBitmapValueImpl(field_id, phbmp);
}
} // namespace credential_provider } // namespace credential_provider
...@@ -39,6 +39,7 @@ class ATL_NO_VTABLE CReauthCredentialAnonymous ...@@ -39,6 +39,7 @@ class ATL_NO_VTABLE CReauthCredentialAnonymous
DECLARE_PROTECT_FINAL_CONSTRUCT() DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT GetStringValueImpl(DWORD field_id, wchar_t** value) override; HRESULT GetStringValueImpl(DWORD field_id, wchar_t** value) override;
HRESULT GetBitmapValueImpl(DWORD field_id, HBITMAP* phbmp) override;
}; };
} // namespace credential_provider } // namespace credential_provider
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment