324 lines
6.1 KiB
C++
324 lines
6.1 KiB
C++
//
|
|
// 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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|