📄 wiadriver.cpp
字号:
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 + -