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.
482 lines
14 KiB
482 lines
14 KiB
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 1998
|
|
*
|
|
* TITLE: WiaGItm.Cpp
|
|
*
|
|
* VERSION: 1.0
|
|
*
|
|
* AUTHOR: ByronC
|
|
*
|
|
* DATE: 14 Jan, 2000
|
|
*
|
|
* DESCRIPTION:
|
|
* Implementation of CGenWiaItem.
|
|
*
|
|
*******************************************************************************/
|
|
#include "precomp.h"
|
|
|
|
#include "stiexe.h"
|
|
#include "wiapsc.h"
|
|
#define WIA_DECLARE_MANAGED_PROPS
|
|
#include "helpers.h"
|
|
|
|
|
|
/**************************************************************************\
|
|
* Initialize
|
|
*
|
|
* CGenWiaItem Initialize method. This method overrieds the base class
|
|
* CWiaItem::Initialize, since a generated item
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pIWiaItemRoot -
|
|
* pIWiaMiniDrv -
|
|
* pWiaDrvItem -
|
|
* pIUnknownInner -
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 14 Jan, 2000 - Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CGenWiaItem::Initialize(
|
|
IWiaItem *pIWiaItemRoot,
|
|
IWiaPropertyStorage *pIWiaDevInfoProps,
|
|
ACTIVE_DEVICE *pActiveDevice,
|
|
CWiaDrvItem *pWiaDrvItem,
|
|
IUnknown *pIUnknownInner)
|
|
{
|
|
|
|
DBG_FN(CGenWiaItem::Initialize);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
#ifdef DEBUG
|
|
BSTR bstr;
|
|
if (SUCCEEDED(pWiaDrvItem->GetItemName(&bstr))) {
|
|
DBG_TRC(("CGenWiaItem::Initialize: 0x%08X, %ws, drv item: 0x%08X", this, bstr, pWiaDrvItem));
|
|
SysFreeString(bstr);
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Validate parameters
|
|
//
|
|
|
|
if (!pActiveDevice || !pIWiaItemRoot || !pWiaDrvItem) {
|
|
DBG_ERR(("CGenWiaItem::Initialize NULL input parameters"));
|
|
return E_POINTER;
|
|
}
|
|
|
|
//
|
|
// If optional inner component is present, save a pointer to it.
|
|
//
|
|
|
|
if (pIUnknownInner) {
|
|
DBG_TRC(("CGenWiaItem::Initialize, pIUnknownInner: %X", pIUnknownInner));
|
|
m_pIUnknownInner = pIUnknownInner;
|
|
}
|
|
|
|
//
|
|
// Save driver info.
|
|
//
|
|
|
|
m_pWiaDrvItem = pWiaDrvItem;
|
|
m_pActiveDevice = pActiveDevice;
|
|
m_pIWiaItemRoot = pIWiaItemRoot;
|
|
|
|
hr = pWiaDrvItem->LinkToDrvItem(this);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CGenWiaItem::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(("CGenWiaItem::Initialize, PropertyStorage Initialize failed"));
|
|
return hr;
|
|
}
|
|
} else {
|
|
DBG_ERR(("CGenWiaItem::Initialize, not enough memory to create CWiaPropStg"));
|
|
hr = E_OUTOFMEMORY;
|
|
return hr;
|
|
}
|
|
m_bInitialized = TRUE;
|
|
|
|
//
|
|
// AddRef the driver item which can not be deleted until all
|
|
// CWiaItem references are released and the driver item has been
|
|
// removed from the driver item tree.
|
|
//
|
|
|
|
pWiaDrvItem->AddRef();
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* GetItemType
|
|
*
|
|
* Get the item type from the corresponding driver item.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pItemType - Pointer to the returned item type.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 14 Jan, 2000 - Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CGenWiaItem::GetItemType(LONG *pItemType)
|
|
{
|
|
DBG_FN(CGenWiaItem::GetItemType);
|
|
|
|
return m_pCWiaTree->GetItemFlags(pItemType);
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* InitManagedItemProperties
|
|
*
|
|
* A private helper for CGenWiaItem::Initialize, which initializes the
|
|
* WIA managed item properties.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 14 Jan, 2000 - Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall CGenWiaItem::InitManagedItemProperties(
|
|
LONG lFlags,
|
|
BSTR bstrItemName,
|
|
BSTR bstrFullItemName)
|
|
{
|
|
DBG_FN(CWiaItem::InitManagedItemProperties);
|
|
ULONG ulNumProps;
|
|
|
|
ulNumProps = 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 propvar;
|
|
ULONG ulFlag;
|
|
for (UINT i = 0; i < ulNumProps; i++) {
|
|
|
|
if (i == PROFILE_INDEX) {
|
|
propvar.vt = VT_BSTR | VT_VECTOR;
|
|
ulFlag = WIA_PROP_RW | WIA_PROP_CACHEABLE | WIA_PROP_LIST;
|
|
} else {
|
|
propvar.vt = VT_I4;
|
|
ulFlag = WIA_PROP_READ | WIA_PROP_CACHEABLE | WIA_PROP_NONE;
|
|
}
|
|
propvar.ulVal = 0;
|
|
|
|
hr = wiasSetPropertyAttributes((BYTE*)this,
|
|
1,
|
|
&s_psItemNameType[i],
|
|
&ulFlag,
|
|
&propvar);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaItem::InitManagedItemProperties, wiasSetPropertyAttributes failed, index: %d", i));
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the item names and type.
|
|
//
|
|
|
|
PROPVARIANT *ppropvar;
|
|
|
|
ppropvar = (PROPVARIANT*) LocalAlloc(LPTR, sizeof(PROPVARIANT) * ulNumProps);
|
|
if (ppropvar) {
|
|
memset(ppropvar, 0, sizeof(ppropvar[0]) * ulNumProps);
|
|
|
|
ppropvar[0].vt = VT_BSTR;
|
|
ppropvar[0].bstrVal = bstrItemName;
|
|
ppropvar[1].vt = VT_BSTR;
|
|
ppropvar[1].bstrVal = bstrFullItemName;
|
|
ppropvar[2].vt = VT_I4;
|
|
ppropvar[2].lVal = lFlags;
|
|
|
|
hr = (m_pPropStg->CurStg())->WriteMultiple(ulNumProps,
|
|
s_psItemNameType,
|
|
ppropvar,
|
|
WIA_DIP_FIRST);
|
|
if (FAILED(hr)) {
|
|
ReportReadWriteMultipleError(hr, "CWiaItem::InitManagedItemProperties",
|
|
NULL,
|
|
FALSE,
|
|
ulNumProps,
|
|
s_psItemNameType);
|
|
}
|
|
LocalFree(ppropvar);
|
|
} else {
|
|
DBG_ERR(("CWiaItem::InitManagedItemProperties, Out of Memory!"));
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT GetParamsForInitialize(
|
|
BYTE *pWiasContext,
|
|
CWiaItem **ppRoot,
|
|
ACTIVE_DEVICE **ppActiveDevice,
|
|
CWiaDrvItem **ppDrvItem)
|
|
{
|
|
DBG_FN(GetParamsForInitialize);
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Get the root item, the nearest driver item, and the minidriver
|
|
// interfaces. These are needed for the child item's initialization.
|
|
//
|
|
|
|
hr = wiasGetRootItem(pWiasContext, (BYTE**) ppRoot);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
*ppDrvItem = ((CWiaItem*)pWiasContext)->GetDrvItemPtr();
|
|
if (*ppDrvItem) {
|
|
CWiaItem *pItem = (CWiaItem*) pWiasContext;
|
|
|
|
*ppActiveDevice = pItem->m_pActiveDevice;
|
|
} else {
|
|
DBG_ERR(("GetParamsForInitialize, No driver item found!"));
|
|
hr = E_INVALIDARG;
|
|
}
|
|
} else {
|
|
DBG_ERR(("GetParamsForInitialize, Could not get root item!"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT AddGenItemToParent(
|
|
CWiaItem *pParent,
|
|
LONG lFlags,
|
|
BSTR bstrItemName,
|
|
BSTR bstrFullItemName,
|
|
CGenWiaItem *pChild)
|
|
{
|
|
DBG_FN(GetParamsForInitialize);
|
|
HRESULT hr = E_FAIL;
|
|
|
|
//
|
|
// Create the Tree
|
|
//
|
|
|
|
CWiaTree *pNewTreeItem = new CWiaTree;
|
|
|
|
if (pNewTreeItem) {
|
|
|
|
//
|
|
// Adjust parent's flags to indicate folder
|
|
//
|
|
|
|
pParent->m_pCWiaTree->SetFolderFlags();
|
|
|
|
//
|
|
// Initialize the tree with flags, names and payload
|
|
//
|
|
|
|
hr = pNewTreeItem->Initialize(lFlags,
|
|
bstrItemName,
|
|
bstrFullItemName,
|
|
(void*)pChild);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
pChild->m_pCWiaTree = pNewTreeItem;
|
|
|
|
hr = pChild->m_pCWiaTree->AddItemToFolder(pParent->m_pCWiaTree);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("AddGenItemToParent, Could not add item to folder!"));
|
|
}
|
|
} else {
|
|
DBG_ERR(("AddGenItemToParent, Failed to initialize the tree!"));
|
|
}
|
|
|
|
if (FAILED(hr)) {
|
|
delete pNewTreeItem;
|
|
pChild->m_pCWiaTree = NULL;
|
|
}
|
|
} else {
|
|
DBG_ERR(("AddGenItemToParent, Out of Memory!"));
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* wiasCreateChildAppItem
|
|
*
|
|
* This function creates a new App. Item and inserts it as a child of the
|
|
* specified (parent) item. Note, that this item will not have any
|
|
* properties in it's property sets, until the driver/app actaully fills
|
|
* them in.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pWiasContext - the address of the item context to which we
|
|
* want to add a child.
|
|
* ppWiasChildContext - the address of a pointer which will contain the
|
|
* address of the newly created child item's
|
|
* context.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 14 Jan, 2000 - Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT _stdcall wiasCreateChildAppItem(
|
|
BYTE *pParentWiasContext,
|
|
LONG lFlags,
|
|
BSTR bstrItemName,
|
|
BSTR bstrFullItemName,
|
|
BYTE **ppWiasChildContext)
|
|
{
|
|
|
|
DBG_FN(wiasCreateChildAppItem);
|
|
HRESULT hr = S_OK;
|
|
CGenWiaItem *pChild;
|
|
CWiaItem *pItem = (CWiaItem*) pParentWiasContext;
|
|
CWiaItem *pRoot = NULL;
|
|
CWiaDrvItem *pDrvItem = NULL;
|
|
ACTIVE_DEVICE *pActiveDevice = NULL;
|
|
|
|
if ((ValidateWiaItem((IWiaItem*) pParentWiasContext) != S_OK) ||
|
|
(IsBadWritePtr(ppWiasChildContext, sizeof(BYTE*)))) {
|
|
|
|
DBG_ERR(("wiasCreateChildAppItem, Invalid parameter!"));
|
|
return E_INVALIDARG;
|
|
} else {
|
|
*ppWiasChildContext = NULL;
|
|
}
|
|
|
|
//
|
|
// Mark that this item is a generated item.
|
|
//
|
|
|
|
lFlags |= WiaItemTypeGenerated;
|
|
|
|
//
|
|
// Create a new instance of a generated WIA app. item.
|
|
//
|
|
|
|
pChild = new CGenWiaItem();
|
|
if (pChild) {
|
|
|
|
hr = GetParamsForInitialize(pParentWiasContext, &pRoot, &pActiveDevice, &pDrvItem);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// Initialize the new child item
|
|
//
|
|
|
|
hr = pChild->Initialize((IWiaItem*) pRoot, NULL, pActiveDevice, pDrvItem, NULL);
|
|
if (SUCCEEDED(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()
|
|
//
|
|
|
|
hr = pChild->InitManagedItemProperties(lFlags,
|
|
bstrItemName,
|
|
bstrFullItemName);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// Add to the parent's Tree
|
|
//
|
|
|
|
hr = AddGenItemToParent(pItem,
|
|
lFlags,
|
|
bstrItemName,
|
|
bstrFullItemName,
|
|
pChild);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
//
|
|
// Initialization successful. Note that we
|
|
// don't AddRef here since if the caller was
|
|
// a driver, IWiaItems are BYTE* pWiasContexts
|
|
// and not COM objects. Caller must AddRef
|
|
// if handing the created to an Application.
|
|
//
|
|
|
|
//
|
|
// Fill in ICM Profile information, if not root item.
|
|
// This would normally go in InitManagedItemProperties,
|
|
// but the item had not been added to the tree by that
|
|
// time...
|
|
//
|
|
|
|
if (pRoot != pChild) {
|
|
hr = FillICMPropertyFromRegistry(NULL, (IWiaItem*) pChild);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr)) {
|
|
delete pChild;
|
|
pChild = NULL;
|
|
}
|
|
} else {
|
|
DBG_ERR(("wiasCreateChildAppItem, Out of Memory!"));
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
*ppWiasChildContext = (BYTE*)pChild;
|
|
}
|
|
|
|
return hr;
|
|
}
|