|
|
//
// ident.cpp - implementation of CIdentity class
//
#include "private.h"
#include "strconst.h"
#include "multiusr.h"
//
// Constructor / destructor
//
CEnumUserIdentity::CEnumUserIdentity() { m_cRef = 1; m_dwCurrentUser = 0; m_cCountUsers = 0; m_rguidUsers = NULL; m_fInited = FALSE;
DllAddRef(); }
CEnumUserIdentity::~CEnumUserIdentity() { _Cleanup();
DllRelease(); }
//
// IUnknown members
//
STDMETHODIMP CEnumUserIdentity::QueryInterface( REFIID riid, void **ppv) { if (NULL == ppv) { return E_INVALIDARG; } *ppv=NULL;
// Validate requested interface
if(IID_IUnknown == riid) { *ppv = (IUnknown *)this; } else if(IID_IEnumUserIdentity == riid) { *ppv = (IEnumUserIdentity *)this; }
// Addref through the interface
if( NULL != *ppv ) { ((LPUNKNOWN)*ppv)->AddRef(); return S_OK; }
return E_NOINTERFACE; }
STDMETHODIMP_(ULONG) CEnumUserIdentity::AddRef() { return ++m_cRef; }
STDMETHODIMP_(ULONG) CEnumUserIdentity::Release() { if( 0L != --m_cRef ) return m_cRef;
delete this; return 0L; }
//
// IEnumUserIdentity members
//
STDMETHODIMP CEnumUserIdentity::Next(ULONG celt, IUnknown **rgelt, ULONG *pceltFetched) { ULONG celtFetched = 0; HRESULT hr = ResultFromScode(S_OK); CUserIdentity *pIdentity;
if (!m_fInited) hr = _Init();
if (FAILED(hr)) return hr;
while (celt) { if (m_dwCurrentUser == m_cCountUsers) { hr = ResultFromScode(S_FALSE); break; }
pIdentity = new CUserIdentity; if (pIdentity) { if (SUCCEEDED(pIdentity->InitFromCookie(&m_rguidUsers[m_dwCurrentUser]))) { rgelt[celtFetched++] = pIdentity; m_dwCurrentUser++; } else { pIdentity->Release(); hr = ResultFromScode(E_OUTOFMEMORY); break; } } else { hr = ResultFromScode(E_OUTOFMEMORY); break; } celt--; }
if (FAILED(hr)) { for (ULONG i = 0; i < celtFetched; i++) rgelt[i]->Release(); celtFetched = 0; }
if (pceltFetched != NULL) *pceltFetched = celtFetched;
return hr; }
STDMETHODIMP CEnumUserIdentity::Skip(ULONG celt) { SCODE sc; HRESULT hr = S_OK;
if (!m_fInited) hr = _Init();
if (FAILED(hr)) return hr;
if (m_dwCurrentUser + celt > m_cCountUsers) { m_dwCurrentUser = m_cCountUsers; sc = S_FALSE; } else { m_dwCurrentUser += celt; sc = S_OK; }
return ResultFromScode(sc); }
STDMETHODIMP CEnumUserIdentity::Reset(void) { m_dwCurrentUser = 0; _Cleanup(); return S_OK; }
STDMETHODIMP CEnumUserIdentity::Clone(IEnumUserIdentity **ppenum) { CEnumUserIdentity *pEnum; HRESULT hr = S_OK;
if (!m_fInited) hr = _Init();
if (FAILED(hr)) return hr;
pEnum = new CEnumUserIdentity;
if (pEnum) { hr = pEnum->_Init(m_dwCurrentUser, m_cCountUsers, m_rguidUsers);
if (SUCCEEDED(hr)) *ppenum = pEnum; else delete pEnum; }
return hr; }
STDMETHODIMP CEnumUserIdentity::GetCount(ULONG *pnCount) { HRESULT hr = S_OK;
if (!m_fInited) hr = _Init();
if (FAILED(hr)) return hr;
*pnCount = m_cCountUsers;
return S_OK; }
STDMETHODIMP CEnumUserIdentity::_Cleanup() { MemFree(m_rguidUsers); m_rguidUsers = NULL; m_cCountUsers = 0; m_fInited = FALSE;
return S_OK; }
STDMETHODIMP CEnumUserIdentity::_Init() { HRESULT hr=S_OK; HKEY hReg = NULL; DWORD cUsers = 0; DWORD cbMaxSubKeyLen; DWORD cb; DWORD dwEnumIndex = 0; BOOL fDisabled = MU_IdentitiesDisabled();
m_cCountUsers = 0;
// Open or Create root server key
if (RegCreateKeyEx(HKEY_CURRENT_USER, c_szRegRoot, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hReg, NULL) != ERROR_SUCCESS) { hr = E_FAIL; goto exit; }
// Enumerate keys
if (RegQueryInfoKey(hReg, NULL, NULL, 0, &cUsers, &cbMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { hr = E_FAIL; goto exit; }
// No users ?
if (cUsers == 0) goto done;
if (fDisabled) cUsers = 1;
// Allocate the users array
MemAlloc((LPVOID *)&m_rguidUsers, sizeof(GUID) * cUsers); if (!m_rguidUsers) { cUsers = 0; goto done; }
// Zero init
ZeroMemory(m_rguidUsers, sizeof(GUID) * cUsers);
if (fDisabled) { MU_GetDefaultUserID(&m_rguidUsers[0]); goto done; }
while (TRUE) { HKEY hkUserKey; DWORD dwStatus, dwSize, dwType; TCHAR szKeyNameBuffer[MAX_PATH]; TCHAR szUid[255];
if (RegEnumKey(hReg, dwEnumIndex++, szKeyNameBuffer,MAX_PATH) != ERROR_SUCCESS) break; if (RegOpenKey(hReg, szKeyNameBuffer, &hkUserKey) == ERROR_SUCCESS) { dwSize = sizeof(szUid); dwStatus = RegQueryValueEx(hkUserKey, c_szUserID, NULL, &dwType, (LPBYTE)szUid, &dwSize); Assert(ERROR_SUCCESS == dwStatus);
if (ERROR_SUCCESS == dwStatus) GUIDFromAString(szUid, &m_rguidUsers[dwEnumIndex - 1]);
RegCloseKey(hkUserKey); } else AssertSz(FALSE, "Couldn't open user's key"); }
done: m_cCountUsers = cUsers; m_fInited = TRUE;
exit: if (hReg) RegCloseKey(hReg);
return hr; }
STDMETHODIMP CEnumUserIdentity::_Init(DWORD dwCurrentUser, DWORD dwCountUsers, GUID *prgUserCookies) { m_dwCurrentUser = dwCurrentUser; m_cCountUsers = dwCountUsers;
// Allocate the users array
MemAlloc((LPVOID *)&m_rguidUsers, sizeof(GUID) * dwCountUsers); if (!m_rguidUsers) return E_OUTOFMEMORY;
CopyMemory(m_rguidUsers, prgUserCookies, sizeof(GUID) * dwCountUsers);
m_fInited = TRUE; return S_OK; }
|