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

📄 wiadriver.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        else
        {
            WIAS_ERROR((g_hInst, "wiasReadPropLong(WIA_IPS_PHOTOMETRIC_INTERP) failed, hr: 0x%X", hr));
        }
    }
    
    //
    // The discrete bits per channel table is described by the new WIA_IPA_RAW_BITS_PER_CHANNEL:
    //
    if(S_OK == hr)
    {
        memset(&RawHeader.BitsPerChannel[0], 0, sizeof(RawHeader.BitsPerChannel)); 
        
        PROPSPEC ps;
        ps.ulKind = PRSPEC_PROPID;
        ps.propid = WIA_IPA_RAW_BITS_PER_CHANNEL;
        PROPVARIANT pv = {0};

        hr = wiasReadMultiple(pWiasContext, 1, &ps, &pv, NULL);
        if(S_OK == hr)
        {
            ULONG ulItemCount = (pv.caub.cElems > 8) ? 8 : pv.caub.cElems;
            for(ULONG i = 0; i < pv.caub.cElems; i++)
            {
                RawHeader.BitsPerChannel[i] = *(BYTE *)((BYTE *)pv.caub.pElems + i * sizeof(BYTE));
            }
        }
    }
    
    //
    // In the case of this sample the image data is retrieved from a resource bitmap.
    //
    // Important: this bitmap must be initialized by the WiaDevice::InitializeForDownload 
    // before calling this function. 
    //
    if(S_OK == hr)
    {
        if(!m_WiaDevice.InitializedForDownload())
        {
            //
            // S_FALSE returned from this function would be interpreted as a cancel request:
            //
            hr = E_INVALIDARG; 
            WIAS_ERROR((g_hInst, "Bitmap not initialized correctly, hr: 0x%X", hr));
        }
    }

    if(S_OK == hr)
    {
        //
        // For the line order use the BitmapData object initialized for the sample bitmap that 
        // we are using: the "Stride" field value sign indicates the line order: 
        //
        RawHeader.LineOrder = ((m_WiaDevice.GetBitmapData())->Stride < 0) ? 
            WIA_LINE_ORDER_BOTTOM_TO_TOP : WIA_LINE_ORDER_TOP_TO_BOTTOM; 
    
        //
        // We won't be using a color palette here but it would be possible to try to retrieve
        // the color palette, if any, from the DIB header describing the sample bitmap:
        //
        RawHeader.PaletteSize = 0; 
        RawHeader.PaletteOffset = 0;
    }        

    //
    // Write the header to the stream provided to us:
    //                                
    ULONG ulBytesWritten = 0;
    if(S_OK == hr)
    {
        hr = pDestination->Write(&RawHeader, RawHeader.HeaderSize, &ulBytesWritten);
    }
   
    return hr;
}



HRESULT CWIADriver::DownloadToStream(           LONG                           lFlags,
                                     __in       BYTE                           *pWiasContext,
                                     __in       PMINIDRV_TRANSFER_CONTEXT      pmdtc,
                                     const      GUID                           &guidItemCategory,
                                     const      GUID                           &guidFormatID,
                                     __callback IWiaMiniDrvTransferCallback    *pTransferCallback,
                                     __out      LONG                           *plDevErrVal)
{
    HRESULT hr                  = S_OK;
    BSTR    bstrItemName        = NULL;
    BSTR    bstrFullItemName    = NULL;
    UINT    uiBitmapResourceID  = GetBitmapResourceIDFromCategory(guidItemCategory);

    //
    // A maximum of 10 image transfers (including final and preview scans) can be requested 
    // from the Feeder item before the driver will return WIA_ERROR_PAPER_EMPTY. In order to 
    // reset the counter (used only for the Feeder item) the application must change a Feeder 
    // item property current value or reload the driver.
    //
    // IMPORTANT: 
    // 
    // Legacy WIA applications such as Scan Wizard requires WIA_ERROR_PAPER_EMPTY
    // (as the return code for IWiaMiniDrv::drvAcquireItemData) in order to stop 
    // normally a Feeder acquisition sequence. 
    //
    WIA_DRIVER_ITEM_CONTEXT *pWiaDriverItemContext = NULL;
    hr = wiasGetDriverItemPrivateContext(pWiasContext, (BYTE**)&pWiaDriverItemContext);
    if ((!pWiaDriverItemContext) && (SUCCEEDED(hr)))
    {
        hr = E_POINTER;
    }
    if (FAILED(hr))
    {
        WIAS_ERROR((g_hInst, "Failed to get private driver item context data, hr = 0x%lx", hr));
    }
    
    const ULONG ulMaxTransfers = 10;
    if ((SUCCEEDED(hr)) && (IsEqualGUID(WIA_CATEGORY_FEEDER, guidItemCategory)))
    {
        //
        // Limit the number of "continuous" transfers from the Feeder item - 
        // without this Scan Wizard would not stop requesting transfers:
        //
        if (pWiaDriverItemContext->ulFeederTransferCount >= ulMaxTransfers)
        {
            hr = WIA_ERROR_PAPER_EMPTY;
        }
    }

    if (S_OK == hr)
    {
        //  Get the item name
        hr = wiasReadPropStr(pWiasContext, WIA_IPA_ITEM_NAME, &bstrItemName, NULL, TRUE);
        if (SUCCEEDED(hr))
        {
            //  Get the full item name
            hr = wiasReadPropStr(pWiasContext, WIA_IPA_FULL_ITEM_NAME, &bstrFullItemName, NULL, TRUE);
            if (SUCCEEDED(hr))
            {
                //  Get the destination stream
                IStream *pDestination = NULL;
                hr = pTransferCallback->GetNextStream(0, bstrItemName, bstrFullItemName, &pDestination);
                if (hr == S_OK)
                {
                    WiaTransferParams *pParams = (WiaTransferParams*)CoTaskMemAlloc(sizeof(WiaTransferParams));
                    if (pParams)
                    {
                        memset(pParams, 0, sizeof(WiaTransferParams));
                        BYTE    *pBuffer        = NULL;
                        ULONG   ulBufferSize    = 0;
                        hr = AllocateTransferBuffer(pWiasContext, &pBuffer, &ulBufferSize);
                        if (SUCCEEDED(hr))
                        {
                            if ((S_OK == hr) && (guidItemCategory != WIA_CATEGORY_FINISHED_FILE) && (WIA_CATEGORY_FOLDER != guidItemCategory))
                            {
                                LONG    lErrorHandling = ERROR_HANDLING_NONE;

                                hr = wiasReadPropLong(pWiasContext, MY_WIA_ERROR_HANDLING_PROP, &lErrorHandling, NULL, TRUE);

                                BOOL    bSendWarmingUpMsg       = lErrorHandling & ERROR_HANDLING_WARMING_UP;
                                BOOL    bSendCoverOpenMsg       = lErrorHandling & ERROR_HANDLING_COVER_OPEN;
                                BOOL    bSendPrivateErrorMsg    = lErrorHandling & ERROR_HANDLING_PRIVATE_ERROR;
                                BOOL    bSendUnhandledStatusMsg = lErrorHandling & ERROR_HANDLING_UNHANDLED_STATUS;
                                BOOL    bSendUnhandledErrorMsg  = lErrorHandling & ERROR_HANDLING_UNHANDLED_ERROR;

                                //  We need to initialize our device object for each item we transfer.
                                //  Each item may have it's own selection area, data type and so on.
                                hr = m_WiaDevice.InitializeForDownload(pWiasContext,
                                                                    g_hInst,
                                                                    uiBitmapResourceID, 
                                                                    guidFormatID);

                                if ((S_OK == hr) && bSendWarmingUpMsg)
                                {
                                    //
                                    // Send non-modal warming up message. To be catched by default UI
                                    // unless application handles it (WiaPreview does not handle this
                                    // message).
                                    //
                                    // Sending "update messages" makes it possible for a user to cancel transfer
                                    // and also for an error handler to provide progress dialog.
                                    //                            
                                    for (int i = 0; i < 10 ; i++)
                                    {
                                        pParams->lMessage           = WIA_TRANSFER_MSG_DEVICE_STATUS;
                                        pParams->hrErrorStatus      = WIA_STATUS_WARMING_UP;
                                        pParams->lPercentComplete   = i * 10;
                                        pParams->ulTransferredBytes = 0;

                                        hr = pTransferCallback->SendMessage(0, pParams);

                                        if (S_OK != hr)
                                        {
                                            break;
                                        }

                                        Sleep(500);
                                    }
                                }

                                if (S_OK == hr)
                                {
                                    BOOL    bProblemFixed = FALSE;

                                    //  Data transfer loop
                                    //  Read from device
                                    ULONG   ulBytesRead         = 0;
                                    LONG    lPercentComplete    = 0;

                                    if (bSendUnhandledStatusMsg)
                                    {
                                        //
                                        // Send "special" unhandled status message
                                        //
                                        pParams->lMessage           = WIA_TRANSFER_MSG_DEVICE_STATUS;
                                        pParams->hrErrorStatus      = UNHANDLED_PRIVATE_STATUS_MESSAGE_1;
                                        pParams->lPercentComplete   = 0;
                                        pParams->ulTransferredBytes = 0;
        
                                        hr = pTransferCallback->SendMessage(0, pParams);
                                    }

                                    if ((S_OK == hr) && bSendUnhandledErrorMsg)
                                    {

                                        //
                                        // Since none handles this device error it will cause our transfer to be
                                        // be aborted.
                                        //
                                        pParams->lMessage           = WIA_TRANSFER_MSG_DEVICE_STATUS;
                                        pParams->hrErrorStatus      = UNHANDLED_PRIVATE_STATUS_ERROR_1;
                                        pParams->lPercentComplete   = 0;
                                        pParams->ulTransferredBytes = 0;
        
                                        hr = pTransferCallback->SendMessage(0, pParams);
                                    }

                                    if ((S_OK == hr) && bSendCoverOpenMsg)
                                    {
                                        pParams->lMessage           = WIA_TRANSFER_MSG_DEVICE_STATUS;
                                        pParams->hrErrorStatus      = WIA_ERROR_COVER_OPEN;
                                        pParams->lPercentComplete   = 0;
                                        pParams->ulTransferredBytes = 0;
        
                                        hr = pTransferCallback->SendMessage(0, pParams);
                                    }

                                    //
                                    // If this is a Raw format transfer we should transfer the raw header first.
                                    // WiaDevice::InitializeForDownload suceedeed and it is safe to execute
                                    // now DownloadRawHeader:
                                    //
                                    if((S_OK == hr) && (IsEqualGUID(guidFormatID, WiaImgFmt_RAW)))
                                    {
                                        hr = DownloadRawHeader(pDestination, pWiasContext, pmdtc);

                                        if(S_OK == hr)
                                        {
                                            WIA_RAW_HEADER& RawHeader = m_WiaDevice.m_RawHeader;
                                            LONG lPercentComplete  = (LONG)((((float)RawHeader.HeaderSize /
                                                (float)(RawHeader.RawDataSize + RawHeader.HeaderSize + RawHeader.PaletteSize))) * 100.0f);     
                                            
                                            pParams->lMessage            = WIA_TRANSFER_MSG_STATUS;
                                            pParams->lPercentComplete    = lPercentComplete;
                                            pParams->ulTransferredBytes += RawHeader.HeaderSize;

                                            hr = pTransferCallback->SendMessage(0, pParams);
                                        }
                                    }

                                    while((S_OK == hr) && 
                                        ((hr = m_WiaDevice.GetNextBand(pBuffer, ulBufferSize, &ulBytesRead, &lPercentComplete, guidFormatID)) == S_OK))
                                    {
                                        //      Check whether the transfer has been cancelled
                                        //      Write to stream
                                        ULONG   ulBytesWritten = 0;
                                        hr = pDestination->Write(pBuffer, ulBytesRead, &ulBytesWritten);
                                        
                                        if (S_OK == hr)
                                        {
                                            //      Make progress callback
                                            pParams->lMessage            = WIA_TRANSFER_MSG_STATUS;
                                            pParams->lPercentComplete    = lPercentComplete;
                                            pParams->ulTransferredBytes += ulBytesWritten;

                                            hr = pTransferCallback->SendMessage(0, pParams);
                                            if (FAILED(hr))
                                            {
                                                WIAS_ERROR((g_hInst, "Failed to send progress notification during download, hr = 0x%lx",hr));
                                                break;
                                            }
                                            else if (S_FALSE == hr)
                                            {
                                                //
                                                // Transfer cancelled
                                                //
                                                break;
                                            }
                                            else if (S_OK != hr)
                                            {
                                                WIAS_ERROR((g_hInst, "SendMessage returned unknown Success value, hr = 0x%lx",hr));
                                                hr = E_UNEXPECTED;
                                                break;
                                            }

                                            if ((lPercentComplete > 50) && !bProblemFixed)
                                            {

                                                if (bSendPrivateErrorMsg)
                                                {
                                                    //
                                                    // Send "special" driver status message that only our error handling extension knows about
                                                    //

⌨️ 快捷键说明

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