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

📄 wiadriver.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                                    pParams->lMessage                       = WIA_TRANSFER_MSG_DEVICE_STATUS;
                                                    pParams->hrErrorStatus                  = HANDLED_PRIVATE_STATUS_ERROR_1;
                                                    
                                                    hr = pTransferCallback->SendMessage(0, pParams);
                                                }

                                                if (S_OK == hr)
                                                {
                                                    bProblemFixed = TRUE;
                                                }
                                            }
                                        }
                                    }

                                    if ((pWiaDriverItemContext) && (IsEqualGUID(WIA_CATEGORY_FEEDER, guidItemCategory)))
                                    {
                                        //
                                        // Increment the feeder transfer counter for both preview and final scans:
                                        //
                                        if (pWiaDriverItemContext->ulFeederTransferCount < ulMaxTransfers)
                                        {
                                            pWiaDriverItemContext->ulFeederTransferCount += 1;
                                        }
                                    }
        
                                    if (WIA_STATUS_END_OF_MEDIA == hr)
                                    {
                                        hr = S_OK;
                                    }
                                    
                                    m_WiaDevice.UninitializeForDownload();
                                }
                                else
                                {
                                    WIAS_ERROR((g_hInst, "Failed to initialize device for download, hr = 0x%lx",hr));
                                }
                            }
                            else
                            {
                                WIA_DRIVER_ITEM_CONTEXT *pWiaDriverItemContext = NULL;
                                hr = wiasGetDriverItemPrivateContext(pWiasContext,(BYTE**)&pWiaDriverItemContext);
                                if(SUCCEEDED(hr) && (pWiaDriverItemContext))
                                {
                                    // Transfer data item contents (storage item data)
                                    //  Data transfer loop
                                    //      Read from device
                                    IStream *pStorageDataStream = NULL;
                                    hr = SHCreateStreamOnFile(pWiaDriverItemContext->bstrStorageDataPath,STGM_READ,&pStorageDataStream);
                                    if(SUCCEEDED(hr))
                                    {
                                        ULONG   ulBytesRead      = 0;
                                        LONG    lPercentComplete = -1;
                                        while((SUCCEEDED(pStorageDataStream->Read(pBuffer, ulBufferSize, &ulBytesRead)) && ulBytesRead))
                                        {
                                            //      Write to stream
                                            ULONG   ulBytesWritten = 0;
                                            hr = pDestination->Write(pBuffer, ulBytesRead, &ulBytesWritten);
                                            if (SUCCEEDED(hr))
                                            {
                                                //      Make progress callback
                                                pParams->lMessage            = WIA_TRANSFER_MSG_STATUS;
                                                pParams->lPercentComplete    = lPercentComplete;
                                                pParams->ulTransferredBytes += ulBytesWritten;

                                                hr = pTransferCallback->SendMessage(0, pParams);
                                                if (hr != S_OK)
                                                {
                                                    if (FAILED(hr))
                                                    {
                                                        WIAS_ERROR((g_hInst, "Failed to send progress notification during download, hr = 0x%lx",hr));
                                                    }
                                                    else if (S_FALSE == hr)
                                                    {
                                                        WIAS_TRACE((g_hInst, "Download was cancelled"));
                                                    }
                                                    else
                                                    {
                                                        WIAS_ERROR((g_hInst, "SendMessage returned unknown Success value, hr = 0x%lx",hr));
                                                        hr = E_UNEXPECTED;
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        pStorageDataStream->Release();
                                        pStorageDataStream = NULL;
                                    }
                                    else
                                    {
                                        WIAS_ERROR((g_hInst, "Failed to create a source stream on storage item data content file (%ws), hr = 0x%lx",pWiaDriverItemContext->bstrStorageDataPath,hr));
                                    }
                                }
                                else
                                {
                                    WIAS_ERROR((g_hInst, "Failed to get WIA driver item private context, hr = 0x%lx",hr));
                                }
                            }
                            FreeTransferBuffer(pBuffer);
                        }
                        else
                        {
                            WIAS_ERROR((g_hInst, "Failed to allocate memory for transfer buffer, hr = 0x%lx",hr));
                        }
                        CoTaskMemFree(pParams);
                        pParams = NULL;
                    }
                    else
                    {
                        hr = E_OUTOFMEMORY;
                        WIAS_ERROR((g_hInst, "Failed to allocate memory for WiaTransferParams structure, hr = 0x%lx",hr));
                    }
                    pDestination->Release();
                    pDestination = NULL;
                }
                else if(!((S_FALSE == hr) || (WIA_STATUS_SKIP_ITEM == hr)))
                {
                    WIAS_ERROR((g_hInst, "GetNextStream returned unknown Success value, hr = 0x%lx",hr));
                    hr = E_UNEXPECTED;
                }
                else
                {
                    WIAS_ERROR((g_hInst, "Failed to get the destination stream for download, hr = 0x%lx",hr));
                }

                SysFreeString(bstrFullItemName);
                bstrFullItemName = NULL;
            }
            else
            {
                WIAS_ERROR((g_hInst, "Failed to read the WIA_IPA_FULL_ITEM_NAME property, hr = 0x%lx",hr));
            }
            SysFreeString(bstrItemName);
            bstrItemName = NULL;
        }
        else
        {
            WIAS_ERROR((g_hInst, "Failed to read the WIA_IPA_ITEM_NAME property, hr = 0x%lx",hr));
        }
    }
    return hr;
}

HRESULT CWIADriver::UploadFromStream(           LONG                           lFlags,
                                     __in       BYTE                           *pWiasContext,
                                                const GUID                     &guidItemCategory,
                                     __callback IWiaMiniDrvTransferCallback    *pTransferCallback,
                                     __out      LONG                           *plDevErrVal)
{
    HRESULT hr           = S_OK;

    IStream *pSourceStream = NULL;
    hr = pTransferCallback->GetNextStream(lFlags,NULL,NULL,&pSourceStream);
    if(SUCCEEDED(hr))
    {
        BSTR bstrItemName = NULL;
        hr = wiasReadPropStr(pWiasContext,WIA_IPA_ITEM_NAME,&bstrItemName,NULL,TRUE);
        if(SUCCEEDED(hr))
        {
            STATSTG statstg = {0};

            hr = pSourceStream->Stat(&statstg, STATFLAG_NONAME);
            if(SUCCEEDED(hr))
            {
                WiaTransferParams *pParams = (WiaTransferParams*)CoTaskMemAlloc(sizeof(WiaTransferParams));
                if (pParams)
                {
                    memset(pParams, 0, sizeof(WiaTransferParams));

                    hr = m_WiaDevice.Upload(bstrItemName, statstg.cbSize.LowPart, pSourceStream,pTransferCallback, pParams,m_wszStoragePath);
                    if(SUCCEEDED(hr))
                    {
                        // Succeeded with upload.  We expect the App to do a synchronize to get the new items,
                        // so there's nothing further we need to do.

                        //
                        // TBD: Ideal case would be to create a WIA driver item, and link it to the existing
                        //      application item.  This will also be the place that a item created/added event
                        //      would be sent to the other clients, allowing them to reenumerate and pick up the
                        //      freshly uploaded item.
                        //
                    }
                    else
                    {
                        WIAS_ERROR((g_hInst, "Failed to upload data to the device, hr = 0x%lx",hr));
                    }

                    CoTaskMemFree(pParams);
                    pParams = NULL;
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                    WIAS_ERROR((g_hInst, "Failed to allocate memory for WiaTransferParams structure, hr = 0x%lx",hr));
                }
            }
            else
            {
                WIAS_ERROR((g_hInst, "Failed to call IStream::Stat on application provided stream, hr = 0x%lx",hr));
            }
            SysFreeString(bstrItemName);
            bstrItemName = NULL;
        }
        else
        {
            WIAS_ERROR((g_hInst, "Failed to read WIA_IPA_ITEM_NAME property, hr = 0x%lx",hr));
        }

        pSourceStream->Release();
        pSourceStream = NULL;
    }
    else if(!((S_FALSE == hr) ||(WIA_STATUS_SKIP_ITEM == hr)))
    {
        WIAS_ERROR((g_hInst, "GetNextStream returned unknown Success value, hr = 0x%lx",hr));
        hr = E_UNEXPECTED;
    }
    return hr;
}

HRESULT CWIADriver::drvAcquireItemData(__in    BYTE                      *pWiasContext,
                                               LONG                      lFlags,
                                       __in    PMINIDRV_TRANSFER_CONTEXT pmdtc,
                                       __out   LONG                      *plDevErrVal)
{
    HRESULT hr                  = E_INVALIDARG;
    GUID    guidItemCategory    = GUID_NULL;
    GUID    guidFormatID        = GUID_NULL;

    if((pWiasContext)&&(pmdtc)&&(plDevErrVal))
    {
        //
        // Read the current transfer format that we are requested to use:
        //
        guidFormatID = pmdtc->guidFormatID;
        
        //
        // Read the WIA item category, to decide which data transfer handler should
        // be used.
        //
        hr = wiasReadPropGuid(pWiasContext,WIA_IPA_ITEM_CATEGORY,&guidItemCategory,NULL,TRUE);
        if (SUCCEEDED(hr))
        {
            //
            //  Check what kind of data transfer is requested.  This driver
            //  supports 2 transfer modes:
            //  1.  Stream-based download
            //  2.  Stream-based upload
            //

            if (lFlags & WIA_MINIDRV_TRANSFER_DOWNLOAD)
            {
                // This is stream-based download
                IWiaMiniDrvTransferCallback *pTransferCallback = NULL;
                hr = GetTransferCallback(pmdtc, &pTransferCallback);
                if (SUCCEEDED(hr))
                {
                    LONG lStreamsToDownload = 0;
                    LONG lStreamCount = 0;
                    
                    if (!IsEqualGUID(guidItemCategory, WIA_CATEGORY_FEEDER))
                    {
                        lStreamsToDownload = 1;
                    }
                    else
                    {
                        hr = wiasReadPropLong(pWiasContext, WIA_IPS_PAGES, &lStreamsToDownload, NULL, TRUE);
                        if (FAILED(hr))
                        {
                            WIAS_ERROR((g_hInst, "drvAcquireItemData: failure reading WIA_IPS_PAGES property for Feeder item, hr = 0x%lx", hr));
                        }
                        else if (ALL_PAGES == lStreamsToDownload)
                        {
                            //
                            // When WIA_IPS_PAGES is set to 0 (ALL_PAGES) meaning "scan as many documents 
                            // as there may be loaded into the feeder" consider in the case of this sample 
                            // driver that we have just one document loaded in the feeder:
                            //
                            lStreamsToDownload = 1;
                        }
                    }

                    //
                    // We support only TYMED_FILE for WIA_IPA_TYMED so we should call DownloadToStream 
                    // for each individual image transfer. If WIA_IPA_TYMED would support and would be
                    // set to TYMED_MULTIPAGE_FILE then all images acquired in a continous sequence should
                    // be transferred to the same strem (GetNextStream called just once):
                    //
                    while ((S_OK == hr) && (lStreamCount < lStreamsToDownload))
                    {
                        //
                        // DownloadToStream writes its own trace message in case of failure:
                        //
                        hr = DownloadToStream(lFlags, pWiasContext, pmdtc, guidItemCategory, guidFormatID, pTransferCallback, plDevErrVal);
                        lStreamCount++;
                    }

                    pTransferCallback->Release();
                    pTransferCallback = NULL;
                }
                else
                {
                    WIAS_ERROR((g_hInst, "Could not get our IWiaMiniDrvTransferCallback for download"));
                }
            }
            else if (lFlags & WIA_MINIDRV_TRANSFER_UPLOAD)
            {
                //
                // We only want to do "Upload" if category of the item is WIA_CATEGORY_FINISHED_FILE and it is not the root storage item:
                //
                LONG    lItemType = 0;

                hr = wiasGetItemType(pWiasContext,&lItemType);

⌨️ 快捷键说明

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