|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 1998 * * TITLE: IItem.Cpp * * VERSION: 2.0 * * AUTHOR: ReedB * * DATE: 30 July, 1998 * * DESCRIPTION: * Implementation of CWiaItem for WIA scanner class driver. * *******************************************************************************/ #include "precomp.h"
#include "stiexe.h"
#define WIA_DECLARE_DEVINFO_PROP_ARRAY
#include "wiamindr.h"
#include "wiapsc.h"
#define WIA_DECLARE_MANAGED_PROPS
#include "helpers.h"
#include "wiapropp.h"
#include "ienumdc.h"
#include "ienumitm.h"
#include "callback.h"
#include "devmgr.h"
#include "wiaevntp.h"
/**************************************************************************\
* CopyDrvItemToTreeItem * * Create a CWiaTree object using a CWiaDrvItem as a template. * * Arguments: * * lFlags - * pCWiaDrvItemSrc - * ppCWiaTreeDst - * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
CopyDrvItemToTreeItem( LONG lFlags, CWiaDrvItem *pCWiaDrvItemSrc, CWiaItem *pCWiaItem, CWiaTree **ppCWiaTreeDst) { DBG_FN(::CopyDrvItemToTreeItem); HRESULT hr;
*ppCWiaTreeDst = NULL;
CWiaTree *pNewTreeItem = new CWiaTree;
if (pNewTreeItem) {
BSTR bstrItemName;
hr = pCWiaDrvItemSrc->GetItemName(&bstrItemName);
if (SUCCEEDED(hr)) { BSTR bstrFullItemName;
hr = pCWiaDrvItemSrc->GetFullItemName(&bstrFullItemName);
if (SUCCEEDED(hr)) {
hr = pNewTreeItem->Initialize(lFlags, bstrItemName, bstrFullItemName, (void*)pCWiaItem); if (SUCCEEDED(hr)) { *ppCWiaTreeDst = pNewTreeItem; }
SysFreeString(bstrFullItemName); } SysFreeString(bstrItemName); }
if (FAILED(hr)) { delete pNewTreeItem; } } else { DBG_ERR(("CopyDrvItemToTreeItem, new CWiaTree failed")); hr = E_OUTOFMEMORY; } return hr; }
/**************************************************************************\
* UpdateWiaItemTree * * Update the application item tree. Called on the * parent of the new child item or item to unlink. * * Arguments: * * lFlag - Action to preform. * pWiaDrvItem - * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::UpdateWiaItemTree( LONG lFlag, CWiaDrvItem *pWiaDrvItem) { DBG_FN(CWiaItem::UpdateWiaItemTree); HRESULT hr = S_OK;
if (lFlag == DELETE_ITEM) {
//
// Unlink the item from the app item tree.
//
hr = m_pCWiaTree->RemoveItemFromFolder(WiaItemTypeDeleted); } else if (lFlag == ADD_ITEM) {
//
// Create a CWiaItem for this driver item.
//
CWiaItem *pItem = new CWiaItem();
if (!pItem) { DBG_ERR(("UpdateWiaItemTree new CWiaItem failed")); return E_OUTOFMEMORY; }
hr = pItem->Initialize(m_pIWiaItemRoot, NULL, m_pActiveDevice, pWiaDrvItem); if (SUCCEEDED(hr)) {
//
// Create a CWiaTree object for this node and add it to the tree.
//
LONG lFlags;
pWiaDrvItem->GetItemFlags(&lFlags);
hr = CopyDrvItemToTreeItem(lFlags, pWiaDrvItem, pItem, &pItem->m_pCWiaTree); if (SUCCEEDED(hr)) {
hr = pItem->m_pCWiaTree->AddItemToFolder(m_pCWiaTree); if (SUCCEEDED(hr)) { return hr; } } } delete pItem; } else { DBG_ERR(("UpdateWiaItemTree unknown flag: 0x%08X", lFlag)); hr = E_FAIL; } return hr; }
/**************************************************************************\
* BuildWiaItemTreeHelper * * Process the child items for BuildWiaItemTree. * * Arguments: * * pWiaDrvItem - * pTreeParent - * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::BuildWiaItemTreeHelper( CWiaDrvItem *pWiaDrvItem, CWiaTree *pTreeParent) { DBG_FN(CWiaItem::BuildWiaItemTreeHelper); //
// Walk the child items.
//
CWiaDrvItem *pChildDrvItem;
HRESULT hr = pWiaDrvItem->GetFirstChildItem((IWiaDrvItem**) &pChildDrvItem);
while (hr == S_OK) {
//
// Create a CWiaItem for this node.
//
CWiaItem *pItem = new CWiaItem();
if (!pItem) { DBG_ERR(("BuildWiaItemTreeHelper new CWiaItem failed")); hr = E_OUTOFMEMORY; break; }
hr = pItem->Initialize(m_pIWiaItemRoot, NULL, m_pActiveDevice, pChildDrvItem); if (SUCCEEDED(hr)) {
//
// Create a CWiaTree object for this node and add it to the tree.
//
LONG lFlags;
pChildDrvItem->GetItemFlags(&lFlags);
hr = CopyDrvItemToTreeItem(lFlags, pChildDrvItem, pItem, &pItem->m_pCWiaTree); if (SUCCEEDED(hr)) {
hr = pItem->m_pCWiaTree->AddItemToFolder(pTreeParent); if (SUCCEEDED(hr)) {
if (lFlags & (WiaItemTypeFolder | WiaItemTypeHasAttachments)) {
//
// For folder items call BuildWiaItemTreeHelper recursively
// to process the folders child items.
//
hr = BuildWiaItemTreeHelper((CWiaDrvItem*)pChildDrvItem, pItem->m_pCWiaTree); } } }
//
// Process the next sibling driver item.
//
if (SUCCEEDED(hr)) { hr = pChildDrvItem->GetNextSiblingItem((IWiaDrvItem**) &pChildDrvItem); } } else { delete pItem; } }
//
// Change S_FALSE to S_OK since S_FALSE simply means there are no more children to process.
//
if (hr == S_FALSE) { hr = S_OK; } return hr; }
/**************************************************************************\
* BuildWiaItemTree * * For root items, build a copy of the driver item tree and create a * CWiaItem for each node. * * Arguments: * * pIWiaItemRoot - * pIWiaMiniDrv - * pWiaDrvItem - * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::BuildWiaItemTree(IWiaPropertyStorage *pIWiaDevInfoProps) { DBG_FN(CWiaItem::BuildWiaItemTree);
//
// Must be root item.
//
LONG lFlags;
m_pWiaDrvItem->GetItemFlags(&lFlags);
if (!(lFlags & WiaItemTypeRoot)) { DBG_ERR(("BuildWiaItemTree, caller doesn't have WiaItemTypeRoot set")); return E_INVALIDARG; }
HRESULT hr = CopyDrvItemToTreeItem(lFlags, m_pWiaDrvItem, this, &m_pCWiaTree);
if (SUCCEEDED(hr)) {
//
// Since this is the root item, initialize the root item properties with a
// mirror of the DEVINFOPROPS (WIA_DIP_* ID's).
//
hr = InitRootProperties(pIWiaDevInfoProps); if (FAILED(hr)) { DBG_TRC(("BuildWiaItemTree, InitRootProperties, about to unlink...")); UnlinkAppItemTree(WiaItemTypeDeleted); return hr; }
//
// Process the child items.
//
hr = BuildWiaItemTreeHelper(m_pWiaDrvItem, m_pCWiaTree); if (FAILED(hr)) { DBG_TRC(("BuildWiaItemTree, BuildWiaItemTreeHelper failed, about to unlink...")); UnlinkAppItemTree(WiaItemTypeDeleted); } } return hr; }
/**************************************************************************\
* InitWiaManagedItemProperties * * A private helper for CWiaItem::Initialize, which initializes the * WIA managed item properties based on the driver item values. * * Arguments: * * None * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::InitWiaManagedItemProperties( IWiaPropertyStorage *pIWiaDevInfoProps) { DBG_FN(CWiaItem::InitWiaManagedItemProperties); ULONG ulNumProps;
ulNumProps = (m_pIWiaItemRoot == this) ? NUM_WIA_MANAGED_PROPS - 1 : NUM_WIA_MANAGED_PROPS; //
// WIA manages the item name and type properties, so set the
// property names here.
//
HRESULT hr = wiasSetItemPropNames((BYTE*)this, ulNumProps, s_piItemNameType, s_pszItemNameType);
//
// Set the name and type properties attributes.
//
PROPVARIANT pv; ULONG ulFlag; for (UINT i = 0; i < ulNumProps; i++) {
if (i == PROFILE_INDEX) { pv.vt = VT_BSTR | VT_VECTOR; ulFlag = WIA_PROP_RW | WIA_PROP_CACHEABLE | WIA_PROP_LIST; } else { pv.vt = VT_I4; ulFlag = WIA_PROP_READ | WIA_PROP_CACHEABLE | WIA_PROP_NONE; } pv.ulVal = 0;
hr = wiasSetPropertyAttributes((BYTE*)this, 1, &s_psItemNameType[i], &ulFlag, &pv); if (FAILED(hr)) { DBG_ERR(("CWiaItem::Initialize, wiasSetPropertyAttributes failed, index: %d", i)); break; } }
//
// Get the item names and type from the driver item and set
// them to the item properties.
//
BSTR bstrItemName; BSTR bstrFullItemName;
hr = m_pWiaDrvItem->GetItemName(&bstrItemName); if (SUCCEEDED(hr)) { hr = m_pWiaDrvItem->GetFullItemName(&bstrFullItemName); if (SUCCEEDED(hr)) {
LONG lFlags;
m_pWiaDrvItem->GetItemFlags(&lFlags); // Can't fail, except on param validate.
//
// Set the item names and type.
//
PROPVARIANT *propvar;
propvar = (PROPVARIANT*) LocalAlloc(LPTR, sizeof(PROPVARIANT) * ulNumProps); if (propvar) { memset(propvar, 0, sizeof(PROPVARIANT) * ulNumProps);
propvar[0].vt = VT_BSTR; propvar[0].bstrVal = bstrItemName; propvar[1].vt = VT_BSTR; propvar[1].bstrVal = bstrFullItemName; propvar[2].vt = VT_I4; propvar[2].lVal = lFlags;
hr = (m_pPropStg->CurStg())->WriteMultiple(ulNumProps, s_psItemNameType, propvar, WIA_DIP_FIRST); if (SUCCEEDED(hr)) { //
// Fill in ICM Profile information
//
hr = FillICMPropertyFromRegistry(pIWiaDevInfoProps, (IWiaItem*) this); }
if (FAILED(hr)) { ReportReadWriteMultipleError(hr, "CWiaItem::InitWiaManagedItemProperties", NULL, FALSE, ulNumProps, s_psItemNameType); } LocalFree(propvar); } else { DBG_ERR(("CWiaItem::InitWiaManagedItemProperties, Out of Memory!")); hr = E_OUTOFMEMORY; } SysFreeString(bstrFullItemName);
} SysFreeString(bstrItemName); } return hr; }
/**************************************************************************\
* * InitRootProperties * * A private helper for CWiaItem::Initialize, which initializes the * root item properties to a mirror of DEVINFOPROPS. * * Arguments: * * None * * Return Value: * * status * * History: * * 9/3/1998 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::InitRootProperties(IWiaPropertyStorage *pIWiaDevInfoProps) { DBG_FN(CWiaItem::InitRootProperties); HRESULT hr = S_OK;
//
// Write the root item property names.
//
hr = WriteItemPropNames(NUMROOTITEMPROPS, g_piRootItem, g_pszRootItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::InitRootProperties, WritePropNames failed")); return hr; }
//
// Copy the device information properties from source to destination.
//
PROPVARIANT propvar[WIA_NUM_DIP]; ULONG ulIndex;
memset(propvar, 0, sizeof(propvar));
hr = pIWiaDevInfoProps->ReadMultiple(WIA_NUM_DIP, g_psDeviceInfo, propvar);
if (SUCCEEDED(hr)) { hr = (m_pPropStg->CurStg())->WriteMultiple(WIA_NUM_DIP, g_psDeviceInfo, propvar, WIA_DIP_FIRST);
if (FAILED(hr)) { ReportReadWriteMultipleError(hr, "InitRootProperties", NULL, FALSE, WIA_NUM_DIP, g_psDeviceInfo); }
FreePropVariantArray(WIA_NUM_DIP, propvar); } else { ReportReadWriteMultipleError(hr, "InitRootProperties", NULL, TRUE, WIA_NUM_DIP, g_psDeviceInfo); DBG_ERR(("CWiaItem::InitRootProperties failed")); return hr; }
//
// Write out the property info from our private array.
//
hr = wiasSetItemPropAttribs((BYTE*)this, NUMROOTITEMPROPS, g_psRootItem, g_wpiRootItem); if (SUCCEEDED(hr) && m_pActiveDevice->m_DrvWrapper.IsVolumeDevice()) { //
// This is a volume device. We must add some volume specific properties
//
hr = AddVolumePropertiesToRoot(m_pActiveDevice); } return hr; }
/*******************************************************************************
* * QueryInterface * AddRef * Release * * DESCRIPTION: * IUnknown Interface. AddRef and Release mantain a global refernce count * of all device objects on the root item. * * PARAMETERS: * *******************************************************************************/
HRESULT _stdcall CWiaItem::QueryInterface(const IID& iid, void** ppv) { *ppv = NULL;
if (iid == IID_IUnknown || iid == IID_IWiaItem) { *ppv = (IWiaItem*) this; } else if (iid == IID_IWiaPropertyStorage) { *ppv = (IWiaPropertyStorage*) this; } else if (iid == IID_IPropertyStorage) { *ppv = (IPropertyStorage*) this; } else if (iid == IID_IWiaDataTransfer) { *ppv = (IWiaDataTransfer*) this; } else if (iid == IID_IWiaItemInternal) { *ppv = (IWiaItemInternal*) this; } else if (iid == IID_IWiaItemExtras) { *ppv = (IWiaItemExtras*) this; } else {
//
// Blind aggregation to optional inner component.
//
if (m_pIUnknownInner) { return m_pIUnknownInner->QueryInterface(iid, ppv); } else { return E_NOINTERFACE; } } reinterpret_cast<IUnknown*>(*ppv)->AddRef(); return (S_OK); }
ULONG _stdcall CWiaItem::AddRef() { DBG_FN(CWiaItem::AddRef);
TAKE_ACTIVE_DEVICE tad(m_pActiveDevice);
LONG lType = 0; LONG lRef = 1;
lRef = InterlockedIncrement((long*) &m_cLocalRef); GetItemType(&lType); if (!(lType & WiaItemTypeRemoved)) { lRef = InterlockedIncrement((long*) &(((CWiaItem*)m_pIWiaItemRoot)->m_cRef)); }
return lRef; }
ULONG _stdcall CWiaItem::Release() { DBG_FN(CWiaItem::Release);
LONG lType = 0; ULONG ulRef = InterlockedDecrement((long*)&m_cLocalRef); GetItemType(&lType); if (lType & WiaItemTypeRemoved) {
if (ulRef == 0) { delete this; return 0; } else { return m_cLocalRef; } } else if (InterlockedDecrement((long*) &(((CWiaItem*)m_pIWiaItemRoot)->m_cRef)) == 0) {
ulRef = ((CWiaItem*)m_pIWiaItemRoot)->m_cRef;
//
// If the combined refernce count of the root item goes to zero
// first notify driver that client connection is being removed, then
// unlink the tree and release all of the items.
//
//
// But first cleanup any remote transfers in progress that are a
// result of crashed or malicious clients
//
CWiaItem * pItem = (CWiaItem*) m_pIWiaItemRoot; while(pItem) { CWiaRemoteTransfer *pTransfer = (CWiaRemoteTransfer *)InterlockedExchangePointer((PVOID *)&pItem->m_pRemoteTransfer, NULL); if(pTransfer) { CleanupRemoteTransfer(pTransfer); } pItem = pItem->GetNextLinearItem(); }
HRESULT hr = E_FAIL; LONG lDevErrVal = 0; ACTIVE_DEVICE *pActiveDevice = m_pActiveDevice;
//
// Call drvUnInitialize if it hasn't been called yet (could have been
// called if driver was unloaded).
// Note that we must check flags on the ROOT item.
//
if (!(((CWiaItem*)m_pIWiaItemRoot)->m_lInternalFlags & ITEM_FLAG_DRV_UNINITIALIZE_THROWN)) {
{ LOCK_WIA_DEVICE _LWD(this, &hr);
if(SUCCEEDED(hr)) { hr = m_pActiveDevice->m_DrvWrapper.WIA_drvUnInitializeWia((BYTE*)m_pIWiaItemRoot); } m_lInternalFlags |= ITEM_FLAG_DRV_UNINITIALIZE_THROWN; } }
DBG_TRC(("CWiaItem::Release, m_cRef = 0, about to unlink...")); UnlinkAppItemTree(WiaItemTypeDeleted);
if (pActiveDevice) { //
// Release the ACTIVE_DEVICE object. Notice that we release it AFTER
// the item is through with it.
//
pActiveDevice->Release(); pActiveDevice = NULL; } }
return ulRef; }
/**************************************************************************\
* CWiaItem::UnlinkChildAppItemTree * * This method recursively unlinks the tree by calling * RemoveItemFromFolder on each item under the root. * * Arguments: * * lReason - Reason for unlink of tree. * * Return Value: * * Status * * History: * * 1/21/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::UnlinkChildAppItemTree(LONG lReason) { DBG_FN(CWiaItem::UnlinkChildAppItemTree);
//
// Check that we have a valid tree
//
if (!m_pCWiaTree) { return S_FALSE; }
//
// Delete the childern.
//
CWiaTree *pChild, *pNext;
HRESULT hr = m_pCWiaTree->GetFirstChildItem(&pChild);
while (hr == S_OK) {
//
// Get a tree items associated app item.
//
CWiaItem *pChildAppItem;
pChildAppItem = NULL; hr = pChild->GetItemData((void**)&pChildAppItem); if (hr == S_OK) { //
// If the child is a folder then call
// recursively to delete all childern under.
//
LONG lFlags;
pChild->GetItemFlags(&lFlags);
if (lFlags & (WiaItemTypeFolder | WiaItemTypeHasAttachments)) { hr = pChildAppItem->UnlinkChildAppItemTree(lReason); if (FAILED(hr)) { break; } } } else { DBG_ERR(("CWiaItem::UnlinkChildAppItemTree no app item on tree item: %X", pChild)); }
hr = pChild->GetNextSiblingItem(&pNext);
//
// Remove item from tree.
//
pChild->RemoveItemFromFolder(lReason);
//
// Delete the child item.
//
if (pChildAppItem) {
delete pChildAppItem; }
pChild = pNext; } return hr; }
/**************************************************************************\
* CWiaItem::UnlinkAppItemTree * * This method unlinks the app item tree. * * Arguments: * * lReason - Reason for unlinking the tree. * * Return Value: * * Status * * History: * * 1/21/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::UnlinkAppItemTree(LONG lReason) { DBG_FN(CWiaItem::UnlinkAppItemTree);
//
// Work off of the root item.
//
CWiaItem *pRoot = (CWiaItem*) m_pIWiaItemRoot;
//
// Unlink any childern.
//
pRoot->UnlinkChildAppItemTree(lReason);
//
// Finally, delete the root item.
//
delete pRoot; return S_OK; }
/**************************************************************************\
* CWiaItem::CWiaItem * * CWiaItem Constructor Method. * * Arguments: * * None * * Return Value: * * Status * * History: * * 11/11/1998 Original Version * \**************************************************************************/
CWiaItem::CWiaItem() { m_ulSig = CWIAITEM_SIG; m_cRef = 0; m_cLocalRef = 0;
m_pWiaDrvItem = NULL; m_pActiveDevice = NULL; m_pIUnknownInner = NULL; m_pCWiaTree = NULL; m_pIWiaItemRoot = this; m_bInitialized = FALSE; m_pICMValues = NULL; m_lICMSize = 0;
m_pPropStg = NULL;
m_hBandSection = NULL; m_pBandBuffer = NULL; m_lBandBufferLength = 0; m_ClientBaseAddress = 0; m_bMapSection = FALSE; m_cwfiBandedTran = 0; m_pwfiBandedTran = NULL; m_pRemoteTransfer = NULL; m_lLastDevErrVal = 0; m_lInternalFlags = 0; }
/**************************************************************************\
* CWiaItem::Initialize * * CWiaItem Initialize method. * * Arguments: * * pIWiaItemRoot - * pIWiaMiniDrv - * pWiaDrvItem - * pIUnknownInner - * * Return Value: * * Status * * History: * * 11/11/1998 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::Initialize( IWiaItem *pIWiaItemRoot, IWiaPropertyStorage *pIWiaDevInfoProps, ACTIVE_DEVICE *pActiveDevice, CWiaDrvItem *pWiaDrvItem, IUnknown *pIUnknownInner) { DBG_FN(CWiaItem::Initialize); #ifdef DEBUG
BSTR bstr; if SUCCEEDED(pWiaDrvItem->GetItemName(&bstr)) { DBG_TRC(("CWiaItem::Initialize: 0x%08X, %S, drv item: 0x%08X", this, bstr, pWiaDrvItem)); SysFreeString(bstr); } #endif
//
// Validate parameters
//
if (!pActiveDevice || !pIWiaItemRoot || !pWiaDrvItem) { DBG_ERR(("CWiaItem::Initialize NULL input parameters")); return E_POINTER; }
//
// If optional inner component is present, save a pointer to it.
//
if (pIUnknownInner) { DBG_TRC(("CWiaItem::Initialize, pIUnknownInner: %X", pIUnknownInner)); m_pIUnknownInner = pIUnknownInner; }
//
// Link to the items corresponding driver item.
//
m_pWiaDrvItem = pWiaDrvItem; m_pIWiaItemRoot = pIWiaItemRoot; m_pActiveDevice = pActiveDevice; m_pWiaDrvItem->SetActiveDevice(pActiveDevice);
HRESULT hr = pWiaDrvItem->LinkToDrvItem(this); if (FAILED(hr)) { DBG_ERR(("CWiaItem::Initialize, LinkToDrvItem failed")); return hr; }
//
// Create streams and property storage for item properties.
//
m_pPropStg = new CWiaPropStg(); if (m_pPropStg) { hr = m_pPropStg->Initialize(); if (FAILED(hr)) { delete m_pPropStg; m_pPropStg = NULL; DBG_ERR(("CWiaItem::Initialize, PropertyStorage Initialize failed")); return hr; } } else { DBG_ERR(("CWiaItem::Initialize, not enough memory to create CWiaPropStg")); hr = E_OUTOFMEMORY; return hr; }
//
// Initialize the WIA managed item properties (name, full name, type, ...)
// from the driver item. Must set m_bInitialized to TRUE so that
// InitWiaManagedProperties doesn't attempt to InitLazyProps()
//
m_bInitialized = TRUE; hr = InitWiaManagedItemProperties(pIWiaDevInfoProps);
pWiaDrvItem->AddRef();
if (FAILED(hr)) { DBG_ERR(("CWiaItem::Initialize, InitWiaManagedItemProperties failed")); m_bInitialized = FALSE; return hr; } //
// If this is the root item, build a copy of the driver item tree
// and create a CWiaItem for each node.
//
if (this == pIWiaItemRoot) { hr = BuildWiaItemTree(pIWiaDevInfoProps); }
if (FAILED(hr)) { DBG_ERR(("CWiaItem::Initialize, BuildWiaItemTree failed")); return hr; }
m_bInitialized = FALSE; return hr; }
/**************************************************************************\
* CWiaItem::InitLazyProps * * Helper used to implement lazy initialization. Property initialization * is put off until the item is being accessed by an application for the * first time. * * Arguments: * * bLockDevice - bool value specifying whether a lock is needed. * * Return Value: * * Status * * History: * * 10/10/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::InitLazyProps( BOOL bLockDevice) { DBG_FN(CWiaItem::InitLazyProps); HRESULT hr = S_OK;
LONG lFlags = 0;
//
// Must set to TRUE before call to drvInitItemProperties
//
m_bInitialized = TRUE;
//
// Call the device to initialize the item properties.
//
{ LOCK_WIA_DEVICE _LWD(bLockDevice, this, &hr);
if(SUCCEEDED(hr)) {
hr = m_pActiveDevice->m_DrvWrapper.WIA_drvInitItemProperties((BYTE*)this,lFlags, &m_lLastDevErrVal); } }
if (FAILED(hr)) { m_bInitialized = FALSE; }
return hr; }
/**************************************************************************\
* CWiaItem::~CWiaItem * * CWiaItem Destructor Method. * * Arguments: * * None * * Return Value: * * Status * * History: * * 11/11/1998 Original Version * \**************************************************************************/
CWiaItem::~CWiaItem() { DBG_FN(CWiaItem::~CWiaItem); #ifdef ITEM_TRACE
BSTR bstr;
if (m_pWiaDrvItem && SUCCEEDED(m_pWiaDrvItem->GetItemName(&bstr))) { DBG_TRC(("CWiaItem destroy: %08X, %S", this, bstr)); SysFreeString(bstr); } else { DBG_TRC(("CWiaItem destroy: %08X", this)); } #endif
CWiaRemoteTransfer *pRemoteTransfer = (CWiaRemoteTransfer *) InterlockedExchangePointer((PVOID *)&m_pRemoteTransfer, NULL); if(pRemoteTransfer) { CleanupRemoteTransfer(m_pRemoteTransfer); }
//
// Delete the associated tree item.
//
if (m_pCWiaTree) { delete m_pCWiaTree; m_pCWiaTree = NULL; }
//
// Release WiaDrvItem. If ref count of m_pWiaDrvItem goes to zero
// it will be destroyed at this time. For the ref count to be zero
// no other CWiaItem object may have reference to it and it must be
// disconnected from the device item tree.
//
if (m_pWiaDrvItem) {
//
// Unlink from the app item's corresponding driver item.
//
m_pWiaDrvItem->UnlinkFromDrvItem(this);
m_pWiaDrvItem->Release(); m_pWiaDrvItem = NULL; }
//
// Free the item property storage and streams.
//
if (m_pPropStg) {
delete m_pPropStg; m_pPropStg = NULL; }
//
// Free the cached ICM values
//
if (m_pICMValues) { LocalFree(m_pICMValues); m_pICMValues = NULL; }
//
// Set other members to empty since we're done with this item.
//
m_pWiaDrvItem = NULL; m_pIUnknownInner = NULL; m_pIWiaItemRoot = NULL; m_bInitialized = FALSE; m_lICMSize = 0;
m_hBandSection = NULL; m_pBandBuffer = NULL; m_lBandBufferLength = 0; m_ClientBaseAddress = 0; m_bMapSection = FALSE; m_cwfiBandedTran = 0; m_pwfiBandedTran = NULL; m_lInternalFlags = 0; }
/**************************************************************************\
* CWiaItem::GetItemType * * Get the item type from the corresponding driver item. * * Arguments: * * pItemType - Pointer to the returned item type. * * Return Value: * * Status * * History: * * 11/11/1998 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::GetItemType(LONG *pItemType) { DBG_FN(CWiaItem::GetItemType); LONG lFlags = 0; HRESULT hr = S_FALSE;
if (m_pWiaDrvItem) {
//
// Get the driver item flags. This is the flags basis for App. Items
// that were created as a result of copying the driver item tree i.e.
// non-generated items.
//
hr = m_pWiaDrvItem->GetItemFlags(&lFlags); if (SUCCEEDED(hr)) {
//
// The App. item may have analysis-generated children, which the
// corresponding driver item wont have. So check whether this
// item has children, and adjust the flags accordingly.
//
if (m_pCWiaTree) { if (m_pCWiaTree->GetFirstChildItem(NULL) == S_OK) {
//
// Has children, so clear File flag and set Folder
//
if (!(lFlags & WiaItemTypeHasAttachments)) { lFlags = (lFlags | WiaItemTypeFolder) & ~WiaItemTypeFile; } } }
*pItemType = lFlags; } else { DBG_ERR(("CWiaItem::GetItemType, Could not get the driver item flags!")); } }
return hr; }
/**************************************************************************\
* CWiaItem::EnumChildItems * * Enumerate all child items under the current item, providing the * item is a folder * * Arguments: * * ppIEnumWiaItem - return an IEnumWiaItem object to the caller * * Return Value: * * Status * * History: * * 11/11/1998 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::EnumChildItems(IEnumWiaItem **ppIEnumWiaItem) { DBG_FN(CWiaItem::EnumChildItems); HRESULT hr;
//
// Corresponding driver item must be valid.
//
hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumChildItems, ValidateWiaDrvItemAccess failed")); return hr; }
//
// Validate parameters
//
if (ppIEnumWiaItem == NULL) { DBG_ERR(("CWiaItem::EnumChildItems NULL input parameters")); return E_POINTER; }
*ppIEnumWiaItem = NULL;
//
// Create the enumerator object.
//
CEnumWiaItem* pEnumWiaItem = new CEnumWiaItem();
if (pEnumWiaItem != NULL) {
//
// Initialize the enumerator object.
//
hr = pEnumWiaItem->Initialize(this);
if (SUCCEEDED(hr)) {
//
// get IID_IEnumWiaItem Interface
//
hr = pEnumWiaItem->QueryInterface(IID_IEnumWiaItem, (void **)ppIEnumWiaItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumChildItems, QI of IID_IEnumWiaItem failed")); delete pEnumWiaItem; } } else { delete pEnumWiaItem; } } else { DBG_ERR(("CWiaItem::EnumChildItems, new CEnumWiaItem failed")); hr = E_OUTOFMEMORY; } return hr; }
CWiaItem* _stdcall CWiaItem::GetNextLinearItem(void) { return m_pCWiaTree ? m_pCWiaTree->GetNextLinearItem() : NULL; }
CWiaItem* _stdcall CWiaTree::GetNextLinearItem() { if(m_pLinearList && m_pLinearList->m_pData) { return static_cast<CWiaItem *>(m_pLinearList->m_pData); } else { return NULL; } }
/**************************************************************************\
* DeleteItem * * Applications use this method to delete items. * * Arguments: * * lFlags * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::DeleteItem(LONG lFlags) { DBG_FN(CWiaItem::DeleteItem); LONG lItemFlags; HRESULT hr; IWiaDrvItem *pIChildItem = NULL; LONG lAccessRights;
//
// Corresponding driver item must be valid.
//
hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::DeleteItem, ValidateWiaDrvItemAccess failed")); return hr; }
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) { hr = InitLazyProps(); if (FAILED(hr)) { DBG_ERR(("CWiaItem::DeleteItem, InitLazyProps failed")); return hr; } }
GetItemType(&lItemFlags);
//
// Root item can not be deleted, the application needs it
// in order to release the device.
//
if (lItemFlags & WiaItemTypeRoot) { DBG_ERR(("CWiaItem::DeleteItem, Deletion was attempted on a Root Item")); return (E_INVALIDARG); }
//
// Folder can be deleted only when it is empty
//
if (lItemFlags & (WiaItemTypeFolder | WiaItemTypeHasAttachments)) {
if (m_pCWiaTree->GetFirstChildItem(NULL) == S_OK) { DBG_ERR(("CWiaItem::DeleteItem, Item still has children!")); return (E_INVALIDARG); } }
//
// Check whether the item can be deleted. Generated items can always be
// deleted regardless of AccessRights
//
hr = wiasReadPropLong((BYTE*)this, WIA_IPA_ACCESS_RIGHTS, &lAccessRights, NULL, false); if (hr == S_OK) {
if (!((lAccessRights & WIA_ITEM_CAN_BE_DELETED) || (lItemFlags & WiaItemTypeGenerated))){ DBG_ERR(("CWiaItem::DeleteItem, Item can not be deleted")); return (HRESULT_FROM_WIN32(ERROR_INVALID_ACCESS)); } }
//
// If it's not a generated item, call the driver and ask it to remove
// the item from it's tree.
//
if (!(lItemFlags & WiaItemTypeGenerated)) { //
// Call the mini driver to delete the driver item.
//
{ LOCK_WIA_DEVICE _LWD(this, &hr);
if(SUCCEEDED(hr)) { hr = m_pActiveDevice->m_DrvWrapper.WIA_drvDeleteItem((BYTE*)this, lFlags, &m_lLastDevErrVal); } }
if (SUCCEEDED(hr)) {
//
// Unlink the IWiaDrvItem from the device item tree.
// This will also disable any device access through m_pWiaDrvItem
// by setting the WiaItemTypeDeleted flag.
//
hr = m_pWiaDrvItem->RemoveItemFromFolder(WiaItemTypeDeleted | WiaItemTypeRemoved); } } else {
//
// Since there is no corresponding driver item, manually remove this
// from the tree,
//
hr = m_pCWiaTree->RemoveItemFromFolder(WiaItemTypeDeleted | WiaItemTypeRemoved); }
if (SUCCEEDED(hr)) { //
// Decrement the root item ref count by however much this local ref count
// contributed to it.
//
for (ULONG i = 0; i < m_cLocalRef; i++) { m_pIWiaItemRoot->Release(); } } return hr; }
/*******************************************************************************
* * AnalyzeItem * * DESCRIPTION: * * * PARAMETERS: * *******************************************************************************/
HRESULT _stdcall CWiaItem::AnalyzeItem(LONG lFlags) { DBG_FN(CWiaItem::AnalyzeItem); //
// Corresponding driver item must be valid.
//
HRESULT hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::AnalyzeItem, ValidateWiaDrvItemAccess failed")); return hr; }
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) { hr = InitLazyProps(); if (FAILED(hr)) { DBG_ERR(("CWiaItem::AnalyzeItem, InitLazyProps failed")); return hr; } }
//
// call driver to implement this device dependent call
//
{ LOCK_WIA_DEVICE _LWD(this, &hr);
if(SUCCEEDED(hr)) { hr = m_pActiveDevice->m_DrvWrapper.WIA_drvAnalyzeItem((BYTE*)this, lFlags, &m_lLastDevErrVal); } }
return hr; }
/*******************************************************************************
* * CreateChildItem * * DESCRIPTION: * * * PARAMETERS: * *******************************************************************************/
HRESULT _stdcall CWiaItem::CreateChildItem( LONG lFlags, BSTR bstrItemName, BSTR bstrFullItemName, IWiaItem **ppNewItem) { DBG_FN(CWiaItem::CreateChildItem);
CGenWiaItem *pGenItem = NULL; HRESULT hr = S_OK;
*ppNewItem = NULL;
//
// Create the new item
//
hr = wiasCreateChildAppItem((BYTE*) this, lFlags, bstrItemName, bstrFullItemName, (BYTE**) &pGenItem); if (SUCCEEDED(hr)) {
//
// Get the driver to initialize the item.
//
hr = pGenItem->InitLazyProps(TRUE); if (SUCCEEDED(hr)) {
//
// Return the IWiaItem interface to the calling App.
//
hr = pGenItem->QueryInterface(IID_IWiaItem, (VOID**)ppNewItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::CreateChildItem, bad mini driver interface")); } } else { DBG_ERR(("CWiaItem::CreateChildItem, Error initializing the item properties")); }
if (FAILED(hr)) { delete pGenItem; } } else { DBG_ERR(("CWiaItem::CreateChildItem, error creating generated item")); } return hr; }
/**************************************************************************\
* DeviceCommand * * Issue a device command. * * Arguments: * * lFlags - * plCommand - * ppIWiaItem - * * Return Value: * * Status * * History: * * 11/12/1998 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::DeviceCommand( LONG lFlags, const GUID *plCommand, IWiaItem **ppIWiaItem) { DBG_FN(CWiaItem::DeviceCommand); IWiaDrvItem *pIWiaDrvItem = NULL; HRESULT hr; CWiaItem *pItem;
//
// Driver interface must be valid.
//
if (!m_pActiveDevice) { DBG_ERR(("CWiaItem::DeviceCommand, bad mini driver interface")); return E_FAIL; }
//
// Corresponding driver item must be valid.
//
hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::DeviceCommand, ValidateWiaDrvItemAccess failed")); return hr; }
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) { hr = InitLazyProps(); if (FAILED(hr)) { DBG_ERR(("CWiaItem::DeviceCommand, InitLazyProps failed")); return hr; } }
{ LOCK_WIA_DEVICE _LWD(this, &hr);
if(SUCCEEDED(hr)) { hr = m_pActiveDevice->m_DrvWrapper.WIA_drvDeviceCommand((BYTE*)this, lFlags, plCommand, &pIWiaDrvItem, &m_lLastDevErrVal); } }
if ((!pIWiaDrvItem) || (!ppIWiaItem)) { return hr; }
//
// If we are here, the command has resulted in a drv item being added to
// the drv and app item trees. Find and return the app item.
//
if (ppIWiaItem) {
BSTR bstrName;
*ppIWiaItem = NULL;
hr = pIWiaDrvItem->GetFullItemName(&bstrName); if (SUCCEEDED(hr)) { hr = FindItemByName(0, bstrName, ppIWiaItem); } SysFreeString(bstrName); } return hr; }
/*******************************************************************************
* * DeviceDlg * * DESCRIPTION: * Executes only on the client side. * * PARAMETERS: * *******************************************************************************/
HRESULT _stdcall CWiaItem::DeviceDlg( HWND hwndParent, LONG lFlags, LONG lIntent, LONG *plItemCount, IWiaItem ***pIWiaItems) { DBG_FN(CWiaItem::DeviceDlg); DBG_ERR(("CWiaItem::DeviceDlg, Bad Proxy")); return E_FAIL; }
/**************************************************************************\
* CWiaItem::GetRootItem * * return interface to root item * * Arguments: * * ppIWiaItem - return IWiaItem interface * * Return Value: * * Status * * History: * * 10/20/1998 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::GetRootItem(IWiaItem **ppIWiaItem) { DBG_FN(CWiaItem::GetRootItem); HRESULT hr = S_OK; LONG lDevErrVal;
//
// verify root is valid
//
if (m_pIWiaItemRoot != NULL) {
m_pIWiaItemRoot->AddRef(); *ppIWiaItem = m_pIWiaItemRoot;
} else { DBG_ERR(("CWiaItem::GetRootItem: Bad Root item pointer")); hr = E_FAIL; } return hr; }
/**************************************************************************\
* FindItemByName * * Find an item based on its full name. Full name must be of the format. * * DeviceID\RootDir\[sub-dirs]\ItemName * * Arguments: * * lFalgs * bstrFullItemName * ppIWiaItem * * Return Value: * * Status * * History: * * 10/9/1998 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::FindItemByName( LONG lFlags, BSTR bstrFullItemName, IWiaItem **ppIWiaItem) { DBG_FN(CWiaItem::FindItemByName); HRESULT hr;
if (bstrFullItemName == NULL) { DBG_WRN(("CWiaItem::FindItemByName, bstrFullItemName parameter is NULL")); return E_INVALIDARG; }
//
// Corresponding driver item must be valid.
//
hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::FindItemByName, ValidateWiaDrvItemAccess failed")); return hr; }
*ppIWiaItem = NULL;
//
// check for empty
//
if (wcscmp(bstrFullItemName, L"") == 0) { DBG_ERR(("CWiaItem::FindItemByName, Full Item Name is NULL")); return S_FALSE; }
//
// try to find matching driver item from linear list
//
CWiaTree *pIChildItem;
//
// Make Sure the tree doesn't get deleted, then search the tree.
//
AddRef();
hr = m_pCWiaTree->FindItemByName(lFlags, bstrFullItemName, &pIChildItem);
//
// If the item was found, get the app item pointer and addref.
//
if (hr == S_OK) {
hr = pIChildItem->GetItemData((void**)ppIWiaItem);
if (hr == S_OK) { (*ppIWiaItem)->AddRef(); } else { DBG_ERR(("CWiaItem::FindItemByName, bad item data")); } } else { //DBG_WRN(("CWiaItem::FindItemByName, Item (%ws) not found in tree", bstrFullItemName));
}
Release();
return hr; }
/**************************************************************************\
* EnumDeviceCapabilities * * * * Arguments: * * * * Return Value: * * Status * * History: * * 1/15/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::EnumDeviceCapabilities( LONG lFlags, IEnumWIA_DEV_CAPS **ppIEnum) { DBG_FN(CWiaItem::EnumDeviceCapabilities);
//
// Corresponding driver item must be valid.
//
HRESULT hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumDeviceCapabilities, ValidateWiaDrvItemAccess failed")); return hr; }
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) { hr = InitLazyProps(); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumDeviceCapabilities, InitLazyProps failed")); return hr; } }
//
// Add support for flags later.
//
CEnumDC *pEnum = new CEnumDC();;
if (!pEnum) { DBG_ERR(("CWiaItem::EnumDeviceCapabilities, new CEnumDC failed")); return E_OUTOFMEMORY; }
hr = pEnum->Initialize(lFlags, this); if (SUCCEEDED(hr)) {
hr = pEnum->QueryInterface(IID_IEnumWIA_DEV_CAPS, (void **) ppIEnum); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumDeviceCapabilities, QI for IID_IEnumWIA_DEV_CAPS failed")); delete pEnum; } } else { DBG_ERR(("CWiaItem::EnumDeviceCapabilities, call to Initialize failed")); delete pEnum; }
return hr; }
/**************************************************************************\
* EnumRegisterEventInfo * * * * Arguments: * * * * Return Value: * * Status * * History: * * 1/15/1999 Original Version * \**************************************************************************/ HRESULT _stdcall CWiaItem::EnumRegisterEventInfo( LONG lFlags, const GUID *pEventGUID, IEnumWIA_DEV_CAPS **ppIEnumDevCap) { DBG_FN(CWiaItem::EnumRegisterEventInfo); HRESULT hr; LONG lItemType; PROPSPEC propSpec[1]; PROPVARIANT propVar[1];
//
// Retrieve the item type and check whether it is the root item
//
hr = m_pWiaDrvItem->GetItemFlags(&lItemType); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumRegisterEventInfo() : Failed to get item type")); return (hr); }
if (! (lItemType & WiaItemTypeRoot)) { DBG_ERR(("CWiaItem::EnumRegisterEventInfo() : Called on non-root item")); return (E_INVALIDARG); }
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) { hr = InitLazyProps(); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumRegisterEventInfo, InitLazyProps failed")); return hr; } }
//
// Retrieve the Device ID from root item's property
//
propSpec->ulKind = PRSPEC_PROPID; propSpec->propid = WIA_DIP_DEV_ID; hr = ReadMultiple(1, propSpec, propVar); if (FAILED(hr)) { DBG_ERR(("CWiaItem::EnumRegisterEventInfo() : Failed to get device id")); return (hr); }
//
// Ask the Event Notifier to create the enumerator
//
hr = g_eventNotifier.CreateEnumEventInfo( propVar->bstrVal, pEventGUID, ppIEnumDevCap);
//
// Garbage collection
//
PropVariantClear(propVar); return (hr); }
/**************************************************************************\
* CWiaItem::Diagnostic * * Pass through to USD's diagnostic. * * Arguments: * * ulSize - the size of the buffer in bytes * pBuffer - a pointer to the Diagnostic information buffer * * Return Value: * * Status * * History: * * 12/14/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::Diagnostic( ULONG ulSize, BYTE *pBuffer) { DBG_FN(CWiaItem::Diagnostic); IStiUSD *pIStiUSD; HRESULT hr = S_OK;
hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::Diagnostic() : Driver Item not valid!")); return hr; }
_try {
//
// Get IStiUsd
//
if (m_pActiveDevice) { //
// Call diagnostic
//
{ LOCK_WIA_DEVICE _LWD(this, &hr);
if(SUCCEEDED(hr)) { hr = m_pActiveDevice->m_DrvWrapper.STI_Diagnostic((STI_DIAG*)pBuffer); } }
} else { DBG_ERR(("CWiaItem::Diagnostic() : invalid MiniDriver interface")); return E_INVALIDARG; } } _except(EXCEPTION_EXECUTE_HANDLER) { DBG_ERR(("CWiaItem::Diagnostic() : Exception in USD!")); hr = E_FAIL; }
return hr; }
/**************************************************************************\
* CWiaItem::DumpItemData * * Allocate buffer and dump formated private CWiaItem data into it. * * Arguments: * * * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::DumpItemData(BSTR *bstrItemData) { DBG_FN(CWiaItem::DumpItemData); #ifdef ITEMDEBUG
#define BUF_SIZE 2048
#define LINE_SIZE 128
WCHAR szTemp[BUF_SIZE]; LPOLESTR psz = szTemp; BSTR bstr;
psz+= wsprintfW(psz, L"App item, CWiaItem: %08X\r\n\r\n", this); psz+= wsprintfW(psz, L"Address Member Value\r\n\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_pWiaDrvItem: %08X\r\n", &m_pWiaDrvItem, m_pWiaDrvItem); psz+= wsprintfW(psz, L"%08X m_pActiveDevice: %08X\r\n", &m_pActiveDevice, m_pActiveDevice); psz+= wsprintfW(psz, L"%08X m_pIUnknownInner: %08X\r\n", &m_pIUnknownInner, m_pIUnknownInner); psz+= wsprintfW(psz, L"%08X m_pCWiaTree: %08X\r\n", &m_pCWiaTree, m_pCWiaTree); psz+= wsprintfW(psz, L"%08X m_pIWiaItemRoot: %08X\r\n", &m_pIWiaItemRoot, m_pIWiaItemRoot); psz+= wsprintfW(psz, L"%08X m_pPropStg: %08X\r\n", &m_pPropStg, m_pPropStg); psz+= wsprintfW(psz, L"%08X m_hBandSection: %08X\r\n", &m_hBandSection, m_hBandSection); psz+= wsprintfW(psz, L"%08X m_pBandBuffer: %08X\r\n", &m_pBandBuffer, m_pBandBuffer); psz+= wsprintfW(psz, L"%08X m_lBandBufferLength: %08X\r\n", &m_lBandBufferLength, m_lBandBufferLength); psz+= wsprintfW(psz, L"%08X m_ClientBaseAddress: %08X\r\n", &m_ClientBaseAddress, m_ClientBaseAddress); psz+= wsprintfW(psz, L"%08X m_bMapSection: %08X\r\n", &m_bMapSection, m_bMapSection); psz+= wsprintfW(psz, L"%08X m_cfeBandedTran: %08X\r\n", &m_cwfiBandedTran, m_cwfiBandedTran); psz+= wsprintfW(psz, L"%08X m_pfeBandedTran: %08X\r\n", &m_pwfiBandedTran, m_pwfiBandedTran);
if (psz > (szTemp + (BUF_SIZE - LINE_SIZE))) { DBG_ERR(("CWiaItem::DumpItemData buffer too small")); }
bstr = SysAllocString(szTemp); if (bstr) { *bstrItemData = bstr; return S_OK; } return E_OUTOFMEMORY; #else
return E_NOTIMPL; #endif
}
/**************************************************************************\
* CWiaItem::DumpDrvItemData * * Allocate buffer and dump formated private CWiaDrvItem data into it. * * Arguments: * * * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::DumpDrvItemData(BSTR *bstrDrvItemData) { DBG_FN(CWiaItem::DumpDrvItemData); #ifdef DEBUG
if (m_pWiaDrvItem) { return m_pWiaDrvItem->DumpItemData(bstrDrvItemData); } else { *bstrDrvItemData = SysAllocString(L"No linkage to driver item"); if (*bstrDrvItemData) { return S_OK; } return E_OUTOFMEMORY; } #else
return E_NOTIMPL; #endif
}
/**************************************************************************\
* CWiaItem::DumpTreeItemData * * Allocate buffer and dump formated private CWiaTree data into it. * * Arguments: * * * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::DumpTreeItemData(BSTR *bstrTreeItemData) { DBG_FN(CWiaItem::DumpTreeItemData); #ifdef DEBUG
if (m_pCWiaTree) { return m_pCWiaTree->DumpTreeData(bstrTreeItemData); } else { *bstrTreeItemData = SysAllocString(L"No linkage to tree item"); if (*bstrTreeItemData) { return S_OK; } return E_OUTOFMEMORY; } #else
return E_NOTIMPL; #endif
}
/**************************************************************************\
* CWiaItem::GetTreePtr * * Returns a pointer to an items corresponding tree entry. * * Arguments: * * None * * Return Value: * * Pointer to a tree item on success, null if failure. * * History: * * 1/19/1999 Original Version * \**************************************************************************/
CWiaTree* _stdcall CWiaItem::GetTreePtr(void) { DBG_FN(CWiaItem::GetTreePtr); if (m_pCWiaTree) { return m_pCWiaTree; } else { DBG_ERR(("CWiaItem::GetTreePtr NULL tree item pointer for item: %X", this)); return NULL; } }
/**************************************************************************\
* CWiaItem::GetDrvItemPtr * * Returns a pointer to an items corresponding driver item. * * Arguments: * * None * * Return Value: * * Pointer to a driver item on success, null if failure. * * History: * * 1/19/1999 Original Version * \**************************************************************************/
CWiaDrvItem* _stdcall CWiaItem::GetDrvItemPtr(void) { DBG_FN(CWiaItem::GetDrvItemPtr); if (m_pWiaDrvItem) { return m_pWiaDrvItem; } else { DBG_ERR(("CWiaItem::GetDrvItemPtr NULL driver item pointer for item: %X", this)); return NULL; } }
/**************************************************************************\
* CWiaItem::WriteItemPropNames * * Write property names to all internal property storage. * * Arguments: * * * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::WriteItemPropNames( LONG cItemProps, PROPID *ppId, LPOLESTR *ppszNames) { DBG_FN(CWiaItem::WriteItemPropNames); if (IsBadReadPtr(ppId, sizeof(PROPID) * cItemProps) || IsBadReadPtr(ppszNames, sizeof(LPOLESTR) * cItemProps)) { DBG_ERR(("CWiaItem::WriteItemPropNames, NULL input pointer")); return E_INVALIDARG; }
HRESULT hr = m_pPropStg->WriteItemPropNames(cItemProps, ppId, ppszNames); if (FAILED(hr)) { DBG_ERR(("CWiaItem::WriteItemPropNames, WritePropertyNames failed (0x%X)", hr)); return hr; } return hr; }
/**************************************************************************\
* CWiaItem::GetItemPropStreams * * Get pointers to all internal property storage. * * Arguments: * * * * Return Value: * * Status * * History: * * 1/19/1999 Original Version * \**************************************************************************/
HRESULT _stdcall CWiaItem::GetItemPropStreams( IPropertyStorage **ppIPropStg, IPropertyStorage **ppIPropAccessStg, IPropertyStorage **ppIPropValidStg, IPropertyStorage **ppIPropOldStg) { DBG_FN(CWiaItem::GetItemPropStreams); HRESULT hr;
if (!m_pPropStg) { DBG_ERR(("CWiaItem::GetItemPropStreams, NULL internal property storage pointer")); return E_FAIL; }
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps(); if (FAILED(hr)) { DBG_ERR(("CWiaItem::GetItemPropStreams, InitLazyProps failed")); return hr; } }
if (ppIPropStg) { *ppIPropStg = m_pPropStg->CurStg(); }
if (ppIPropAccessStg) { *ppIPropAccessStg = m_pPropStg->AccessStg(); }
if (ppIPropValidStg) { *ppIPropValidStg = m_pPropStg->ValidStg(); }
if (ppIPropOldStg) { *ppIPropOldStg = m_pPropStg->OldStg(); if (!(*ppIPropOldStg)) { //
// Note that if the old property storage is NULL, we
// return the current value storage
//
*ppIPropOldStg = m_pPropStg->CurStg(); } } return S_OK; }
/**************************************************************************\
* CWiaItem::AddVolumePropertiesToRoot * * This helper method takes a Root WiaItem and adds any volume specific * properties to it. Note that this should only be called on the Root * item of Volume devices. * * Arguments: * * pActiveDevice - Pointer to Root's active device object * * Return Value: * * Status * * History: * * 12/13/2000 Original Version * \**************************************************************************/ HRESULT CWiaItem::AddVolumePropertiesToRoot( ACTIVE_DEVICE *pActiveDevice) { DBG_FN(AddVolumePropertiesToRoot); HRESULT hr = S_OK;
//
// To add new FIle SYstem properties:
// Simply add the appropriate entries to
// piFileSystem
// psFileSystem
// pwszFileSystem
// pwszFileSystem
// wpiFileSystem
// Then, don't forget to add the current value entries to
// pvFileSystem
// before doing a WriteMultiple. Notice that PropVariant arrays
// cannot be statically initialized (will give problems on 64bit)
//
PROPID piFileSystem[] = {WIA_DPF_MOUNT_POINT}; PROPSPEC psFileSystem[] = { {PRSPEC_PROPID, WIA_DPF_MOUNT_POINT} }; LPOLESTR pwszFileSystem[] = {WIA_DPF_MOUNT_POINT_STR};
WIA_PROPERTY_INFO wpiFileSystem[] = { {WIA_PROP_RNC, VT_BSTR, 0, 0, 0, 0}, // WIA_DPF_MOUNT_POINT
};
PROPVARIANT pvFileSystem[sizeof(piFileSystem) / sizeof(piFileSystem[0])];
//
// Write the File System property names.
//
hr = WriteItemPropNames(sizeof(piFileSystem) / sizeof(piFileSystem[0]), piFileSystem, pwszFileSystem); if (FAILED(hr)) { DBG_ERR(("CWiaItem::AddVolumePropertiesToRoot, WritePropNames failed")); return hr; }
//
// Write the File System property values
//
ULONG ulIndex;
memset(pvFileSystem, 0, sizeof(pvFileSystem));
BSTR bstrMountPoint = NULL; DEVICE_INFO *pDevInfo = pActiveDevice->m_DrvWrapper.getDevInfo();
if (pDevInfo) { bstrMountPoint = SysAllocString(pDevInfo->wszAlternateID); }
pvFileSystem[0].vt = VT_BSTR; pvFileSystem[0].bstrVal = bstrMountPoint;
hr = (m_pPropStg->CurStg())->WriteMultiple(sizeof(piFileSystem) / sizeof(piFileSystem[0]), psFileSystem, pvFileSystem, WIA_DPF_FIRST); FreePropVariantArray(sizeof(piFileSystem) / sizeof(piFileSystem[0]), pvFileSystem); if (FAILED(hr)) { ReportReadWriteMultipleError(hr, "CWiaItem::AddVolumePropertiesToRoot", NULL, FALSE, WIA_NUM_DIP, g_psDeviceInfo); DBG_ERR(("CWiaItem::AddVolumePropertiesToRoot failed")); return hr; }
//
// Write out the File System property attributes
//
hr = wiasSetItemPropAttribs((BYTE*)this, sizeof(piFileSystem) / sizeof(piFileSystem[0]), psFileSystem, wpiFileSystem);
return hr; }
|