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.

323 lines
6.1 KiB

  1. //
  2. // ident.cpp - implementation of CIdentity class
  3. //
  4. #include "private.h"
  5. #include "strconst.h"
  6. #include "multiusr.h"
  7. //
  8. // Constructor / destructor
  9. //
  10. CEnumUserIdentity::CEnumUserIdentity()
  11. {
  12. m_cRef = 1;
  13. m_dwCurrentUser = 0;
  14. m_cCountUsers = 0;
  15. m_rguidUsers = NULL;
  16. m_fInited = FALSE;
  17. DllAddRef();
  18. }
  19. CEnumUserIdentity::~CEnumUserIdentity()
  20. {
  21. _Cleanup();
  22. DllRelease();
  23. }
  24. //
  25. // IUnknown members
  26. //
  27. STDMETHODIMP CEnumUserIdentity::QueryInterface(
  28. REFIID riid, void **ppv)
  29. {
  30. if (NULL == ppv)
  31. {
  32. return E_INVALIDARG;
  33. }
  34. *ppv=NULL;
  35. // Validate requested interface
  36. if(IID_IUnknown == riid)
  37. {
  38. *ppv = (IUnknown *)this;
  39. }
  40. else if(IID_IEnumUserIdentity == riid)
  41. {
  42. *ppv = (IEnumUserIdentity *)this;
  43. }
  44. // Addref through the interface
  45. if( NULL != *ppv ) {
  46. ((LPUNKNOWN)*ppv)->AddRef();
  47. return S_OK;
  48. }
  49. return E_NOINTERFACE;
  50. }
  51. STDMETHODIMP_(ULONG) CEnumUserIdentity::AddRef()
  52. {
  53. return ++m_cRef;
  54. }
  55. STDMETHODIMP_(ULONG) CEnumUserIdentity::Release()
  56. {
  57. if( 0L != --m_cRef )
  58. return m_cRef;
  59. delete this;
  60. return 0L;
  61. }
  62. //
  63. // IEnumUserIdentity members
  64. //
  65. STDMETHODIMP CEnumUserIdentity::Next(ULONG celt, IUnknown **rgelt, ULONG *pceltFetched)
  66. {
  67. ULONG celtFetched = 0;
  68. HRESULT hr = ResultFromScode(S_OK);
  69. CUserIdentity *pIdentity;
  70. if (!m_fInited)
  71. hr = _Init();
  72. if (FAILED(hr))
  73. return hr;
  74. while (celt)
  75. {
  76. if (m_dwCurrentUser == m_cCountUsers) {
  77. hr = ResultFromScode(S_FALSE);
  78. break;
  79. }
  80. pIdentity = new CUserIdentity;
  81. if (pIdentity)
  82. {
  83. if (SUCCEEDED(pIdentity->InitFromCookie(&m_rguidUsers[m_dwCurrentUser])))
  84. {
  85. rgelt[celtFetched++] = pIdentity;
  86. m_dwCurrentUser++;
  87. }
  88. else
  89. {
  90. pIdentity->Release();
  91. hr = ResultFromScode(E_OUTOFMEMORY);
  92. break;
  93. }
  94. }
  95. else
  96. {
  97. hr = ResultFromScode(E_OUTOFMEMORY);
  98. break;
  99. }
  100. celt--;
  101. }
  102. if (FAILED(hr))
  103. {
  104. for (ULONG i = 0; i < celtFetched; i++)
  105. rgelt[i]->Release();
  106. celtFetched = 0;
  107. }
  108. if (pceltFetched != NULL)
  109. *pceltFetched = celtFetched;
  110. return hr;
  111. }
  112. STDMETHODIMP CEnumUserIdentity::Skip(ULONG celt)
  113. {
  114. SCODE sc;
  115. HRESULT hr = S_OK;
  116. if (!m_fInited)
  117. hr = _Init();
  118. if (FAILED(hr))
  119. return hr;
  120. if (m_dwCurrentUser + celt > m_cCountUsers) {
  121. m_dwCurrentUser = m_cCountUsers;
  122. sc = S_FALSE;
  123. }
  124. else {
  125. m_dwCurrentUser += celt;
  126. sc = S_OK;
  127. }
  128. return ResultFromScode(sc);
  129. }
  130. STDMETHODIMP CEnumUserIdentity::Reset(void)
  131. {
  132. m_dwCurrentUser = 0;
  133. _Cleanup();
  134. return S_OK;
  135. }
  136. STDMETHODIMP CEnumUserIdentity::Clone(IEnumUserIdentity **ppenum)
  137. {
  138. CEnumUserIdentity *pEnum;
  139. HRESULT hr = S_OK;
  140. if (!m_fInited)
  141. hr = _Init();
  142. if (FAILED(hr))
  143. return hr;
  144. pEnum = new CEnumUserIdentity;
  145. if (pEnum)
  146. {
  147. hr = pEnum->_Init(m_dwCurrentUser, m_cCountUsers, m_rguidUsers);
  148. if (SUCCEEDED(hr))
  149. *ppenum = pEnum;
  150. }
  151. return hr;
  152. }
  153. STDMETHODIMP CEnumUserIdentity::GetCount(ULONG *pnCount)
  154. {
  155. HRESULT hr = S_OK;
  156. if (!m_fInited)
  157. hr = _Init();
  158. if (FAILED(hr))
  159. return hr;
  160. *pnCount = m_cCountUsers;
  161. return S_OK;
  162. }
  163. STDMETHODIMP CEnumUserIdentity::_Cleanup()
  164. {
  165. MemFree(m_rguidUsers);
  166. m_rguidUsers = NULL;
  167. m_cCountUsers = 0;
  168. m_fInited = FALSE;
  169. return S_OK;
  170. }
  171. STDMETHODIMP CEnumUserIdentity::_Init()
  172. {
  173. HRESULT hr=S_OK;
  174. HKEY hReg = NULL;
  175. DWORD cUsers = 0;
  176. DWORD cbMaxSubKeyLen;
  177. DWORD cb;
  178. DWORD dwEnumIndex = 0;
  179. BOOL fDisabled = MU_IdentitiesDisabled();
  180. m_cCountUsers = 0;
  181. // Open or Create root server key
  182. if (RegCreateKeyEx(HKEY_CURRENT_USER, c_szRegRoot, 0, NULL, REG_OPTION_NON_VOLATILE,
  183. KEY_ALL_ACCESS, NULL, &hReg, NULL) != ERROR_SUCCESS)
  184. {
  185. hr = E_FAIL;
  186. goto exit;
  187. }
  188. // Enumerate keys
  189. if (RegQueryInfoKey(hReg, NULL, NULL, 0, &cUsers, &cbMaxSubKeyLen, NULL, NULL, NULL, NULL,
  190. NULL, NULL) != ERROR_SUCCESS)
  191. {
  192. hr = E_FAIL;
  193. goto exit;
  194. }
  195. // No users ?
  196. if (cUsers == 0)
  197. goto done;
  198. if (fDisabled)
  199. cUsers = 1;
  200. // Allocate the users array
  201. MemAlloc((LPVOID *)&m_rguidUsers, sizeof(GUID) * cUsers);
  202. if (!m_rguidUsers)
  203. {
  204. cUsers = 0;
  205. goto done;
  206. }
  207. // Zero init
  208. ZeroMemory(m_rguidUsers, sizeof(GUID) * cUsers);
  209. if (fDisabled)
  210. {
  211. MU_GetDefaultUserID(&m_rguidUsers[0]);
  212. goto done;
  213. }
  214. while (TRUE)
  215. {
  216. HKEY hkUserKey;
  217. DWORD dwStatus, dwSize, dwType;
  218. TCHAR szKeyNameBuffer[MAX_PATH];
  219. TCHAR szUid[255];
  220. if (RegEnumKey(hReg, dwEnumIndex++, szKeyNameBuffer,MAX_PATH)
  221. != ERROR_SUCCESS)
  222. break;
  223. if (RegOpenKey(hReg, szKeyNameBuffer, &hkUserKey) == ERROR_SUCCESS)
  224. {
  225. dwSize = sizeof(szUid);
  226. dwStatus = RegQueryValueEx(hkUserKey, c_szUserID, NULL, &dwType, (LPBYTE)szUid, &dwSize);
  227. Assert(ERROR_SUCCESS == dwStatus);
  228. if (ERROR_SUCCESS == dwStatus)
  229. GUIDFromAString(szUid, &m_rguidUsers[dwEnumIndex - 1]);
  230. RegCloseKey(hkUserKey);
  231. }
  232. else
  233. AssertSz(FALSE, "Couldn't open user's key");
  234. }
  235. done:
  236. m_cCountUsers = cUsers;
  237. m_fInited = TRUE;
  238. exit:
  239. if (hReg)
  240. RegCloseKey(hReg);
  241. return hr;
  242. }
  243. STDMETHODIMP CEnumUserIdentity::_Init(DWORD dwCurrentUser, DWORD dwCountUsers, GUID *prgUserCookies)
  244. {
  245. m_dwCurrentUser = dwCurrentUser;
  246. m_cCountUsers = dwCountUsers;
  247. // Allocate the users array
  248. MemAlloc((LPVOID *)&m_rguidUsers, sizeof(GUID) * dwCountUsers);
  249. if (!m_rguidUsers)
  250. return E_OUTOFMEMORY;
  251. CopyMemory(m_rguidUsers, prgUserCookies, sizeof(GUID) * dwCountUsers);
  252. m_fInited = TRUE;
  253. return S_OK;
  254. }