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.
1951 lines
58 KiB
1951 lines
58 KiB
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 2000
|
|
*
|
|
* TITLE: drvwrap.cpp
|
|
*
|
|
* VERSION: 1.0
|
|
*
|
|
* AUTHOR: ByronC
|
|
*
|
|
* DATE: 6 Nov, 2000
|
|
*
|
|
* DESCRIPTION:
|
|
* Declarations and definitions for the WIA driver wrapper class.
|
|
* It faciliates JIT loading/unloading of drivers and provides an extra layer
|
|
* of abstraction for WIA server components - they don't deal directly with
|
|
* driver interfaces. This is to make us more robust and implement smart
|
|
* driver handling.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#include "stiexe.h"
|
|
#include "lockmgr.h"
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::CDrvWrap
|
|
*
|
|
* Constructor for driver wrapper.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None.
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
CDrvWrap::CDrvWrap()
|
|
{
|
|
m_hDriverDLL = NULL;
|
|
m_hInternalMutex = NULL;
|
|
m_pDeviceInfo = NULL;
|
|
m_pUsdIUnknown = NULL;
|
|
m_pIStiUSD = NULL;
|
|
m_pIWiaMiniDrv = NULL;
|
|
m_pIStiDeviceControl = NULL;
|
|
m_bJITLoading = FALSE;
|
|
m_lWiaTreeCount = 0;
|
|
m_bPreparedForUse = FALSE;
|
|
m_bUnload = FALSE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::~CDrvWrap
|
|
*
|
|
* Desctructor for driver wrapper. Calls internal clear to make sure
|
|
* driver is unloaded if it hasn't been already. Releases any
|
|
* resources help by the wrapper that needs to live accross driver
|
|
* loading/unloading, such as the DEVICE_INFO
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None.
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
CDrvWrap::~CDrvWrap()
|
|
{
|
|
//
|
|
// Release driver interfaces and unload driver
|
|
//
|
|
InternalClear();
|
|
|
|
if (m_hInternalMutex) {
|
|
CloseHandle(m_hInternalMutex);
|
|
m_hInternalMutex = NULL;
|
|
}
|
|
|
|
if (m_pDeviceInfo) {
|
|
DestroyDevInfo(m_pDeviceInfo);
|
|
m_pDeviceInfo = NULL;
|
|
}
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::Initialize
|
|
*
|
|
* Initializes any object members that could not be set in the constructor,
|
|
* such as allocating resources that may fail.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
HRESULT CDrvWrap::Initialize()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
m_hInternalMutex = CreateMutex(NULL, FALSE, NULL);
|
|
m_pDeviceInfo = (DEVICE_INFO*) LocalAlloc(LPTR, sizeof(DEVICE_INFO));
|
|
if (!m_hInternalMutex || !m_pDeviceInfo) {
|
|
|
|
DBG_ERR(("CDrvWrap::Initialize, out of memory!"));
|
|
hr = E_OUTOFMEMORY;
|
|
} else {
|
|
hr = S_OK;
|
|
}
|
|
|
|
if (FAILED(hr)) {
|
|
if (m_hInternalMutex) {
|
|
CloseHandle(m_hInternalMutex);
|
|
m_hInternalMutex = NULL;
|
|
}
|
|
if (m_pDeviceInfo) {
|
|
LocalFree(m_pDeviceInfo);
|
|
m_pDeviceInfo = NULL;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::QueryInterface
|
|
*
|
|
* This QI will return it's own "this" pointer for IUnknown, but will
|
|
* delegate down to the USD for any other interface.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* iid - The interface ID of the requested interface.
|
|
* ppv - Pointer to variable receiving the interface pointer.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
HRESULT _stdcall CDrvWrap::QueryInterface(const IID& iid, void** ppv)
|
|
{
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
//
|
|
// Always delegate down to USD, unless asking for IUnknown
|
|
//
|
|
|
|
if (iid == IID_IUnknown) {
|
|
*ppv = (IUnknown*) this;
|
|
AddRef();
|
|
hr = S_OK;
|
|
} else {
|
|
if (PrepForUse(FALSE)) {
|
|
if (m_pUsdIUnknown) {
|
|
hr = m_pUsdIUnknown->QueryInterface(iid, ppv);
|
|
} else {
|
|
DBG_TRC(("CDrvWrap::QueryInterface, m_pUsdIUnknown == NULL"))
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::QueryInterface, attempting to call IStiUSD::QueryInterface when driver is not loaded"));
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::AddRef
|
|
*
|
|
* Notice that this method simply returns 2. We don't want to subject the
|
|
* lifetime of this object to ref-counting.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* 2
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
ULONG _stdcall CDrvWrap::AddRef(void)
|
|
{
|
|
ULONG ulCount = 2;
|
|
|
|
//
|
|
// Since we plan to manually load/unload the driver, we don't really want
|
|
// to honor any AddRef/Release calls.
|
|
//
|
|
|
|
return ulCount;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::Release
|
|
*
|
|
* Notice that this method simply returns 1. We don't want to subject the
|
|
* lifetime of this object to ref-counting.
|
|
*
|
|
* Arguments:
|
|
*
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* 1
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
ULONG _stdcall CDrvWrap::Release(void)
|
|
{
|
|
ULONG ulCount = 1;
|
|
|
|
//
|
|
// We don't want this object to be controlled with refcounting - the
|
|
// DEVICE_OBJECT will manually delete us when it's done. Also, since
|
|
// we want to manually load/unload the driver, we don't really want
|
|
// to honor any AddRef/Release calls down to it..
|
|
//
|
|
|
|
return ulCount;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::LoadInitDriver
|
|
*
|
|
* Load the USD and initialize it appropriately.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* hKeyDeviceParams - The device registry key. This is handed down to the
|
|
* driver during intialization. If it is NULL, we will
|
|
* attempt to find the real one to hand down to the
|
|
* driver. For volume devices, there is no registry
|
|
* key and NULL will be handed down.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
HRESULT CDrvWrap::LoadInitDriver(HKEY hKeyDeviceParams)
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
IUnknown *pThisUnk = NULL;
|
|
BOOL bOpenedKey = FALSE;
|
|
|
|
if (!m_pDeviceInfo) {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, can't load driver with no Device Information"));
|
|
return hr;
|
|
}
|
|
|
|
if (!m_pDeviceInfo->bValid) {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, called with invalid Device Information"));
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Create a new IStiDeviceControl object. This needs to be handed down to the
|
|
// driver during initialization. If we can't create it, then bail, since we
|
|
// wont be able to initialize the driver properly.
|
|
//
|
|
|
|
hr = CreateDeviceControl();
|
|
if (FAILED(hr)) {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, could not create IStiDeviceControl object. Aborting driver loading"));
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// If the hKeyDeviceParams is NULL, see if it is a real WIA device. If not, then
|
|
// it is supposed to be NULL, else see if we can get it from our DevMan, using
|
|
// this device's DevInfoData.
|
|
//
|
|
|
|
|
|
if ((hKeyDeviceParams == NULL) && (m_pDeviceInfo->dwInternalType & INTERNAL_DEV_TYPE_REAL)) {
|
|
|
|
//
|
|
// Check whether device is interface or devnode type device. Grab the
|
|
// HKey from the appropriate place
|
|
//
|
|
|
|
hKeyDeviceParams = g_pDevMan->GetDeviceHKey(m_pDeviceInfo->wszDeviceInternalName, NULL);
|
|
bOpenedKey = TRUE;
|
|
}
|
|
|
|
//
|
|
// We always create the USD object as aggregated, so first we get our IUnknown
|
|
// pointer to pass it it during CoCreate.
|
|
//
|
|
|
|
hr = QueryInterface(IID_IUnknown, (void**) &pThisUnk);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// Call our own version of CoCreate. This is to facilitate manual loading/unloading
|
|
// of drivers.
|
|
//
|
|
hr = MyCoCreateInstanceW(m_pDeviceInfo->wszUSDClassId,
|
|
pThisUnk,
|
|
IID_IUnknown,
|
|
(PPV) &m_pUsdIUnknown,
|
|
&m_hDriverDLL);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// QI for the IStiUSD interface. Notice that we can call our own
|
|
// QueryInterface since it delegates down to the driver via m_pUsdIUnknown.
|
|
//
|
|
hr = m_pUsdIUnknown->QueryInterface(IID_IStiUSD, (void**) &m_pIStiUSD);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// If this is a WIA device, QI for IWiaMiniDrv
|
|
//
|
|
if (IsWiaDevice()) {
|
|
hr = m_pUsdIUnknown->QueryInterface(IID_IWiaMiniDrv, (void**) &m_pIWiaMiniDrv);
|
|
if (FAILED(hr)) {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, WIA driver did not return IWiaMiniDrv interface for device (%ws)", getDeviceId()));
|
|
|
|
//
|
|
// Change hr here to indicate success. Even if WIA portoin of driver
|
|
// doesn't work, the STI portion does so far. Any WIA calls down to this
|
|
// driver will result in a E_NOINTERFACE error returned by the wrapper.
|
|
//
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We now have the Sti USD, so let's initialize it
|
|
//
|
|
|
|
hr = STI_Initialize(m_pIStiDeviceControl,
|
|
STI_VERSION_REAL,
|
|
hKeyDeviceParams);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// Now get capabilities of the USD and verify version
|
|
//
|
|
|
|
STI_USD_CAPS DeviceCapabilities;
|
|
hr = STI_GetCapabilities(&DeviceCapabilities);
|
|
if (SUCCEEDED(hr)) {
|
|
if (STI_VERSION_MIN_ALLOWED <= DeviceCapabilities.dwVersion) {
|
|
//
|
|
// Everything's fine, we've loaded the USD. Do any post
|
|
// initialization steps e.g. for MSC devices, make sure
|
|
// we tell the driver what drive/mount point is should
|
|
// be attached to.
|
|
//
|
|
|
|
} else {
|
|
|
|
//
|
|
// Driver version is too old, driver will probably not work, so unload it.
|
|
//
|
|
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, driver version is incompatible (too old)"));
|
|
hr = STIERR_OLD_VERSION;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, STI_GetCapabilities failed"));
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, STI_Initialize failed"));
|
|
}
|
|
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, QI to driver failed to return IStiUSD"));
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, failed to CoCreate driver, hr = 0x%08X", hr));
|
|
}
|
|
|
|
//
|
|
// If anything failed, call UnloadDriver to clean up.
|
|
//
|
|
|
|
if (FAILED(hr)) {
|
|
DBG_WRN(("CDrvWrap::LoadInitDriver, Aborting driver loading"));
|
|
pThisUnk->Release();
|
|
UnLoadDriver();
|
|
}
|
|
} else {
|
|
DBG_ERR(("CDrvWrap::LoadInitDriver, could not get this IUnknown to hand to driver for aggregation"));
|
|
}
|
|
|
|
//
|
|
// If we had to open the key, make sure we close it. We don't want to close the key
|
|
// if it was handed to us.
|
|
//
|
|
if(hKeyDeviceParams && bOpenedKey) RegCloseKey(hKeyDeviceParams);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::UnLoadDriver
|
|
*
|
|
* This method will unload the driver. NOTE assumption: This method
|
|
* assumes all WIA item references have already been released when this
|
|
* is called. The reason is that drvUnInitializeWia needs to be called for
|
|
* each WIA Item tree.
|
|
* TBD:
|
|
* One possible way to get around this is: Keep a list of WIA items
|
|
* attached to this device. Then, if we get here, call drvUnitializeWia,
|
|
* passing the root of each item tree. Another, much better way: store
|
|
* the driver item tree in the wrapper. Then destroy the tree either when
|
|
* asked, or when unloading the driver.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT CDrvWrap::UnLoadDriver()
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
|
|
//
|
|
// Release all driver interfaces we're holding
|
|
//
|
|
|
|
if (m_pIWiaMiniDrv) {
|
|
m_pIWiaMiniDrv->Release();
|
|
m_pIWiaMiniDrv = NULL;
|
|
}
|
|
if (m_pIStiUSD) {
|
|
m_pIStiUSD->Release();
|
|
m_pIStiUSD = NULL;
|
|
}
|
|
if (m_pUsdIUnknown) {
|
|
m_pUsdIUnknown->Release();
|
|
m_pUsdIUnknown = NULL;
|
|
}
|
|
|
|
//
|
|
// Release the device control object
|
|
//
|
|
|
|
if (m_pIStiDeviceControl) {
|
|
m_pIStiDeviceControl->Release();
|
|
m_pIStiDeviceControl = NULL;
|
|
}
|
|
|
|
//
|
|
// Unload the driver DLL. We load/unload the DLL manually to ensure the driver
|
|
// DLL is released when requested e.g. when the user wants to update the driver.
|
|
//
|
|
|
|
if (m_hDriverDLL) {
|
|
FreeLibrary(m_hDriverDLL);
|
|
m_hDriverDLL = NULL;
|
|
}
|
|
|
|
m_lWiaTreeCount = 0;
|
|
m_bPreparedForUse = FALSE;
|
|
m_bUnload = FALSE;
|
|
|
|
//
|
|
// Notice that we don't clear m_pDeviceInfo. This information is needed if we
|
|
// decide to reload the driver.
|
|
//
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::IsValid
|
|
*
|
|
* This object is considered valid if there is nothing preventing it from
|
|
* loading the driver.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
BOOL CDrvWrap::IsValid()
|
|
{
|
|
//
|
|
// This object is considered valid if there is nothing preventing
|
|
// it from loading the driver.
|
|
// We should be able to load the driver if:
|
|
// - We have a non-NULL DeviceInfo struct
|
|
// - The DeviceInfo struct contains valid data
|
|
// - The device is marked as active
|
|
//
|
|
|
|
if (m_pDeviceInfo) {
|
|
if (m_pDeviceInfo->bValid && (m_pDeviceInfo->dwDeviceState & DEV_STATE_ACTIVE)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::IsDriverLoaded
|
|
*
|
|
* Checks whether driver is loaded
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* True - driver is loaded
|
|
* False - driver is not loaded
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
BOOL CDrvWrap::IsDriverLoaded()
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
|
|
//
|
|
// We know driver is loaded if we have a valid interface pointer to it.
|
|
//
|
|
|
|
if (m_pUsdIUnknown) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::IsWiaDevice
|
|
*
|
|
* This method looks at the capabilities to decide whether a driver is
|
|
* WIA capable or not.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* TRUE - Is a WIA device
|
|
* FALSE - Not a WIA device
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
BOOL CDrvWrap::IsWiaDevice()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
|
|
//
|
|
// Drivers report that they're WIA capable in their STI capabilties
|
|
// entry.
|
|
//
|
|
|
|
return (m_pDeviceInfo->dwInternalType & INTERNAL_DEV_TYPE_WIA);
|
|
}
|
|
|
|
//
|
|
// If we don't know for sure it's a WIA device, then assume it isn't
|
|
//
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::IsWiaDriverLoaded
|
|
*
|
|
* This method looks at the IWIaMiniDrv interface pointer from the driver
|
|
* and returns whether it is valid or not.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* TRUE - WIA portion of driver is loaded
|
|
* FALSE - WIA portion of driver is not loaded
|
|
*
|
|
* History:
|
|
*
|
|
* 12/15/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
BOOL CDrvWrap::IsWiaDriverLoaded()
|
|
{
|
|
if (m_pIWiaMiniDrv) {
|
|
|
|
//
|
|
// If this interface is non-NULL, it means we successfully QI'd
|
|
// for it during initialization. Therefore the driver is loaded
|
|
// and is WIA capable.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::IsPlugged
|
|
*
|
|
* Checks the DEVICE_INFO to see whether the device has been marked as
|
|
* active. Devies on a PnP bus like USB are inactive if not plugged in.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* TRUE - Device is active, and is considered plugged
|
|
* FALSE - Device is inactive, and is not considered to be plugged in.
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
BOOL CDrvWrap::IsPlugged()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
|
|
//
|
|
// Check the device state
|
|
//
|
|
return (m_pDeviceInfo->dwDeviceState & DEV_STATE_ACTIVE);
|
|
}
|
|
|
|
//
|
|
// If we don't know for sure it's plugged in, then assume it isn't
|
|
//
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::IsVolumeDevice
|
|
*
|
|
* Checks the DEVICE_INFO to see whether the device is marked as a volume
|
|
* device.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* TRUE - Device is a volume device
|
|
* FALSE - Device is not a volume device
|
|
*
|
|
* History:
|
|
*
|
|
* 12/13/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
BOOL CDrvWrap::IsVolumeDevice()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
|
|
//
|
|
// Check the device internal type
|
|
//
|
|
|
|
return (m_pDeviceInfo->dwInternalType & INTERNAL_DEV_TYPE_VOL);
|
|
}
|
|
|
|
//
|
|
// If we don't know for sure it's a volume device, then assume it isn't
|
|
//
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::PrepForUse
|
|
*
|
|
* This method is generally called just before making a call down to the
|
|
* driver. It checks to see whether the driver is loaded, and if it isn't,
|
|
* will attempt to load it.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* bForWiaCall - Indicates whether this is being called because a WIA
|
|
* call is about to be made. This will check that the
|
|
* IWiaMiniDrv interface is valid.
|
|
* pRootItem - not used
|
|
*
|
|
* Return Value:
|
|
*
|
|
* TRUE - Device is ready to be used
|
|
* FALSE - Device cannot be used (driver could not be loaded/initialized)
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL CDrvWrap::PrepForUse(BOOL bForWiaCall, IWiaItem *pRootItem)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!m_bPreparedForUse || (bForWiaCall && !m_pIWiaMiniDrv)) {
|
|
|
|
//
|
|
// Only attempt to load if the device is marked as ACTIVE
|
|
//
|
|
if (m_pDeviceInfo->dwDeviceState & DEV_STATE_ACTIVE) {
|
|
if (!IsDriverLoaded()) {
|
|
hr = LoadInitDriver();
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
if (m_pDeviceInfo) {
|
|
|
|
if (bForWiaCall) {
|
|
//
|
|
// For WIA devices, check that we have a valid IWiaMiniDrv interface
|
|
//
|
|
if (IsWiaDevice()) {
|
|
if (!m_pIWiaMiniDrv) {
|
|
|
|
//
|
|
// Attempt to Q.I. for IWiaMiniDrv again.
|
|
//
|
|
hr = m_pUsdIUnknown->QueryInterface(IID_IWiaMiniDrv,
|
|
(VOID**) &m_pIWiaMiniDrv);
|
|
if (FAILED(hr) || !m_pIWiaMiniDrv) {
|
|
DBG_WRN(("CDrvWrap::PrepForUse, attempting to use WIA driver which doesn't have IWiaMiniDrv interface"));
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::PrepForUse, attempting to use driver with NULL DeviceInfo"));
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
m_bPreparedForUse = TRUE;
|
|
}
|
|
} else {
|
|
DBG_ERR(("CDrvWrap::PrepForUse, LoadInitDriver() failed (%x)", hr));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!m_bPreparedForUse) {
|
|
DBG_TRC(("CDrvWrap::PrepForUse, Driver could NOT be loaded!"));
|
|
}
|
|
|
|
return m_bPreparedForUse;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
//
|
|
// Accessor methods
|
|
//
|
|
|
|
WCHAR* CDrvWrap::getPnPId()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
//TBD:
|
|
//return m_pDeviceInfo->wszPnPId;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
WCHAR* CDrvWrap::getDeviceId()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->wszDeviceInternalName;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DWORD CDrvWrap::getLockHoldingTime()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->dwLockHoldingTime;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DWORD CDrvWrap::getGenericCaps()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->DeviceCapabilities.dwGenericCaps;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DWORD CDrvWrap::getPollTimeout()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->dwPollTimeout;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DWORD CDrvWrap::getDisableNotificationsValue()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->dwDisableNotifications;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DWORD CDrvWrap::getHWConfig()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->dwHardwareConfiguration;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DWORD CDrvWrap::getDeviceState()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->dwDeviceState;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
HRESULT CDrvWrap::setDeviceState(
|
|
DWORD dwNewDevState)
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
m_pDeviceInfo->dwDeviceState = dwNewDevState;
|
|
return S_OK;
|
|
}
|
|
DBG_WRN(("CDrvWrap::setDeviceState, attempting to set device state when DeviceInfo is NULL"));
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
DEVICE_INFO* CDrvWrap::getDevInfo()
|
|
{
|
|
return m_pDeviceInfo;
|
|
}
|
|
|
|
HRESULT CDrvWrap::setDevInfo(DEVICE_INFO *pInfo)
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
|
|
if (pInfo) {
|
|
//
|
|
// Caller allocates pInfo. We release it when we're done.
|
|
// DeviceInfo must be set before driver can be loaded.
|
|
//
|
|
m_pDeviceInfo = pInfo;
|
|
} else {
|
|
DBG_ERR(("CDrvWrap::setDevInfo, attempting to set DeviceInfo to invalid value (NULL)"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
ULONG CDrvWrap::getInternalType()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return m_pDeviceInfo->dwInternalType;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
VOID CDrvWrap::setJITLoading(BOOL bJITLoading)
|
|
{
|
|
m_bJITLoading = bJITLoading;
|
|
}
|
|
|
|
BOOL CDrvWrap::getJITLoading()
|
|
{
|
|
return m_bJITLoading;
|
|
}
|
|
|
|
LONG CDrvWrap::getWiaClientCount()
|
|
{
|
|
return m_lWiaTreeCount;
|
|
}
|
|
|
|
BOOL CDrvWrap::wasConnectEventThrown()
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
return (m_pDeviceInfo->dwDeviceState & DEV_STATE_CON_EVENT_WAS_THROWN);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
VOID CDrvWrap::setConnectEventState(
|
|
BOOL bEventState)
|
|
{
|
|
if (m_pDeviceInfo) {
|
|
if (bEventState) {
|
|
|
|
//
|
|
// Set the bit to indicate that connect event was thrown
|
|
//
|
|
m_pDeviceInfo->dwDeviceState = (m_pDeviceInfo->dwDeviceState | DEV_STATE_CON_EVENT_WAS_THROWN);
|
|
} else {
|
|
|
|
//
|
|
// Clear the bit that indicated the connect event was thrown
|
|
//
|
|
m_pDeviceInfo->dwDeviceState = (m_pDeviceInfo->dwDeviceState & (~DEV_STATE_CON_EVENT_WAS_THROWN));
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// End of accessor methods
|
|
//
|
|
/*****************************************************************************/
|
|
|
|
/*****************************************************************************/
|
|
//
|
|
// Wrapper methods for IStiUSD
|
|
//
|
|
|
|
HRESULT CDrvWrap::STI_Initialize(
|
|
IStiDeviceControl *pHelDcb,
|
|
DWORD dwStiVersion,
|
|
HKEY hParametersKey)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
//
|
|
// Initialize USD object
|
|
//
|
|
__try {
|
|
hr = m_pIStiUSD->Initialize(pHelDcb,
|
|
dwStiVersion,
|
|
hParametersKey);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER ) {
|
|
DBG_WRN(("CDrvWrap::STI_Initialize, exception in driver calling IStiUSD::Initialize"));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_Initialize, attempting to call IStiUSD::Initialize when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_GetCapabilities(STI_USD_CAPS *pDevCaps)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
//
|
|
// Get STI capabilities from USD object
|
|
//
|
|
__try {
|
|
hr = m_pIStiUSD->GetCapabilities(pDevCaps);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER ) {
|
|
DBG_WRN(("CDrvWrap::STI_GetCapabilities, exception in driver calling IStiUSD::GetCapabilities"));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_GetCapabilities, attempting to call IStiUSD::GetCapabilities when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_GetStatus(
|
|
STI_DEVICE_STATUS *pDevStatus)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
//
|
|
// Get status from USD object
|
|
//
|
|
__try {
|
|
hr = m_pIStiUSD->GetStatus(pDevStatus);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER ) {
|
|
DBG_WRN(("CDrvWrap::STI_GetStatus, exception in driver calling IStiUSD::GetStatus"));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_GetStatus, attempting to call IStiUSD::GetStatus when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_GetNotificationData(
|
|
STINOTIFY *lpNotify)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
//
|
|
// Get event data from USD object
|
|
//
|
|
__try {
|
|
hr = m_pIStiUSD->GetNotificationData(lpNotify);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER ) {
|
|
DBG_WRN(("CDrvWrap::STI_GetNotificationData, exception in driver calling IStiUSD::GetNotificationData"));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_GetNotificationData, attempting to call IStiUSD::GetNotificationData when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_SetNotificationHandle(
|
|
HANDLE hEvent)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
//
|
|
// Set notification handle for USD object
|
|
//
|
|
__try {
|
|
hr = m_pIStiUSD->SetNotificationHandle(hEvent);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER ) {
|
|
DBG_WRN(("CDrvWrap::STI_SetNotificationHandle, exception in driver calling IStiUSD::SetNotificationHandle"));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_SetNotificationHandle, attempting to call IStiUSD::SetNotificationHandle when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_DeviceReset()
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
//
|
|
// Get status from USD object
|
|
//
|
|
__try {
|
|
hr = m_pIStiUSD->DeviceReset();
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::STI_DeviceReset, driver returned failure with hr = 0x%08X", hr));
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::STI_DeviceReset, exception in driver calling IStiUSD::DeviceReset"));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_DeviceReset, attempting to call IStiUSD::DeviceReset when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_Diagnostic(
|
|
STI_DIAG *pDiag)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
__try {
|
|
hr = m_pIStiUSD->Diagnostic(pDiag);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::STI_Diagnostic, driver returned failure with hr = 0x%08X", hr));
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::STI_Diagnostic, exception in Diagnostic: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_Diagnostic, attempting to call IStiUSD::Diagnostic when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_LockDevice()
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
__try {
|
|
hr = m_pIStiUSD->LockDevice();
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::STI_LockDevice, driver returned failure with hr = 0x%08X", hr));
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::STI_LockDevice, exception in LockDevice: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_LockDevice, attempting to call IStiUSD::LockDevice when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_UnLockDevice()
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
__try {
|
|
hr = m_pIStiUSD->UnLockDevice();
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::STI_UnLockDevice, driver returned failure with hr = 0x%08X", hr));
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::STI_UnLockDevice, exception in UnLockDevice: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_UnlockDevice, attempting to call IStiUSD::UnLockDevice when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::STI_Escape(
|
|
STI_RAW_CONTROL_CODE EscapeFunction,
|
|
LPVOID lpInData,
|
|
DWORD cbInDataSize,
|
|
LPVOID pOutData,
|
|
DWORD dwOutDataSize,
|
|
LPDWORD pdwActualData)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(FALSE)) {
|
|
__try {
|
|
hr = m_pIStiUSD->Escape(EscapeFunction,
|
|
lpInData,
|
|
cbInDataSize,
|
|
pOutData,
|
|
dwOutDataSize,
|
|
pdwActualData);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::STI_Escape, driver returned failure with hr = 0x%08X", hr));
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::STI_Escape, exception in Escape: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::STI_Escape, attempting to call IStiUSD::Escape when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// End of IStiUSD wrapper methods
|
|
//
|
|
/*****************************************************************************/
|
|
|
|
/*****************************************************************************/
|
|
//
|
|
// Wrapper methods for IWiaMiniDrv. All mini-driver wrapper methods call PrepForUse(...) to make sure
|
|
// the driver is loaded before using.
|
|
//
|
|
|
|
HRESULT CDrvWrap::WIA_drvInitializeWia(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
BSTR bstrDeviceID,
|
|
BSTR bstrRootFullItemName,
|
|
IUnknown *pStiDevice,
|
|
IUnknown *pIUnknownOuter,
|
|
IWiaDrvItem **ppIDrvItemRoot,
|
|
IUnknown **ppIUnknownInner,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvInitializeWia(pWiasContext,
|
|
lFlags,
|
|
bstrDeviceID,
|
|
bstrRootFullItemName,
|
|
pStiDevice,
|
|
pIUnknownOuter,
|
|
ppIDrvItemRoot,
|
|
ppIUnknownInner,
|
|
plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvInitializeWia, Error calling driver: drvInitializeWia failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvInitializeWia, exception in drvInitializeWia: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvInitializeWia, attempting to call IWiaMiniDrv::drvInitializeWia when driver is not loaded"));
|
|
}
|
|
if (SUCCEEDED(hr)) {
|
|
// TBD: Take a sync primitive?
|
|
InterlockedIncrement(&m_lWiaTreeCount);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvGetDeviceErrorStr(
|
|
LONG lFlags,
|
|
LONG lDevErr,
|
|
LPOLESTR *ppszDevErrStr,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvGetDeviceErrorStr(lFlags,
|
|
lDevErr,
|
|
ppszDevErrStr,
|
|
plDevErrVal);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvGetDeviceErrorStr, call to driver's drvGetDeviceErrorStr failed (0x%08X)", hr));
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvGetDeviceErrorStr, attempting to call IWiaMiniDrv::drvGetDeviceErrorStr when driver is not loaded"));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvDeviceCommand(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
const GUID *plCommand,
|
|
IWiaDrvItem **ppWiaDrvItem,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvDeviceCommand(pWiasContext, lFlags, plCommand, ppWiaDrvItem, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvDeviceCommand, Error calling driver: drvDeviceCommand failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvDeviceCommand, exception in drvDeviceCommand: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvDeviceCommand, attempting to call IWiaMiniDrv::drvDeviceCommand when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvAcquireItemData(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
PMINIDRV_TRANSFER_CONTEXT pmdtc,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvAcquireItemData(pWiasContext, lFlags, pmdtc, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvAcquireItemData, Error calling driver : drvAcquireItemData failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvAcquireItemData, exception in drvAcquireItemData: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvAcquireItemData, attempting to call IWiaMiniDrv::drvAcquireItemData when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvInitItemProperties(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvInitItemProperties(pWiasContext,lFlags, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvInitItemProperties, Error calling driver: drvInitItemProperties failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvInitItemProperties, exception in drvInitItemProperties: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvInitItemProperties, attempting to call IWiaMiniDrv::drvInitItemProperties when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvValidateItemProperties(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
ULONG nPropSpec,
|
|
const PROPSPEC *pPropSpec,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvValidateItemProperties(pWiasContext,
|
|
lFlags,
|
|
nPropSpec,
|
|
pPropSpec,
|
|
plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvValidateItemProperties, Error calling driver: drvValidateItemProperties with hr = 0x%08X (This is normal if the app wrote an invalid value)", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvValidateItemProperties, exception in drvValidateItemProperties: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvValidateItemProperties, attempting to call IWiaMiniDrv::drvValidateItemProperties when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvWriteItemProperties(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
PMINIDRV_TRANSFER_CONTEXT pmdtc,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvWriteItemProperties(pWiasContext,
|
|
lFlags,
|
|
pmdtc,
|
|
plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvWriteItemProperties, error calling driver: drvWriteItemProperties failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvWriteItemProperties, exception in drvWriteItemProperties: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvWriteItemProperties, attempting to call IWiaMiniDrv::drvWriteItemProperties when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvReadItemProperties(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
ULONG nPropSpec,
|
|
const PROPSPEC *pPropSpec,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvReadItemProperties(pWiasContext,
|
|
lFlags,
|
|
nPropSpec,
|
|
pPropSpec,
|
|
plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvReadItemProperties, Error calling driver: drvReadItemProperties failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvReadItemProperties, exception in drvReadItemProperties: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvReadItemProperties, attempting to call IWiaMiniDrv::drvReadItemProperties when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvLockWiaDevice(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
|
|
//
|
|
// We request a lock on the device here. This is to ensure we don't
|
|
// make calls down to the driver, which then turns around and
|
|
// makes a call to us e.g. via the Fake Sti Device.
|
|
// We no longer require driver to use the Fake Sti Device for
|
|
// mutally exclusive locking - this way we do it automatically.
|
|
//
|
|
hr = g_pStiLockMgr->RequestLock(((CWiaItem*) pWiasContext)->m_pActiveDevice, WIA_LOCK_WAIT_TIME);
|
|
if (SUCCEEDED(hr)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvLockWiaDevice(pWiasContext, lFlags, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvLockWiaDevice, driver returned failure with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvLockWiaDevice, exception in drvLockWiaDevice: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvLockWiaDevice, could not get device lock"));
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvLockWiaDevice, attempting to call IWiaMiniDrv::drvLockWiaDevice when driver is not loaded"));
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvUnLockWiaDevice(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
//
|
|
// Note that we only want to call if the driver is loaded, therefore we don't
|
|
// call PrepForUse. PrepForUse will attempt to load the driver if it wasn't
|
|
// already loaded.
|
|
//
|
|
|
|
if (IsDriverLoaded()) {
|
|
|
|
//
|
|
// Request to unlock the device for mutally exclusive access.
|
|
// Ignore the return, we must still call the drvUnlockWiaDevice entry
|
|
// point.
|
|
//
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvUnLockWiaDevice(pWiasContext, lFlags, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvUnLockWiaDevice, driver returned failure with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvUnLockWiaDevice, exception in drvUnLockWiaDevice: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
hr = g_pStiLockMgr->RequestUnlock(((CWiaItem*) pWiasContext)->m_pActiveDevice);
|
|
|
|
if (SUCCEEDED(hr) && m_bUnload) {
|
|
UnLoadDriver();
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvUnLockWiaDevice, attempting to call IWiaMiniDrv::drvUnLockWiaDevice when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvAnalyzeItem(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvAnalyzeItem(pWiasContext, lFlags, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvAnalyzeItem, Error calling driver: drvAnalyzeItem failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvAnalyzeItem, exception in drvAnalyzeItem: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvAnalyzeItem, attempting to call IWiaMiniDrv::drvAnalyzeItem when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvDeleteItem(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvDeleteItem(pWiasContext, lFlags, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvDeleteItem, Error calling driver: drvDeleteItem failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR( ("CDrvWrap::WIA_drvDeleteItem, exception in drvDeleteItem: %0xX", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvDeleteItem, attempting to call IWiaMiniDrv::drvDeleteItem when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvFreeDrvItemContext(
|
|
LONG lFlags,
|
|
BYTE *pSpecContext,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvFreeDrvItemContext(lFlags, pSpecContext, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvFreeDrvItemContext, Error calling driver: drvFreeDrvItemContext failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR( ("CDrvWrap::WIA_drvFreeDrvItemContext, exception in drvFreeDrvItemContext: %0xX", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvFreeDrvItemContext, attempting to call IWiaMiniDrv::drvFreeDrvItemContext when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvGetCapabilities(
|
|
BYTE *pWiasContext,
|
|
LONG ulFlags,
|
|
LONG *pcelt,
|
|
WIA_DEV_CAP_DRV **ppCapabilities,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvGetCapabilities(pWiasContext, ulFlags, pcelt, ppCapabilities, plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvGetCapabilities, driver returned failure with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvGetCapabilities, exception in drvGetCapabilities: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvGetCapabilities, attempting to call IWiaMiniDrv::drvGetCapabilities when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvGetWiaFormatInfo(
|
|
BYTE *pWiasContext,
|
|
LONG lFlags,
|
|
LONG *pcelt,
|
|
WIA_FORMAT_INFO **ppwfi,
|
|
LONG *plDevErrVal)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvGetWiaFormatInfo(pWiasContext,
|
|
lFlags,
|
|
pcelt,
|
|
ppwfi,
|
|
plDevErrVal);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvGetWiaFormatInfo, Error calling driver : drvGetWiaFormatInfo failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(*plDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR( ("CDrvWrap::WIA_drvGetWiaFormatInfo, exception in drvGetWiaFormatInfo: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvGetWiaFormatInfo, attempting to call IWiaMiniDrv::drvGetWiaFormatInfo when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvNotifyPnpEvent(
|
|
const GUID *pEventGUID,
|
|
BSTR bstrDeviceID,
|
|
ULONG ulReserved)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
LONG lDevErrVal = 0;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvNotifyPnpEvent(pEventGUID, bstrDeviceID, ulReserved);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvNotifyPnpEvent, driver returned failure with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(lDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvNotifyPnpEvent, exception in drvNotifyPnpEvent: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvNotifyPnpEvent, attempting to call IWiaMiniDrv::drvNotifyPnpEvent when driver is not loaded"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDrvWrap::WIA_drvUnInitializeWia(
|
|
BYTE *pWiasContext)
|
|
{
|
|
HRESULT hr = WIA_ERROR_OFFLINE;
|
|
LONG lDevErrVal = 0;
|
|
|
|
if (PrepForUse(TRUE)) {
|
|
__try {
|
|
hr = m_pIWiaMiniDrv->drvUnInitializeWia(pWiasContext);
|
|
|
|
if(FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvUnInitializeWia, Error calling driver: drvUnInitializeWia failed with hr = 0x%08X", hr));
|
|
ReportMiniDriverError(lDevErrVal, NULL);
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DBG_ERR(("CDrvWrap::WIA_drvUnInitializeWia, exception in drvUnInitializeWia: 0x%X", GetExceptionCode()));
|
|
hr = WIA_ERROR_EXCEPTION_IN_DRIVER;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::WIA_drvUnInitializeWia, attempting to call IWiaMiniDrv::drvUnInitializeWia when driver is not loaded"));
|
|
}
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
// TBD: Take a sync primitive?
|
|
if(InterlockedDecrement(&m_lWiaTreeCount) == 0) {
|
|
// No item trees left.
|
|
// Note that we can't unload now, since the device still needs to
|
|
// be unlocked, therefore simply mark it to be unloaded by
|
|
// WIA_drvUnlockWiaDevice.
|
|
if (m_bJITLoading) {
|
|
m_bUnload = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
//
|
|
// End of wrapper methods for IWiaMiniDrv
|
|
//
|
|
/*****************************************************************************/
|
|
|
|
//
|
|
// Private methods
|
|
//
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::CreateDeviceControl
|
|
*
|
|
* Creates a IStiDeviceControl object to hand down to the driver during
|
|
* its initialization.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
HRESULT CDrvWrap::CreateDeviceControl()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (m_pDeviceInfo) {
|
|
|
|
DWORD dwBusType = 0;
|
|
DWORD dwControlTypeType = 0;
|
|
|
|
//
|
|
// Bus type is retrieved from dwHardwareConfiguration in the DeviceInformation struct
|
|
// Use this to determine ControlTypeType
|
|
//
|
|
|
|
dwBusType = m_pDeviceInfo->dwHardwareConfiguration;
|
|
|
|
//
|
|
// Convert STI bit flags for device mode into HEL_ bit mask
|
|
//
|
|
|
|
if (dwBusType & (STI_HW_CONFIG_USB | STI_HW_CONFIG_SCSI)) {
|
|
dwControlTypeType = HEL_DEVICE_TYPE_WDM;
|
|
}
|
|
else if (dwBusType & STI_HW_CONFIG_PARALLEL) {
|
|
dwControlTypeType = HEL_DEVICE_TYPE_PARALLEL;
|
|
}
|
|
else if (dwBusType & STI_HW_CONFIG_SERIAL) {
|
|
dwControlTypeType = HEL_DEVICE_TYPE_SERIAL;
|
|
}
|
|
else {
|
|
DBG_WRN(("CDrvWrap::CreateDeviceControl, Cannot determine device control type, resorting to WDM"));
|
|
dwControlTypeType = HEL_DEVICE_TYPE_WDM;
|
|
}
|
|
|
|
hr = NewDeviceControl(dwControlTypeType,
|
|
(STI_DEVICE_CREATE_STATUS | STI_DEVICE_CREATE_FOR_MONITOR),
|
|
m_pDeviceInfo->wszPortName,
|
|
0,
|
|
&m_pIStiDeviceControl);
|
|
if (FAILED(hr)) {
|
|
m_pIStiDeviceControl = NULL;
|
|
DBG_WRN(("CDrvWrap::CreateDeviceControl, failed to create new device control object"));
|
|
}
|
|
} else {
|
|
DBG_WRN(("CDrvWrap::CreateDeviceControl, can't create IStiDeviceControl with NULL device information"));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::InternalClear
|
|
*
|
|
* This will unload the driver, if it is loaded, and clear member
|
|
* variables associated with the loaded driver state.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* InternalClear
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 11/06/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
HRESULT CDrvWrap::InternalClear()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (IsDriverLoaded()) {
|
|
hr = UnLoadDriver();
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CDrvWrap::InternalClear, Error unloading driver"));
|
|
}
|
|
}
|
|
m_hDriverDLL = NULL;
|
|
m_pUsdIUnknown = NULL;
|
|
m_pIStiUSD = NULL;
|
|
m_pIWiaMiniDrv = NULL;
|
|
m_pIStiDeviceControl = NULL;
|
|
m_bJITLoading = FALSE;
|
|
m_lWiaTreeCount = 0;
|
|
m_bPreparedForUse = FALSE;
|
|
m_bUnload = FALSE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CDrvWrap::::ReportMiniDriverError
|
|
*
|
|
* Report a mini driver error. The caller is responsible for
|
|
* locking/unlocking the device. In most cases, the driver is already
|
|
* locked when ReportMiniDriverError is called, so there is no need to lock
|
|
* is again here.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* lDevErr - Error value returned from the mini driver.
|
|
* pszWhat - What the class driver was doing when the error ocured.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 10/20/1998 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT CDrvWrap::ReportMiniDriverError(
|
|
LONG lDevErr,
|
|
LPOLESTR pszWhat)
|
|
{
|
|
DBG_FN(CDrvWrap::ReportMiniDriverError);
|
|
HRESULT hr = S_OK;
|
|
LONG lFlags = 0;
|
|
LONG lDevErrVal;
|
|
|
|
if (lDevErr) {
|
|
LPOLESTR pszErr = NULL;
|
|
|
|
WIA_drvGetDeviceErrorStr(lFlags, lDevErr, &pszErr, &lDevErrVal);
|
|
|
|
_try {
|
|
if (FAILED(hr)) {
|
|
pszErr = NULL;
|
|
}
|
|
|
|
if (pszWhat) {
|
|
DBG_ERR(("Device error during %ws", pszWhat));
|
|
}
|
|
|
|
if (pszErr) {
|
|
DBG_ERR((" %ws", pszErr));
|
|
}
|
|
}
|
|
_finally {
|
|
};
|
|
}
|
|
else {
|
|
hr = S_FALSE;
|
|
}
|
|
return hr;
|
|
}
|
|
|