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.

892 lines
24 KiB

  1. //----------------------------------------------------------------------------
  2. // Copyright (c) 1998, 1999 Microsoft Corporation.
  3. //
  4. //
  5. // miniitem.cpp
  6. //
  7. // Implementation of the WIA IrTran-P camera item methods.
  8. //
  9. // Author: MarkE 30-Aug-98 Original TestCam version.
  10. //
  11. // EdwardR 11-Aug-99 Rewritten for IrTran-P devices.
  12. //
  13. //----------------------------------------------------------------------------
  14. #include <stdio.h>
  15. #include <objbase.h>
  16. #include <sti.h>
  17. #include "ircamera.h"
  18. #include "defprop.h"
  19. extern HINSTANCE g_hInst; // Global DLL hInstance
  20. //----------------------------------------------------------------------------
  21. // ValidateDataTransferContext()
  22. //
  23. // Validate the data transfer context. This is a helper function, called
  24. // by IrUsdDevice::drvAcquireItemData().
  25. //
  26. // Parameters:
  27. //
  28. // pDataTransferContext --
  29. //
  30. // Return:
  31. //
  32. // HRESULT S_OK
  33. // E_INVALIDARG
  34. //----------------------------------------------------------------------------
  35. HRESULT ValidateDataTransferContext(
  36. IN MINIDRV_TRANSFER_CONTEXT *pDataTransferContext )
  37. {
  38. //
  39. // Check the context size:
  40. //
  41. if (pDataTransferContext->lSize != sizeof(MINIDRV_TRANSFER_CONTEXT))
  42. {
  43. WIAS_ERROR((g_hInst,"ValidateDataTransferContext(): invalid data transfer context size"));
  44. return E_INVALIDARG;;
  45. }
  46. //
  47. // For tymed file or hglobal, only WiaImgFmt_JPEG is allowed:
  48. //
  49. if ( (pDataTransferContext->tymed == TYMED_FILE)
  50. || (pDataTransferContext->tymed == TYMED_HGLOBAL))
  51. {
  52. if (pDataTransferContext->guidFormatID != WiaImgFmt_JPEG)
  53. {
  54. WIAS_ERROR((g_hInst,"ValidateDataTransferContext(): invalid format for TYMED_FILE"));
  55. return E_INVALIDARG;;
  56. }
  57. }
  58. //
  59. // For tymed CALLBACK, only WiaImgFmt_JPEG is allowed:
  60. //
  61. if (pDataTransferContext->tymed == TYMED_CALLBACK)
  62. {
  63. if (pDataTransferContext->guidFormatID != WiaImgFmt_JPEG)
  64. {
  65. WIAS_ERROR((g_hInst,"ValidateDataTransferContext(): Invalid format for TYMED_CALLBACK"));
  66. return E_INVALIDARG;;
  67. }
  68. //
  69. // The callback is always double buffered, non-callback case
  70. // (TYMED_FILE) never is:
  71. //
  72. if (pDataTransferContext->pTransferBuffer == NULL)
  73. {
  74. WIAS_ERROR((g_hInst, "ValidateDataTransferContext(): Null transfer buffer"));
  75. return E_INVALIDARG;
  76. }
  77. }
  78. return S_OK;
  79. }
  80. //----------------------------------------------------------------------------
  81. // SendBitmapHeader()
  82. //
  83. //
  84. //
  85. // Arguments:
  86. //
  87. //
  88. //
  89. // Return Value:
  90. //
  91. // HRESULT S_OK
  92. //
  93. //----------------------------------------------------------------------------
  94. HRESULT SendBitmapHeader(
  95. IN IWiaDrvItem *pDrvItem,
  96. IN MINIDRV_TRANSFER_CONTEXT *pTranCtx )
  97. {
  98. HRESULT hr;
  99. WIAS_ASSERT(g_hInst, pDrvItem != NULL);
  100. WIAS_ASSERT(g_hInst, pTranCtx != NULL);
  101. WIAS_ASSERT(g_hInst, pTranCtx->tymed == TYMED_CALLBACK);
  102. //
  103. // driver is sending TOPDOWN data, must swap biHeight
  104. //
  105. // this routine assumes pTranCtx->pHeader points to a
  106. // BITMAPINFO header (TYMED_FILE doesn't use this path
  107. // and DIB is the only format supported now)
  108. //
  109. PBITMAPINFO pbmi = (PBITMAPINFO)pTranCtx->pTransferBuffer;
  110. if (pTranCtx->guidFormatID == WiaImgFmt_BMP)
  111. {
  112. pbmi->bmiHeader.biHeight = -pbmi->bmiHeader.biHeight;
  113. }
  114. hr = pTranCtx->
  115. pIWiaMiniDrvCallBack->
  116. MiniDrvCallback(
  117. IT_MSG_DATA,
  118. IT_STATUS_TRANSFER_TO_CLIENT,
  119. 0,
  120. 0,
  121. pTranCtx->lHeaderSize,
  122. pTranCtx,
  123. 0 );
  124. if (hr == S_OK)
  125. {
  126. //
  127. // advance offset for destination copy
  128. //
  129. pTranCtx->cbOffset += pTranCtx->lHeaderSize;
  130. }
  131. return hr;
  132. }
  133. //----------------------------------------------------------------------------
  134. // IrUsdDevice::drvDeleteItem()
  135. //
  136. // Try to delete a device item.
  137. //
  138. // BUGBUG: Not yet implemented.
  139. //
  140. // Arguments:
  141. //
  142. // pWiasContext - The context of the item to delete
  143. // lFlags - unused
  144. // plDevErrVal - unused
  145. //
  146. // Return Value:
  147. //
  148. // HRESULT - STG_E_ACCESSDENIED
  149. //
  150. //----------------------------------------------------------------------------
  151. HRESULT _stdcall IrUsdDevice::drvDeleteItem(
  152. IN BYTE *pWiasContext,
  153. IN LONG lFlags,
  154. OUT LONG *plDevErrVal )
  155. {
  156. HRESULT hr = S_OK;
  157. IWiaDrvItem *pDrvItem = 0;
  158. IRCAM_IMAGE_CONTEXT *pContext = 0;
  159. WIAS_TRACE((g_hInst,"IrUsdDevice::drvDeleteItem()"));
  160. *plDevErrVal = 0;
  161. hr = wiasGetDrvItem( pWiasContext, &pDrvItem );
  162. if (FAILED(hr))
  163. {
  164. return hr;
  165. }
  166. hr = pDrvItem->GetDeviceSpecContext( (BYTE**)&pContext );
  167. if (FAILED(hr))
  168. {
  169. return hr;
  170. }
  171. hr = CamDeletePicture( pContext );
  172. return hr;
  173. }
  174. //----------------------------------------------------------------------------
  175. // IrUsdDevice::drvAcquireItemData()
  176. //
  177. // Scan data into buffer. This routine scans the entire contents into
  178. // the destination buffer in one call. Status will be sent back if
  179. // the callback routine is provided
  180. //
  181. // Arguments:
  182. //
  183. // pWiasContext - Identifies what item we are working with.
  184. // lFlags - unused
  185. // pTranCtx - Buffer and callback information
  186. // plDevErrVal - Return error value
  187. //
  188. // Return Value:
  189. //
  190. // HRESULT - S_OK
  191. // E_POINTER
  192. //
  193. //----------------------------------------------------------------------------
  194. HRESULT _stdcall IrUsdDevice::drvAcquireItemData(
  195. IN BYTE *pWiasContext,
  196. IN LONG lFlags,
  197. IN MINIDRV_TRANSFER_CONTEXT *pTranCtx,
  198. OUT LONG *plDevErrVal)
  199. {
  200. HRESULT hr;
  201. *plDevErrVal = 0;
  202. WIAS_TRACE((g_hInst,"IrUsdDevice::drvAcquireItemData()"));
  203. //
  204. // Get a pointer to the associated driver item.
  205. //
  206. IWiaDrvItem* pDrvItem;
  207. hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
  208. if (FAILED(hr))
  209. {
  210. return hr;
  211. }
  212. //
  213. // Validate the data transfer context.
  214. //
  215. hr = ValidateDataTransferContext(pTranCtx);
  216. if (FAILED(hr))
  217. {
  218. return hr;
  219. }
  220. //
  221. // Get item specific driver data:
  222. //
  223. IRCAM_IMAGE_CONTEXT *pMCamContext;
  224. pDrvItem->GetDeviceSpecContext((BYTE **)&pMCamContext);
  225. if (!pMCamContext)
  226. {
  227. WIAS_ERROR((g_hInst,"IrUsdDevice::drvAcquireItemData(): NULL item context"));
  228. return E_POINTER;
  229. }
  230. //
  231. // Use WIA services to fetch format specific info.
  232. //
  233. hr = wiasGetImageInformation(pWiasContext,
  234. 0,
  235. pTranCtx);
  236. if (hr != S_OK)
  237. {
  238. return hr;
  239. }
  240. //
  241. // Determine if this is a callback or buffered transfer
  242. //
  243. if (pTranCtx->tymed == TYMED_CALLBACK) {
  244. //
  245. // For formats that have a data header, send it to the client
  246. //
  247. if (pTranCtx->lHeaderSize > 0)
  248. {
  249. hr = SendBitmapHeader(
  250. pDrvItem,
  251. pTranCtx);
  252. }
  253. if (hr == S_OK)
  254. {
  255. hr = CamLoadPictureCB(
  256. pMCamContext,
  257. pTranCtx,
  258. plDevErrVal);
  259. }
  260. }
  261. else
  262. {
  263. //
  264. // Offset past the header in the buffer and get the picture data:
  265. //
  266. pTranCtx->cbOffset += pTranCtx->lHeaderSize;
  267. hr = CamLoadPicture(
  268. pMCamContext,
  269. pTranCtx,
  270. plDevErrVal);
  271. }
  272. return hr;
  273. }
  274. //----------------------------------------------------------------------------
  275. // IrUsdDevice::drvInitItemProperties()
  276. //
  277. // Initialize the device item properties.
  278. //
  279. // Arguments:
  280. //
  281. // pWiasContext - Pointer to WIA item context.
  282. // lFLags - unused
  283. // plDevErrVal - pointer to hardware error value.
  284. //
  285. //
  286. // Return Value:
  287. //
  288. // HRESULT - S_OK
  289. // E_INVALIDARG
  290. //
  291. //----------------------------------------------------------------------------
  292. HRESULT _stdcall IrUsdDevice::drvInitItemProperties(
  293. IN BYTE *pWiasContext,
  294. IN LONG lFlags,
  295. OUT LONG *plDevErrVal )
  296. {
  297. HRESULT hr;
  298. LONG lItemType;
  299. IRCAM_IMAGE_CONTEXT *pContext;
  300. WIAS_TRACE((g_hInst,"IrUsdDevice::drvInitItemProperties()"));
  301. //
  302. // NOTE: This device doesn't touch hardware to initialize the
  303. // device item properties.
  304. //
  305. *plDevErrVal = 0;
  306. //
  307. // Parameter validation.
  308. //
  309. if (!pWiasContext)
  310. {
  311. WIAS_ERROR((g_hInst,"IrUsdDevice::drvInitItemProperties(): invalid input pointers"));
  312. return E_INVALIDARG;
  313. }
  314. //
  315. // Get a pointer to the associated driver item:
  316. //
  317. IWiaDrvItem* pDrvItem;
  318. hr = wiasGetDrvItem( pWiasContext, &pDrvItem );
  319. if (FAILED(hr))
  320. {
  321. return hr;
  322. }
  323. //
  324. // The root item has the all the device properties
  325. //
  326. hr = pDrvItem->GetItemFlags(&lItemType);
  327. if (FAILED(hr))
  328. {
  329. return hr;
  330. }
  331. if (lItemType & WiaItemTypeRoot)
  332. {
  333. //
  334. // Root item property initialization finishes here:
  335. //
  336. return InitDeviceProperties( pWiasContext, plDevErrVal);
  337. }
  338. //
  339. // If this is a file, init the properties
  340. //
  341. if (lItemType & WiaItemTypeFile)
  342. {
  343. //
  344. // Add the item property names:
  345. //
  346. hr = wiasSetItemPropNames(pWiasContext,
  347. NUM_CAM_ITEM_PROPS,
  348. gItemPropIDs,
  349. gItemPropNames);
  350. if (FAILED(hr))
  351. {
  352. WIAS_ERROR((g_hInst,"IrUsdDevice::drvInitItemProperties(): wiasSetItemPropNames() failed"));
  353. return hr;
  354. }
  355. //
  356. // Use WIA services to set default item properties:
  357. //
  358. hr = wiasWriteMultiple( pWiasContext,
  359. NUM_CAM_ITEM_PROPS,
  360. gPropSpecDefaults,
  361. (PROPVARIANT*)gPropVarDefaults);
  362. if (FAILED(hr))
  363. {
  364. return hr;
  365. }
  366. hr = pDrvItem->GetDeviceSpecContext((BYTE **)&pContext);
  367. if (FAILED(hr))
  368. {
  369. WIAS_ERROR((g_hInst,"IrUsdDevice::drvInitItemProperties(): GetDeviceSpecContext failed"));
  370. return hr;
  371. }
  372. hr = InitImageInformation(pWiasContext,
  373. pContext,
  374. plDevErrVal);
  375. if (FAILED(hr))
  376. {
  377. WIAS_ERROR((g_hInst,"IrUsdDevice::drvInitItemProperties(): InitImageInformation() failed"));
  378. return hr;
  379. }
  380. }
  381. return S_OK;
  382. }
  383. //----------------------------------------------------------------------------
  384. // IrUsdDevice::drvValidateItemProperties()
  385. //
  386. // Validate the device item properties.
  387. //
  388. // Arguments:
  389. //
  390. // pWiasContext - wia item context
  391. // lFlags - unused
  392. // nPropSpec -
  393. // pPropSpec -
  394. // plDevErrVal - device error value
  395. //
  396. // Return Value:
  397. //
  398. // HRESULT
  399. //
  400. //----------------------------------------------------------------------------
  401. HRESULT _stdcall IrUsdDevice::drvValidateItemProperties(
  402. BYTE *pWiasContext,
  403. LONG lFlags,
  404. ULONG nPropSpec,
  405. const PROPSPEC *pPropSpec,
  406. LONG *plDevErrVal )
  407. {
  408. //
  409. // This device doesn't touch hardware to validate the device item properties
  410. //
  411. *plDevErrVal = 0;
  412. //
  413. // Parameter validation.
  414. //
  415. if (!pWiasContext || !pPropSpec)
  416. {
  417. WIAS_ERROR((g_hInst,"IrUsdDevice::drvValidateItemProperties(): Invalid input pointers"));
  418. return E_POINTER;
  419. }
  420. //
  421. // validate size
  422. //
  423. HRESULT hr = S_OK;
  424. IWiaDrvItem* pDrvItem;
  425. hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
  426. if (FAILED(hr))
  427. {
  428. return hr;
  429. }
  430. LONG lItemType;
  431. hr = pDrvItem->GetItemFlags(&lItemType);
  432. if (hr == S_OK)
  433. {
  434. if (lItemType & WiaItemTypeFile)
  435. {
  436. //
  437. // calc item size
  438. //
  439. hr = SetItemSize(pWiasContext);
  440. //
  441. // Change MinBufferSize property. Need to get Tymed and
  442. // ItemSize first, since MinBufferSize in dependant on these
  443. // properties.
  444. //
  445. LONG lTymed;
  446. LONG lItemSize;
  447. LONG lMinBufSize = 0;
  448. HRESULT hr = S_OK;
  449. hr = wiasReadPropLong(pWiasContext, WIA_IPA_TYMED, &lTymed, NULL, TRUE);
  450. if (FAILED(hr))
  451. {
  452. WIAS_ERROR((g_hInst,"drvValidateItemProperties, could not read TYMED property"));
  453. return hr;
  454. }
  455. hr = wiasReadPropLong(pWiasContext, WIA_IPA_ITEM_SIZE, &lItemSize, NULL, TRUE);
  456. if (SUCCEEDED(hr))
  457. {
  458. //
  459. // Update the MinBufferSize property.
  460. //
  461. switch (lTymed)
  462. {
  463. case TYMED_CALLBACK:
  464. lMinBufSize = 65535;
  465. break;
  466. default:
  467. lMinBufSize = lItemSize;
  468. }
  469. if (lMinBufSize)
  470. {
  471. hr = wiasWritePropLong(pWiasContext, WIA_IPA_MIN_BUFFER_SIZE, lMinBufSize);
  472. if (FAILED(hr))
  473. {
  474. WIAS_ERROR((g_hInst, "drvValidateItemProperties, could not write value for WIA_IPA_MIN_BUFFER_SIZE"));
  475. }
  476. }
  477. }
  478. else
  479. {
  480. WIAS_ERROR((g_hInst, "drvValidateItemProperties, could not read value for ItemSize"));
  481. }
  482. }
  483. else if (lItemType & WiaItemTypeRoot)
  484. {
  485. //
  486. // Find out whether the Root Path property is changed
  487. //
  488. #if FALSE
  489. for (ULONG i = 0; i < nPropSpec; i++)
  490. {
  491. if (((pPropSpec[i].ulKind == PRSPEC_PROPID) &&
  492. (pPropSpec[i].propid == WIA_DPP_TCAM_ROOT_PATH)) ||
  493. ((pPropSpec[i].ulKind == PRSPEC_LPWSTR) &&
  494. (wcscmp(pPropSpec[i].lpwstr, WIA_DPP_TCAM_ROOT_PATH_STR) == 0)))
  495. {
  496. BSTR bstrRootPath;
  497. //
  498. // Retrieve the new value for Root Path property
  499. //
  500. hr = wiasReadPropStr(
  501. pWiasContext,
  502. WIA_DPP_TCAM_ROOT_PATH,
  503. &bstrRootPath,
  504. NULL,
  505. TRUE);
  506. if (FAILED(hr))
  507. {
  508. return hr;
  509. }
  510. #ifdef UNICODE
  511. wcscpy(gpszPath, bstrRootPath);
  512. #else
  513. wcstombs(gpszPath, bstrRootPath, MAX_PATH);
  514. #endif
  515. //
  516. // Release the Root Path bstr
  517. //
  518. SysFreeString(bstrRootPath);
  519. //
  520. // Rebuild the item tree and send event notification
  521. //
  522. hr = DeleteDeviceItemTree(plDevErrVal);
  523. if (FAILED(hr))
  524. {
  525. break;
  526. }
  527. hr = BuildDeviceItemTree(plDevErrVal);
  528. if (FAILED(hr))
  529. {
  530. break;
  531. }
  532. m_guidLastEvent = WIA_EVENT_DEVICE_CONNECTED;
  533. SetEvent(m_hSignalEvent);
  534. break;
  535. }
  536. }
  537. #endif
  538. }
  539. }
  540. return hr;
  541. }
  542. //----------------------------------------------------------------------------
  543. /**************************************************************************\
  544. * IrUsdDevice::drvWriteItemProperties
  545. *
  546. * Write the device item properties to the hardware.
  547. *
  548. * Arguments:
  549. *
  550. * pWiasContext - the corresponding wia item context
  551. * pmdtc - pointer to mini driver context
  552. * pFlags - unused
  553. * plDevErrVal - the device error value
  554. *
  555. * Return Value:
  556. *
  557. * Status
  558. *
  559. * History:
  560. *
  561. * 10/29/1998 Original Version
  562. *
  563. \**************************************************************************/
  564. //----------------------------------------------------------------------------
  565. HRESULT _stdcall IrUsdDevice::drvWriteItemProperties(
  566. BYTE *pWiasContext,
  567. LONG lFlags,
  568. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  569. LONG *plDevErrVal)
  570. {
  571. //
  572. // Assume no device hardware errors.
  573. //
  574. *plDevErrVal = 0;
  575. //
  576. // Parameter validation.
  577. //
  578. if ((! pWiasContext) || (! pmdtc)) {
  579. WIAS_ERROR((g_hInst,"drvWriteItemProperties, invalid input pointers"));
  580. return E_POINTER;
  581. }
  582. //
  583. // Get a pointer to the associated driver item.
  584. //
  585. IWiaDrvItem* pDrvItem;
  586. HRESULT hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
  587. if (FAILED(hr)) {
  588. return hr;
  589. }
  590. IRCAM_IMAGE_CONTEXT *pItemContext;
  591. hr = pDrvItem->GetDeviceSpecContext((BYTE**)&pItemContext);
  592. if (FAILED(hr)) {
  593. WIAS_ERROR((g_hInst,"drvWriteItemProperties, NULL item context"));
  594. return E_POINTER;
  595. }
  596. //
  597. // Write the device item properties to the hardware here.
  598. //
  599. return hr;
  600. }
  601. //----------------------------------------------------------------------------
  602. /**************************************************************************\
  603. * IrUsdDevice::drvReadItemProperties
  604. *
  605. * Read the device item properties from the hardware.
  606. *
  607. * Arguments:
  608. *
  609. * pWiasContext - wia item context
  610. * lFlags - unused
  611. * nPropSpec -
  612. * pPropSpec -
  613. * plDevErrVal - device error value
  614. *
  615. * Return Value:
  616. *
  617. * Status
  618. *
  619. * History:
  620. *
  621. * 10/29/1998 Original Version
  622. *
  623. \**************************************************************************/
  624. //----------------------------------------------------------------------------
  625. HRESULT _stdcall IrUsdDevice::drvReadItemProperties(
  626. BYTE *pWiasContext,
  627. LONG lFlags,
  628. ULONG nPropSpec,
  629. const PROPSPEC *pPropSpec,
  630. LONG *plDevErrVal)
  631. {
  632. // For most scanner devices, item properties are stored in the driver
  633. // and written out at acquire image time. Some devices support properties
  634. // which should be updated on every property read. This can be done here.
  635. *plDevErrVal = 0;
  636. return S_OK;
  637. }
  638. //----------------------------------------------------------------------------
  639. /**************************************************************************\
  640. * IrUsdDevice::drvLockWiaDevice
  641. *
  642. * Lock access to the device.
  643. *
  644. * Arguments:
  645. *
  646. * pWiasContext - unused,
  647. * lFlags - unused
  648. * plDevErrVal - device error value
  649. *
  650. *
  651. * Return Value:
  652. *
  653. * Status
  654. *
  655. * History:
  656. *
  657. * 9/11/1998 Original Version
  658. *
  659. \**************************************************************************/
  660. //----------------------------------------------------------------------------
  661. HRESULT IrUsdDevice::drvLockWiaDevice(
  662. BYTE *pWiasContext,
  663. LONG lFlags,
  664. LONG *plDevErrVal)
  665. {
  666. *plDevErrVal = 0;
  667. return m_pStiDevice->LockDevice(100);
  668. }
  669. //----------------------------------------------------------------------------
  670. /**************************************************************************\
  671. * IrUsdDevice::drvUnLockWiaDevice
  672. *
  673. * Unlock access to the device.
  674. *
  675. * Arguments:
  676. *
  677. * pWiasContext - unused
  678. * lFlags - unused
  679. * plDevErrVal - device error value
  680. *
  681. *
  682. * Return Value:
  683. *
  684. * Status
  685. *
  686. * History:
  687. *
  688. * 9/11/1998 Original Version
  689. *
  690. \**************************************************************************/
  691. //----------------------------------------------------------------------------
  692. HRESULT IrUsdDevice::drvUnLockWiaDevice(
  693. BYTE *pWiasContext,
  694. LONG lFlags,
  695. LONG *plDevErrVal)
  696. {
  697. plDevErrVal = 0;
  698. return m_pStiDevice->UnLockDevice();
  699. }
  700. //----------------------------------------------------------------------------
  701. /**************************************************************************\
  702. * IrUsdDevice::drvAnalyzeItem
  703. *
  704. * The test camera does not support imag analysis.
  705. *
  706. * Arguments:
  707. *
  708. * pWiasContext - Pointer to the device item context to be analyzed.
  709. * lFlags - Operation flags.
  710. * plDevErrVal - device error value
  711. *
  712. * Return Value:
  713. *
  714. * Status
  715. *
  716. * History:
  717. *
  718. * 10/15/1998 Original Version
  719. *
  720. \**************************************************************************/
  721. //----------------------------------------------------------------------------
  722. HRESULT _stdcall IrUsdDevice::drvAnalyzeItem(
  723. BYTE *pWiasContext,
  724. LONG lFlags,
  725. LONG *plDevErrVal)
  726. {
  727. *plDevErrVal = 0;
  728. return E_NOTIMPL;
  729. }
  730. //----------------------------------------------------------------------------
  731. /**************************************************************************\
  732. * IrUsdDevice::drvFreeDrvItemContext
  733. *
  734. * The test scanner does not support imag analysis.
  735. *
  736. * Arguments:
  737. *
  738. * lFlags - unused
  739. * pSpecContext - Pointer to item specific context.
  740. * plDevErrVal - device error value
  741. *
  742. * Return Value:
  743. *
  744. * Status
  745. *
  746. * History:
  747. *
  748. * 10/15/1998 Original Version
  749. *
  750. \**************************************************************************/
  751. //----------------------------------------------------------------------------
  752. HRESULT _stdcall IrUsdDevice::drvFreeDrvItemContext(
  753. LONG lFlags,
  754. BYTE *pSpecContext,
  755. LONG *plDevErrVal )
  756. {
  757. IRCAM_IMAGE_CONTEXT *pContext = (IRCAM_IMAGE_CONTEXT*)pSpecContext;
  758. if (pContext != NULL)
  759. {
  760. if (pContext->pszCameraImagePath != NULL)
  761. {
  762. free(pContext->pszCameraImagePath);
  763. pContext->pszCameraImagePath = NULL;
  764. }
  765. }
  766. return S_OK;
  767. }