Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

370 lines
8.2 KiB

//
// ident.cpp - implementation of CUserIdentity class
//
#include "private.h"
#include "shlwapi.h"
#include "multiusr.h"
#include "strconst.h"
#include "multiutl.h"
#include <shfolder.h>
//
// Constructor / destructor
//
CUserIdentity::CUserIdentity()
: m_cRef(1),
m_fSaved(FALSE),
m_fUsePassword(0)
{
m_szUsername[0] = 0;
m_szPassword[0] = 0;
ZeroMemory(&m_uidCookie, sizeof(GUID));
DllAddRef();
}
CUserIdentity::~CUserIdentity()
{
DllRelease();
}
//
// IUnknown members
//
STDMETHODIMP CUserIdentity::QueryInterface(
REFIID riid, void **ppv)
{
if (NULL == ppv)
{
return E_INVALIDARG;
}
*ppv=NULL;
// Validate requested interface
if(IID_IUnknown == riid)
{
*ppv = (IUnknown *)this;
}
else if ((IID_IUserIdentity == riid)
|| (IID_IUserIdentity2 == riid))
{
*ppv = (IUserIdentity2 *)this;
}
// Addref through the interface
if( NULL != *ppv ) {
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CUserIdentity::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CUserIdentity::Release()
{
if( 0L != --m_cRef )
return m_cRef;
delete this;
return 0L;
}
//
// IUserIdentity members
//
STDMETHODIMP CUserIdentity::GetCookie(GUID *puidCookie)
{
if (!m_fSaved)
return E_INVALIDARG;
*puidCookie = m_uidCookie;
return S_OK;
}
STDMETHODIMP CUserIdentity::OpenIdentityRegKey(DWORD dwDesiredAccess, HKEY *phKey)
{
TCHAR szRootPath[MAX_PATH];
HRESULT hr = S_OK;
if (!m_fSaved)
return E_IDENTITY_NOT_FOUND;
MU_GetRegRootForUserID(&m_uidCookie, szRootPath);
hr = RegCreateKey(HKEY_CURRENT_USER, szRootPath, phKey);
RegCloseKey(*phKey);
hr = RegOpenKeyEx(HKEY_CURRENT_USER, szRootPath, 0, dwDesiredAccess, phKey);
return (hr == ERROR_SUCCESS ? S_OK : E_FAIL);
}
STDMETHODIMP CUserIdentity::GetIdentityFolder(DWORD dwFlags, WCHAR *pszPath, ULONG ulBuffSize)
{
WCHAR szwRootPath[MAX_PATH];
HRESULT hr;
if (!m_fSaved)
return E_IDENTITY_NOT_FOUND;
hr = MU_GetUserDirectoryRoot(&m_uidCookie, dwFlags, szwRootPath, MAX_PATH);
if (SUCCEEDED(hr))
{
StrCpyW(pszPath, szwRootPath);
}
return hr;
}
STDMETHODIMP CUserIdentity::GetName(WCHAR *pszName, ULONG ulBuffSize)
{
if (!m_fSaved || ulBuffSize == 0)
return E_IDENTITY_NOT_FOUND;
if (MultiByteToWideChar(CP_ACP, 0, m_szUsername, -1, pszName, ulBuffSize) == 0)
return GetLastError();
return S_OK;
}
STDMETHODIMP CUserIdentity::SetName(WCHAR *pszName)
{
TCHAR szRegPath[MAX_PATH];
HRESULT hr = S_OK;
HKEY hKey;
USERINFO uiCurrent;
LPARAM lpNotify = IIC_CURRENT_IDENTITY_CHANGED;
TCHAR szUsername[CCH_USERNAME_MAX_LENGTH];
if (WideCharToMultiByte(CP_ACP, 0, pszName, -1, szUsername, CCH_USERNAME_MAX_LENGTH, NULL, NULL) == 0)
{
return GetLastError();
}
//
// Only perform change if the username doesn't already exist.
//
if (!MU_UsernameExists(szUsername) && strcmp(szUsername, m_szUsername) != 0)
{
strcpy( m_szUsername, szUsername );
hr = _SaveUser();
// if its not the current identity, then just broadcast that an identity changed
if (MU_GetUserInfo(NULL, &uiCurrent) && (m_uidCookie != uiCurrent.uidUserID))
{
lpNotify = IIC_IDENTITY_CHANGED;
}
// tell apps that the user's name changed
if (SUCCEEDED(hr))
{
PostMessage(HWND_BROADCAST, WM_IDENTITY_INFO_CHANGED, 0, lpNotify);
}
}
else
{
hr = E_IDENTITY_EXISTS;
}
return hr;
}
STDMETHODIMP CUserIdentity::SetPassword(WCHAR *pszPassword)
{
#ifdef IDENTITY_PASSWORDS
TCHAR szRegPath[MAX_PATH];
HRESULT hr = S_OK;
HKEY hKey;
if (!m_fSaved)
return E_IDENTITY_NOT_FOUND;
if (WideCharToMultiByte(CP_ACP, 0, pszPassword, -1, m_szPassword, CCH_USERPASSWORD_MAX_LENGTH, NULL, NULL) == 0)
return GetLastError();
m_fUsePassword = (*m_szPassword != 0);
hr = _SaveUser();
return hr;
#else
return E_NOTIMPL;
#endif
}
STDMETHODIMP CUserIdentity::_SaveUser()
{
DWORD dwType, dwSize, dwValue, dwStatus;
HKEY hkCurrUser;
TCHAR szPath[MAX_PATH];
TCHAR szUid[255];
HRESULT hr;
if (*m_szUsername == 0)
return E_INVALIDARG;
if (!m_fUsePassword)
m_szPassword[0] = 0;
if (!m_fSaved)
hr = _ClaimNextUserId(&m_uidCookie);
Assert(m_uidCookie != GUID_NULL);
Assert(SUCCEEDED(hr));
//
// Save our settings
//
USERINFO UserInfo;
UserInfo.uidUserID= m_uidCookie;
lstrcpy( UserInfo.szUsername, m_szUsername);
UserInfo.fUsePassword= m_fUsePassword;
UserInfo.fPasswordValid= m_fUsePassword;
lstrcpy( UserInfo.szPassword, m_szPassword );
BOOL bSuccess= MU_SetUserInfo(&UserInfo);
if (bSuccess)
{
m_fSaved = TRUE;
return S_OK;
}
else
{
return E_FAIL;
}
}
STDMETHODIMP CUserIdentity::InitFromUsername(TCHAR *pszUsername)
{
GUID uidCookie;
HRESULT hr;
if(FAILED(hr = MU_UsernameToUserId(pszUsername, &uidCookie)))
return hr;
return InitFromCookie(&uidCookie);
}
STDMETHODIMP CUserIdentity::InitFromCookie(GUID *puidCookie)
{
BOOL bSuccess;
USERINFO UserInfo;
HRESULT hrRet = E_FAIL;
bSuccess = MU_GetUserInfo( puidCookie, &UserInfo );
if (bSuccess)
{
m_fUsePassword = UserInfo.fUsePassword;
lstrcpy( m_szUsername, UserInfo.szUsername );
lstrcpy( m_szPassword, UserInfo.szPassword );
m_uidCookie = UserInfo.uidUserID;
m_fSaved = TRUE;
hrRet = S_OK;
}
return hrRet;
}
STDMETHODIMP CUserIdentity::GetOrdinal(DWORD* pdwOrdinal)
{
if (!pdwOrdinal)
{
return E_INVALIDARG;
}
HKEY hSourceSubKey, hkUserKey;
DWORD dwSize, dwType;
DWORD dwIdentityOrdinal = 1, dwOrdinal = 0;
TCHAR szUid[MAX_PATH];
HRESULT hr = E_FAIL;
AStringFromGUID(&m_uidCookie, szUid, MAX_PATH);
if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hSourceSubKey) == ERROR_SUCCESS)
{
dwSize = sizeof(dwIdentityOrdinal);
RegQueryValueEx(hSourceSubKey, c_szIdentityOrdinal, NULL, &dwType, (LPBYTE)&dwIdentityOrdinal, &dwSize);
if (RegOpenKey(hSourceSubKey, szUid, &hkUserKey) == ERROR_SUCCESS)
{
if (RegQueryValueEx(hkUserKey, c_szIdentityOrdinal, NULL, &dwType, (LPBYTE)&dwOrdinal, &dwSize)!=ERROR_SUCCESS)
{
if (RegSetValueEx(hkUserKey, c_szIdentityOrdinal, NULL, REG_DWORD, (LPBYTE)&dwIdentityOrdinal, dwSize)==ERROR_SUCCESS)
{
dwOrdinal = dwIdentityOrdinal++;
RegSetValueEx(hSourceSubKey, c_szIdentityOrdinal, 0, REG_DWORD, (LPBYTE)&dwIdentityOrdinal, dwSize);
hr = S_OK;
}
else
{
AssertSz(FALSE, "Couldn't set the identity ordinal");
}
}
else
{
hr = S_OK;
}
RegCloseKey(hkUserKey);
}
else
{
AssertSz(FALSE, "Couldn't open user's Key");
}
RegCloseKey(hSourceSubKey);
}
else
{
AssertSz(FALSE, "Couldn't open user profiles root Key");
}
*pdwOrdinal = dwOrdinal;
return hr;
}
//----------------------------------------------------------------------------
// Changes password to newPass if oldPass matches the current password
//----------------------------------------------------------------------------
STDMETHODIMP CUserIdentity::ChangePassword(WCHAR *szOldPass, WCHAR *szNewPass)
{
HRESULT hr = E_FAIL;
TCHAR szOldPwd[CCH_USERPASSWORD_MAX_LENGTH+1];
if (!m_fSaved)
{
return E_IDENTITY_NOT_FOUND;
}
if (WideCharToMultiByte(CP_ACP, 0, szOldPass, -1, szOldPwd, CCH_USERPASSWORD_MAX_LENGTH, NULL, NULL) == 0)
{
return E_FAIL;
}
if (!m_fUsePassword || lstrcmp(szOldPwd, m_szPassword) == 0)
{
hr = SetPassword(szNewPass);
}
return hr;
}