/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORP., 2000 * * TITLE: validate.cpp * * VERSION: 1.0 * * DATE: 17 July, 2000 * * DESCRIPTION: * *******************************************************************************/ #include "pch.h" extern HINSTANCE g_hInst; // used for WIAS_LOGPROC macro /**************************************************************************\ * ValidateDataTransferContext * * Checks the data transfer context to ensure it's valid. * * Arguments: * * pDataTransferContext - Pointer the data transfer context. * * Return Value: * * Status * * History: * * 7/18/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::ValidateDataTransferContext( PMINIDRV_TRANSFER_CONTEXT pDataTransferContext) { CWiaLogProc WIAS_LOGPROC(m_pIWiaLog, WIALOG_NO_RESOURCE_ID, WIALOG_LEVEL3, "::ValidateDataTransferContext"); if (pDataTransferContext->lSize != sizeof(MINIDRV_TRANSFER_CONTEXT)) { WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ValidateDataTransferContext, invalid data transfer context")); return E_INVALIDARG;; } // // for TYMED file, only WiaImgFmt_BMP is allowed by this driver // if (pDataTransferContext->tymed == TYMED_FILE) { if (pDataTransferContext->guidFormatID != WiaImgFmt_BMP) { if (pDataTransferContext->guidFormatID != WiaImgFmt_TIFF) { WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ValidateDataTransferContext, invalid format for TYMED_FILE")); return E_INVALIDARG; } } } // // for TYMED CALLBACK, only WiaImgFmt_MEMORYBMP is allowed by this driver // if (pDataTransferContext->tymed == TYMED_CALLBACK) { if (pDataTransferContext->guidFormatID != WiaImgFmt_MEMORYBMP) { WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ValidateDataTransferContext, invalid format for TYMED_CALLBACK")); return E_INVALIDARG;; } } return S_OK; } /**************************************************************************\ * UpdateValidDepth * * Helper that updates the valid value for depth based on the data type. * * Arguments: * * pWiasContext - a pointer to the WiaItem context * lDataType - the value of the DataType property. * lDepth - the address of the variable where the Depth's new value * will be returned. * * Return Value: * * Status - S_OK if successful * E_INVALIDARG if lDataType is unknown * Errors are those returned by wiasReadPropLong, * and wiasWritePropLong. * * History: * * 7/18/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::UpdateValidDepth( BYTE *pWiasContext, LONG lDataType, LONG *lDepth) { CWiaLogProc WIAS_LOGPROC(m_pIWiaLog, WIALOG_NO_RESOURCE_ID, WIALOG_LEVEL3, "CWIAScannerDevice::UpdateValidDepth"); HRESULT hr = S_OK; LONG pValidDepth[1]; switch (lDataType) { case WIA_DATA_THRESHOLD: pValidDepth[0] = 1; break; case WIA_DATA_GRAYSCALE: pValidDepth[0] = 8; break; case WIA_DATA_COLOR: pValidDepth[0] = 24; break; default: WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("UpdateValidDepth, unknown data type")); return E_INVALIDARG; } if (lDepth) { *lDepth = pValidDepth[0]; } return hr; } /**************************************************************************\ * CheckDataType * * This helper method is called to check whether WIA_IPA_DATATYPE * property is changed. When this property changes, other dependant * properties and their valid values must also be changed. * * Arguments: * * pWiasContext - a pointer to the item context whose properties have * changed. * pContext - a pointer to the property context (which indicates * which properties are being written). * * Return Value: * * Status * * History: * * 7/18/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::CheckDataType( BYTE *pWiasContext, WIA_PROPERTY_CONTEXT *pContext) { CWiaLogProc WIAS_LOGPROC(m_pIWiaLog, WIALOG_NO_RESOURCE_ID, WIALOG_LEVEL3, "CWIAScannerDevice::CheckDataType"); WIAS_CHANGED_VALUE_INFO cviDataType, cviDepth; HRESULT hr = S_OK; // // Call wiasGetChangedValue for DataType. It is checked first since it's // not dependant on any other property. All properties in this method // that follow are dependant properties of DataType. // // The call to wiasGetChangedValue specifies that validation should not be // skipped (since valid values for DataType never change). Also, // the address of a variable for the old value is NULL, since the old // value is not needed. The address of bDataTypeChanged is passed // so that dependant properties will know whether the DataType is being // changed or not. This is important since dependant properties may need // their valid values updated and may need to be folded to new valid // values. // hr = wiasGetChangedValueLong(pWiasContext, pContext, FALSE, WIA_IPA_DATATYPE, &cviDataType); if (FAILED(hr)) { return hr; } // // Call wiasGetChangedValue for Depth. Depth is a dependant property of // DataType whose valid value changes according to what the current // value of DataType is. // // The call to wiasGetChangedValue specifies that validation should only // be skipped if the DataType has changed. This is because the valid // values for Depth will change according to the new value for // DataType. The address of a variable for the old value is NULL, since // the old value is not needed. The address of bDepthChanged is passed // so that dependant properties will know whether the Depth is being // changed or not. This is important since dependant properties may need // their valid values updated and may need to be folded to new valid // values. // hr = wiasGetChangedValueLong(pWiasContext, pContext, cviDataType.bChanged, WIA_IPA_DEPTH, &cviDepth); if (FAILED(hr)) { return hr; } if (cviDataType.bChanged) { // // DataType changed so update valid value for Depth // hr = UpdateValidDepth(pWiasContext, cviDataType.Current.lVal, &cviDepth.Current.lVal); if (SUCCEEDED(hr)) { // // Check whether we must fold. Depth will only be folded if it // is not one of the properties that the app is changing. // if (!cviDepth.bChanged) { hr = wiasWritePropLong(pWiasContext, WIA_IPA_DEPTH, cviDepth.Current.lVal); } } } // // Update properties dependant on DataType and Depth. // Here, ChannelsPerPixel and BitsPerChannel are updated. // if (cviDataType.bChanged || cviDepth.bChanged) { if (SUCCEEDED(hr)) { #define NUM_PROPS_TO_SET 2 PROPSPEC ps[NUM_PROPS_TO_SET] = { {PRSPEC_PROPID, WIA_IPA_CHANNELS_PER_PIXEL}, {PRSPEC_PROPID, WIA_IPA_BITS_PER_CHANNEL}}; PROPVARIANT pv[NUM_PROPS_TO_SET]; for (LONG index = 0; index < NUM_PROPS_TO_SET; index++) { PropVariantInit(&pv[index]); pv[index].vt = VT_I4; } switch (cviDataType.Current.lVal) { case WIA_DATA_THRESHOLD: pv[0].lVal = 1; pv[1].lVal = 1; break; case WIA_DATA_GRAYSCALE: pv[0].lVal = 1; pv[1].lVal = 8; break; case WIA_DATA_COLOR: pv[0].lVal = 3; pv[1].lVal = 8; break; default: pv[0].lVal = 1; pv[1].lVal = 8; break; } hr = wiasWriteMultiple(pWiasContext, NUM_PROPS_TO_SET, ps, pv); } } return hr; } /**************************************************************************\ * CheckIntent * * This helper method is called to make the relevant changes if the * Current Intent property changes. * * Arguments: * * pWiasContext - a pointer to the item context whose properties have * changed. * pContext - a pointer to the property context (which indicates * which properties are being written). * * Return Value: * * Status * * History: * * 7/18/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::CheckIntent( BYTE *pWiasContext, WIA_PROPERTY_CONTEXT *pContext) { CWiaLogProc WIAS_LOGPROC(m_pIWiaLog, WIALOG_NO_RESOURCE_ID, WIALOG_LEVEL3, "CWIAScannerDevice::CheckIntent"); HRESULT hr; WIAS_CHANGED_VALUE_INFO cviIntent; // // Call wiasGetChangedValue for CurrentIntent. CurrentIntent is checked first // since it's not dependant on any other property. All properties in // this method that follow are dependant properties of CurrentIntent. // // The call to wiasGetChangedValue specifies that validation should not be // skipped (since valid values for CurrentIntent never change). The // address of the old value is specified as NULL, since it is not used. // The address of bIntentChanged is passed so that dependant properties // will know whether the YResolution is being changed or not. This is // important since dependant properties will need their valid values // updated and may need to be folded to new valid values. // hr = wiasGetChangedValueLong(pWiasContext, pContext, FALSE, WIA_IPS_CUR_INTENT, &cviIntent); if (SUCCEEDED(hr)) { if (cviIntent.bChanged) { LONG lImageSizeIntent = (cviIntent.Current.lVal & WIA_INTENT_SIZE_MASK); LONG lImageTypeIntent = (cviIntent.Current.lVal & WIA_INTENT_IMAGE_TYPE_MASK); switch (lImageTypeIntent) { case WIA_INTENT_NONE: break; case WIA_INTENT_IMAGE_TYPE_GRAYSCALE: wiasWritePropLong(pWiasContext, WIA_IPA_DATATYPE, WIA_DATA_GRAYSCALE); UpdateValidDepth (pWiasContext, WIA_DATA_GRAYSCALE, NULL); wiasWritePropLong(pWiasContext, WIA_IPA_DEPTH, 8); break; case WIA_INTENT_IMAGE_TYPE_TEXT: wiasWritePropLong(pWiasContext, WIA_IPA_DATATYPE, WIA_DATA_THRESHOLD); UpdateValidDepth (pWiasContext, WIA_DATA_THRESHOLD, NULL); wiasWritePropLong(pWiasContext, WIA_IPA_DEPTH, 1); break; case WIA_INTENT_IMAGE_TYPE_COLOR: wiasWritePropLong(pWiasContext, WIA_IPA_DATATYPE, WIA_DATA_COLOR); UpdateValidDepth(pWiasContext, WIA_DATA_COLOR, NULL); wiasWritePropLong(pWiasContext, WIA_IPA_DEPTH, 24); break; default: WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CheckIntent, unknown intent (TYPE) = %d",lImageTypeIntent)); return E_INVALIDARG; } switch (lImageSizeIntent) { case WIA_INTENT_NONE: break; case WIA_INTENT_MINIMIZE_SIZE: case WIA_INTENT_MAXIMIZE_QUALITY: { // // Set the X and Y Resolutions. // wiasWritePropLong(pWiasContext, WIA_IPS_XRES, lImageSizeIntent & WIA_INTENT_MINIMIZE_SIZE ? 150 : 300); wiasWritePropLong(pWiasContext, WIA_IPS_YRES, lImageSizeIntent & WIA_INTENT_MINIMIZE_SIZE ? 150 : 300); // // The Resolutions and DataType were set, so update the property // context to indicate that they have changed. // wiasSetPropChanged(WIA_IPS_XRES, pContext, TRUE); wiasSetPropChanged(WIA_IPS_YRES, pContext, TRUE); wiasSetPropChanged(WIA_IPA_DATATYPE, pContext, TRUE); } break; default: WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CheckIntent, unknown intent (SIZE) = %d",lImageSizeIntent)); return E_INVALIDARG; } } } else { WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CheckIntent, wiasGetChangedValue (intent) failed")); } return hr; } /**************************************************************************\ * CheckPreferredFormat * * This helper method is called to make the relevant changes if the * Format property changes. * * Arguments: * * pWiasContext - a pointer to the item context whose properties have * changed. * pContext - a pointer to the property context (which indicates * which properties are being written). * * Return Value: * * Status * * History: * * 7/18/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::CheckPreferredFormat( BYTE *pWiasContext, WIA_PROPERTY_CONTEXT *pContext) { HRESULT hr = S_OK; // // update WIA_IPA_PREFERRED_FORMAT property // GUID FormatGUID; hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &FormatGUID, NULL, TRUE); if (SUCCEEDED(hr)) { hr = wiasWritePropGuid(pWiasContext, WIA_IPA_PREFERRED_FORMAT, FormatGUID); if (FAILED(hr)) { WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CheckPreferredFormat, could not write WIA_IPA_PREFERRED_FORMAT")); return hr; } } else { WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("CheckIntent, could not read WIA_IPA_FORMAT")); } return hr; } /**************************************************************************\ * CheckADFStatus * * * Arguments: * * pWiasContext - pointer to an Item. * * Return Value: * * Byte count. * * History: * * 7/18/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::CheckADFStatus(BYTE *pWiasContext, WIA_PROPERTY_CONTEXT *pContext) { CWiaLogProc WIAS_LOGPROC(m_pIWiaLog, WIALOG_NO_RESOURCE_ID, WIALOG_LEVEL3, "CWIAScannerDevice::CheckADFStatus"); if(!m_bADFAttached) return S_OK; HRESULT hr = S_OK; BYTE *pRootItemCtx = NULL; LONG lDocHandlingSelect = 0; hr = wiasGetRootItem(pWiasContext, &pRootItemCtx); if (FAILED(hr)) { return E_FAIL; } hr = wiasReadPropLong(pRootItemCtx, WIA_DPS_DOCUMENT_HANDLING_SELECT, &lDocHandlingSelect, NULL, FALSE); if(hr == S_FALSE){ lDocHandlingSelect = FEEDER; } if (SUCCEEDED(hr)) { switch (lDocHandlingSelect) { case FEEDER: m_bADFEnabled = TRUE; hr = S_OK; break; default: hr = E_INVALIDARG; return hr; break; } } // // update document handling status // if (m_bADFEnabled) { HRESULT Temphr = m_pScanAPI->FakeScanner_ADFAvailable(); if (S_OK == Temphr) { hr = wiasWritePropLong(pWiasContext, WIA_DPS_DOCUMENT_HANDLING_STATUS,FEED_READY); } else { hr = wiasWritePropLong(pWiasContext, WIA_DPS_DOCUMENT_HANDLING_STATUS,PAPER_JAM); } if (FAILED(Temphr)) hr = Temphr; } else { hr = wiasWritePropLong(pWiasContext, WIA_DPS_DOCUMENT_HANDLING_STATUS,FLAT_READY); } return hr; } /**************************************************************************\ * CheckPreview * * * Arguments: * * pWiasContext - pointer to an Item. * * Return Value: * * Byte count. * * History: * * 8/21/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::CheckPreview(BYTE *pWiasContext, WIA_PROPERTY_CONTEXT *pContext) { CWiaLogProc WIAS_LOGPROC(m_pIWiaLog, WIALOG_NO_RESOURCE_ID, WIALOG_LEVEL3, "CWIAScannerDevice::CheckPreview"); HRESULT hr = S_OK; BYTE *pRootItemCtx = NULL; LONG lPreview = 0; hr = wiasGetRootItem(pWiasContext, &pRootItemCtx); if (FAILED(hr)) { return E_FAIL; } hr = wiasReadPropLong(pRootItemCtx, WIA_DPS_PREVIEW, &lPreview, NULL, FALSE); if(hr == S_FALSE){ // property does not exist...so return S_OK return S_OK; } if (SUCCEEDED(hr)) { switch (lPreview) { case WIA_FINAL_SCAN: WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("CheckPreview, Set to WIA_FINAL_SCAN")); hr = S_OK; break; default: WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("CheckPreview, Set to invalid argument (%d)",lPreview)); hr = E_INVALIDARG; break; } } return hr; } /**************************************************************************\ * CheckXExtent * * * Arguments: * * pWiasContext - pointer to an Item. * * Return Value: * * Byte count. * * History: * * 8/21/2000 Original Version * \**************************************************************************/ HRESULT CWIAScannerDevice::CheckXExtent(BYTE *pWiasContext, WIA_PROPERTY_CONTEXT *pContext, LONG lWidth) { HRESULT hr = S_OK; CWiaLogProc WIAS_LOGPROC(m_pIWiaLog, WIALOG_NO_RESOURCE_ID, WIALOG_LEVEL3, "CheckXExtent"); LONG lMaxExtent; LONG lExt; WIAS_CHANGED_VALUE_INFO cviXRes, cviXExt; // // get x resolution changes // hr = wiasGetChangedValueLong(pWiasContext,pContext,FALSE,WIA_IPS_XRES,&cviXRes); if (FAILED(hr)) { return hr; } // // get x extent changes // hr = wiasGetChangedValueLong(pWiasContext,pContext,cviXRes.bChanged,WIA_IPS_XEXTENT,&cviXExt); if (FAILED(hr)) { return hr; } // // update extent // lMaxExtent = ((cviXRes.Current.lVal * lWidth) / 1000); // // Update read-only property : PIXELS_PER_LINE. The width in pixels // of the scanned image is the same size as the XExtent. // if (SUCCEEDED(hr)) { hr = wiasWritePropLong(pWiasContext, WIA_IPS_XEXTENT, lMaxExtent); hr = wiasWritePropLong(pWiasContext, WIA_IPA_PIXELS_PER_LINE, lMaxExtent); } return hr; }