Leaked source code of windows server 2003
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

/*******************************************************************************
*
* (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;
}