339 lines
7.9 KiB
C++
339 lines
7.9 KiB
C++
|
|
// 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)
|
|
{
|
|
*ppv = (IUserIdentity *)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;
|
|
|
|
if (WideCharToMultiByte(CP_ACP, 0, pszName, -1, m_szUsername, CCH_USERNAME_MAX_LENGTH, NULL, NULL) == 0)
|
|
return GetLastError();
|
|
|
|
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);
|
|
|
|
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));
|
|
|
|
MU_GetRegRootForUserID(&m_uidCookie, szPath);
|
|
|
|
Assert(pszRegPath && *pszRegPath);
|
|
|
|
if ((dwStatus = RegCreateKey(HKEY_CURRENT_USER, szPath, &hkCurrUser)) == ERROR_SUCCESS)
|
|
{
|
|
ULONG cbSize;
|
|
TCHAR szBuffer[255];
|
|
|
|
// write out the correct values
|
|
dwType = REG_SZ;
|
|
dwSize = lstrlen(m_szUsername) + 1;
|
|
RegSetValueEx(hkCurrUser, c_szUsername, 0, dwType, (LPBYTE)m_szUsername, dwSize);
|
|
|
|
#ifdef IDENTITY_PASSWORDS
|
|
dwType = REG_BINARY ;
|
|
cbSize = strlen(m_szPassword) + 1;
|
|
lstrcpy(szBuffer, m_szPassword);
|
|
EncodeUserPassword(szBuffer, &cbSize);
|
|
dwSize = cbSize;
|
|
RegSetValueEx(hkCurrUser, c_szPassword, 0, dwType, (LPBYTE)szBuffer, dwSize);
|
|
|
|
dwType = REG_DWORD;
|
|
dwValue = (m_fUsePassword ? 1 : 0);
|
|
dwSize = sizeof(dwValue);
|
|
RegSetValueEx(hkCurrUser, c_szUsePassword, 0, dwType, (LPBYTE)&dwValue, dwSize);
|
|
#endif
|
|
|
|
// make sure the shortened name is there for directories. If not, create it.
|
|
dwSize = sizeof(DWORD);
|
|
if ((dwStatus = RegQueryValueEx(hkCurrUser, c_szDirName, NULL, &dwType, (LPBYTE)&dwValue, &dwSize)) != ERROR_SUCCESS)
|
|
{
|
|
dwValue = MU_GenerateDirectoryNameForIdentity(&m_uidCookie);
|
|
|
|
dwType = REG_DWORD;
|
|
dwSize = sizeof(dwValue);
|
|
RegSetValueEx(hkCurrUser, c_szDirName, 0, dwType, (LPBYTE)&dwValue, dwSize);
|
|
}
|
|
|
|
AStringFromGUID(&m_uidCookie, szUid, 255);
|
|
|
|
dwType = REG_SZ;
|
|
dwSize = lstrlen(szUid) + 1;
|
|
RegSetValueEx(hkCurrUser, c_szUserID, 0, dwType, (LPBYTE)&szUid, dwSize);
|
|
|
|
RegCloseKey(hkCurrUser);
|
|
|
|
m_fSaved = TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
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)
|
|
{
|
|
TCHAR szPWBuffer[255];
|
|
TCHAR szRegPath[MAX_PATH];
|
|
HKEY hKey;
|
|
BOOL bResult = false;
|
|
LONG lValue;
|
|
DWORD dwStatus, dwType, dwSize;
|
|
GUID uidCookie;
|
|
|
|
if( puidCookie == NULL)
|
|
MU_GetCurrentUserID(&uidCookie);
|
|
else
|
|
uidCookie = *puidCookie;
|
|
|
|
MU_GetRegRootForUserID(&uidCookie, szRegPath);
|
|
|
|
Assert(pszRegPath && *pszRegPath);
|
|
|
|
if (RegOpenKey(HKEY_CURRENT_USER, szRegPath, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
*m_szPassword = 0;
|
|
m_fUsePassword = false;
|
|
ZeroMemory(&m_uidCookie, sizeof(GUID));
|
|
|
|
dwSize = sizeof(m_szUsername);
|
|
if ((dwStatus = RegQueryValueEx(hKey, c_szUsername, NULL, &dwType, (LPBYTE)m_szUsername, &dwSize)) == ERROR_SUCCESS &&
|
|
(0 != *m_szUsername))
|
|
{
|
|
//we have the username, that is the only required part. The others are optional.
|
|
bResult = true;
|
|
|
|
#ifdef IDENTITY_PASSWORDS
|
|
dwSize = sizeof(lValue);
|
|
if ((dwStatus = RegQueryValueEx(hKey, c_szUsePassword, NULL, &dwType, (LPBYTE)&lValue, &dwSize)) == ERROR_SUCCESS)
|
|
{
|
|
m_fUsePassword = (lValue != 0);
|
|
}
|
|
|
|
dwSize = sizeof(szPWBuffer);
|
|
dwStatus = RegQueryValueEx(hKey, c_szPassword, NULL, &dwType, (LPBYTE)szPWBuffer, &dwSize);
|
|
ULONG cbSize;
|
|
|
|
cbSize = dwSize;
|
|
if (ERROR_SUCCESS == dwStatus && cbSize > 1)
|
|
{
|
|
DecodeUserPassword(szPWBuffer, &cbSize);
|
|
strcpy(m_szPassword, szPWBuffer);
|
|
}
|
|
else
|
|
*m_szPassword = 0;
|
|
|
|
#endif
|
|
|
|
m_uidCookie = uidCookie;
|
|
m_fSaved = TRUE;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return (bResult ? S_OK : E_FAIL);
|
|
}
|