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

  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. *ppv=NULL;
  38. // Validate requested interface
  39. if(IID_IUnknown == riid)
  40. {
  41. *ppv = (IUnknown *)this;
  42. }
  43. else if ((IID_IUserIdentity == riid)
  44. || (IID_IUserIdentity2 == riid))
  45. {
  46. *ppv = (IUserIdentity2 *)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. if (SUCCEEDED(hr))
  96. {
  97. StrCpyW(pszPath, szwRootPath);
  98. }
  99. return hr;
  100. }
  101. STDMETHODIMP CUserIdentity::GetName(WCHAR *pszName, ULONG ulBuffSize)
  102. {
  103. if (!m_fSaved || ulBuffSize == 0)
  104. return E_IDENTITY_NOT_FOUND;
  105. if (MultiByteToWideChar(CP_ACP, 0, m_szUsername, -1, pszName, ulBuffSize) == 0)
  106. return GetLastError();
  107. return S_OK;
  108. }
  109. STDMETHODIMP CUserIdentity::SetName(WCHAR *pszName)
  110. {
  111. TCHAR szRegPath[MAX_PATH];
  112. HRESULT hr = S_OK;
  113. HKEY hKey;
  114. USERINFO uiCurrent;
  115. LPARAM lpNotify = IIC_CURRENT_IDENTITY_CHANGED;
  116. TCHAR szUsername[CCH_USERNAME_MAX_LENGTH];
  117. if (WideCharToMultiByte(CP_ACP, 0, pszName, -1, szUsername, CCH_USERNAME_MAX_LENGTH, NULL, NULL) == 0)
  118. {
  119. return GetLastError();
  120. }
  121. //
  122. // Only perform change if the username doesn't already exist.
  123. //
  124. if (!MU_UsernameExists(szUsername) && strcmp(szUsername, m_szUsername) != 0)
  125. {
  126. strcpy( m_szUsername, szUsername );
  127. hr = _SaveUser();
  128. // if its not the current identity, then just broadcast that an identity changed
  129. if (MU_GetUserInfo(NULL, &uiCurrent) && (m_uidCookie != uiCurrent.uidUserID))
  130. {
  131. lpNotify = IIC_IDENTITY_CHANGED;
  132. }
  133. // tell apps that the user's name changed
  134. if (SUCCEEDED(hr))
  135. {
  136. PostMessage(HWND_BROADCAST, WM_IDENTITY_INFO_CHANGED, 0, lpNotify);
  137. }
  138. }
  139. else
  140. {
  141. hr = E_IDENTITY_EXISTS;
  142. }
  143. return hr;
  144. }
  145. STDMETHODIMP CUserIdentity::SetPassword(WCHAR *pszPassword)
  146. {
  147. #ifdef IDENTITY_PASSWORDS
  148. TCHAR szRegPath[MAX_PATH];
  149. HRESULT hr = S_OK;
  150. HKEY hKey;
  151. if (!m_fSaved)
  152. return E_IDENTITY_NOT_FOUND;
  153. if (WideCharToMultiByte(CP_ACP, 0, pszPassword, -1, m_szPassword, CCH_USERPASSWORD_MAX_LENGTH, NULL, NULL) == 0)
  154. return GetLastError();
  155. m_fUsePassword = (*m_szPassword != 0);
  156. hr = _SaveUser();
  157. return hr;
  158. #else
  159. return E_NOTIMPL;
  160. #endif
  161. }
  162. STDMETHODIMP CUserIdentity::_SaveUser()
  163. {
  164. DWORD dwType, dwSize, dwValue, dwStatus;
  165. HKEY hkCurrUser;
  166. TCHAR szPath[MAX_PATH];
  167. TCHAR szUid[255];
  168. HRESULT hr;
  169. if (*m_szUsername == 0)
  170. return E_INVALIDARG;
  171. if (!m_fUsePassword)
  172. m_szPassword[0] = 0;
  173. if (!m_fSaved)
  174. hr = _ClaimNextUserId(&m_uidCookie);
  175. Assert(m_uidCookie != GUID_NULL);
  176. Assert(SUCCEEDED(hr));
  177. //
  178. // Save our settings
  179. //
  180. USERINFO UserInfo;
  181. UserInfo.uidUserID= m_uidCookie;
  182. lstrcpy( UserInfo.szUsername, m_szUsername);
  183. UserInfo.fUsePassword= m_fUsePassword;
  184. UserInfo.fPasswordValid= m_fUsePassword;
  185. lstrcpy( UserInfo.szPassword, m_szPassword );
  186. BOOL bSuccess= MU_SetUserInfo(&UserInfo);
  187. if (bSuccess)
  188. {
  189. m_fSaved = TRUE;
  190. return S_OK;
  191. }
  192. else
  193. {
  194. return E_FAIL;
  195. }
  196. }
  197. STDMETHODIMP CUserIdentity::InitFromUsername(TCHAR *pszUsername)
  198. {
  199. GUID uidCookie;
  200. HRESULT hr;
  201. if(FAILED(hr = MU_UsernameToUserId(pszUsername, &uidCookie)))
  202. return hr;
  203. return InitFromCookie(&uidCookie);
  204. }
  205. STDMETHODIMP CUserIdentity::InitFromCookie(GUID *puidCookie)
  206. {
  207. BOOL bSuccess;
  208. USERINFO UserInfo;
  209. HRESULT hrRet = E_FAIL;
  210. bSuccess = MU_GetUserInfo( puidCookie, &UserInfo );
  211. if (bSuccess)
  212. {
  213. m_fUsePassword = UserInfo.fUsePassword;
  214. lstrcpy( m_szUsername, UserInfo.szUsername );
  215. lstrcpy( m_szPassword, UserInfo.szPassword );
  216. m_uidCookie = UserInfo.uidUserID;
  217. m_fSaved = TRUE;
  218. hrRet = S_OK;
  219. }
  220. return hrRet;
  221. }
  222. STDMETHODIMP CUserIdentity::GetOrdinal(DWORD* pdwOrdinal)
  223. {
  224. if (!pdwOrdinal)
  225. {
  226. return E_INVALIDARG;
  227. }
  228. HKEY hSourceSubKey, hkUserKey;
  229. DWORD dwSize, dwType;
  230. DWORD dwIdentityOrdinal = 1, dwOrdinal = 0;
  231. TCHAR szUid[MAX_PATH];
  232. HRESULT hr = E_FAIL;
  233. AStringFromGUID(&m_uidCookie, szUid, MAX_PATH);
  234. if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hSourceSubKey) == ERROR_SUCCESS)
  235. {
  236. dwSize = sizeof(dwIdentityOrdinal);
  237. RegQueryValueEx(hSourceSubKey, c_szIdentityOrdinal, NULL, &dwType, (LPBYTE)&dwIdentityOrdinal, &dwSize);
  238. if (RegOpenKey(hSourceSubKey, szUid, &hkUserKey) == ERROR_SUCCESS)
  239. {
  240. if (RegQueryValueEx(hkUserKey, c_szIdentityOrdinal, NULL, &dwType, (LPBYTE)&dwOrdinal, &dwSize)!=ERROR_SUCCESS)
  241. {
  242. if (RegSetValueEx(hkUserKey, c_szIdentityOrdinal, NULL, REG_DWORD, (LPBYTE)&dwIdentityOrdinal, dwSize)==ERROR_SUCCESS)
  243. {
  244. dwOrdinal = dwIdentityOrdinal++;
  245. RegSetValueEx(hSourceSubKey, c_szIdentityOrdinal, 0, REG_DWORD, (LPBYTE)&dwIdentityOrdinal, dwSize);
  246. hr = S_OK;
  247. }
  248. else
  249. {
  250. AssertSz(FALSE, "Couldn't set the identity ordinal");
  251. }
  252. }
  253. else
  254. {
  255. hr = S_OK;
  256. }
  257. RegCloseKey(hkUserKey);
  258. }
  259. else
  260. {
  261. AssertSz(FALSE, "Couldn't open user's Key");
  262. }
  263. RegCloseKey(hSourceSubKey);
  264. }
  265. else
  266. {
  267. AssertSz(FALSE, "Couldn't open user profiles root Key");
  268. }
  269. *pdwOrdinal = dwOrdinal;
  270. return hr;
  271. }
  272. //----------------------------------------------------------------------------
  273. // Changes password to newPass if oldPass matches the current password
  274. //----------------------------------------------------------------------------
  275. STDMETHODIMP CUserIdentity::ChangePassword(WCHAR *szOldPass, WCHAR *szNewPass)
  276. {
  277. HRESULT hr = E_FAIL;
  278. TCHAR szOldPwd[CCH_USERPASSWORD_MAX_LENGTH+1];
  279. if (!m_fSaved)
  280. {
  281. return E_IDENTITY_NOT_FOUND;
  282. }
  283. if (WideCharToMultiByte(CP_ACP, 0, szOldPass, -1, szOldPwd, CCH_USERPASSWORD_MAX_LENGTH, NULL, NULL) == 0)
  284. {
  285. return E_FAIL;
  286. }
  287. if (!m_fUsePassword || lstrcmp(szOldPwd, m_szPassword) == 0)
  288. {
  289. hr = SetPassword(szNewPass);
  290. }
  291. return hr;
  292. }