summaryrefslogtreecommitdiff
path: root/wia/ProdScan/InitProp.cpp
diff options
context:
space:
mode:
authorkarlf <[email protected]>2016-08-11 13:28:13 -0700
committerkarlf <[email protected]>2016-08-11 13:28:13 -0700
commit96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch)
treead5f3ede5cbcd6b598677ce41bcf8318471bdd92 /wia/ProdScan/InitProp.cpp
parent687b274aa38fd05c8c26e3068932121876d7f745 (diff)
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'wia/ProdScan/InitProp.cpp')
-rw-r--r--wia/ProdScan/InitProp.cpp3134
1 files changed, 3134 insertions, 0 deletions
diff --git a/wia/ProdScan/InitProp.cpp b/wia/ProdScan/InitProp.cpp
new file mode 100644
index 00000000..0254112d
--- /dev/null
+++ b/wia/ProdScan/InitProp.cpp
@@ -0,0 +1,3134 @@
+/**************************************************************************
+*
+* Copyright � Microsoft Corporation
+*
+* File Name: InitProp.cpp
+*
+* Description: This file contains code for WIA property initialization
+* for the Production Scanner Driver Sample
+*
+***************************************************************************/
+
+#include "stdafx.h"
+
+/**************************************************************************\
+*
+* Initializes the Root item properties
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeRootItemProperties(
+ _In_ BYTE* pWiasContext)
+{
+ HRESULT hr = S_OK;
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // Validate input:
+ //
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "Invalid parameter, hr = 0x%08X", hr));
+ }
+
+ //
+ // Initialize Root item properties:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CWIAPropertyManager PropertyManager;
+
+ //
+ // WIA_IPA_ITEM_CATEGORY:
+ //
+ GUID guidItemCategory = WIA_CATEGORY_ROOT;
+ hr = PropertyManager.AddProperty(WIA_IPA_ITEM_CATEGORY, WIA_IPA_ITEM_CATEGORY_STR, RN, guidItemCategory);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_ITEM_CATEGORY, hr = 0x%08X", hr));
+ }
+
+ //
+ // WIA_IPA_ACCESS_RIGHTS
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lAccessRights = WIA_ITEM_READ;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_ACCESS_RIGHTS, WIA_IPA_ACCESS_RIGHTS_STR, RF, lAccessRights, lAccessRights);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_ACCESS_RIGHTS, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_DPS_DOCUMENT_HANDLING_CAPABILITIES and default WIA_DPS_DOCUMENT_HANDLING_STATUS:
+ //
+
+ LONG lDocumentHandlingCapabilities = AUTO_SOURCE | FLAT | FEED | DUP | IMPRINTER | ENDORSER |
+ BARCODE_READER | PATCH_CODE_READER | MICR_READER;
+
+ LONG lDocumentHandlingStatus = FLAT_READY | FEED_READY | DUP_READY | IMPRINTER_READY | ENDORSER_READY |
+ BARCODE_READER_READY | PATCH_CODE_READER_READY | MICR_READER_READY;
+
+ LONG lValidDocumentHandlingStatus = FLAT_COVER_UP | FLAT_READY | FEED_READY | DUP_READY | IMPRINTER_READY |
+ ENDORSER_READY | BARCODE_READER_READY | PATCH_CODE_READER_READY | MICR_READER_READY |
+ PAPER_JAM | PATH_COVER_UP | MULTIPLE_FEED | DEVICE_ATTENTION | LAMP_ERR;
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_DPS_DOCUMENT_HANDLING_CAPABILITIES,
+ WIA_DPS_DOCUMENT_HANDLING_CAPABILITIES_STR , RN, lDocumentHandlingCapabilities);
+
+ if(FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_DPS_DOCUMENT_HANDLING_CAPABILITIES, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_DPS_DOCUMENT_HANDLING_STATUS:
+ //
+ if (SUCCEEDED(hr))
+ {
+ //
+ // Initialize with default ready flag values:
+ //
+ hr = PropertyManager.AddProperty(WIA_DPS_DOCUMENT_HANDLING_STATUS,
+ WIA_DPS_DOCUMENT_HANDLING_STATUS_STR, RN, lDocumentHandlingStatus, lValidDocumentHandlingStatus);
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_DPS_DOCUMENT_HANDLING_STATUS, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_DPA_CONNECT_STATUS
+ //
+ // The sample device is always available:
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lDeviceConnected = 1;
+ hr = PropertyManager.AddProperty(WIA_DPA_CONNECT_STATUS, WIA_DPA_CONNECT_STATUS_STR, RN, lDeviceConnected);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_DPA_CONNECT_STATUS, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_DPS_SCAN_AVAILABLE_ITEM:
+ //
+ if (SUCCEEDED(hr))
+ {
+ //
+ // If the global (per driver instance) m_bstrScanAvailableItem is not yet initialized
+ // initialize it now to an empty string. Note that because we use here m_bstrScanAvailableItem
+ // to initialize the property we do not need to execute UpdateScanAvailableItemProperty:
+ //
+ if (!m_bstrScanAvailableItem)
+ {
+ hr = UpdateScanAvailableItemName(NULL);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize the scan available item name, hr = 0x%08X", hr));
+ }
+ }
+ else
+ {
+ WIAS_TRACE((g_hInst, "Scan available from %ws", m_bstrScanAvailableItem));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ #pragma prefast(suppress:__WARNING_INVALID_PARAM_VALUE_1, "m_bstrScanAvailableItem is allocated to an empty string by the UpdateScanAvailableItemName call above"
+ hr = PropertyManager.AddProperty(WIA_DPS_SCAN_AVAILABLE_ITEM, WIA_DPS_SCAN_AVAILABLE_ITEM_STR, RN, m_bstrScanAvailableItem);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_DPS_SCAN_AVAILABLE_ITEM, hr = 0x%08X", hr));
+ }
+ }
+ }
+
+ //
+ // Set the properties:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA root item properties, hr = 0x%08X", hr));
+ }
+ }
+ else
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_ITEM_CATEGORY, hr = 0x%08X", hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Wrapper method to initializes the properties for the child items this
+* sample driver creates.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+* nDocumentHandlingSelect - a WIA_DPS_DOCUMENT_HANDLING_SELECT value (such
+* as FLAT or FEED (defined in wiadef.h) identifying
+* the item being initialized
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeChildItemProperties(
+ _In_ BYTE* pWiasContext,
+ UINT nDocumentHandlingSelect)
+
+{
+ HRESULT hr = S_OK;
+ CWIAPropertyManager PropertyManager;
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // No need to validate parameters of trace failures here, the called functions
+ // do the validation and output full error traces:
+ //
+ hr = InitializeCommonChildProperties(pWiasContext, nDocumentHandlingSelect);
+ if (SUCCEEDED(hr))
+ {
+ if ((FLAT == nDocumentHandlingSelect) || (FEEDER == nDocumentHandlingSelect))
+ {
+ hr = InitializeFlatbedFeederProperties(pWiasContext, nDocumentHandlingSelect);
+ if (SUCCEEDED(hr) && (FEEDER == nDocumentHandlingSelect))
+ {
+ hr = InitializeFeederSpecificProperties(pWiasContext);
+ }
+ }
+ else if ((IMPRINTER == nDocumentHandlingSelect) || (ENDORSER == nDocumentHandlingSelect))
+ {
+ hr = InitializeImprinterEndorserProperties(pWiasContext, nDocumentHandlingSelect);
+ }
+ else if (BARCODE_READER == nDocumentHandlingSelect)
+ {
+ hr = InitializeBarcodeReaderProperties(pWiasContext);
+ }
+ else if (PATCH_CODE_READER == nDocumentHandlingSelect)
+ {
+ hr = InitializePatchCodeReaderProperties(pWiasContext);
+ }
+ else if (MICR_READER == nDocumentHandlingSelect)
+ {
+ hr = InitializeMicrReaderProperties(pWiasContext);
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes common child item properties (properties common to all
+* data source items this driver creates: Flatbed, Feeder, Auto, Imprinter, etc.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+* nDocumentHandlingSelect - a WIA_DPS_DOCUMENT_HANDLING_SELECT value (such
+* as FLAT or FEED (defined in wiadef.h) identifying
+* the item being initialized
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeCommonChildProperties(
+ _In_ BYTE* pWiasContext,
+ UINT nDocumentHandlingSelect)
+
+{
+ HRESULT hr = S_OK;
+
+ CWIAPropertyManager PropertyManager;
+
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializeCommonChildProperties, invalid item context parameter, hr = 0x%08X", hr));
+ }
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // WIA_IPA_ITEM_CATEGORY
+ //
+ if (SUCCEEDED(hr))
+ {
+ GUID guidItemCategory = WIA_CATEGORY_FLATBED;
+
+ switch (nDocumentHandlingSelect)
+ {
+ case FLAT:
+ guidItemCategory = WIA_CATEGORY_FLATBED;
+ break;
+
+ case FEED:
+ guidItemCategory = WIA_CATEGORY_FEEDER;
+ break;
+
+ case AUTO_SOURCE:
+ guidItemCategory = WIA_CATEGORY_AUTO;
+ break;
+
+ case IMPRINTER:
+ guidItemCategory = WIA_CATEGORY_IMPRINTER;
+ break;
+
+ case ENDORSER:
+ guidItemCategory = WIA_CATEGORY_ENDORSER;
+ break;
+
+ case BARCODE_READER:
+ guidItemCategory = WIA_CATEGORY_BARCODE_READER;
+ break;
+
+ case PATCH_CODE_READER:
+ guidItemCategory = WIA_CATEGORY_PATCH_CODE_READER;
+ break;
+
+ case MICR_READER:
+ guidItemCategory = WIA_CATEGORY_MICR_READER;
+ break;
+
+ default:
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializeCommonChildProperties, invalid item (%u) parameter, hr = 0x%08X",
+ nDocumentHandlingSelect, hr));
+ }
+
+ hr = PropertyManager.AddProperty(WIA_IPA_ITEM_CATEGORY, WIA_IPA_ITEM_CATEGORY_STR, RN, guidItemCategory);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_ITEM_CATEGORY for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_ACCESS_RIGHTS
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lAccessRights = WIA_ITEM_READ;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_ACCESS_RIGHTS, WIA_IPA_ACCESS_RIGHTS_STR, RF, lAccessRights, lAccessRights);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_ACCESS_RIGHTS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_FORMAT
+ //
+ // For image transfers, this sample driver supports the DIB (mandatory default), EXIF and Raw image file formats.
+ //
+ // The sample imprinter and endorser items support the CSV (mandatory default) and TXT for text transfers and
+ // DIB (mandatory default) for graphics transfers. Default data transfer mode is text (required).
+ //
+ // The sample barcode, patch code and MICR reader items support the required XML and Raw metadata transfers.
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<GUID> guidFormatArray;
+
+ if ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect) ||
+ (AUTO_SOURCE == nDocumentHandlingSelect))
+ {
+ guidFormatArray.Append(WiaImgFmt_BMP);
+ guidFormatArray.Append(WiaImgFmt_EXIF);
+ guidFormatArray.Append(WiaImgFmt_RAW);
+ }
+ else if ((IMPRINTER == nDocumentHandlingSelect) || (ENDORSER == nDocumentHandlingSelect))
+ {
+ guidFormatArray.Append(WiaImgFmt_CSV);
+ guidFormatArray.Append(WiaImgFmt_TXT);
+ guidFormatArray.Append(WiaImgFmt_BMP);
+ }
+ else if (BARCODE_READER == nDocumentHandlingSelect)
+ {
+ guidFormatArray.Append(WiaImgFmt_XMLBAR);
+ guidFormatArray.Append(WiaImgFmt_RAWBAR);
+ }
+ else if (PATCH_CODE_READER == nDocumentHandlingSelect)
+ {
+ guidFormatArray.Append(WiaImgFmt_XMLPAT);
+ guidFormatArray.Append(WiaImgFmt_RAWPAT);
+ }
+ else if (MICR_READER == nDocumentHandlingSelect)
+ {
+ guidFormatArray.Append(WiaImgFmt_XMLMIC);
+ guidFormatArray.Append(WiaImgFmt_RAWMIC);
+ }
+
+ hr = PropertyManager.AddProperty(WIA_IPA_FORMAT, WIA_IPA_FORMAT_STR, RWL, guidFormatArray[0], guidFormatArray[0], &guidFormatArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_FORMAT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_TYMED
+ //
+ // This sample driver supports only TYMED_FILE (single page files) for image as well as text and metadata data transfers
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lTymedArray;
+ lTymedArray.Append(TYMED_FILE);
+
+ hr = PropertyManager.AddProperty(WIA_IPA_TYMED, WIA_IPA_TYMED_STR, RWL, lTymedArray[0], lTymedArray[0], &lTymedArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_TYMED for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_PREFERRED_FORMAT
+ //
+ // For image transfers, this sample driver reports EXIF as the preferred transfer file format.
+ //
+ // For printer/endorser transfers, this driver reports CSV as the preferred transfer file format.
+ //
+ // For barcode, patch code and MICR metadata transfers, this driver reports XML as the preferred transfer file format.
+ //
+ if (SUCCEEDED(hr))
+ {
+ GUID guidPreferredFormat = {};
+
+ if ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect) ||
+ (AUTO_SOURCE == nDocumentHandlingSelect))
+ {
+ guidPreferredFormat = WiaImgFmt_EXIF;
+ }
+ else if ((IMPRINTER == nDocumentHandlingSelect) || (ENDORSER == nDocumentHandlingSelect))
+ {
+ guidPreferredFormat = WiaImgFmt_CSV;
+ }
+ else if (BARCODE_READER == nDocumentHandlingSelect)
+ {
+ guidPreferredFormat = WiaImgFmt_XMLBAR;
+ }
+ else if (PATCH_CODE_READER == nDocumentHandlingSelect)
+ {
+ guidPreferredFormat = WiaImgFmt_XMLPAT;
+ }
+ else if (MICR_READER == nDocumentHandlingSelect)
+ {
+ guidPreferredFormat = WiaImgFmt_XMLMIC;
+ }
+
+ hr = PropertyManager.AddProperty(WIA_IPA_PREFERRED_FORMAT, WIA_IPA_PREFERRED_FORMAT_STR, RN, guidPreferredFormat);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_PREFERRED_FORMAT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_FILENAME_EXTENSION
+ //
+ if (SUCCEEDED(hr))
+ {
+ BSTR bstrFileExtension = NULL;
+
+ //
+ // Note that WIA_IPA_FILENAME_EXTENSION must match the WIA_IPA_FORMAT current value, not WIA_IPA_PREFERRED_FORMAT:
+ //
+ if ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect) ||
+ (AUTO_SOURCE == nDocumentHandlingSelect))
+ {
+ bstrFileExtension = SysAllocString(FILE_EXT_BMP);
+ }
+ else if ((IMPRINTER == nDocumentHandlingSelect) || (ENDORSER == nDocumentHandlingSelect))
+ {
+ bstrFileExtension = SysAllocString(FILE_EXT_CSV);
+ }
+ else if ((BARCODE_READER == nDocumentHandlingSelect) || (PATCH_CODE_READER == nDocumentHandlingSelect) ||
+ (MICR_READER == nDocumentHandlingSelect))
+ {
+ bstrFileExtension = SysAllocString(FILE_EXT_XML);
+ }
+
+ if (bstrFileExtension)
+ {
+ hr = PropertyManager.AddProperty(WIA_IPA_FILENAME_EXTENSION, WIA_IPA_FILENAME_EXTENSION_STR, RN, bstrFileExtension);
+
+ SysFreeString(bstrFileExtension);
+ bstrFileExtension = NULL;
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ WIAEX_ERROR((g_hInst, "Could not allocate the file name extension property value, hr = 0x%08X", hr));
+ }
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_FILENAME_EXTENSION for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_COMPRESSION
+ //
+ // For image transfers, this sample driver supports no compression (mandatory default, for DIB and Raw transfers)
+ // and JPEG (EEXIF transfers). The sample driver also pretends to support auto-compression (WIA_COMPRESSION_AUTO)
+ // but in auto-compression mode JPEG compression is always selected.
+ //
+ // For all other metadata transfers, this sample driver supports no compression (mandatory default).
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lCompressionArray;
+
+ lCompressionArray.Append(WIA_COMPRESSION_NONE);
+ if ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect) || (AUTO_SOURCE == nDocumentHandlingSelect))
+ {
+ lCompressionArray.Append(WIA_COMPRESSION_JPEG);
+ lCompressionArray.Append(WIA_COMPRESSION_AUTO);
+ }
+
+ hr = PropertyManager.AddProperty(WIA_IPA_COMPRESSION, WIA_IPA_COMPRESSION_STR, RWL, lCompressionArray[0], lCompressionArray[0], &lCompressionArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_COMPRESSION for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // Apply the property changes to the current session's Application Item Tree:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA item properties for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes the properties common to the Flatbed and Feeder items.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+* nDocumentHandlingSelect - FLAT or FEED (defined in wiadef.h)
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeFlatbedFeederProperties(
+ _In_ BYTE* pWiasContext,
+ UINT nDocumentHandlingSelect)
+
+{
+ HRESULT hr = S_OK;
+ CWIAPropertyManager PropertyManager;
+
+ if ((!pWiasContext) || ((FLAT != nDocumentHandlingSelect) && (FEED != nDocumentHandlingSelect)))
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializeFlatbedFeederProperties, invalid parameter, hr = 0x%08X", hr));
+ }
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // WIA_IPA_ITEM_SIZE
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lItemSize = 0;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_ITEM_SIZE, WIA_IPA_ITEM_SIZE_STR, RN, lItemSize);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_ITEM_SIZE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_PLANAR:
+ //
+ LONG lPlanar = WIA_PACKED_PIXEL;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_PLANAR, WIA_IPA_PLANAR_STR, RN, lPlanar);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_PLANAR for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ //
+ // WIA_IPA_DATATYPE
+ //
+ // This sample driver supports 24-bpp RGB color and 8-bpp Grayscale for the image transfers, as well as the auto color mode.
+ // When WIA_DATA_AUTO is set the sample driver choses randomly between WIA_DATA_GRAYSCALE and WIA_DATA_COLOR.
+ // A real driver should base this decision on the actual document that is scanned:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lDataTypeArray;
+ lDataTypeArray.Append(WIA_DATA_GRAYSCALE);
+ lDataTypeArray.Append(WIA_DATA_COLOR);
+ lDataTypeArray.Append(WIA_DATA_AUTO);
+
+ hr = PropertyManager.AddProperty(WIA_IPA_DATATYPE, WIA_IPA_DATATYPE_STR, RWL, lDataTypeArray[0], lDataTypeArray[0], &lDataTypeArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_DATATYPE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_DEPTH
+ //
+ // This sample driver supports 24-bpp RGB color and 8-bpp Grayscale, as well as the auto value (WIA_DEPTH_AUTO or 0):
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lDepthArray;
+ lDepthArray.Append(8);
+ lDepthArray.Append(24);
+ lDepthArray.Append(WIA_DEPTH_AUTO);
+
+ hr = PropertyManager.AddProperty(WIA_IPA_DEPTH , WIA_IPA_DEPTH_STR, RWLC, lDepthArray[0], lDepthArray[0], &lDepthArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_DEPTH for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_CHANNELS_PER_PIXEL
+ //
+ // This sample driver supports 1 and 3 channels (samples) per pixel
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lChannelsPerPixel = 1; //default value that matches the default WIA_DATA_GRAYSCALE
+
+ hr = PropertyManager.AddProperty(WIA_IPA_CHANNELS_PER_PIXEL, WIA_IPA_CHANNELS_PER_PIXEL_STR, RN, lChannelsPerPixel);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_CHANNELS_PER_PIXEL for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_BITS_PER_CHANNEL
+ //
+ // This sample driver supports only 8 bits per channel (sample)
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lBitsPerChannel = 8;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_BITS_PER_CHANNEL, WIA_IPA_BITS_PER_CHANNEL_STR, RN, lBitsPerChannel);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_BITS_PER_CHANNEL for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_RAW_BITS_PER_CHANNEL
+ //
+ if (SUCCEEDED(hr))
+ {
+ BYTE bRawBitsPerChannel[] = { 8 }; //to match the default WIA_DATA_GRAYSCALE
+
+ hr = PropertyManager.AddProperty(WIA_IPA_RAW_BITS_PER_CHANNEL, WIA_IPA_RAW_BITS_PER_CHANNEL_STR, RN, &bRawBitsPerChannel[0], 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_RAW_BITS_PER_CHANNEL for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+
+ //
+ // WIA_IPS_CUR_INTENT
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lCurrentIntent = WIA_INTENT_NONE;
+ LONG lValidIntents = WIA_INTENT_IMAGE_TYPE_COLOR | WIA_INTENT_IMAGE_TYPE_GRAYSCALE | WIA_INTENT_MAXIMIZE_QUALITY | WIA_INTENT_MINIMIZE_SIZE;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_CUR_INTENT, WIA_IPS_CUR_INTENT_STR, RWF, lCurrentIntent, lValidIntents);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_CUR_INTENT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_OPTICAL_XRES and WIA_IPS_OPTICAL_YRES
+ //
+ // This sample driver reports OPTICAL_RESOLUTION DPI as optical resolution on both scan directions
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lOpticalResolution = OPTICAL_RESOLUTION;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_OPTICAL_XRES, WIA_IPS_OPTICAL_XRES_STR, RN, lOpticalResolution);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_OPTICAL_XRES for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_OPTICAL_YRES, WIA_IPS_OPTICAL_YRES_STR, RN, lOpticalResolution);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_OPTICAL_YRES for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+ }
+
+ //
+ // WIA_IPS_XRES and WIA_IPS_YRES
+ //
+ // This sample driver supports OPTICAL_RESOLUTION DPI as the only scan resolution for both scan directions
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lResolutionArray;
+ lResolutionArray.Append(OPTICAL_RESOLUTION);
+
+ //
+ // Add WIA_IPS_XRES and WIA_IPS_YRES as WIA_PROP_LIST:
+ //
+ hr = PropertyManager.AddProperty(WIA_IPS_XRES, WIA_IPS_XRES_STR, RWLC, lResolutionArray[0], lResolutionArray[0], &lResolutionArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_XRES for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_YRES, WIA_IPS_YRES_STR, RWLC, lResolutionArray[0], lResolutionArray[0], &lResolutionArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_YRES for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+ }
+
+ //
+ // WIA_IPS_XSCALING and WIA_IPS_YSCALING
+ //
+ // This sample driover supports only 100% scaling (which means no actual scaling)
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lScaling = 100;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_XSCALING, WIA_IPS_XSCALING_STR, RWRC, lScaling, lScaling, lScaling, lScaling, 0);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_XSCALING for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_YSCALING, WIA_IPS_YSCALING_STR, RWRC, lScaling, lScaling, lScaling, lScaling, 0);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_YSCALING for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+ }
+
+ //
+ // WIA_IPS_MIN_HORIZONTAL_SIZE, WIA_IPS_MAX_HORIZONTAL_SIZE, WIA_IPS_MIN_VERTICAL_SIZE and WIA_IPS_MAX_VERTICAL_SIZE
+ //
+ // This sample driver supports for both flatbed and feeder the following:
+ //
+ // Minimum scan region is MIN_SCAN_AREA_WIDTH x MIN_SCAN_AREA_HEIGHT
+ // Maximum scan region is MAX_SCAN_AREA_WIDTH x MAX_SCAN_AREA_HEIGHT
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lMaximumWidth = MAX_SCAN_AREA_WIDTH;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_MAX_HORIZONTAL_SIZE, WIA_IPS_MAX_HORIZONTAL_SIZE_STR, RN, lMaximumWidth);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MAX_HORIZONTAL_SIZE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ LONG lMaximumHeight = MAX_SCAN_AREA_HEIGHT;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_MAX_VERTICAL_SIZE, WIA_IPS_MAX_VERTICAL_SIZE_STR, RN, lMaximumHeight);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MAX_VERTICAL_SIZE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ LONG lMinimumWidth = MIN_SCAN_AREA_WIDTH;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_MIN_HORIZONTAL_SIZE, WIA_IPS_MIN_HORIZONTAL_SIZE_STR, RN, lMinimumWidth);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MIN_HORIZONTAL_SIZE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ LONG lMinimumHeight = MIN_SCAN_AREA_HEIGHT;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_MIN_VERTICAL_SIZE, WIA_IPS_MIN_VERTICAL_SIZE_STR, RN, lMinimumHeight);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MIN_VERTICAL_SIZE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_XPOS, WIA_IPS_YPOS, WIA_IPS_XEXTENT and WIA_IPS_YEXTENT
+ //
+ // In general, for the flatbed item, valid values are to be initialized from
+ // (considering current WIA_IPS_X/YRES and WIA_IPS_X/YSCALING):
+ //
+ // WIA_IPS_MIN_HORIZONTAL_SIZE,
+ // WIA_IPS_MIN_VERTICAL_SIZE,
+ // WIA_IPS_MAX_HORIZONTAL_SIZE,
+ // WIA_IPS_MAX_VERTICAL_SIZE
+ //
+ // For the feeder item valid values are to be initialized from
+ // the size of the currently selected document size, considering
+ // orientation and current WIA_IPS_X/YRES/SCALING:
+ //
+ // WIA_IPS_PAGE_SIZE
+ // WIA_IPS_PAGE_WIDTH/HEIGHT (if WIA_IPS_PAGE_SIZE is set to CUSTOM, default)
+ // WIA_IPS_ORIENTATION
+ //
+ // The default scan region should cover the entire available scan area.
+ //
+
+ LONG lMinXExtent = 1;
+ LONG lMinYExtent = 1;
+ LONG lMaxXExtent = 2;
+ LONG lMaxYExtent = 2;
+
+ LONG lXResolution = OPTICAL_RESOLUTION;
+ LONG lYResolution = OPTICAL_RESOLUTION;
+
+ if (SUCCEEDED(hr) && (AUTO_SOURCE != nDocumentHandlingSelect))
+ {
+ //
+ // Convert back from 1/1000" values x pixels-per-inch:
+ //
+ lMinXExtent = (MIN_SCAN_AREA_WIDTH * lXResolution) / 1000;
+ if (!lMinXExtent)
+ {
+ lMinXExtent = 1;
+ }
+ lMinYExtent = (MIN_SCAN_AREA_HEIGHT * lYResolution) / 1000;
+ if (!lMinYExtent)
+ {
+ lMinYExtent = 1;
+ }
+ lMaxXExtent = (MAX_SCAN_AREA_WIDTH * lXResolution) / 1000;
+ lMaxYExtent = (MAX_SCAN_AREA_HEIGHT * lYResolution) / 1000;
+
+ //
+ // IMPORTANT: do not round up!
+ //
+ // lMaxXExtent = (LONG)((((float)MAX_SCAN_AREA_WIDTH * (float)lXResolution) / 1000.0f) + 0.5f);
+ // lMaxYExtent = (LONG)((((float)MAX_SCAN_AREA_HEIGHT * (float)lYResolution) / 1000.0f) + 0.5f);
+ //
+
+ if ((lMaxXExtent < 1) || (lMaxYExtent < 1) || (lMinXExtent > lMaxXExtent) || (lMinYExtent > lMaxYExtent))
+ {
+ hr = E_FAIL;
+ WIAEX_ERROR((g_hInst, "Invalid resolution and-or minimum and-or maximum scan area size values, hr = 0x%08X", hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_XPOS, WIA_IPS_XPOS_STR, RWRC, 0, 0, 0, lMaxXExtent - lMinXExtent, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_XPOS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_YPOS, WIA_IPS_YPOS_STR, RWRC, 0, 0, 0, lMaxYExtent - lMinYExtent, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_YPOS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_XEXTENT, WIA_IPS_XEXTENT_STR, RWRC, lMaxXExtent, lMaxXExtent, lMinXExtent, lMaxXExtent, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_XEXTENT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_YEXTENT, WIA_IPS_YEXTENT_STR, RWRC, lMaxYExtent, lMaxYExtent, lMinYExtent, lMaxYExtent, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_YEXTENT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+ }
+
+ //
+ // WIA_IPS_BRIGHTNESS and WIA_IPS_CONTRAST
+ //
+ // This sample driver simulates brightness and contrast adjustment between
+ // a standard range from -1000 to 1000, with a default value of 0.
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_BRIGHTNESS, WIA_IPS_BRIGHTNESS_STR, RWRC, 0, 0, -1000, 1000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_BRIGHTNESS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_CONTRAST, WIA_IPS_CONTRAST_STR, RWRC, 0, 0, -1000, 1000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_CONTRAST for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_ROTATION
+ //
+ // This sample driver supports only 0 degrees rotation (no actual rotation)
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lRotationArray;
+ lRotationArray.Append(0);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_ROTATION, WIA_IPS_ROTATION_STR, RWLC, lRotationArray[0], lRotationArray[0], &lRotationArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ROTATION for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_THRESHOLD
+ //
+ // This sample driver supports only the default value of 128
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_THRESHOLD, WIA_IPS_THRESHOLD_STR, RWRC, 128, 128, 128, 128, 0);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_THRESHOLD for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PREVIEW
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lScanModeArray;
+ lScanModeArray.Append(WIA_FINAL_SCAN);
+ lScanModeArray.Append(WIA_PREVIEW_SCAN);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PREVIEW, WIA_IPS_PREVIEW_STR, RWL, lScanModeArray[0], lScanModeArray[0], &lScanModeArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PREVIEW for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_SHOW_PREVIEW_CONTROL
+ //
+ if (SUCCEEDED(hr))
+ {
+ //
+ // There is the option to disable the preview control for Feeder but this sample driver is not using it:
+ //
+ // lShowPreviewControl = (FLAT == nDocumentHandlingSelect) ? WIA_SHOW_PREVIEW_CONTROL : WIA_DONT_SHOW_PREVIEW_CONTROL;
+ //
+
+ LONG lShowPreviewControl = WIA_SHOW_PREVIEW_CONTROL;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_SHOW_PREVIEW_CONTROL, WIA_IPS_SHOW_PREVIEW_CONTROL_STR, RN, lShowPreviewControl);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SHOW_PREVIEW_CONTROL for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_SUPPORTS_CHILD_ITEM_CREATION
+ //
+ if (SUCCEEDED(hr))
+ {
+ BOOL lSupportsChildItem = FALSE;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_SUPPORTS_CHILD_ITEM_CREATION, WIA_IPS_SUPPORTS_CHILD_ITEM_CREATION_STR, RN, lSupportsChildItem);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SUPPORTS_CHILD_ITEM_CREATION for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PHOTOMETRIC_INTERP
+ //
+ // This sample driver supports only the default value of WIA_PHOTO_WHITE_1
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lPhotoInterpArray;
+ lPhotoInterpArray.Append(WIA_PHOTO_WHITE_1);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PHOTOMETRIC_INTERP, WIA_IPS_PHOTOMETRIC_INTERP_STR, RWL, lPhotoInterpArray[0], lPhotoInterpArray[0], &lPhotoInterpArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PHOTOMETRIC_INTERP for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // Even though deprecated the following "image information" properties are still required
+ // for compatibility with existing legacy XP applications, including Scanner and Camera Wizard,
+ // applications using the default WIA UI (including Paint) and the TWAIN applications using
+ // the WIA driver though the TWAIN - WIA compatibility layer:
+ //
+ // WIA_IPA_PIXELS_PER_LINE - the image width, in pixels, for the final image
+ // WIA_IPA_NUMBER_OF_LINES - the image length, in pixels, for the final image
+ // WIA_IPA_BYTES_PER_LINE - line width in bytes matching WIA_IPA_PIXELS_PER_LINE and WIA_IPA_DEPTH
+ //
+ // All these values must match the exact dimensions of the final image to be transferred
+ // to the application, a mismatch could cause unpredictable behaviour, including Divide by Zero
+ // and Access Violation errors in the application attempting to receive data that doesn't exist.
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ LONG lPixelsPerLine = lMaxXExtent;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_PIXELS_PER_LINE, WIA_IPA_PIXELS_PER_LINE_STR, RN, lPixelsPerLine);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_PIXELS_PER_LINE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ LONG lNumberOfLines = lMaxYExtent;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_NUMBER_OF_LINES, WIA_IPA_NUMBER_OF_LINES_STR, RN, lNumberOfLines);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_NUMBER_OF_LINES for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ //
+ // DIB (the default image file transfer format) lines must be DWORD aligned, meaning
+ // that each line must be multiple by 4 bytes in length, padded if necessary at the end:
+ //
+ LONG lBytesPerLine = 2552;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_BYTES_PER_LINE, WIA_IPA_BYTES_PER_LINE_STR, RN, lBytesPerLine);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_BYTES_PER_LINE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_BUFFER_SIZE must be supported in order to be able to increase (if needed) the default 64KB value set
+ // by the WIA Compatibility Layer in the WIA Service when the driver is used with a legacy WIA 1.0 application:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ LONG lBufferSize = DEFAULT_BUFFER_SIZE;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_BUFFER_SIZE, WIA_IPA_BUFFER_SIZE_STR, RN, lBufferSize);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_BUFFER_SIZE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_AUTO_CROP
+ //
+ // The sample driver implements WIA_AUTO_CROP_SINGLE but does not support actual image cropping:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lAutoCropArray;
+ lAutoCropArray.Append(WIA_AUTO_CROP_DISABLED);
+ lAutoCropArray.Append(WIA_AUTO_CROP_SINGLE);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_AUTO_CROP, WIA_IPS_AUTO_CROP_STR, RWL, lAutoCropArray[0], lAutoCropArray[0], &lAutoCropArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_AUTO_CROP for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_OVER_SCAN
+ //
+ // The sample driver pretends to support overscanning on all directions, however the overscan settings are unfunctional:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lOverScanArray;
+ lOverScanArray.Append(WIA_OVER_SCAN_DISABLED);
+ lOverScanArray.Append(WIA_OVER_SCAN_TOP_BOTTOM);
+ lOverScanArray.Append(WIA_OVER_SCAN_LEFT_RIGHT);
+ lOverScanArray.Append(WIA_OVER_SCAN_ALL);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_OVER_SCAN, WIA_IPS_OVER_SCAN_STR, RWL, lOverScanArray[0], lOverScanArray[0], &lOverScanArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_OVER_SCAN for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_OVER_SCAN_LEFT, WIA_IPS_OVER_SCAN_RIGHT, WIA_IPS_OVER_SCAN_TOP and WIA_IPS_OVER_SCAN_BOTTOM
+ //
+ // The sample driver pretends to support overscanning from 0 to 1" on all document sides, in 0.001" increments:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_OVER_SCAN_LEFT, WIA_IPS_OVER_SCAN_LEFT_STR, RWRC, 0, 0, 0, 1000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_OVER_SCAN_LEFT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_OVER_SCAN_RIGHT, WIA_IPS_OVER_SCAN_RIGHT_STR, RWRC, 0, 0, 0, 1000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_OVER_SCAN_RIGHT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_OVER_SCAN_TOP, WIA_IPS_OVER_SCAN_TOP_STR, RWRC, 0, 0, 0, 1000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_OVER_SCAN_TOP for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_OVER_SCAN_BOTTOM, WIA_IPS_OVER_SCAN_BOTTOM_STR, RWRC, 0, 0, 0, 1000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_OVER_SCAN_BOTTOM for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_COLOR_DROP
+ //
+ // The sample driver implements the color-drop properties, however it does not
+ // execute any actual color filtering (drop) on the test image:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lColorDropArray;
+ lColorDropArray.Append(WIA_COLOR_DROP_DISABLED);
+ lColorDropArray.Append(WIA_COLOR_DROP_RED);
+ lColorDropArray.Append(WIA_COLOR_DROP_GREEN);
+ lColorDropArray.Append(WIA_COLOR_DROP_BLUE);
+ lColorDropArray.Append(WIA_COLOR_DROP_RGB);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_COLOR_DROP, WIA_IPS_COLOR_DROP_STR, RWL, lColorDropArray[0], lColorDropArray[0], &lColorDropArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_COLOR_DROP for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_COLOR_DROP_MULTI:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_COLOR_DROP_MULTI, WIA_IPS_COLOR_DROP_MULTI_STR, RN, g_lMaxDropColors);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_COLOR_DROP_MULTI for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_COLOR_DROP_RED, WIA_IPS_COLOR_DROP_GREEN and WIA_IPS_COLOR_DROP_BLUE:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_COLOR_DROP_RED, WIA_IPS_COLOR_DROP_RED_STR, RW, g_lMaxDropColors, (LONG *)&g_lDefaultDropColors[0]);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_COLOR_DROP_RED for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_COLOR_DROP_GREEN, WIA_IPS_COLOR_DROP_GREEN_STR, RW, g_lMaxDropColors, (LONG *)&g_lDefaultDropColors[0]);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_COLOR_DROP_GREEN for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_COLOR_DROP_BLUE, WIA_IPS_COLOR_DROP_BLUE_STR, RW, g_lMaxDropColors, (LONG *)&g_lDefaultDropColors[0]);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_COLOR_DROP_BLUE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // Apply the property changes to the current session's Application Item Tree:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA item properties for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes the properties specific to the Feeder item.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeFeederSpecificProperties(
+ _In_ BYTE* pWiasContext)
+
+{
+ HRESULT hr = S_OK;
+ CWIAPropertyManager PropertyManager;
+
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializeFeederSpecificProperties, invalid parameter, hr = 0x%08X", hr));
+ }
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // WIA_IPS_DOCUMENT_HANDLING_SELECT
+ //
+ LONG lDocumentHandlingSelect = FRONT_ONLY;
+ LONG lDocumentHandlingSelectValidValues = FRONT_ONLY | DUPLEX;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_DOCUMENT_HANDLING_SELECT, WIA_IPS_DOCUMENT_HANDLING_SELECT_STR, RWF, lDocumentHandlingSelect, lDocumentHandlingSelectValidValues);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_DOCUMENT_HANDLING_SELECT, hr = 0x%08X", hr));
+ }
+
+ //
+ // WIA_IPS_SHEET_FEEDER_REGISTRATION
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lFeederRegistration = LEFT_JUSTIFIED;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_SHEET_FEEDER_REGISTRATION, WIA_IPS_SHEET_FEEDER_REGISTRATION_STR, RN, lFeederRegistration);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SHEET_FEEDER_REGISTRATION, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PAGES
+ //
+ // Important: the default value for this property should be ALL_PAGES (0).
+ // However legacy XP applications need a WIA_IPS_PAGES > 0 in order to work.
+ // For this reason the default WIA_IPS_PAGES is changed to 1. Clients who need
+ // to transfer all available images must set WIA_IPS_PAGES to ALL_PAGES.
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lMaxPages = 0x7FFFFFFF; //maximum pozitive value for a signed 32-bit integer
+ LONG lMinPages = 0; //ALL_PAGES
+ LONG lDefaultPages = 1;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PAGES, WIA_IPS_PAGES_STR,
+ RWR, lDefaultPages, lDefaultPages, lMinPages, lMaxPages, 1);
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PAGES, hr = 0x%08X", hr));
+ }
+ }
+
+ LONG lPageWidth = MAX_SCAN_AREA_WIDTH;
+ LONG lPageHeight = MAX_SCAN_AREA_HEIGHT;
+
+ //
+ // WIA_IPS_PAGE_SIZE
+ //
+ // This sample driver supports Letter, custom and auto-detect document sizes
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lDefaultPageSize = WIA_PAGE_CUSTOM;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PAGE_SIZE, WIA_IPS_PAGE_SIZE_STR, RWL, lDefaultPageSize, lDefaultPageSize, &m_lPortraitSizesArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PAGE_SIZE, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_ORIENTATION
+ //
+ // This sample driver supports only Portrait orientation
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lOrientationArray;
+ lOrientationArray.Append(PORTRAIT);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_ORIENTATION, WIA_IPS_ORIENTATION_STR, RWL, lOrientationArray[0], lOrientationArray[0], &lOrientationArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ORIENTATION, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PAGE_WIDTH
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PAGE_WIDTH, WIA_IPS_PAGE_WIDTH_STR, RN, lPageWidth);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ORIENTATION, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PAGE_HEIGHT
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PAGE_HEIGHT, WIA_IPS_PAGE_HEIGHT_STR, RN, lPageHeight);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ORIENTATION, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_JOB_SEPARATORS
+ //
+ // When job separators are enabled, the sample driver simulates a job separator page every JOB_SEPARATOR_AT_PAGE pages scanned:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lJobSeparatorsArray;
+ lJobSeparatorsArray.Append(WIA_SEPARATOR_DISABLED);
+ lJobSeparatorsArray.Append(WIA_SEPARATOR_DETECT_SCAN_CONTINUE);
+ lJobSeparatorsArray.Append(WIA_SEPARATOR_DETECT_SCAN_STOP);
+ lJobSeparatorsArray.Append(WIA_SEPARATOR_DETECT_NOSCAN_CONTINUE);
+ lJobSeparatorsArray.Append(WIA_SEPARATOR_DETECT_NOSCAN_STOP);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_JOB_SEPARATORS, WIA_IPS_JOB_SEPARATORS_STR, RWL, lJobSeparatorsArray[0], lJobSeparatorsArray[0], &lJobSeparatorsArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_JOB_SEPARATORS, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_LONG_DOCUMENT
+ //
+ // The sample driver implemenmts the property but does not implement the actual functionality:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lLongDocArray;
+ lLongDocArray.Append(WIA_LONG_DOCUMENT_DISABLED);
+ lLongDocArray.Append(WIA_LONG_DOCUMENT_ENABLED);
+ lLongDocArray.Append(WIA_LONG_DOCUMENT_SPLIT);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_LONG_DOCUMENT, WIA_IPS_LONG_DOCUMENT_STR, RWL, lLongDocArray[0], lLongDocArray[0], &lLongDocArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_LONG_DOCUMENT, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_BLANK_PAGES
+ //
+ // The sample driver implements the property but does not implement actual blank page detection functionality:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lBlankPagesArray;
+ lBlankPagesArray.Append(WIA_BLANK_PAGE_DETECTION_DISABLED);
+ lBlankPagesArray.Append(WIA_BLANK_PAGE_DISCARD);
+ lBlankPagesArray.Append(WIA_BLANK_PAGE_JOB_SEPARATOR);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_BLANK_PAGES, WIA_IPS_BLANK_PAGES_STR, RWL, lBlankPagesArray[0], lBlankPagesArray[0], &lBlankPagesArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_BLANK_PAGES, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_BLANK_PAGES_SENSITIVITY
+ //
+ // This sample driver reports a range of supported values (which are not functional)
+ // between 0 and 10 inclusive, with 5 being the default sensitivity:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_BLANK_PAGES_SENSITIVITY, WIA_IPS_BLANK_PAGES_SENSITIVITY_STR, RWR, 5, 5, 1, 10, 1);
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_BLANK_PAGES_SENSITIVITY, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_MULTI_FEED
+ //
+ // When multi-feed detection is enabled, the sample driver simulates a multi-feed condition every MULTI_FEED_AT_PAGE pages scanned:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lMultiFeedArray;
+ lMultiFeedArray.Append(WIA_MULTI_FEED_DETECT_DISABLED);
+ lMultiFeedArray.Append(WIA_MULTI_FEED_DETECT_STOP_ERROR);
+ lMultiFeedArray.Append(WIA_MULTI_FEED_DETECT_STOP_SUCCESS);
+ lMultiFeedArray.Append(WIA_MULTI_FEED_DETECT_CONTINUE);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_MULTI_FEED, WIA_IPS_MULTI_FEED_STR, RWL, lMultiFeedArray[0], lMultiFeedArray[0], &lMultiFeedArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MULTI_FEED, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_MULTI_FEED_SENSITIVITY
+ //
+ // This sample driver reports a range of supported values (which are not functional)
+ // between 0 and 10 inclusive, with 5 being the default sensitivity:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_MULTI_FEED_SENSITIVITY, WIA_IPS_MULTI_FEED_SENSITIVITY_STR, RWR, 5, 5, 1, 10, 1);
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MULTI_FEED_SENSITIVITY, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_ALARM
+ //
+ // This sample driver does pretend to support one kind of audible alarm (beep) to signal
+ // when a multi-feed conditions is detected, not functional:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lAlarmArray;
+ lAlarmArray.Append(WIA_ALARM_NONE);
+ lAlarmArray.Append(WIA_ALARM_BEEP1);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_ALARM, WIA_IPS_ALARM_STR, RWL, lAlarmArray[0], lAlarmArray[0], &lAlarmArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ALARM, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_SCAN_AHEAD:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lScanAheadArray;
+ lScanAheadArray.Append(WIA_SCAN_AHEAD_DISABLED);
+ lScanAheadArray.Append(WIA_SCAN_AHEAD_ENABLED);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_SCAN_AHEAD, WIA_IPS_SCAN_AHEAD_STR, RWL, lScanAheadArray[0], lScanAheadArray[0], &lScanAheadArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SCAN_AHEAD, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_SCAN_AHEAD_CAPACITY:
+ //
+ if (SUCCEEDED(hr))
+ {
+ ULONG ulScanAheadCapacity = 0; //undefined
+
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_SCAN_AHEAD_CAPACITY, WIA_IPS_SCAN_AHEAD_CAPACITY_STR, RN, ulScanAheadCapacity);
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SCAN_AHEAD_CAPACITY, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_FEEDER_CONTROL
+ //
+ // The sample driver pretents to support manual feeder motor control
+ // (the WIA_COMMAND_START_FEEDER and the WIA_COMMAND_STOP_FEEDER commands):
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lFeederControlArray;
+ lFeederControlArray.Append(WIA_FEEDER_CONTROL_AUTO);
+ lFeederControlArray.Append(WIA_FEEDER_CONTROL_MANUAL);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_FEEDER_CONTROL, WIA_IPS_FEEDER_CONTROL_STR, RWL, lFeederControlArray[0], lFeederControlArray[0], &lFeederControlArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SCAN_AHEAD, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Apply the property changes to the current session's Application Item Tree:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA item properties for feeder, hr = 0x%08X", hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes the properties specific to the Imprinter and Endorser items.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+* nDocumentHandlingSelect - IMPRINTER or ENDORSER (defined in wiadef.h)
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeImprinterEndorserProperties(
+ _In_ BYTE* pWiasContext,
+ UINT nDocumentHandlingSelect)
+{
+ HRESULT hr = S_OK;
+ CWIAPropertyManager PropertyManager;
+
+ if ((!pWiasContext) || ((IMPRINTER != nDocumentHandlingSelect) && (ENDORSER != nDocumentHandlingSelect)))
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializeImprinterEndorserProperties, invalid parameter, hr = 0x%08X", hr));
+ }
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER
+ //
+ // This sample driver pretends to have an imprinter on the front side of the feeder and an endorser on the back side
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lPrinterEndorserArray;
+ lPrinterEndorserArray.Append(WIA_PRINTER_ENDORSER_DISABLED);
+ lPrinterEndorserArray.Append(WIA_PRINTER_ENDORSER_AUTO);
+ lPrinterEndorserArray.Append((IMPRINTER == nDocumentHandlingSelect) ? WIA_PRINTER_ENDORSER_FEEDER_FRONT : WIA_PRINTER_ENDORSER_FEEDER_BACK);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER, WIA_IPS_PRINTER_ENDORSER_STR, RWL, lPrinterEndorserArray[0], lPrinterEndorserArray[0], &lPrinterEndorserArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_ORDER
+ //
+ // The sample imprinter operates after scan, the sample endorser operates before scan
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lPrinterEndorserOrder = (IMPRINTER == nDocumentHandlingSelect) ? WIA_PRINTER_ENDORSER_AFTER_SCAN : WIA_PRINTER_ENDORSER_BEFORE_SCAN;
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_ORDER, WIA_IPS_PRINTER_ENDORSER_ORDER_STR, RN, lPrinterEndorserOrder);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_ORDER for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_COUNTER
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_COUNTER , WIA_IPS_PRINTER_ENDORSER_COUNTER_STR, RWRC, 0, 0, 0, 0xFFFFFFFF, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_COUNTER for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_STEP
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_STEP, WIA_IPS_PRINTER_ENDORSER_STEP_STR, RWRC, 1, 1, 1, 0xFFFFFFFF, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_STEP for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_XOFFSET and WIA_IPS_PRINTER_ENDORSER_YOFFSET
+ //
+ // This sample driver pretends to support from 0" to 3" inclusive imprinter and endorser offsets, in 0.001" step increments
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_XOFFSET, WIA_IPS_PRINTER_ENDORSER_XOFFSET_STR, RWRC, 0, 0, 0, 3000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_XOFFSET for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ else
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_YOFFSET, WIA_IPS_PRINTER_ENDORSER_YOFFSET_STR, RWRC, 0, 0, 0, 3000, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_YOFFSET for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+ }
+
+ //
+ // WIA_IPS_ROTATION
+ //
+ // This sample driver pretends to support all standard 90' rotation values for its imprinter and endorser units
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lRotationArray;
+ lRotationArray.Append(PORTRAIT);
+ lRotationArray.Append(LANDSCAPE);
+ lRotationArray.Append(ROT180);
+ lRotationArray.Append(ROT270);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_ROTATION, WIA_IPS_ROTATION_STR, RWL, lRotationArray[0], lRotationArray[0], &lRotationArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ROTATION for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_NUM_LINES
+ //
+ // This sample driver pretends that supports only one line of text for the imprinter and for the endorser
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_NUM_LINES, WIA_IPS_PRINTER_ENDORSER_NUM_LINES_STR, RN, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_NUM_LINES for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_STRING
+ //
+ if (SUCCEEDED(hr))
+ {
+ BSTR bstrPrinterEndorser = SysAllocString((IMPRINTER == nDocumentHandlingSelect) ? L"Sample imprinter text" : L"Sample endorser text");
+ if (bstrPrinterEndorser)
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_STRING, WIA_IPS_PRINTER_ENDORSER_STRING_STR, RW, bstrPrinterEndorser);
+
+ SysFreeString(bstrPrinterEndorser);
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ WIAEX_ERROR((g_hInst, "Could not allocate memory for the the WIA_IPS_PRINTER_ENDORSER_STRING property value, hr = 0x%08X", hr));
+ }
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_STRING for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_VALID_CHARACTERS
+ //
+ if (SUCCEEDED(hr))
+ {
+ BSTR bstrValidChars = SysAllocString((IMPRINTER == nDocumentHandlingSelect) ? SAMPLE_IMPRINTER_VALID_CHARS : SAMPLE_ENDORSER_VALID_CHARS);
+ if (bstrValidChars)
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_VALID_CHARACTERS, WIA_IPS_PRINTER_ENDORSER_VALID_CHARACTERS_STR, RN, bstrValidChars);
+
+ SysFreeString(bstrValidChars);
+ bstrValidChars = NULL;
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ WIAEX_ERROR((g_hInst, "Could not allocate memory for the the IA_IPS_PRINTER_ENDORSER_VALID_CHARACTERS property value, hr = 0x%08X", hr));
+ }
+
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_VALID_CHARACTERS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_VALID_FORMAT_SPECIFIERS
+ //
+ // This sample driver implements this optional property only for the imprinter
+ // where it implements a sub-set of all the possible standard values.
+ //
+ if (SUCCEEDED(hr) && (IMPRINTER == nDocumentHandlingSelect))
+ {
+ LONG lFormatSpecs[] = {
+ WIA_PRINT_DATE,
+ WIA_PRINT_YEAR,
+ WIA_PRINT_MONTH,
+ WIA_PRINT_DAY,
+ WIA_PRINT_WEEK_DAY,
+ WIA_PRINT_TIME_24H,
+ WIA_PRINT_HOUR_24H,
+ WIA_PRINT_MINUTE,
+ WIA_PRINT_SECOND,
+ WIA_PRINT_PAGE_COUNT};
+ ULONG ulFormatSpecs = ARRAYSIZE(lFormatSpecs);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_VALID_FORMAT_SPECIFIERS, WIA_IPS_PRINTER_ENDORSER_VALID_FORMAT_SPECIFIERS_STR, RN, ulFormatSpecs, lFormatSpecs);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_VALID_FORMAT_SPECIFIERS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_PADDING
+ //
+ // This sample driver does pretend to support all imprinter/endorser padding values but does not really apply padding:
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lPaddingArray;
+ lPaddingArray.Append(WIA_PRINT_PADDING_NONE);
+ lPaddingArray.Append(WIA_PRINT_PADDING_ZERO);
+ lPaddingArray.Append(WIA_PRINT_PADDING_BLANK);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_PADDING, WIA_IPS_PRINTER_ENDORSER_PADDING_STR, RWL, lPaddingArray[0], lPaddingArray[0], &lPaddingArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_PADDING for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_FONT_TYPE
+ //
+ // This sample driver does support all font type values but does not apply font type changes.
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lFontTypeArray;
+ lFontTypeArray.Append(WIA_PRINT_FONT_NORMAL);
+ lFontTypeArray.Append(WIA_PRINT_FONT_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_EXTRA_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_ITALIC_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_ITALIC_EXTRA_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_ITALIC);
+ lFontTypeArray.Append(WIA_PRINT_FONT_SMALL);
+ lFontTypeArray.Append(WIA_PRINT_FONT_SMALL_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_SMALL_EXTRA_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_SMALL_ITALIC_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_SMALL_ITALIC_EXTRA_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_SMALL_ITALIC);
+ lFontTypeArray.Append(WIA_PRINT_FONT_LARGE);
+ lFontTypeArray.Append(WIA_PRINT_FONT_LARGE_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_LARGE_EXTRA_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_LARGE_ITALIC_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_LARGE_ITALIC_EXTRA_BOLD);
+ lFontTypeArray.Append(WIA_PRINT_FONT_LARGE_ITALIC);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_FONT_TYPE, WIA_IPS_PRINTER_ENDORSER_FONT_TYPE_STR, RWL, lFontTypeArray[0], lFontTypeArray[0], &lFontTypeArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_FONT_TYPE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_CHARACTER_ROTATION
+ //
+ // This sample driver pretends to support all possible values, but does not actually apply any character rotation.
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lCharRotatationArray;
+ lCharRotatationArray.Append(PORTRAIT);
+ lCharRotatationArray.Append(LANDSCAPE);
+ lCharRotatationArray.Append(ROT180);
+ lCharRotatationArray.Append(ROT270);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_CHARACTER_ROTATION, WIA_IPS_PRINTER_ENDORSER_CHARACTER_ROTATION_STR,
+ RWL, lCharRotatationArray[0], lCharRotatationArray[0], &lCharRotatationArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_CHARACTER_ROTATION for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_MAX_CHARACTERS
+ //
+ // This sample driver pretends to support a maximum number of characters of 0xFFFFFFFF (unrealistic) for the imprinter and endorser.
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_MAX_CHARACTERS, WIA_IPS_PRINTER_ENDORSER_MAX_CHARACTERS_STR, RN, 0xFFFFFFFF);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_MAX_CHARACTERS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_INK
+ //
+ // This sample driver hard-codes a value of 50% (half capacity remaining) for the imprinter and endorser ink.
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_INK, WIA_IPS_PRINTER_ENDORSER_INK_STR, RN, 50);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_INK for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_TEXT_UPLOAD
+ //
+ // This sample driver reports to support imprinter/endorser text upload to show how an upload
+ // transfer is to be executed, however the uploaded data is not retained/applied.
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_TEXT_UPLOAD, WIA_IPS_PRINTER_ENDORSER_TEXT_UPLOAD_STR, RN, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_TEXT_UPLOAD for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_TEXT_DOWNLOAD
+ //
+ // This sample driver reports to support imprinter/endorser text download to show how a download
+ // transfer is to be executed, however the downloaded data is always the same/fixed, and is not
+ // modified to match WIA_IPS_PRINTER_ENDORSER_STRING.
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_TEXT_DOWNLOAD, WIA_IPS_PRINTER_ENDORSER_TEXT_DOWNLOAD_STR, RN, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_TEXT_DOWNLOAD for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_GRAPHICS, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_STR, RN, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_GRAPHICS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS_POSITION
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lPositionArray;
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_DEVICE_DEFAULT);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_LEFT);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_RIGHT);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_TOP);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_BOTTOM);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_TOP_LEFT);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_TOP_RIGHT);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_BOTTOM_LEFT);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_BOTTOM_RIGHT);
+ lPositionArray.Append(WIA_PRINTER_ENDORSER_GRAPHICS_BACKGROUND);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_GRAPHICS_POSITION, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_POSITION_STR, RWL, lPositionArray[0], lPositionArray[0], &lPositionArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ROTATION for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_WIDTH
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_HEIGHT
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MAX_WIDTH
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MAX_HEIGHT
+ //
+ // This sample driver supports a fixed/predefined graphics size that match the sample imprinter/endorser test image
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_WIDTH, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_WIDTH_STR, RN, IMPRINTER_MIN_WIDTH);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_WIDTH for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MAX_WIDTH, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MAX_WIDTH_STR, RN, IMPRINTER_MAX_WIDTH);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_WIDTH for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_HEIGHT, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_HEIGHT_STR, RN, IMPRINTER_MIN_HEIGHT);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MIN_HEIGHT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MAX_HEIGHT, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MAX_HEIGHT_STR, RN, IMPRINTER_MAX_HEIGHT);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_GRAPHICS_MAX_HEIGHT for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_MAX_GRAPHICS
+ //
+ // This sample driver pretends to support a maximum number of graphics of 1 for its imprinter and endorser.
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_PRINTER_ENDORSER_MAX_GRAPHICS, WIA_IPS_PRINTER_ENDORSER_MAX_GRAPHICS_STR, RN, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_MAX_GRAPHICS for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS_UPLOAD
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_GRAPHICS_UPLOAD, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_UPLOAD_STR, RN, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_GRAPHICS_UPLOAD for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPS_PRINTER_ENDORSER_GRAPHICS_DOWNLOAD
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddProperty(WIA_IPS_PRINTER_ENDORSER_GRAPHICS_DOWNLOAD, WIA_IPS_PRINTER_ENDORSER_GRAPHICS_DOWNLOAD_STR, RN, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PRINTER_ENDORSER_GRAPHICS_DOWNLOAD for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_DATATYPE
+ //
+ // The sample driver supports 1-bpp BW graphics data for the imprinter and the endorser.
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lDataTypeArray;
+ lDataTypeArray.Append(WIA_DATA_DITHER);
+
+ hr = PropertyManager.AddProperty(WIA_IPA_DATATYPE, WIA_IPA_DATATYPE_STR, RWL, lDataTypeArray[0], lDataTypeArray[0], &lDataTypeArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_DATATYPE for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_DEPTH
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lDepthArray;
+ lDepthArray.Append(1);
+
+ hr = PropertyManager.AddProperty(WIA_IPA_DEPTH , WIA_IPA_DEPTH_STR, RWLC, lDepthArray[0], lDepthArray[0], &lDepthArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_DEPTH for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_CHANNELS_PER_PIXEL
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lChannelsPerPixel = 1;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_CHANNELS_PER_PIXEL, WIA_IPA_CHANNELS_PER_PIXEL_STR, RN, lChannelsPerPixel);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_CHANNELS_PER_PIXEL for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // WIA_IPA_BITS_PER_CHANNEL
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lBitsPerChannel = 1;
+
+ hr = PropertyManager.AddProperty(WIA_IPA_BITS_PER_CHANNEL, WIA_IPA_BITS_PER_CHANNEL_STR, RN, lBitsPerChannel);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPA_BITS_PER_CHANNEL for item %u, hr = 0x%08X", nDocumentHandlingSelect, hr));
+ }
+ }
+
+ //
+ // Apply the property changes to the current session's Application Item Tree:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA item properties for item %u, hr = 0x%08X",
+ nDocumentHandlingSelect, hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes the properties specific to the Barcode Reader item.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeBarcodeReaderProperties(
+ _In_ BYTE* pWiasContext)
+{
+ HRESULT hr = S_OK;
+ CWIAPropertyManager PropertyManager;
+
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializeBarcodeReaderProperties, invalid parameter, hr = 0x%08X", hr));
+ }
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // WIA_IPS_BARCODE_READER
+ //
+ // This sample driver pretends to support a barcode reader device installed on the front feeder side
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lBarcodeReaderArray;
+ lBarcodeReaderArray.Append(WIA_BARCODE_READER_DISABLED);
+ lBarcodeReaderArray.Append(WIA_BARCODE_READER_AUTO);
+ lBarcodeReaderArray.Append(WIA_BARCODE_READER_FEEDER_FRONT);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_BARCODE_READER, WIA_IPS_BARCODE_READER_STR, RWL, lBarcodeReaderArray[0], lBarcodeReaderArray[0], &lBarcodeReaderArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_BARCODE_READER, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_MAXIMUM_BARCODES_PER_PAGE
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_MAXIMUM_BARCODES_PER_PAGE, WIA_IPS_MAXIMUM_BARCODES_PER_PAGE_STR, RWR, 0, 0, 0, 10, 1);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MAXIMUM_BARCODES_PER_PAGE, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_BARCODE_SEARCH_DIRECTION
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lBarcodeSearchArray;
+ lBarcodeSearchArray.Append(WIA_BARCODE_AUTO_SEARCH);
+ lBarcodeSearchArray.Append(WIA_BARCODE_HORIZONTAL_SEARCH);
+ lBarcodeSearchArray.Append(WIA_BARCODE_VERTICAL_SEARCH);
+ lBarcodeSearchArray.Append(WIA_BARCODE_HORIZONTAL_VERTICAL_SEARCH);
+ lBarcodeSearchArray.Append(WIA_BARCODE_VERTICAL_HORIZONTAL_SEARCH);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_BARCODE_SEARCH_DIRECTION, WIA_IPS_BARCODE_SEARCH_DIRECTION_STR, RWL, lBarcodeSearchArray[0], lBarcodeSearchArray[0], &lBarcodeSearchArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_BARCODE_SEARCH_DIRECTION, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_MAXIMUM_BARCODE_SEARCH_RETRIES
+ //
+ // This sample driver pretends to support no retries (range containing only the value 0)
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_MAXIMUM_BARCODE_SEARCH_RETRIES, WIA_IPS_MAXIMUM_BARCODE_SEARCH_RETRIES_STR, RWR, 0, 0, 0, 0, 0);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MAXIMUM_BARCODE_SEARCH_RETRIES, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_BARCODE_SEARCH_TIMEOUT
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.AddPropertyUL(WIA_IPS_BARCODE_SEARCH_TIMEOUT, WIA_IPS_BARCODE_SEARCH_TIMEOUT_STR, RWR, 0, 0, 0, 100, 10);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_BARCODE_SEARCH_TIMEOUT, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_SUPPORTED_BARCODE_TYPES
+ //
+ // This sample driver pretends to support a multitude of barcode types. This driver
+ // ignores this setting when delivering its hard-coded sample barcodes but uses
+ // WIA_IPS_SUPPORTED_BARCODE_TYPES to validate WIA_IPS_ENABLED_BARCODE_TYPES
+ //
+ if (SUCCEEDED(hr))
+ {
+ ULONG ulBarcodeTypes = ARRAYSIZE(g_lSupportedBarcodeTypes);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_SUPPORTED_BARCODE_TYPES, WIA_IPS_SUPPORTED_BARCODE_TYPES_STR, RN, ulBarcodeTypes, (LONG *)&g_lSupportedBarcodeTypes[0]);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SUPPORTED_BARCODE_TYPES, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_ENABLED_BARCODE_TYPES
+ //
+ // By default when barcode detection is enabled there are 3 barcodes enabled, which
+ // happen to match the sample, hard-coded, barcode metadata for this driver
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lDefaultEnabledBarcodeTypes[] = { WIA_BARCODE_UPCA, WIA_BARCODE_CODABAR, WIA_BARCODE_CODE39_FULLASCII };
+ ULONG ulBarcodeTypes = ARRAYSIZE(lDefaultEnabledBarcodeTypes);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_ENABLED_BARCODE_TYPES, WIA_IPS_ENABLED_BARCODE_TYPES_STR, RW, ulBarcodeTypes, &lDefaultEnabledBarcodeTypes[0]);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ENABLED_BARCODE_TYPES, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Apply the property changes to the current session's Application Item Tree:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA item properties for the barcode reader item, hr = 0x%08X", hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes the properties specific to the Patch Code Reader item.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializePatchCodeReaderProperties(
+ _In_ BYTE* pWiasContext)
+{
+ HRESULT hr = S_OK;
+ CWIAPropertyManager PropertyManager;
+
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializePatchCodeReaderProperties, invalid parameter, hr = 0x%08X", hr));
+ }
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // WIA_IPS_PATCH_CODE_READER
+ //
+ // This sample driver pretends to support a patch code reader device installed
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lPatchCodeReaderArray;
+ lPatchCodeReaderArray.Append(WIA_PATCH_CODE_READER_DISABLED);
+ lPatchCodeReaderArray.Append(WIA_PATCH_CODE_READER_AUTO);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_PATCH_CODE_READER, WIA_IPS_PATCH_CODE_READER_STR, RWL, lPatchCodeReaderArray[0], lPatchCodeReaderArray[0], &lPatchCodeReaderArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_PATCH_CODE_READER, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_SUPPORTED_PATCH_CODE_TYPES
+ //
+ // This sample driver pretends to support a multitude of barcode types. This driver
+ // ignores this setting when delivering its hard-coded sample barcodes but uses
+ // WIA_IPS_SUPPORTED_PATCH_CODE_TYPES to validate WIA_IPS_ENABLED_PATCH_CODE_TYPES
+ //
+ if (SUCCEEDED(hr))
+ {
+ ULONG ulPatchCodeTypes = ARRAYSIZE(g_lSupportedPatchCodeTypes);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_SUPPORTED_PATCH_CODE_TYPES, WIA_IPS_SUPPORTED_PATCH_CODE_TYPES_STR, RN, ulPatchCodeTypes, (LONG *)&g_lSupportedPatchCodeTypes[0]);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_SUPPORTED_PATCH_CODE_TYPES, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_ENABLED_PATCH_CODE_TYPES
+ //
+ // By default when barcode detection is enabled there are 2 patch codes enabled, which
+ // happen to match the sample, hard-coded, patch code metadata for this driver
+ //
+ if (SUCCEEDED(hr))
+ {
+ LONG lDefaultEnabledPatchCodeTypes[] = { WIA_PATCH_CODE_2, WIA_PATCH_CODE_3 };
+ ULONG ulPatchCodeTypes = ARRAYSIZE(lDefaultEnabledPatchCodeTypes);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_ENABLED_PATCH_CODE_TYPES, WIA_IPS_ENABLED_PATCH_CODE_TYPES_STR, RW, ulPatchCodeTypes, &lDefaultEnabledPatchCodeTypes[0]);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ENABLED_PATCH_CODE_TYPES, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // WIA_IPS_ALARM
+ //
+ // This sample driver does pretend to support one kind of audible alarm (beep) to signal
+ // when a path code is successfully detected
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lAlarmArray;
+ lAlarmArray.Append(WIA_ALARM_NONE);
+ lAlarmArray.Append(WIA_ALARM_BEEP1);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_ALARM, WIA_IPS_ALARM_STR, RWL, lAlarmArray[0], lAlarmArray[0], &lAlarmArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_ALARM, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Apply the property changes to the current session's Application Item Tree:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA item properties for the patch code reader item, hr = 0x%08X", hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes the properties specific to the MICR Reader item.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeMicrReaderProperties(
+ _In_ BYTE* pWiasContext)
+{
+ HRESULT hr = S_OK;
+ CWIAPropertyManager PropertyManager;
+
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::InitializeMicrReaderProperties, invalid parameter, hr = 0x%08X", hr));
+ }
+
+ WIAEX_TRACE_BEGIN;
+
+ //
+ // WIA_IPS_MICR_READER
+ //
+ // This sample driver pretends to support a MICR reader device installed on the front feeder side
+ //
+ if (SUCCEEDED(hr))
+ {
+ CBasicDynamicArray<LONG> lMICRReaderArray;
+ lMICRReaderArray.Append(WIA_MICR_READER_DISABLED);
+ lMICRReaderArray.Append(WIA_MICR_READER_AUTO);
+ lMICRReaderArray.Append(WIA_MICR_READER_FEEDER_FRONT);
+
+ hr = PropertyManager.AddProperty(WIA_IPS_MICR_READER, WIA_IPS_MICR_READER_STR, RWL, lMICRReaderArray[0], lMICRReaderArray[0], &lMICRReaderArray);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to initialize WIA_IPS_MICR_READER, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Apply the property changes to the current session's Application Item Tree:
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = PropertyManager.SetItemProperties(pWiasContext);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "CWIAPropertyManager::SetItemProperties failed to set WIA item properties for the MICR reader item, hr = 0x%08X", hr));
+ }
+ }
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Initializes WIA_FORMAT_INFO arrays needed for IWiaMiniDrv::drvGetWiaFormatInfo
+*
+* Parameters:
+*
+* None
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::InitializeFormatInfoArrays()
+{
+ HRESULT hr = S_OK;
+ WIA_FORMAT_INFO tFormatInfo = {};
+
+ //
+ // This sample driver supports the same WIA_FORMAT_INFO array for Root, Flatbed, Feeder and Auto items:
+ //
+ // { WiaImgFmt_BMP, TYMED_FILE }
+ // { WiaImgFmt_EXIF, TYMED_FILE }
+ // { WiaImgFmt_RAW, TYMED_FILE }
+ //
+
+ m_tFormatInfo.Destroy();
+
+ tFormatInfo.guidFormatID = WiaImgFmt_BMP;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfo.Append(tFormatInfo);
+
+ tFormatInfo.guidFormatID = WiaImgFmt_EXIF;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfo.Append(tFormatInfo);
+
+ tFormatInfo.guidFormatID = WiaImgFmt_RAW;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfo.Append(tFormatInfo);
+
+ //
+ // The Imprinter and Endorser items support:
+ //
+ // { WiaImgFmt_CSV, TYMED_FILE }
+ // { WiaImgFmt_TXT, TYMED_FILE }
+ // { WiaImgFmt_BMP, TYMED_FILE }
+ //
+
+ m_tFormatInfoImprinterEndorser.Destroy();
+
+ tFormatInfo.guidFormatID = WiaImgFmt_CSV;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoImprinterEndorser.Append(tFormatInfo);
+
+ tFormatInfo.guidFormatID = WiaImgFmt_TXT;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoImprinterEndorser.Append(tFormatInfo);
+
+ tFormatInfo.guidFormatID = WiaImgFmt_BMP;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoImprinterEndorser.Append(tFormatInfo);
+
+ //
+ // The Barcode Reader item supports:
+ //
+ // { WiaImgFmt_XMLBAR, TYMED_FILE }
+ // { WiaImgFmt_RAWBAR, TYMED_FILE }
+ //
+
+ m_tFormatInfoBarcodeReader.Destroy();
+
+ tFormatInfo.guidFormatID = WiaImgFmt_XMLBAR;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoBarcodeReader.Append(tFormatInfo);
+
+ tFormatInfo.guidFormatID = WiaImgFmt_RAWBAR;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoBarcodeReader.Append(tFormatInfo);
+
+ //
+ // The Patch Code Reader item supports:
+ //
+ // { WiaImgFmt_XMLPAT, TYMED_FILE }
+ // { WiaImgFmt_RAWPAT, TYMED_FILE }
+ //
+
+ m_tFormatInfoPatchCodeReader.Destroy();
+
+ tFormatInfo.guidFormatID = WiaImgFmt_XMLPAT;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoPatchCodeReader.Append(tFormatInfo);
+
+ tFormatInfo.guidFormatID = WiaImgFmt_RAWPAT;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoPatchCodeReader.Append(tFormatInfo);
+
+ //
+ // The MICR Reader item supports:
+ //
+ // { WiaImgFmt_XMLMIC, TYMED_FILE }
+ // { WiaImgFmt_RAWMIC, TYMED_FILE }
+ //
+
+ m_tFormatInfoMicrReader.Destroy();
+
+ tFormatInfo.guidFormatID = WiaImgFmt_XMLMIC;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoMicrReader.Append(tFormatInfo);
+
+ tFormatInfo.guidFormatID = WiaImgFmt_RAWMIC;
+ tFormatInfo.lTymed = TYMED_FILE;
+ m_tFormatInfoMicrReader.Append(tFormatInfo);
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Updates the following image information properties in auto-detect color mode.
+* Because this sample driver does not support cropping (scan region changes)
+* and supports only a single/fixed scan resolution this function is not needed
+* to be executed in other situations:
+*
+* WIA_IPA_PIXELS_PER_LINE
+* WIA_IPA_NUMBER_OF_LINES
+* WIA_IPA_BYTES_PER_LINE
+* WIA_IPA_CHANNELS_PER_PIXEL
+* WIA_IPA_RAW_CHANNELS_PER_PIXEL
+*
+* Note that these properties are not implemented/available on the Auto item.
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+* lDataType - data type; if set to WIA_DATA_AUTO the
+* function reads the current WIA_IPA_DATATYPE.
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+HRESULT CWiaDriver::UpdateImageInfoProperties(
+ _In_ BYTE *pWiasContext,
+ LONG lDataType)
+{
+ HRESULT hr = S_OK;
+ GUID guidItemCategory = WIA_CATEGORY_ROOT;
+ LONG lDepth = 8;
+ LONG lChannelsPerPixel = 1;
+ LONG lCompression = WIA_COMPRESSION_NONE;
+ GUID guidFormat = WiaImgFmt_UNDEFINED;
+ LONG lXExtent = 0;
+ LONG lYExtent = 0;
+ LONG lPixelsPerLine = 0;
+ LONG lNumberOfLines = 0;
+ LONG lBytesPerLine = 0;
+
+ WIAEX_TRACE_BEGIN;
+
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "CWiaDriver::UpdateImageInfoProperties, invalid parameter, hr = 0x%08X", hr));
+ }
+
+ //
+ // Read WIA_IPA_ITEM_CATEGORY to identify the current item:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasReadPropGuid(pWiasContext, WIA_IPA_ITEM_CATEGORY, &guidItemCategory, NULL, TRUE);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_ITEM_CATEGORY, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Cannot validate image information properties on the Root or Auto items:
+ //
+ if (SUCCEEDED(hr) && ((IsEqualGUID(WIA_CATEGORY_ROOT, guidItemCategory)) ||
+ (IsEqualGUID(WIA_CATEGORY_AUTO, guidItemCategory))))
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "Functionality not supported on this item, hr = 0x%08X", hr));
+ }
+
+ //
+ // If a data type is not specified, read WIA_IPA_DATATYPE:
+ //
+ if (SUCCEEDED(hr))
+ {
+ if (WIA_DATA_AUTO == lDataType)
+ {
+ LONG lActualDataType = WIA_DATA_GRAYSCALE;
+
+ hr = wiasReadPropLong(pWiasContext, WIA_IPA_DATATYPE, &lActualDataType, NULL, TRUE);
+ if (SUCCEEDED(hr))
+ {
+ if (WIA_DATA_AUTO == lActualDataType)
+ {
+ WIAEX_ERROR((g_hInst, "Unspecified data type! Considering 8-bpp grayscale (default) and trying to continue"));
+ lDepth = 8;
+ }
+ else
+ {
+ lDepth = (WIA_DATA_COLOR == lActualDataType) ? 24 : 8;
+ }
+ }
+ else
+ {
+ WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_DATA_TYPE, hr = 0x%08X", hr));
+ }
+ }
+ else
+ {
+ lDepth = (WIA_DATA_COLOR == lDataType) ? 24 : 8;
+ }
+ }
+
+ //
+ // Check the current WIA_IPA_COMPRESSION:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasReadPropLong(pWiasContext, WIA_IPA_COMPRESSION, &lCompression, NULL, TRUE);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_COMPRESSION, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Check the current WIA_IPA_FORMAT:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormat, NULL, TRUE);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_FORMAT, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Check the current WIA_IPS_XEXTENT and WIA_IPS_YTEXTENT:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasReadPropLong(pWiasContext, WIA_IPS_XEXTENT, &lXExtent, NULL, TRUE);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Error reading current WIA_IPS_XEXTENT, hr = 0x%08X", hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasReadPropLong(pWiasContext, WIA_IPS_YEXTENT, &lYExtent, NULL, TRUE);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Error reading current WIA_IPS_YEXTENT, hr = 0x%08X", hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ //
+ // The number of bytes per line include the padding necessary to make each uncompressed
+ // line (DIB or Raw) DWORD aligned. When data is compressed the number of bytes per line
+ // calculated here reflects the original uncompressed image:
+ //
+ lPixelsPerLine = lXExtent;
+ lNumberOfLines = lYExtent;
+ lBytesPerLine = BytesPerLine(lPixelsPerLine, lDepth);
+
+ WIAS_TRACE((g_hInst, "Image information: %u PPL, %u lines, %u BPL (compression: %u)",
+ lPixelsPerLine, lNumberOfLines, lBytesPerLine, lCompression));
+ }
+
+ //
+ // Update the following properties, supported for backwards compatibility (with WIA 1.0
+ // and TWAIN) on the Flatbed and Feeder item but not on the new Auto item:
+ //
+ // WIA_IPA_PIXELS_PER_LINE - the image width, in pixels, for the final image
+ // WIA_IPA_NUMBER_OF_LINES - the image length, in pixels, for the final image
+ // WIA_IPA_BYTES_PER_LINE - line width in bytes that must match WIA_IPA_PIXELS_PER_LINE and WIA_IPA_DEPTH
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasWritePropLong(pWiasContext, WIA_IPA_PIXELS_PER_LINE, lPixelsPerLine);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_PIXELS_PER_LINE, hr = 0x%08X", hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasWritePropLong(pWiasContext, WIA_IPA_NUMBER_OF_LINES, lNumberOfLines);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_NUMBER_OF_LINES, hr = 0x%08X", hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasWritePropLong(pWiasContext, WIA_IPA_BYTES_PER_LINE, lBytesPerLine);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_BYTES_PER_LINE, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Update WIA_IPA_CHANNELS_PER_PIXEL and WIA_IPA_RAW_BITS_PER_CHANNEL top match the bit depth.
+ // Note that this saple driver does not need to update WIA_IPA_BITS_PER_CHANNEL, and that
+ // WIA_IPA_DEPTH and WIA_IPA_DATA_TYPE are updated during validation (see ValidateFormatProperties):
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ lChannelsPerPixel = (24 == lDepth) ? 3 : 1;
+ hr = wiasWritePropLong(pWiasContext, WIA_IPA_CHANNELS_PER_PIXEL, lChannelsPerPixel);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_CHANNELS_PER_PIXEL, hr = 0x%08X", hr));
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ BYTE bRawBitsPerChannel[3] = {};
+
+ for (int i = 0; i < lChannelsPerPixel; i++)
+ {
+ bRawBitsPerChannel[i] = 8;
+ }
+
+ hr = wiasWritePropBin(pWiasContext, WIA_IPA_RAW_BITS_PER_CHANNEL, lChannelsPerPixel, bRawBitsPerChannel);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_RAW_BITS_PER_CHANNEL, hr = 0x%08X", hr));
+ }
+ }
+
+
+ WIAEX_TRACE_FUNC_HR;
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Updates the globally stored (per driver instance) scan available item
+* name indicating that this item is marked for data transfer due to a
+* device initiated scan operation, and/or the scanner is not in a scan
+* available state.
+*
+* Parameters:
+*
+* wszInputSource - a WIA item name as the name of the input source,
+* NULL to reset the value to an empty string.
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+HRESULT CWiaDriver::UpdateScanAvailableItemName(
+ _In_opt_ LPCWSTR wszInputSource)
+{
+ HRESULT hr = S_OK;
+
+ //
+ // Clear the current name:
+ //
+ if (m_bstrScanAvailableItem)
+ {
+ SysFreeString(m_bstrScanAvailableItem);
+ m_bstrScanAvailableItem = NULL;
+ }
+
+ //
+ // Identify the input source and prepare the value containing the apropriate item name:
+ //
+ if (wszInputSource)
+ {
+ if (!wcscmp(WIA_DRIVER_FEEDER_NAME, wszInputSource))
+ {
+ WIAS_TRACE((g_hInst, "Scan available from feeder (%ws)", wszInputSource));
+ m_bstrScanAvailableItem = SysAllocString(WIA_DRIVER_FEEDER_NAME);
+ }
+ else if (!wcscmp(WIA_DRIVER_FLATBED_NAME, wszInputSource))
+ {
+ WIAS_TRACE((g_hInst, "Scan available from flatbed (%ws)", wszInputSource));
+ m_bstrScanAvailableItem = SysAllocString(WIA_DRIVER_FLATBED_NAME);
+ }
+ else
+ {
+ WIAS_TRACE((g_hInst, "Scan available from unknown input source (%ws) - information not recorded",
+ wszInputSource));
+ m_bstrScanAvailableItem = SysAllocString(L"");
+ }
+ }
+ else
+ {
+ //
+ // A trace message is avoided here on purpose - the following message, if enabled,
+ // would be visible both when initializing a new AIT Root with no scan available
+ // input source recorded -and- when resetting the scan available soure information
+ // from within IWiaMiniDrv::drvAcquireItemData before executing a new scan job.
+ //
+ m_bstrScanAvailableItem = SysAllocString(L"");
+ }
+
+ if (!m_bstrScanAvailableItem)
+ {
+ hr = E_OUTOFMEMORY;
+ WIAEX_ERROR((g_hInst, "Failed to update the scan available item name, out of memory, hr = 0x%08X", hr));
+ }
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Updates the WIA_DPS_SCAN_AVAILABLE_ITEM property at real-time when an
+* application attempts to read a property from its AIT Root item. We cannot
+* make this update immediately following a notification that a device initiated
+* scan is available because the event comes globally, outside of any application
+* session context (possibly at a time when no application session exists).
+*
+* WARNING: must not be called on other items than Root (WiaItemTypeRoot).
+*
+* Parameters:
+*
+* pWiasContext - pointer to the item context
+*
+* Return Value:
+*
+* S_OK if successful, an error HRESULT otherwise
+*
+\**************************************************************************/
+HRESULT CWiaDriver::UpdateScanAvailableItemProperty(
+ _In_ BYTE *pWiasContext)
+{
+ HRESULT hr = S_OK;
+
+ if (!pWiasContext)
+ {
+ hr = E_INVALIDARG;
+ WIAEX_ERROR((g_hInst, "Invalid parameter, hr = 0x%08X", hr));
+ }
+
+ //
+ // If no value is initialized yet, initialize it now to an
+ // empty string meaning "no scan available source recorded":
+ //
+ if (SUCCEEDED(hr) && (!m_bstrScanAvailableItem))
+ {
+ m_bstrScanAvailableItem = SysAllocString(L"");
+ if (!m_bstrScanAvailableItem)
+ {
+ hr = E_OUTOFMEMORY;
+ WIAEX_ERROR((g_hInst, "Failed to initialize an empty string in lieu of a scan available item name, hr = 0x%08X", hr));
+ }
+ }
+
+ //
+ // Update the WIA_DPS_SCAN_AVAILABLE_ITEM property:
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = wiasWritePropStr(pWiasContext, WIA_DPS_SCAN_AVAILABLE_ITEM, m_bstrScanAvailableItem);
+ if (FAILED(hr))
+ {
+ WIAEX_ERROR((g_hInst, "wiasWritePropStr(WIA_DPS_SCAN_AVAILABLE_ITEM, '%ws') failed, hr = 0x%08X", m_bstrScanAvailableItem, hr));
+ }
+ }
+
+ return hr;
+}
+
+/**************************************************************************\
+*
+* Retrieves standard WIA page sizes that fit in the specified scan area
+* dimensions considering the specified orientation.
+*
+* Parameters:
+*
+* lMaxWidth - maximum width of the total scan area, in 1/1000"
+* lMaxHeight - maximum height of the total scan area, in 1/1000"
+* lMinWidth - minimum width of the total scan area, in 1/1000"
+* lMinHeight - minimum height of the total scan area, in 1/1000"
+* bPortrait - TRUE for portrait, FALSE for landscape orientation
+* arrayPageSizes - reference for array where to return page sizes
+*
+* Return Value:
+*
+* The number of page sizes found
+*
+\**************************************************************************/
+
+LONG CWiaDriver::GetValidPageSizes(
+ LONG lMaxWidth,
+ LONG lMaxHeight,
+ LONG lMinWidth,
+ LONG lMinHeight,
+ BOOL bPortrait,
+ CBasicDynamicArray<LONG>& arrayPageSizes)
+{
+ LONG lNumPageSizesFound = 0;
+ LONG lNumKnownPageSizes = sizeof(g_DefinedPageSizeCombinations) / sizeof(g_DefinedPageSizeCombinations[0]);
+
+ //
+ // Do not erase page sizes already added to the array,
+ // append new values that are not yet in the array:
+ //
+ // arrayPageSizes.Destroy();
+ //
+
+ for (LONG i = 0; i < lNumKnownPageSizes; i++)
+ {
+ if (bPortrait)
+ {
+ if ((g_DefinedPageSizeCombinations[i].m_lPageWidth <= lMaxWidth) &&
+ (g_DefinedPageSizeCombinations[i].m_lPageHeight <= lMaxHeight) &&
+ (g_DefinedPageSizeCombinations[i].m_lPageWidth >= lMinWidth) &&
+ (g_DefinedPageSizeCombinations[i].m_lPageHeight >= lMinHeight))
+ {
+ if (-1 == arrayPageSizes.Find(g_DefinedPageSizeCombinations[i].m_lPageSize))
+ {
+ arrayPageSizes.Append(g_DefinedPageSizeCombinations[i].m_lPageSize);
+ }
+ }
+ }
+ else
+ {
+ if ((g_DefinedPageSizeCombinations[i].m_lPageWidth <= lMaxHeight) &&
+ (g_DefinedPageSizeCombinations[i].m_lPageHeight <= lMaxWidth) &&
+ (g_DefinedPageSizeCombinations[i].m_lPageWidth >= lMinHeight) &&
+ (g_DefinedPageSizeCombinations[i].m_lPageHeight >= lMinWidth))
+ {
+ if (-1 == arrayPageSizes.Find(g_DefinedPageSizeCombinations[i].m_lPageSize))
+ {
+ arrayPageSizes.Append(g_DefinedPageSizeCombinations[i].m_lPageSize);
+ }
+ }
+ }
+ }
+
+ lNumPageSizesFound = arrayPageSizes.Size();
+
+ return lNumPageSizesFound;
+}
+
+/**************************************************************************\
+*
+* Returns the width and height for the specified standard page size,
+* in 1/1000", according with the indicated orientation
+*
+* Parameters:
+*
+* lPageSize - the page size to return the dimensions for
+* bPortrait - TRUE for portait orientation, FALSE for landscape
+* lPageWidth - reference for variable to receive the page width
+* lPageHeight - reference for variable to receive the page height
+* Return Value:
+*
+* S_OK if successful, E_INVALIDARG if no such standard page size is found
+*
+\**************************************************************************/
+
+HRESULT CWiaDriver::GetPageDimensions(
+ LONG lPageSize,
+ BOOL bPortrait,
+ LONG& lPageWidth,
+ LONG& lPageHeight)
+{
+ HRESULT hr = E_INVALIDARG;
+ LONG lNumKnownPageSizes = sizeof(g_DefinedPageSizeCombinations) / sizeof(g_DefinedPageSizeCombinations[0]);
+
+ for (LONG i = 0; i < lNumKnownPageSizes; i++)
+ {
+ if (g_DefinedPageSizeCombinations[i].m_lPageSize == lPageSize)
+ {
+ if (bPortrait)
+ {
+ lPageWidth = g_DefinedPageSizeCombinations[i].m_lPageWidth;
+ lPageHeight = g_DefinedPageSizeCombinations[i].m_lPageHeight;
+ }
+ else
+ {
+ lPageWidth = g_DefinedPageSizeCombinations[i].m_lPageHeight;
+ lPageHeight = g_DefinedPageSizeCombinations[i].m_lPageWidth;
+ }
+
+ hr = S_OK;
+ break;
+ }
+ }
+
+ return hr;
+}