ident.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //
  2. // ident.cpp - implementation of CUserIdentity class
  3. //
  4. #include "private.h"
  5. #include "shlwapi.h"
  6. #include "multiusr.h"
  7. #include "strconst.h"
  8. #include "multiutl.h"
  9. #include <shfolder.h>
  10. //
  11. // Constructor / destructor
  12. //
  13. CUserIdentity::CUserIdentity()
  14.     : m_cRef(1),
  15.       m_fSaved(FALSE),
  16.       m_fUsePassword(0)
  17. {
  18.     m_szUsername[0] = 0;
  19.     m_szPassword[0] = 0;
  20.     ZeroMemory(&m_uidCookie, sizeof(GUID));
  21.     DllAddRef();
  22. }
  23. CUserIdentity::~CUserIdentity()
  24. {
  25.     DllRelease();
  26. }
  27. //
  28. // IUnknown members
  29. //
  30. STDMETHODIMP CUserIdentity::QueryInterface(
  31.     REFIID riid, void **ppv)
  32. {
  33.     if (NULL == ppv)
  34.     {
  35.         return E_INVALIDARG;
  36.     }
  37.     
  38.     *ppv=NULL;
  39.     // Validate requested interface
  40.     if(IID_IUnknown == riid)
  41.     {
  42.         *ppv = (IUnknown *)this;
  43.     }
  44.     else if(IID_IUserIdentity == riid)
  45.     {
  46.         *ppv = (IUserIdentity *)this;
  47.     }
  48.     // Addref through the interface
  49.     if( NULL != *ppv ) {
  50.         ((LPUNKNOWN)*ppv)->AddRef();
  51.         return S_OK;
  52.     }
  53.     return E_NOINTERFACE;
  54. }
  55. STDMETHODIMP_(ULONG) CUserIdentity::AddRef()
  56. {
  57.     return ++m_cRef;
  58. }
  59. STDMETHODIMP_(ULONG) CUserIdentity::Release()
  60. {
  61.     if( 0L != --m_cRef )
  62.         return m_cRef;
  63.     delete this;
  64.     return 0L;
  65. }
  66. // 
  67. // IUserIdentity members
  68. //
  69. STDMETHODIMP CUserIdentity::GetCookie(GUID *puidCookie)
  70. {
  71.     if (!m_fSaved)
  72.         return E_INVALIDARG;
  73.     *puidCookie = m_uidCookie;
  74.     return S_OK;
  75. }
  76. STDMETHODIMP CUserIdentity::OpenIdentityRegKey(DWORD dwDesiredAccess, HKEY *phKey)
  77. {
  78.     TCHAR    szRootPath[MAX_PATH];
  79.     HRESULT  hr = S_OK;
  80.     if (!m_fSaved)
  81.         return E_IDENTITY_NOT_FOUND;
  82.     MU_GetRegRootForUserID(&m_uidCookie, szRootPath);
  83.     hr = RegCreateKey(HKEY_CURRENT_USER, szRootPath, phKey);
  84.     RegCloseKey(*phKey);
  85.     hr = RegOpenKeyEx(HKEY_CURRENT_USER, szRootPath, 0, dwDesiredAccess, phKey);
  86.     return (hr == ERROR_SUCCESS ? S_OK : E_FAIL);
  87. }
  88. STDMETHODIMP CUserIdentity::GetIdentityFolder(DWORD dwFlags, WCHAR *pszPath, ULONG ulBuffSize)
  89. {
  90.     WCHAR    szwRootPath[MAX_PATH];
  91.     HRESULT hr;
  92.     if (!m_fSaved)
  93.         return E_IDENTITY_NOT_FOUND;
  94.     hr = MU_GetUserDirectoryRoot(&m_uidCookie, dwFlags, szwRootPath, MAX_PATH);
  95.     
  96.     if (SUCCEEDED(hr))
  97.     {
  98.         StrCpyW(pszPath, szwRootPath);
  99.     }
  100.     return hr;
  101. }
  102. STDMETHODIMP CUserIdentity::GetName(WCHAR *pszName, ULONG ulBuffSize)
  103. {
  104.     if (!m_fSaved || ulBuffSize == 0)
  105.         return E_IDENTITY_NOT_FOUND;
  106.     if (MultiByteToWideChar(CP_ACP, 0, m_szUsername, -1, pszName, ulBuffSize) == 0)
  107.         return GetLastError();
  108.     
  109.     return S_OK;
  110. }
  111. STDMETHODIMP CUserIdentity::SetName(WCHAR *pszName)
  112. {
  113.     TCHAR       szRegPath[MAX_PATH];
  114.     HRESULT     hr = S_OK;
  115.     HKEY        hKey;
  116.     USERINFO    uiCurrent;
  117.     LPARAM      lpNotify = IIC_CURRENT_IDENTITY_CHANGED;
  118.     
  119.     if (WideCharToMultiByte(CP_ACP, 0, pszName, -1, m_szUsername, CCH_USERNAME_MAX_LENGTH, NULL, NULL) == 0)
  120.         return GetLastError();
  121.     
  122.     hr = _SaveUser();
  123.     
  124.     // if its not the current identity, then just broadcast that an identity changed
  125.     if (MU_GetUserInfo(NULL, &uiCurrent) && (m_uidCookie != uiCurrent.uidUserID))
  126.         lpNotify = IIC_IDENTITY_CHANGED;
  127.     // tell apps that the user's name changed
  128.     if (SUCCEEDED(hr))
  129.         PostMessage(HWND_BROADCAST, WM_IDENTITY_INFO_CHANGED, 0, lpNotify);
  130.     return hr;
  131. }
  132. STDMETHODIMP CUserIdentity::SetPassword(WCHAR *pszPassword)
  133. {
  134. #ifdef IDENTITY_PASSWORDS
  135.     TCHAR       szRegPath[MAX_PATH];
  136.     HRESULT     hr = S_OK;
  137.     HKEY        hKey;
  138.     
  139.     if (!m_fSaved)
  140.         return E_IDENTITY_NOT_FOUND;
  141.     if (WideCharToMultiByte(CP_ACP, 0, pszPassword, -1, m_szPassword, CCH_USERPASSWORD_MAX_LENGTH, NULL, NULL) == 0)
  142.         return GetLastError();
  143.     
  144.     m_fUsePassword = (*m_szPassword != 0);
  145.     hr = _SaveUser();
  146.     return hr;
  147. #else
  148.     return E_NOTIMPL;
  149. #endif
  150. }
  151. STDMETHODIMP CUserIdentity::_SaveUser()
  152. {
  153.     DWORD   dwType, dwSize, dwValue, dwStatus;
  154.     HKEY    hkCurrUser;
  155.     TCHAR   szPath[MAX_PATH];
  156.     TCHAR   szUid[255];
  157.     HRESULT hr;
  158.     if (*m_szUsername == 0)
  159.         return E_INVALIDARG;
  160.     if (!m_fUsePassword)
  161.         m_szPassword[0] = 0;
  162.     if (!m_fSaved)
  163.         hr = _ClaimNextUserId(&m_uidCookie);
  164.     Assert(m_uidCookie != GUID_NULL);
  165.     Assert(SUCCEEDED(hr));
  166.     
  167.     MU_GetRegRootForUserID(&m_uidCookie, szPath);
  168.     
  169.     Assert(pszRegPath && *pszRegPath);
  170.     
  171.     if ((dwStatus = RegCreateKey(HKEY_CURRENT_USER, szPath, &hkCurrUser)) == ERROR_SUCCESS)
  172.     {
  173.         ULONG   cbSize;
  174.         TCHAR   szBuffer[255];
  175.         
  176.         // write out the correct values
  177.         dwType = REG_SZ;
  178.         dwSize = lstrlen(m_szUsername) + 1;
  179.         RegSetValueEx(hkCurrUser, c_szUsername, 0, dwType, (LPBYTE)m_szUsername, dwSize);
  180. #ifdef IDENTITY_PASSWORDS
  181.         dwType = REG_BINARY ;
  182.         cbSize = strlen(m_szPassword) + 1;
  183.         lstrcpy(szBuffer, m_szPassword);
  184.         EncodeUserPassword(szBuffer, &cbSize);
  185.         dwSize = cbSize;
  186.         RegSetValueEx(hkCurrUser, c_szPassword, 0, dwType, (LPBYTE)szBuffer, dwSize);
  187.         dwType = REG_DWORD;
  188.         dwValue = (m_fUsePassword ? 1 : 0);
  189.         dwSize = sizeof(dwValue);
  190.         RegSetValueEx(hkCurrUser, c_szUsePassword, 0, dwType, (LPBYTE)&dwValue, dwSize);
  191. #endif
  192.         // make sure the shortened name is there for directories.  If not, create it.
  193.         dwSize = sizeof(DWORD);
  194.         if ((dwStatus = RegQueryValueEx(hkCurrUser, c_szDirName, NULL, &dwType, (LPBYTE)&dwValue, &dwSize)) != ERROR_SUCCESS)
  195.         {
  196.             dwValue = MU_GenerateDirectoryNameForIdentity(&m_uidCookie);
  197.         
  198.             dwType = REG_DWORD;
  199.             dwSize = sizeof(dwValue);
  200.             RegSetValueEx(hkCurrUser, c_szDirName, 0, dwType, (LPBYTE)&dwValue, dwSize);
  201.         }
  202.         AStringFromGUID(&m_uidCookie,  szUid, 255);
  203.         dwType = REG_SZ;
  204.         dwSize = lstrlen(szUid) + 1;
  205.         RegSetValueEx(hkCurrUser, c_szUserID, 0, dwType, (LPBYTE)&szUid, dwSize);
  206.         RegCloseKey(hkCurrUser);
  207.         
  208.         m_fSaved = TRUE;
  209.         return S_OK;
  210.     }
  211.     return E_FAIL;
  212. }
  213. STDMETHODIMP CUserIdentity::InitFromUsername(TCHAR *pszUsername)
  214. {
  215.     GUID   uidCookie;
  216.     HRESULT hr;
  217.     if(FAILED(hr = MU_UsernameToUserId(pszUsername, &uidCookie)))
  218.         return hr;
  219.     return InitFromCookie(&uidCookie);
  220. }
  221. STDMETHODIMP CUserIdentity::InitFromCookie(GUID *puidCookie)
  222. {
  223.     TCHAR   szPWBuffer[255];
  224.     TCHAR   szRegPath[MAX_PATH];
  225.     HKEY    hKey;
  226.     BOOL    bResult = false;
  227.     LONG    lValue;
  228.     DWORD   dwStatus, dwType, dwSize;
  229.     GUID    uidCookie;
  230.     if( puidCookie == NULL)
  231.         MU_GetCurrentUserID(&uidCookie);
  232.     else
  233.         uidCookie = *puidCookie;
  234.     MU_GetRegRootForUserID(&uidCookie, szRegPath);
  235.     
  236.     Assert(pszRegPath && *pszRegPath);
  237.     if (RegOpenKey(HKEY_CURRENT_USER, szRegPath, &hKey) == ERROR_SUCCESS)
  238.     {
  239.         *m_szPassword = 0;
  240.         m_fUsePassword = false;
  241.         ZeroMemory(&m_uidCookie, sizeof(GUID));
  242.         dwSize = sizeof(m_szUsername);
  243.         if ((dwStatus = RegQueryValueEx(hKey, c_szUsername, NULL, &dwType, (LPBYTE)m_szUsername, &dwSize)) == ERROR_SUCCESS &&
  244.                 (0 != *m_szUsername))
  245.         {
  246.             //we have the username, that is the only required part.  The others are optional.
  247.             bResult = true;
  248.             
  249. #ifdef IDENTITY_PASSWORDS
  250.             dwSize = sizeof(lValue);
  251.             if ((dwStatus = RegQueryValueEx(hKey, c_szUsePassword, NULL, &dwType, (LPBYTE)&lValue, &dwSize)) == ERROR_SUCCESS)
  252.             {
  253.                 m_fUsePassword = (lValue != 0);
  254.             }
  255.             dwSize = sizeof(szPWBuffer);
  256.             dwStatus = RegQueryValueEx(hKey, c_szPassword, NULL, &dwType, (LPBYTE)szPWBuffer, &dwSize);
  257.             ULONG   cbSize;
  258.             
  259.             cbSize = dwSize;
  260.             if (ERROR_SUCCESS == dwStatus  && cbSize > 1)
  261.             {
  262.                 DecodeUserPassword(szPWBuffer, &cbSize);
  263.                 strcpy(m_szPassword, szPWBuffer);
  264.             }
  265.             else
  266.                 *m_szPassword = 0;
  267. #endif
  268.             
  269.             m_uidCookie = uidCookie;
  270.             m_fSaved = TRUE;
  271.         }
  272.         RegCloseKey(hKey);
  273.     }
  274.         
  275.     return (bResult ? S_OK : E_FAIL);
  276. }