diff options
| author | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
|---|---|---|
| committer | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
| commit | 96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch) | |
| tree | ad5f3ede5cbcd6b598677ce41bcf8318471bdd92 /wia/ProdScan/PropMan.cpp | |
| parent | 687b274aa38fd05c8c26e3068932121876d7f745 (diff) | |
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'wia/ProdScan/PropMan.cpp')
| -rw-r--r-- | wia/ProdScan/PropMan.cpp | 1499 |
1 files changed, 1499 insertions, 0 deletions
diff --git a/wia/ProdScan/PropMan.cpp b/wia/ProdScan/PropMan.cpp new file mode 100644 index 00000000..6dc0e86f --- /dev/null +++ b/wia/ProdScan/PropMan.cpp @@ -0,0 +1,1499 @@ +/************************************************************************** +* +* 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; +} |
