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

Windows Kernel

Development Platform:

Visual C++

  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.     
  35.     *ppv=NULL;
  36.     // Validate requested interface
  37.     if(IID_IUnknown == riid)
  38.     {
  39.         *ppv = (IUnknown *)this;
  40.     }
  41.     else if(IID_IEnumUserIdentity == riid)
  42.     {
  43.         *ppv = (IEnumUserIdentity *)this;
  44.     }
  45.     // Addref through the interface
  46.     if( NULL != *ppv ) {
  47.         ((LPUNKNOWN)*ppv)->AddRef();
  48.         return S_OK;
  49.     }
  50.     return E_NOINTERFACE;
  51. }
  52. STDMETHODIMP_(ULONG) CEnumUserIdentity::AddRef()
  53. {
  54.     return ++m_cRef;
  55. }
  56. STDMETHODIMP_(ULONG) CEnumUserIdentity::Release()
  57. {
  58.     if( 0L != --m_cRef )
  59.         return m_cRef;
  60.     delete this;
  61.     return 0L;
  62. }
  63. // 
  64. // IEnumUserIdentity members
  65. //
  66. STDMETHODIMP CEnumUserIdentity::Next(ULONG celt, IUnknown **rgelt, ULONG *pceltFetched)
  67. {
  68. ULONG celtFetched = 0;
  69. HRESULT hr = ResultFromScode(S_OK);
  70.     CUserIdentity   *pIdentity;
  71.     if (!m_fInited)
  72.         hr = _Init();
  73.     if (FAILED(hr))
  74.         return hr;
  75.     while (celt) 
  76.     {
  77.         if (m_dwCurrentUser == m_cCountUsers) {
  78.             hr = ResultFromScode(S_FALSE);
  79.             break;
  80.         }
  81.         pIdentity = new CUserIdentity;
  82.         if (pIdentity)
  83.         {
  84.             if (SUCCEEDED(pIdentity->InitFromCookie(&m_rguidUsers[m_dwCurrentUser])))
  85.             {
  86.                 rgelt[celtFetched++] = pIdentity;
  87.                 m_dwCurrentUser++;
  88.             }
  89.             else
  90.             {
  91.                 pIdentity->Release();
  92.                 hr = ResultFromScode(E_OUTOFMEMORY);
  93.                 break;
  94.             }
  95.         }
  96.         else
  97.         {
  98.             hr = ResultFromScode(E_OUTOFMEMORY);
  99.             break;
  100.         }
  101.         celt--;
  102.     }
  103.     if (FAILED(hr))
  104.     {
  105.         for (ULONG i = 0; i < celtFetched; i++)
  106.             rgelt[i]->Release();
  107.         celtFetched = 0;
  108.     }
  109. if (pceltFetched != NULL)
  110. *pceltFetched = celtFetched;
  111. return hr;
  112. }
  113. STDMETHODIMP CEnumUserIdentity::Skip(ULONG celt)
  114. {
  115.     SCODE sc;
  116.     HRESULT hr = S_OK;
  117.     if (!m_fInited)
  118.         hr = _Init();
  119.     if (FAILED(hr))
  120.         return hr;
  121. if (m_dwCurrentUser + celt > m_cCountUsers) {
  122. m_dwCurrentUser = m_cCountUsers;
  123. sc = S_FALSE;
  124. }
  125. else {
  126. m_dwCurrentUser += celt;
  127. sc = S_OK;
  128. }
  129. return ResultFromScode(sc);
  130. }
  131. STDMETHODIMP CEnumUserIdentity::Reset(void)
  132. {
  133.     m_dwCurrentUser = 0;
  134.     _Cleanup();
  135.     return S_OK;
  136. }
  137. STDMETHODIMP CEnumUserIdentity::Clone(IEnumUserIdentity **ppenum)
  138. {
  139.     CEnumUserIdentity   *pEnum;
  140.     HRESULT             hr = S_OK;
  141.     if (!m_fInited)
  142.         hr = _Init();
  143.     if (FAILED(hr))
  144.         return hr;
  145.     pEnum = new CEnumUserIdentity;
  146.     if (pEnum)
  147.     {
  148.         hr = pEnum->_Init(m_dwCurrentUser, m_cCountUsers, m_rguidUsers);
  149.         if (SUCCEEDED(hr))
  150.             *ppenum = pEnum;
  151.     }
  152.     return hr;
  153. }
  154. STDMETHODIMP CEnumUserIdentity::GetCount(ULONG *pnCount)
  155. {
  156.     HRESULT hr = S_OK;
  157.     if (!m_fInited)
  158.         hr = _Init();
  159.     if (FAILED(hr))
  160.         return hr;
  161.     *pnCount = m_cCountUsers;
  162.     return S_OK;
  163. }
  164. STDMETHODIMP CEnumUserIdentity::_Cleanup()
  165. {
  166.     SafeMemFree(m_rguidUsers);
  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.     
  203.     if (!m_rguidUsers)
  204.     {
  205.         cUsers = 0;
  206.         goto done;
  207.     }
  208.     // Zero init
  209.     ZeroMemory(m_rguidUsers, sizeof(GUID) * cUsers);
  210.     if (fDisabled)
  211.     {
  212.         MU_GetDefaultUserID(&m_rguidUsers[0]);
  213.         goto done;
  214.     }
  215.     while (TRUE) 
  216.     {
  217.         HKEY    hkUserKey;
  218.         DWORD   dwStatus, dwSize, dwType;
  219.         TCHAR   szKeyNameBuffer[MAX_PATH];
  220.         TCHAR   szUid[255];
  221.         if (RegEnumKey(hReg, dwEnumIndex++, szKeyNameBuffer,MAX_PATH)
  222.             !=  ERROR_SUCCESS)
  223.             break;
  224.         
  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.     
  252.     if (!m_rguidUsers)
  253.         return E_OUTOFMEMORY;
  254.     CopyMemory(m_rguidUsers, prgUserCookies, sizeof(GUID) * dwCountUsers);
  255.     m_fInited = TRUE;
  256.     
  257.     return S_OK;
  258. }