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.
503 lines
11 KiB
503 lines
11 KiB
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 1998
|
|
*
|
|
* TITLE: IEnumWFI.Cpp
|
|
*
|
|
* VERSION: 2.1
|
|
*
|
|
* AUTHOR: ByronC
|
|
*
|
|
* DATE: 20 Mar, 1998
|
|
* 08/10/1999 - Converted from IEnumWiaFormatInfo to IEnumWIA_FORMAT_INFO
|
|
*
|
|
* DESCRIPTION:
|
|
* Implementation of IEnumWIA_FORMAT_INFO interface for
|
|
* WIA device class driver server.
|
|
*
|
|
*******************************************************************************/
|
|
#include "precomp.h"
|
|
|
|
#include "stiexe.h"
|
|
|
|
#include "wiamindr.h"
|
|
#include "coredbg.h"
|
|
|
|
#include "ienumwfi.h"
|
|
|
|
#include "helpers.h"
|
|
|
|
|
|
/********************************************************************************\
|
|
*
|
|
* AllocCopyWFI
|
|
*
|
|
* DESCRIPTION:
|
|
* Allocates and copies an array of WIA_FORMAT_INFO structures.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* ulCount - the number of elements to copy
|
|
* pwfiIn - pointer to the WIA_FORMAT_INFO structures
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Pointer to the newly created array.
|
|
* History:
|
|
*
|
|
* 10/04/99 Original Version
|
|
*
|
|
\********************************************************************************/
|
|
WIA_FORMAT_INFO *AllocCopyWFI(
|
|
ULONG ulCount,
|
|
WIA_FORMAT_INFO *pwfiIn)
|
|
{
|
|
DBG_FN(::AllocCopyWFI);
|
|
|
|
if (!ulCount) {
|
|
return NULL;
|
|
}
|
|
|
|
WIA_FORMAT_INFO *pwfi = (WIA_FORMAT_INFO*) CoTaskMemAlloc(sizeof(WIA_FORMAT_INFO) * ulCount);
|
|
|
|
if (pwfi) {
|
|
|
|
for (ULONG i = 0; i < ulCount; i++) {
|
|
|
|
//
|
|
// Copy the structure
|
|
//
|
|
|
|
memcpy(&pwfi[i], &pwfiIn[i], sizeof(WIA_FORMAT_INFO));
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERR(("CEnumWiaFormatInfo : AllocCopyFe, unable to allocate WIA_FORMAT_INFO buffer"));
|
|
}
|
|
|
|
return pwfi;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* CEnumWiaFormatInfo
|
|
*
|
|
* DESCRIPTION:
|
|
* CEnumWiaFormatInfo Constructor.
|
|
*
|
|
* History:
|
|
*
|
|
* 10/04/99 Original Version
|
|
*
|
|
\********************************************************************************/
|
|
|
|
CEnumWiaFormatInfo::CEnumWiaFormatInfo()
|
|
|
|
{
|
|
m_cRef = 0;
|
|
m_iCur = 0;
|
|
m_cFormatInfo = 0;
|
|
m_pFormatInfo = NULL;
|
|
m_pCWiaItem = NULL;
|
|
}
|
|
|
|
|
|
/********************************************************************************\
|
|
*
|
|
* Initialize
|
|
*
|
|
* DESCRIPTION:
|
|
* Sets up the enumerator. It makes a call down to the driver for the
|
|
* information needed for the enumeration.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pWiaItem - A pointer to the calling item.
|
|
* pWiaMiniDrv - A pointer to the corresponding mini driver
|
|
* lFlags - flags
|
|
*
|
|
* Return Value:
|
|
*
|
|
* status
|
|
*
|
|
* History:
|
|
*
|
|
* 10/04/99 Original Version
|
|
*
|
|
\********************************************************************************/
|
|
|
|
HRESULT CEnumWiaFormatInfo::Initialize(
|
|
CWiaItem *pWiaItem)
|
|
{
|
|
DBG_FN(CEnumWiaFormatInfo::Initialize);
|
|
|
|
HRESULT hr = E_FAIL;
|
|
WIA_FORMAT_INFO *pFormat;
|
|
|
|
m_iCur = 0;
|
|
m_cFormatInfo = 0;
|
|
m_pCWiaItem = pWiaItem;
|
|
|
|
//
|
|
// Make call to driver. Driver returns an array of WIA_FORMAT_INFO.
|
|
//
|
|
|
|
LONG lFlags = 0;
|
|
|
|
{
|
|
LOCK_WIA_DEVICE _LWD(pWiaItem, &hr);
|
|
|
|
if(SUCCEEDED(hr)) {
|
|
hr = m_pCWiaItem->m_pActiveDevice->m_DrvWrapper.WIA_drvGetWiaFormatInfo((BYTE*)pWiaItem,
|
|
lFlags,
|
|
&m_cFormatInfo,
|
|
&pFormat,
|
|
&(pWiaItem->m_lLastDevErrVal));
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
//
|
|
// Check that the count we get back is valid. Zero elements is supported.
|
|
//
|
|
if (m_cFormatInfo < 0) {
|
|
m_cFormatInfo = 0;
|
|
DBG_ERR(("CEnumWiaFormatInfo::Initialize, drvGetWiaFormatInfo returned invalid count"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// Check whether pointer received is valid
|
|
//
|
|
|
|
if (IsBadReadPtr(pFormat, sizeof(WIA_FORMAT_INFO)*m_cFormatInfo)) {
|
|
DBG_ERR(("CEnumWiaFormatInfo::Initialize, drvGetWiaFormatInfo returned invalid pointer"));
|
|
return E_POINTER;
|
|
}
|
|
|
|
//
|
|
// Make a local copy in case minidriver goes away.
|
|
//
|
|
|
|
m_pFormatInfo = AllocCopyWFI(m_cFormatInfo, pFormat);
|
|
} else {
|
|
DBG_ERR(("CEnumWiaFormatInfo::Initialize, Error calling driver: drvGetWiaFormatInfo failed"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/********************************************************************************\
|
|
*
|
|
* ~CEnumWiaFormatInfo
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* Destructor. Frees up the m_prgfe structure, if it was allocated
|
|
*
|
|
* History:
|
|
*
|
|
* 10/04/99 Original Version
|
|
*
|
|
\********************************************************************************/
|
|
|
|
CEnumWiaFormatInfo::~CEnumWiaFormatInfo()
|
|
{
|
|
DBG_FN(CEnumWiaFormatInfo::~CEnumWiaFormatInfo);
|
|
if (NULL!=m_pFormatInfo) {
|
|
|
|
//
|
|
// Free our local copy of the device's WIA_FORMAT_INFOs
|
|
//
|
|
|
|
CoTaskMemFree(m_pFormatInfo);
|
|
}
|
|
m_cRef = 0;
|
|
m_iCur = 0;
|
|
m_cFormatInfo = 0;
|
|
m_pFormatInfo = NULL;
|
|
m_pCWiaItem = NULL;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* QueryInterface
|
|
* AddRef
|
|
* Release
|
|
*
|
|
* DESCRIPTION:
|
|
* CEnumWiaFormatInfo IUnknown Interface.
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaFormatInfo::QueryInterface(const IID& iid, void** ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if (iid == IID_IUnknown || iid == IID_IEnumWIA_FORMAT_INFO) {
|
|
*ppv = (IEnumWIA_FORMAT_INFO*) this;
|
|
} else {
|
|
return E_NOINTERFACE;
|
|
}
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG _stdcall CEnumWiaFormatInfo::AddRef()
|
|
{
|
|
InterlockedIncrement((long*) &m_cRef);
|
|
return m_cRef;
|
|
}
|
|
|
|
ULONG _stdcall CEnumWiaFormatInfo::Release()
|
|
{
|
|
ULONG ulRefCount = m_cRef - 1;
|
|
|
|
if (InterlockedDecrement((long*) &m_cRef) == 0) {
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return ulRefCount;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* Next
|
|
*
|
|
* Device capability enumerator, this enumerator returns an array of
|
|
* WIA_FORMAT_INFO structs.
|
|
* Next_Proxy ensures that last parameter is non-NULL.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* cwfi - number requested.
|
|
* pwfi - WIA_FORMAT_INFO returned in this array
|
|
* pcwfi - returned number of entries written. NULLs are
|
|
* ignored.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 10/04/99 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaFormatInfo::Next(
|
|
ULONG cwfi,
|
|
WIA_FORMAT_INFO *pwfi,
|
|
ULONG *pcwfi)
|
|
{
|
|
DBG_FN(CEnumWiaFormatInfo::Next);
|
|
|
|
HRESULT hr;
|
|
ULONG ulCount;
|
|
ULONG cReturn = 0L;
|
|
|
|
//
|
|
// Parameter validation.
|
|
//
|
|
|
|
if (NULL == m_pFormatInfo) {
|
|
return S_FALSE;
|
|
}
|
|
|
|
*pcwfi = 0L;
|
|
|
|
//
|
|
// Check if the current index indicates that we've already been through
|
|
// all the elements.
|
|
//
|
|
|
|
if (m_iCur >= (ULONG)m_cFormatInfo) {
|
|
return S_FALSE;
|
|
}
|
|
|
|
//
|
|
// Check that the requested number of elements exist. If not,
|
|
// set ulCount to the remaining number of elements.
|
|
//
|
|
|
|
if (cwfi > (m_cFormatInfo - m_iCur)) {
|
|
ulCount = m_cFormatInfo - m_iCur;
|
|
} else {
|
|
ulCount = cwfi;
|
|
}
|
|
|
|
//
|
|
// Copy the structres into the return
|
|
//
|
|
|
|
for (ULONG i = 0; i < ulCount; i++) {
|
|
|
|
//
|
|
// Make the copy
|
|
//
|
|
|
|
memcpy(&pwfi[i], &m_pFormatInfo[m_iCur++], sizeof(WIA_FORMAT_INFO));
|
|
}
|
|
|
|
*pcwfi = ulCount;
|
|
|
|
//
|
|
// Return S_FALSE if we returned less elements than requested
|
|
//
|
|
|
|
if (ulCount < cwfi) {
|
|
return S_FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* Skip
|
|
*
|
|
* Skips WIA_FORMAT_INFOs in the enumeration.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* celt - number of items to skip.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* status
|
|
*
|
|
* History:
|
|
*
|
|
* 12/04/99 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaFormatInfo::Skip(ULONG cwfi)
|
|
{
|
|
DBG_FN(CEnumWiaFormatInfo::Skip);
|
|
|
|
if ((((m_iCur + cwfi) >= (ULONG)m_cFormatInfo))
|
|
|| (NULL == m_pFormatInfo)) {
|
|
return S_FALSE;
|
|
}
|
|
|
|
m_iCur+= cwfi;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* EnumDC::Reset
|
|
*
|
|
* Resets the enumeration to the first element
|
|
*
|
|
* Arguments:
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* status
|
|
*
|
|
* History:
|
|
*
|
|
* 16/03/99 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaFormatInfo::Reset(void)
|
|
{
|
|
DBG_FN(CEnumWiaFormatInfo::Reset);
|
|
m_iCur = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* Clone
|
|
*
|
|
* Creates another IEnumWIA_FORMAT_INFO enumeration object and returns an
|
|
* interface pointer to it.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* ppIEnum - Address that receives the new enumeration object
|
|
*
|
|
* Return Value:
|
|
*
|
|
*
|
|
* History:
|
|
*
|
|
* 16/03/99 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaFormatInfo::Clone(IEnumWIA_FORMAT_INFO **ppIEnum)
|
|
{
|
|
DBG_FN(CEnumWiaFormatInfo::Clone);
|
|
HRESULT hr;
|
|
CEnumWiaFormatInfo *pClone;
|
|
|
|
*ppIEnum = NULL;
|
|
|
|
//
|
|
// Create the clone
|
|
//
|
|
|
|
pClone = new CEnumWiaFormatInfo();
|
|
|
|
if (!pClone) {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
hr = pClone->Initialize(m_pCWiaItem);
|
|
if (SUCCEEDED(hr)) {
|
|
pClone->AddRef();
|
|
pClone->m_iCur = m_iCur;
|
|
*ppIEnum = pClone;
|
|
} else {
|
|
DBG_ERR(("CEnumWiaFormatInfo::Clone, Initialization failed"));
|
|
delete pClone;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* GetCount
|
|
*
|
|
* Returns the number of elements stored in this enumerator.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pcelt - address of ULONG where to put the number of elements.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status - S_OK if successful
|
|
* E_FAIL if failed
|
|
*
|
|
* History:
|
|
*
|
|
* 05/07/99 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
HRESULT _stdcall CEnumWiaFormatInfo::GetCount(ULONG *pcelt)
|
|
{
|
|
DBG_FN(CEnumWiaFormatInfo::GetCount);
|
|
|
|
*pcelt = 0;
|
|
|
|
//
|
|
// Check that we actually have a FORMAETC list and that the count
|
|
// has a non-zero value.
|
|
//
|
|
|
|
if(m_cFormatInfo && m_pFormatInfo) {
|
|
|
|
*pcelt = m_cFormatInfo;
|
|
return S_OK;
|
|
}
|
|
|
|
return E_FAIL;
|
|
}
|
|
|