Leaked source code of windows server 2003
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.

325 lines
6.5 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. else
  151. delete pEnum;
  152. }
  153. return hr;
  154. }
  155. STDMETHODIMP CEnumUserIdentity::GetCount(ULONG *pnCount)
  156. {
  157. HRESULT hr = S_OK;
  158. if (!m_fInited)
  159. hr = _Init();
  160. if (FAILED(hr))
  161. return hr;
  162. *pnCount = m_cCountUsers;
  163. return S_OK;
  164. }
  165. STDMETHODIMP CEnumUserIdentity::_Cleanup()
  166. {
  167. MemFree(m_rguidUsers);
  168. m_rguidUsers = NULL;
  169. m_cCountUsers = 0;
  170. m_fInited = FALSE;
  171. return S_OK;
  172. }
  173. STDMETHODIMP CEnumUserIdentity::_Init()
  174. {
  175. HRESULT hr=S_OK;
  176. HKEY hReg = NULL;
  177. DWORD cUsers = 0;
  178. DWORD cbMaxSubKeyLen;
  179. DWORD cb;
  180. DWORD dwEnumIndex = 0;
  181. BOOL fDisabled = MU_IdentitiesDisabled();
  182. m_cCountUsers = 0;
  183. // Open or Create root server key
  184. if (RegCreateKeyEx(HKEY_CURRENT_USER, c_szRegRoot, 0, NULL, REG_OPTION_NON_VOLATILE,
  185. KEY_ALL_ACCESS, NULL, &hReg, NULL) != ERROR_SUCCESS)
  186. {
  187. hr = E_FAIL;
  188. goto exit;
  189. }
  190. // Enumerate keys
  191. if (RegQueryInfoKey(hReg, NULL, NULL, 0, &cUsers, &cbMaxSubKeyLen, NULL, NULL, NULL, NULL,
  192. NULL, NULL) != ERROR_SUCCESS)
  193. {
  194. hr = E_FAIL;
  195. goto exit;
  196. }
  197. // No users ?
  198. if (cUsers == 0)
  199. goto done;
  200. if (fDisabled)
  201. cUsers = 1;
  202. // Allocate the users array
  203. MemAlloc((LPVOID *)&m_rguidUsers, sizeof(GUID) * cUsers);
  204. if (!m_rguidUsers)
  205. {
  206. cUsers = 0;
  207. goto done;
  208. }
  209. // Zero init
  210. ZeroMemory(m_rguidUsers, sizeof(GUID) * cUsers);
  211. if (fDisabled)
  212. {
  213. MU_GetDefaultUserID(&m_rguidUsers[0]);
  214. goto done;
  215. }
  216. while (TRUE)
  217. {
  218. HKEY hkUserKey;
  219. DWORD dwStatus, dwSize, dwType;
  220. TCHAR szKeyNameBuffer[MAX_PATH];
  221. TCHAR szUid[255];
  222. if (RegEnumKey(hReg, dwEnumIndex++, szKeyNameBuffer,MAX_PATH)
  223. != ERROR_SUCCESS)
  224. break;
  225. if (RegOpenKey(hReg, szKeyNameBuffer, &hkUserKey) == ERROR_SUCCESS)
  226. {
  227. dwSize = sizeof(szUid);
  228. dwStatus = RegQueryValueEx(hkUserKey, c_szUserID, NULL, &dwType, (LPBYTE)szUid, &dwSize);
  229. Assert(ERROR_SUCCESS == dwStatus);
  230. if (ERROR_SUCCESS == dwStatus)
  231. GUIDFromAString(szUid, &m_rguidUsers[dwEnumIndex - 1]);
  232. RegCloseKey(hkUserKey);
  233. }
  234. else
  235. AssertSz(FALSE, "Couldn't open user's key");
  236. }
  237. done:
  238. m_cCountUsers = cUsers;
  239. m_fInited = TRUE;
  240. exit:
  241. if (hReg)
  242. RegCloseKey(hReg);
  243. return hr;
  244. }
  245. STDMETHODIMP CEnumUserIdentity::_Init(DWORD dwCurrentUser, DWORD dwCountUsers, GUID *prgUserCookies)
  246. {
  247. m_dwCurrentUser = dwCurrentUser;
  248. m_cCountUsers = dwCountUsers;
  249. // Allocate the users array
  250. MemAlloc((LPVOID *)&m_rguidUsers, sizeof(GUID) * dwCountUsers);
  251. if (!m_rguidUsers)
  252. return E_OUTOFMEMORY;
  253. CopyMemory(m_rguidUsers, prgUserCookies, sizeof(GUID) * dwCountUsers);
  254. m_fInited = TRUE;
  255. return S_OK;
  256. }