windows-nt/Source/XPSP1/NT/printscan/wia/test/wiaperf/download.cpp
2020-09-26 16:20:57 +08:00

316 lines
9.4 KiB
C++

#include <windows.h>
#include <atlbase.h>
#include "resource.h"
#include "wia.h"
#include "classes.h"
#include "commctrl.h"
extern CComPtr<IWiaDevMgr> g_pDevMgr;
LPCTSTR cszFilePath = TEXT("%temp%\\foobar.img");
TCHAR szFilePath[MAX_PATH] = TEXT("\0");
class CDataCallback : public IWiaDataCallback
{
public:
HRESULT STDMETHODCALLTYPE BandedDataCallback(LONG lMessage,
LONG lStatus,
LONG lPercentComplete,
LONG lOffset,
LONG lLength,
LONG lReserved,
LONG lResLength,
BYTE *pbBuffer);
HRESULT STDMETHODCALLTYPE QueryInterface(THIS_ REFIID riid, OUT PVOID *ppvObj)
{
*ppvObj = NULL;
if (IsEqualGUID(riid, IID_IUnknown))
{
*ppvObj = static_cast<IUnknown*>(this);
}
else if (IsEqualGUID(riid, IID_IWiaDataCallback))
{
*ppvObj = static_cast<IWiaDataCallback*>(this);
}
else return E_NOINTERFACE;
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef(THIS) {
return InterlockedIncrement (reinterpret_cast<LONG*>(&m_cRef));
}
ULONG STDMETHODCALLTYPE Release(void) {
ULONG ulRet = InterlockedDecrement (reinterpret_cast<LONG*>(&m_cRef));
if (!ulRet)
{
delete this;
}
return ulRet;
}
CDataCallback () : m_cRef(1), m_pBits(NULL) {};
private:
~CDataCallback () {if (m_pBits) delete [] m_pBits;}
ULONG m_cRef;
PBYTE m_pBits;
PBYTE m_pWrite;
LONG m_lSize;
};
STDMETHODIMP
CDataCallback::BandedDataCallback(LONG lMessage,
LONG lStatus,
LONG lPercentComplete,
LONG lOffset,
LONG lLength,
LONG lReserved,
LONG lResLength,
BYTE *pbData)
{
switch (lMessage)
{
case IT_MSG_DATA_HEADER:
{
WIA_DATA_CALLBACK_HEADER *pHead= reinterpret_cast<WIA_DATA_CALLBACK_HEADER*>(pbData);
m_pBits = new BYTE[pHead->lBufferSize];
if (!m_pBits)
{
return E_OUTOFMEMORY;
}
m_lSize = pHead->lBufferSize;
m_pWrite = m_pBits;
}
break;
case IT_MSG_DATA:
{
CopyMemory (m_pWrite, pbData, lLength);
m_pWrite+=lLength;
}
break;
case IT_MSG_TERMINATION:
{
if (m_pBits)
{
HANDLE hFile = CreateFile (szFilePath, GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
0,
NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dw = 0;
WriteFile (hFile, m_pBits, static_cast<DWORD>(m_lSize), &dw, NULL);
CloseHandle (hFile);
}
}
}
break;
}
return S_OK;
}
VOID
CTest::DownloadItem (IWiaItem *pItem, DWORD &dwPix, ULONG &ulSize, bool bBanded)
{
HRESULT hr;
LARGE_INTEGER liStart;
LARGE_INTEGER liEnd;
STGMEDIUM stg;
PROPSPEC ps[2];
PROPVARIANT pv[2];
GUID guidFmt;
WIA_DATA_TRANSFER_INFO wdti;
CComQIPtr<IWiaPropertyStorage, &IID_IWiaPropertyStorage> pps(pItem);
CComQIPtr<IWiaDataTransfer, &IID_IWiaDataTransfer> pXfer;
CDataCallback *pDataCallback = NULL;
QueryPerformanceCounter (&liStart);
PropVariantInit (&pv[0]);
if (!bBanded)
{
ZeroMemory (&stg, sizeof(stg));
stg.pUnkForRelease = NULL;
stg.tymed = TYMED_FILE;
#ifdef UNICODE
stg.lpszFileName = szFilePath;
#else
WCHAR szPath[MAX_PATH];
MultiByteToWideChar (CP_ACP, 0, szFilePath, -1, szPath, MAX_PATH);
stg.lpszFileName = szPath;
#endif
// stg.lpszFileName = NULL;
}
else
{
ZeroMemory (&wdti, sizeof(wdti));
wdti.ulSize = sizeof(wdti);
ps[0].ulKind = PRSPEC_PROPID;
ps[0].propid = WIA_IPA_MIN_BUFFER_SIZE;
hr = pps->ReadMultiple (1, &ps[0], &pv[0]);
LogAPI (TEXT("IWiaPropertyStorage::ReadMultiple (WIA_IPA_MIN_BUFFER_SIZE)"), hr);
if (hr == NOERROR)
{
wdti.ulBufferSize = 2*pv[0].ulVal;
}
else
{
wdti.ulBufferSize = 65536;
}
wdti.bDoubleBuffer = TRUE;
PropVariantClear (&pv[0]);
pDataCallback = new CDataCallback;
}
ps[0].ulKind = PRSPEC_PROPID;
ps[0].propid = WIA_IPA_PREFERRED_FORMAT;
hr = pps->ReadMultiple (1, &ps[0], &pv[0]);
LogAPI (TEXT("IWiaPropertyStorage::ReadMultiple (WIA_IPA_PREFERRED_FORMAT)"), hr);
if (NOERROR == hr)
{
guidFmt = *(pv[0].puuid);
PropVariantClear (&pv[0]);
ps[0].propid = WIA_IPA_FORMAT;
ps[1].ulKind = PRSPEC_PROPID;
ps[1].propid = WIA_IPA_TYMED;
pv[0].vt = VT_CLSID;
pv[0].puuid = &guidFmt;
pv[1].vt = VT_I4;
pv[1].intVal = bBanded?TYMED_CALLBACK:TYMED_FILE;
hr = pps->WriteMultiple (2, ps, pv, 2);
LogAPI (TEXT("IWiaPropertyStorage::WriteMultiple(WIA_IPA_FORMAT, WIA_IPA_TYMED)"), hr);
ps[0].propid = WIA_IPA_ITEM_SIZE;
PropVariantInit (&pv[0]);
hr = pps->ReadMultiple (1, &ps[0], &pv[0]);
LogAPI (TEXT("IWiaPropertyStorage::ReadMultiple(WIA_IPA_ITEM_SIZE)"), hr);
ulSize += pv[0].ulVal;
dwPix++;
pXfer = pItem;
if (!pXfer)
{
LogString (TEXT("Unable to QI for IWiaDataTransfer!"));
}
else if (!bBanded)
{
hr = pXfer->idtGetData (&stg, NULL);
LogAPI (TEXT("IWiaDataTransfer::idtGetData"), hr);
}
else if (pDataCallback)
{
CComQIPtr<IWiaDataCallback, &IID_IWiaDataCallback> pcb(pDataCallback);
hr = pXfer->idtGetBandedData (&wdti, pcb);
LogAPI (TEXT("IWiaDataTransfer::idtGetBandedData"), hr);
}
}
QueryPerformanceCounter (&liEnd);
if (!bBanded)
{
DeleteFileW (const_cast<LPCWSTR>(stg.lpszFileName));
}
DeleteFile (const_cast<LPCTSTR>(szFilePath));
liEnd.QuadPart = liEnd.QuadPart - liStart.QuadPart;
LogTime (TEXT("Download time for image "), liEnd);
if (pDataCallback)
{
pDataCallback->Release();
}
}
VOID
CTest::RecursiveDownload (IWiaItem *pFolder, DWORD &dwPix, ULONG &ulSize, bool bBanded)
{
HRESULT hr;
CComPtr<IEnumWiaItem> pEnum;
DWORD dw;
CComPtr<IWiaItem> pItem;
LONG lItemType;
hr = pFolder->EnumChildItems(&pEnum);
LogAPI(TEXT("IWiaItem::EnumChildItems"), hr);
while (NOERROR == hr)
{
hr = pEnum->Next (1,&pItem, &dw);
if (dw)
{
hr = pItem->GetItemType (&lItemType);
LogAPI (TEXT("IWiaItem::GetItemType"), hr);
if (lItemType & WiaItemTypeFolder)
{
RecursiveDownload (pItem, dwPix, ulSize);
}
else
{
DownloadItem (pItem, dwPix, ulSize, bBanded);
}
}
}
}
VOID
CTest::TstDownload (CTest *pThis, BSTR strDeviceId)
{
LARGE_INTEGER liStart;
LARGE_INTEGER liEnd;
ULONG ulTotalSize = 0;
DWORD dwPix = 0;
HRESULT hr;
TCHAR sz[200];
CComPtr<IWiaItem> pRoot;
ExpandEnvironmentStrings (cszFilePath, szFilePath, MAX_PATH);
pThis->LogString (TEXT("--> Start test for idtGetData (no callback)"));
pThis->LogString (TEXT("Note that the total log time in this test includes time for logging!"));
QueryPerformanceCounter (&liStart);
hr = g_pDevMgr->CreateDevice (strDeviceId, &pRoot);
pThis->LogAPI(TEXT("IWiaDevMgr::CreateDevice"), hr);
if (SUCCEEDED(hr))
{
pThis->RecursiveDownload (pRoot, dwPix, ulTotalSize);
}
QueryPerformanceCounter (&liEnd);
liEnd.QuadPart = liEnd.QuadPart - liStart.QuadPart;
wsprintf (sz, TEXT("Total pix:%d, Total size:%d kilobytes"), dwPix, ulTotalSize/1024);
pThis->LogTime (sz, liEnd);
}
VOID
CTest::TstBandedDownload (CTest *pThis, BSTR strDeviceId)
{
LARGE_INTEGER liStart;
LARGE_INTEGER liEnd;
ULONG ulTotalSize = 0;
DWORD dwPix = 0;
HRESULT hr;
TCHAR sz[200];
CComPtr<IWiaItem> pRoot;
ExpandEnvironmentStrings (cszFilePath, szFilePath, MAX_PATH);
pThis->LogString (TEXT("--> Start test for idtGetBandedData "));
pThis->LogString (TEXT("Note that the total log time in this test includes time for logging!"));
QueryPerformanceCounter (&liStart);
hr = g_pDevMgr->CreateDevice (strDeviceId, &pRoot);
pThis->LogAPI(TEXT("IWiaDevMgr::CreateDevice"), hr);
if (SUCCEEDED(hr))
{
pThis->RecursiveDownload (pRoot, dwPix, ulTotalSize, true);
}
QueryPerformanceCounter (&liEnd);
liEnd.QuadPart = liEnd.QuadPart - liStart.QuadPart;
wsprintf (sz, TEXT("Total pix:%d, Total size:%d kilobytes"), dwPix, ulTotalSize/1024);
pThis->LogTime (sz, liEnd);
}