1153 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1153 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*******************************************************************************
 | 
						|
*
 | 
						|
*  (C) COPYRIGHT MICROSOFT CORP., 1998
 | 
						|
*
 | 
						|
*  TITLE:       IDrvItem.Cpp
 | 
						|
*
 | 
						|
*  VERSION:     2.0
 | 
						|
*
 | 
						|
*  AUTHOR:      marke
 | 
						|
*
 | 
						|
*  DATE:        30 Aug, 1998
 | 
						|
*
 | 
						|
*  DESCRIPTION:
 | 
						|
*   Implementation of the WIA test camera item methods.
 | 
						|
*
 | 
						|
*******************************************************************************/
 | 
						|
#include "precomp.h"
 | 
						|
#include "stiexe.h"
 | 
						|
 | 
						|
#include "linklist.h"
 | 
						|
#include "wiamindr.h"
 | 
						|
 | 
						|
#include "ienumitm.h"
 | 
						|
#include "helpers.h"
 | 
						|
#include "lockmgr.h"
 | 
						|
 | 
						|
VOID WINAPI FreeDrvItemContextCallback(VOID *pData);
 | 
						|
VOID WINAPI ReleaseDrvItemCallback(VOID *pData);
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::QueryInterface
 | 
						|
*
 | 
						|
*   Standard COM method.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   iid - Interface ID to query
 | 
						|
*   ppv - Pointer to returned interface.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT _stdcall CWiaDrvItem::QueryInterface(const IID& iid, void** ppv)
 | 
						|
{
 | 
						|
    *ppv = NULL;
 | 
						|
 | 
						|
    if ((iid == IID_IUnknown) || (iid == IID_IWiaDrvItem)) {
 | 
						|
        *ppv = (IWiaDrvItem*) this;
 | 
						|
    } else {
 | 
						|
       return E_NOINTERFACE;
 | 
						|
    }
 | 
						|
    AddRef();
 | 
						|
    return (S_OK);
 | 
						|
}
 | 
						|
 | 
						|
ULONG   _stdcall CWiaDrvItem::AddRef()
 | 
						|
{
 | 
						|
    InterlockedIncrement((long*) &m_cRef);
 | 
						|
    return m_cRef;
 | 
						|
}
 | 
						|
 | 
						|
ULONG   _stdcall CWiaDrvItem::Release()
 | 
						|
{
 | 
						|
    ULONG ulRefCount = m_cRef - 1;
 | 
						|
 | 
						|
    if (InterlockedDecrement((long*) &m_cRef) == 0) {
 | 
						|
        delete this;
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    return ulRefCount;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem
 | 
						|
*
 | 
						|
*   CWiaDrvItem constructor.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   None
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
CWiaDrvItem::CWiaDrvItem()
 | 
						|
{
 | 
						|
    m_ulSig            = CWIADRVITEM_SIG;
 | 
						|
    m_cRef             = 0;
 | 
						|
 | 
						|
    m_pbDrvItemContext = NULL;
 | 
						|
    m_pIWiaMiniDrv     = NULL;
 | 
						|
    m_pCWiaTree        = NULL;
 | 
						|
 | 
						|
    m_pActiveDevice    = NULL;
 | 
						|
 | 
						|
    InitializeListHead(&m_leAppItemListHead);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* Initialize
 | 
						|
*
 | 
						|
*   Initializ a new CWiaDrvItem.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   lFlags              - Object flags for new item.
 | 
						|
*   bstrItemName        - Item name.
 | 
						|
*   bstrFullItemName    - Full item name, including path.
 | 
						|
*   pIWiaMiniDrv        - Pointer to the device object.
 | 
						|
*   cbDevSpecContext    - Number of bytes to allocate for device
 | 
						|
*                         specific context.
 | 
						|
*   ppDevSpecContext    - Pointer to returned device specific context.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::Initialize(
 | 
						|
    LONG            lFlags,
 | 
						|
    BSTR            bstrItemName,
 | 
						|
    BSTR            bstrFullItemName,
 | 
						|
    IWiaMiniDrv     *pIWiaMiniDrv,
 | 
						|
    LONG            cbDevSpecContext,
 | 
						|
    BYTE            **ppDevSpecContext
 | 
						|
    )
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::Initialize);
 | 
						|
 | 
						|
    DBG_TRC(("CWiaDrvItem::Initialize: 0x%08X, %S", this, bstrItemName));
 | 
						|
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
 | 
						|
    if (pIWiaMiniDrv == NULL) {
 | 
						|
        DBG_ERR(("CWiaDrvItem::Initialize, bad pIWiaMiniDrv parameter"));
 | 
						|
        return E_INVALIDARG;
 | 
						|
    }
 | 
						|
 | 
						|
    m_pCWiaTree = new CWiaTree;
 | 
						|
 | 
						|
    if (m_pCWiaTree) {
 | 
						|
        hr = m_pCWiaTree->Initialize(lFlags,
 | 
						|
                                     bstrItemName,
 | 
						|
                                     bstrFullItemName,
 | 
						|
                                     (void*)this);
 | 
						|
        if (SUCCEEDED(hr)) {
 | 
						|
 | 
						|
            m_pIWiaMiniDrv = pIWiaMiniDrv;
 | 
						|
 | 
						|
            //
 | 
						|
            // alloc device specific context
 | 
						|
            //
 | 
						|
 | 
						|
            if (cbDevSpecContext > 0) {
 | 
						|
                hr = AllocDeviceSpecContext(cbDevSpecContext, ppDevSpecContext);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (FAILED(hr)) {
 | 
						|
            delete m_pCWiaTree;
 | 
						|
            m_pCWiaTree = NULL;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        DBG_ERR(("CWiaDrvItem::Initialize, new CWiaTree failed"));
 | 
						|
        hr = E_OUTOFMEMORY;
 | 
						|
    }
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* ~CWiaDrvItem
 | 
						|
*
 | 
						|
*   CWiaDrvItem destructor
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   None
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
CWiaDrvItem::~CWiaDrvItem()
 | 
						|
{
 | 
						|
    DBG_TRC(("CWiaDrvItem::~CWiaDrvItem, (destroy)"));
 | 
						|
 | 
						|
    //
 | 
						|
    // Release the backing tree item.
 | 
						|
    //
 | 
						|
 | 
						|
    if (m_pCWiaTree) {
 | 
						|
        delete m_pCWiaTree;
 | 
						|
        m_pCWiaTree = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // free device driver references
 | 
						|
    //
 | 
						|
 | 
						|
    if (m_pbDrvItemContext != NULL) {
 | 
						|
 | 
						|
        FreeDrvItemContextCallback((VOID*)this);
 | 
						|
 | 
						|
//        DBG_ERR(("CWiaDrvItem destroy, device specific context not empty"));
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Unlink the app item list.
 | 
						|
    //
 | 
						|
 | 
						|
    LIST_ENTRY          *pEntry;
 | 
						|
    PAPP_ITEM_LIST_EL   pElem;
 | 
						|
 | 
						|
    while (!IsListEmpty(&m_leAppItemListHead)) {
 | 
						|
        pEntry = RemoveHeadList(&m_leAppItemListHead);
 | 
						|
        if (pEntry) {
 | 
						|
            pElem = CONTAINING_RECORD( pEntry, APP_ITEM_LIST_EL, ListEntry );
 | 
						|
            if (pElem) {
 | 
						|
                LocalFree(pElem);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // clear all members
 | 
						|
    //
 | 
						|
 | 
						|
    if (m_pActiveDevice) {
 | 
						|
 | 
						|
        //
 | 
						|
        //  If the ACTIVE_DEVICE is pointing to us, make sure
 | 
						|
        //  we set its Driver Item pointer to NULL since we're going away...
 | 
						|
        //
 | 
						|
        if (m_pActiveDevice->m_pRootDrvItem == this) {
 | 
						|
            m_pActiveDevice->SetDriverItem(NULL);
 | 
						|
        }
 | 
						|
        m_pActiveDevice = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    m_ulSig            = 0;
 | 
						|
    m_pbDrvItemContext = NULL;
 | 
						|
    m_pIWiaMiniDrv     = NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::AddItemToFolder
 | 
						|
*
 | 
						|
*   Add a CWiaDrvItem to the driver item tree.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   pIParent - Parent of the driver item.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT _stdcall CWiaDrvItem::AddItemToFolder(IWiaDrvItem *pIParent)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::AddItemToFolder);
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
 | 
						|
    if (!pIParent) {
 | 
						|
        DBG_ERR(("CWiaDrvItem::AddItemToFolder, NULL parent"));
 | 
						|
        return E_INVALIDARG;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Get temporary parent object.
 | 
						|
    //
 | 
						|
 | 
						|
    CWiaDrvItem *pParent = (CWiaDrvItem *)pIParent;
 | 
						|
 | 
						|
    //
 | 
						|
    // Use tree method to add item.
 | 
						|
    //
 | 
						|
 | 
						|
    hr = m_pCWiaTree->AddItemToFolder(pParent->m_pCWiaTree);
 | 
						|
    if (SUCCEEDED(hr)) {
 | 
						|
 | 
						|
        //
 | 
						|
        // Inc ref count of this (child) item since we're giving out
 | 
						|
        // a reference for it to parent.
 | 
						|
        //
 | 
						|
        this->AddRef();
 | 
						|
 | 
						|
        //
 | 
						|
        // If the parent of this drv item has corresponding app items,
 | 
						|
        // run down the list and add a new child app item to each tree.
 | 
						|
        //
 | 
						|
 | 
						|
        {
 | 
						|
            CWiaCritSect    CritSect(&g_semDeviceMan);
 | 
						|
            PLIST_ENTRY     pEntry = pParent->m_leAppItemListHead.Flink;
 | 
						|
 | 
						|
            while (pEntry != &pParent->m_leAppItemListHead) {
 | 
						|
 | 
						|
                PAPP_ITEM_LIST_EL pElem;
 | 
						|
 | 
						|
                pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
 | 
						|
 | 
						|
                CWiaItem *pCWiaItem = pElem->pCWiaItem;
 | 
						|
 | 
						|
                hr = pCWiaItem->UpdateWiaItemTree(ADD_ITEM, this);
 | 
						|
                if (FAILED(hr)) {
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                pEntry = pEntry->Flink;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* RemoveItemFromFolder
 | 
						|
*
 | 
						|
*   Remove a CWiaDrvItem from the driver item tree and mark it so that
 | 
						|
*   no device access can be done through it.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   lReason - Reason for removal of CWiaDrvItem.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::RemoveItemFromFolder(LONG lReason)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::RemoveItemFromFolder);
 | 
						|
    HRESULT hr = S_OK;
 | 
						|
 | 
						|
    //
 | 
						|
    // Use tree method to remove item.
 | 
						|
    //
 | 
						|
 | 
						|
    hr = m_pCWiaTree->RemoveItemFromFolder(lReason);
 | 
						|
    if (SUCCEEDED(hr)) {
 | 
						|
 | 
						|
        //
 | 
						|
        // If this drv item has corresponding app items, run down the
 | 
						|
        // list and unlink the app item from each tree.
 | 
						|
        //
 | 
						|
 | 
						|
        {
 | 
						|
            CWiaCritSect    CritSect(&g_semDeviceMan);
 | 
						|
            PLIST_ENTRY     pEntry = m_leAppItemListHead.Flink;
 | 
						|
 | 
						|
            while (pEntry != &m_leAppItemListHead) {
 | 
						|
 | 
						|
                PAPP_ITEM_LIST_EL pElem;
 | 
						|
 | 
						|
                pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
 | 
						|
 | 
						|
                CWiaItem *pCWiaItem = pElem->pCWiaItem;
 | 
						|
 | 
						|
                pCWiaItem->UpdateWiaItemTree(DELETE_ITEM, this);
 | 
						|
 | 
						|
                pEntry = pEntry->Flink;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        //
 | 
						|
        // Free device specific context.
 | 
						|
        //
 | 
						|
 | 
						|
        FreeDrvItemContextCallback((VOID*)this);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // release reference
 | 
						|
    //
 | 
						|
 | 
						|
    this->Release();
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
HRESULT _stdcall CWiaDrvItem::CallDrvUninitializeForAppItems(
 | 
						|
    ACTIVE_DEVICE   *pActiveDevice)
 | 
						|
{
 | 
						|
    //
 | 
						|
    // If this drv item has corresponding app items, run down the
 | 
						|
    // list and call drvUnInitializeWia for each App. Item.
 | 
						|
    //
 | 
						|
 | 
						|
    if (pActiveDevice) {
 | 
						|
        PLIST_ENTRY     pEntry = m_leAppItemListHead.Flink;
 | 
						|
 | 
						|
        while (pEntry != &m_leAppItemListHead) {
 | 
						|
 | 
						|
            PLIST_ENTRY         pEntryNext = pEntry->Flink;
 | 
						|
            PAPP_ITEM_LIST_EL   pElem;
 | 
						|
 | 
						|
            pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
 | 
						|
 | 
						|
            CWiaItem *pCWiaItem = pElem->pCWiaItem;
 | 
						|
 | 
						|
            HRESULT         hr              = E_FAIL;
 | 
						|
            LONG            lDevErrVal      = 0;
 | 
						|
 | 
						|
            if (pCWiaItem) {
 | 
						|
 | 
						|
                //
 | 
						|
                //  Only call drvUninitializeWia if it has not been called for this item
 | 
						|
                //  already...
 | 
						|
                //
 | 
						|
                if (!(pCWiaItem->m_lInternalFlags & ITEM_FLAG_DRV_UNINITIALIZE_THROWN)) {
 | 
						|
                    hr = g_pStiLockMgr->RequestLock(pActiveDevice, WIA_LOCK_WAIT_TIME, FALSE);
 | 
						|
 | 
						|
                    if(SUCCEEDED(hr)) {
 | 
						|
 | 
						|
                        hr = pActiveDevice->m_DrvWrapper.WIA_drvUnInitializeWia((BYTE*)pCWiaItem);
 | 
						|
                        if (FAILED(hr)) {
 | 
						|
                            DBG_WRN(("CWiaDrvItem::CallDrvUninitializeForAppItems, drvUnitializeWia failed"));
 | 
						|
                        }
 | 
						|
                        pCWiaItem->m_lInternalFlags |= ITEM_FLAG_DRV_UNINITIALIZE_THROWN;
 | 
						|
 | 
						|
                        g_pStiLockMgr->RequestUnlock(pActiveDevice, FALSE);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            pEntry = pEntryNext;
 | 
						|
        }
 | 
						|
        DBG_TRC(("Done calling drvUnInitializeWia for all items..."));
 | 
						|
    } else {
 | 
						|
        ASSERT(("CWiaDrvItem::CallDrvUninitializeForAppItems , called with NULL - this should never happen!", pActiveDevice));
 | 
						|
    }
 | 
						|
    
 | 
						|
    //
 | 
						|
    //  We don't care what happened - always return S_OK
 | 
						|
    //
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* GetDeviceSpecContext
 | 
						|
*
 | 
						|
*   Get the device specific context from a driver item.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   ppSpecContext - Pointer to a pointer to receive the device
 | 
						|
*                   specific context pointer.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::GetDeviceSpecContext(PBYTE *ppSpecContext)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::GetDeviceSpecContext);
 | 
						|
    if (ppSpecContext == NULL) {
 | 
						|
        DBG_ERR(("GetDeviceSpecContext, NULL ppSpecContext pointer"));
 | 
						|
        return E_POINTER;
 | 
						|
    }
 | 
						|
 | 
						|
    *ppSpecContext = m_pbDrvItemContext;
 | 
						|
 | 
						|
    if (!m_pbDrvItemContext) {
 | 
						|
        DBG_ERR(("GetDeviceSpecContext, NULL device specific context"));
 | 
						|
        return E_INVALIDARG;
 | 
						|
    }
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* AllocDeviceSpecContext
 | 
						|
*
 | 
						|
*   Allocate the device specific context from a driver item.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   cbDevSpecContext    - Number of bytes to allocate for device
 | 
						|
*                         specific context.
 | 
						|
*   ppDevSpecContext    - Pointer to returned device specific context.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::AllocDeviceSpecContext(
 | 
						|
    LONG    cbSize,
 | 
						|
    PBYTE   *ppSpecContext)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::AllocDeviceSpecContext);
 | 
						|
    //
 | 
						|
    // validate size, may want to set max
 | 
						|
    //
 | 
						|
 | 
						|
    if ((cbSize < 0) || (cbSize > WIA_MAX_CTX_SIZE)) {
 | 
						|
        DBG_ERR(("CWiaDrvItem::AllocDeviceSpecContext, request > WIA_MAX_CTX_SIZE"));
 | 
						|
        return E_INVALIDARG;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // if a spec context already exists then fail
 | 
						|
    //
 | 
						|
 | 
						|
    if (m_pbDrvItemContext != NULL) {
 | 
						|
        DBG_ERR(("CWiaDrvItem::AllocDeviceSpecContext, Context already exists!"));
 | 
						|
        return E_INVALIDARG;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // attempt to alloc
 | 
						|
    //
 | 
						|
 | 
						|
    m_pbDrvItemContext = (PBYTE)LocalAlloc(LPTR, cbSize);
 | 
						|
 | 
						|
    if (m_pbDrvItemContext == NULL) {
 | 
						|
        DBG_ERR(("CWiaDrvItem::AllocDeviceSpecContext, unable to allocate %d bytes", cbSize));
 | 
						|
        return E_OUTOFMEMORY;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // return ctx if pointer supplied
 | 
						|
    //
 | 
						|
 | 
						|
    if (ppSpecContext != NULL) {
 | 
						|
        *ppSpecContext = m_pbDrvItemContext;
 | 
						|
    }
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* FreeDeviceSpecContext
 | 
						|
*
 | 
						|
*   Free device specific context
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   None
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::FreeDeviceSpecContext(void)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::FreeDeviceSpecContext);
 | 
						|
    if (m_pbDrvItemContext != NULL) {
 | 
						|
        LocalFree(m_pbDrvItemContext);
 | 
						|
        m_pbDrvItemContext = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* GetItemFlags
 | 
						|
*
 | 
						|
*   Return the driver item flags.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   plFlags - Pointer to a value to receive the driver item flags.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::GetItemFlags(LONG *plFlags)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::GetItemFlags);
 | 
						|
    return m_pCWiaTree->GetItemFlags(plFlags);
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* LinkToDrvItem
 | 
						|
*
 | 
						|
*   Adds the passed in CWiaItem to the driver items list of corresponding
 | 
						|
*   application items.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   pCWiaItem - Pointer to application item.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT _stdcall CWiaDrvItem::LinkToDrvItem(CWiaItem *pCWiaItem)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::LinkToDrvItem);
 | 
						|
    CWiaCritSect        CritSect(&g_semDeviceMan);
 | 
						|
    PAPP_ITEM_LIST_EL   pElem;
 | 
						|
 | 
						|
    pElem = (PAPP_ITEM_LIST_EL) LocalAlloc(0, sizeof(APP_ITEM_LIST_EL));
 | 
						|
    if (pElem) {
 | 
						|
        pElem->pCWiaItem = pCWiaItem;
 | 
						|
        InsertHeadList(&m_leAppItemListHead, &pElem->ListEntry);
 | 
						|
        return S_OK;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        DBG_ERR(("CWiaDrvItem::LinkToDrvItem alloc of APP_ITEM_LIST_EL failed"));
 | 
						|
        return E_OUTOFMEMORY;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* UnlinkFromDrvItem
 | 
						|
*
 | 
						|
*   Removes the passed in CWiaItem from the driver items list of
 | 
						|
*   corresponding application items.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   pCWiaItem - Pointer to application item.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT _stdcall CWiaDrvItem::UnlinkFromDrvItem(CWiaItem *pCWiaItem)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::UnlinkFromDrvItem);
 | 
						|
    CWiaCritSect    CritSect(&g_semDeviceMan);
 | 
						|
    PLIST_ENTRY     pEntry = m_leAppItemListHead.Flink;
 | 
						|
 | 
						|
    while (pEntry != &m_leAppItemListHead) {
 | 
						|
 | 
						|
        PAPP_ITEM_LIST_EL pElem;
 | 
						|
 | 
						|
        pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
 | 
						|
 | 
						|
        if (pElem->pCWiaItem == pCWiaItem) {
 | 
						|
            RemoveEntryList(pEntry);
 | 
						|
            LocalFree(pElem);
 | 
						|
            return S_OK;
 | 
						|
        }
 | 
						|
 | 
						|
        pEntry = pEntry->Flink;
 | 
						|
    }
 | 
						|
    DBG_ERR(("CWiaDrvItem::UnlinkFromDrvItem, app item not found: 0x%08X", pCWiaItem));
 | 
						|
    return S_FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::GetFullItemName
 | 
						|
*
 | 
						|
*   Allocates and fills in a BSTR with this items full name. The full item
 | 
						|
*   name includes item path information.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   pbstrFullItemName - Pointer to returned full item name.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::GetFullItemName(BSTR *pbstrFullItemName)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::GetFullItemName);
 | 
						|
    return m_pCWiaTree->GetFullItemName(pbstrFullItemName);
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::GetItemName
 | 
						|
*
 | 
						|
*   Allocates and fills in a BSTR with this items name. The item name
 | 
						|
*   does not include item path information.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   pbstrItemName - Pointer to returned item name.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::GetItemName(BSTR *pbstrItemName)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::GetItemName);
 | 
						|
    return m_pCWiaTree->GetItemName(pbstrItemName);
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::DumpItemData
 | 
						|
*
 | 
						|
*   Allocate buffer and dump formatted private CWiaDrvItem data into it.
 | 
						|
*   This method is debug only. Free component returns E_NOTIMPL.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   bstrDrvItemData - Pointer to allocated buffer. Caller must free.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/19/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT  _stdcall CWiaDrvItem::DumpItemData(BSTR *bstrDrvItemData)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::DumpItemData);
 | 
						|
#ifdef ITEMDEBUG
 | 
						|
 | 
						|
#define TREE_BUF_SIZE 1024
 | 
						|
#define BUF_SIZE      512  + TREE_BUF_SIZE
 | 
						|
#define LINE_SIZE     128
 | 
						|
 | 
						|
    WCHAR       szTemp[BUF_SIZE], szTreeTmp[TREE_BUF_SIZE];
 | 
						|
    LPOLESTR    psz = szTemp;
 | 
						|
 | 
						|
    wcscpy(szTemp, L"");
 | 
						|
 | 
						|
    psz+= wsprintfW(psz, L"Drv item, CWiaDrvItem: %08X\r\n\r\n", this);
 | 
						|
    psz+= wsprintfW(psz, L"Address      Member              Value\r\n");
 | 
						|
    psz+= wsprintfW(psz, L"%08X     m_ulSig:            %08X\r\n", &m_ulSig,            m_ulSig);
 | 
						|
    psz+= wsprintfW(psz, L"%08X     m_cRef:             %08X\r\n", &m_cRef,             m_cRef);
 | 
						|
    psz+= wsprintfW(psz, L"%08X     m_pIWiaMiniDrv:     %08X\r\n", &m_pIWiaMiniDrv,     m_pIWiaMiniDrv);
 | 
						|
    psz+= wsprintfW(psz, L"%08X     m_pbDrvItemContext: %08X\r\n", &m_pbDrvItemContext, m_pbDrvItemContext);
 | 
						|
    psz+= wsprintfW(psz, L"%08X     m_leAppItemListHead:%08X\r\n", &m_leAppItemListHead,m_leAppItemListHead);
 | 
						|
 | 
						|
    psz+= wsprintfW(psz, L"\r\n");
 | 
						|
 | 
						|
    BSTR bstrTree;
 | 
						|
 | 
						|
    HRESULT hr = m_pCWiaTree->DumpTreeData(&bstrTree);
 | 
						|
    if (SUCCEEDED(hr)) {
 | 
						|
        psz+= wsprintfW(psz, L"%ls", bstrTree);
 | 
						|
        SysFreeString(bstrTree);
 | 
						|
    }
 | 
						|
 | 
						|
    psz+= wsprintfW(psz, L"\r\n");
 | 
						|
 | 
						|
    if (psz > (szTemp + (BUF_SIZE - LINE_SIZE))) {
 | 
						|
        DBG_ERR(("CWiaDrvItem::DumpDrvItemData buffer too small"));
 | 
						|
    }
 | 
						|
 | 
						|
    *bstrDrvItemData = SysAllocString(szTemp);
 | 
						|
    if (*bstrDrvItemData) {
 | 
						|
        return S_OK;
 | 
						|
    }
 | 
						|
    return E_OUTOFMEMORY;
 | 
						|
#else
 | 
						|
    return E_NOTIMPL;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::UnlinkItemTree
 | 
						|
*
 | 
						|
*   This method unlinks the tree. Must be called on the root
 | 
						|
*   driver item.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   lReason - Reason for unlinking the tree.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/21/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT _stdcall CWiaDrvItem::UnlinkItemTree(LONG lReason)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::UnlinkItemTree);
 | 
						|
 | 
						|
    //
 | 
						|
    //  AddRef this item, since ReleaseDrvItemCallback will call release
 | 
						|
    //  and we don't want to destroy this object.
 | 
						|
    //
 | 
						|
    AddRef();
 | 
						|
    return m_pCWiaTree->UnlinkItemTree(lReason,
 | 
						|
                                       (PFN_UNLINK_CALLBACK)ReleaseDrvItemCallback);
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::FindItemByName
 | 
						|
*
 | 
						|
*   Locate a driver item by it's full item name.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   lFlags           - Operation flags.
 | 
						|
*   bstrFullItemName - Requested item name.
 | 
						|
*   ppItem           - Pointer to returned item, if found.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/27/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT CWiaDrvItem::FindItemByName(
 | 
						|
    LONG            lFlags,
 | 
						|
    BSTR            bstrFullItemName,
 | 
						|
    IWiaDrvItem     **ppItem)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::FindItemByName);
 | 
						|
    if (ppItem) {
 | 
						|
        *ppItem = NULL;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        DBG_ERR(("CWiaDrvItem::FindItemByName NULL ppItem"));
 | 
						|
        return E_INVALIDARG;
 | 
						|
    }
 | 
						|
 | 
						|
    CWiaTree *pCWiaTree;
 | 
						|
 | 
						|
    HRESULT hr = m_pCWiaTree->FindItemByName(lFlags, bstrFullItemName, &pCWiaTree);
 | 
						|
    if (hr == S_OK) {
 | 
						|
 | 
						|
        pCWiaTree->GetItemData((void**)ppItem);
 | 
						|
 | 
						|
        if (*ppItem) {
 | 
						|
            (*ppItem)->AddRef();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::FindChildItemByName
 | 
						|
*
 | 
						|
*   Locate a child item by it's item name.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   bstrItemName - Requested item name.
 | 
						|
*   ppIChildItem - Pointer to returned item, if found.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/27/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT CWiaDrvItem::FindChildItemByName(
 | 
						|
    BSTR            bstrItemName,
 | 
						|
    IWiaDrvItem     **ppIChildItem)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::FindChildItemName);
 | 
						|
    CWiaTree *pCWiaTree;
 | 
						|
 | 
						|
    HRESULT hr = m_pCWiaTree->FindChildItemByName(bstrItemName, &pCWiaTree);
 | 
						|
    if (hr == S_OK) {
 | 
						|
 | 
						|
        pCWiaTree->GetItemData((void**)ppIChildItem);
 | 
						|
 | 
						|
        if (*ppIChildItem) {
 | 
						|
            (*ppIChildItem)->AddRef();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::GetParent
 | 
						|
*
 | 
						|
*   Get parent of this item.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   ppIParentItem - Pointer to returned parent, if found.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/27/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT CWiaDrvItem::GetParentItem(IWiaDrvItem **ppIParentItem)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::GetParentItem);
 | 
						|
    CWiaTree *pCWiaTree;
 | 
						|
 | 
						|
    HRESULT hr = m_pCWiaTree->GetParentItem(&pCWiaTree);
 | 
						|
    if (hr == S_OK) {
 | 
						|
        pCWiaTree->GetItemData((void**)ppIParentItem);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        *ppIParentItem = NULL;
 | 
						|
    }
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::GetFirstChild
 | 
						|
*
 | 
						|
*   Return the first child item of this folder.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   ppIChildItem - Pointer to returned child item, if found.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/27/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT CWiaDrvItem::GetFirstChildItem(IWiaDrvItem **ppIChildItem)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::GetFirstChildItem);
 | 
						|
    CWiaTree *pCWiaTree;
 | 
						|
 | 
						|
    HRESULT hr = m_pCWiaTree->GetFirstChildItem(&pCWiaTree);
 | 
						|
    if (hr == S_OK) {
 | 
						|
        pCWiaTree->GetItemData((void**)ppIChildItem);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        *ppIChildItem = NULL;
 | 
						|
    }
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* CWiaDrvItem::GetNextSiblingItem
 | 
						|
*
 | 
						|
*   Find the next sibling of this item.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   ppSiblingItem - Pointer to the returned sibling item, if found.
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*   Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    1/27/1999 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
HRESULT CWiaDrvItem::GetNextSiblingItem(
 | 
						|
    IWiaDrvItem  **ppSiblingItem)
 | 
						|
{
 | 
						|
    DBG_FN(CWiaDrvItem::GetNextSiblingItem);
 | 
						|
    CWiaTree *pCWiaTree;
 | 
						|
 | 
						|
    HRESULT hr = m_pCWiaTree->GetNextSiblingItem(&pCWiaTree);
 | 
						|
    if (hr == S_OK) {
 | 
						|
        pCWiaTree->GetItemData((void**)ppSiblingItem);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        *ppSiblingItem = NULL;
 | 
						|
    }
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
/**************************************************************************\
 | 
						|
* FreeDrvItemContextCallback
 | 
						|
*
 | 
						|
*   Callback function to free the driver item context.  Called by
 | 
						|
*   CWiaTree::UnlinkItemTree(...) for each node in the tree.
 | 
						|
*
 | 
						|
* Arguments:
 | 
						|
*
 | 
						|
*   pData     - payload data for the tree node.  We know that this will be
 | 
						|
*               a driver item, since only a driver item specifies this
 | 
						|
*               callback (see CWiaDrvItem::UnlinkItemTree(...))
 | 
						|
*
 | 
						|
* Return Value:
 | 
						|
*
 | 
						|
*    Status
 | 
						|
*
 | 
						|
* History:
 | 
						|
*
 | 
						|
*    10/20/1998 Original Version
 | 
						|
*
 | 
						|
\**************************************************************************/
 | 
						|
 | 
						|
VOID WINAPI FreeDrvItemContextCallback(
 | 
						|
    VOID *pData)
 | 
						|
{
 | 
						|
    DBG_FN(::FreeDrvItemContextCallback);
 | 
						|
 | 
						|
    CWiaDrvItem *pDrvItem = (CWiaDrvItem*) pData;
 | 
						|
    HRESULT     hr = S_OK;
 | 
						|
 | 
						|
    if (pDrvItem) {
 | 
						|
 | 
						|
        //
 | 
						|
        // Free device specific context, if it exists.
 | 
						|
        //
 | 
						|
 | 
						|
        LONG    lFlags = 0;
 | 
						|
        LONG    lDevErrVal;
 | 
						|
 | 
						|
        if (pDrvItem->m_pbDrvItemContext != NULL) {
 | 
						|
 | 
						|
            __try {
 | 
						|
                if (pDrvItem->m_pIWiaMiniDrv) {
 | 
						|
                    hr = pDrvItem->m_pIWiaMiniDrv->drvFreeDrvItemContext(lFlags,
 | 
						|
                        pDrvItem->m_pbDrvItemContext,
 | 
						|
                        &lDevErrVal);
 | 
						|
                }
 | 
						|
                if (FAILED(hr)) {
 | 
						|
                    DBG_ERR(("FreeDrvItemContextCallback, drvFreeDrvItemContext failed 0x%X", hr));
 | 
						|
                }
 | 
						|
            } __except(EXCEPTION_EXECUTE_HANDLER) {
 | 
						|
                DBG_WRN(("FreeDrvItemContextCallback, exception calling drvFreeDrvItemContext (this is expected)"));
 | 
						|
            }
 | 
						|
 | 
						|
            LocalFree(pDrvItem->m_pbDrvItemContext);
 | 
						|
            pDrvItem->m_pbDrvItemContext = NULL;
 | 
						|
        } else {
 | 
						|
            DBG_TRC(("FreeDrvItemContextCallback, Context is NULL!  Nothing to free..."));
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
VOID WINAPI ReleaseDrvItemCallback(
 | 
						|
    VOID *pData)
 | 
						|
{
 | 
						|
    DBG_FN(::ReleaseDrvItemCallback);
 | 
						|
 | 
						|
    CWiaDrvItem *pDrvItem = (CWiaDrvItem*) pData;
 | 
						|
    HRESULT     hr = S_OK;
 | 
						|
 | 
						|
    if (pDrvItem) {
 | 
						|
 | 
						|
        //
 | 
						|
        // First, free the driver item context
 | 
						|
        //
 | 
						|
 | 
						|
        FreeDrvItemContextCallback(pData);
 | 
						|
 | 
						|
        //
 | 
						|
        // Call release on the driver item
 | 
						|
        //
 | 
						|
 | 
						|
        pDrvItem->Release();
 | 
						|
    }
 | 
						|
}
 | 
						|
 |