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.
 
 
 
 
 
 

2507 lines
63 KiB

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