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.
447 lines
9.2 KiB
447 lines
9.2 KiB
// WMDMDeviceEnum.cpp : Implementation of CWMDMDeviceEnum
|
|
#include "stdafx.h"
|
|
#include "mswmdm.h"
|
|
#include "spinfo.h"
|
|
#include "WMDMDeviceEnum.h"
|
|
#include "Device.h"
|
|
#include "loghelp.h"
|
|
#include "scserver.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWMDMDeviceEnum
|
|
|
|
extern CSPInfo **g_pSPs;
|
|
extern WORD g_wSPCount;
|
|
extern CSecureChannelServer *g_pAppSCServer;
|
|
|
|
CWMDMDeviceEnum::CWMDMDeviceEnum()
|
|
: m_ppEnums(NULL), m_wCurrentSP(0), m_wSPCount(0)
|
|
{
|
|
GlobalAddRef();
|
|
|
|
m_pwSPSkipped=NULL;
|
|
hrInitializeEnumArray();
|
|
}
|
|
|
|
CWMDMDeviceEnum::~CWMDMDeviceEnum()
|
|
{
|
|
if (m_ppEnums)
|
|
{
|
|
for (WORD x=0;x<m_wSPCount;x++)
|
|
m_ppEnums[x]->Release();
|
|
delete m_ppEnums;
|
|
}
|
|
if( m_pwSPSkipped )
|
|
{
|
|
delete [] m_pwSPSkipped;
|
|
m_pwSPSkipped=NULL;
|
|
}
|
|
|
|
GlobalRelease();
|
|
}
|
|
|
|
|
|
|
|
// IWMDMEnumDevice Methods
|
|
HRESULT CWMDMDeviceEnum::Next(ULONG celt,
|
|
IWMDMDevice **ppDevice,
|
|
ULONG *pceltFetched)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
ULONG celtRemaining;
|
|
ULONG ulFetched;
|
|
ULONG ulX;
|
|
IMDSPDevice **ppDevList = NULL;
|
|
CComObject<CWMDMDevice> *pDevObj = NULL;
|
|
WORD *pwSPIndexList = NULL;
|
|
ULONG ulIndexOffset;
|
|
|
|
if (g_pAppSCServer)
|
|
{
|
|
if(!g_pAppSCServer->fIsAuthenticated())
|
|
{
|
|
hr = WMDM_E_NOTCERTIFIED;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
if (!ppDevice || !pceltFetched || celt == 0)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
|
|
m_csCurrentSP.Lock();
|
|
|
|
// If we have gone through all of the SPs then the user must reset
|
|
if (m_wCurrentSP > g_wSPCount - 1)
|
|
{
|
|
*pceltFetched = 0;
|
|
*ppDevice = NULL;
|
|
goto exit;
|
|
}
|
|
|
|
if( !m_pwSPSkipped )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
ppDevList = new IMDSPDevice *[celt];
|
|
if (!ppDevList)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
pwSPIndexList = new WORD[celt];
|
|
if (!pwSPIndexList)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
hr = E_FAIL;
|
|
if( m_ppEnums[m_wCurrentSP] )
|
|
{
|
|
hr = m_ppEnums[m_wCurrentSP]->Next(celt, ppDevList, &ulFetched);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ulFetched = 0;
|
|
hr = S_OK; // Ignore the failure, continue to search the next SP.
|
|
//goto exit;
|
|
}
|
|
|
|
for (ulIndexOffset=0;ulIndexOffset<ulFetched;ulIndexOffset++)
|
|
{
|
|
pwSPIndexList[ulIndexOffset] = m_pwSPSkipped[m_wCurrentSP];
|
|
}
|
|
|
|
if(celt != ulFetched)
|
|
{
|
|
celtRemaining = celt - ulFetched;
|
|
m_wCurrentSP++;
|
|
while (m_wCurrentSP < m_wSPCount)
|
|
{
|
|
hr = m_ppEnums[m_wCurrentSP]->Reset();
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_ppEnums[m_wCurrentSP]->Next(celtRemaining,
|
|
reinterpret_cast<IMDSPDevice **>(ppDevList + ulIndexOffset),
|
|
&ulFetched);
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
for ( UINT uFetchedIndex = 0;uFetchedIndex<ulFetched; ulIndexOffset++, uFetchedIndex++)
|
|
{
|
|
pwSPIndexList[ulIndexOffset] = m_pwSPSkipped[m_wCurrentSP];
|
|
}
|
|
|
|
if (celtRemaining == ulFetched)
|
|
{
|
|
// We have all of the device we need
|
|
celtRemaining = 0;
|
|
break;
|
|
}
|
|
celtRemaining = celtRemaining - ulFetched;
|
|
m_wCurrentSP++;
|
|
}
|
|
// Tell the caller how many devices we are returning.
|
|
*pceltFetched = celt - celtRemaining;
|
|
}
|
|
else
|
|
{
|
|
*pceltFetched = ulFetched;
|
|
}
|
|
|
|
m_csCurrentSP.Unlock();
|
|
|
|
for (ulX=0;ulX<*pceltFetched;ulX++)
|
|
{
|
|
hr = CComObject<CWMDMDevice>::CreateInstance(&pDevObj);
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = pDevObj->QueryInterface(IID_IWMDMDevice, reinterpret_cast<void**>(&ppDevice[ulX]));
|
|
if (FAILED(hr))
|
|
{
|
|
delete pDevObj;
|
|
goto exit;
|
|
}
|
|
|
|
pDevObj->SetContainedPointer(ppDevList[ulX], pwSPIndexList[ulX]);
|
|
// @@@@ Must release in all failure paths as well
|
|
ppDevList[ulX]->Release();
|
|
}
|
|
exit:
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (celt == *pceltFetched)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
if (*pceltFetched == 0)
|
|
{
|
|
*ppDevice = NULL;
|
|
}
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
|
|
if (ppDevList)
|
|
delete [] ppDevList;
|
|
if (pwSPIndexList)
|
|
delete [] pwSPIndexList;
|
|
|
|
hrLogDWORD("IWMDMEnumDevice::Next returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMDeviceEnum::Skip(ULONG celt, ULONG *pceltFetched)
|
|
{
|
|
HRESULT hr;
|
|
ULONG celtRemaining;
|
|
ULONG ulFetched;
|
|
|
|
if (g_pAppSCServer)
|
|
{
|
|
if(!g_pAppSCServer->fIsAuthenticated())
|
|
{
|
|
hr = WMDM_E_NOTCERTIFIED;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
if (!pceltFetched || celt == 0)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
|
|
m_csCurrentSP.Lock();
|
|
|
|
// If we have gone through all of the SPs then the user must reset
|
|
// @@@@ unsigned compare: consider g_wSPCount == 0
|
|
if (m_wCurrentSP > g_wSPCount - 1)
|
|
{
|
|
*pceltFetched = 0;
|
|
hr = S_OK;
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_ppEnums[m_wCurrentSP]->Skip(celt, &ulFetched);
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if(celt != ulFetched)
|
|
{
|
|
celtRemaining = celt - ulFetched;
|
|
m_wCurrentSP++;
|
|
while (m_wCurrentSP < m_wSPCount)
|
|
{
|
|
hr = m_ppEnums[m_wCurrentSP]->Reset();
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = m_ppEnums[m_wCurrentSP]->Skip(celtRemaining, &ulFetched);
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
if (celtRemaining == ulFetched)
|
|
{
|
|
// We have all of the device we need
|
|
celtRemaining = 0;
|
|
break;
|
|
}
|
|
celtRemaining = celtRemaining - ulFetched;
|
|
m_wCurrentSP++;
|
|
}
|
|
// Tell the caller how many devices we are returning.
|
|
*pceltFetched = celt - celtRemaining;
|
|
}
|
|
else
|
|
*pceltFetched = ulFetched;
|
|
|
|
m_csCurrentSP.Unlock();
|
|
|
|
exit:
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (celt == *pceltFetched)
|
|
hr = S_OK;
|
|
else
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
hrLogDWORD("IWMDMEnumDevice::Skip returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMDeviceEnum::Reset()
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (g_pAppSCServer)
|
|
{
|
|
if(!g_pAppSCServer->fIsAuthenticated())
|
|
{
|
|
hr = WMDM_E_NOTCERTIFIED;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
m_csCurrentSP.Lock();
|
|
|
|
m_wCurrentSP = 0;
|
|
|
|
hr = m_ppEnums[m_wCurrentSP]->Reset();
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
m_csCurrentSP.Unlock();
|
|
exit:
|
|
|
|
hrLogDWORD("IWMDMEnumDevice::Skip returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMDeviceEnum::Clone(IWMDMEnumDevice **ppEnumDevice)
|
|
{
|
|
HRESULT hr;
|
|
CComObject<CWMDMDeviceEnum> *pEnumObj;
|
|
|
|
if (g_pAppSCServer)
|
|
{
|
|
if(!g_pAppSCServer->fIsAuthenticated())
|
|
{
|
|
hr = WMDM_E_NOTCERTIFIED;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
if (!ppEnumDevice)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto exit;
|
|
}
|
|
|
|
m_csCurrentSP.Lock();
|
|
|
|
hr = CComObject<CWMDMDeviceEnum>::CreateInstance(&pEnumObj);
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = pEnumObj->QueryInterface(IID_IWMDMEnumDevice, reinterpret_cast<void**>(ppEnumDevice));
|
|
if (FAILED(hr))
|
|
{
|
|
delete pEnumObj;
|
|
goto exit;
|
|
}
|
|
|
|
m_csCurrentSP.Unlock();
|
|
|
|
exit:
|
|
|
|
hrLogDWORD("IWMDMEnumDevice::Clone returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMDeviceEnum::hrInitializeEnumArray()
|
|
{
|
|
HRESULT hr;
|
|
WORD x;
|
|
IMDServiceProvider *pProv = NULL;
|
|
|
|
if( m_pwSPSkipped )
|
|
{
|
|
delete [] m_pwSPSkipped;
|
|
}
|
|
m_pwSPSkipped = new WORD [g_wSPCount];
|
|
if (!m_pwSPSkipped)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
m_ppEnums = new IMDSPEnumDevice *[g_wSPCount];
|
|
if (!m_ppEnums)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
hr = S_OK;
|
|
for (x=0,m_wSPCount=0;x<g_wSPCount;x++)
|
|
{
|
|
hr = g_pSPs[x]->hrGetInterface(&pProv);
|
|
if (FAILED(hr))
|
|
{
|
|
continue; // goto exit;
|
|
}
|
|
hr = pProv->EnumDevices(&m_ppEnums[m_wSPCount]);
|
|
if (FAILED(hr))
|
|
{
|
|
pProv->Release();
|
|
pProv = NULL;
|
|
continue; // goto exit;
|
|
}
|
|
|
|
m_pwSPSkipped[m_wSPCount]=x; // Remember the index for SAC
|
|
m_wSPCount++;
|
|
pProv->Release();
|
|
pProv = NULL;
|
|
|
|
}
|
|
|
|
exit:
|
|
if (pProv)
|
|
pProv->Release();
|
|
|
|
hrLogDWORD("CWMDMDeviceEnum::hrInitializeEnumArray returned 0x%08lx", hr, hr);
|
|
|
|
return hr;
|
|
}
|