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.

829 lines
29 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT 2000, MICROSOFT CORP.
  4. *
  5. * TITLE: Child.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * DATE: 18 July, 2000
  10. *
  11. * DESCRIPTION:
  12. * This file implements the helper methods for IWiaMiniDrv for child items.
  13. *
  14. *******************************************************************************/
  15. #include "pch.h"
  16. /**************************************************************************\
  17. * BuildChildItemProperties
  18. *
  19. * This helper creates the properties for a child item.
  20. *
  21. * Arguments:
  22. *
  23. * pWiasContext - WIA service context
  24. *
  25. \**************************************************************************/
  26. HRESULT CWiaCameraDevice::BuildChildItemProperties(
  27. BYTE *pWiasContext
  28. )
  29. {
  30. DBG_FN("CWiaCameraDevice::BuildChildItemProperties");
  31. HRESULT hr = S_OK;
  32. //
  33. // Locals
  34. //
  35. ITEM_CONTEXT *pItemCtx = NULL;
  36. MCAM_ITEM_INFO *pItemInfo = NULL;
  37. CWiauPropertyList ItemProps;
  38. const INT NUM_ITEM_PROPS = 20; // Make sure this number is large
  39. // enough to hold all child properties
  40. INT index = 0;
  41. LONG lAccessRights = 0;
  42. BOOL bBitmap = FALSE;
  43. LONG pTymedArray[] = { TYMED_FILE, TYMED_CALLBACK };
  44. int iNumFormats = 0;
  45. GUID *pguidFormatArray = NULL;
  46. BSTR bstrExtension = NULL;
  47. LONG lMinBufSize = 0;
  48. //
  49. // Get the driver item context
  50. //
  51. hr = wiauGetDrvItemContext(pWiasContext, (VOID **) &pItemCtx);
  52. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "GetDrvItemContext failed");
  53. pItemInfo = pItemCtx->pItemInfo;
  54. //
  55. // Call the microdriver to fill in information about the item
  56. //
  57. hr = m_pDevice->GetItemInfo(m_pDeviceInfo, pItemInfo);
  58. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "GetItemInfo failed");
  59. //
  60. // Set up properties that are used for all item types
  61. //
  62. hr = ItemProps.Init(NUM_ITEM_PROPS);
  63. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "Init property list failed");
  64. //
  65. // WIA_IPA_ITEM_TIME
  66. //
  67. hr = ItemProps.DefineProperty(&index, WIA_IPA_ITEM_TIME, WIA_IPA_ITEM_TIME_STR,
  68. WIA_PROP_READ, WIA_PROP_NONE);
  69. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  70. ItemProps.SetCurrentValue(index, &pItemInfo->Time);
  71. //
  72. // WIA_IPA_ACCESS_RIGHTS
  73. //
  74. hr = ItemProps.DefineProperty(&index, WIA_IPA_ACCESS_RIGHTS, WIA_IPA_ACCESS_RIGHTS_STR,
  75. WIA_PROP_READ, WIA_PROP_FLAG);
  76. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  77. //
  78. // If device supports changing the read-only status, item access rights is r/w
  79. //
  80. lAccessRights = pItemInfo->bReadOnly ? WIA_ITEM_READ : WIA_ITEM_RD;
  81. if (pItemInfo->bCanSetReadOnly)
  82. {
  83. ItemProps.SetAccessSubType(index, WIA_PROP_RW, WIA_PROP_FLAG);
  84. ItemProps.SetValidValues(index, lAccessRights, lAccessRights, WIA_ITEM_RD);
  85. }
  86. else
  87. {
  88. ItemProps.SetCurrentValue(index, lAccessRights);
  89. }
  90. if (pItemInfo->iType == WiaMCamTypeUndef) {
  91. wiauDbgWarning("BuildChildItemProperties", "Item's type is undefined");
  92. }
  93. //
  94. // Set up non-folder properties
  95. //
  96. else if (pItemInfo->iType != WiaMCamTypeFolder) {
  97. //
  98. // WIA_IPA_PREFERRED_FORMAT
  99. //
  100. hr = ItemProps.DefineProperty(&index, WIA_IPA_PREFERRED_FORMAT, WIA_IPA_PREFERRED_FORMAT_STR,
  101. WIA_PROP_READ, WIA_PROP_NONE);
  102. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  103. ItemProps.SetCurrentValue(index, (GUID *) pItemInfo->pguidFormat);
  104. bBitmap = IsEqualGUID(WiaImgFmt_BMP, *pItemInfo->pguidFormat);
  105. //
  106. // WIA_IPA_TYMED
  107. //
  108. hr = ItemProps.DefineProperty(&index, WIA_IPA_TYMED, WIA_IPA_TYMED_STR,
  109. WIA_PROP_RW, WIA_PROP_LIST);
  110. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  111. ItemProps.SetValidValues(index, TYMED_FILE, TYMED_FILE,
  112. sizeof(pTymedArray) / sizeof(pTymedArray[0]), pTymedArray);
  113. //
  114. // WIA_IPA_FORMAT
  115. //
  116. // First call drvGetWiaFormatInfo to get the valid formats
  117. //
  118. hr = wiauGetValidFormats(this, pWiasContext, TYMED_FILE, &iNumFormats, &pguidFormatArray);
  119. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "wiauGetValidFormats failed");
  120. if (iNumFormats == 0)
  121. {
  122. wiauDbgError("BuildChildItemProperties", "wiauGetValidFormats returned zero formats");
  123. hr = E_FAIL;
  124. goto Cleanup;
  125. }
  126. hr = ItemProps.DefineProperty(&index, WIA_IPA_FORMAT, WIA_IPA_FORMAT_STR,
  127. WIA_PROP_RW, WIA_PROP_LIST);
  128. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  129. ItemProps.SetValidValues(index, (GUID *) pItemInfo->pguidFormat, (GUID *) pItemInfo->pguidFormat,
  130. iNumFormats, &pguidFormatArray);
  131. //
  132. // WIA_IPA_FILENAME_EXTENSION
  133. //
  134. hr = ItemProps.DefineProperty(&index, WIA_IPA_FILENAME_EXTENSION, WIA_IPA_FILENAME_EXTENSION_STR,
  135. WIA_PROP_READ, WIA_PROP_NONE);
  136. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  137. bstrExtension = SysAllocString(pItemInfo->wszExt);
  138. REQUIRE_ALLOC(bstrExtension, hr, "BuildChildItemProperties");
  139. ItemProps.SetCurrentValue(index, bstrExtension);
  140. //
  141. // WIA_IPA_ITEM_SIZE
  142. //
  143. hr = ItemProps.DefineProperty(&index, WIA_IPA_ITEM_SIZE, WIA_IPA_ITEM_SIZE_STR,
  144. WIA_PROP_READ, WIA_PROP_NONE);
  145. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  146. ItemProps.SetCurrentValue(index, pItemInfo->lSize);
  147. //
  148. // WIA_IPA_MIN_BUFFER_SIZE
  149. //
  150. hr = ItemProps.DefineProperty(&index, WIA_IPA_MIN_BUFFER_SIZE, WIA_IPA_MIN_BUFFER_SIZE_STR,
  151. WIA_PROP_READ, WIA_PROP_NONE);
  152. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  153. if (!bBitmap && pItemInfo->lSize > 0)
  154. lMinBufSize = min(MIN_BUFFER_SIZE, pItemInfo->lSize);
  155. else
  156. lMinBufSize = MIN_BUFFER_SIZE;
  157. ItemProps.SetCurrentValue(index, lMinBufSize);
  158. //
  159. // Set up the image-only properties
  160. //
  161. if (pItemInfo->iType == WiaMCamTypeImage)
  162. {
  163. //
  164. // WIA_IPA_DATATYPE
  165. //
  166. // This property is mainly used by scanners. Set to color since most camera
  167. // images will be color.
  168. //
  169. hr = ItemProps.DefineProperty(&index, WIA_IPA_DATATYPE, WIA_IPA_DATATYPE_STR,
  170. WIA_PROP_READ, WIA_PROP_NONE);
  171. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  172. ItemProps.SetCurrentValue(index, (LONG) WIA_DATA_COLOR);
  173. //
  174. // WIA_IPA_DEPTH
  175. //
  176. hr = ItemProps.DefineProperty(&index, WIA_IPA_DEPTH, WIA_IPA_DEPTH_STR,
  177. WIA_PROP_READ, WIA_PROP_NONE);
  178. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  179. ItemProps.SetCurrentValue(index, pItemInfo->lDepth);
  180. //
  181. // WIA_IPA_CHANNELS_PER_PIXEL
  182. //
  183. hr = ItemProps.DefineProperty(&index, WIA_IPA_CHANNELS_PER_PIXEL, WIA_IPA_CHANNELS_PER_PIXEL_STR,
  184. WIA_PROP_READ, WIA_PROP_NONE);
  185. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  186. ItemProps.SetCurrentValue(index, pItemInfo->lChannels);
  187. //
  188. // WIA_IPA_BITS_PER_CHANNEL
  189. //
  190. hr = ItemProps.DefineProperty(&index, WIA_IPA_BITS_PER_CHANNEL, WIA_IPA_BITS_PER_CHANNEL_STR,
  191. WIA_PROP_READ, WIA_PROP_NONE);
  192. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  193. ItemProps.SetCurrentValue(index, pItemInfo->lBitsPerChannel);
  194. //
  195. // WIA_IPA_PLANAR
  196. //
  197. hr = ItemProps.DefineProperty(&index, WIA_IPA_PLANAR, WIA_IPA_PLANAR_STR,
  198. WIA_PROP_READ, WIA_PROP_NONE);
  199. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  200. ItemProps.SetCurrentValue(index, (LONG) WIA_PACKED_PIXEL);
  201. //
  202. // WIA_IPA_PIXELS_PER_LINE
  203. //
  204. hr = ItemProps.DefineProperty(&index, WIA_IPA_PIXELS_PER_LINE, WIA_IPA_PIXELS_PER_LINE_STR,
  205. WIA_PROP_READ, WIA_PROP_NONE);
  206. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  207. ItemProps.SetCurrentValue(index, pItemInfo->lWidth);
  208. //
  209. // WIA_IPA_BYTES_PER_LINE
  210. //
  211. hr = ItemProps.DefineProperty(&index, WIA_IPA_BYTES_PER_LINE, WIA_IPA_BYTES_PER_LINE_STR,
  212. WIA_PROP_READ, WIA_PROP_NONE);
  213. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  214. if (bBitmap)
  215. ItemProps.SetCurrentValue(index, ((pItemInfo->lWidth * pItemInfo->lDepth + 31) & ~31) / 8);
  216. else
  217. ItemProps.SetCurrentValue(index, (LONG) 0);
  218. //
  219. // WIA_IPA_NUMBER_OF_LINES
  220. //
  221. hr = ItemProps.DefineProperty(&index, WIA_IPA_NUMBER_OF_LINES, WIA_IPA_NUMBER_OF_LINES_STR,
  222. WIA_PROP_READ, WIA_PROP_NONE);
  223. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  224. ItemProps.SetCurrentValue(index, pItemInfo->lHeight);
  225. //
  226. // WIA_IPC_THUMBNAIL
  227. //
  228. hr = ItemProps.DefineProperty(&index, WIA_IPC_THUMBNAIL, WIA_IPC_THUMBNAIL_STR,
  229. WIA_PROP_READ, WIA_PROP_NONE);
  230. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  231. ItemProps.SetCurrentValue(index, (BYTE *) NULL, 0);
  232. //
  233. // WIA_IPC_THUMB_WIDTH
  234. //
  235. // This field is probably zero until the thumbnail is read in, but set it anyway
  236. //
  237. hr = ItemProps.DefineProperty(&index, WIA_IPC_THUMB_WIDTH, WIA_IPC_THUMB_WIDTH_STR,
  238. WIA_PROP_READ, WIA_PROP_NONE);
  239. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  240. ItemProps.SetCurrentValue(index, pItemInfo->lThumbWidth);
  241. //
  242. // WIA_IPC_THUMB_HEIGHT
  243. //
  244. // This field is probably zero until the thumbnail is read in, but set it anyway
  245. //
  246. hr = ItemProps.DefineProperty(&index, WIA_IPC_THUMB_HEIGHT, WIA_IPC_THUMB_HEIGHT_STR,
  247. WIA_PROP_READ, WIA_PROP_NONE);
  248. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  249. ItemProps.SetCurrentValue(index, pItemInfo->lThumbHeight);
  250. //
  251. // WIA_IPC_SEQUENCE
  252. //
  253. if (pItemInfo->lSequenceNum > 0)
  254. {
  255. hr = ItemProps.DefineProperty(&index, WIA_IPC_SEQUENCE, WIA_IPC_SEQUENCE_STR,
  256. WIA_PROP_READ, WIA_PROP_NONE);
  257. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  258. ItemProps.SetCurrentValue(index, pItemInfo->lSequenceNum);
  259. }
  260. //
  261. // WIA_IPA_COMPRESSION
  262. //
  263. // This property is mainly used by scanners. Set to no compression.
  264. //
  265. hr = ItemProps.DefineProperty(&index, WIA_IPA_COMPRESSION, WIA_IPA_COMPRESSION_STR,
  266. WIA_PROP_READ, WIA_PROP_NONE);
  267. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "DefineProperty failed");
  268. ItemProps.SetCurrentValue(index, (LONG) WIA_COMPRESSION_NONE);
  269. }
  270. }
  271. //
  272. // Last step: send all the properties to WIA
  273. //
  274. hr = ItemProps.SendToWia(pWiasContext);
  275. REQUIRE_SUCCESS(hr, "BuildChildItemProperties", "SendToWia failed");
  276. Cleanup:
  277. if (pguidFormatArray)
  278. delete []pguidFormatArray;
  279. if (bstrExtension)
  280. SysFreeString(bstrExtension);
  281. return hr;
  282. }
  283. /**************************************************************************\
  284. * ReadChildItemProperties
  285. *
  286. * Update the properties for the child items.
  287. *
  288. * Arguments:
  289. *
  290. * pWiasContext - WIA service context
  291. *
  292. \**************************************************************************/
  293. HRESULT CWiaCameraDevice::ReadChildItemProperties(
  294. BYTE *pWiasContext,
  295. LONG lNumPropSpecs,
  296. const PROPSPEC *pPropSpecs
  297. )
  298. {
  299. DBG_FN("CWiaCameraDevice::ReadChildItemProperties");
  300. HRESULT hr = S_OK;
  301. //
  302. // Locals
  303. //
  304. ITEM_CONTEXT *pItemCtx = NULL;
  305. MCAM_ITEM_INFO *pItemInfo = NULL;
  306. LONG lAccessRights = 0;
  307. LONG lThumbWidth = 0;
  308. INT iNativeThumbSize = 0;
  309. BYTE *pbNativeThumb = NULL;
  310. INT iConvertedThumbSize = 0;
  311. BYTE *pbConvertedThumb = NULL;
  312. BMP_IMAGE_INFO BmpImageInfo;
  313. REQUIRE_ARGS(!lNumPropSpecs || !pPropSpecs, hr, "ReadChildItemProperties");
  314. //
  315. // Get the driver item context
  316. //
  317. hr = wiauGetDrvItemContext(pWiasContext, (VOID **) &pItemCtx);
  318. REQUIRE_SUCCESS(hr, "ReadChildItemProperties", "wiauGetDrvItemContext failed");
  319. pItemInfo = pItemCtx->pItemInfo;
  320. //
  321. // See if the item time is being read
  322. //
  323. if (wiauPropInPropSpec(lNumPropSpecs, pPropSpecs, WIA_IPA_ITEM_TIME))
  324. {
  325. PROPVARIANT propVar;
  326. PROPSPEC propSpec;
  327. propVar.vt = VT_VECTOR | VT_UI2;
  328. propVar.caui.cElems = sizeof(SYSTEMTIME) / sizeof(WORD);
  329. propVar.caui.pElems = (WORD *) &pItemInfo->Time;
  330. propSpec.ulKind = PRSPEC_PROPID;
  331. propSpec.propid = WIA_IPA_ITEM_TIME;
  332. hr = wiasWriteMultiple(pWiasContext, 1, &propSpec, &propVar);
  333. REQUIRE_SUCCESS(hr, "ReadChildItemProperties", "wiasWriteMultiple failed");
  334. }
  335. //
  336. // See if the access rights are being read
  337. //
  338. if (wiauPropInPropSpec(lNumPropSpecs, pPropSpecs, WIA_IPA_ACCESS_RIGHTS))
  339. {
  340. lAccessRights = pItemInfo->bReadOnly ? WIA_ITEM_READ : WIA_ITEM_RD;
  341. hr = wiasWritePropLong(pWiasContext, WIA_IPA_ACCESS_RIGHTS, lAccessRights);
  342. REQUIRE_SUCCESS(hr, "ReadChildItemProperties", "wiasWritePropLong failed");
  343. }
  344. //
  345. // For images, update the thumbnail properties if requested
  346. //
  347. if (pItemInfo->iType == WiaMCamTypeImage)
  348. {
  349. //
  350. // Get the thumbnail if requested to update any of the thumbnail properties and
  351. // the thumbnail is not already cached.
  352. //
  353. PROPID propsToUpdate[] = {
  354. WIA_IPC_THUMB_WIDTH,
  355. WIA_IPC_THUMB_HEIGHT,
  356. WIA_IPC_THUMBNAIL
  357. };
  358. if (wiauPropsInPropSpec(lNumPropSpecs, pPropSpecs, sizeof(propsToUpdate) / sizeof(PROPID), propsToUpdate))
  359. {
  360. //
  361. // See if the thumbnail has already been read
  362. //
  363. wiasReadPropLong(pWiasContext, WIA_IPC_THUMB_WIDTH, &lThumbWidth, NULL, TRUE);
  364. REQUIRE_SUCCESS(hr, "ReadChildItemProperties", "wiasReadPropLong for thumbnail width failed");
  365. //
  366. // Get the thumbnail from the camera in it's native format
  367. //
  368. hr = m_pDevice->GetThumbnail(m_pDeviceInfo, pItemInfo, &iNativeThumbSize, &pbNativeThumb);
  369. REQUIRE_SUCCESS(hr, "ReadChildItemProperties", "GetThumbnail failed");
  370. //
  371. // If the format isn't supported by GDI+, return an error
  372. //
  373. if (!m_Converter.IsFormatSupported(pItemInfo->pguidThumbFormat)) {
  374. wiauDbgError("ReadChildItemProperties", "Thumb format not supported");
  375. hr = E_FAIL;
  376. goto Cleanup;
  377. }
  378. //
  379. // Call the WIA driver helper to convert to BMP
  380. //
  381. hr = m_Converter.ConvertToBmp(pbNativeThumb, iNativeThumbSize,
  382. &pbConvertedThumb, &iConvertedThumbSize,
  383. &BmpImageInfo, SKIP_BOTHHDR);
  384. REQUIRE_SUCCESS(hr, "ReadChildItemProperties", "ConvertToBmp failed");
  385. //
  386. // Fill in the thumbnail information based on the information returned from the helper
  387. //
  388. pItemInfo->lThumbWidth = BmpImageInfo.Width;
  389. pItemInfo->lThumbHeight = BmpImageInfo.Height;
  390. //
  391. // Update the related thumbnail properties. Update the thumb width and height in case
  392. // the device didn't report them in the ObjectInfo structure (they are optional there).
  393. //
  394. PROPSPEC propSpecs[3];
  395. PROPVARIANT propVars[3];
  396. propSpecs[0].ulKind = PRSPEC_PROPID;
  397. propSpecs[0].propid = WIA_IPC_THUMB_WIDTH;
  398. propVars[0].vt = VT_I4;
  399. propVars[0].lVal = pItemInfo->lThumbWidth;
  400. propSpecs[1].ulKind = PRSPEC_PROPID;
  401. propSpecs[1].propid = WIA_IPC_THUMB_HEIGHT;
  402. propVars[1].vt = VT_I4;
  403. propVars[1].lVal = pItemInfo->lThumbHeight;
  404. propSpecs[2].ulKind = PRSPEC_PROPID;
  405. propSpecs[2].propid = WIA_IPC_THUMBNAIL;
  406. propVars[2].vt = VT_VECTOR | VT_UI1;
  407. propVars[2].caub.cElems = iConvertedThumbSize;
  408. propVars[2].caub.pElems = pbConvertedThumb;
  409. hr = wiasWriteMultiple(pWiasContext, 3, propSpecs, propVars);
  410. REQUIRE_SUCCESS(hr, "ReadChildItemProperties", "wiasWriteMultiple failed");
  411. }
  412. }
  413. Cleanup:
  414. if (pbNativeThumb) {
  415. delete []pbNativeThumb;
  416. pbNativeThumb = NULL;
  417. }
  418. if (pbConvertedThumb) {
  419. delete []pbConvertedThumb;
  420. pbConvertedThumb = NULL;
  421. }
  422. return hr;
  423. }
  424. /**************************************************************************\
  425. * AcquireData
  426. *
  427. * Transfers native data from the device.
  428. *
  429. * Arguments:
  430. *
  431. *
  432. \**************************************************************************/
  433. HRESULT CWiaCameraDevice::AcquireData(
  434. ITEM_CONTEXT *pItemCtx,
  435. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  436. BYTE *pBuf,
  437. LONG lBufSize,
  438. BOOL bConverting
  439. )
  440. {
  441. DBG_FN("CWiaCameraDevice::AcquireData");
  442. HRESULT hr = S_OK;
  443. BYTE *pCur = NULL;
  444. UINT uiState = MCAM_STATE_FIRST;
  445. LONG lPercentComplete = 0;
  446. LONG lTotalToRead = pItemCtx->pItemInfo->lSize;
  447. LONG lOffset = 0;
  448. DWORD dwBytesToRead = 0;
  449. BOOL bFileTransfer = pmdtc->tymed & TYMED_FILE;
  450. LONG lMessage = 0;
  451. LONG lStatus = 0;
  452. //
  453. // If pBuf is non-null use that as the buffer, otherwise use the buffer
  454. // and size in pmdtc
  455. //
  456. if (pBuf)
  457. {
  458. pCur = pBuf;
  459. dwBytesToRead = lBufSize;
  460. }
  461. else
  462. {
  463. pCur = pmdtc->pTransferBuffer;
  464. dwBytesToRead = pmdtc->lBufferSize;
  465. }
  466. //
  467. // If the transfer size is the entire item, split it into approximately
  468. // 10 equal transfers in order to show progress to the app, but don't
  469. // make it smaller than 1k
  470. //
  471. if ((dwBytesToRead == (DWORD) lTotalToRead) &&
  472. (dwBytesToRead > 1024))
  473. {
  474. dwBytesToRead = (lTotalToRead / 10 + 3) & ~0x3;
  475. }
  476. //
  477. // Set up parameters for the callback function
  478. //
  479. if (bConverting)
  480. {
  481. lMessage = IT_MSG_STATUS;
  482. lStatus = IT_STATUS_TRANSFER_FROM_DEVICE;
  483. }
  484. else if (bFileTransfer)
  485. {
  486. lMessage = IT_MSG_STATUS;
  487. lStatus = IT_STATUS_TRANSFER_TO_CLIENT;
  488. }
  489. else // e.g. memory transfer
  490. {
  491. lMessage = IT_MSG_DATA;
  492. lStatus = IT_STATUS_TRANSFER_TO_CLIENT;
  493. }
  494. //
  495. // Read data until finished
  496. //
  497. while (lOffset < lTotalToRead)
  498. {
  499. //
  500. // If this is the last read, adjust the amount of data to read
  501. // and the state
  502. //
  503. if (dwBytesToRead >= (DWORD) (lTotalToRead - lOffset))
  504. {
  505. dwBytesToRead = (lTotalToRead - lOffset);
  506. uiState |= MCAM_STATE_LAST;
  507. }
  508. //
  509. // Get the data from the camera
  510. //
  511. hr = m_pDevice->GetItemData(m_pDeviceInfo, pItemCtx->pItemInfo, uiState, pCur, dwBytesToRead);
  512. REQUIRE_SUCCESS(hr, "AcquireData", "GetItemData failed");
  513. //
  514. // Calculate the percent complete for the callback function. If converting,
  515. // report the percent complete as TRANSFER_PERCENT of the actual. From
  516. // TRANSFER_PERCENT to 100% will be reported during format conversion.
  517. //
  518. if (bConverting)
  519. lPercentComplete = (lOffset + dwBytesToRead) * TRANSFER_PERCENT / lTotalToRead;
  520. else
  521. lPercentComplete = (lOffset + dwBytesToRead) * 100 / lTotalToRead;
  522. //
  523. // Call the callback function to send status and/or data to the app
  524. //
  525. hr = pmdtc->pIWiaMiniDrvCallBack->
  526. MiniDrvCallback(lMessage, lStatus, lPercentComplete,
  527. lOffset, dwBytesToRead, pmdtc, 0);
  528. REQUIRE_SUCCESS(hr, "AcquireData", "MiniDrvCallback failed");
  529. if (hr == S_FALSE)
  530. {
  531. //
  532. // Transfer is being cancelled by the app
  533. //
  534. wiauDbgWarning("AcquireData", "transfer cancelled");
  535. goto Cleanup;
  536. }
  537. //
  538. // Increment buffer pointer only if converting or this is a
  539. // file transfer
  540. //
  541. if (bConverting || bFileTransfer)
  542. {
  543. pCur += dwBytesToRead;
  544. }
  545. //
  546. // For a memory transfer not using a buffer allocated by the minidriver,
  547. // update the buffer pointer and size from the transfer context in case
  548. // of double buffering
  549. //
  550. else if (!pBuf)
  551. {
  552. pCur = pmdtc->pTransferBuffer;
  553. dwBytesToRead = pmdtc->lBufferSize;
  554. }
  555. //
  556. // Adjust variables for the next iteration
  557. //
  558. lOffset += dwBytesToRead;
  559. uiState &= ~MCAM_STATE_FIRST;
  560. }
  561. //
  562. // For file transfers, write the data to file
  563. //
  564. if (!pBuf && bFileTransfer)
  565. {
  566. //
  567. // Call WIA to write the data to the file
  568. //
  569. hr = wiasWriteBufToFile(0, pmdtc);
  570. REQUIRE_SUCCESS(hr, "AcquireData", "wiasWriteBufToFile failed");
  571. }
  572. Cleanup:
  573. //
  574. // If the transfer wasn't completed, send cancel to the device
  575. //
  576. if (!(uiState & MCAM_STATE_LAST))
  577. {
  578. wiauDbgTrace("AcquireData", "Prematurely stopping transfer");
  579. uiState = MCAM_STATE_CANCEL;
  580. hr = m_pDevice->GetItemData(m_pDeviceInfo, pItemCtx->pItemInfo, uiState, NULL, 0);
  581. if (FAILED(hr))
  582. wiauDbgErrorHr(hr, "AcquireData", "GetItemData last failed");
  583. }
  584. return hr;
  585. }
  586. /**************************************************************************\
  587. * Convert
  588. *
  589. * Translates native data to BMP and sends the data to the app.
  590. *
  591. * Arguments:
  592. *
  593. *
  594. \**************************************************************************/
  595. HRESULT CWiaCameraDevice::Convert(
  596. BYTE *pWiasContext,
  597. ITEM_CONTEXT *pItemCtx,
  598. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  599. BYTE *pNativeImage,
  600. LONG lNativeSize
  601. )
  602. {
  603. DBG_FN("CWiaCameraDevice::Convert");
  604. HRESULT hr = S_OK;
  605. //
  606. // Locals
  607. //
  608. LONG lMsg = 0; // Parameter to the callback function
  609. LONG lPercentComplete = 0; // Parameter to the callback function
  610. BOOL bUseAppBuffer = FALSE; // Indicates whether to transfer directly into the app's buffer
  611. BYTE *pBmpBuffer = NULL; // Buffer used to hold converted image
  612. INT iBmpBufferSize = 0; // Size of the converted image buffer
  613. LONG lBytesToCopy = 0;
  614. LONG lOffset = 0;
  615. BYTE *pCurrent = NULL;
  616. BMP_IMAGE_INFO BmpImageInfo;
  617. SKIP_AMOUNT iSkipAmt = SKIP_OFF;
  618. //
  619. // Check arguments
  620. //
  621. REQUIRE_ARGS(!pNativeImage, hr, "Convert");
  622. //
  623. // The msg to send to the app via the callback depends on whether
  624. // this is a file or callback transfer
  625. //
  626. lMsg = ((pmdtc->tymed & TYMED_FILE) ? IT_MSG_STATUS : IT_MSG_DATA);
  627. //
  628. // If the class driver allocated a buffer and the buffer is large
  629. // enough, convert directly into that buffer. Otherwise, pass NULL
  630. // to the ConvertToBmp function so that it will allocate a buffer.
  631. //
  632. if (pmdtc->bClassDrvAllocBuf &&
  633. pmdtc->lBufferSize >= pmdtc->lItemSize) {
  634. bUseAppBuffer = TRUE;
  635. pBmpBuffer = pmdtc->pTransferBuffer;
  636. iBmpBufferSize = pmdtc->lBufferSize;
  637. }
  638. //
  639. // Convert the image to BMP. Skip the BMP file header if the app asked
  640. // for a "memory bitmap" (aka DIB).
  641. //
  642. memset(&BmpImageInfo, 0, sizeof(BmpImageInfo));
  643. if (IsEqualGUID(pmdtc->guidFormatID, WiaImgFmt_MEMORYBMP)) {
  644. iSkipAmt = SKIP_FILEHDR;
  645. }
  646. hr = m_Converter.ConvertToBmp(pNativeImage, lNativeSize, &pBmpBuffer,
  647. &iBmpBufferSize, &BmpImageInfo, iSkipAmt);
  648. REQUIRE_SUCCESS(hr, "Convert", "ConvertToBmp failed");
  649. //
  650. // Send the data to the app. If the class driver allocated the buffer,
  651. // but it was too small, send the data back one chunk at a time.
  652. // Otherwise send all the data back at once.
  653. //
  654. if (pmdtc->bClassDrvAllocBuf &&
  655. pmdtc->lBufferSize < BmpImageInfo.Size) {
  656. pCurrent = pBmpBuffer;
  657. while (lOffset < BmpImageInfo.Size)
  658. {
  659. lBytesToCopy = BmpImageInfo.Size - lOffset;
  660. if (lBytesToCopy > pmdtc->lBufferSize) {
  661. lBytesToCopy = pmdtc->lBufferSize;
  662. //
  663. // Calculate how much of the data has been sent back so far. Report percentages to
  664. // the app between TRANSFER_PERCENT and 100 percent. Make sure it is never larger
  665. // than 99 until the end.
  666. //
  667. lPercentComplete = TRANSFER_PERCENT + ((100 - TRANSFER_PERCENT) * lOffset) / pmdtc->lItemSize;
  668. if (lPercentComplete > 99) {
  669. lPercentComplete = 99;
  670. }
  671. }
  672. //
  673. // This will complete the transfer, so set the percentage to 100
  674. else {
  675. lPercentComplete = 100;
  676. }
  677. memcpy(pmdtc->pTransferBuffer, pCurrent, lBytesToCopy);
  678. //
  679. // Call the application's callback transfer to report status and/or transfer data
  680. //
  681. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(lMsg, IT_STATUS_TRANSFER_TO_CLIENT,
  682. lPercentComplete, lOffset, lBytesToCopy, pmdtc, 0);
  683. REQUIRE_SUCCESS(hr, "Convert", "MiniDrvCallback failed");
  684. if (hr == S_FALSE)
  685. {
  686. wiauDbgWarning("Convert", "transfer cancelled");
  687. hr = S_FALSE;
  688. goto Cleanup;
  689. }
  690. pCurrent += lBytesToCopy;
  691. lOffset += lBytesToCopy;
  692. }
  693. }
  694. else
  695. {
  696. //
  697. // Send the data to the app in one big chunk
  698. //
  699. pmdtc->pTransferBuffer = pBmpBuffer;
  700. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(lMsg, IT_STATUS_TRANSFER_TO_CLIENT,
  701. 100, 0, BmpImageInfo.Size, pmdtc, 0);
  702. REQUIRE_SUCCESS(hr, "Convert", "MiniDrvCallback failed");
  703. }
  704. Cleanup:
  705. if (!bUseAppBuffer) {
  706. if (pBmpBuffer) {
  707. delete []pBmpBuffer;
  708. pBmpBuffer = NULL;
  709. iBmpBufferSize = 0;
  710. }
  711. }
  712. return hr;
  713. }