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.
 
 
 
 
 
 

1899 lines
55 KiB

/*******************************************************************************
*
* (C) COPYRIGHT 2000, MICROSOFT CORP.
*
* TITLE: IWiaMiniDrv.cpp
*
* VERSION: 1.0
*
* DATE: 18 July, 2000
*
* DESCRIPTION:
* Implementation of the WIA sample camera IWiaMiniDrv methods. This file
* contains 3 sections. The first is the WIA minidriver entry points, all
* starting with "drv". The next section is public help methods. The last
* section is private helper methods.
*
*******************************************************************************/
#include "pch.h"
#ifndef INITGUID
#include <initguid.h>
#endif
//
// A few extra format GUIDs
//
DEFINE_GUID(GUID_NULL, 0,0,0,0,0,0,0,0,0,0,0);
DEFINE_GUID(FMT_NOTHING, 0x81a566e7,0x8620,0x4fba,0xbc,0x8e,0xb2,0x7c,0x17,0xad,0x9e,0xfd);
/**************************************************************************\
* CWiaCameraDevice::drvInitializeWia
*
* Initialize the WIA mini driver. This function will be called each time an
* application creates a device. The first time through, the driver item tree
* will be created and other initialization will be done.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags, unused.
* bstrDeviceID - Device ID.
* bstrRootFullItemName - Full item name.
* pIPropStg - Device info. properties.
* pStiDevice - STI device interface.
* pIUnknownOuter - Outer unknown interface.
* ppIDrvItemRoot - Pointer to returned root item.
* ppIUnknownInner - Pointer to returned inner unknown.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvInitializeWia(
BYTE *pWiasContext,
LONG lFlags,
BSTR bstrDeviceID,
BSTR bstrRootFullItemName,
IUnknown *pStiDevice,
IUnknown *pIUnknownOuter,
IWiaDrvItem **ppIDrvItemRoot,
IUnknown **ppIUnknownInner,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvInitializeWia");
if (!ppIUnknownInner || !pIUnknownOuter)
{
// optional arguments, may be NULLs
}
if (!pWiasContext || !bstrDeviceID || !bstrRootFullItemName ||
!pStiDevice || !ppIDrvItemRoot || !plDevErrVal)
{
wiauDbgError("drvInitializeWia", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
//
// Locals
//
MCAM_ITEM_INFO *pItem = NULL;
wiauDbgTrace("drvInitializeWia", "device ID: %S", bstrDeviceID);
*ppIDrvItemRoot = NULL;
if (ppIUnknownInner)
{
*ppIUnknownInner = NULL;
}
//
// Count the number of apps connected so that resources can be
// freed when it reaches zero
//
m_iConnectedApps++;;
wiauDbgTrace("drvInitializeWia", "Number of connected apps is now %d", m_iConnectedApps);
if (m_iConnectedApps == 1)
{
//
// Save STI device interface for calling locking functions
//
m_pStiDevice = (IStiDevice *)pStiDevice;
//
// Cache the device ID
//
m_bstrDeviceID = SysAllocString(bstrDeviceID);
REQUIRE_ALLOC(m_bstrDeviceID, hr, "drvInitializeWia");
//
// Cache the root item name
//
m_bstrRootFullItemName = SysAllocString(bstrRootFullItemName);
REQUIRE_ALLOC(m_bstrRootFullItemName, hr, "drvInitializeWia");
//
// For devices connected to ports that can be shared (e.g. USB),
// open the device and initialize access to the camera
//
if (!m_pDeviceInfo->bExclusivePort) {
hr = m_pDevice->Open(m_pDeviceInfo, m_wszPortName);
REQUIRE_SUCCESS(hr, "Initialize", "Open failed");
}
//
// Get information from the device
//
hr = m_pDevice->GetDeviceInfo(m_pDeviceInfo, &pItem);
REQUIRE_SUCCESS(hr, "drvInitializeWia", "GetDeviceInfo failed");
//
// Build the capabilities array
//
hr = BuildCapabilities();
REQUIRE_SUCCESS(hr, "drvInitializeWia", "BuildCapabilities failed");
//
// Build the device item tree
//
hr = BuildItemTree(pItem);
REQUIRE_SUCCESS(hr, "drvInitializeWia", "BuildItemTree failed");
}
*ppIDrvItemRoot = m_pRootItem;
Cleanup:
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvUnInitializeWia
*
* Gets called when a client connection is going away.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA Root item context of the client's
* item tree.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvUnInitializeWia(BYTE *pWiasContext)
{
DBG_FN("CWiaCameraDevice::drvUnInitializeWia");
if (!pWiasContext)
{
wiauDbgError("drvUnInitializeWia", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
m_iConnectedApps--;
if (m_iConnectedApps == 0)
{
hr = FreeResources();
if (FAILED(hr))
wiauDbgErrorHr(hr, "drvUnInitializeWia", "FreeResources failed, continuing...");
//
// Do not delete the device object here, because GetStatus may still be called later.
//
}
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvInitItemProperties
*
* Initialize the device item properties. Called during item
* initialization. This is called by the WIA Class driver
* after the item tree has been built. It is called once for every
* item in the tree. For the root item, just set the properties already
* set up in drvInitializeWia. For child items, access the camera for
* information about the item and for images also get the thumbnail.
*
* Arguments:
*
* pWiasContext - Pointer to WIA item.
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvInitItemProperties(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvInitItemProperties");
if (!pWiasContext || !plDevErrVal)
{
wiauDbgError("drvInitItemProperties", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
LONG lItemType;
hr = wiasGetItemType(pWiasContext, &lItemType);
REQUIRE_SUCCESS(hr, "drvInitItemProperties", "wiasGetItemType failed");
if (lItemType & WiaItemTypeRoot) {
//
// Build root item properties, initializing global
// structures with their default and valid values
//
hr = BuildRootItemProperties(pWiasContext);
REQUIRE_SUCCESS(hr, "drvInitItemProperties", "BuildRootItemProperties failed");
}
else {
//
// Build child item properties, initializing global
// structures with their default and valid values
//
hr = BuildChildItemProperties(pWiasContext);
REQUIRE_SUCCESS(hr, "drvInitItemProperties", "BuildChildItemProperties failed");
}
Cleanup:
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvLockWiaDevice
*
* Lock access to the device.
*
* Arguments:
*
* pWiasContext - unused, can be NULL
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvLockWiaDevice(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvLockWiaDevice");
if (!plDevErrVal)
{
wiauDbgError("drvLockWiaDevice", "invalid arguments");
return E_INVALIDARG;
}
*plDevErrVal = 0;
return m_pStiDevice->LockDevice(100);
}
/**************************************************************************\
* CWiaCameraDevice::drvUnLockWiaDevice
*
* Unlock access to the device.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvUnLockWiaDevice(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvUnLockWiaDevice");
if (!pWiasContext || !plDevErrVal)
{
wiauDbgError("drvUnLockWiaDevice", "invalid arguments");
return E_INVALIDARG;
}
*plDevErrVal = 0;
return m_pStiDevice->UnLockDevice();
}
/**************************************************************************\
* CWiaCameraDevice::drvFreeDrvItemContext
*
* Free any device specific context.
*
* Arguments:
*
* lFlags - Operation flags, unused.
* pDevSpecContext - Pointer to device specific context.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvFreeDrvItemContext(
LONG lFlags,
BYTE *pSpecContext,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvFreeDrvItemContext");
if (!pSpecContext || !plDevErrVal)
{
wiauDbgError("drvFreeDrvItemContext", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
ITEM_CONTEXT *pItemCtx = (ITEM_CONTEXT *) pSpecContext;
if (pItemCtx)
{
if (pItemCtx->pItemInfo) {
hr = m_pDevice->FreeItemInfo(m_pDeviceInfo, pItemCtx->pItemInfo);
if (FAILED(hr))
wiauDbgErrorHr(hr, "drvFreeDrvItemContext", "FreeItemInfo failed");
}
pItemCtx->pItemInfo = NULL;
if (pItemCtx->pFormatInfo)
{
delete []pItemCtx->pFormatInfo;
pItemCtx->pFormatInfo = NULL;
}
pItemCtx->lNumFormatInfo = 0;
}
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvReadItemProperties
*
* Read the device item properties. When a client application tries to
* read a WIA Item's properties, the WIA Class driver will first notify
* the driver by calling this method.
*
* Arguments:
*
* pWiasContext - wia item
* lFlags - Operation flags, unused.
* nPropSpec - Number of elements in pPropSpec.
* pPropSpec - Pointer to property specification, showing which properties
* the application wants to read.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvReadItemProperties(
BYTE *pWiasContext,
LONG lFlags,
ULONG nPropSpec,
const PROPSPEC *pPropSpec,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvReadItemProperties");
if (!pWiasContext || !pPropSpec || !plDevErrVal)
{
wiauDbgError("drvReadItemProperties", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
LONG lItemType;
hr = wiasGetItemType(pWiasContext, &lItemType);
REQUIRE_SUCCESS(hr, "drvReadItemProperties", "wiasGetItemType failed");
if (lItemType & WiaItemTypeRoot) {
//
// Build root item properties, initializing global
// structures with their default and valid values
//
hr = ReadRootItemProperties(pWiasContext, nPropSpec, pPropSpec);
REQUIRE_SUCCESS(hr, "drvReadItemProperties", "ReadRootItemProperties failed");
}
else {
//
// Build child item properties, initializing global
// structures with their default and valid values
//
hr = ReadChildItemProperties(pWiasContext, nPropSpec, pPropSpec);
REQUIRE_SUCCESS(hr, "drvReadItemProperties", "ReadChildItemProperties failed");
}
Cleanup:
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvWriteItemProperties
*
* Write the device item properties to the hardware. This is called by the
* WIA Class driver prior to drvAcquireItemData when the client requests
* a data transfer.
*
* Arguments:
*
* pWiasContext - Pointer to WIA item.
* lFlags - Operation flags, unused.
* pmdtc - Pointer to mini driver context. On entry, only the
* portion of the mini driver context which is derived
* from the item properties is filled in.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvWriteItemProperties(
BYTE *pWiasContext,
LONG lFlags,
PMINIDRV_TRANSFER_CONTEXT pmdtc,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvWriteItemProperties");
if (!pWiasContext || !pmdtc || !plDevErrVal)
{
wiauDbgError("drvWriteItemProperties", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
//
// This function doesn't need to do anything, because all of the camera
// properties are written in drvValidateItemProperties
//
*plDevErrVal = 0;
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvAcquireItemData
*
* Transfer data from a mini driver item to device manger.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item.
* lFlags - Operation flags, unused.
* pmdtc - Pointer to mini driver context. On entry, only the
* portion of the mini driver context which is derived
* from the item properties is filled in.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvAcquireItemData(
BYTE *pWiasContext,
LONG lFlags,
PMINIDRV_TRANSFER_CONTEXT pmdtc,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvAcquireItemData");
if (!pWiasContext || !plDevErrVal || !pmdtc)
{
wiauDbgError("drvAcquireItemData", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
//
// Locals
//
BYTE *pTempBuf = NULL;
LONG lBufSize = 0;
ITEM_CONTEXT *pItemCtx = NULL;
BOOL bConvert = FALSE;
//
// Get item context
//
hr = wiauGetDrvItemContext(pWiasContext, (VOID **) &pItemCtx);
REQUIRE_SUCCESS(hr, "drvAcquireItemData", "wiauGetDrvItemContext failed");
//
// If the format requested is BMP or DIB, and the image is not already in BMP
// format, convert it
//
bConvert = (IsEqualGUID(pmdtc->guidFormatID, WiaImgFmt_BMP) ||
IsEqualGUID(pmdtc->guidFormatID, WiaImgFmt_MEMORYBMP)) &&
!IsEqualGUID(*(pItemCtx->pItemInfo->pguidFormat), WiaImgFmt_BMP);
//
// If the class driver did not allocate the transfer buffer or the image is being
// converted to DIB or BMP, allocate a temporary buffer.
//
if (bConvert || !pmdtc->bClassDrvAllocBuf) {
lBufSize = pItemCtx->pItemInfo->lSize;
pTempBuf = new BYTE[lBufSize];
REQUIRE_ALLOC(pTempBuf, hr, "drvAcquireItemData");
}
//
// Acquire the data from the device
//
hr = AcquireData(pItemCtx, pmdtc, pTempBuf, lBufSize, bConvert);
REQUIRE_SUCCESS(hr, "drvAcquireItemData", "AcquireData failed");
if (hr == S_FALSE)
{
wiauDbgWarning("drvAcquireItemData", "Transfer cancelled");
goto Cleanup;
}
//
// Now convert the data to BMP, if necessary
//
if (bConvert)
{
hr = Convert(pWiasContext, pItemCtx, pmdtc, pTempBuf, lBufSize);
REQUIRE_SUCCESS(hr, "drvAcquireItemData", "Convert failed");
}
Cleanup:
if (pTempBuf)
{
delete []pTempBuf;
pTempBuf = NULL;
lBufSize = 0;
}
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvGetWiaFormatInfo
*
* Returns an array of WIA_FORMAT_INFO structs, which specify the format
* and media type pairs that are supported.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item context, unused.
* lFlags - Operation flags, unused.
* pcelt - Pointer to returned number of elements in
* returned WIA_FORMAT_INFO array.
* ppwfi - Pointer to returned WIA_FORMAT_INFO array.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvGetWiaFormatInfo(
BYTE *pWiasContext,
LONG lFlags,
LONG *pcelt,
WIA_FORMAT_INFO **ppwfi,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvGetWiaFormatInfo");
if (!pWiasContext || !pcelt || !ppwfi || !plDevErrVal)
{
wiauDbgError("drvGetWiaFormatInfo", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
//
// Locals
//
IWiaDrvItem *pWiaDrvItem = NULL;
ITEM_CONTEXT *pItemCtx = NULL;
const GUID *pguidFormat = NULL;
BOOL bAddBmp = FALSE;
*pcelt = 0;
*ppwfi = NULL;
hr = wiauGetDrvItemContext(pWiasContext, (VOID **) &pItemCtx, &pWiaDrvItem);
REQUIRE_SUCCESS(hr, "drvGetWiaFormatInfo", "wiauGetDrvItemContext failed");
if (!pItemCtx->pFormatInfo)
{
//
// The format info list is not intialized. Do it now.
//
LONG ItemType;
DWORD ui32;
hr = wiasGetItemType(pWiasContext, &ItemType);
REQUIRE_SUCCESS(hr, "drvGetWiaFormatInfo", "wiasGetItemType");
if ((ItemType & WiaItemTypeFolder) ||
(ItemType & WiaItemTypeRoot))
{
//
// Folders and the root don't really need format info, but some apps may fail
// without it. Create a fake list just in case.
//
pItemCtx->pFormatInfo = new WIA_FORMAT_INFO[2];
REQUIRE_ALLOC(pItemCtx->pFormatInfo, hr, "drvGetWiaFormatInfo");
pItemCtx->lNumFormatInfo = 2;
pItemCtx->pFormatInfo[0].lTymed = TYMED_FILE;
pItemCtx->pFormatInfo[0].guidFormatID = FMT_NOTHING;
pItemCtx->pFormatInfo[1].lTymed = TYMED_CALLBACK;
pItemCtx->pFormatInfo[1].guidFormatID = FMT_NOTHING;
}
else if (ItemType & WiaItemTypeFile)
{
//
// Create the supported format for the item, based on the format stored in the
// ObjectInfo structure.
//
if (!pItemCtx->pItemInfo)
{
wiauDbgError("drvGetWiaFormatInfo", "Item info pointer in context is null");
hr = E_FAIL;
goto Cleanup;
}
pguidFormat = pItemCtx->pItemInfo->pguidFormat;
//
// If the format of the item is supported by the converter utility, add the
// BMP types to the format array, since this driver can convert those to BMP
//
bAddBmp = m_Converter.IsFormatSupported(pguidFormat);
ULONG NumWfi = bAddBmp ? 2 : 1;
//
// Allocate two entries for each format, one for file transfer and one for callback
//
WIA_FORMAT_INFO *pwfi = new WIA_FORMAT_INFO[2 * NumWfi];
REQUIRE_ALLOC(pwfi, hr, "drvGetWiaFormatInfo");
pwfi[0].guidFormatID = *pguidFormat;
pwfi[0].lTymed = TYMED_FILE;
pwfi[1].guidFormatID = *pguidFormat;
pwfi[1].lTymed = TYMED_CALLBACK;
//
// Add the BMP entries when appropriate
//
if (bAddBmp)
{
pwfi[2].guidFormatID = WiaImgFmt_BMP;
pwfi[2].lTymed = TYMED_FILE;
pwfi[3].guidFormatID = WiaImgFmt_MEMORYBMP;
pwfi[3].lTymed = TYMED_CALLBACK;
}
pItemCtx->lNumFormatInfo = 2 * NumWfi;
pItemCtx->pFormatInfo = pwfi;
}
}
*pcelt = pItemCtx->lNumFormatInfo;
*ppwfi = pItemCtx->pFormatInfo;
Cleanup:
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvValidateItemProperties
*
* Validate the device item properties. It is called when changes are made
* to an item's properties. Driver should not only check that the values
* are valid, but must update any valid values that may change as a result.
* If an a property is not being written by the application, and it's value
* is invalid, then "fold" it to a new value, else fail validation (because
* the application is setting the property to an invalid value).
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags, unused.
* nPropSpec - The number of properties that are being written
* pPropSpec - An array of PropSpecs identifying the properties that
* are being written.
* plDevErrVal - Pointer to the device error value.
*
***************************************************************************/
HRESULT CWiaCameraDevice::drvValidateItemProperties(
BYTE *pWiasContext,
LONG lFlags,
ULONG nPropSpec,
const PROPSPEC *pPropSpec,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvValidateItemProperties");
if (!pWiasContext || !pPropSpec || !plDevErrVal)
{
wiauDbgError("drvValidateItemProperties", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
//
// Locals
//
LONG lItemType = 0;
ITEM_CONTEXT *pItemCtx = NULL;
MCAM_ITEM_INFO *pItemInfo = NULL;
BOOL bFormatUpdated = FALSE;
LONG lRights = 0;
BOOL bReadOnly = 0;
//
// Have the service validate against the valid values for each property
//
hr = wiasValidateItemProperties(pWiasContext, nPropSpec, pPropSpec);
REQUIRE_SUCCESS(hr, "drvValidateItemProperties", "wiasValidateItemProperties failed");
//
// Get the item type
//
hr = wiasGetItemType(pWiasContext, &lItemType);
REQUIRE_SUCCESS(hr, "drvValidateItemProperties", "wiasGetItemType");
//
// Validate root item properties
//
if (lItemType & WiaItemTypeRoot) {
//
// None yet
//
}
//
// Validate child item properties
//
else {
//
// Get the driver item context and item info pointer
//
hr = wiauGetDrvItemContext(pWiasContext, (VOID **) &pItemCtx);
REQUIRE_SUCCESS(hr, "drvGetWiaFormatInfo", "wiauGetDrvItemContext failed");
pItemInfo = pItemCtx->pItemInfo;
//
// See if access rights were changed
//
if (wiauPropInPropSpec(nPropSpec, pPropSpec, WIA_IPA_ACCESS_RIGHTS))
{
hr = wiasReadPropLong(pWiasContext, WIA_IPA_ACCESS_RIGHTS, &lRights, NULL, TRUE);
REQUIRE_SUCCESS(hr, "drvValidateItemProperties", "wiasReadPropLong failed");
bReadOnly = (lRights == WIA_ITEM_READ);
hr = m_pDevice->SetItemProt(m_pDeviceInfo, pItemInfo, bReadOnly);
REQUIRE_SUCCESS(hr, "drvValidateItemProperties", "SetItemProt failed");
pItemInfo->bReadOnly = bReadOnly;
}
//
// If tymed property was changed, update format and item size
//
if (wiauPropInPropSpec(nPropSpec, pPropSpec, WIA_IPA_TYMED)) {
//
// Create a property context needed by some WIA Service
// functions used below.
//
WIA_PROPERTY_CONTEXT Context;
hr = wiasCreatePropContext(nPropSpec, (PROPSPEC*)pPropSpec, 0,
NULL, &Context);
REQUIRE_SUCCESS(hr, "drvValidateItemProperties", "wiasCreatePropContext failed");
//
// Use the WIA Service to update the valid values
// for format. It will pull the values from the
// structure returned by drvGetWiaFormatInfo, using the
// new value for tymed.
//
hr = wiasUpdateValidFormat(pWiasContext, &Context, (IWiaMiniDrv*) this);
REQUIRE_SUCCESS(hr, "drvGetWiaFormatInfo", "wiasUpdateValidFormat failed");
//
// Free the property context
//
hr = wiasFreePropContext(&Context);
REQUIRE_SUCCESS(hr, "drvGetWiaFormatInfo", "wiasFreePropContext failed");
//
// The format may have changed, so update the properties
// dependent on format
//
bFormatUpdated = TRUE;
}
//
// If the format was changed, just update the item size
//
if (bFormatUpdated || wiauPropInPropSpec(nPropSpec, pPropSpec, WIA_IPA_FORMAT))
{
//
// Update the affected item properties
//
hr = wiauSetImageItemSize(pWiasContext, pItemInfo->lWidth, pItemInfo->lHeight,
pItemInfo->lDepth, pItemInfo->lSize, pItemInfo->wszExt);
REQUIRE_SUCCESS(hr, "drvGetWiaFormatInfo", "wiauSetImageItemSize failed");
}
}
Cleanup:
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvDeleteItem
*
* Delete an item from the device.
*
* Arguments:
*
* pWiasContext - Indicates the item to delete.
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvDeleteItem(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvDeleteItem");
if (!pWiasContext || !plDevErrVal)
{
wiauDbgError("drvDeleteItem", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
//
// Locals
//
ITEM_CONTEXT *pItemCtx = NULL;
IWiaDrvItem *pDrvItem = NULL;
BSTR bstrFullName = NULL;
hr = wiauGetDrvItemContext(pWiasContext, (VOID **) &pItemCtx, &pDrvItem);
REQUIRE_SUCCESS(hr, "drvDeleteItem", "wiauGetDrvItemContext failed");
hr = m_pDevice->DeleteItem(m_pDeviceInfo, pItemCtx->pItemInfo);
REQUIRE_SUCCESS(hr, "drvDeleteItem", "DeleteItem failed");
//
// Get the item's full name
//
hr = pDrvItem->GetFullItemName(&bstrFullName);
REQUIRE_SUCCESS(hr, "drvDeleteItem", "GetFullItemName failed");
//
// Queue an "item deleted" event
//
hr = wiasQueueEvent(m_bstrDeviceID, &WIA_EVENT_ITEM_DELETED, bstrFullName);
REQUIRE_SUCCESS(hr, "drvDeleteItem", "wiasQueueEvent failed");
Cleanup:
if (bstrFullName)
SysFreeString(bstrFullName);
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvNotifyPnpEvent
*
* Pnp Event received by device manager. This is called when a Pnp event
* is received for this device.
*
* Arguments:
*
*
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvNotifyPnpEvent(
const GUID *pEventGUID,
BSTR bstrDeviceID,
ULONG ulReserved)
{
DBG_FN("CWiaCameraDevice::DrvNotifyPnpEvent");
if (!pEventGUID)
{
wiauDbgError("drvNotifyPnpEvent", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvGetCapabilities
*
* Get supported device commands and events as an array of WIA_DEV_CAPS.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags.
* pcelt - Pointer to returned number of elements in
* returned GUID array.
* ppCapabilities - Pointer to returned GUID array.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvGetCapabilities(
BYTE *pWiasContext,
LONG ulFlags,
LONG *pcelt,
WIA_DEV_CAP_DRV **ppCapabilities,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvGetCapabilites");
if (!pWiasContext)
{
//
// The WIA service may pass in a NULL for the pWiasContext. This is expected
// because there is a case where no item was created at the time the event was fired.
//
}
if (!pcelt || !ppCapabilities || !plDevErrVal)
{
wiauDbgError("drvGetCapabilities", "invalid arguments");
return E_INVALIDARG;
}
*plDevErrVal = 0;
//
// Return values depend on the passed flags. Flags specify whether we should return
// commands, events, or both.
//
if (ulFlags & (WIA_DEVICE_COMMANDS | WIA_DEVICE_EVENTS)) {
//
// Return both events and commands
//
*pcelt = m_lNumCapabilities;
*ppCapabilities = m_pCapabilities;
}
else if (ulFlags & WIA_DEVICE_COMMANDS) {
//
// Return commands only
//
*pcelt = m_lNumSupportedCommands;
*ppCapabilities = &m_pCapabilities[m_lNumSupportedEvents];
}
else if (ulFlags & WIA_DEVICE_EVENTS) {
//
// Return events only
//
*pcelt = m_lNumSupportedEvents;
*ppCapabilities = m_pCapabilities;
}
return S_OK;
}
/**************************************************************************\
* CWiaCameraDevice::drvDeviceCommand
*
* Issue a command to the device.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item.
* lFlags - Operation flags, unused.
* plCommand - Pointer to command GUID.
* ppWiaDrvItem - Optional pointer to returned item, unused.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvDeviceCommand(
BYTE *pWiasContext,
LONG lFlags,
const GUID *plCommand,
IWiaDrvItem **ppWiaDrvItem,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvDeviceCommand");
if (!pWiasContext || !plCommand || !ppWiaDrvItem || !plDevErrVal)
{
wiauDbgError("drvDeviceCommand", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErrVal = 0;
//
// Locals
//
MCAM_ITEM_INFO *pItem = NULL;
//
// Check which command was issued
//
if (*plCommand == WIA_CMD_SYNCHRONIZE) {
//
// SYNCHRONIZE - Re-build the item tree, if the device needs it.
//
if (m_pDeviceInfo->bSyncNeeded)
{
hr = m_pDevice->StopEvents(m_pDeviceInfo);
REQUIRE_SUCCESS(hr, "drvDeviceCommand", "StopEvents failed");
hr = DeleteItemTree(WiaItemTypeDisconnected);
REQUIRE_SUCCESS(hr, "drvDeviceCommand", "DeleteItemTree failed");
hr = m_pDevice->GetDeviceInfo(m_pDeviceInfo, &pItem);
REQUIRE_SUCCESS(hr, "drvDeviceCommand", "GetDeviceInfo failed");
hr = BuildItemTree(pItem);
REQUIRE_SUCCESS(hr, "drvDeviceCommand", "BuildItemTree failed");
}
}
#if DEADCODE
//
// Not implemented yet
//
else if (*plCommand == WIA_CMD_TAKE_PICTURE) {
//
// TAKE_PICTURE - Command the camera to capture a new image.
//
hr = m_pDevice->TakePicture(&pItem);
REQUIRE_SUCCESS(hr, "drvDeviceCommand", "TakePicture failed");
hr = AddObject(pItem);
REQUIRE_SUCCESS(hr, "drvDeviceCommand", "AddObject failed");
hr = LinkToParent(pItem);
REQUIRE_SUCCESS(hr, "drvDeviceCommand", "LinkToParent failed");
}
#endif
else {
wiauDbgWarning("drvDeviceCommand", "Unknown command 0x%08x", *plCommand);
hr = E_NOTIMPL;
goto Cleanup;
}
Cleanup:
return hr;
}
/**************************************************************************\
* CWiaCameraDevice::drvAnalyzeItem
*
* This device does not support image analysis, so return E_NOTIMPL.
*
* Arguments:
*
* pWiasContext - Pointer to the device item to be analyzed.
* lFlags - Operation flags.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvAnalyzeItem(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
DBG_FN("CWiaCameraDevice::drvAnalyzeItem");
if (!pWiasContext || !plDevErrVal)
{
wiauDbgError("drvAnalyzeItem", "invalid arguments");
return E_INVALIDARG;
}
*plDevErrVal = 0;
return E_NOTIMPL;
}
/**************************************************************************\
* CWiaCameraDevice::drvGetDeviceErrorStr
*
* Map a device error value to a string.
*
* Arguments:
*
* lFlags - Operation flags, unused.
* lDevErrVal - Device error value.
* ppszDevErrStr - Pointer to returned error string.
* plDevErrVal - Pointer to the device error value.
*
\**************************************************************************/
HRESULT CWiaCameraDevice::drvGetDeviceErrorStr(
LONG lFlags,
LONG lDevErrVal,
LPOLESTR *ppszDevErrStr,
LONG *plDevErr)
{
DBG_FN("CWiaCameraDevice::drvGetDeviceErrorStr");
if (!ppszDevErrStr || !plDevErr)
{
wiauDbgError("drvGetDeviceErrorStr", "invalid arguments");
return E_INVALIDARG;
}
HRESULT hr = S_OK;
*plDevErr = 0;
//
// Map device errors to a string appropriate for showing to the user
//
switch (lDevErrVal) {
case 0:
*ppszDevErrStr = NULL;
break;
default:
*ppszDevErrStr = NULL;
hr = E_FAIL;
}
return hr;
}
/*******************************************************************************
*
* P R I V A T E M E T H O D S
*
*******************************************************************************/
/**************************************************************************\
* FreeResources
*
* Cleans up all of the resources held by the driver.
*
\**************************************************************************/
HRESULT
CWiaCameraDevice::FreeResources()
{
DBG_FN("CWiaCameraDevice::FreeResources");
HRESULT hr = S_OK;
wiauDbgTrace("FreeResources", "Connected apps is now zero, freeing resources...");
hr = m_pDevice->StopEvents(m_pDeviceInfo);
if (FAILED(hr))
wiauDbgErrorHr(hr, "FreeResources", "StopEvents failed");
// Destroy the driver item tree
hr = DeleteItemTree(WiaItemTypeDisconnected);
if (FAILED(hr))
wiauDbgErrorHr(hr, "FreeResources", "UnlinkItemTree failed");
// Delete allocated arrays
DeleteCapabilitiesArrayContents();
//
// For devices connected to ports that can be shared (e.g. USB),
// close the device
//
if (m_pDeviceInfo && !m_pDeviceInfo->bExclusivePort) {
hr = m_pDevice->Close(m_pDeviceInfo);
if (FAILED(hr))
wiauDbgErrorHr(hr, "FreeResources", "Close failed");
}
// Free the storage for the device ID
if (m_bstrDeviceID) {
SysFreeString(m_bstrDeviceID);
m_bstrDeviceID = NULL;
}
// Free the storage for the root item name
if (m_bstrRootFullItemName) {
SysFreeString(m_bstrRootFullItemName);
m_bstrRootFullItemName = NULL;
}
/*
// Kill notification thread if it exists.
SetNotificationHandle(NULL);
// Close event for syncronization of notifications shutdown.
if (m_hShutdownEvent && (m_hShutdownEvent != INVALID_HANDLE_VALUE)) {
CloseHandle(m_hShutdownEvent);
m_hShutdownEvent = NULL;
}
//
// WIA member destruction
//
// Cleanup the WIA event sink.
if (m_pIWiaEventCallback) {
m_pIWiaEventCallback->Release();
m_pIWiaEventCallback = NULL;
}
*/
return hr;
}
/**************************************************************************\
* DeleteItemTree
*
* Call device manager to unlink and release our reference to
* all items in the driver item tree.
*
* Arguments:
*
*
*
\**************************************************************************/
HRESULT
CWiaCameraDevice::DeleteItemTree(LONG lReason)
{
DBG_FN("CWiaCameraDevice::DeleteItemTree");
HRESULT hr = S_OK;
//
// If no tree, return.
//
if (!m_pRootItem)
goto Cleanup;
//
// Call device manager to unlink the driver item tree.
//
hr = m_pRootItem->UnlinkItemTree(lReason);
REQUIRE_SUCCESS(hr, "DeleteItemTree", "UnlinkItemTree failed");
m_pRootItem->Release();
m_pRootItem = NULL;
Cleanup:
return hr;
}
/**************************************************************************\
* BuildItemTree
*
* The device uses the WIA Service functions to build up a tree of
* device items.
*
* Arguments:
*
*
*
\**************************************************************************/
HRESULT
CWiaCameraDevice::BuildItemTree(MCAM_ITEM_INFO *pItem)
{
DBG_FN("CWiaCameraDevice::BuildItemTree");
HRESULT hr = S_OK;
//
// Locals
//
BSTR bstrRoot = NULL;
ITEM_CONTEXT *pItemCtx = NULL;
MCAM_ITEM_INFO *pCurItem = NULL;
//
// Make sure the item tree doesn't already exist
//
if (m_pRootItem)
{
wiauDbgError("BuildItemTree", "Item tree already exists");
hr = E_FAIL;
goto Cleanup;
}
//
// Create the root item name
//
bstrRoot = SysAllocString(L"Root");
REQUIRE_ALLOC(bstrRoot, hr, "BuildItemTree");
//
// Create the root item
//
hr = wiasCreateDrvItem(WiaItemTypeFolder | WiaItemTypeDevice | WiaItemTypeRoot,
bstrRoot,
m_bstrRootFullItemName,
(IWiaMiniDrv *)this,
sizeof(ITEM_CONTEXT),
(BYTE **) &pItemCtx,
&m_pRootItem);
REQUIRE_SUCCESS(hr, "BuildItemTree", "wiasCreateDrvItem failed");
//
// Initialize item context fields for the root
//
memset(pItemCtx, 0, sizeof(ITEM_CONTEXT));
//
// Create a driver item for each item on the camera
//
pCurItem = pItem;
while (pCurItem) {
hr = AddObject(pCurItem);
REQUIRE_SUCCESS(hr, "BuildItemTree", "AddObject failed");
pCurItem = pCurItem->pNext;
}
//
// Link each item to its parent
//
pCurItem = pItem;
while (pCurItem) {
hr = LinkToParent(pCurItem);
REQUIRE_SUCCESS(hr, "BuildItemTree", "LinkToParent failed");
pCurItem = pCurItem->pNext;
}
Cleanup:
if (bstrRoot)
SysFreeString(bstrRoot);
return hr;
}
/**************************************************************************\
* AddObject
*
* Helper function to add an item to the driver item tree
*
* Arguments:
*
* pItemInfo - Pointer to the item info structure
*
\**************************************************************************/
HRESULT CWiaCameraDevice::AddObject(MCAM_ITEM_INFO *pItemInfo)
{
DBG_FN("CWiaCameraDevice::AddObject");
HRESULT hr = S_OK;
//
// Locals
//
LONG lItemType = 0;
BSTR bstrItemFullName = NULL;
BSTR bstrItemName = NULL;
WCHAR wszTemp[MAX_PATH];
IWiaDrvItem *pItem = NULL;
ITEM_CONTEXT *pItemCtx = NULL;
REQUIRE_ARGS(!pItemInfo, hr, "AddObject");
//
// Create the item's full name
//
hr = ConstructFullName(pItemInfo, wszTemp, sizeof(wszTemp) / sizeof(wszTemp[0]));
REQUIRE_SUCCESS(hr, "AddObject", "ConstructFullName failed");
wiauDbgTrace("AddObject", "Adding item %S", wszTemp);
bstrItemFullName = SysAllocString(wszTemp);
REQUIRE_ALLOC(bstrItemFullName, hr, "AddObject");
bstrItemName = SysAllocString(pItemInfo->pwszName);
REQUIRE_ALLOC(bstrItemName, hr, "AddObject");
//
// Make sure there is no filename extension in the name
//
if (wcschr(bstrItemFullName, L'.'))
{
wiauDbgError("AddObject", "Item names must not contain filename extensions");
hr = E_FAIL;
goto Cleanup;
}
//
// Set the item's type
//
switch (pItemInfo->iType) {
case WiaMCamTypeFolder:
lItemType = ITEMTYPE_FOLDER;
break;
case WiaMCamTypeImage:
lItemType = ITEMTYPE_IMAGE;
break;
case WiaMCamTypeAudio:
lItemType = ITEMTYPE_AUDIO;
break;
case WiaMCamTypeVideo:
lItemType = ITEMTYPE_VIDEO;
break;
default:
lItemType = ITEMTYPE_FILE;
break;
}
//
// See if the item has attachments
//
if (pItemInfo->bHasAttachments)
lItemType |= WiaItemTypeHasAttachments;
//
// Create the driver item
//
hr = wiasCreateDrvItem(lItemType,
bstrItemName,
bstrItemFullName,
(IWiaMiniDrv *)this,
sizeof(ITEM_CONTEXT),
(BYTE **) &pItemCtx,
&pItem);
REQUIRE_SUCCESS(hr, "AddObject", "wiasCreateDrvItem failed");
//
// Fill in the driver item context. Wait until the thumbnail is requested before
// reading it in.
//
memset(pItemCtx, 0, sizeof(ITEM_CONTEXT));
pItemCtx->pItemInfo = pItemInfo;
//
// Put a pointer to the driver item in the item info structure
//
pItemInfo->pDrvItem = pItem;
Cleanup:
if (bstrItemFullName)
SysFreeString(bstrItemFullName);
if (bstrItemName)
SysFreeString(bstrItemName);
return hr;
}
/**************************************************************************\
* ConstructFullName
*
* Helper function for creating the item's full name
*
* Arguments:
*
* pItemInfo - Pointer to the item info structure
* pwszFullName - Pointer to area to construct name
* cchFullNameSize - size (in characters) of buffer provided in pwszFullName
*
\**************************************************************************/
HRESULT CWiaCameraDevice::ConstructFullName(MCAM_ITEM_INFO *pItemInfo,
WCHAR *pwszFullName,
INT cchFullNameSize)
{
DBG_FN("CWiaCameraDevice::ConstructFullName");
HRESULT hr = S_OK;
if (!pItemInfo)
{
wiauDbgError("ConstructFullName", "pItemInfo arg is NULL");
return E_INVALIDARG;
}
if (pItemInfo->pParent)
{
hr = ConstructFullName(pItemInfo->pParent, pwszFullName, cchFullNameSize);
}
else
{
if (lstrlenW(m_bstrRootFullItemName) < cchFullNameSize)
{
lstrcpyW(pwszFullName, m_bstrRootFullItemName);
}
else
{
hr = E_FAIL;
}
}
if (SUCCEEDED(hr) && pItemInfo->pwszName)
{
//
// Verify that buffer is big enough to accommodate both strings + "\" + terminating zero
//
if (lstrlenW(pwszFullName) + lstrlenW(pItemInfo->pwszName) + 2 <= cchFullNameSize)
{
lstrcatW(pwszFullName, L"\\");
lstrcatW(pwszFullName, pItemInfo->pwszName);
}
else
{
hr = E_FAIL; // buffer is not big enough
}
}
return hr;
}
/**************************************************************************\
* LinkToParent
*
* Helper function to link an item to its parent in the item tree
*
* Arguments:
*
* pItemInfo - Pointer to the item info structure
* bQueueEvent - Indicates whether to queue an WIA event
*
\**************************************************************************/
HRESULT CWiaCameraDevice::LinkToParent(MCAM_ITEM_INFO *pItemInfo, BOOL bQueueEvent)
{
DBG_FN("CWiaCameraDevice::LinkToParent");
HRESULT hr = S_OK;
//
// Locals
//
IWiaDrvItem *pParentDrvItem = NULL;
IWiaDrvItem *pItem = NULL;
BSTR bstrItemFullName = NULL;
REQUIRE_ARGS(!pItemInfo, hr, "LinkToParent");
//
// Retrieve the driver item and make sure it's not null
//
pItem = pItemInfo->pDrvItem;
if (!pItem) {
wiauDbgError("LinkToParent", "Driver item pointer is null");
hr = E_FAIL;
goto Cleanup;
}
//
// Find the item's parent driver item object
//
if (pItemInfo->pParent) {
pParentDrvItem = pItemInfo->pParent->pDrvItem;
}
else {
//
// If the parent pointer is null, use the root as the parent
//
pParentDrvItem = m_pRootItem;
}
//
// The driver item should exist for the parent, but just make sure
//
if (!pParentDrvItem) {
wiauDbgError("LinkToParent", "Parent driver item is null");
hr = E_FAIL;
goto Cleanup;
}
//
// Place the item under it's parent
//
hr = pItem->AddItemToFolder(pParentDrvItem);
REQUIRE_SUCCESS(hr, "LinkToParent", "AddItemToFolder failed");
//
// The minidriver doesn't need the driver item pointer any more, so release it.
// The service will still keep a reference until the item is deleted.
//
pItem->Release();
//
// Post an item added event, if requested
//
if (bQueueEvent)
{
hr = pItem->GetFullItemName(&bstrItemFullName);
REQUIRE_SUCCESS(hr, "LinkToParent", "GetFullItemName failed");
hr = wiasQueueEvent(m_bstrDeviceID, &WIA_EVENT_ITEM_CREATED, bstrItemFullName);
REQUIRE_SUCCESS(hr, "LinkToParent", "wiasQueueEvent failed");
}
Cleanup:
if (bstrItemFullName)
SysFreeString(bstrItemFullName);
return hr;
}
/**************************************************************************\
* GetOLESTRResourceString
*
* This helper gets a LPOLESTR from a resource location
*
* Arguments:
*
* lResourceID - Resource ID of the target BSTR value
* ppsz - pointer to a OLESTR value (caller must free this string with CoTaskMemFree)
*
* Return Value:
*
* Status
*
\**************************************************************************/
HRESULT CWiaCameraDevice::GetOLESTRResourceString(LONG lResourceID, LPOLESTR *ppsz)
{
DBG_FN("GetOLESTRResourceString");
if (!ppsz)
{
return E_INVALIDARG;
}
HRESULT hr = S_OK;
TCHAR tszStringValue[255];
if (LoadString(g_hInst, lResourceID, tszStringValue, 255) == 0)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
goto Cleanup;
}
#ifdef UNICODE
//
// just allocate memory and copy string
//
*ppsz = NULL;
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(tszStringValue));
if (*ppsz != NULL)
{
wcscpy(*ppsz, tszStringValue);
}
else
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
#else
WCHAR wszStringValue[255];
//
// convert szStringValue from char* to unsigned short* (ANSI only)
//
if (!MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
tszStringValue,
lstrlenA(tszStringValue)+1,
wszStringValue,
(sizeof(wszStringValue)/sizeof(wszStringValue[0]))))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
goto Cleanup;
}
*ppsz = NULL;
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(wszStringValue));
if (*ppsz != NULL)
{
wcscpy(*ppsz,wszStringValue);
}
else
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
#endif
Cleanup:
return hr;
}
/**************************************************************************\
* BuildCapabilities
*
* This helper initializes the capabilities array
*
* Arguments:
*
* none
*
\**************************************************************************/
HRESULT CWiaCameraDevice::BuildCapabilities()
{
DBG_FN("BuildCapabilities");
HRESULT hr = S_OK;
if (m_pCapabilities != NULL) {
//
// Capabilities have already been initialized,
// so return S_OK.
//
return hr;
}
m_lNumSupportedCommands = 1;
m_lNumSupportedEvents = 3;
m_lNumCapabilities = (m_lNumSupportedCommands + m_lNumSupportedEvents);
m_pCapabilities = new WIA_DEV_CAP_DRV[m_lNumCapabilities];
REQUIRE_ALLOC(m_pCapabilities, hr, "BuildCapabilities");
//
// Initialize EVENTS
//
//
// WIA_EVENT_DEVICE_CONNECTED
//
hr = GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_NAME, &m_pCapabilities[0].wszName);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
hr = GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_DESC, &m_pCapabilities[0].wszDescription);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
m_pCapabilities[0].guid = (GUID*)&WIA_EVENT_DEVICE_CONNECTED;
m_pCapabilities[0].ulFlags = WIA_NOTIFICATION_EVENT;
m_pCapabilities[0].wszIcon = WIA_ICON_DEVICE_CONNECTED;
//
// WIA_EVENT_DEVICE_DISCONNECTED
//
hr = GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_NAME, &m_pCapabilities[1].wszName);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
hr = GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_DESC, &m_pCapabilities[1].wszDescription);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
m_pCapabilities[1].guid = (GUID*)&WIA_EVENT_DEVICE_DISCONNECTED;
m_pCapabilities[1].ulFlags = WIA_NOTIFICATION_EVENT;
m_pCapabilities[1].wszIcon = WIA_ICON_DEVICE_DISCONNECTED;
//
// WIA_EVENT_ITEM_DELETED
//
hr = GetOLESTRResourceString(IDS_EVENT_ITEM_DELETED_NAME, &m_pCapabilities[2].wszName);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
hr = GetOLESTRResourceString(IDS_EVENT_ITEM_DELETED_DESC, &m_pCapabilities[2].wszDescription);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
m_pCapabilities[2].guid = (GUID*)&WIA_EVENT_ITEM_DELETED;
m_pCapabilities[2].ulFlags = WIA_NOTIFICATION_EVENT;
m_pCapabilities[2].wszIcon = WIA_ICON_ITEM_DELETED;
//
// Initialize COMMANDS
//
//
// WIA_CMD_SYNCHRONIZE
//
hr = GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_NAME, &m_pCapabilities[3].wszName);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
hr = GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_DESC, &m_pCapabilities[3].wszDescription);
REQUIRE_SUCCESS(hr, "BuildCapabilities", "GetOLESTRResourceString failed");
m_pCapabilities[3].guid = (GUID*)&WIA_CMD_SYNCHRONIZE;
m_pCapabilities[3].ulFlags = 0;
m_pCapabilities[3].wszIcon = WIA_ICON_SYNCHRONIZE;
Cleanup:
return hr;
}
/**************************************************************************\
* DeleteCapabilitiesArrayContents
*
* This helper deletes the capabilities array
*
* Arguments:
*
* none
*
\**************************************************************************/
HRESULT CWiaCameraDevice::DeleteCapabilitiesArrayContents()
{
DBG_FN("DeleteCapabilitiesArrayContents");
HRESULT hr = S_OK;
if (m_pCapabilities) {
for (LONG i = 0; i < m_lNumCapabilities; i++)
{
CoTaskMemFree(m_pCapabilities[i].wszName);
CoTaskMemFree(m_pCapabilities[i].wszDescription);
}
delete []m_pCapabilities;
m_pCapabilities = NULL;
}
m_lNumSupportedCommands = 0;
m_lNumSupportedEvents = 0;
m_lNumCapabilities = 0;
return hr;
}