⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 errhandler.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
字号:
/*****************************************************************************
 *
 *  errhandler.cpp
 *
 *  Copyright (c) 2003 Microsoft Corporation.  All Rights Reserved.
 *
 *  DESCRIPTION:
 *
 *  CErrHandler is a simple error handler, which works together with
 *  the wiadriver.
 *  
 *******************************************************************************/

#include "stdafx.h"

#define MYDESCSTRING TEXT("Special driver device status error (only for testing purposes). Press 'Ok' to continue. Hitting 'Cancel' will abort the transfer.")

#define HANDLED_PRIVATE_STATUS_ERROR_1  MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 1001)

// {CFC1A4D4-5F27-4881-81E4-1BE314EB22F7}
static const GUID CLSID_WiaErrorHandler = 
{ 0xcfc1a4d4, 0x5f27, 0x4881, { 0x81, 0xe4, 0x1b, 0xe3, 0x14, 0xeb, 0x22, 0xf7 } };

static LONG g_cLocks = 0;

void LockModule(void)   { InterlockedIncrement(&g_cLocks); }
void UnlockModule(void) { InterlockedDecrement(&g_cLocks); }

class CErrHandler : public IWiaErrorHandler
{
public:

    STDMETHODIMP
    QueryInterface(const IID& iid_requested, void** ppInterfaceOut);

    STDMETHODIMP_(ULONG)
    AddRef(void);

    STDMETHODIMP_(ULONG)
    Release(void);

    STDMETHODIMP
    ReportStatus(
        IN  LONG        lFlags,
        IN  HWND        hwndParent,
        IN  IWiaItem2   *pWiaItem2,
        IN  HRESULT     hrStatus,
        IN  LONG        lPercentComplete);

    STDMETHODIMP
    GetStatusDescription(
        IN  LONG        lFlags,
        IN  IWiaItem2   *pWiaItem2,
        IN  HRESULT     hrStatus,
        OUT BSTR        *pbstrDescription);

private:

    LONG        m_nRefCount;
};

///
///  QueryInterface
///
STDMETHODIMP
CErrHandler::QueryInterface(const IID& iid_requested, void** ppInterfaceOut)
{
    HRESULT hr = S_OK;

    hr = ppInterfaceOut ? S_OK : E_POINTER;

    if (SUCCEEDED(hr))
    {
        *ppInterfaceOut = NULL;
    }
    
    //
    //  We support IID_IUnknown and IID_IWiaErrorHandler
    //
    if (SUCCEEDED(hr))
    {
        if (IID_IUnknown == iid_requested) 
        {
            *ppInterfaceOut = static_cast<IUnknown*>(this);
        }
        else if (IID_IWiaErrorHandler == iid_requested) 
        {
            *ppInterfaceOut = static_cast<IWiaErrorHandler*>(this);
        }
        else
        {
            hr = E_NOINTERFACE;
        }
    }

    if (SUCCEEDED(hr))
    {
        reinterpret_cast<IUnknown*>(*ppInterfaceOut)->AddRef();
    }

    return hr;
}

///
///  AddRef
///
STDMETHODIMP_(ULONG)
CErrHandler::AddRef(void)
{
    if (m_nRefCount == 0)
    {
        LockModule();
    }

    return InterlockedIncrement(&m_nRefCount);
}

///
///  Release
///
STDMETHODIMP_(ULONG)
CErrHandler::Release(void)
{
    ULONG nRetval = InterlockedDecrement(&m_nRefCount);

    if (0 == nRetval) 
    {
        delete this;
        UnlockModule();
    }

    return nRetval;
}

/*****************************************************************************
 *  
 *  @doc INTERNAL
 *  
 *  @func STDMETHODIMP | CErrHandler::ReportStatus | ReportStatus implementation
 *
 *  @parm   LONG | lFlags | 
 *          Flags - currently unused.
 *  
 *  @parm   HWND | hwndParent |
 *          Window handle provided by the application
 * 
 *  @parm   IWiaItem2 | pWiaItem2 | 
 *          The item which is currently being transferred
 *
 *  @parm   HRESULT | hrStatus | 
 *          Status code
 *
 *  @parm   LONG    | lPercentComplete
 *          Percent of operation completed (e.g. warming up device)
 *
 * 
 *  @comm
 *  ReportStatus handles HANDLED_PRIVATE_STATUS_ERROR_1 for which it displays a modal
 *  dialog box which enables a user to cancel the transfer or to continue.
 *  For all other messages we return WIA_STATUS_NOT_HANDLED
 *
 *  @rvalue S_OK    | 
 *              The function successfully handled the device status message.
 *
 *  @rvalue WIA_STATUS_NOT_HANDLED |
 *              The function does not handle this device status message
 *
 *  @rvalue E_XXX   | 
 *              Error 
 * 
 *****************************************************************************/
STDMETHODIMP
CErrHandler::ReportStatus(
    IN  LONG        lFlags,
    IN  HWND        hwndParent,
    IN  IWiaItem2   *pWiaItem2,
    IN  HRESULT     hrStatus,
    IN  LONG        lPercentComplete)
{
    HRESULT hr = pWiaItem2 ? WIA_STATUS_NOT_HANDLED : E_INVALIDARG;

    if ((WIA_STATUS_NOT_HANDLED == hr) && (HANDLED_PRIVATE_STATUS_ERROR_1 == hrStatus))
    {
        int i = MessageBox(hwndParent, MYDESCSTRING,TEXT("Driver UI Extension - Handling HANDLED_PRIVATE_STATUS_ERROR_1 message"),MB_OKCANCEL|MB_TASKMODAL|MB_ICONERROR);

        if (IDOK == i)
        {
            hr = S_OK;
        }
        else
        {
            hr = HANDLED_PRIVATE_STATUS_ERROR_1;
        }
    }

    return hr;
}

/*****************************************************************************
 *  
 *  @doc INTERNAL
 *  
 *  @func STDMETHODIMP | CErrHandler::GetStatusDescription | GetStatusDescription implementation
 *
 *  @parm   LONG | lFlags | 
 *          Flags - currently unused.
 *  
 *  @parm   IWiaItem2 | pWiaItem2 | 
 *          The item which is currently being transferred
 *
 *  @parm   HRESULT | hrStatus | 
 *          Status code
 *
 *  @parm   BSTR* | pbstrDescription |
 *          On S_OK this pbstrDescription will point to string with status description  
 *
 * 
 *  @comm
 *  GetStatusDescription handles HANDLED_PRIVATE_STATUS_ERROR_1 for which it returns
 *  a description string. It returns WIA_STATUS_NOT_HANDLED for all other messages
 *
 *  @rvalue S_OK    | 
 *              The function successfully handled the device status message.
 *
 *  @rvalue WIA_STATUS_NOT_HANDLED |
 *              The function does not handle this device status message
 *
 *  @rvalue E_XXX   | 
 *              Error 
 * 
 *****************************************************************************/
STDMETHODIMP
CErrHandler::GetStatusDescription(
    IN  LONG        lFlags,
    IN  IWiaItem2   *pWiaItem2,
    IN  HRESULT     hrStatus,
    OUT BSTR        *pbstrDescription)
{
    HRESULT hr = (pbstrDescription && pWiaItem2) ? WIA_STATUS_NOT_HANDLED : E_INVALIDARG;

    if ((WIA_STATUS_NOT_HANDLED == hr) && (HANDLED_PRIVATE_STATUS_ERROR_1 == hrStatus))
    {
        BSTR    bstrDescription = NULL;

        bstrDescription = SysAllocString(MYDESCSTRING);

        if (bstrDescription)
        {
            *pbstrDescription = bstrDescription;
            hr = S_OK;
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }

    return hr;
}


/*****************************************************************************
 *
 *  Class Object
 *
 *******************************************************************************/
class CErrClassObject : public IClassFactory
{
public:

    STDMETHODIMP
    QueryInterface(const IID& iid_requested, void** ppInterfaceOut)
    {
        HRESULT hr = S_OK;

        hr = ppInterfaceOut ? S_OK : E_POINTER;

        if (SUCCEEDED(hr))
        {
            *ppInterfaceOut = NULL;
        }

        //
        //  We only support IID_IUnknown and IID_IClassFactory
        //
        if (SUCCEEDED(hr))
        {
            if (IID_IUnknown == iid_requested) 
            {
                *ppInterfaceOut = static_cast<IUnknown*>(this);
            }
            else if (IID_IClassFactory == iid_requested) 
            {
                *ppInterfaceOut = static_cast<IClassFactory*>(this);
            }
            else
            {
                hr = E_NOINTERFACE;
            }
        }

        if (SUCCEEDED(hr))
        {
            reinterpret_cast<IUnknown*>(*ppInterfaceOut)->AddRef();
        }
    
        return hr;
    }

    STDMETHODIMP_(ULONG)
    AddRef(void)
    {
        LockModule();
        return 2;
    }
    
    STDMETHODIMP_(ULONG)
    Release(void)
    {
        UnlockModule();
        return 1;
    }

    STDMETHODIMP
    CreateInstance(IUnknown *pUnkOuter,
                   REFIID   riid,
                   void     **ppv)
    {
        CErrHandler  *pErrHandler = NULL;
        HRESULT      hr;

        hr = ppv ? S_OK : E_POINTER;

        if (SUCCEEDED(hr))
        {
            *ppv = 0;
        }

        if (SUCCEEDED(hr))
        {
            if (pUnkOuter)
            {
                hr = CLASS_E_NOAGGREGATION;
            }
        }

        if (SUCCEEDED(hr))
        {
            pErrHandler = new CErrHandler();

            hr = pErrHandler ? S_OK : E_OUTOFMEMORY;
        }

        if (SUCCEEDED(hr))
        {
            pErrHandler->AddRef();
            hr = pErrHandler->QueryInterface(riid, ppv);
            pErrHandler->Release();
        }

        return hr;
    }

    STDMETHODIMP
    LockServer(BOOL bLock)
    {
        if (bLock)
        {
            LockModule();
        }
        else
        {
            UnlockModule();
        }

        return S_OK;
    }
};

STDAPI DllCanUnloadNow(void)
{
    return (g_cLocks == 0) ? S_OK : S_FALSE;
}

STDAPI DllGetClassObject(REFCLSID   rclsid,
                         REFIID     riid,
                         void       **ppv)
{
    static  CErrClassObject s_FilterClass;

    HRESULT     hr;

    hr = ppv ? S_OK : E_INVALIDARG;

    if (SUCCEEDED(hr))
    {
        if (rclsid == CLSID_WiaErrorHandler)
        {
            hr = s_FilterClass.QueryInterface(riid, ppv);
        }
        else
        {
            *ppv = 0;
            hr = CLASS_E_CLASSNOTAVAILABLE;
        }
    }

    return hr;
}

STDAPI DllUnregisterServer()
{
    return S_OK;
}

STDAPI DllRegisterServer()
{
    return S_OK;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -