Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1060 lines
24 KiB

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1998
*
* TITLE: MiniItem.Cpp
*
* VERSION: 2.0
*
* AUTHOR: marke
*
* DATE: 30 Aug, 1998
*
* DESCRIPTION:
* Implementation of the WIA test camera item methods.
*
*******************************************************************************/
#include <stdio.h>
#include <objbase.h>
#include <sti.h>
#ifdef TEST_PER_USER_DATA
#ifdef UNICODE
#include <userenv.h>
#endif
#endif
#include "testusd.h"
#include "defprop.h"
extern HINSTANCE g_hInst; // Global hInstance
/*******************************************************************************
*
* ValidateDataTransferContext
*
* DESCRIPTION:
* Validate the data transfer context.
*
* PARAMETERS:
*
*******************************************************************************/
HRESULT
ValidateDataTransferContext(
PMINIDRV_TRANSFER_CONTEXT pDataTransferContext)
{
if (pDataTransferContext->lSize != sizeof(MINIDRV_TRANSFER_CONTEXT)) {
WIAS_ERROR((g_hInst,"ValidateDataTransferContext, invalid data transfer context"));
return E_INVALIDARG;;
}
//
// for tymed file or hglobal, only WiaImgFmt_MEMORYBMP is allowed
//
if ((pDataTransferContext->tymed == TYMED_FILE) ||
(pDataTransferContext->tymed == TYMED_HGLOBAL)) {
if (pDataTransferContext->guidFormatID != WiaImgFmt_BMP && pDataTransferContext->guidFormatID != WiaAudFmt_WAV) {
WIAS_ERROR((g_hInst,"ValidateDataTransferContext, invalid format"));
return E_INVALIDARG;;
}
}
//
// for tymed CALLBACK, only WiaImgFmt_MEMORYBMP is allowed
//
if (pDataTransferContext->tymed == TYMED_CALLBACK) {
if ((pDataTransferContext->guidFormatID != WiaImgFmt_BMP) &&
(pDataTransferContext->guidFormatID != WiaImgFmt_MEMORYBMP)) {
WIAS_ERROR((g_hInst,"AcquireDeviceData, invalid format"));
return E_INVALIDARG;;
}
}
//
// callback is always double buffered, non-callback never is
//
if (pDataTransferContext->pTransferBuffer == NULL) {
WIAS_ERROR((g_hInst, "AcquireDeviceData, invalid transfer buffer"));
return E_INVALIDARG;
}
return S_OK;
}
/**************************************************************************\
* SendBitmapHeader
*
*
*
* Arguments:
*
*
*
* Return Value:
*
* Status
*
* History:
*
* 11/17/1998 Original Version
*
\**************************************************************************/
HRESULT SendBitmapHeader(
IWiaDrvItem *pDrvItem,
PMINIDRV_TRANSFER_CONTEXT pTranCtx)
{
HRESULT hr;
WIAS_ASSERT(g_hInst, pDrvItem != NULL);
WIAS_ASSERT(g_hInst, pTranCtx != NULL);
WIAS_ASSERT(g_hInst, pTranCtx->tymed == TYMED_CALLBACK);
//
// driver is sending TOPDOWN data, must swap biHeight
//
// this routine assumes pTranCtx->pHeader points to a
// BITMAPINFO header (TYMED_FILE doesn't use this path
// and DIB is the only format supported now)
//
PBITMAPINFO pbmi = (PBITMAPINFO)pTranCtx->pTransferBuffer;
if (pTranCtx->guidFormatID == WiaImgFmt_MEMORYBMP) {
pbmi->bmiHeader.biHeight = -pbmi->bmiHeader.biHeight;
}
hr = pTranCtx->
pIWiaMiniDrvCallBack->
MiniDrvCallback(
IT_MSG_DATA,
IT_STATUS_TRANSFER_TO_CLIENT,
0,
0,
pTranCtx->lHeaderSize,
pTranCtx,
0);
if (hr == S_OK) {
//
// advance offset for destination copy
//
pTranCtx->cbOffset += pTranCtx->lHeaderSize;
}
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvDeleteItem
*
* Try to delete a device item. Device items for the test scanner may
* not be modified.
*
* Arguments:
*
* pWiasContext - The context of the item to delete
* lFlags - unused
* plDevErrVal - unused
*
* Return Value:
*
* Status
*
* History:
*
* 10/15/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvDeleteItem(
BYTE* pWiasContext,
LONG lFlags,
LONG* plDevErrVal)
{
*plDevErrVal = 0;
return STG_E_ACCESSDENIED;
}
/**************************************************************************\
* TestUsdDevice::drvAcquireItemData
*
* Scan data into buffer. This routine scans the entire contents into
* the destination buffer in one call. Status will be sent back if
* the callback routine is provided
*
* Arguments:
*
* pWiasContext - identifies ITEM context
* lFlags - unused
* pTranCtx - buffer and callback information
* plDevErrVal - error value
*
* Return Value:
*
* Status
*
* History:
*
* 11/17/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvAcquireItemData(
BYTE *pWiasContext,
LONG lFlags,
PMINIDRV_TRANSFER_CONTEXT pTranCtx,
LONG *plDevErrVal)
{
HRESULT hr;
// #define TEST_PER_USER_DATA 1
#ifdef TEST_PER_USER_DATA
#ifdef UNICODE
BOOL bRet;
TCHAR tszUserName[MAX_PATH];
DWORD dwBufSize;
HANDLE hToken;
PROFILEINFO profileInfo;
LONG lRet;
HKEY hKeyCurUser;
#endif
#endif
*plDevErrVal = 0;
//
// How to access per user setting in the USD
//
#ifdef TEST_PER_USER_DATA
#ifdef UNICODE
#ifdef DEBUG
dwBufSize = MAX_PATH;
bRet = GetUserName(tszUserName, &dwBufSize);
#endif
#endif
#endif
#ifdef TEST_PER_USER_DATA
#ifdef UNICODE
hToken = NULL;
__try {
hr = CoImpersonateClient();
if (FAILED(hr)) {
__leave;
}
#ifdef NEED_USER_PROFILE
bRet = OpenThreadToken(
GetCurrentThread(),
TOKEN_ALL_ACCESS,
TRUE,
&hToken);
if (! bRet) {
__leave;
}
//
// Get the client's user name
//
dwBufSize = MAX_PATH;
bRet = GetUserName(tszUserName, &dwBufSize);
//
// Revert to system account
//
hr = CoRevertToSelf();
if (FAILED(hr)) {
__leave;
}
hr = S_FALSE;
//
// Load the user profile
//
ZeroMemory(&profileInfo, sizeof(profileInfo));
profileInfo.dwSize = sizeof(profileInfo);
profileInfo.dwFlags = PI_NOUI;
profileInfo.lpUserName = tszUserName;
bRet = LoadUserProfile(hToken, &profileInfo);
if (! bRet) {
__leave;
}
//
// Access user portion of the registry
//
// Use profileInfo.hProfile instead of HKEY_CURRENT_USER
//
//
hKeyCurUser = (HKEY)profileInfo.hProfile;
#else
lRet = RegOpenCurrentUser(KEY_ALL_ACCESS, &hKeyCurUser);
if (lRet != ERROR_SUCCESS) {
__leave;
}
#endif
HKEY hKeyEnv;
lRet = RegOpenKey(
hKeyCurUser,
TEXT("Environment"),
&hKeyEnv);
if (lRet == ERROR_SUCCESS) {
RegCloseKey(hKeyEnv);
}
}
__finally {
if (hr == S_OK) {
CoRevertToSelf();
}
#ifdef NEED_USER_PROFILE
if (bRet) {
UnloadUserProfile(hToken, profileInfo.hProfile);
}
if (hToken) {
CloseHandle(hToken);
}
#else
if (hKeyCurUser) {
RegCloseKey(hKeyCurUser);
}
#endif
}
#endif
#endif
//
// 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(pTranCtx);
if (FAILED(hr)) {
return hr;
}
//
// get item specific driver data
//
MEMCAM_IMAGE_CONTEXT *pMCamContext;
pDrvItem->GetDeviceSpecContext((BYTE **)&pMCamContext);
if (!pMCamContext) {
WIAS_ERROR((g_hInst,"drvAcquireItemData, NULL item context"));
return E_POINTER;
}
//
// Use WIA services to fetch format specific info.
//
if (!IsEqualGUID (pTranCtx->guidFormatID, WiaAudFmt_WAV) )
{
hr = wiasGetImageInformation(pWiasContext,
0,
pTranCtx);
}
else
{
WIN32_FILE_ATTRIBUTE_DATA wfd;
GetFileAttributesEx (pMCamContext->pszCameraImagePath,GetFileExInfoStandard, &wfd);
pTranCtx->lItemSize = (LONG)wfd.nFileSizeLow;
}
if (hr != S_OK) {
return hr;
}
//
// determine if this is a callback or buffered transfer
//
if (pTranCtx->tymed == TYMED_CALLBACK) {
//
// For formats that have a data header, send it to the client
//
if (pTranCtx->lHeaderSize > 0) {
hr = SendBitmapHeader(
pDrvItem,
pTranCtx);
}
if (hr == S_OK) {
hr = CamLoadPictureCB(
pMCamContext,
pTranCtx,
plDevErrVal);
}
} else {
//
// inc past header
//
pTranCtx->cbOffset += pTranCtx->lHeaderSize;
hr = CamLoadPicture(
pMCamContext,
pTranCtx,
plDevErrVal);
}
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvInitItemProperties
*
* Initialize the device item properties.
*
* Arguments:
*
* pWiasContext - Pointer to WIA item context.
* lFLags - unused
* plDevErrVal - pointer to hardware error value.
*
*
* Return Value:
*
* Status
*
* History:
*
* 10/29/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvInitItemProperties(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
HRESULT hr;
LONG lItemType;
PMEMCAM_IMAGE_CONTEXT pContext;
//
// This device doesn't touch hardware to initialize the
// device item properties.
//
*plDevErrVal = 0;
//
// Parameter validation.
//
if (!pWiasContext) {
WIAS_ERROR((g_hInst,"drvInitItemProperties, invalid input pointers"));
return (E_INVALIDARG);
}
//
// Get a pointer to the associated driver item.
//
IWiaDrvItem* pDrvItem;
hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
if (FAILED(hr)) {
return hr;
}
//
// Root item has the all the device properties
//
hr = pDrvItem->GetItemFlags(&lItemType);
if (FAILED(hr)) {
return (hr);
}
if (lItemType & WiaItemTypeRoot) {
// Root item property init finishes here
return (InitDeviceProperties(pWiasContext,
plDevErrVal));
}
//
// If this is a file, init the properties
//
if (lItemType & WiaItemTypeImage) {
//
// Add the item property names.
//
hr = wiasSetItemPropNames(pWiasContext,
NUM_CAM_ITEM_PROPS,
gItemPropIDs,
gItemPropNames);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst,"drvInitItemProperties, wiasSetItemPropNames() failed"));
return (hr);
}
//
// Use WIA services to set the defaul item properties.
//
hr = wiasWriteMultiple(pWiasContext,
NUM_CAM_ITEM_PROPS,
gPropSpecDefaults,
(PROPVARIANT*)gPropVarDefaults);
if (FAILED(hr)) {
return (hr);
}
hr = pDrvItem->GetDeviceSpecContext((BYTE **)&pContext);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst,"drvInitItemProperties, GetDeviceSpecContext failed"));
return (hr);
}
hr = InitImageInformation(pWiasContext,
pContext,
plDevErrVal);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst,"drvInitItemProperties InitImageInformation() failed"));
return (hr);
}
}
else if (lItemType & WiaItemTypeAudio)
{
//
// Add the item property names.
//
hr = wiasSetItemPropNames(pWiasContext,
NUM_AUDIO_PROPS,
gAudioPropIDs,
gAudioPropNames);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst,"drvInitItemProperties, wiasSetItemPropNames() failed"));
return (hr);
}
//
// Use WIA services to set the defaul item properties.
//
hr = wiasWriteMultiple(pWiasContext,
NUM_AUDIO_PROPS,
gAudioPropDefaults,
(PROPVARIANT*)gAudioDefaults);
if (FAILED(hr)) {
return (hr);
}
hr = pDrvItem->GetDeviceSpecContext((BYTE **)&pContext);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst,"drvInitItemProperties, GetDeviceSpecContext failed"));
return (hr);
}
hr = InitAudioInformation (pWiasContext,
pContext,
plDevErrVal);
}
return (S_OK);
}
/**************************************************************************\
* TestUsdDevice::drvValidateItemProperties
*
* Validate the device item properties.
*
* Arguments:
*
* pWiasContext - wia item context
* lFlags - unused
* nPropSpec -
* pPropSpec -
* plDevErrVal - 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)
{
//
// This device doesn't touch hardware to validate the device item properties.
//
*plDevErrVal = 0;
//
// Parameter validation.
//
if (!pWiasContext || !pPropSpec) {
WIAS_ERROR((g_hInst,"drvValidateItemProperties, invalid input pointers"));
return E_POINTER;
}
//
// validate size
//
HRESULT hr = S_OK;
IWiaDrvItem* pDrvItem;
hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
if (FAILED(hr)) {
return hr;
}
LONG lItemType;
hr = pDrvItem->GetItemFlags(&lItemType);
if (hr == S_OK) {
if (lItemType & WiaItemTypeImage) {
//
// calc item size
//
hr = SetItemSize(pWiasContext);
//
// Change MinBufferSize property. Need to get Tymed and
// ItemSize first, since MinBufferSize in dependant on these
// properties.
//
LONG lTymed;
LONG lItemSize;
LONG lMinBufSize = 0;
HRESULT hr = S_OK;
hr = wiasReadPropLong(pWiasContext, WIA_IPA_TYMED, &lTymed, NULL, TRUE);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst,"drvValidateItemProperties, could not read TYMED property"));
return hr;
}
hr = wiasReadPropLong(pWiasContext, WIA_IPA_ITEM_SIZE, &lItemSize, NULL, TRUE);
if (SUCCEEDED(hr)) {
//
// Update the MinBufferSize property.
//
switch (lTymed) {
case TYMED_CALLBACK:
lMinBufSize = 65535;
break;
default:
lMinBufSize = lItemSize;
}
if (lMinBufSize) {
hr = wiasWritePropLong(pWiasContext, WIA_IPA_MIN_BUFFER_SIZE, lMinBufSize);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst, "drvValidateItemProperties, could not write value for WIA_IPA_MIN_BUFFER_SIZE"));
}
}
} else {
WIAS_ERROR((g_hInst, "drvValidateItemProperties, could not read value for ItemSize"));
}
} else if (lItemType & WiaItemTypeRoot) {
//
// Find out whether the Root Path property is changed
//
for (ULONG i = 0; i < nPropSpec; i++) {
if (((pPropSpec[i].ulKind == PRSPEC_PROPID) &&
(pPropSpec[i].propid == WIA_DPP_TCAM_ROOT_PATH)) ||
((pPropSpec[i].ulKind == PRSPEC_LPWSTR) &&
(wcscmp(pPropSpec[i].lpwstr, WIA_DPP_TCAM_ROOT_PATH_STR) == 0))) {
BSTR bstrRootPath;
//
// Retrieve the new value for Root Path property
//
hr = wiasReadPropStr(
pWiasContext,
WIA_DPP_TCAM_ROOT_PATH,
&bstrRootPath,
NULL,
TRUE);
if (FAILED(hr)) {
return (hr);
}
#ifdef UNICODE
wcscpy(gpszPath, bstrRootPath);
#else
wcstombs(gpszPath, bstrRootPath, MAX_PATH);
#endif
//
// Release the Root Path bstr
//
SysFreeString(bstrRootPath);
//
// Rebuild the item tree and send event notification
//
hr = DeleteDeviceItemTree(plDevErrVal);
if (FAILED(hr)) {
break;
}
hr = BuildDeviceItemTree(plDevErrVal);
if (FAILED(hr)) {
break;
}
m_guidLastEvent = WIA_EVENT_DEVICE_CONNECTED;
SetEvent(m_hSignalEvent);
break;
}
}
}
}
return (hr);
}
/**************************************************************************\
* TestUsdDevice::drvWriteItemProperties
*
* Write the device item properties to the hardware.
*
* Arguments:
*
* pWiasContext - the corresponding wia item context
* pmdtc - pointer to mini driver context
* pFlags - unused
* plDevErrVal - 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)
{
//
// Assume no device hardware errors.
//
*plDevErrVal = 0;
//
// Parameter validation.
//
if ((! pWiasContext) || (! pmdtc)) {
WIAS_ERROR((g_hInst,"drvWriteItemProperties, invalid input pointers"));
return E_POINTER;
}
//
// Get a pointer to the associated driver item.
//
IWiaDrvItem* pDrvItem;
HRESULT hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
if (FAILED(hr)) {
return hr;
}
PMEMCAM_IMAGE_CONTEXT pItemContext;
hr = pDrvItem->GetDeviceSpecContext((BYTE**)&pItemContext);
if (FAILED(hr)) {
WIAS_ERROR((g_hInst,"drvWriteItemProperties, NULL item context"));
return E_POINTER;
}
//
// Write the device item properties to the hardware here.
//
return hr;
}
/**************************************************************************\
* TestUsdDevice::drvReadItemProperties
*
* Read the device item properties from the hardware.
*
* Arguments:
*
* pWiasContext - wia item context
* lFlags - unused
* nPropSpec -
* pPropSpec -
* plDevErrVal - 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)
{
// 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. This can be done here.
*plDevErrVal = 0;
return S_OK;
}
/**************************************************************************\
* TestUsdDevice::drvLockWiaDevice
*
* Lock access to the device.
*
* Arguments:
*
* pWiasContext - unused,
* lFlags - unused
* plDevErrVal - device error value
*
*
* Return Value:
*
* Status
*
* History:
*
* 9/11/1998 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::drvLockWiaDevice(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
*plDevErrVal = 0;
if (m_pStiDevice)
{
return m_pStiDevice->LockDevice(100);
}
return S_OK;
}
/**************************************************************************\
* TestUsdDevice::drvUnLockWiaDevice
*
* Unlock access to the device.
*
* Arguments:
*
* pWiasContext - unused
* lFlags - unused
* plDevErrVal - device error value
*
*
* Return Value:
*
* Status
*
* History:
*
* 9/11/1998 Original Version
*
\**************************************************************************/
HRESULT TestUsdDevice::drvUnLockWiaDevice(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
plDevErrVal = 0;
return m_pStiDevice->UnLockDevice();
}
/**************************************************************************\
* TestUsdDevice::drvAnalyzeItem
*
* The test camera does not support imag analysis.
*
* Arguments:
*
* pWiasContext - Pointer to the device item context to be analyzed.
* lFlags - Operation flags.
* plDevErrVal - device error value
*
* Return Value:
*
* Status
*
* History:
*
* 10/15/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvAnalyzeItem(
BYTE *pWiasContext,
LONG lFlags,
LONG *plDevErrVal)
{
*plDevErrVal = 0;
return E_NOTIMPL;
}
/**************************************************************************\
* TestUsdDevice::drvFreeDrvItemContext
*
* The test scanner does not support imag analysis.
*
* Arguments:
*
* lFlags - unused
* pSpecContext - Pointer to item specific context.
* plDevErrVal - device error value
*
* Return Value:
*
* Status
*
* History:
*
* 10/15/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall TestUsdDevice::drvFreeDrvItemContext(
LONG lFlags,
BYTE *pSpecContext,
LONG *plDevErrVal)
{
PMEMCAM_IMAGE_CONTEXT pContext = (PMEMCAM_IMAGE_CONTEXT)pSpecContext;
if (pContext != NULL) {
if (pContext->pszCameraImagePath != NULL) {
free(pContext->pszCameraImagePath);
pContext->pszCameraImagePath = NULL;
}
}
return S_OK;
}