2025-04-27 07:49:33 -04:00

3718 lines
125 KiB
C++

/***************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1999
*
* TITLE: MiniDrv.Cpp
*
* VERSION: 3.0
*
* DATE: 18 Nov, 1999
*
* DESCRIPTION:
* Implementation of the WIA test scanner methods.
*
****************************************************************************/
#include <stdio.h>
#include <tchar.h>
#include <objbase.h>
#include <sti.h>
#include <assert.h>
#include "resource.h"
#include "testusd.h"
#include "defprop.h"
//
// Defines for scan phase. Used in data transfers
//
#define START 0
#define CONTINUE 1
#define END 2
//
// Handle to the module used for WIAS_ERROR and WIAS_TRACE
//
extern HINSTANCE g_hInst;
//
// Pointer to WIA Logging Interface used for WIAS_LERROR and WIAS_LTRACE
//
extern IWiaLog *g_pIWiaLog;
//
// Prototypes for private functions implemented in MiniDrv.Cpp
//
HRESULT _stdcall GetBmiSize(PBITMAPINFO pbmi, LONG *plBmiSize);
UINT AlignInPlace(
PBYTE pBuffer,
LONG cbWritten,
LONG lBytesPerScanLine,
LONG lBytesPerScanLineRaw);
/**************************************************************************\
* ValidateDataTransferContext
*
* Checks the data transfer context to ensure it's valid.
*
* Arguments:
*
* pDataTransferContext - Pointer the data transfer context.
*
* Return Value:
*
* Status
*
* History:
*
* 10/15/1998 Original Version
*
\**************************************************************************/
HRESULT ValidateDataTransferContext(
PMINIDRV_TRANSFER_CONTEXT pDataTransferContext)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"::ValidateDataTransferContext");
if (pDataTransferContext->lSize != sizeof(MINIDRV_TRANSFER_CONTEXT)) {
WIAS_LERROR(g_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) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AcquireDeviceData, invalid format"));
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(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AcquireDeviceData, invalid format"));
return E_INVALIDARG;;
}
}
//
// callback is always double buffered, non-callback never is
//
if (pDataTransferContext->pTransferBuffer == NULL) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AcquireDeviceData, invalid transfer buffer"));
return E_INVALIDARG;
}
return S_OK;
}
/**************************************************************************\
* TestUsdDevice::drvDeleteItem
*
* Try to delete a device item. Device items for the test scanner may
* not be modified, so simply return access denied.
*
* Arguments:
*
* pWiasContext - Indicates the item to delete.
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 10/15/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvDeleteItem(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
plDevErrVal = 0;
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvDeleteItem");
return STG_E_ACCESSDENIED;
}
/**************************************************************************\
* SendBitmapHeader
*
* Send the bitmap header info to the callback routine. This is a helper
* function used in TYMED_CALLBACK transfers.
*
* Arguments:
*
* pmdtc - a pointer to a transfer context.
*
* Return Value:
*
* Status
*
* History:
*
* 11/17/1998 Original Version
*
\**************************************************************************/
HRESULT SendBitmapHeader(
PMINIDRV_TRANSFER_CONTEXT pmdtc)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"::SendBitmapHeader");
HRESULT hr;
WIAS_ASSERT( g_hInst, pmdtc != NULL);
WIAS_ASSERT( g_hInst, pmdtc->tymed == TYMED_CALLBACK);
WIAS_ASSERT( g_hInst, pmdtc->guidFormatID == WiaImgFmt_MEMORYBMP);
//
// Driver is sending TOPDOWN data, must swap biHeight
//
// This routine assumes pMiniTranCtx->pHeader points to a
// BITMAPINFO header (TYMED_FILE doesn't use this path
// and DIB is the only format supported).
//
PBITMAPINFO pbmi = (PBITMAPINFO)pmdtc->pTransferBuffer;
pbmi->bmiHeader.biHeight = -pbmi->bmiHeader.biHeight;
//
// Send to class driver. WIA Class driver will pass
// data through to client.
//
hr = pmdtc->
pIWiaMiniDrvCallBack->
MiniDrvCallback(IT_MSG_DATA,
IT_STATUS_TRANSFER_TO_CLIENT,
0,
0,
pmdtc->lHeaderSize,
pmdtc,
0);
if (hr == S_OK) {
//
// If the transfer was successfull, advance offset for
// destination copy by the size of the data just sent.
//
pmdtc->cbOffset += pmdtc->lHeaderSize;
}
return hr;
}
/**************************************************************************\
* ScanItem
*
* Copy data from scanner into buffer. This routine must fill the
* complete buffer. Status is sent back to the client if a callback
* routine is provided.
*
* Data must be copied to the buffer from the bottom up to compensate
* for WiaImgFmt_BMP that defines DIB data as "BOTTOM-UP" :(
*
* Arguments:
*
* pItemContext - private item data
* pMiniTranCtx - mini dirver supplied transfer info
* plDevErrVal - device error value
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::ScanItem(
PTESTMINIDRIVERITEMCONTEXT pItemContext,
PMINIDRV_TRANSFER_CONTEXT pmdtc,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::ScanItem");
HRESULT hr = S_OK;
//
// Init buffer info
//
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(""));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("ScanItem:"));
LONG cbWritten = 0;
LONG cbSize;
LONG cbRemaining = pmdtc->lBufferSize - pmdtc->lHeaderSize;
PBYTE pBuf = pmdtc->pTransferBuffer + pmdtc->lHeaderSize;
LONG lPhase = START;
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pmdtc->lBufferSize: %d", pmdtc->lBufferSize));
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pmdtc->lHeaderSize: %d",pmdtc ->lHeaderSize));
if (pItemContext->lBytesPerScanLine == 0) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, lBytesPerScanLine == 0"));
return E_FAIL;
}
//
// Scan until buffer runs out or scanner completes transfer
//
while ((lPhase == START) || (cbWritten)) {
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" cbRemaining: %d", cbRemaining));
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pItemContext->lBytesPerScanLine: %d", pItemContext->lBytesPerScanLine));
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pItemContext->lBytesPerScanLineRaw: %d", pItemContext->lBytesPerScanLineRaw));
//
// Limit requests to 64K or less. Capping requests is driver specific.
//
cbSize = (cbRemaining > 0x10000) ? 0x10000 : cbRemaining;
//
// Request size to scanner must be modula the raw bytes per scan row.
// Enough space for the alignment padding must be reserved.
// These are requirements for the helper AlignInPlace().
//
cbSize = (cbSize / pItemContext->lBytesPerScanLine) *
pItemContext->lBytesPerScanLineRaw;
//
// Check if the scan is finished. If cbSize == 0 then we've transfered
// all the necessary data, so break from the scan loop.
//
if (cbSize == 0) {
break;
}
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lPhase: %d", lPhase));
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pBuf: %08X", pBuf));
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" cbSize: %d", cbSize));
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" cbRemaining: %d", cbRemaining));
//
// Device specific call to get data from the scanner and put it into
// a buffer. cbSize is the requested number of bytes to retrieve
// from the scanner, and cbWritten will be set to the actual number
// of bytes that were returned.
//
hr = Scan(pmdtc->guidFormatID,
lPhase,
pBuf,
cbSize,
&cbWritten,
pItemContext,
pmdtc);
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" cbWritten: %d", cbWritten));
//
// Change scan phase from START to CONTINUE, so that next call to
// Scan(...) will be in the correct phase.
//
if (lPhase == START) {
lPhase = CONTINUE;
}
if (hr == S_OK) {
if (cbWritten) {
//
// Align the data on DWORD boundries.
//
cbWritten = AlignInPlace(pBuf,
cbWritten,
pItemContext->lBytesPerScanLine,
pItemContext->lBytesPerScanLineRaw);
//
// Advance the buffer
//
pBuf += cbWritten;
cbRemaining -= cbWritten;
//
// If a status callback was specified, then callback the class
// driver.
//
if (pmdtc->pIWiaMiniDrvCallBack) {
//
// Calculate the percent complete for status.
//
FLOAT FractionComplete;
LONG PercentComplete;
if (pmdtc->lBufferSize) {
FractionComplete = (FLOAT)(pmdtc->lBufferSize - cbRemaining) / (FLOAT)pmdtc->lBufferSize;
} else {
FractionComplete = 0.0f;
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, pmdtc->lBufferSize = 0!"));
}
PercentComplete = (LONG)(100 * FractionComplete);
//
// Send status to class driver. WIA Class driver will
// pass status to client.
//
hr = pmdtc->
pIWiaMiniDrvCallBack->
MiniDrvCallback(IT_MSG_STATUS,
IT_STATUS_TRANSFER_TO_CLIENT,
PercentComplete,
0,
0,
pmdtc,
0);
//
// If user cancels scan, S_FALSE will be returned by
// callback. Also check for error, and abort scan
// if one occurred.
//
if (hr == S_FALSE) {
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("ScanItem, Transfer canceled by client"));
break;
} else if (FAILED(hr)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, MiniDrvCallback failed"));
WIAS_LHRESULT(g_pIWiaLog, hr);
break;
}
}
}
} else {
hr = E_FAIL;
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, data transfer failed"));
GetLastError((PULONG)plDevErrVal);
break;
}
}
//
// Let the scanner know we are done.
//
Scan(GUID_NULL, END, NULL, 0, NULL, pItemContext, pmdtc);
return hr;
}
/**************************************************************************\
* ScanItemCB
*
* Use client data callbacks to transfer banded data into app transfer
* buffer and callback client
*
* Arguments:
*
* pItemContext - private item data
* pmdtc - buffer and callback information
* plDevErrVal - device error value
*
* Return Value:
*
* Status
*
* History:
*
* 11/17/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::ScanItemCB(
PTESTMINIDRIVERITEMCONTEXT pItemContext,
PMINIDRV_TRANSFER_CONTEXT pmdtc,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::ScanItemCB");
HRESULT hr = S_OK;
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(""));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("ScanItemCB:"));
//
// There must be a callback supplied, else fail the transfer.
//
if ((pmdtc->pIWiaMiniDrvCallBack == NULL) ||
(!pmdtc->bTransferDataCB)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItemCB, invalid callback params"));
return E_INVALIDARG;
}
//
// Send Bitmap header.
//
hr = SendBitmapHeader(pmdtc);
//
// Transfer may have failed or been canceled. Only continue if S_OK.
//
if (hr != S_OK) {
return hr;
}
//WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("ScanItemCB, lBufferSize: 0x%lx\n", pmdtc->lBufferSize));
if (pItemContext->lBytesPerScanLine == 0) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItemCB, lBytesPerScanLine == 0"));
return E_FAIL;
}
//
// Init buffer variables
//
LONG cbWritten;
LONG cbSize;
LONG cbRemaining = pmdtc->lBufferSize;
LONG lPhase = START;
//
// Scan until buffer runs out or scanner completes transfer
//
while ((lPhase == START) || (cbWritten)) {
PBYTE pBuf = pmdtc->pTransferBuffer;
//
// Limit requests to 64K or less. Capping requests is driver
// specific. The smaller the limit, the more frequent the
// status messages.
//
cbSize = (cbRemaining > 0x10000) ? 0x10000 : cbRemaining;
//
// Request size to scanner must be modula the raw bytes per scan row.
// Enough space for the alignment padding must be reserved.
// These are requirements for the helper AlignInPlace().
//
cbSize = (cbSize / pItemContext->lBytesPerScanLine) *
pItemContext->lBytesPerScanLineRaw;
//
// Check if the scan is finished. If cbSize == 0 then we've transfered
// all the necessary data, so break from the scan loop.
//
if (cbSize == 0) {
break;
}
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lPhase: %d", lPhase));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pBuf: %08X", pBuf));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" cbSize: %d", cbSize));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" cbRemaining: %d", cbRemaining));
//
// Device specific call to get data from the scanner and put it into
// a buffer. cbSize is the requested number of bytes to retrieve
// from the scanner, and cbWritten will be set to the actual number
// of bytes that were returned.
//
hr = Scan(pmdtc->guidFormatID,
lPhase,
pBuf,
cbSize,
&cbWritten,
pItemContext,
pmdtc);
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" cbWritten: %d", cbWritten));
//
// Change scan phase from START to CONTINUE, so that next call to
// Scan(...) will be in the correct phase.
//
if (lPhase == START) {
lPhase = CONTINUE;
}
if (hr == S_OK) {
if (cbWritten) {
//
// Align the data on DWORD boundries.
//
cbWritten = AlignInPlace(pBuf,
cbWritten,
pItemContext->lBytesPerScanLine,
pItemContext->lBytesPerScanLineRaw);
//
// Calculate the percent complete for status.
//
FLOAT FractionComplete;
LONG PercentComplete;
if ((pmdtc->lImageSize + pmdtc->lHeaderSize)) {
FractionComplete = (FLOAT) (pmdtc->cbOffset + cbWritten) /
(FLOAT) (pmdtc->lImageSize + pmdtc->lHeaderSize);
} else {
FractionComplete = 0.0f;
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItemCB, pmdtc->lImageSize + pmdtc->lHeaderSize= 0!"));
}
PercentComplete = (LONG)(100 * FractionComplete);
//
// Send data to class driver. WIA Class driver will
// pass data to client.
//
hr = pmdtc->
pIWiaMiniDrvCallBack->
MiniDrvCallback(IT_MSG_DATA,
IT_STATUS_TRANSFER_TO_CLIENT,
PercentComplete,
pmdtc->cbOffset,
cbWritten,
pmdtc,
0);
//
// If user cancels scan, S_FALSE will be returned by
// callback. Also check for error, and abort scan
// if one occurred.
//
if (hr == S_FALSE) {
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("ScanItemCB, MiniDrvCallback canceled by client"));
break;
}
else if (FAILED(hr)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItemCB, MiniDrvCallback failed"));
WIAS_LHRESULT(g_pIWiaLog, hr);
DebugBreak();
break;
}
pmdtc->cbOffset += cbWritten;
}
}
else {
hr = E_FAIL;
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItemCB, data transfer failed"));
GetLastError((PULONG)plDevErrVal);
break;
}
}
// Let the hardware know we are done scanning.
Scan(GUID_NULL, END, NULL, 0, NULL, pItemContext, pmdtc);
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvAcquireItemData
*
* Transfer data from mini driver item to device manger.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item.
* lFlags - Operation flags, unused.
* pmdtc - Pointer to mini driver context. On entry, only the
* portion of the mini driver context which is derived
* from the item properties is filled in.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 11/17/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvAcquireItemData(
BYTE *pWiasContext,
LONG lFlags,
PMINIDRV_TRANSFER_CONTEXT pmdtc,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvAcquireItemData");
HRESULT hr;
plDevErrVal = 0;
//
// Get a pointer to the associated driver item.
//
IWiaDrvItem* pDrvItem;
hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
if (FAILED(hr)) {
return hr;
}
//
// Validate the data transfer context.
//
hr = ValidateDataTransferContext(pmdtc);
if (FAILED(hr)) {
return hr;
}
//
// Get item specific driver data
//
PTESTMINIDRIVERITEMCONTEXT pItemContext;
hr = pDrvItem->GetDeviceSpecContext((BYTE**)&pItemContext);
if (FAILED(hr)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, NULL item context"));
return hr;
}
//
// Set data source file name. This is where the test scanner
// gets it's data from.
//
hr = SetSrcBmp((BYTE*)pWiasContext);
if (hr != S_OK) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, SetSrcBmp failed"));
return hr;
}
//
// Use WIA services to fetch format specific info. This information
// is based on the property settings.
//
hr = wiasGetImageInformation(pWiasContext, 0, pmdtc);
if (hr != S_OK) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, GetImageInformation failed"));
return hr;
}
//
// Determine if this is a callback or buffered transfer.
//
if (pmdtc->tymed == TYMED_CALLBACK) {
hr = ScanItemCB(pItemContext,
pmdtc,
plDevErrVal);
} else {
hr = ScanItem(pItemContext,
pmdtc,
plDevErrVal);
}
if (!pmdtc->bClassDrvAllocBuf) {
CoTaskMemFree(pmdtc->pTransferBuffer);
}
return hr;
}
/**************************************************************************\
* SetItemSize
*
* Call wias to calc new item size
*
* Arguments:
*
* pWiasContext - item
*
* Return Value:
*
* Status
*
* History:
*
* 4/21/1999 Original Version
*
\**************************************************************************/
HRESULT SetItemSize(
BYTE *pWiasContext)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"::SetItemSize");
#define NUM_PROPS_TO_SET 3
LONG lWidthInBytes = 0;
LONG lMinBufSize = 0;
PROPSPEC ps[NUM_PROPS_TO_SET] = {
{PRSPEC_PROPID, WIA_IPA_ITEM_SIZE},
{PRSPEC_PROPID, WIA_IPA_BYTES_PER_LINE},
{PRSPEC_PROPID, WIA_IPA_MIN_BUFFER_SIZE}};
PROPVARIANT pv[NUM_PROPS_TO_SET];
HRESULT hr = S_OK;
MINIDRV_TRANSFER_CONTEXT mdtc;
//
// Clear the MiniDrvTransferContext
//
memset(&mdtc,0,sizeof(MINIDRV_TRANSFER_CONTEXT));
//
// Read format and tymed
//
GUID guidFormatID;
hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormatID, NULL, TRUE);
if (FAILED(hr)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, ReadPropLong WIA_IPA_FORMAT error"));
return hr;
}
hr = wiasReadPropLong(pWiasContext,WIA_IPA_TYMED, (LONG*)&mdtc.tymed, NULL, TRUE);
if (FAILED(hr)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, ReadPropLong WIA_IPA_TYMED error"));
return hr;
}
//
// wias works for DIB,TIFF formats
//
hr = wiasGetImageInformation(pWiasContext, WIAS_INIT_CONTEXT, &mdtc);
if (FAILED(hr)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, could not get image information"));
return hr;
}
//
// Set the MinBufferSize property. MinBufferSize is the minimum buffer
// that a client can request for a data transfer.
//
switch (mdtc.tymed) {
case TYMED_CALLBACK:
lMinBufSize = 65535;
break;
case TYMED_FILE:
lMinBufSize = mdtc.lImageSize + mdtc.lHeaderSize;
break;
default:
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, unknown tymed: 0x%08X", mdtc.tymed));
return E_INVALIDARG;
}
//
// Initialize propvar's. Then write the values. Don't need to call
// PropVariantClear when done, since there are only LONG values.
//
for (int i = 0; i < NUM_PROPS_TO_SET; i++) {
PropVariantInit(&pv[i]);
pv[i].vt = VT_I4;
}
pv[0].lVal = mdtc.lItemSize;
pv[1].lVal = mdtc.cbWidthInBytes;
pv[2].lVal = lMinBufSize;
hr = wiasWriteMultiple(pWiasContext, NUM_PROPS_TO_SET, ps, pv);
if (SUCCEEDED(hr)) {
//
// Get a pointer to the associated driver item.
//
IWiaDrvItem* pDrvItem;
hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
if (FAILED(hr)) {
return hr;
}
PTESTMINIDRIVERITEMCONTEXT pItemContext;
hr = pDrvItem->GetDeviceSpecContext((BYTE**)&pItemContext);
if (SUCCEEDED(hr)) {
//
// Calculate how many scan lines will fit in the buffer.
//
pItemContext->lBytesPerScanLineRaw = ((mdtc.lWidthInPixels * mdtc.lDepth) + 7) / 8;
pItemContext->lBytesPerScanLine = (((mdtc.lWidthInPixels * mdtc.lDepth) + 31) / 8) & 0xfffffffc;
pItemContext->lTotalRequested = pItemContext->lBytesPerScanLineRaw * mdtc.lLines;
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvWriteItemProperties, NULL item context"));
}
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, WriteMultiple failed"));
}
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvInitItemProperties
*
* Initialize the device item properties. Called during item
* initialization. This is called by the WIA Class driver
* after the item tree has been built. It is called once for every
* item in the tree.
*
* Arguments:
*
* pWiasContext - Pointer to WIA item.
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
*
* Return Value:
*
* Status
*
* History:
*
* 10/29/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvInitItemProperties(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvInitItemProperties");
HRESULT hr = S_OK;
//
// This device doesn't touch hardware to initialize the device item
// properties, so set plDevErrVal to 0.
//
*plDevErrVal = 0;
//
// Get a pointer to the associated driver item.
//
IWiaDrvItem* pDrvItem;
hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
if (FAILED(hr)) {
return hr;
}
//
// Set initial item properties.
//
LONG lItemType = 0;
pDrvItem->GetItemFlags(&lItemType);
if (lItemType & WiaItemTypeRoot) {
//
// This is for the root item.
//
//
// Build Root Item Properties, initializing global
// structures with their default and valid values
//
hr = BuildRootItemProperties();
if(FAILED(hr)) {
return hr;
}
//
// Add the device specific root item property names,
// using WIA service.
//
hr = wiasSetItemPropNames(pWiasContext,
NUM_ROOTITEMDEFAULTS,
g_piRootItemDefaults,
g_pszRootItemDefaults);
if (FAILED(hr)) {
return hr;
}
//
// Set the device specific root item properties to
// their default values using WIA service.
//
hr = wiasWriteMultiple(pWiasContext,
NUM_ROOTITEMDEFAULTS,
g_psRootItemDefaults,
g_pvRootItemDefaults);
//
// Free PROPVARIANT array, This frees any memory that was allocated for a prop variant value.
//
FreePropVariantArray(NUM_ROOTITEMDEFAULTS,g_pvRootItemDefaults);
if (FAILED(hr)) {
return hr;
}
//
// Use WIA services to set the property access and
// valid value information from g_wpiItemDefaults.
//
hr = wiasSetItemPropAttribs(pWiasContext,
NUM_ROOTITEMDEFAULTS,
g_psRootItemDefaults,
g_wpiRootItemDefaults);
} else {
//
// This is for the child item.(Top)
//
//
// Build Top Item Properties, initializing global
// structures with their default and valid values
//
hr = BuildTopItemProperties();
if(FAILED(hr)) {
return hr;
}
//
// Use the WIA service to set the item property names.
//
hr = wiasSetItemPropNames(pWiasContext,
NUM_ITEMDEFAULTS,
g_piItemDefaults,
g_pszItemDefaults);
if (FAILED(hr)) {
return hr;
}
//
// Use WIA services to set the item properties to their default
// values.
//
hr = wiasWriteMultiple(pWiasContext,
NUM_ITEMDEFAULTS,
g_psItemDefaults,
(PROPVARIANT*)g_pvItemDefaults);
if (FAILED(hr)) {
return hr;
}
//
// Use WIA services to set the property access and
// valid value information from g_wpiItemDefaults.
//
hr = wiasSetItemPropAttribs(pWiasContext,
NUM_ITEMDEFAULTS,
g_psItemDefaults,
g_wpiItemDefaults);
if (FAILED(hr)) {
return hr;
}
//
// Set item size properties.
//
hr = SetItemSize(pWiasContext);
}
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvValidateItemProperties
*
* Validate the device item properties. It is called when changes are made
* to an item's properties. Driver should not only check that the values
* are valid, but must update any valid values that may change as a result.
* If an a property is not being written by the application, and it's value
* is invalid, then "fold" it to a new value, else fail validation (because
* the application is setting the property to an invalid value).
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags, unused.
* nPropSpec - The number of properties that are being written
* pPropSpec - An array of PropSpecs identifying the properties that
* are being written.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 10/29/1998 Original Version
***************************************************************************/
HRESULT _stdcall TestUsdDevice::drvValidateItemProperties(
BYTE *pWiasContext,
LONG lFlags,
ULONG nPropSpec,
const PROPSPEC *pPropSpec,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvValidateItemProperties");
WIA_PROPERTY_CONTEXT Context;
HRESULT hr = S_OK;
LONG lItemType;
//
// This device doesn't touch hardware to validate the device item
// properties, so set device error to 0.
//
*plDevErrVal = 0;
hr = wiasGetItemType(pWiasContext, &lItemType);
if (SUCCEEDED(hr)) {
if (lItemType & WiaItemTypeRoot) {
//
// Insert root item validation here
//
} else {
//
// Validate the child item properties here. Start with
// dependent property validation, followed by a general
// property validation against their valid values with
// wiasValidateItemProperties.
//
//
// Create a property context needed by some WIA Service
// functions used below.
//
hr = wiasCreatePropContext(nPropSpec,
(PROPSPEC*)pPropSpec,
0,
NULL,
&Context);
if (SUCCEEDED(hr)) {
//
// Check Current Intent first
//
hr = CheckIntent(pWiasContext, &Context);
if (SUCCEEDED(hr)) {
//
// Check if DataType is being written
//
hr = CheckDataType(pWiasContext, &Context);
if (SUCCEEDED(hr)) {
//
// Use the WIA service to update the scan rect
// properties and valid values.
//
hr = wiasUpdateScanRect(pWiasContext,
&Context,
HORIZONTAL_BED_SIZE,
VERTICAL_BED_SIZE);
if (SUCCEEDED(hr)) {
//
// Use the WIA Service to update the valid values
// for Format. These are based on the value of
// WIA_IPA_TYMED, so validation is also performed
// on the tymed property by the service.
//
hr = wiasUpdateValidFormat(pWiasContext,
&Context,
(IWiaMiniDrv*) this);
if (SUCCEEDED(hr)) {
//
// Check Preferred format
//
hr = CheckPreferredFormat(pWiasContext, &Context);
}
}
}
}
wiasFreePropContext(&Context);
}
//
// Update the item size
//
if (SUCCEEDED(hr)) {
hr = SetItemSize(pWiasContext);
}
//
// If all necessary changes have been made
// successfully, validate the properties against
// their new valid values.
//
if (SUCCEEDED(hr)) {
hr = wiasValidateItemProperties(pWiasContext, nPropSpec, pPropSpec);
}
}
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, could not get item type"));
}
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvWriteItemProperties
*
* Write the device item properties to the hardware. This is called by the
* WIA Class driver prior to drvAcquireItemData when the client requests
* a data transfer.
*
* Arguments:
*
* pWiasContext - Pointer to WIA item.
* lFlags - Operation flags, unused.
* pmdtc - Pointer to mini driver context. On entry, only the
* portion of the mini driver context which is derived
* from the item properties is filled in.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 10/29/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvWriteItemProperties(
BYTE *pWiasContext,
LONG lFlags,
PMINIDRV_TRANSFER_CONTEXT pmdtc,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvWriteItemProperties");
HRESULT hr = S_OK;
// No device hardware errors.
*plDevErrVal = 0;
//
// The Test Scanner has no hardware, so there is nothing to do here.
//
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvReadItemProperties
*
* Read the device item properties. When a client application tries to
* read a WIA Item's properties, the WIA Class driver will first notify
* the driver by calling this method.
*
* Arguments:
*
* pWiasContext - wia item
* lFlags - Operation flags, unused.
* nPropSpec - Number of elements in pPropSpec.
* pPropSpec - Pointer to property specification, showing which properties
* the application wants to read.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 10/29/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvReadItemProperties(
BYTE *pWiasContext,
LONG lFlags,
ULONG nPropSpec,
const PROPSPEC *pPropSpec,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvReadItemProperties");
//
// For most scanner devices, item properties are stored in the driver
// and written out at acquire image time. Some devices support properties
// which should be updated on every property read e.g. say there was
// a property representing the device's internal clock.
// The updating of such properties should be done here.
//
*plDevErrVal = 0;
return S_OK;
}
/**************************************************************************\
* TestUsdDevice::drvLockWiaDevice
*
* Lock access to the device.
*
* Arguments:
*
* pWiasContext - unused, can be NULL
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
*
* Return Value:
*
* Status
*
* History:
*
* 9/11/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvLockWiaDevice(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvLockWiaDevice");
*plDevErrVal = 0;
return m_pStiDevice->LockDevice(100);
}
/**************************************************************************\
* TestUsdDevice::drvUnLockWiaDevice
*
* Unlock access to the device.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags, unused.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 9/11/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvUnLockWiaDevice(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvUnLockWiaDevice");
*plDevErrVal = 0;
return m_pStiDevice->UnLockDevice();
}
/**************************************************************************\
* TestUsdDevice::drvAnalyzeItem
*
* This scanner does not support image analysis, so return E_NOTIMPL.
*
* Arguments:
*
* pWiasContext - Pointer to the device item to be analyzed.
* lFlags - Operation flags.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 10/15/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvAnalyzeItem(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvAnalyzeItem");
*plDevErrVal = 0;
return E_NOTIMPL;
}
/**************************************************************************\
* TestUsdDevice::drvFreeDrvItemContext
*
* Free any device specific context.
*
* Arguments:
*
* lFlags - Operation flags, unused.
* pDevSpecContext - Pointer to device specific context.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 10/15/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvFreeDrvItemContext(
LONG lFlags,
BYTE *pSpecContext,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvFreeDrvItemContext");
PTESTMINIDRIVERITEMCONTEXT pContext;
*plDevErrVal = 0;
pContext = (PTESTMINIDRIVERITEMCONTEXT) pSpecContext;
if (pContext) {
// Free any driver item specific context here.
}
return S_OK;
}
/**************************************************************************\
* TestUsdDevice::drvInitializeWia
*
* Initialize the WIA mini driver. This will build up the driver item tree
* and perform any other initialization code that's needed for WIA.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags, unused.
* bstrDeviceID - Device ID.
* bstrRootFullItemName - Full item name.
* pIPropStg - Device info. properties.
* pStiDevice - STI device interface.
* pIUnknownOuter - Outer unknown interface.
* ppIDrvItemRoot - Pointer to returned root item.
* ppIUnknownInner - Pointer to returned inner unknown.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 9/11/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvInitializeWia(
BYTE *pWiasContext,
LONG lFlags,
BSTR bstrDeviceID,
BSTR bstrRootFullItemName,
IUnknown *pStiDevice,
IUnknown *pIUnknownOuter,
IWiaDrvItem **ppIDrvItemRoot,
IUnknown **ppIUnknownInner,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvInitializeWia");
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("drvInitializeWia, device ID: %ws", bstrDeviceID));
HRESULT hr = S_OK;
*plDevErrVal = 0;
*ppIDrvItemRoot = NULL;
*ppIUnknownInner = NULL;
//
// Need to init names and STI pointer?
//
if (m_pStiDevice == NULL) {
//
// save STI device inteface for locking
//
m_pStiDevice = (IStiDevice *)pStiDevice;
//
// Cache the device ID.
//
m_bstrDeviceID = SysAllocString(bstrDeviceID);
if (!m_bstrDeviceID) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, unable to allocate device ID string"));
return E_OUTOFMEMORY;
}
//
// Cache the root property stream name.
//
m_bstrRootFullItemName = SysAllocString(bstrRootFullItemName);
if (!m_bstrRootFullItemName) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, unable to allocate prop stream name"));
return E_OUTOFMEMORY;
}
}
//
// Initialize Capabilities array
//
hr = BuildCapabilities();
if(FAILED(hr)) {
return hr;
}
//
// Build the device item tree, if it hasn't been built yet.
//
if (!m_pIDrvItemRoot) {
LONG lDevErrVal;
//
// The WIA_CMD_SYNCHRONIZE command will build the item tree.
//
hr = drvDeviceCommand(NULL, 0, &WIA_CMD_SYNCHRONIZE, NULL, &lDevErrVal);
}
*ppIDrvItemRoot = m_pIDrvItemRoot;
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvUnInitializeWia
*
* Gets called when a client connection is going away.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA Root item context of the client's
* item tree.
*
* Return Value:
* Status
*
* History:
*
* 30/12/1999 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvUnInitializeWia(
BYTE *pWiasContext)
{
return S_OK;
}
/**************************************************************************\
* drvGetDeviceErrorStr
*
* Map a device error value to a string.
*
* Arguments:
*
* lFlags - Operation flags, unused.
* lDevErrVal - Device error value.
* ppszDevErrStr - Pointer to returned error string.
* plDevErrVal - Pointer to the device error value.
*
*
* Return Value:
*
* Status
*
* History:
*
* 10/2/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvGetDeviceErrorStr(
LONG lFlags,
LONG lDevErrVal,
LPOLESTR *ppszDevErrStr,
LONG *plDevErr)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvGetDeviceErrorStr");
*plDevErr = 0;
//
// Map device errors to a string to be placed in the event log.
//
switch (lDevErrVal) {
case 0:
*ppszDevErrStr = L"No Error";
break;
default:
*ppszDevErrStr = L"Device Error, Unknown Error";
return E_FAIL;
}
return S_OK;
}
/**************************************************************************\
* drvDeviceCommand
*
* Issue a command to the device.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item.
* lFlags - Operation flags, unused.
* plCommand - Pointer to command GUID.
* ppWiaDrvItem - Optional pointer to returned item, unused.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 9/11/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvDeviceCommand(
BYTE *pWiasContext,
LONG lFlags,
const GUID *plCommand,
IWiaDrvItem **ppWiaDrvItem,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvDeviceCommand");
//
// This device doesn't touch hardware, so set device error value to 0.
//
*plDevErrVal = 0;
HRESULT hr;
//
// Check which command was issued
//
if (*plCommand == WIA_CMD_SYNCHRONIZE) {
//
// SYNCHRONIZE - Build the minidriver representation of
// the current item list, if it doesn't exist.
//
if (!m_pIDrvItemRoot) {
hr = BuildItemTree();
}
else {
hr = S_OK;
}
}
else if (*plCommand == WIA_CMD_BUILD_DEVICE_TREE) {
//
// BUILD_DEVICE_TREE - Build the minidriver representation of
// the current item list, if it doesn't exist.
//
if (!m_pIDrvItemRoot) {
hr = BuildItemTree();
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, WIA_CMD_BUILD_DEVICE_TREE, device tree allready exists"));
hr = E_INVALIDARG;
}
}
else if (*plCommand == WIA_CMD_DELETE_DEVICE_TREE) {
//
// DELETE_DEVICE_TREE - Delete the minidriver representation of
// the current item list, if it exists.
//
if (m_pIDrvItemRoot) {
hr = DeleteItemTree();
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, WIA_CMD_DELETE_DEVICE_TREE, device tree doesn't exist"));
hr = E_INVALIDARG;
}
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, unknown command"));
hr = E_NOTIMPL;
}
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvGetCapabilities
*
* Get supported device commands and events as an array of WIA_DEV_CAPS.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item, unused.
* lFlags - Operation flags.
* pcelt - Pointer to returned number of elements in
* returned GUID array.
* ppCapabilities - Pointer to returned GUID array.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 17/3/1999 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvGetCapabilities(
BYTE *pWiasContext,
LONG ulFlags,
LONG *pcelt,
WIA_DEV_CAP_DRV **ppCapabilities,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvGetCapabilites");
*plDevErrVal = 0;
//
// Return depends on flags. Flags specify whether we should return
// commands, events, or both.
//
//
switch (ulFlags) {
case WIA_DEVICE_COMMANDS:
//
// Only commands
//
*pcelt = NUM_CAPABILITIES - NUM_EVENTS;
*ppCapabilities = &g_Capabilities[NUM_EVENTS];
break;
case WIA_DEVICE_EVENTS:
//
// Only events
//
*pcelt = NUM_EVENTS;
*ppCapabilities = g_Capabilities;
break;
case (WIA_DEVICE_COMMANDS | WIA_DEVICE_EVENTS):
//
// Both events and commands
//
*pcelt = NUM_CAPABILITIES;
*ppCapabilities = g_Capabilities;
break;
default:
//
// Flags is invalid
//
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetCapabilities, flags was invalid"));
return E_INVALIDARG;
}
return S_OK;
}
/**************************************************************************\
* drvGetWiaFormatInfo
*
* Returns an array of WIA_FORMAT_INFO structs, which specify the format
* and media type pairs that are supported.
*
* Arguments:
*
* pWiasContext - Pointer to the WIA item context, unused.
* lFlags - Operation flags, unused.
* pcelt - Pointer to returned number of elements in
* returned WIA_FORMAT_INFO array.
* ppwfi - Pointer to returned WIA_FORMAT_INFO array.
* plDevErrVal - Pointer to the device error value.
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1999 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvGetWiaFormatInfo(
BYTE *pWiasContext,
LONG lFlags,
LONG *pcelt,
WIA_FORMAT_INFO **ppwfi,
LONG *plDevErrVal)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::drvGetWiaFormatInfo");
//
// If it hasn't been done already, set up the g_wfiTable table
//
if (!g_wfiTable) {
g_wfiTable = (WIA_FORMAT_INFO*) CoTaskMemAlloc(sizeof(WIA_FORMAT_INFO) * NUM_WIA_FORMAT_INFO);
if (!g_wfiTable) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, out of memory"));
return E_OUTOFMEMORY;
}
//
// Set up the GUID Format / TYMED pairs
//
g_wfiTable[0].guidFormatID = WiaImgFmt_MEMORYBMP;
g_wfiTable[0].lTymed = TYMED_CALLBACK;
g_wfiTable[1].guidFormatID = WiaImgFmt_BMP;
g_wfiTable[1].lTymed = TYMED_FILE;
}
*plDevErrVal = 0;
*pcelt = NUM_WIA_FORMAT_INFO;
*ppwfi = g_wfiTable;
return S_OK;
}
/**************************************************************************\
* drvNotifyPnpEvent
*
* Pnp Event received by device manager. This is called when a Pnp event
* is received for this device.
*
* Arguments:
*
*
*
* Return Value:
*
* Status
*
* History:
*
* Aug/3rd/1999 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvNotifyPnpEvent(
const GUID *pEventGUID,
BSTR bstrDeviceID,
ULONG ulReserved)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL1,
"TestUsdDevice::DrvNotifyPnpEvent");
//
// Do nothing, since device is not Plug-and-play.
//
return (S_OK);
}
/*******************************************************************************
*
* P R I V A T E M E T H O D S
*
*******************************************************************************/
/**************************************************************************\
* AlignInPlace
*
* DWORD align a data buffer in place.
*
* Arguments:
*
* pBuffer - Pointer to the data buffer.
* cbWritten - Size of the data in bytes.
* lBytesPerScanLine - Number of bytes per scan line in the output data.
* lBytesPerScanLineRaw - Number of bytes per scan line in the input data.
*
* Return Value:
*
* Status
*
* History:
*
* 10/29/1998 Original Version
*
\**************************************************************************/
UINT AlignInPlace(
PBYTE pBuffer,
LONG cbWritten,
LONG lBytesPerScanLine,
LONG lBytesPerScanLineRaw)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"::AlignInPlace");
if (lBytesPerScanLineRaw % 4) {
UINT uiPadBytes = lBytesPerScanLine - lBytesPerScanLineRaw;
UINT uiDevLinesWritten = cbWritten / lBytesPerScanLineRaw;
PBYTE pSrc = pBuffer + cbWritten - 1;
PBYTE pDst = pBuffer + (uiDevLinesWritten * lBytesPerScanLine) - 1;
while (pSrc >= pBuffer) {
pDst -= uiPadBytes;
for (LONG i = 0; i < lBytesPerScanLineRaw; i++) {
*pDst-- = *pSrc--;
}
}
return uiDevLinesWritten * lBytesPerScanLine;
}
return cbWritten;
}
/**************************************************************************\
* TestUsdDevice::FillBufferFromFile
*
* Get the image data from the data source file.
*
* Arguments:
*
* pBuffer - Pointer to the data buffer.
* lLength - Size of the data buffer in bytes.
* pReceived - Number of bytes written to the buffer.
* pdic - Pointer to the item context.
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1998 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::FillBufferFromFile(
PBYTE pBuffer,
LONG lLength,
PLONG pReceived,
PTESTMINIDRIVERITEMCONTEXT pdic)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::FillBufferFromFile");
HRESULT hr = S_OK;
PBYTE pbSrc = pdic->pTestBmpBits;
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" FillBufferFromFile"));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pBuffer: %X", pBuffer));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lLength: %d", lLength));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pReceived: %X", pReceived));
while (((*pReceived) < lLength) &&
(pdic->lTotalWritten < pdic->lTotalRequested)){
// Return a scan line
for (LONG i = 0; i < pdic->lBytesPerScanLineRaw; i++) {
if ((pdic->lTestBmpLine < pdic->lTestBmpHeight) &&
(pdic->lTestBmpLine >= 0) &&
(i < pdic->lTestBmpBytesPerScanLine)) {
// If the source bitmap still has data copy it.
*pBuffer++ = *pbSrc++;
*pReceived += 1;
pdic->lTotalWritten++;
} else {
// If the source bitmap is out of line data,
// pad out line with zero data.
*pBuffer++ = 0;
*pReceived += 1;
pdic->lTotalWritten++;
}
}
if (pdic->lTestBmpDir == 1) {
pbSrc+= pdic->lTestBmpLinePad;
pdic->lTestBmpLine++;
}
else {
pbSrc -= (pdic->lTestBmpBytesPerScanLine * 2);
pbSrc -= pdic->lTestBmpLinePad;
pdic->lTestBmpLine--;
}
}
pdic->pTestBmpBits = pbSrc;
return hr;
}
/**************************************************************************\
* TestUsdDevice::FillBufferWithTestPattern
*
* Generate the image data from a test pattern.
*
* Arguments:
*
* pBuffer - Pointer to the data buffer.
* lLength - Size of the data buffer in bytes.
* pReceived - Number of bytes written to the buffer.
* pItemContext - Pointer to the item context.
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1998 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::FillBufferWithTestPattern(
PBYTE pBuffer,
LONG lLength,
PLONG pReceived,
PTESTMINIDRIVERITEMCONTEXT pdic,
PMINIDRV_TRANSFER_CONTEXT pmtc)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::FillBufferWithTestPattern");
HRESULT hr = S_OK;
BYTE bColor;
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" FillBufferWithTestPattern"));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pBuffer: %X", pBuffer));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lLength: %d", lLength));
// WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pReceived: %X", pReceived));
while (((*pReceived) < lLength) &&
(pdic->lTotalWritten < pdic->lTotalRequested)) {
switch (pmtc->lDepth) {
case 1:
if ((!pdic->lTotalWritten) ||
((pdic->lTotalWritten % pdic->lBytesPerScanLineRaw) == 0)) {
bColor = 0x55;
}
else {
bColor = 0xAA;
}
*pBuffer++ = bColor;
(*pReceived)++;
pdic->lTotalWritten++;
break;
case 8:
if ((!pdic->lTotalWritten) ||
((pdic->lTotalWritten % pdic->lBytesPerScanLineRaw) == 0)) {
bColor = 0x55;
}
else {
if (LOBYTE(pBuffer) & 1) {
bColor = 0xC0;
}
else {
bColor = 0x00;
}
}
*pBuffer++ = bColor;
(*pReceived)++;
pdic->lTotalWritten++;
break;
case 24:
if ((!pdic->lTotalWritten) ||
((pdic->lTotalWritten % pdic->lBytesPerScanLineRaw) == 0)) {
bColor = 0x55;
}
else {
bColor = 0xC0;
}
if (LOBYTE(pBuffer) & 1) {
*pBuffer++ = bColor;
*pBuffer++ = 0x00;
*pBuffer++ = bColor;
}
else {
*pBuffer++ = 0x00;
*pBuffer++ = 0x00;
*pBuffer++ = 0x00;
}
(*pReceived)+= 3;
pdic->lTotalWritten += 3;
break;
default:
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::FillBufferWithTestPattern, unknown depth"));
hr = E_FAIL;
break;
}
}
return hr;
}
/**************************************************************************\
* SetSrcBmp
*
* Set the correct source bitmap file associated with the current
* bitdepth setting.
*
* Arguments:
*
* pWiasContext - wia item
*
* Return Value:
*
* Status
*
* History:
*
* 6/28/1999 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::SetSrcBmp(BYTE *pWiasContext)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::SetSrcBmp");
HRESULT hr = S_OK;
LONG lbitdepth = 0;
//
// Read WIA_IPA_DEPTH property, to get current setting
//
hr = wiasReadPropLong(pWiasContext, WIA_IPA_DEPTH, (LONG*)&lbitdepth, NULL, true);
if (SUCCEEDED(hr)) {
//
// Build the path name of the data source file.
//
DWORD dwRet = GetTempPath(MAX_PATH, m_szSrcDataName);
if (dwRet != 0) {
switch(lbitdepth)
{
case 1: // 1-bit data requested
_tcscat(m_szSrcDataName, DATA_1BIT_SRC_NAME);
break;
case 24:// 24-bit data requested
_tcscat(m_szSrcDataName, DATA_24BIT_SRC_NAME);
break;
case 8: // 8-bit data requested
default:
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("Defaulting to 8-bit"));
_tcscat(m_szSrcDataName, DATA_8BIT_SRC_NAME);
break;
}
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::SetSrcBmp, unable to get data source file name"));
return STIERR_NOT_INITIALIZED;
}
// Make sure we can open the data source file.
HANDLE hTestBmp = CreateFile(m_szSrcDataName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
NULL);
// obtain last error information
m_dwLastOperationError = ::GetLastError();
if (hTestBmp == INVALID_HANDLE_VALUE) {
hr = HRESULT_FROM_WIN32(m_dwLastOperationError);
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::SetSrcBmp, unable to open data source file:"));
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,(" %s", m_szSrcDataName));
WIAS_LHRESULT(g_pIWiaLog, hr);
} else {
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" Source data: %s", m_szSrcDataName));
CloseHandle(hTestBmp);
}
}
return hr;
}
/**************************************************************************\
* OpenTestBmp
*
* Open the test bitmap data file as a memory mapped file and retrieve
* image size/format data.
*
* Arguments:
*
* pItemContext - Pointer to the item context.
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1998 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::OpenTestBmp(
GUID guidFormatID,
PTESTMINIDRIVERITEMCONTEXT pdic)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::OpenTestBmp");
HRESULT hr = S_OK;
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" OpenTestBmp"));
// Data source file should be closed.
if (pdic->hTestBmp != INVALID_HANDLE_VALUE) {
CloseHandle(pdic->hTestBmp);
pdic->hTestBmp = NULL;
}
// Open the data source file.
pdic->hTestBmp = CreateFile(m_szSrcDataName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
NULL);
// obtain last error information
m_dwLastOperationError = ::GetLastError();
if (pdic->hTestBmp != INVALID_HANDLE_VALUE) {
// Create a file mapping to the test bitmap.
pdic->hTestBmpMap = NULL;
pdic->hTestBmpMap = CreateFileMapping(pdic->hTestBmp,
NULL,
PAGE_READWRITE,
0,
0,
NULL);
if (pdic->hTestBmpMap != NULL) {
// Map a view of the test bitmap.
pdic->pTestBmp = NULL;
pdic->pTestBmp = (PBYTE)MapViewOfFileEx(pdic->hTestBmpMap,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0,
NULL);
if (pdic->pTestBmp != NULL) {
// Retrieve image size/format data.
PBYTE pb = pdic->pTestBmp;
PBITMAPFILEHEADER pbmFile = (PBITMAPFILEHEADER)pb;
PBITMAPINFO pbmi = (PBITMAPINFO)(pb + sizeof(BITMAPFILEHEADER));
// Validate bitmap.
if (pbmFile->bfType == 'MB') {
// get BMP size
LONG lBmiSize = 0;
hr = GetBmiSize(pbmi, &lBmiSize);
if (SUCCEEDED(hr)) {
// Reset total bytes written.
pdic->lTotalWritten = 0;
// Fill in test bitmap parameters.
pdic->lTestBmpDepth = pbmi->bmiHeader.biBitCount;
pdic->lTestBmpWidth = pbmi->bmiHeader.biWidth;
pdic->lTestBmpHeight = pbmi->bmiHeader.biHeight;
// Calculate data bytes per line in test bitmap.
pdic->lTestBmpBytesPerScanLine = ((pdic->lTestBmpWidth *
pdic->lTestBmpDepth) + 7) / 8;
// Calculate pad bytes per line in test bitmap.
pdic->lTestBmpLinePad = pdic->lTestBmpBytesPerScanLine % 4;
if (pdic->lTestBmpLinePad) {
pdic->lTestBmpLinePad = 4 - pdic->lTestBmpLinePad;
}
// Point to test bitmap image bits.
pdic->pTestBmpBits = pb;
pdic->pTestBmpBits += sizeof(BITMAPFILEHEADER);
pdic->pTestBmpBits += lBmiSize;
if (guidFormatID == WiaImgFmt_MEMORYBMP) {
// Test bitmap is stored bottom up. If they want top
// up, start at the last line in the file.
pdic->lTestBmpDir = -1;
pdic->lTestBmpLine = pdic->lTestBmpHeight - 1;
pdic->pTestBmpBits += pdic->lTestBmpHeight *
(pdic->lTestBmpBytesPerScanLine + pdic->lTestBmpLinePad);
}
else {
// Test bitmap is stored bottom up. If they want bottom
// up, start at the first line in the file.
pdic->lTestBmpDir = 1;
pdic->lTestBmpLine = 0;
}
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("-- TestBmp Information --"));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lTestBmpDepth: %d", pdic->lTestBmpDepth));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lTestBmpWidth: %d", pdic->lTestBmpWidth));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lTestBmpHeight: %d", pdic->lTestBmpHeight));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" pTestBmpBits: %X", pdic->pTestBmpBits));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lTestBmpBytesPerScanLine: %d", pdic->lTestBmpBytesPerScanLine));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lTestBmpLinePad: %d", pdic->lTestBmpLinePad));
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,(" lTestBmpDir: %d", pdic->lTestBmpDir));
return hr;
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::OpenTestBmp, invalid BMI"));
}
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::OpenTestBmp, not a valid bitmap"));
}
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::OpenTestBmp, MapViewOfFileEx failed"));
}
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::OpenTestBmp, CreateFilemapping failed"));
}
}
else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::OpenTestBmp, unable to open data source file:"));
}
if (SUCCEEDED(hr)) {
hr = HRESULT_FROM_WIN32(m_dwLastOperationError);
}
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,(" %s", m_szSrcDataName));
WIAS_LHRESULT(g_pIWiaLog, hr);
CloseTestBmp(pdic);
return hr;
}
/**************************************************************************\
* CloseTestBmp
*
* Close the test bitmap data file and clear the image size/format data.
*
* Arguments:
*
* pItemContext - Pointer to the item context.
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1998 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::CloseTestBmp(
PTESTMINIDRIVERITEMCONTEXT pItemContext)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::CloseTestBmp");
pItemContext->lTestBmpDepth = 0;
pItemContext->lTestBmpWidth = 0;
pItemContext->lTestBmpHeight = 0;
pItemContext->pTestBmpBits = NULL;
pItemContext->lTestBmpLine = 0;
// Unmap data source file.
if (pItemContext->pTestBmp != NULL) {
UnmapViewOfFile(pItemContext->pTestBmp);
pItemContext->pTestBmp = NULL;
}
// Close data source file mapping.
if (pItemContext->hTestBmpMap != NULL) {
CloseHandle(pItemContext->hTestBmpMap);
pItemContext->hTestBmpMap = NULL;
}
// Close data source file handle.
if (pItemContext->hTestBmp != INVALID_HANDLE_VALUE) {
CloseHandle(pItemContext->hTestBmp);
pItemContext->hTestBmp = INVALID_HANDLE_VALUE;
}
return S_OK;
}
/**************************************************************************\
* Scan
*
* Get the image data from the device hardware.
*
* Arguments:
*
* iPhase - Phase of the scan (START, CONTINUE, END).
* pBuffer - Pointer to the data buffer.
* lLength - Size of the data buffer in bytes.
* pReceived - Number of bytes written to the buffer.
* pItemContext - Pointer to the item context.
*
* Return Value:
*
* Status
*
* History:
*
* 11/18/1998 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::Scan(
GUID guidFormatID,
LONG iPhase,
PBYTE pBuffer,
LONG lLength,
PLONG pReceived,
PTESTMINIDRIVERITEMCONTEXT pItemContext,
PMINIDRV_TRANSFER_CONTEXT pmtc)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::Scan");
HRESULT hr = S_OK;
static HRESULT hrOpen = S_FALSE;
if (!pItemContext) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::Scan, NULL pItemContext"));
DebugBreak();
return E_INVALIDARG;
}
switch (iPhase) {
case START:
hrOpen = OpenTestBmp(guidFormatID, pItemContext);
if (FAILED(hr)) {
return hrOpen;
}
case CONTINUE:
if (pReceived && pBuffer) {
*pReceived = 0;
if ((pmtc->lDepth == pItemContext->lTestBmpDepth) &&
(hrOpen == S_OK)) {
// If we have a scan request for the same format
// as the test bitmap, fill the buffer from the
// test bitmap.
hr = FillBufferFromFile(pBuffer,
lLength,
pReceived,
pItemContext);
} else {
// The test bitmap doesn't match the request,
// fill the buffer with a test pattern.
hr = FillBufferWithTestPattern(pBuffer,
lLength,
pReceived,
pItemContext,
pmtc);
}
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::Scan, null parameter"));
hr = E_INVALIDARG;
}
break;
case END:
hr = CloseTestBmp(pItemContext);
hrOpen = S_FALSE;
break;
default:
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("TestUsdDevice::Scan, unknown phase"));
hr = E_FAIL;
}
return hr;
}
/**************************************************************************\
* UnlinkItemTree
*
* Call device manager to unlink and release our reference to
* all items in the driver item tree.
*
* Arguments:
*
*
*
* Return Value:
*
* Status
*
* History:
*
* 10/2/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::DeleteItemTree(void)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::DeleteItemTree");
//
// If no tree, return.
//
if (!m_pIDrvItemRoot) {
return S_OK;
}
//
// Call device manager to unlink the driver item tree.
//
HRESULT hr = m_pIDrvItemRoot->UnlinkItemTree(WiaItemTypeDisconnected);
if (SUCCEEDED(hr)) {
m_pIDrvItemRoot = NULL;
}
return hr;
}
/**************************************************************************\
* BuildItemTree
*
* The device uses the WIA Service functions to build up a tree of
* device items. The test scanner supports only a single scanning item so
* build a device item tree with only one child off the root.
*
* Arguments:
*
*
*
* Return Value:
*
* Status
*
* History:
*
* 10/2/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::BuildItemTree(void)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"TestUsdDevice::BuildItemTree");
WIAS_LTRACE(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("TestUsdDevice::BuildItemTree"));
//
// The device item tree must not exist.
//
WIAS_ASSERT( (g_hInst), (m_pIDrvItemRoot == NULL));
//
// Call the class driver to create the root item.
//
HRESULT hr = E_FAIL;
//
// Name the root.
//
BSTR bstrRoot = NULL;
hr = GetBSTRResourceString(IDS_FULLROOTITEM_NAME,&bstrRoot,TRUE);
if (bstrRoot) {
hr = wiasCreateDrvItem(WiaItemTypeFolder |
WiaItemTypeDevice |
WiaItemTypeRoot,
bstrRoot,
bstrRoot,
(IWiaMiniDrv *)this,
sizeof(TESTMINIDRIVERITEMCONTEXT),
NULL,
&m_pIDrvItemRoot);
SysFreeString(bstrRoot);
if (FAILED(hr)) {
return hr;
}
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, unable to allocate item name"));
return E_OUTOFMEMORY;
}
//
// Create and add the Top/Front and Bottom/Back device items.
//
for (INT i = 0; i < NUM_DEVICE_ITEM; i++) {
//
// Build the item names.
//
BSTR bstrItemName = NULL;
BSTR bstrFullItemName = NULL;
bstrItemName = NULL;
hr = GetBSTRResourceString(IDS_TOPITEM_NAME,&bstrItemName,TRUE);
if (SUCCEEDED(hr)) {
hr = GetBSTRResourceString(IDS_FULLTOPITEM_NAME,&bstrFullItemName,TRUE);
if (SUCCEEDED(hr)) {
//
// Call the class driver to create another driver item.
// This will be inserted as the child item.
//
PTESTMINIDRIVERITEMCONTEXT pItemContext;
IWiaDrvItem *pItem = NULL;
hr = wiasCreateDrvItem(WiaItemTypeFile |
WiaItemTypeImage |
WiaItemTypeDevice,
bstrItemName,
bstrFullItemName,
(IWiaMiniDrv *)this,
sizeof(TESTMINIDRIVERITEMCONTEXT),
(PBYTE*) &pItemContext,
&pItem);
if (SUCCEEDED(hr)) {
//
// Initialize device specific context.
//
memset(pItemContext, 0, sizeof(TESTMINIDRIVERITEMCONTEXT));
pItemContext->lSize = sizeof(TESTMINIDRIVERITEMCONTEXT);
//
// Call the class driver to add pItem to the folder
// m_pIDrvItemRoot (i.e. make pItem a child of
// m_pIDrvItemRoot).
//
hr = pItem->AddItemToFolder(m_pIDrvItemRoot);
if (FAILED(hr)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, AddItemToFolder failed"));
}
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, wiasCreateDrvItem failed"));
}
//
// free the BSTR allocated by the BSTRResourceString helper
//
SysFreeString(bstrFullItemName);
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, unable to allocate full item name"));
hr = E_OUTOFMEMORY;
}
//
// free the BSTR allocated by the BSTRResourceString helper
//
SysFreeString(bstrItemName);
} else {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, unable to allocate item name"));
hr = E_OUTOFMEMORY;
}
break; // Error if here, quit iterating.
}
if (FAILED(hr)) {
DeleteItemTree();
}
return hr;
}
/**************************************************************************\
* GetBmiSize
*
* Get the size of the BMI structure. We should never see biCompression
* set to BI_RLE.
*
* Arguments:
*
* pbmi - Pointer to input BITMAPINFO structure.
* plBmiSize - Pointer output BMI size.
*
* Return Value:
*
* Size of
*
* History:
*
* 1/19/1999 Original Version
*
\**************************************************************************/
HRESULT _stdcall GetBmiSize(PBITMAPINFO pbmi, LONG *plBmiSize)
{
CWiaLogProc WIAS_LOGPROC(g_pIWiaLog,
WIALOG_NO_RESOURCE_ID,
WIALOG_LEVEL3,
"::GetBmiSize");
// check plBmiSize pointer to see if it can be written to properly
if (IsBadWritePtr(plBmiSize, sizeof(LONG))) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetBmiSize, bad plBmiSize"));
return E_POINTER;
}
LONG lSize = pbmi->bmiHeader.biSize;
if ((pbmi->bmiHeader.biCompression == BI_RLE8) ||
(pbmi->bmiHeader.biCompression == BI_RLE4)) {
WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetBmiSize, BI_RLE not allowed"));
return E_INVALIDARG;
}
// determine the size of bits and palette data
if ((pbmi->bmiHeader.biBitCount == 24) ||
((pbmi->bmiHeader.biBitCount == 32) &&
(pbmi->bmiHeader.biCompression == BI_RGB))) {
// no color table case, no colors unless stated
lSize += sizeof(RGBQUAD) * pbmi->bmiHeader.biClrUsed;
} else if (((pbmi->bmiHeader.biBitCount == 32) &&
(pbmi->bmiHeader.biCompression == BI_BITFIELDS)) ||
(pbmi->bmiHeader.biBitCount == 16)) {
// bitfields case
lSize += 3 * sizeof(RGBQUAD);
} else if (pbmi->bmiHeader.biBitCount == 1) {
// palette cases
LONG lPal = pbmi->bmiHeader.biClrUsed;
if ((lPal == 0) || (lPal > 2)) {
lPal = 2;
}
lSize += lPal * sizeof(RGBQUAD);
} else if (pbmi->bmiHeader.biBitCount == 4) {
// palette case
LONG lPal = pbmi->bmiHeader.biClrUsed;
if ((lPal == 0) || (lPal > 16)) {
lPal = 16;
}
lSize += lPal * sizeof(RGBQUAD);
} else if (pbmi->bmiHeader.biBitCount == 8){
// palette case
LONG lPal = pbmi->bmiHeader.biClrUsed;
if ((lPal == 0) || (lPal > 256)){
lPal = 256;
}
lSize += lPal * sizeof(RGBQUAD);
}
// assign calculated size to returned value
*plBmiSize = lSize;
return S_OK;
}
/**************************************************************************\
* GetBSTRResourceString
*
* This helper gets a BSTR from a resource location
*
* Arguments:
*
* lResourceID - Resource ID of the target BSTR value
* pBSTR - pointer to a BSTR value (caller must free this string)
* bLocal - TRUE - for local resources, FALSE - for wiaservc resources
*
* Return Value:
*
* Status
*
* History:
*
* 11/16/1999 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::GetBSTRResourceString(LONG lResourceID,BSTR *pBSTR,BOOL bLocal)
{
HRESULT hr = S_OK;
TCHAR szStringValue[255];
if(bLocal) {
//
// We are looking for a resource in our own private resource file
//
LoadString(g_hInst,lResourceID,szStringValue,sizeof(szStringValue));
//
// NOTE: caller must free this allocated BSTR
//
#ifdef UNICODE
*pBSTR = SysAllocString(szStringValue);
#else
WCHAR wszStringValue[255];
//
// convert szStringValue from char* to unsigned short* (ANSI only)
//
MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
szStringValue,
lstrlenA(szStringValue)+1,
wszStringValue,
sizeof(wszStringValue));
*pBSTR = SysAllocString(wszStringValue);
#endif
} else {
//
// We are looking for a resource in the wiaservc's resource file
//
hr = E_NOTIMPL;
}
return hr;
}
/**************************************************************************\
* GetOLESTRResourceString
*
* This helper gets a LPOLESTR from a resource location
*
* Arguments:
*
* lResourceID - Resource ID of the target BSTR value
* ppsz - pointer to a OLESTR value (caller must free this string)
* bLocal - TRUE - for local resources, FALSE - for wiaservc resources
*
* Return Value:
*
* Status
*
* History:
*
* 11/16/1999 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal)
{
HRESULT hr = S_OK;
TCHAR szStringValue[255];
if(bLocal) {
//
// We are looking for a resource in our own private resource file
//
LoadString(g_hInst,lResourceID,szStringValue,sizeof(szStringValue));
//
// NOTE: caller must free this allocated BSTR
//
#ifdef UNICODE
*ppsz = NULL;
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(szStringValue));
if(*ppsz != NULL) {
wcscpy(*ppsz,szStringValue);
} else {
return E_OUTOFMEMORY;
}
#else
WCHAR wszStringValue[255];
//
// convert szStringValue from char* to unsigned short* (ANSI only)
//
MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
szStringValue,
lstrlenA(szStringValue)+1,
wszStringValue,
sizeof(wszStringValue));
*ppsz = NULL;
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(wszStringValue));
if(*ppsz != NULL) {
wcscpy(*ppsz,wszStringValue);
} else {
return E_OUTOFMEMORY;
}
#endif
} else {
//
// We are looking for a resource in the wiaservc's resource file
//
hr = E_NOTIMPL;
}
return hr;
}
/**************************************************************************\
* BuildRootItemProperties
*
* This helper initialize the global arrays used for Property intialization.
* note: These globals are defined in ( DEFPROP.H )
*
* [Array Name] [Description] [Array Type]
*
* g_pszRootItemDefaults - Property name array (LPOLESTR)
* g_piRootItemDefaults - Property ID array (PROPID)
* g_pvRootItemDefaults - Property Variant array (PROPVARIANT)
* g_psRootItemDefaults - Property Spec array (PROPSPEC)
* g_wpiRootItemDefaults - WIA Property Info array (WIA_PROPERTY_INFO)
*
*
* Arguments:
*
* none
*
* Return Value:
*
* Status
*
* History:
*
* 11/16/1999 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::BuildRootItemProperties()
{
HRESULT hr = S_OK;
// start index after initial properties
INT iPropArrayIndex = NUM_ROOTITEMDEFAULTS;
// Intialize WIA_DPS_HORIZONTAL_BED_SIZE
g_pszRootItemDefaults[0] = WIA_DPS_HORIZONTAL_BED_SIZE_STR;
g_piRootItemDefaults [0] = WIA_DPS_HORIZONTAL_BED_SIZE;
g_pvRootItemDefaults [0].lVal = HORIZONTAL_BED_SIZE;
g_pvRootItemDefaults [0].vt = VT_I4;
g_psRootItemDefaults [0].ulKind = PRSPEC_PROPID;
g_psRootItemDefaults [0].propid = g_piRootItemDefaults [0];
g_wpiRootItemDefaults[0].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiRootItemDefaults[0].vt = g_pvRootItemDefaults [0].vt;
// Intialize WIA_DPS_VERTICAL_BED_SIZE
g_pszRootItemDefaults[1] = WIA_DPS_VERTICAL_BED_SIZE_STR;
g_piRootItemDefaults [1] = WIA_DPS_VERTICAL_BED_SIZE;
g_pvRootItemDefaults [1].lVal = VERTICAL_BED_SIZE;
g_pvRootItemDefaults [1].vt = VT_I4;
g_psRootItemDefaults [1].ulKind = PRSPEC_PROPID;
g_psRootItemDefaults [1].propid = g_piRootItemDefaults [1];
g_wpiRootItemDefaults[1].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiRootItemDefaults[1].vt = g_pvRootItemDefaults [1].vt;
// Intialize WIA_IPA_ACCESS_RIGHTS
g_pszRootItemDefaults[2] = WIA_IPA_ACCESS_RIGHTS_STR;
g_piRootItemDefaults [2] = WIA_IPA_ACCESS_RIGHTS;
g_pvRootItemDefaults [2].lVal = WIA_ITEM_READ|WIA_ITEM_WRITE;
g_pvRootItemDefaults [2].vt = VT_UI4;
g_psRootItemDefaults [2].ulKind = PRSPEC_PROPID;
g_psRootItemDefaults [2].propid = g_piRootItemDefaults [2];
g_wpiRootItemDefaults[2].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiRootItemDefaults[2].vt = g_pvRootItemDefaults [2].vt;
// Intialize WIA_DPS_OPTICAL_XRES
g_pszRootItemDefaults[3] = WIA_DPS_OPTICAL_XRES_STR;
g_piRootItemDefaults [3] = WIA_DPS_OPTICAL_XRES;
g_pvRootItemDefaults [3].lVal = OPTICAL_XRESOLUTION;
g_pvRootItemDefaults [3].vt = VT_I4;
g_psRootItemDefaults [3].ulKind = PRSPEC_PROPID;
g_psRootItemDefaults [3].propid = g_piRootItemDefaults [3];
g_wpiRootItemDefaults[3].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiRootItemDefaults[3].vt = g_pvRootItemDefaults [3].vt;
// Intialize WIA_DPS_OPTICAL_YRES
g_pszRootItemDefaults[4] = WIA_DPS_OPTICAL_YRES_STR;
g_piRootItemDefaults [4] = WIA_DPS_OPTICAL_YRES;
g_pvRootItemDefaults [4].lVal = OPTICAL_YRESOLUTION;
g_pvRootItemDefaults [4].vt = VT_I4;
g_psRootItemDefaults [4].ulKind = PRSPEC_PROPID;
g_psRootItemDefaults [4].propid = g_piRootItemDefaults [4];
g_wpiRootItemDefaults[4].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiRootItemDefaults[4].vt = g_pvRootItemDefaults [4].vt;
// Initialize WIA_DPA_FIRMWARE_VERSION
g_pszRootItemDefaults[5] = WIA_DPA_FIRMWARE_VERSION_STR;
g_piRootItemDefaults [5] = WIA_DPA_FIRMWARE_VERSION;
g_pvRootItemDefaults [5].bstrVal = SysAllocString(WIATSCAN_FIRMWARE_VERSION);
g_pvRootItemDefaults [5].vt = VT_BSTR;
g_psRootItemDefaults [5].ulKind = PRSPEC_PROPID;
g_psRootItemDefaults [5].propid = g_piRootItemDefaults [5];
g_wpiRootItemDefaults[5].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiRootItemDefaults[5].vt = g_pvRootItemDefaults [5].vt;
// Initialize WIA_IPA_ITEM_FLAGS
g_pszRootItemDefaults[6] = WIA_IPA_ITEM_FLAGS_STR;
g_piRootItemDefaults [6] = WIA_IPA_ITEM_FLAGS;
g_pvRootItemDefaults [6].lVal = WiaItemTypeRoot|WiaItemTypeFolder|WiaItemTypeDevice;
g_pvRootItemDefaults [6].vt = VT_I4;
g_psRootItemDefaults [6].ulKind = PRSPEC_PROPID;
g_psRootItemDefaults [6].propid = g_piRootItemDefaults [6];
g_wpiRootItemDefaults[6].lAccessFlags = WIA_PROP_READ|WIA_PROP_FLAG;
g_wpiRootItemDefaults[6].vt = g_pvRootItemDefaults [6].vt;
g_wpiRootItemDefaults[6].ValidVal.Flag.Nom = g_pvRootItemDefaults [6].lVal;
g_wpiRootItemDefaults[6].ValidVal.Flag.ValidBits = WiaItemTypeRoot|WiaItemTypeFolder|WiaItemTypeDevice;
if(g_bHasADF) {
//
// Initialize Automatic Document Feeder properties
//
}
if(g_bHasTPA) {
//
// Initialize Transparant Adapter properties
//
}
return hr;
}
/**************************************************************************\
* BuildTopItemProperties
*
* This helper initialize the global arrays used for Property intialization.
* note: These globals are defined in ( DEFPROP.H )
*
* [Array Name] [Description] [Array Type]
*
* g_pszItemDefaults - Property name array (LPOLESTR)
* g_piItemDefaults - Property ID array (PROPID)
* g_pvItemDefaults - Property Variant array (PROPVARIANT)
* g_psItemDefaults - Property Spec array (PROPSPEC)
* g_wpiItemDefaults - WIA Property Info array (WIA_PROPERTY_INFO)
*
* Arguments:
*
* none
*
* Return Value:
*
* Status
*
* History:
*
* 11/16/1999 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::BuildTopItemProperties()
{
HRESULT hr = S_OK;
// Intialize WIA_IPS_XRES (RANGE)
g_pszItemDefaults[0] = WIA_IPS_XRES_STR;
g_piItemDefaults [0] = WIA_IPS_XRES;
g_pvItemDefaults [0].lVal = INITIAL_XRESOLUTION;
g_pvItemDefaults [0].vt = VT_I4;
g_psItemDefaults [0].ulKind = PRSPEC_PROPID;
g_psItemDefaults [0].propid = g_piItemDefaults [0];
g_wpiItemDefaults[0].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[0].vt = g_pvItemDefaults [0].vt;
g_wpiItemDefaults[0].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[0].ValidVal.Range.Min = 12;
g_wpiItemDefaults[0].ValidVal.Range.Max = 1600;
g_wpiItemDefaults[0].ValidVal.Range.Nom = g_pvItemDefaults [0].lVal;
// Intialize WIA_IPS_YRES (RANGE)
g_pszItemDefaults[1] = WIA_IPS_YRES_STR;
g_piItemDefaults [1] = WIA_IPS_YRES;
g_pvItemDefaults [1].lVal = INITIAL_YRESOLUTION;
g_pvItemDefaults [1].vt = VT_I4;
g_psItemDefaults [1].ulKind = PRSPEC_PROPID;
g_psItemDefaults [1].propid = g_piItemDefaults [1];
g_wpiItemDefaults[1].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[1].vt = g_pvItemDefaults [1].vt;
g_wpiItemDefaults[1].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[1].ValidVal.Range.Min = 12;
g_wpiItemDefaults[1].ValidVal.Range.Max = 1600;
g_wpiItemDefaults[1].ValidVal.Range.Nom = g_pvItemDefaults [1].lVal;
// Intialize WIA_IPS_XEXTENT (RANGE)
g_pszItemDefaults[2] = WIA_IPS_XEXTENT_STR;
g_piItemDefaults [2] = WIA_IPS_XEXTENT;
g_pvItemDefaults [2].lVal = (INITIAL_XRESOLUTION * HORIZONTAL_BED_SIZE)/1000;
g_pvItemDefaults [2].vt = VT_I4;
g_psItemDefaults [2].ulKind = PRSPEC_PROPID;
g_psItemDefaults [2].propid = g_piItemDefaults [2];
g_wpiItemDefaults[2].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[2].vt = g_pvItemDefaults [2].vt;
g_wpiItemDefaults[2].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[2].ValidVal.Range.Min = 1;
g_wpiItemDefaults[2].ValidVal.Range.Max = g_pvItemDefaults [2].lVal;
g_wpiItemDefaults[2].ValidVal.Range.Nom = g_pvItemDefaults [2].lVal;
// Intialize WIA_IPS_YEXTENT (RANGE)
g_pszItemDefaults[3] = WIA_IPS_YEXTENT_STR;
g_piItemDefaults [3] = WIA_IPS_YEXTENT;
g_pvItemDefaults [3].lVal = (INITIAL_YRESOLUTION * VERTICAL_BED_SIZE)/1000;;
g_pvItemDefaults [3].vt = VT_I4;
g_psItemDefaults [3].ulKind = PRSPEC_PROPID;
g_psItemDefaults [3].propid = g_piItemDefaults [3];
g_wpiItemDefaults[3].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[3].vt = g_pvItemDefaults [3].vt;
g_wpiItemDefaults[3].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[3].ValidVal.Range.Min = 1;
g_wpiItemDefaults[3].ValidVal.Range.Max = g_pvItemDefaults [3].lVal;
g_wpiItemDefaults[3].ValidVal.Range.Nom = g_pvItemDefaults [3].lVal;
// Intialize WIA_IPS_XPOS (RANGE)
g_pszItemDefaults[4] = WIA_IPS_XPOS_STR;
g_piItemDefaults [4] = WIA_IPS_XPOS;
g_pvItemDefaults [4].lVal = 0;
g_pvItemDefaults [4].vt = VT_I4;
g_psItemDefaults [4].ulKind = PRSPEC_PROPID;
g_psItemDefaults [4].propid = g_piItemDefaults [4];
g_wpiItemDefaults[4].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[4].vt = g_pvItemDefaults [4].vt;
g_wpiItemDefaults[4].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[4].ValidVal.Range.Min = 0;
g_wpiItemDefaults[4].ValidVal.Range.Max = (g_wpiItemDefaults[2].ValidVal.Range.Max - 1);
g_wpiItemDefaults[4].ValidVal.Range.Nom = g_pvItemDefaults [4].lVal;
// Intialize WIA_IPS_YPOS (RANGE)
g_pszItemDefaults[5] = WIA_IPS_YPOS_STR;
g_piItemDefaults [5] = WIA_IPS_YPOS;
g_pvItemDefaults [5].lVal = 0;
g_pvItemDefaults [5].vt = VT_I4;
g_psItemDefaults [5].ulKind = PRSPEC_PROPID;
g_psItemDefaults [5].propid = g_piItemDefaults [5];
g_wpiItemDefaults[5].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[5].vt = g_pvItemDefaults [5].vt;
g_wpiItemDefaults[5].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[5].ValidVal.Range.Min = 0;
g_wpiItemDefaults[5].ValidVal.Range.Max = (g_wpiItemDefaults[3].ValidVal.Range.Max - 1);
g_wpiItemDefaults[5].ValidVal.Range.Nom = g_pvItemDefaults [5].lVal;
// Intialize WIA_IPA_DATATYPE (LIST)
g_pszItemDefaults[6] = WIA_IPA_DATATYPE_STR;
g_piItemDefaults [6] = WIA_IPA_DATATYPE;
g_pvItemDefaults [6].lVal = INITIAL_DATATYPE;
g_pvItemDefaults [6].vt = VT_I4;
g_psItemDefaults [6].ulKind = PRSPEC_PROPID;
g_psItemDefaults [6].propid = g_piItemDefaults [6];
g_wpiItemDefaults[6].lAccessFlags = WIA_PROP_RW|WIA_PROP_LIST;
g_wpiItemDefaults[6].vt = g_pvItemDefaults [6].vt;
g_wpiItemDefaults[6].ValidVal.List.pList = (BYTE*)g_DataTypeArray;
g_wpiItemDefaults[6].ValidVal.List.Nom = g_pvItemDefaults [6].lVal;
g_wpiItemDefaults[6].ValidVal.List.cNumList = NUM_DATATYPES;
// Intialize WIA_IPA_DEPTH (LIST)
g_pszItemDefaults[7] = WIA_IPA_DEPTH_STR;
g_piItemDefaults [7] = WIA_IPA_DEPTH;
g_pvItemDefaults [7].lVal = INITIAL_BITDEPTH;
g_pvItemDefaults [7].vt = VT_I4;
g_psItemDefaults [7].ulKind = PRSPEC_PROPID;
g_psItemDefaults [7].propid = g_piItemDefaults [7];
g_wpiItemDefaults[7].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[7].vt = g_pvItemDefaults [7].vt;
// Intialize WIA_IPS_BRIGHTNESS (RANGE)
g_pszItemDefaults[8] = WIA_IPS_BRIGHTNESS_STR;
g_piItemDefaults [8] = WIA_IPS_BRIGHTNESS;
g_pvItemDefaults [8].lVal = INITIAL_BRIGHTNESS;
g_pvItemDefaults [8].vt = VT_I4;
g_psItemDefaults [8].ulKind = PRSPEC_PROPID;
g_psItemDefaults [8].propid = g_piItemDefaults [8];
g_wpiItemDefaults[8].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[8].vt = g_pvItemDefaults [8].vt;
g_wpiItemDefaults[8].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[8].ValidVal.Range.Min = -127;
g_wpiItemDefaults[8].ValidVal.Range.Max = 128;
g_wpiItemDefaults[8].ValidVal.Range.Nom = g_pvItemDefaults [8].lVal;
// Intialize WIA_IPS_CONTRAST (RANGE)
g_pszItemDefaults[9] = WIA_IPS_CONTRAST_STR;
g_piItemDefaults [9] = WIA_IPS_CONTRAST;
g_pvItemDefaults [9].lVal = INITIAL_CONTRAST;
g_pvItemDefaults [9].vt = VT_I4;
g_psItemDefaults [9].ulKind = PRSPEC_PROPID;
g_psItemDefaults [9].propid = g_piItemDefaults [9];
g_wpiItemDefaults[9].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[9].vt = g_pvItemDefaults [9].vt;
g_wpiItemDefaults[9].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[9].ValidVal.Range.Min = -127;
g_wpiItemDefaults[9].ValidVal.Range.Max = 128;
g_wpiItemDefaults[9].ValidVal.Range.Nom = g_pvItemDefaults [9].lVal;
// Intialize WIA_IPS_CUR_INTENT (FLAG)
g_pszItemDefaults[10] = WIA_IPS_CUR_INTENT_STR;
g_piItemDefaults [10] = WIA_IPS_CUR_INTENT;
g_pvItemDefaults [10].lVal = WIA_INTENT_NONE;
g_pvItemDefaults [10].vt = VT_I4;
g_psItemDefaults [10].ulKind = PRSPEC_PROPID;
g_psItemDefaults [10].propid = g_piItemDefaults [10];
g_wpiItemDefaults[10].lAccessFlags = WIA_PROP_RW|WIA_PROP_FLAG;
g_wpiItemDefaults[10].vt = g_pvItemDefaults [10].vt;
g_wpiItemDefaults[10].ValidVal.Flag.Nom = g_pvItemDefaults [10].lVal;
g_wpiItemDefaults[10].ValidVal.Flag.ValidBits = WIA_INTENT_SIZE_MASK | WIA_INTENT_IMAGE_TYPE_MASK;
// Intialize WIA_IPA_PIXELS_PER_LINE (NONE)
g_pszItemDefaults[11] = WIA_IPA_PIXELS_PER_LINE_STR;
g_piItemDefaults [11] = WIA_IPA_PIXELS_PER_LINE;
g_pvItemDefaults [11].lVal = (INITIAL_XRESOLUTION * HORIZONTAL_BED_SIZE)/1000;
g_pvItemDefaults [11].vt = VT_I4;
g_psItemDefaults [11].ulKind = PRSPEC_PROPID;
g_psItemDefaults [11].propid = g_piItemDefaults [11];
g_wpiItemDefaults[11].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[11].vt = g_pvItemDefaults [11].vt;
// Intialize WIA_IPA_NUMER_OF_LINES (NONE)
g_pszItemDefaults[12] = WIA_IPA_NUMBER_OF_LINES_STR;
g_piItemDefaults [12] = WIA_IPA_NUMBER_OF_LINES;
g_pvItemDefaults [12].lVal = (INITIAL_YRESOLUTION * VERTICAL_BED_SIZE)/1000;
g_pvItemDefaults [12].vt = VT_I4;
g_psItemDefaults [12].ulKind = PRSPEC_PROPID;
g_psItemDefaults [12].propid = g_piItemDefaults [12];
g_wpiItemDefaults[12].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[12].vt = g_pvItemDefaults [12].vt;
// Intialize WIA_IPA_ITEM_TIME (NONE)
g_pszItemDefaults[13] = WIA_IPA_ITEM_TIME_STR;
g_piItemDefaults [13] = WIA_IPA_ITEM_TIME;
g_pvItemDefaults [13].lVal = 0;
g_pvItemDefaults [13].vt = VT_VECTOR|VT_I4;
g_psItemDefaults [13].ulKind = PRSPEC_PROPID;
g_psItemDefaults [13].propid = g_piItemDefaults [13];
g_wpiItemDefaults[13].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[13].vt = g_pvItemDefaults [13].vt;
// Intialize WIA_IPA_PREFERRED_FORMAT (NONE)
g_pszItemDefaults[14] = WIA_IPA_PREFERRED_FORMAT_STR;
g_piItemDefaults [14] = WIA_IPA_PREFERRED_FORMAT;
g_pvItemDefaults [14].puuid = INITIAL_FORMAT;
g_pvItemDefaults [14].vt = VT_CLSID;
g_psItemDefaults [14].ulKind = PRSPEC_PROPID;
g_psItemDefaults [14].propid = g_piItemDefaults [14];
g_wpiItemDefaults[14].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[14].vt = g_pvItemDefaults [14].vt;
// Intialize WIA_IPA_ITEM_SIZE (NONE)
g_pszItemDefaults[15] = WIA_IPA_ITEM_SIZE_STR;
g_piItemDefaults [15] = WIA_IPA_ITEM_SIZE;
g_pvItemDefaults [15].lVal = 0;
g_pvItemDefaults [15].vt = VT_I4;
g_psItemDefaults [15].ulKind = PRSPEC_PROPID;
g_psItemDefaults [15].propid = g_piItemDefaults [15];
g_wpiItemDefaults[15].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[15].vt = g_pvItemDefaults [15].vt;
// Intialize WIA_IPS_THRESHOLD (RANGE)
g_pszItemDefaults[16] = WIA_IPS_THRESHOLD_STR;
g_piItemDefaults [16] = WIA_IPS_THRESHOLD;
g_pvItemDefaults [16].lVal = 0;
g_pvItemDefaults [16].vt = VT_I4;
g_psItemDefaults [16].ulKind = PRSPEC_PROPID;
g_psItemDefaults [16].propid = g_piItemDefaults [16];
g_wpiItemDefaults[16].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[16].vt = g_pvItemDefaults [16].vt;
g_wpiItemDefaults[16].ValidVal.Range.Inc = 1;
g_wpiItemDefaults[16].ValidVal.Range.Min = -127;
g_wpiItemDefaults[16].ValidVal.Range.Max = 128;
g_wpiItemDefaults[16].ValidVal.Range.Nom = g_pvItemDefaults [16].lVal;
// Intialize WIA_IPA_FORMAT (LIST)
g_pszItemDefaults[17] = WIA_IPA_FORMAT_STR;
g_piItemDefaults [17] = WIA_IPA_FORMAT;
g_pvItemDefaults [17].puuid = INITIAL_FORMAT;
g_pvItemDefaults [17].vt = VT_CLSID;
g_psItemDefaults [17].ulKind = PRSPEC_PROPID;
g_psItemDefaults [17].propid = g_piItemDefaults [17];
g_wpiItemDefaults[17].lAccessFlags = WIA_PROP_RW|WIA_PROP_LIST;
g_wpiItemDefaults[17].vt = g_pvItemDefaults [17].vt;
g_wpiItemDefaults[17].ValidVal.ListGuid.pList = (GUID*)g_pInitialFormatArray;
g_wpiItemDefaults[17].ValidVal.ListGuid.Nom = *g_pvItemDefaults [17].puuid;
g_wpiItemDefaults[17].ValidVal.ListGuid.cNumList = NUM_INITIALFORMATS;
// Intialize WIA_IPA_TYMED (LIST)
g_pszItemDefaults[18] = WIA_IPA_TYMED_STR;
g_piItemDefaults [18] = WIA_IPA_TYMED;
g_pvItemDefaults [18].lVal = INITIAL_TYMED;
g_pvItemDefaults [18].vt = VT_I4;
g_psItemDefaults [18].ulKind = PRSPEC_PROPID;
g_psItemDefaults [18].propid = g_piItemDefaults [18];
g_wpiItemDefaults[18].lAccessFlags = WIA_PROP_RW|WIA_PROP_LIST;
g_wpiItemDefaults[18].vt = g_pvItemDefaults [18].vt;
g_wpiItemDefaults[18].ValidVal.List.pList = (BYTE*)g_TYMEDArray;
g_wpiItemDefaults[18].ValidVal.List.Nom = g_pvItemDefaults [18].lVal;
g_wpiItemDefaults[18].ValidVal.List.cNumList = NUM_TYMEDS;
// Intialize WIA_IPA_CHANNELS_PER_PIXEL (NONE)
g_pszItemDefaults[19] = WIA_IPA_CHANNELS_PER_PIXEL_STR;
g_piItemDefaults [19] = WIA_IPA_CHANNELS_PER_PIXEL;
g_pvItemDefaults [19].lVal = INITIAL_CHANNELS_PER_PIXEL;
g_pvItemDefaults [19].vt = VT_I4;
g_psItemDefaults [19].ulKind = PRSPEC_PROPID;
g_psItemDefaults [19].propid = g_piItemDefaults [19];
g_wpiItemDefaults[19].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[19].vt = g_pvItemDefaults [19].vt;
// Intialize WIA_IPA_BITS_PER_CHANNEL (NONE)
g_pszItemDefaults[20] = WIA_IPA_BITS_PER_CHANNEL_STR;
g_piItemDefaults [20] = WIA_IPA_BITS_PER_CHANNEL;
g_pvItemDefaults [20].lVal = INITIAL_BITS_PER_CHANNEL;
g_pvItemDefaults [20].vt = VT_I4;
g_psItemDefaults [20].ulKind = PRSPEC_PROPID;
g_psItemDefaults [20].propid = g_piItemDefaults [20];
g_wpiItemDefaults[20].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[20].vt = g_pvItemDefaults [20].vt;
// Intialize WIA_IPA_PLANAR (NONE)
g_pszItemDefaults[21] = WIA_IPA_PLANAR_STR;
g_piItemDefaults [21] = WIA_IPA_PLANAR;
g_pvItemDefaults [21].lVal = INITIAL_PLANAR;
g_pvItemDefaults [21].vt = VT_I4;
g_psItemDefaults [21].ulKind = PRSPEC_PROPID;
g_psItemDefaults [21].propid = g_piItemDefaults [21];
g_wpiItemDefaults[21].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[21].vt = g_pvItemDefaults [21].vt;
// Intialize WIA_IPA_BYTES_PER_LINE (NONE)
g_pszItemDefaults[22] = WIA_IPA_BYTES_PER_LINE_STR;
g_piItemDefaults [22] = WIA_IPA_BYTES_PER_LINE;
g_pvItemDefaults [22].lVal = 0;
g_pvItemDefaults [22].vt = VT_I4;
g_psItemDefaults [22].ulKind = PRSPEC_PROPID;
g_psItemDefaults [22].propid = g_piItemDefaults [22];
g_wpiItemDefaults[22].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[22].vt = g_pvItemDefaults [22].vt;
// Intialize WIA_IPA_MIN_BUFFER_SIZE (NONE)
g_pszItemDefaults[23] = WIA_IPA_MIN_BUFFER_SIZE_STR;
g_piItemDefaults [23] = WIA_IPA_MIN_BUFFER_SIZE;
g_pvItemDefaults [23].lVal = MIN_BUFFER_SIZE;
g_pvItemDefaults [23].vt = VT_I4;
g_psItemDefaults [23].ulKind = PRSPEC_PROPID;
g_psItemDefaults [23].propid = g_piItemDefaults [23];
g_wpiItemDefaults[23].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[23].vt = g_pvItemDefaults [23].vt;
// Intialize WIA_IPA_ACCESS_RIGHTS (NONE)
g_pszItemDefaults[24] = WIA_IPA_ACCESS_RIGHTS_STR;
g_piItemDefaults [24] = WIA_IPA_ACCESS_RIGHTS;
g_pvItemDefaults [24].lVal = WIA_ITEM_READ|WIA_ITEM_WRITE;
g_pvItemDefaults [24].vt = VT_UI4;
g_psItemDefaults [24].ulKind = PRSPEC_PROPID;
g_psItemDefaults [24].propid = g_piItemDefaults [24];
g_wpiItemDefaults[24].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[24].vt = g_pvItemDefaults [24].vt;
// Intialize WIA_IPA_SENSITIVITY (RANGE)
g_pszItemDefaults[25] = WIA_IPA_SENSITIVITY_STR;
g_piItemDefaults [25] = WIA_IPA_SENSITIVITY;
g_pvItemDefaults [25].fltVal = INITIAL_SENSITIVITY;
g_pvItemDefaults [25].vt = VT_R4;
g_psItemDefaults [25].ulKind = PRSPEC_PROPID;
g_psItemDefaults [25].propid = g_piItemDefaults [25];
g_wpiItemDefaults[25].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[25].vt = g_pvItemDefaults [25].vt;
g_wpiItemDefaults[25].ValidVal.RangeFloat.Inc = 1.0f;
g_wpiItemDefaults[25].ValidVal.RangeFloat.Min = -10.0f;
g_wpiItemDefaults[25].ValidVal.RangeFloat.Max = 10.0f;
g_wpiItemDefaults[25].ValidVal.RangeFloat.Nom = g_pvItemDefaults [25].fltVal;
// Intialize WIA_IPA_CORRECTION (RANGE)
g_pszItemDefaults[26] = WIA_IPA_CORRECTION_STR;
g_piItemDefaults [26] = WIA_IPA_CORRECTION;
g_pvItemDefaults [26].fltVal = INITIAL_CORRECTION;
g_pvItemDefaults [26].vt = VT_R4;
g_psItemDefaults [26].ulKind = PRSPEC_PROPID;
g_psItemDefaults [26].propid = g_piItemDefaults [26];
g_wpiItemDefaults[26].lAccessFlags = WIA_PROP_RW|WIA_PROP_RANGE;
g_wpiItemDefaults[26].vt = g_pvItemDefaults [26].vt;
g_wpiItemDefaults[26].ValidVal.RangeFloat.Inc = 1.0f;
g_wpiItemDefaults[26].ValidVal.RangeFloat.Min = -500.0f;
g_wpiItemDefaults[26].ValidVal.RangeFloat.Max = 500.0f;
g_wpiItemDefaults[26].ValidVal.RangeFloat.Nom = g_pvItemDefaults [26].fltVal;
// Intialize WIA_IPA_COMPRESSION (LIST)
g_pszItemDefaults[27] = WIA_IPA_COMPRESSION_STR;
g_piItemDefaults [27] = WIA_IPA_COMPRESSION;
g_pvItemDefaults [27].lVal = INITIAL_COMPRESSION;
g_pvItemDefaults [27].vt = VT_I4;
g_psItemDefaults [27].ulKind = PRSPEC_PROPID;
g_psItemDefaults [27].propid = g_piItemDefaults [27];
g_wpiItemDefaults[27].lAccessFlags = WIA_PROP_RW|WIA_PROP_LIST;
g_wpiItemDefaults[27].vt = g_pvItemDefaults [27].vt;
g_wpiItemDefaults[27].ValidVal.List.pList = (BYTE*)g_CompressionArray;
g_wpiItemDefaults[27].ValidVal.List.Nom = g_pvItemDefaults [27].lVal;
g_wpiItemDefaults[27].ValidVal.List.cNumList = NUM_COMPRESSIONS;
// Initialize WIA_IPA_ITEM_FLAGS
g_pszItemDefaults[28] = WIA_IPA_ITEM_FLAGS_STR;
g_piItemDefaults [28] = WIA_IPA_ITEM_FLAGS;
g_pvItemDefaults [28].lVal = WiaItemTypeImage|WiaItemTypeFile|WiaItemTypeDevice;
g_pvItemDefaults [28].vt = VT_I4;
g_psItemDefaults [28].ulKind = PRSPEC_PROPID;
g_psItemDefaults [28].propid = g_piItemDefaults [28];
g_wpiItemDefaults[28].lAccessFlags = WIA_PROP_READ|WIA_PROP_FLAG;
g_wpiItemDefaults[28].vt = g_pvItemDefaults [28].vt;
g_wpiItemDefaults[28].ValidVal.Flag.Nom = g_pvItemDefaults [28].lVal;
g_wpiItemDefaults[28].ValidVal.Flag.ValidBits = WiaItemTypeImage|WiaItemTypeFile|WiaItemTypeDevice;
// Initialize WIA_IPS_PHOTOMETRIC_INTERP
g_pszItemDefaults[29] = WIA_IPS_PHOTOMETRIC_INTERP_STR;
g_piItemDefaults [29] = WIA_IPS_PHOTOMETRIC_INTERP;
g_pvItemDefaults [29].lVal = INITIAL_PHOTOMETRIC_INTERP;
g_pvItemDefaults [29].vt = VT_I4;
g_psItemDefaults [29].ulKind = PRSPEC_PROPID;
g_psItemDefaults [29].propid = g_piItemDefaults [29];
g_wpiItemDefaults[29].lAccessFlags = WIA_PROP_READ|WIA_PROP_NONE;
g_wpiItemDefaults[29].vt = g_pvItemDefaults [29].vt;
return hr;
}
/**************************************************************************\
* BuildCapabilities
*
* This helper initialize the global capabilities array
*
* Arguments:
*
* none
*
* Return Value:
*
* Status
*
* History:
*
* 11/16/1999 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::BuildCapabilities()
{
HRESULT hr = S_OK;
if(g_bCapabilitiesInitialized) {
//
// Capabilities have already been initialized,
// so return S_OK.
//
return hr;
}
//
// Initialize EVENTS
//
// WIA_EVENT_DEVICE_CONNECTED
GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_NAME,&(g_Capabilities[0].wszName),TRUE);
GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_DESC,&(g_Capabilities[0].wszDescription),TRUE);
g_Capabilities[0].guid = (GUID*)&WIA_EVENT_DEVICE_CONNECTED;
g_Capabilities[0].ulFlags = WIA_NOTIFICATION_EVENT | WIA_ACTION_EVENT;
g_Capabilities[0].wszIcon = WIA_ICON_DEVICE_CONNECTED;
// WIA_EVENT_DEVICE_DISCONNECTED
GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_NAME,&(g_Capabilities[1].wszName),TRUE);
GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_DESC,&(g_Capabilities[1].wszDescription),TRUE);
g_Capabilities[1].guid = (GUID*)&WIA_EVENT_DEVICE_DISCONNECTED;
g_Capabilities[1].ulFlags = WIA_NOTIFICATION_EVENT;
g_Capabilities[1].wszIcon = WIA_ICON_DEVICE_DISCONNECTED;
//
// Initialize COMMANDS
//
// WIA_CMD_SYNCHRONIZE
GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_NAME,&(g_Capabilities[2].wszName),TRUE);
GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_DESC,&(g_Capabilities[2].wszDescription),TRUE);
g_Capabilities[2].guid = (GUID*)&WIA_CMD_SYNCHRONIZE;
g_Capabilities[2].ulFlags = 0;
g_Capabilities[2].wszIcon = WIA_ICON_SYNCHRONIZE;
// WIA_CMD_DELETE_ALL_ITEMS
GetOLESTRResourceString(IDS_CMD_DELETE_ALL_ITEMS_NAME,&(g_Capabilities[3].wszName),TRUE);
GetOLESTRResourceString(IDS_CMD_DELETE_ALL_ITEMS_DESC,&(g_Capabilities[3].wszDescription),TRUE);
g_Capabilities[3].guid = (GUID*)&WIA_CMD_DELETE_ALL_ITEMS;
g_Capabilities[3].ulFlags = 0;
g_Capabilities[3].wszIcon = WIA_ICON_DELETE_ALL_ITEMS;
// WIA_CMD_DELETE_DEVICE_TREE
GetOLESTRResourceString(IDS_CMD_DELETE_DEVICE_TREE_NAME,&(g_Capabilities[4].wszName),TRUE);
GetOLESTRResourceString(IDS_CMD_DELETE_DEVICE_TREE_DESC,&(g_Capabilities[4].wszDescription),TRUE);
g_Capabilities[4].guid = (GUID*)&WIA_CMD_DELETE_DEVICE_TREE;
g_Capabilities[4].ulFlags = 0;
g_Capabilities[4].wszIcon = WIA_ICON_DELETE_DEVICE_TREE;
// WIA_CMD_BUILD_DEVICE_TREE
GetOLESTRResourceString(IDS_CMD_BUILD_DEVICE_TREE_NAME,&(g_Capabilities[5].wszName),TRUE);
GetOLESTRResourceString(IDS_CMD_BUILD_DEVICE_TREE_DESC,&(g_Capabilities[5].wszDescription),TRUE);
g_Capabilities[5].guid = (GUID*)&WIA_CMD_BUILD_DEVICE_TREE;
g_Capabilities[5].ulFlags = 0;
g_Capabilities[5].wszIcon = WIA_ICON_BUILD_DEVICE_TREE;
g_bCapabilitiesInitialized = TRUE;
return hr;
}
/**************************************************************************\
* DeleteCapabilitiesArrayContents
*
* This helper cleans up allocated strings used in the global capabilities array
*
* Arguments:
*
* none
*
* Return Value:
*
* Status
*
* History:
*
* 11/16/1999 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::DeleteCapabilitiesArrayContents()
{
HRESULT hr = S_OK;
if(g_bCapabilitiesInitialized) {
g_bCapabilitiesInitialized = FALSE;
for (INT i = 0; i < NUM_CAPABILITIES;i++) {
CoTaskMemFree(g_Capabilities[i].wszName);
CoTaskMemFree(g_Capabilities[i].wszDescription);
}
}
return hr;
}