Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
9.7 KiB

  1. #include <windows.h>
  2. #include <atlbase.h>
  3. #include "resource.h"
  4. #include "wia.h"
  5. #include "classes.h"
  6. #include "commctrl.h"
  7. extern CComPtr<IWiaDevMgr> g_pDevMgr;
  8. LPCTSTR cszFilePath = TEXT("%temp%\\foobar.img");
  9. TCHAR szFilePath[MAX_PATH] = TEXT("\0");
  10. class CDataCallback : public IWiaDataCallback
  11. {
  12. public:
  13. HRESULT STDMETHODCALLTYPE BandedDataCallback(LONG lMessage,
  14. LONG lStatus,
  15. LONG lPercentComplete,
  16. LONG lOffset,
  17. LONG lLength,
  18. LONG lReserved,
  19. LONG lResLength,
  20. BYTE *pbBuffer);
  21. HRESULT STDMETHODCALLTYPE QueryInterface(THIS_ REFIID riid, OUT PVOID *ppvObj)
  22. {
  23. *ppvObj = NULL;
  24. if (IsEqualGUID(riid, IID_IUnknown))
  25. {
  26. *ppvObj = static_cast<IUnknown*>(this);
  27. }
  28. else if (IsEqualGUID(riid, IID_IWiaDataCallback))
  29. {
  30. *ppvObj = static_cast<IWiaDataCallback*>(this);
  31. }
  32. else return E_NOINTERFACE;
  33. AddRef();
  34. return S_OK;
  35. }
  36. ULONG STDMETHODCALLTYPE AddRef(THIS) {
  37. return InterlockedIncrement (reinterpret_cast<LONG*>(&m_cRef));
  38. }
  39. ULONG STDMETHODCALLTYPE Release(void) {
  40. ULONG ulRet = InterlockedDecrement (reinterpret_cast<LONG*>(&m_cRef));
  41. if (!ulRet)
  42. {
  43. delete this;
  44. }
  45. return ulRet;
  46. }
  47. CDataCallback () : m_cRef(1), m_pBits(NULL) {};
  48. private:
  49. ~CDataCallback () {if (m_pBits) delete [] m_pBits;}
  50. ULONG m_cRef;
  51. PBYTE m_pBits;
  52. PBYTE m_pWrite;
  53. LONG m_lSize;
  54. };
  55. STDMETHODIMP
  56. CDataCallback::BandedDataCallback(LONG lMessage,
  57. LONG lStatus,
  58. LONG lPercentComplete,
  59. LONG lOffset,
  60. LONG lLength,
  61. LONG lReserved,
  62. LONG lResLength,
  63. BYTE *pbData)
  64. {
  65. switch (lMessage)
  66. {
  67. case IT_MSG_DATA_HEADER:
  68. {
  69. WIA_DATA_CALLBACK_HEADER *pHead= reinterpret_cast<WIA_DATA_CALLBACK_HEADER*>(pbData);
  70. m_pBits = new BYTE[pHead->lBufferSize];
  71. if (!m_pBits)
  72. {
  73. return E_OUTOFMEMORY;
  74. }
  75. m_lSize = pHead->lBufferSize;
  76. m_pWrite = m_pBits;
  77. }
  78. break;
  79. case IT_MSG_DATA:
  80. {
  81. CopyMemory (m_pWrite, pbData, lLength);
  82. m_pWrite+=lLength;
  83. }
  84. break;
  85. case IT_MSG_TERMINATION:
  86. {
  87. if (m_pBits)
  88. {
  89. HANDLE hFile = CreateFile (szFilePath, GENERIC_WRITE,
  90. FILE_SHARE_READ,
  91. NULL,
  92. CREATE_ALWAYS,
  93. 0,
  94. NULL);
  95. if (INVALID_HANDLE_VALUE != hFile)
  96. {
  97. DWORD dw = 0;
  98. WriteFile (hFile, m_pBits, static_cast<DWORD>(m_lSize), &dw, NULL);
  99. CloseHandle (hFile);
  100. }
  101. }
  102. }
  103. break;
  104. }
  105. return S_OK;
  106. }
  107. VOID
  108. CTest::DownloadItem (IWiaItem *pItem, DWORD &dwPix, ULONG &ulSize, bool bBanded)
  109. {
  110. HRESULT hr;
  111. LARGE_INTEGER liStart;
  112. LARGE_INTEGER liEnd;
  113. STGMEDIUM stg;
  114. PROPSPEC ps[2];
  115. PROPVARIANT pv[2];
  116. GUID guidFmt;
  117. WIA_DATA_TRANSFER_INFO wdti;
  118. CComQIPtr<IWiaPropertyStorage, &IID_IWiaPropertyStorage> pps(pItem);
  119. CComQIPtr<IWiaDataTransfer, &IID_IWiaDataTransfer> pXfer;
  120. CDataCallback *pDataCallback = NULL;
  121. QueryPerformanceCounter (&liStart);
  122. PropVariantInit (&pv[0]);
  123. if (!bBanded)
  124. {
  125. ZeroMemory (&stg, sizeof(stg));
  126. stg.pUnkForRelease = NULL;
  127. stg.tymed = TYMED_FILE;
  128. #ifdef UNICODE
  129. stg.lpszFileName = szFilePath;
  130. #else
  131. WCHAR szPath[MAX_PATH];
  132. MultiByteToWideChar (CP_ACP, 0, szFilePath, -1, szPath, MAX_PATH);
  133. stg.lpszFileName = szPath;
  134. #endif
  135. // stg.lpszFileName = NULL;
  136. }
  137. else
  138. {
  139. ZeroMemory (&wdti, sizeof(wdti));
  140. wdti.ulSize = sizeof(wdti);
  141. ps[0].ulKind = PRSPEC_PROPID;
  142. ps[0].propid = WIA_IPA_MIN_BUFFER_SIZE;
  143. hr = pps->ReadMultiple (1, &ps[0], &pv[0]);
  144. LogAPI (TEXT("IWiaPropertyStorage::ReadMultiple (WIA_IPA_MIN_BUFFER_SIZE)"), hr);
  145. if (hr == NOERROR)
  146. {
  147. wdti.ulBufferSize = 2*pv[0].ulVal;
  148. }
  149. else
  150. {
  151. wdti.ulBufferSize = 65536;
  152. }
  153. wdti.bDoubleBuffer = TRUE;
  154. PropVariantClear (&pv[0]);
  155. pDataCallback = new CDataCallback;
  156. }
  157. ps[0].ulKind = PRSPEC_PROPID;
  158. ps[0].propid = WIA_IPA_PREFERRED_FORMAT;
  159. hr = pps->ReadMultiple (1, &ps[0], &pv[0]);
  160. LogAPI (TEXT("IWiaPropertyStorage::ReadMultiple (WIA_IPA_PREFERRED_FORMAT)"), hr);
  161. if (NOERROR == hr)
  162. {
  163. guidFmt = *(pv[0].puuid);
  164. PropVariantClear (&pv[0]);
  165. ps[0].propid = WIA_IPA_FORMAT;
  166. ps[1].ulKind = PRSPEC_PROPID;
  167. ps[1].propid = WIA_IPA_TYMED;
  168. pv[0].vt = VT_CLSID;
  169. pv[0].puuid = &guidFmt;
  170. pv[1].vt = VT_I4;
  171. pv[1].intVal = bBanded?TYMED_CALLBACK:TYMED_FILE;
  172. hr = pps->WriteMultiple (2, ps, pv, 2);
  173. LogAPI (TEXT("IWiaPropertyStorage::WriteMultiple(WIA_IPA_FORMAT, WIA_IPA_TYMED)"), hr);
  174. ps[0].propid = WIA_IPA_ITEM_SIZE;
  175. PropVariantInit (&pv[0]);
  176. hr = pps->ReadMultiple (1, &ps[0], &pv[0]);
  177. LogAPI (TEXT("IWiaPropertyStorage::ReadMultiple(WIA_IPA_ITEM_SIZE)"), hr);
  178. ulSize += pv[0].ulVal;
  179. dwPix++;
  180. pXfer = pItem;
  181. if (!pXfer)
  182. {
  183. LogString (TEXT("Unable to QI for IWiaDataTransfer!"));
  184. }
  185. else if (!bBanded)
  186. {
  187. hr = pXfer->idtGetData (&stg, NULL);
  188. LogAPI (TEXT("IWiaDataTransfer::idtGetData"), hr);
  189. }
  190. else if (pDataCallback)
  191. {
  192. CComQIPtr<IWiaDataCallback, &IID_IWiaDataCallback> pcb(pDataCallback);
  193. hr = pXfer->idtGetBandedData (&wdti, pcb);
  194. LogAPI (TEXT("IWiaDataTransfer::idtGetBandedData"), hr);
  195. }
  196. }
  197. QueryPerformanceCounter (&liEnd);
  198. if (!bBanded)
  199. {
  200. DeleteFileW (const_cast<LPCWSTR>(stg.lpszFileName));
  201. }
  202. DeleteFile (const_cast<LPCTSTR>(szFilePath));
  203. liEnd.QuadPart = liEnd.QuadPart - liStart.QuadPart;
  204. LogTime (TEXT("Download time for image "), liEnd);
  205. if (pDataCallback)
  206. {
  207. pDataCallback->Release();
  208. }
  209. }
  210. VOID
  211. CTest::RecursiveDownload (IWiaItem *pFolder, DWORD &dwPix, ULONG &ulSize, bool bBanded)
  212. {
  213. HRESULT hr;
  214. CComPtr<IEnumWiaItem> pEnum;
  215. DWORD dw;
  216. CComPtr<IWiaItem> pItem;
  217. LONG lItemType;
  218. hr = pFolder->EnumChildItems(&pEnum);
  219. LogAPI(TEXT("IWiaItem::EnumChildItems"), hr);
  220. while (NOERROR == hr)
  221. {
  222. hr = pEnum->Next (1,&pItem, &dw);
  223. if (dw)
  224. {
  225. hr = pItem->GetItemType (&lItemType);
  226. LogAPI (TEXT("IWiaItem::GetItemType"), hr);
  227. if (lItemType & WiaItemTypeFolder)
  228. {
  229. RecursiveDownload (pItem, dwPix, ulSize);
  230. }
  231. else
  232. {
  233. DownloadItem (pItem, dwPix, ulSize, bBanded);
  234. }
  235. }
  236. }
  237. }
  238. VOID
  239. CTest::TstDownload (CTest *pThis, BSTR strDeviceId)
  240. {
  241. LARGE_INTEGER liStart;
  242. LARGE_INTEGER liEnd;
  243. ULONG ulTotalSize = 0;
  244. DWORD dwPix = 0;
  245. HRESULT hr;
  246. TCHAR sz[200];
  247. CComPtr<IWiaItem> pRoot;
  248. ExpandEnvironmentStrings (cszFilePath, szFilePath, MAX_PATH);
  249. pThis->LogString (TEXT("--> Start test for idtGetData (no callback)"));
  250. pThis->LogString (TEXT("Note that the total log time in this test includes time for logging!"));
  251. QueryPerformanceCounter (&liStart);
  252. hr = g_pDevMgr->CreateDevice (strDeviceId, &pRoot);
  253. pThis->LogAPI(TEXT("IWiaDevMgr::CreateDevice"), hr);
  254. if (SUCCEEDED(hr))
  255. {
  256. pThis->RecursiveDownload (pRoot, dwPix, ulTotalSize);
  257. }
  258. QueryPerformanceCounter (&liEnd);
  259. liEnd.QuadPart = liEnd.QuadPart - liStart.QuadPart;
  260. wsprintf (sz, TEXT("Total pix:%d, Total size:%d kilobytes"), dwPix, ulTotalSize/1024);
  261. pThis->LogTime (sz, liEnd);
  262. }
  263. VOID
  264. CTest::TstBandedDownload (CTest *pThis, BSTR strDeviceId)
  265. {
  266. LARGE_INTEGER liStart;
  267. LARGE_INTEGER liEnd;
  268. ULONG ulTotalSize = 0;
  269. DWORD dwPix = 0;
  270. HRESULT hr;
  271. TCHAR sz[200];
  272. CComPtr<IWiaItem> pRoot;
  273. ExpandEnvironmentStrings (cszFilePath, szFilePath, MAX_PATH);
  274. pThis->LogString (TEXT("--> Start test for idtGetBandedData "));
  275. pThis->LogString (TEXT("Note that the total log time in this test includes time for logging!"));
  276. QueryPerformanceCounter (&liStart);
  277. hr = g_pDevMgr->CreateDevice (strDeviceId, &pRoot);
  278. pThis->LogAPI(TEXT("IWiaDevMgr::CreateDevice"), hr);
  279. if (SUCCEEDED(hr))
  280. {
  281. pThis->RecursiveDownload (pRoot, dwPix, ulTotalSize, true);
  282. }
  283. QueryPerformanceCounter (&liEnd);
  284. liEnd.QuadPart = liEnd.QuadPart - liStart.QuadPart;
  285. wsprintf (sz, TEXT("Total pix:%d, Total size:%d kilobytes"), dwPix, ulTotalSize/1024);
  286. pThis->LogTime (sz, liEnd);
  287. }