Sample Code

Windows Driver Samples/ Windows Image Acquisition (WIA) Driver Samples/ C++/ ProdScan/ PropMan.cpp/

/**************************************************************************
*
*  Copyright � Microsoft Corporation
*
*  File Title:  PropMan.cpp
*
*  Project:     Production Scanner Driver Sample
*
*  Description: Contains the class implementation of the
*               CWIAPropertyManager class that encapsulates
*               WIA property creation for this driver.
*
***************************************************************************/

#include "stdafx.h"

/**************************************************************************\
*
* CWIAPropertyManager constructor
*
\**************************************************************************/

CWIAPropertyManager::CWIAPropertyManager()
{
    return;
}

/**************************************************************************\
*
* CWIAPropertyManager destructor
*
\**************************************************************************/

CWIAPropertyManager::~CWIAPropertyManager()
{
    //
    // Cleanup any items contained in the property list before exiting:
    //
    for (INT i = 0; i < m_List.Size(); i++)
    {
        PWIA_PROPERTY_INFO_DATA pPropertyData = m_List[i];

        if (pPropertyData)
        {
            //
            // Delete contents:
            //
            DeletePropertyData(pPropertyData);

            //
            // Delete container:
            //
            delete pPropertyData;
        }
    }
}


/**************************************************************************\
*
* This function finds the specified property, and removes it
* from the list of properties
*
* Parameters:
*
*    lPropertyID - Property ID of the property to find
*
* Return Value:
*
*    Pointer to property information list, NULL if error
*
\**************************************************************************/

PWIA_PROPERTY_INFO_DATA CWIAPropertyManager::FindProperty(
    LONG lPropertyID)
{
    PWIA_PROPERTY_INFO_DATA pInfo = NULL;

    for (INT i = 0; i< m_List.Size(); i++)
    {
        PWIA_PROPERTY_INFO_DATA pPropertyData = m_List[i];

        if (pPropertyData->pid == (ULONG)lPropertyID)
        {
            pInfo = pPropertyData;
            break;
        }
    }

    return pInfo;
}

/**************************************************************************\
*
* This function deletes the contents of a WIA_PROPERTY_DATA structure
*
* Parameters:
*
*    pInfo - pointer containing the property data
*
* Return Value:
*
*    S_OK or a a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::DeletePropertyData(
    _Inout_ PWIA_PROPERTY_INFO_DATA pInfo)
{
    HRESULT hr = E_INVALIDARG;

    if (pInfo)
    {
        //
        // Delete any allocated lists:
        //
        if (pInfo->wpi.lAccessFlags & WIA_PROP_LIST)
        {
            if (pInfo->pv.vt & VT_I4)
            {
                if (pInfo->wpi.ValidVal.List.pList)
                {
                    LocalFree(pInfo->wpi.ValidVal.List.pList);
                    pInfo->wpi.ValidVal.List.pList = NULL;
                }
            }

            if (pInfo->pv.vt & VT_CLSID)
            {
                if (pInfo->wpi.ValidVal.ListGuid.pList)
                {
                    LocalFree(pInfo->wpi.ValidVal.ListGuid.pList);
                    pInfo->wpi.ValidVal.ListGuid.pList = NULL;
                }
            }
        }

        //
        // Free any allocated BSTRs:
        //

        if (VT_BSTR == pInfo->pv.vt)
        {
            SysFreeString(pInfo->pv.bstrVal);
            pInfo->pv.bstrVal = NULL;
        }

        //
        // Delete any allocated GUIDs:
        //

        if (VT_CLSID == pInfo->pv.vt)
        {
            delete pInfo->pv.puuid;
            pInfo->pv.puuid = NULL;
        }

        hr = S_OK;
    }
    return hr;
}

/**************************************************************************\
*
* This function allocates a WIA_PROPERTY_INFO_DATA strucuture
* and initializes the members.
*
* Parameters:
*
*    none
*
* Return Value:
*
*    Pointer to the new structure
*
\**************************************************************************/

PWIA_PROPERTY_INFO_DATA CWIAPropertyManager::AllocatePropertyData()
{

    PWIA_PROPERTY_INFO_DATA pInfo = NULL;

    pInfo = new WIA_PROPERTY_INFO_DATA;

    if (pInfo)
    {
        //
        // Erase all values in newly allocated property data structure:
        //
        memset(pInfo, 0, sizeof(WIA_PROPERTY_INFO_DATA));

        //
        // Properly initialize the property variant:
        //
        PropVariantInit(&pInfo->pv);
    }

    return pInfo;
}

/**************************************************************************\
*
* This function finds the property specified by lPropertyID and deletes the
* contents of the WIA_PROPERTY_INFO_DATA.
*
* Parameters:
*
*    lPropertyID - Property ID of the property to remove and delete
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::RemovePropertyAndDeleteData(
    LONG lPropertyID)
{

    //
    // Find any existing property with the same ID, and remove it from the list:
    //

    PWIA_PROPERTY_INFO_DATA pInfo = FindProperty(lPropertyID);

    if (pInfo)
    {
        //
        // Find and remove the property info from the list and delete the contents:
        //
        m_List.Delete(m_List.Find(pInfo));
        delete pInfo;
        pInfo = NULL;
    }

    return S_OK;
}

/**************************************************************************\
*
* This function adds a new property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID  - Property ID
*  pszName      - Property NAME
*  lAccessFlags - Property Access Flags
*  lCurrValue   - Current Property Value
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG          lPropertyID,
    _In_ LPOLESTR pszName,
    LONG          lAccessFlags,
    LONG          lCurrValue)
{

    HRESULT hr = E_INVALIDARG;

    if (pszName)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {

            //
            // Populate the data in the structure, and add it to the property list:
            //

            pInfo->pszName          = pszName;
            pInfo->pid              = lPropertyID;
            pInfo->pv.lVal          = lCurrValue;
            pInfo->pv.vt            = VT_I4;
            pInfo->ps.ulKind        = PRSPEC_PROPID;
            pInfo->ps.propid        = pInfo->pid;
            pInfo->wpi.lAccessFlags = lAccessFlags;
            pInfo->wpi.vt           = pInfo->pv.vt;

            m_List.Append(pInfo);

            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }

    return hr;
}

/**************************************************************************\
*
* This function adds a new array-of-LONG single-value property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID      - Property ID
*  pszName          - Property NAME
*  lAccessFlags     - Property Access Flags
*  ulCurrValueItems - Number of VT_I4 items in the current value array
*  pCurrValue       - Current Property Value, as an array of VT_I4 (LONG)
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG           lPropertyID,
    _In_ LPOLESTR  pszName,
    LONG           lAccessFlags,
    ULONG          ulCurrValueItems,
    _In_reads_(ulCurrValueItems)
    LONG           *pCurrValue)
{

    HRESULT hr = E_INVALIDARG;

    if (pszName && pCurrValue && ulCurrValueItems)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {
            //
            // Populate the data in the structure, and add it to the property list
            //
            // For a VT_VECTOR | VT_I4 the correct PROPVARIANT member is: cal (type: CAL)
            //
            pInfo->pszName          = pszName;
            pInfo->pid              = lPropertyID;
            pInfo->pv.cal.cElems    = ulCurrValueItems;
            pInfo->pv.cal.pElems    = pCurrValue;
            pInfo->pv.vt            = VT_I4 | VT_VECTOR;
            pInfo->ps.ulKind        = PRSPEC_PROPID;
            pInfo->ps.propid        = pInfo->pid;
            pInfo->wpi.lAccessFlags = lAccessFlags;
            pInfo->wpi.vt           = pInfo->pv.vt;

            m_List.Append(pInfo);

            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }

    return hr;
}

/**************************************************************************\
*
* This function adds a new VT_VECTOR | VT_UI1 (array-of-BYTEs single-value)
* property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID  - Property ID
*  pszName      - Property NAME
*  lAccessFlags - Property Access Flags
*  pbCurrValue  - Current Property Value (BYTE vector)
*  ulNumItems   - Number of items in the current propery value vector
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG          lPropertyID,
    _In_ LPOLESTR pszName,
    LONG          lAccessFlags,
    _In_reads_(ulNumItems)
    BYTE*         pbCurrValue,
    ULONG         ulNumItems)
{
    HRESULT hr = E_INVALIDARG;

    if (pszName)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {
            //
            // Populate the data in the structure, and add it to the property list
            //
            // Note: for a VT_VECTOR | VT_UI1 the correct PROPVARIANT member is: caub (type: CAUB)
            //
            // From MSDN:
            //
            // "If the type indicator is combined with VT_VECTOR by using an OR operator, the value is one of the counted array values.
            // This creates a DWORD count of elements, followed by a pointer to the specified repetitions of the value.
            // For example, a type indicator of VT_LPSTR | VT_VECTOR has a DWORD element count, followed by a pointer to an array of LPSTR elements.
            // VT_VECTOR can be combined by an OR operator with the following types: VT_I1, VT_UI1, VT_I2, VT_UI2, VT_BOOL, VT_I4, VT_UI4, VT_R4,
            // VT_R8, VT_ERROR, VT_I8, VT_UI8, VT_CY, VT_DATE, VT_FILETIME, VT_CLSID, VT_CF, VT_BSTR, VT_LPSTR, VT_LPWSTR, and VT_VARIANT".
            //
            pInfo->pszName          = pszName;
            pInfo->pid              = lPropertyID;
            pInfo->pv.caub.cElems   = ulNumItems;
            pInfo->pv.caub.pElems   = pbCurrValue;
            pInfo->pv.vt            = VT_UI1 | VT_VECTOR;
            pInfo->ps.ulKind        = PRSPEC_PROPID;
            pInfo->ps.propid        = pInfo->pid;
            pInfo->wpi.lAccessFlags = lAccessFlags;
            pInfo->wpi.vt           = pInfo->pv.vt;

            m_List.Append(pInfo);
            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }
    return hr;
}

/**************************************************************************\
*
* This function adds a new property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID  - Property ID
*  pszName      - Property NAME
*  lAccessFlags - Property Access Flags
*  lCurrValue   - Current Property Value
*  lValidBits   - Valid bit values
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG lPropertyID,
    _In_ LPOLESTR pszName,
    LONG lAccessFlags,
    LONG lCurrValue,
    LONG lValidBits)
{

    HRESULT hr = E_INVALIDARG;
    if (pszName)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // when a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // allocate a property info structure
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {

            //
            // populate the data in the structure, and add it to the property list
            //

            pInfo->pszName                     = pszName;
            pInfo->pid                         = lPropertyID;
            pInfo->pv.lVal                     = lCurrValue;
            pInfo->pv.vt                       = VT_I4;
            pInfo->ps.ulKind                   = PRSPEC_PROPID;
            pInfo->ps.propid                   = pInfo->pid;
            pInfo->wpi.lAccessFlags            = lAccessFlags;
            pInfo->wpi.vt                      = pInfo->pv.vt;
            pInfo->wpi.ValidVal.Flag.Nom       = lCurrValue;
            pInfo->wpi.ValidVal.Flag.ValidBits = lValidBits;
            m_List.Append(pInfo);
            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }
    return hr;
}

/**************************************************************************\
*
* This function adds a new property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID  - Property ID
*  pszName      - Property NAME
*  lAccessFlags - Property Access Flags
*  lCurrValue   - Current Property Value
*  lNomValue    - Property Nominal Value
*  lMinValue    - Property Minimum Value
*  lMaxValue    - Property Maximum Value
*  lInc         - Property Increment Value
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG          lPropertyID,
    _In_ LPOLESTR pszName,
    LONG          lAccessFlags,
    LONG          lCurrValue,
    LONG          lNomValue,
    LONG          lMinValue,
    LONG          lMaxValue,
    LONG          lInc)
{
    HRESULT hr = E_INVALIDARG;

    if (pszName &&
       (lMinValue  <=  lMaxValue) &&
       (lNomValue  >= lMinValue) &&
       (lNomValue  <= lMaxValue) &&
       (lCurrValue >= lMinValue) &&
       (lCurrValue <= lMaxValue))
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {
            //
            // Populate the data in the structure, and add it to the property list:
            //

            pInfo->pszName                = pszName;
            pInfo->pid                    = lPropertyID;
            pInfo->pv.lVal                = lCurrValue;
            pInfo->pv.vt                  = VT_I4;
            pInfo->ps.ulKind              = PRSPEC_PROPID;
            pInfo->ps.propid              = pInfo->pid;
            pInfo->wpi.lAccessFlags       = lAccessFlags;
            pInfo->wpi.vt                 = pInfo->pv.vt;
            pInfo->wpi.ValidVal.Range.Inc = lInc;
            pInfo->wpi.ValidVal.Range.Min = lMinValue;
            pInfo->wpi.ValidVal.Range.Max = lMaxValue;
            pInfo->wpi.ValidVal.Range.Nom = lNomValue;

            m_List.Append(pInfo);
            hr = S_OK;
        }
        else
        {
            hr = E_INVALIDARG;
        }
    }

    return hr;
}

/**************************************************************************\
*
* This function adds a new property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID  - Property ID
*  pszName      - Property NAME
*  lAccessFlags - Property Access Flags
*  lCurrValue   - Current Property Value
*  lNomValue    - Property Nominal Value
*  pValueList   - List of Valid Values
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG                           lPropertyID,
    _In_ LPOLESTR                  pszName,
    LONG                           lAccessFlags,
    LONG                           lCurrValue,
    LONG                           lNomValue,
    _In_ CBasicDynamicArray<LONG>* pValueList)
{

    HRESULT hr = E_INVALIDARG;

    if (pszName && pValueList && pValueList->Size())
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;
        LONG *pLongList = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        LONG lNumValues = (LONG)pValueList->Size();
        if (lNumValues)
        {
            pLongList = (LONG*)LocalAlloc(LPTR, (sizeof(LONG) * lNumValues));
            if (pLongList)
            {
                for(INT iIndex = 0; iIndex < lNumValues; iIndex++)
                {
                    pLongList[iIndex] = ((*pValueList)[iIndex]);
                }
                hr = S_OK;
            }
            else
            {
                hr = E_OUTOFMEMORY;
            }

            if (SUCCEEDED(hr))
            {
                //
                // Allocate a property info structure:
                //

                pInfo = AllocatePropertyData();
                if (pInfo)
                {

                    //
                    // Populate the data in the structure, and add it to the property list:
                    //

                    pInfo->pszName                    = pszName;
                    pInfo->pid                        = lPropertyID;
                    pInfo->pv.lVal                    = lCurrValue;
                    pInfo->pv.vt                      = VT_I4;
                    pInfo->ps.ulKind                  = PRSPEC_PROPID;
                    pInfo->ps.propid                  = pInfo->pid;
                    pInfo->wpi.lAccessFlags           = lAccessFlags;
                    pInfo->wpi.vt                     = pInfo->pv.vt;
                    pInfo->wpi.ValidVal.List.pList    = (BYTE*)pLongList;
                    pInfo->wpi.ValidVal.List.Nom      = lNomValue;
                    pInfo->wpi.ValidVal.List.cNumList = lNumValues;

                    m_List.Append(pInfo);
                    hr = S_OK;
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                }
            }
        }
        else
        {
            hr = E_INVALIDARG;
        }

        if (FAILED(hr))
        {
            if (pLongList)
            {
                LocalFree(pLongList);
                pLongList = NULL;
            }
        }
    }
    return hr;
}

/**************************************************************************\
*
* This function adds a new VT_UI4 single value property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID  - Property ID
*  pszName      - Property NAME
*  lAccessFlags - Property Access Flags
*  ulCurrValue  - Current Property Value
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddPropertyUL(
    LONG           lPropertyID,
    _In_ LPOLESTR  pszName,
    LONG           lAccessFlags,
    ULONG          ulCurrValue)
{

    HRESULT hr = E_INVALIDARG;

    if (pszName)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {

            //
            // Populate the data in the structure, and add it to the property list:
            //

            pInfo->pszName          = pszName;
            pInfo->pid              = lPropertyID;
            pInfo->pv.lVal          = ulCurrValue;
            pInfo->pv.vt            = VT_UI4;
            pInfo->ps.ulKind        = PRSPEC_PROPID;
            pInfo->ps.propid        = pInfo->pid;
            pInfo->wpi.lAccessFlags = lAccessFlags;
            pInfo->wpi.vt           = pInfo->pv.vt;

            m_List.Append(pInfo);

            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }

    return hr;
}

/**************************************************************************\
*
* This function adds a new VT_UI4 range property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID  - Property ID
*  pszName      - Property NAME
*  lAccessFlags - Property Access Flags
*  ulCurrValue  - Current Property Value
*  ulNomValue   - Property Nominal Value
*  ulMinValue   - Property Minimum Value
*  ulMaxValue   - Property Maximum Value
*  ulInc        - Property Increment Value
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddPropertyUL(
    LONG          lPropertyID,
    _In_ LPOLESTR pszName,
    LONG          lAccessFlags,
    ULONG         ulCurrValue,
    ULONG         ulNomValue,
    ULONG         ulMinValue,
    ULONG         ulMaxValue,
    ULONG         ulInc)
{
    HRESULT hr = E_INVALIDARG;

    if (pszName &&
       (ulMinValue  <=  ulMaxValue) &&
       (ulNomValue  >= ulMinValue) &&
       (ulNomValue  <= ulMaxValue) &&
       (ulCurrValue >= ulMinValue) &&
       (ulCurrValue <= ulMaxValue))
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {
            //
            // Populate the data in the structure, and add it to the property list:
            //

            pInfo->pszName                = pszName;
            pInfo->pid                    = lPropertyID;
            pInfo->pv.lVal                = ulCurrValue;
            pInfo->pv.vt                  = VT_UI4;
            pInfo->ps.ulKind              = PRSPEC_PROPID;
            pInfo->ps.propid              = pInfo->pid;
            pInfo->wpi.lAccessFlags       = lAccessFlags;
            pInfo->wpi.vt                 = pInfo->pv.vt;
            pInfo->wpi.ValidVal.Range.Inc = ulInc;
            pInfo->wpi.ValidVal.Range.Min = ulMinValue;
            pInfo->wpi.ValidVal.Range.Max = ulMaxValue;
            pInfo->wpi.ValidVal.Range.Nom = ulNomValue;

            m_List.Append(pInfo);
            hr = S_OK;
        }
        else
        {
            hr = E_INVALIDARG;
        }
    }

    return hr;
}

/**************************************************************************\
*
* This function adds a new property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID   - Property ID
*  pszName       - Property NAME
*  lAccessFlags  - Property Access Flags
*  bstrCurrValue - Current Property Value
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG          lPropertyID,
    _In_ LPOLESTR pszName,
    LONG          lAccessFlags,
    _In_ BSTR     bstrCurrValue)
{
    HRESULT hr = E_INVALIDARG;

    if (pszName && bstrCurrValue)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {
            //
            // Populate the data in the structure, and add it to the property list:
            //

            pInfo->pszName          = pszName;
            pInfo->pid              = lPropertyID;
            pInfo->pv.bstrVal       = SysAllocString(bstrCurrValue);
            pInfo->pv.vt            = VT_BSTR;
            pInfo->ps.ulKind        = PRSPEC_PROPID;
            pInfo->ps.propid        = pInfo->pid;
            pInfo->wpi.lAccessFlags = lAccessFlags;
            pInfo->wpi.vt           = pInfo->pv.vt;

            m_List.Append(pInfo);
            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }
    return hr;
}

/**************************************************************************\
*
* This function adds a new array-of-BSTR single-value property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID      - Property ID
*  pszName          - Property NAME
*  lAccessFlags     - Property Access Flags
*  ulCurrValueItems - Number of VT_BSTR items in the current value array
*  pCurrValue       - Current Property Value, as an array of VT_BSTR
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG           lPropertyID,
    _In_ LPOLESTR  pszName,
    LONG           lAccessFlags,
    ULONG          ulCurrValueItems,
    _In_reads_(ulCurrValueItems)
    BSTR           *pCurrValue)
{

    HRESULT hr = E_INVALIDARG;

    if (pszName && pCurrValue && ulCurrValueItems)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate a property info structure:
        //

        pInfo = AllocatePropertyData();
        if (pInfo)
        {
            //
            // Populate the data in the structure, and add it to the property list
            //
            // For a VT_VECTOR | VT_BSTR the correct PROPVARIANT member is: cabstr (type: CABSTR)
            //
            pInfo->pszName          = pszName;
            pInfo->pid              = lPropertyID;
            pInfo->pv.cabstr.cElems = ulCurrValueItems;
            pInfo->pv.cabstr.pElems = pCurrValue;
            pInfo->pv.vt            = VT_VECTOR | VT_BSTR;
            pInfo->ps.ulKind        = PRSPEC_PROPID;
            pInfo->ps.propid        = pInfo->pid;
            pInfo->wpi.lAccessFlags = lAccessFlags;
            pInfo->wpi.vt           = pInfo->pv.vt;

            m_List.Append(pInfo);

            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }

    return hr;
}

/**************************************************************************\
*
* This function adds a new property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID   - Property ID
*  pszName       - Property NAME
*  lAccessFlags  - Property Access Flags
*  guidCurrValue - Current Property Value
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG          lPropertyID,
    _In_ LPOLESTR pszName,
    LONG          lAccessFlags,
    GUID          guidCurrValue)
{
    HRESULT hr = E_INVALIDARG;

    if (pszName)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        //
        // Allocate memory for a new GUID value and copy the data to it.
        // This memory is going to be freed when DeletePropertyData will
        // be called for this VT_CLSID property:
        //
#pragma prefast(suppress:__WARNING_MEMORY_LEAK, "pguid is not leaked")
        GUID *pguid = new GUID;
        if (pguid)
        {
            memcpy(pguid, &guidCurrValue, sizeof(GUID));
            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }

        if (SUCCEEDED(hr))
        {
            //
            // Allocate a property info structure:
            //

            pInfo = AllocatePropertyData();
            if (pInfo)
            {
                //
                // Populate the data in the structure, and add it to the property list:
                //

                pInfo->pszName                = pszName;
                pInfo->pid                    = lPropertyID;
                pInfo->pv.puuid               = pguid;
                pInfo->pv.vt                  = VT_CLSID;
                pInfo->ps.ulKind              = PRSPEC_PROPID;
                pInfo->ps.propid              = pInfo->pid;
                pInfo->wpi.lAccessFlags       = lAccessFlags;
                pInfo->wpi.vt                 = pInfo->pv.vt;

                m_List.Append(pInfo);
                hr = S_OK;
            }
            else
            {
                hr = E_OUTOFMEMORY;
            }
        }
    }

    return hr;
}

/**************************************************************************\
*
* This function adds a new property to the property list.
*
* If a property exists with the same property ID:
*
* 1. The old property is removed from the list, and the contents  destroyed
* 2. The new property is added to the list.
*
* Parameters:
*
*  lPropertyID   - Property ID
*  pszName       - Property NAME
*  lAccessFlags  - Property Access Flags
*  guidCurrValue - Current Property Value
*  guidNomValue  - Property Nominal Value
*  pValueList    - List of Valid Values
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::AddProperty(
    LONG                           lPropertyID,
    _In_ LPOLESTR                  pszName,
    LONG                           lAccessFlags,
    GUID                           guidCurrValue,
    GUID                           guidNomValue,
    _In_ CBasicDynamicArray<GUID>* pValueList)
{

    HRESULT hr = E_INVALIDARG;

    if (pszName && pValueList)
    {
        PWIA_PROPERTY_INFO_DATA pInfo = NULL;
        GUID *pguid = NULL;
        GUID *pguidList = NULL;

        //
        // When a property is being added, always remove any existing property that has the same
        // property ID. Any call to AddProperty() means that the property being added should be
        // treated as the latest.
        //

        RemovePropertyAndDeleteData(lPropertyID);

        LONG lNumValues = (LONG)pValueList->Size();
        if (lNumValues)
        {
            pguidList = (GUID*)LocalAlloc(LPTR,(sizeof(GUID) * lNumValues));
            if (pguidList)
            {
                for (INT iIndex = 0; iIndex < lNumValues; iIndex++)
                {
                    pguidList[iIndex] = ((*pValueList)[iIndex]);
                }

                hr = S_OK;

                if (SUCCEEDED(hr))
                {
#pragma prefast(suppress:__WARNING_ALIASED_MEMORY_LEAK, "pguid is not leaked")
                    pguid = new GUID;
                    if (pguid)
                    {
                        *pguid = guidCurrValue;
                        hr = S_OK;
                    }
                    else
                    {
                        hr = E_OUTOFMEMORY;
                    }
                }
            }

            if (SUCCEEDED(hr))
            {
                //
                // Allocate a property info structure:
                //

                pInfo = AllocatePropertyData();
                if (pInfo)
                {

                    //
                    // Populate the data in the structure, and add it to the property list:
                    //

                    pInfo->pszName                        = pszName;
                    pInfo->pid                            = lPropertyID;
                    pInfo->pv.puuid                       = pguid;
                    pInfo->pv.vt                          = VT_CLSID;
                    pInfo->ps.ulKind                      = PRSPEC_PROPID;
                    pInfo->ps.propid                      = pInfo->pid;
                    pInfo->wpi.lAccessFlags               = lAccessFlags;
                    pInfo->wpi.vt                         = pInfo->pv.vt;
                    pInfo->wpi.ValidVal.ListGuid.pList    = pguidList;
                    pInfo->wpi.ValidVal.ListGuid.Nom      = guidNomValue;
                    pInfo->wpi.ValidVal.ListGuid.cNumList = lNumValues;

                    m_List.Append(pInfo);
                    hr = S_OK;
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                }
            }
            else
            {
                hr = E_OUTOFMEMORY;
            }
        }
        else
        {
            hr = E_INVALIDARG;
        }

        if (FAILED(hr))
        {
            //
            // Free memory any allocated memory if failure occurs:
            //

            if (pguidList)
            {
                LocalFree(pguidList);
                pguidList = NULL;
            }

            if (pguid)
            {
                delete pguid;
                pguid = NULL;
            }
        }
    }
    return hr;
}

/**************************************************************************\
*
* This function removes a property from the property list.
*
* Parameters:
*
*  lPropertyID - Property ID
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::RemoveProperty(
    LONG lPropertyID)
{
    return RemovePropertyAndDeleteData(lPropertyID);
}

/**************************************************************************\
*
* This function uses WIA helper functions to upload the properties
* to the Application Item Tree item created by the WIA service.
*
* Parameters:
*
*  pWiasContext - WIA Context provided by the WIA service
*
* Return Value:
*
*    S_OK or a standard COM error code
*
\**************************************************************************/

HRESULT CWIAPropertyManager::SetItemProperties(
    _Inout_ BYTE* pWiasContext)
{
    HRESULT hr = E_INVALIDARG;

    if (pWiasContext)
    {
        hr = S_OK;

        //
        // Get current number of properties in the list:
        //

        LONG lNumProps = m_List.Size();
        if (lNumProps > 0)
        {
            LONG lIndex = 0;
            LPOLESTR *pszName = NULL;
            PROPID *ppid = NULL;
            PROPVARIANT *ppv = NULL;
            PROPSPEC *pps = NULL;
            WIA_PROPERTY_INFO *pwpi = NULL;

            //
            // Allocate arrays of structures needed to contain the property data:
            //

            #pragma prefast(suppress:__WARNING_MEMORY_LEAK_EXCEPTION, "When using a new operator that throws this can leak:")
            pszName = new LPOLESTR[lNumProps];
            #pragma prefast(suppress:__WARNING_MEMORY_LEAK_EXCEPTION, "When using a new operator that throws this can leak:")
            ppid    = new PROPID[lNumProps];
            #pragma prefast(suppress:__WARNING_MEMORY_LEAK_EXCEPTION, "When using a new operator that throws this can leak:")
            ppv     = new PROPVARIANT[lNumProps];
            #pragma prefast(suppress:__WARNING_MEMORY_LEAK_EXCEPTION, "When using a new operator that throws this can leak:")
            pps     = new PROPSPEC[lNumProps];
            #pragma prefast(suppress:__WARNING_MEMORY_LEAK_EXCEPTION, "When using a new operator that throws this can leak:")
            pwpi    = new WIA_PROPERTY_INFO[lNumProps];

            if (pszName && ppid && ppv && pps && pwpi)
            {
                //
                // Copy the property data into the proper structures:
                //
                for(INT i = 0; i < lNumProps; i++)
                {
                    PWIA_PROPERTY_INFO_DATA pPropertyData = m_List[i];
                    if (pPropertyData)
                    {
                        pszName[lIndex] = pPropertyData->pszName;
                        ppid[lIndex] = pPropertyData->pid;
                        memcpy(&ppv[lIndex], &pPropertyData->pv, sizeof(PROPVARIANT));
                        memcpy(&pps[lIndex], &pPropertyData->ps, sizeof(PROPSPEC));
                        memcpy(&pwpi[lIndex], &pPropertyData->wpi, sizeof(WIA_PROPERTY_INFO));
                        lIndex++;
                    }
                }

                //
                // Send the property names to the WIA service:
                //
                #pragma prefast(suppress:__WARNING_USING_UNINIT_VAR, "ppid, *ppid, pszName and *pszName are initialized above"
                hr = wiasSetItemPropNames(pWiasContext, lNumProps, ppid, pszName);
                if (SUCCEEDED(hr))
                {
                    //
                    // Send the property values to the WIA service:
                    //
                    #pragma prefast(suppress:__WARNING_USING_UNINIT_VAR, "pps and *pps are initialized above"
                    hr = wiasWriteMultiple(pWiasContext, lNumProps, pps, ppv);
                    if (SUCCEEDED(hr))
                    {
                        //
                        // Send the property valid values to the WIA service:
                        //
                        #pragma prefast(suppress:__WARNING_USING_UNINIT_VAR, "pwpi and *pvpi are initialized above"
                        hr = wiasSetItemPropAttribs(pWiasContext, lNumProps, pps, pwpi);
                        if (FAILED(hr))
                        {
                            WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties, wiasSetItemPropAttribs failed"));
                        }
                    }
                    else
                    {
                        WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties, wiasWriteMultiple failed"));
                    }
                }
                else
                {
                    WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties, wiasSetItemPropNames failed"));
                }
            }
            else
            {
                WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties, failed to allocate memory for property arrays"));
                hr = E_OUTOFMEMORY;
            }

            //
            // Always delete any temporary memory allocated before exiting the function.
            // The WIA service makes a copy of the information during the "wias" helper calls.
            //

            if (pszName)
            {
                delete [] pszName;
                pszName = NULL;
            }

            if (ppid)
            {
                delete [] ppid;
                ppid = NULL;
            }

            if (ppv)
            {
                delete [] ppv;
                ppid = NULL;
            }

            if (pps)
            {
                delete [] pps;
                ppid = NULL;
            }

            if (pwpi)
            {
                delete [] pwpi;
                ppid = NULL;
            }
        }
    }

    return hr;
}

Our Services

  • What our customers say about us?

© 2011-2024 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS