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.
505 lines
10 KiB
505 lines
10 KiB
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 1998
|
|
*
|
|
* TITLE: IEnumItm.Cpp
|
|
*
|
|
* VERSION: 2.0
|
|
*
|
|
* AUTHOR: ReedB
|
|
*
|
|
* DATE: 30 July, 1998
|
|
*
|
|
* DESCRIPTION:
|
|
* Implementation of CEnumWiaItem for the WIA device class driver.
|
|
*
|
|
*******************************************************************************/
|
|
#include "precomp.h"
|
|
#include "stiexe.h"
|
|
|
|
#include "wiamindr.h"
|
|
|
|
|
|
#include "ienumitm.h"
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* QueryInterface
|
|
* AddRef
|
|
* Release
|
|
*
|
|
* DESCRIPTION:
|
|
* IUnknown Interface.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaItem::QueryInterface(const IID& iid, void** ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if (iid == IID_IUnknown || iid == IID_IEnumWiaItem) {
|
|
*ppv = (IEnumWiaItem*) this;
|
|
} else {
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return (S_OK);
|
|
}
|
|
|
|
ULONG _stdcall CEnumWiaItem::AddRef()
|
|
{
|
|
InterlockedIncrement((long*) &m_cRef);
|
|
return m_cRef;
|
|
}
|
|
|
|
ULONG _stdcall CEnumWiaItem::Release()
|
|
{
|
|
ULONG ulRefCount = m_cRef - 1;
|
|
|
|
if (InterlockedDecrement((long*) &m_cRef) == 0) {
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return ulRefCount;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CEnumWiaItem::CEnumWiaItem
|
|
*
|
|
* CEnumWiaItem constructor method.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 9/2/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
CEnumWiaItem::CEnumWiaItem()
|
|
{
|
|
m_cRef = 0;
|
|
m_ulIndex = 0;
|
|
m_pInitialFolder = NULL;
|
|
m_pCurrentItem = NULL;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CEnumWiaItem::Initialize
|
|
*
|
|
* CEnumWiaItem initialization method.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 9/2/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT CEnumWiaItem::Initialize(CWiaItem *pInitialFolder)
|
|
{
|
|
DBG_FN(CEnumWiaItem::Initialize);
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (!pInitialFolder) {
|
|
DBG_ERR(("CEnumWiaItem::Initialize, NULL parameters"));
|
|
return E_POINTER;
|
|
}
|
|
|
|
//
|
|
// Verify that initial folder is a folder item.
|
|
//
|
|
|
|
LONG lFlags;
|
|
|
|
pInitialFolder->GetItemType(&lFlags);
|
|
if (!(lFlags & (WiaItemTypeFolder | WiaItemTypeHasAttachments))) {
|
|
DBG_ERR(("CEnumWiaItem::Initialize, pInitialFolder is not a folder"));
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
m_pInitialFolder = pInitialFolder;
|
|
|
|
//
|
|
// Get the initial folders tree entry.
|
|
//
|
|
|
|
CWiaTree *pCurFolderTree;
|
|
|
|
pCurFolderTree = pInitialFolder->GetTreePtr();
|
|
|
|
if (pCurFolderTree) {
|
|
|
|
//
|
|
// Get the first child item from the initial folder.
|
|
//
|
|
|
|
pCurFolderTree->GetFirstChildItem(&m_pCurrentItem);
|
|
|
|
//
|
|
// Ref count the root item.
|
|
//
|
|
|
|
m_pInitialFolder->AddRef();
|
|
}
|
|
else {
|
|
DBG_ERR(("CEnumWiaItem::Initialize, initial folder doesn't have a tree entry"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CEnumWiaItem::~CEnumWiaItem
|
|
*
|
|
* CEnumWiaItem destructor method.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 9/2/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
CEnumWiaItem::~CEnumWiaItem()
|
|
{
|
|
DBG_FN(CEnumWiaItem::~CEnumWiaItem);
|
|
//
|
|
// Decrement root item ref count.
|
|
//
|
|
|
|
if (m_pInitialFolder != NULL) {
|
|
m_pInitialFolder->Release();
|
|
m_pInitialFolder = NULL;
|
|
}
|
|
|
|
//
|
|
// Set other members to empty since we're done with this enumerator.
|
|
//
|
|
|
|
m_ulIndex = 0;
|
|
m_pInitialFolder = NULL;
|
|
m_pCurrentItem = NULL;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CEnumWiaItem::Next
|
|
*
|
|
* Item enumerator, this enumerator only returns one item per call
|
|
* Next_Proxy ensures that last parameter is non-NULL.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* cItem - number requested
|
|
* ppIWiaItem - returned interface pointers
|
|
* pcItemFetched - returned number of objets (1 max)
|
|
*
|
|
* Return Value:
|
|
*
|
|
* status
|
|
*
|
|
* History:
|
|
*
|
|
* 9/2/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaItem::Next(
|
|
ULONG cItem,
|
|
IWiaItem **ppIWiaItem,
|
|
ULONG *pcItemFetched)
|
|
{
|
|
DBG_FN(CEnumWiaItem::Next);
|
|
HRESULT hr;
|
|
ULONG i;
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (cItem == 0) {
|
|
return S_OK;
|
|
}
|
|
|
|
if (! ppIWiaItem){
|
|
DBG_ERR(("CEnumWiaItem::Next NULL input parameters"));
|
|
return E_POINTER;
|
|
}
|
|
|
|
//
|
|
// Clear the return values
|
|
//
|
|
|
|
*pcItemFetched = 0;
|
|
ZeroMemory(ppIWiaItem, cItem * sizeof(IWiaItem *));
|
|
|
|
//
|
|
// Retrieve the requested items
|
|
//
|
|
|
|
for (i = 0; i < cItem; i++) {
|
|
|
|
//
|
|
// If m_pCurrentItem is NULL, then enumeration is complete
|
|
//
|
|
|
|
if (m_pCurrentItem == NULL) {
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Get the next item from the tree and increment refernce count
|
|
// before handing item pointer to the application.
|
|
//
|
|
|
|
hr = m_pCurrentItem->GetItemData((void **)(ppIWiaItem + i));
|
|
if (hr == S_OK) {
|
|
DBG_TRC(("CEnumWiaItem::Next, returning: 0x%08X", ppIWiaItem[i]));
|
|
(ppIWiaItem[i])->AddRef();
|
|
(*pcItemFetched)++;
|
|
} else {
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Advance item enumeration.
|
|
//
|
|
|
|
m_pCurrentItem->GetNextSiblingItem(&m_pCurrentItem);
|
|
|
|
}
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
//
|
|
// Unwind from the error
|
|
//
|
|
|
|
for (i = 0; i < *pcItemFetched; i++) {
|
|
ppIWiaItem[i]->Release();
|
|
ppIWiaItem[i] = NULL;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CEnumWiaItem::Skip
|
|
*
|
|
* Skip to the next enumerated item.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* cItem - number requested
|
|
*
|
|
* Return Value:
|
|
*
|
|
* status
|
|
*
|
|
* History:
|
|
*
|
|
* 9/2/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaItem::Skip(ULONG cItem)
|
|
{
|
|
DBG_FN(CEnumWiaItem::Skip);
|
|
CWiaTree *pOld;
|
|
|
|
pOld = m_pCurrentItem;
|
|
while (m_pCurrentItem && (cItem != 0)) {
|
|
|
|
m_pCurrentItem->GetNextSiblingItem(&m_pCurrentItem);
|
|
|
|
cItem--;
|
|
}
|
|
|
|
//
|
|
// If cItem != 0, then Skip request was too large, so restore
|
|
// m_pCurrentItem and return S_FALSE.
|
|
//
|
|
|
|
if (cItem) {
|
|
m_pCurrentItem = pOld;
|
|
return S_FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CEnumWiaItem::Reset
|
|
*
|
|
* Reset to the first enumerated item.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None
|
|
*
|
|
* Return Value:
|
|
*
|
|
* status
|
|
*
|
|
* History:
|
|
*
|
|
* 9/2/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaItem::Reset(void)
|
|
{
|
|
DBG_FN(CEnumWiaItem::Reset);
|
|
CWiaTree *pCurFolderTree;
|
|
|
|
pCurFolderTree = m_pInitialFolder->GetTreePtr();
|
|
|
|
if (pCurFolderTree) {
|
|
|
|
//
|
|
// Get the first child item from the initial folder.
|
|
//
|
|
|
|
pCurFolderTree->GetFirstChildItem(&m_pCurrentItem);
|
|
}
|
|
else {
|
|
DBG_ERR(("CEnumWiaItem::reset, initial folder doesn't have a tree entry"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CEnumWiaItem::Clone
|
|
*
|
|
* Clone the enumerator
|
|
*
|
|
* Arguments:
|
|
*
|
|
* ppIEnumWiaItem - Pointer to returned clone enumerator.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* status
|
|
*
|
|
* History:
|
|
*
|
|
* 9/2/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CEnumWiaItem::Clone(IEnumWiaItem **ppIEnumWiaItem)
|
|
{
|
|
DBG_FN(CEnumWiaItem::Clone);
|
|
HRESULT hr;
|
|
CEnumWiaItem *pClone;
|
|
|
|
*ppIEnumWiaItem = NULL;
|
|
|
|
//
|
|
// Create the clone
|
|
//
|
|
|
|
pClone = new CEnumWiaItem();
|
|
|
|
if (!pClone) {
|
|
DBG_ERR(("CEnumWiaItem::Clone new CEnumWiaItem failed"));
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
hr = pClone->Initialize(m_pInitialFolder);
|
|
if (SUCCEEDED(hr)) {
|
|
pClone->AddRef();
|
|
pClone->m_pCurrentItem = m_pCurrentItem;
|
|
*ppIEnumWiaItem = pClone;
|
|
} else {
|
|
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 CEnumWiaItem::GetCount(ULONG *pcelt)
|
|
{
|
|
DBG_FN(CEnumWiaItem::GetCount);
|
|
CWiaTree *pCurFolderTree;
|
|
CWiaTree *pCurrentItem;
|
|
ULONG celt = 0;
|
|
|
|
if (!m_pInitialFolder) {
|
|
DBG_ERR(("CEnumWiaItem::GetCount, initial folder not set"));
|
|
return E_POINTER;
|
|
}
|
|
|
|
pCurFolderTree = m_pInitialFolder->GetTreePtr();
|
|
|
|
if (pCurFolderTree) {
|
|
|
|
//
|
|
// Loop through the items
|
|
//
|
|
|
|
for (pCurFolderTree->GetFirstChildItem(&pCurrentItem);
|
|
pCurrentItem;
|
|
pCurrentItem->GetNextSiblingItem(&pCurrentItem)) {
|
|
|
|
celt++;
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERR(("CEnumWiaItem::GetCount, initial folder doesn't have a tree entry"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
*pcelt = celt;
|
|
|
|
return S_OK;
|
|
}
|
|
|