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.

4924 lines
151 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 2000
  4. *
  5. * TITLE: IWiaMiniDrv.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * DATE: 18 July, 2000
  10. *
  11. * DESCRIPTION:
  12. * Implementation of the WIA sample scanner IWiaMiniDrv methods.
  13. *
  14. *******************************************************************************/
  15. #include "pch.h"
  16. extern HINSTANCE g_hInst; // used for WIAS_LOGPROC macro
  17. #define _64BIT_ALIGNMENT // the real 64-bit alignment fix
  18. #define _SERVICE_EXTENT_VALIDATION // let the WIA service validate the extent settings
  19. //#define _OOB_DATA // Out Of Band data support (File Transfers only)
  20. #define BUFFER_PAD 1024 // buffer padding
  21. /**************************************************************************\
  22. * CWIAScannerDevice::drvDeleteItem
  23. *
  24. * This helper is called to delete a device item.
  25. * Note: Device items for this device may not be modified.
  26. * Return access denied.
  27. *
  28. * Arguments:
  29. *
  30. * pWiasContext - Indicates the item to delete.
  31. * lFlags - Operation flags, unused.
  32. * plDevErrVal - Pointer to the device error value.
  33. *
  34. * Return Value:
  35. *
  36. * Status
  37. *
  38. * History:
  39. *
  40. * 7/18/2000 Original Version
  41. *
  42. \**************************************************************************/
  43. HRESULT _stdcall CWIAScannerDevice::drvDeleteItem(
  44. BYTE *pWiasContext,
  45. LONG lFlags,
  46. LONG *plDevErrVal)
  47. {
  48. if (plDevErrVal)
  49. {
  50. *plDevErrVal = 0;
  51. }
  52. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  53. WIALOG_NO_RESOURCE_ID,
  54. WIALOG_LEVEL1,
  55. "CWIAScannerDevice::drvDeleteItem");
  56. return STG_E_ACCESSDENIED;
  57. }
  58. /**************************************************************************\
  59. * SendBitmapHeader
  60. *
  61. * This helper is called to send the bitmap header info to the callback
  62. * routine.
  63. * Note: This is a helper function used in TYMED_CALLBACK transfers.
  64. *
  65. * Arguments:
  66. *
  67. * pmdtc - a pointer to a transfer context.
  68. *
  69. * Return Value:
  70. *
  71. * Status
  72. *
  73. * History:
  74. *
  75. * 7/18/2000 Original Version
  76. *
  77. \**************************************************************************/
  78. HRESULT CWIAScannerDevice::SendBitmapHeader(
  79. PMINIDRV_TRANSFER_CONTEXT pmdtc)
  80. {
  81. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  82. WIALOG_NO_RESOURCE_ID,
  83. WIALOG_LEVEL3,
  84. "CWIAScannerDevice::SendBitmapHeader");
  85. HRESULT hr = S_OK;
  86. BITMAPINFO UNALIGNED *pbmi = (LPBITMAPINFO)pmdtc->pTransferBuffer;
  87. #ifdef _64BIT_ALIGNMENT
  88. BITMAPINFOHEADER UNALIGNED *pbmih = &pbmi->bmiHeader;
  89. pbmih->biHeight = -pbmih->biHeight;
  90. #else
  91. pbmi->bmiHeader.biHeight = -pbmi->bmiHeader.biHeight;
  92. #endif
  93. //
  94. // Send to class driver. WIA Class driver will pass
  95. // data through to client.
  96. //
  97. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_DATA,
  98. IT_STATUS_TRANSFER_TO_CLIENT,
  99. 0,
  100. 0,
  101. pmdtc->lHeaderSize,
  102. pmdtc,
  103. 0);
  104. if (hr == S_OK) {
  105. //
  106. // If the transfer was successfull, advance offset for
  107. // destination copy by the size of the data just sent.
  108. //
  109. pmdtc->cbOffset += pmdtc->lHeaderSize;
  110. }
  111. return hr;
  112. }
  113. /**************************************************************************\
  114. * SendFilePreviewBitmapHeader
  115. *
  116. * This helper is called to send the bitmap header info to the callback
  117. * routine.
  118. * Note: This is a helper function used in TYMED_FILE transfers with
  119. * (out of band data) enabled.
  120. *
  121. * Arguments:
  122. *
  123. * pmdtc - a pointer to a transfer context.
  124. *
  125. * Return Value:
  126. *
  127. * Status
  128. *
  129. * History:
  130. *
  131. * 7/18/2000 Original Version
  132. *
  133. \**************************************************************************/
  134. HRESULT CWIAScannerDevice::SendFilePreviewBitmapHeader(
  135. PMINIDRV_TRANSFER_CONTEXT pmdtc)
  136. {
  137. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  138. WIALOG_NO_RESOURCE_ID,
  139. WIALOG_LEVEL3,
  140. "CWIAScannerDevice::SendBitmapHeader");
  141. HRESULT hr = S_OK;
  142. #ifdef _OOB_DATA
  143. WIAS_DOWN_SAMPLE_INFO DownSampleInfo;
  144. memset(&DownSampleInfo,0,sizeof(DownSampleInfo));
  145. DownSampleInfo.ulBitsPerPixel = pmdtc->lDepth;
  146. DownSampleInfo.ulOriginalWidth = pmdtc->lWidthInPixels;
  147. DownSampleInfo.ulOriginalHeight = pmdtc->lLines;
  148. DownSampleInfo.ulDownSampledHeight = 0;
  149. DownSampleInfo.ulDownSampledWidth = 0;
  150. DownSampleInfo.ulXRes = pmdtc->lXRes;
  151. DownSampleInfo.ulYRes = pmdtc->lYRes;
  152. hr = wiasDownSampleBuffer(WIAS_GET_DOWNSAMPLED_SIZE_ONLY,
  153. &DownSampleInfo);
  154. if (FAILED(hr)) {
  155. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SendFilePreviewBitmapHeader, wiasDownSampleBuffer Failed"));
  156. WIAS_LHRESULT(m_pIWiaLog, hr);
  157. } else {
  158. //
  159. // acquire BITMAPHEADER pointer from pmdtc
  160. //
  161. LPBITMAPINFO UNALIGNED pbmi = (LPBITMAPINFO)pmdtc->pBaseBuffer;
  162. #ifdef _64BIT_ALIGNMENT
  163. BITMAPINFOHEADER UNALIGNED *pbmih = &pbmi->bmiHeader;
  164. pbmih->biHeight = 0; // set height to zero (0)
  165. pbmih->biWidth = DownSampleInfo.ulDownSampledWidth; // set down sampled width
  166. #else
  167. pmdtc->pBaseBuffer = pmdtc->pTransferBuffer + sizeof(BITMAPFILEHEADER);
  168. #endif
  169. //
  170. // adjust width and height
  171. //
  172. pbmi->bmiHeader.biHeight = 0; // set height to zero (0)
  173. pbmi->bmiHeader.biWidth = DownSampleInfo.ulDownSampledWidth; // set down sampled width
  174. //
  175. // Send to class driver. WIA Class driver will pass
  176. // data through to client.
  177. //
  178. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_FILE_PREVIEW_DATA,
  179. IT_STATUS_TRANSFER_TO_CLIENT,
  180. 0,
  181. 0,
  182. pmdtc->lHeaderSize - sizeof(BITMAPFILEHEADER),
  183. pmdtc,
  184. 0);
  185. }
  186. #endif
  187. return hr;
  188. }
  189. /**************************************************************************\
  190. * ScanItem
  191. *
  192. * This helper is called to do a FILE transfer.
  193. * Note: This routine must fill the complete buffer, and return percent
  194. * complete status back to the client if a callback routine is
  195. * provided.
  196. *
  197. * Arguments:
  198. *
  199. * pItemContext - private item data
  200. * pMiniTranCtx - minidriver supplied transfer info
  201. * plDevErrVal - device error value
  202. *
  203. * Return Value:
  204. *
  205. * Status
  206. *
  207. * History:
  208. *
  209. * 7/18/2000 Original Version
  210. *
  211. \**************************************************************************/
  212. HRESULT _stdcall CWIAScannerDevice::ScanItem(
  213. PMINIDRIVERITEMCONTEXT pItemContext,
  214. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  215. LONG *plDevErrVal)
  216. {
  217. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  218. WIALOG_NO_RESOURCE_ID,
  219. WIALOG_LEVEL3,
  220. "CWIAScannerDevice::ScanItem");
  221. HRESULT hr = S_OK;
  222. //
  223. // init buffer info
  224. //
  225. DWORD cbWritten = 0;
  226. LONG cbSize = 0;
  227. LONG cbRemaining = pmdtc->lBufferSize - pmdtc->lHeaderSize;
  228. PBYTE pBuf = pmdtc->pTransferBuffer + pmdtc->lHeaderSize;
  229. LONG lItemSize = pmdtc->lHeaderSize;
  230. BOOL bSwapBGRData = TRUE;
  231. BOOL bDWORDAlign = TRUE;
  232. BOOL bVerticalFlip= TRUE;
  233. LONG lScanPhase = SCAN_START;
  234. ULONG ulDestDataOffset = 0;
  235. BOOL bBitmapData = ((pmdtc->guidFormatID == WiaImgFmt_BMP) || (pmdtc->guidFormatID == WiaImgFmt_MEMORYBMP));
  236. LONG PercentComplete = 0;
  237. #ifdef _OOB_DATA
  238. WIAS_DOWN_SAMPLE_INFO DownSampleInfo;
  239. memset(&DownSampleInfo,0,sizeof(DownSampleInfo));
  240. //
  241. // SEND BITMAPHEADER to client
  242. //
  243. hr = SendFilePreviewBitmapHeader(pmdtc);
  244. if(hr == S_OK){
  245. //
  246. // move offset past file header
  247. //
  248. ulDestDataOffset += (pmdtc->lHeaderSize - sizeof(BITMAPFILEHEADER));
  249. } else {
  250. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, SendFilePreviewBitmapHeader Failed"));
  251. WIAS_LHRESULT(m_pIWiaLog, hr);
  252. return hr;
  253. }
  254. #endif
  255. if (bBitmapData) {
  256. //
  257. // check to see if the color data needs to be swapped
  258. //
  259. hr = m_pScanAPI->IsColorDataBGR(&bSwapBGRData);
  260. if (FAILED(hr)) {
  261. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, IsColorDataBGR() Failed"));
  262. WIAS_LHRESULT(m_pIWiaLog, hr);
  263. return hr;
  264. }
  265. //
  266. // check to see if data needs to be aligned
  267. //
  268. hr = m_pScanAPI->IsAlignmentNeeded(&bDWORDAlign);
  269. if (FAILED(hr)) {
  270. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, IsAlignmentNeeded() Failed"));
  271. WIAS_LHRESULT(m_pIWiaLog, hr);
  272. return hr;
  273. }
  274. }
  275. //
  276. // scan until buffer runs out or scanner completes transfer
  277. //
  278. while ((lScanPhase == SCAN_START) || (cbWritten)) {
  279. //
  280. // default transfer size is m_MaxBufferSize
  281. //
  282. cbSize = m_MaxBufferSize;
  283. if (bBitmapData) {
  284. //
  285. // Limit requests to max buffer size or less.
  286. //
  287. cbSize = (cbRemaining > m_MaxBufferSize) ? m_MaxBufferSize : cbRemaining;
  288. //
  289. // Request size to scanner must be modula the raw bytes per scan row.
  290. // Enough space for the alignment padding must be reserved.
  291. // These are requirements for AlignInPlace
  292. //
  293. cbSize = (cbSize / pItemContext->lBytesPerScanLine) *
  294. pItemContext->lBytesPerScanLineRaw;
  295. //
  296. // check if finished
  297. //
  298. if (cbSize == 0) {
  299. break;
  300. }
  301. }
  302. //
  303. // Device specific call to get data from the scanner and put it into
  304. // a buffer. lScanPhase indicates whether this is the first call to Scan,
  305. // pBuf is a pointer to the buffer, cbSize is the amount of data
  306. // requested from the scanner, and cbWritten will be set to the actual
  307. // amount of data returned by the scanner.
  308. //
  309. hr = m_pScanAPI->Scan(lScanPhase, pBuf, cbSize, &cbWritten);
  310. //
  311. // set flag to SCAN_CONTINUE, for other calls
  312. //
  313. lScanPhase = SCAN_CONTINUE;
  314. if (hr == S_OK) {
  315. if (cbWritten) {
  316. if (bBitmapData) {
  317. //
  318. // Place the scan data in correct byte order for 3 bytes ber pixel data.
  319. //
  320. if ((pmdtc->lDepth == 24)) {
  321. //
  322. // swap data if needed
  323. //
  324. if (bSwapBGRData) {
  325. SwapBuffer24(pBuf, cbWritten);
  326. }
  327. }
  328. //
  329. // Align the data on DWORD boundries.
  330. //
  331. if (bDWORDAlign) {
  332. cbWritten = AlignInPlace(pBuf,
  333. cbWritten,
  334. pItemContext->lBytesPerScanLine,
  335. pItemContext->lBytesPerScanLineRaw);
  336. }
  337. }
  338. //
  339. // advance buffer
  340. //
  341. lItemSize += cbWritten;
  342. pBuf += cbWritten;
  343. cbRemaining -= cbWritten;
  344. //
  345. // If a status callback was specified callback the class driver.
  346. //
  347. if (pmdtc->pIWiaMiniDrvCallBack) {
  348. FLOAT FractionComplete = 0.0f;
  349. if (pmdtc->lBufferSize) {
  350. if(bBitmapData){
  351. PercentComplete = 0;
  352. FractionComplete = (FLOAT)(pmdtc->lBufferSize - cbRemaining) / (FLOAT)pmdtc->lBufferSize;
  353. }
  354. } else {
  355. WIAS_LERROR(m_pIWiaLog,
  356. WIALOG_NO_RESOURCE_ID,
  357. ("ScanItemCB, pmdtc->lBufferSize = 0!"));
  358. }
  359. //
  360. // calculate percent complete
  361. //
  362. if(bBitmapData){
  363. PercentComplete = (LONG)(100 * FractionComplete);
  364. } else {
  365. PercentComplete += 25;
  366. if(PercentComplete >= 100){
  367. PercentComplete = 90;
  368. }
  369. }
  370. //
  371. // call back client with status on the transfer
  372. //
  373. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_STATUS,
  374. IT_STATUS_TRANSFER_TO_CLIENT,
  375. PercentComplete,
  376. 0,
  377. 0,
  378. NULL,
  379. 0);
  380. //
  381. // check for user cancel (from IT_MSG_STATUS callback)
  382. //
  383. if (hr == S_FALSE) {
  384. WIAS_LTRACE(m_pIWiaLog,
  385. WIALOG_NO_RESOURCE_ID,
  386. WIALOG_LEVEL4,
  387. ("ScanItem, Transfer canceled by client (IT_MSG_STATUS callback)"));
  388. break;
  389. } else if (FAILED(hr)) {
  390. //
  391. // transfer failed
  392. //
  393. WIAS_LERROR(m_pIWiaLog,
  394. WIALOG_NO_RESOURCE_ID,
  395. ("ScanItem, MiniDrvCallback failed (IT_MSG_STATUS callback)"));
  396. WIAS_LHRESULT(m_pIWiaLog, hr);
  397. break;
  398. }
  399. #ifdef _OOB_DATA
  400. DownSampleInfo.pDestBuffer = NULL; // allocate this for me?
  401. DownSampleInfo.pSrcBuffer = pBuf - cbWritten;
  402. DownSampleInfo.ulActualSize = 0; // Actual of what? data written?
  403. DownSampleInfo.ulBitsPerPixel = pmdtc->lDepth;
  404. DownSampleInfo.ulDestBufSize = 0;
  405. DownSampleInfo.ulDownSampledHeight = 0;
  406. DownSampleInfo.ulDownSampledWidth = 0;
  407. DownSampleInfo.ulOriginalHeight = (cbWritten / pItemContext->lBytesPerScanLine);
  408. DownSampleInfo.ulOriginalWidth = pmdtc->lWidthInPixels;
  409. DownSampleInfo.ulSrcBufSize = cbWritten;
  410. DownSampleInfo.ulXRes = pmdtc->lXRes;
  411. DownSampleInfo.ulYRes = pmdtc->lYRes;
  412. hr = wiasDownSampleBuffer(0, &DownSampleInfo);
  413. if(FAILED(hr)){
  414. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, wiasDownSampleBuffer Failed"));
  415. WIAS_LHRESULT(m_pIWiaLog, hr);
  416. } else {
  417. pmdtc->pBaseBuffer = DownSampleInfo.pDestBuffer;
  418. //
  419. // call back client with down sampled buffer
  420. //
  421. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_FILE_PREVIEW_DATA,
  422. IT_STATUS_TRANSFER_TO_CLIENT,
  423. PercentComplete,
  424. ulDestDataOffset,
  425. DownSampleInfo.ulActualSize,
  426. pmdtc,
  427. 0);
  428. //
  429. // update offset
  430. //
  431. ulDestDataOffset += DownSampleInfo.ulActualSize;
  432. }
  433. //
  434. // check for user cancel (from IT_MSG_FILE_PREVIEW_DATA callback)
  435. //
  436. if (hr == S_FALSE) {
  437. WIAS_LTRACE(m_pIWiaLog,
  438. WIALOG_NO_RESOURCE_ID,
  439. WIALOG_LEVEL4,
  440. ("ScanItem, Transfer canceled by client (IT_MSG_FILE_PREVIEW_DATA callback)"));
  441. break;
  442. } else if (FAILED(hr)) {
  443. //
  444. // transfer failed
  445. //
  446. WIAS_LERROR(m_pIWiaLog,
  447. WIALOG_NO_RESOURCE_ID,
  448. ("ScanItem, MiniDrvCallback failed (IT_MSG_FILE_PREVIEW_DATA callback)"));
  449. WIAS_LHRESULT(m_pIWiaLog, hr);
  450. break;
  451. }
  452. #endif
  453. }
  454. //
  455. // write the band of data here
  456. //
  457. if (!bBitmapData) {
  458. if (hr == S_OK) {
  459. if (!pmdtc->bClassDrvAllocBuf) {
  460. pmdtc->lItemSize = cbWritten;
  461. hr = wiasWritePageBufToFile(pmdtc);
  462. if (FAILED(hr)) {
  463. WIAS_LERROR(m_pIWiaLog,
  464. WIALOG_NO_RESOURCE_ID,
  465. ("ScanItem, WritePageBufToFile failed"));
  466. }
  467. }
  468. pBuf = pmdtc->pTransferBuffer;
  469. }
  470. }
  471. }
  472. } else {
  473. //
  474. // Get the device error
  475. //
  476. if (plDevErrVal) {
  477. *plDevErrVal = (LONG) hr;
  478. WIAS_LERROR(m_pIWiaLog,
  479. WIALOG_NO_RESOURCE_ID,
  480. ("ScanItem, data transfer failed, status: 0x%X", hr));
  481. }
  482. break;
  483. }
  484. }
  485. if (hr == S_OK) {
  486. //
  487. // On success, flip the buffer about the vertical access if
  488. // we have a DIB header and data.
  489. //
  490. if (pmdtc->guidFormatID == WiaImgFmt_BMP) {
  491. if(bVerticalFlip){
  492. VerticalFlip(pItemContext, pmdtc);
  493. }
  494. }
  495. if (bBitmapData) {
  496. //
  497. // If the mini driver allocated a page buffer, we need to write the
  498. // buffer to the open file handle (opened by class driver).
  499. //
  500. if (!pmdtc->bClassDrvAllocBuf) {
  501. //
  502. // Now that we know the true item size, update the mini driver
  503. // context.
  504. //
  505. pmdtc->lItemSize = lItemSize;
  506. hr = wiasWritePageBufToFile(pmdtc);
  507. if (FAILED(hr)) {
  508. WIAS_LERROR(m_pIWiaLog,
  509. WIALOG_NO_RESOURCE_ID,
  510. ("ScanItem, WritePageBufToFile failed"));
  511. }
  512. }
  513. }
  514. }
  515. HRESULT Temphr = m_pScanAPI->Scan(SCAN_END, NULL, 0, NULL);
  516. if(FAILED(Temphr)){
  517. WIAS_LERROR(m_pIWiaLog,
  518. WIALOG_NO_RESOURCE_ID,
  519. ("ScanItem, Ending a scanning session failed"));
  520. hr = Temphr;
  521. }
  522. #ifdef _OOB_DATA
  523. //
  524. // free down sampled, temporary buffer
  525. //
  526. if(DownSampleInfo.pDestBuffer){
  527. CoTaskMemFree(DownSampleInfo.pDestBuffer);
  528. DownSampleInfo.pDestBuffer = NULL;
  529. }
  530. #endif
  531. if (!bBitmapData) {
  532. //
  533. // call back client with status on the transfer with 100% complete
  534. //
  535. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_STATUS,
  536. IT_STATUS_TRANSFER_TO_CLIENT,
  537. 100,
  538. 0,
  539. 0,
  540. NULL,
  541. 0);
  542. }
  543. return hr;
  544. }
  545. /**************************************************************************\
  546. * ScanItemCB
  547. *
  548. * This helper is called to do a MEMORY transfer.
  549. * Note: This routine must fill buffers, adjust the buffer offset and
  550. * return percent complete status back to the client via a callback
  551. * routine. (a callback interface must be supplied by the caller for
  552. * this routine to function).
  553. *
  554. * Arguments:
  555. *
  556. * pItemContext - private item data
  557. * pmdtc - buffer and callback information
  558. * plDevErrVal - device error value
  559. *
  560. * Return Value:
  561. *
  562. * Status
  563. *
  564. * History:
  565. *
  566. * 7/18/2000 Original Version
  567. *
  568. \**************************************************************************/
  569. HRESULT _stdcall CWIAScannerDevice::ScanItemCB(
  570. PMINIDRIVERITEMCONTEXT pItemContext,
  571. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  572. LONG *plDevErrVal)
  573. {
  574. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  575. WIALOG_NO_RESOURCE_ID,
  576. WIALOG_LEVEL3,
  577. "CWIAScannerDevice::ScanItemCB");
  578. HRESULT hr = S_OK;
  579. //
  580. // init buffer info
  581. //
  582. DWORD cbWritten = 0;
  583. LONG cbSize = 0;
  584. LONG cbRemaining = pmdtc->lImageSize; //pmdtc->lBufferSize - pmdtc->lHeaderSize;
  585. PBYTE pBuf = pmdtc->pTransferBuffer + pmdtc->lHeaderSize;
  586. LONG lItemSize = pmdtc->lHeaderSize;
  587. BOOL bSwapBGRData = TRUE;
  588. BOOL bDWORDAlign = TRUE;
  589. BOOL bVerticalFlip= TRUE;
  590. LONG lScanPhase = SCAN_START;
  591. pmdtc->cbOffset = 0;
  592. BOOL bBitmapData = ((pmdtc->guidFormatID == WiaImgFmt_BMP) || (pmdtc->guidFormatID == WiaImgFmt_MEMORYBMP));
  593. LONG PercentComplete = 0;
  594. //
  595. // This must be a callback transfer request
  596. //
  597. if ((pmdtc->pIWiaMiniDrvCallBack == NULL) ||
  598. (!pmdtc->bTransferDataCB)) {
  599. WIAS_LERROR(m_pIWiaLog,
  600. WIALOG_NO_RESOURCE_ID,
  601. ("ScanItemCB, invalid callback params"));
  602. return E_INVALIDARG;
  603. }
  604. if (bBitmapData) {
  605. //
  606. // SEND BITMAPHEADER to client
  607. //
  608. hr = SendBitmapHeader(pmdtc);
  609. if (hr != S_OK) {
  610. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItemCB, SendBitmapHeader failed"));
  611. WIAS_LHRESULT(m_pIWiaLog, hr);
  612. return hr;
  613. }
  614. //
  615. // check to see if the color data needs to be swapped
  616. //
  617. hr = m_pScanAPI->IsColorDataBGR(&bSwapBGRData);
  618. if (FAILED(hr)) {
  619. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItemCB, IsColorDataBGR() Failed"));
  620. WIAS_LHRESULT(m_pIWiaLog, hr);
  621. return hr;
  622. }
  623. //
  624. // check to see if data needs to be aligned
  625. //
  626. hr = m_pScanAPI->IsAlignmentNeeded(&bDWORDAlign);
  627. if (FAILED(hr)) {
  628. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("ScanItem, IsAlignmentNeeded() Failed"));
  629. WIAS_LHRESULT(m_pIWiaLog, hr);
  630. return hr;
  631. }
  632. }
  633. //
  634. // scan until buffer runs out or scanner completes transfer
  635. //
  636. while ((lScanPhase == SCAN_START) || (cbWritten)) {
  637. //
  638. // assign the pointer to the transfer buffer
  639. //
  640. pBuf = pmdtc->pTransferBuffer;
  641. cbSize = m_MaxBufferSize; // default
  642. if (bBitmapData) {
  643. //
  644. // Limit requests to requested buffer size or less.
  645. //
  646. cbSize = (cbRemaining > pmdtc->lBufferSize) ? pmdtc->lBufferSize : cbRemaining;
  647. //
  648. // Request size to scanner must be modula the raw bytes per scan row.
  649. // Enough space for the alignment padding must be reserved.
  650. // These are requirements for AlignInPlace
  651. //
  652. cbSize = (cbSize / pItemContext->lBytesPerScanLine) *
  653. pItemContext->lBytesPerScanLineRaw;
  654. //
  655. // check if finished
  656. //
  657. if (cbSize == 0) {
  658. break;
  659. }
  660. }
  661. //
  662. // Device specific call to get data from the scanner and put it into
  663. // a buffer. lScanPhase indicates whether this is the first call to Scan,
  664. // pBuf is a pointer to the buffer, cbSize is the amount of data
  665. // requested from the scanner, and cbWritten will be set to the actual
  666. // amount of data returned by the scanner.
  667. //
  668. hr = m_pScanAPI->Scan(lScanPhase, pBuf, cbSize, &cbWritten);
  669. //
  670. // set flag to SCAN_CONTINUE, for other calls
  671. //
  672. lScanPhase = SCAN_CONTINUE;
  673. if (hr == S_OK) {
  674. if (cbWritten) {
  675. if (bBitmapData) {
  676. //
  677. // Place the scan data in correct byte order for 3 bytes ber pixel data.
  678. //
  679. if ((pmdtc->lDepth == 24)) {
  680. //
  681. // swap data if needed
  682. //
  683. if (bSwapBGRData) {
  684. SwapBuffer24(pBuf, cbWritten);
  685. }
  686. }
  687. //
  688. // Align the data on DWORD boundries.
  689. //
  690. if (bDWORDAlign) {
  691. cbWritten = AlignInPlace(pBuf,
  692. cbWritten,
  693. pItemContext->lBytesPerScanLine,
  694. pItemContext->lBytesPerScanLineRaw);
  695. }
  696. }
  697. //
  698. // advance buffer
  699. //
  700. cbRemaining -= cbWritten;
  701. //
  702. // If a status callback was specified callback the class driver.
  703. // There has to be a callback provided, this is the callback
  704. // transfer.
  705. //
  706. if (pmdtc->pIWiaMiniDrvCallBack) {
  707. FLOAT FractionComplete = 0.0f;
  708. if ((pmdtc->lImageSize + pmdtc->lHeaderSize)) {
  709. if (bBitmapData) {
  710. PercentComplete = 0;
  711. FractionComplete = (FLOAT) (pmdtc->cbOffset + cbWritten) /
  712. (FLOAT) (pmdtc->lImageSize + pmdtc->lHeaderSize);
  713. }
  714. } else {
  715. WIAS_LERROR(m_pIWiaLog,
  716. WIALOG_NO_RESOURCE_ID,
  717. ("ScanItemCB, pmdtc->lBufferSize = 0!"));
  718. }
  719. //
  720. // calculate percent complete
  721. //
  722. if (bBitmapData) {
  723. PercentComplete = (LONG)(100 * FractionComplete);
  724. } else {
  725. PercentComplete += 25;
  726. if (PercentComplete >= 100) {
  727. PercentComplete = 90;
  728. }
  729. }
  730. //
  731. // call back client with status on the transfer and data offset
  732. //
  733. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_DATA,
  734. IT_STATUS_TRANSFER_TO_CLIENT,
  735. PercentComplete,
  736. pmdtc->cbOffset,
  737. cbWritten,
  738. pmdtc,
  739. 0);
  740. //
  741. // check for user cancel
  742. //
  743. if (hr == S_FALSE) {
  744. WIAS_LTRACE(m_pIWiaLog,
  745. WIALOG_NO_RESOURCE_ID,
  746. WIALOG_LEVEL4,
  747. ("ScanItemCB, Transfer canceled by client (IT_MSG_DATA callback)"));
  748. break;
  749. } else if (FAILED(hr)) {
  750. //
  751. // transfer failed
  752. //
  753. WIAS_LERROR(m_pIWiaLog,
  754. WIALOG_NO_RESOURCE_ID,
  755. ("ScanItemCB, MiniDrvCallback failed (IT_MSG_DATA callback)"));
  756. WIAS_LHRESULT(m_pIWiaLog, hr);
  757. break;
  758. }
  759. }
  760. //
  761. // move offset
  762. //
  763. pmdtc->cbOffset += cbWritten;
  764. }
  765. } else {
  766. //
  767. // Get the device error
  768. //
  769. if (plDevErrVal) {
  770. *plDevErrVal = (LONG) hr;
  771. WIAS_LERROR(m_pIWiaLog,
  772. WIALOG_NO_RESOURCE_ID,
  773. ("ScanItemCB, data transfer failed, status: 0x%X", hr));
  774. }
  775. break;
  776. }
  777. }
  778. HRESULT Temphr = m_pScanAPI->Scan(SCAN_END, NULL, 0, NULL);
  779. if(FAILED(Temphr)){
  780. WIAS_LERROR(m_pIWiaLog,
  781. WIALOG_NO_RESOURCE_ID,
  782. ("ScanItemCB, Ending a scanning session failed"));
  783. return Temphr;
  784. }
  785. if (!bBitmapData) {
  786. //
  787. // call back client to show 100% with status on the transfer and data offset
  788. //
  789. hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_DATA,
  790. IT_STATUS_TRANSFER_TO_CLIENT,
  791. 100,
  792. pmdtc->cbOffset,
  793. cbWritten,
  794. pmdtc,
  795. 0);
  796. }
  797. return hr;
  798. }
  799. /**************************************************************************\
  800. * CWIAScannerDevice::drvAcquireItemData
  801. *
  802. * This driver entry point is called when image data is requested from the
  803. * device.
  804. *
  805. * Arguments:
  806. *
  807. * pWiasContext - Pointer to the WIA item.
  808. * lFlags - Operation flags, unused.
  809. * pmdtc - Pointer to mini driver context. On entry, only the
  810. * portion of the mini driver context which is derived
  811. * from the item properties is filled in.
  812. * plDevErrVal - Pointer to the device error value.
  813. *
  814. * Return Value:
  815. *
  816. * Status
  817. *
  818. * History:
  819. *
  820. * 7/18/2000 Original Version
  821. *
  822. \**************************************************************************/
  823. HRESULT _stdcall CWIAScannerDevice::drvAcquireItemData(
  824. BYTE *pWiasContext,
  825. LONG lFlags,
  826. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  827. LONG *plDevErrVal)
  828. {
  829. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  830. WIALOG_NO_RESOURCE_ID,
  831. WIALOG_LEVEL1,
  832. "CWIAScannerDevice::drvAcquireItemData");
  833. HRESULT hr = S_OK;
  834. BOOL bBitmapData = ((pmdtc->guidFormatID == WiaImgFmt_BMP) || (pmdtc->guidFormatID == WiaImgFmt_MEMORYBMP));
  835. if (plDevErrVal) {
  836. *plDevErrVal = 0;
  837. }
  838. //
  839. // Get a pointer to the associated driver item.
  840. //
  841. IWiaDrvItem* pDrvItem;
  842. hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
  843. if (FAILED(hr)) {
  844. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, wiasGetDrvItem() failed."));
  845. WIAS_LHRESULT(m_pIWiaLog,hr);
  846. return hr;
  847. }
  848. //
  849. // Validate the data transfer context.
  850. //
  851. hr = ValidateDataTransferContext(pmdtc);
  852. if (FAILED(hr)) {
  853. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, ValidateDataTransferContext() failed."));
  854. WIAS_LHRESULT(m_pIWiaLog,hr);
  855. return hr;
  856. }
  857. //
  858. // Get item specific driver data
  859. //
  860. PMINIDRIVERITEMCONTEXT pItemContext = NULL;
  861. hr = pDrvItem->GetDeviceSpecContext((BYTE**)&pItemContext);
  862. if (FAILED(hr)) {
  863. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, NULL item context"));
  864. WIAS_LHRESULT(m_pIWiaLog,hr);
  865. return hr;
  866. }
  867. //
  868. // allocate a buffer to be used for the data transfer. This will only happen, when the
  869. // the data format is non-bitmap. Item Size is set to 0, telling the WIA service, that
  870. // we will be allocating the buffer for transfer.
  871. //
  872. if (!pmdtc->bClassDrvAllocBuf) {
  873. LONG lClassDrvAllocSize = m_MaxBufferSize + BUFFER_PAD; // max buffer band size
  874. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Attempting to Allocate (%d)bytes for pmdtc->pTransferBuffer",lClassDrvAllocSize));
  875. pmdtc->pTransferBuffer = (PBYTE) CoTaskMemAlloc(lClassDrvAllocSize);
  876. if (!pmdtc->pTransferBuffer) {
  877. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, unable to allocate temp transfer buffer, size: %d",(pmdtc->lImageSize + pmdtc->lHeaderSize)));
  878. return E_OUTOFMEMORY;
  879. }
  880. //
  881. // set new buffer size
  882. //
  883. pmdtc->lBufferSize = lClassDrvAllocSize;
  884. }
  885. if (bBitmapData) {
  886. //
  887. // Use WIA services to fetch format specific info. This information
  888. // is based on the property settings.
  889. //
  890. hr = wiasGetImageInformation(pWiasContext, 0, pmdtc);
  891. if (hr != S_OK) {
  892. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, wiasGetImageInformation failed."));
  893. WIAS_LHRESULT(m_pIWiaLog,hr);
  894. return hr;
  895. }
  896. }
  897. //
  898. // Check if we are in Preview Mode
  899. //
  900. if(IsPreviewScan(pWiasContext)){
  901. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Preview Property is SET"));
  902. m_pScanAPI->SetScanMode(SCANMODE_PREVIEWSCAN);
  903. } else {
  904. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Preview Property is NOT SET"));
  905. m_pScanAPI->SetScanMode(SCANMODE_FINALSCAN);
  906. }
  907. //
  908. // Get number of pages requested, for ADF scanning loop
  909. //
  910. BOOL bEmptyTheADF = FALSE;
  911. LONG lPagesRequested = GetPageCount(pWiasContext);
  912. if (lPagesRequested == 0) {
  913. bEmptyTheADF = TRUE;
  914. lPagesRequested = 1;// set to 1 so we can enter our loop
  915. // WIA_STATUS_END_OF_MEDIA will terminate
  916. // the loop...or an error, or a cancel..
  917. //
  918. }
  919. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Pages to Scan = %d",lPagesRequested));
  920. if (IsADFEnabled(pWiasContext)) { // FEEDER is enabled for scanning
  921. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Feeder is enabled for use"));
  922. //
  923. // clear an potential paper that may be blocking the
  924. // scan pathway.
  925. //
  926. hr = m_pScanAPI->ADFUnFeedPage();
  927. if (FAILED(hr)) {
  928. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, ADFUnFeedPage (begin transfer) Failed"));
  929. WIAS_LHRESULT(m_pIWiaLog, hr);
  930. return hr;
  931. }
  932. } else { // FLATBED is enabled for scanning
  933. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Feeder is disabled or no feeder exists"));
  934. //
  935. // Transfer only a single image
  936. //
  937. bEmptyTheADF = FALSE;
  938. lPagesRequested = 1;
  939. }
  940. //
  941. // WIA document scanning loop
  942. //
  943. LONG lPagesScanned = 0; // number of pages currently scanned
  944. BOOL bCallBackTransfer = FALSE; // callback transfer flag
  945. while (lPagesRequested > 0) {
  946. if (IsADFEnabled(pWiasContext)) {
  947. //
  948. // Check feeder for paper
  949. //
  950. hr = m_pScanAPI->ADFHasPaper();
  951. if (FAILED(hr)) {
  952. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, ADFHasPaper Failed"));
  953. WIAS_LHRESULT(m_pIWiaLog, hr);
  954. return hr;
  955. } else if(hr == S_FALSE){
  956. return WIA_ERROR_PAPER_EMPTY;
  957. }
  958. //
  959. // Attempt to load a page (only if needed)
  960. //
  961. hr = m_pScanAPI->ADFFeedPage();
  962. if (FAILED(hr)) {
  963. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, ADFFeedPage Failed"));
  964. WIAS_LHRESULT(m_pIWiaLog, hr);
  965. return hr;
  966. }
  967. //
  968. // Check feeder's status
  969. //
  970. hr = m_pScanAPI->ADFStatus();
  971. if (FAILED(hr)) {
  972. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, ADFStatus Failed"));
  973. WIAS_LHRESULT(m_pIWiaLog, hr);
  974. return hr;
  975. }
  976. }
  977. if (bBitmapData) {
  978. //
  979. // update image information
  980. //
  981. hr = wiasGetImageInformation(pWiasContext, 0, pmdtc);
  982. if (FAILED(hr)) {
  983. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, wiasGetImageInformation Failed"));
  984. WIAS_LHRESULT(m_pIWiaLog, hr);
  985. return hr;
  986. }
  987. }
  988. //
  989. // Determine if this is a callback or file transfer.
  990. //
  991. if (pmdtc->tymed == TYMED_CALLBACK) {
  992. //
  993. // Scan the page to memory
  994. //
  995. bCallBackTransfer = TRUE;
  996. hr = ScanItemCB(pItemContext,
  997. pmdtc,
  998. plDevErrVal);
  999. } else {
  1000. //
  1001. // Scan the page to file
  1002. //
  1003. hr = ScanItem(pItemContext,
  1004. pmdtc,
  1005. plDevErrVal);
  1006. }
  1007. if (!bEmptyTheADF) {
  1008. //
  1009. // update pages requested counter
  1010. //
  1011. lPagesRequested--;
  1012. }
  1013. if (hr == S_FALSE) {
  1014. //
  1015. // user canceled the scan
  1016. //
  1017. lPagesRequested = 0; // set pages to 0 to cleanly exit loop
  1018. }
  1019. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Pages left to scan = %d",lPagesRequested));
  1020. if (IsADFEnabled(pWiasContext)) {
  1021. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Unloading a page from the feeder"));
  1022. //
  1023. // Attempt to unload the scanned page (only if needed)
  1024. //
  1025. hr = m_pScanAPI->ADFUnFeedPage();
  1026. if (SUCCEEDED(hr)) {
  1027. if (bCallBackTransfer) {
  1028. //
  1029. // send the NEW_PAGE message, when scanning multiple pages
  1030. // in callback mode. This will let the calling application
  1031. // know when an end-of-page has been hit.
  1032. //
  1033. hr = wiasSendEndOfPage(pWiasContext, lPagesScanned, pmdtc);
  1034. if (FAILED(hr)) {
  1035. lPagesRequested = 0;
  1036. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, wiasSendEndOfPage Failed"));
  1037. WIAS_LHRESULT(m_pIWiaLog, hr);
  1038. }
  1039. }
  1040. //
  1041. // increment pages scanned counter
  1042. //
  1043. lPagesScanned++;
  1044. } else {
  1045. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, ADFUnFeedPage (end transfer) Failed"));
  1046. WIAS_LHRESULT(m_pIWiaLog, hr);
  1047. }
  1048. }
  1049. //
  1050. // free any allocated memory between scans to avoid memory leaks
  1051. //
  1052. if (!pmdtc->bClassDrvAllocBuf) {
  1053. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Freeing any allocated memory (single scan operation complete)"));
  1054. if (NULL != pmdtc->pTransferBuffer) {
  1055. CoTaskMemFree(pmdtc->pTransferBuffer);
  1056. pmdtc->pTransferBuffer = NULL;
  1057. }
  1058. }
  1059. if (IsADFEnabled(pWiasContext)) { // FEEDER is enabled for scanning
  1060. //
  1061. // Check feeder for paper, to avoid error conditions
  1062. //
  1063. hr = m_pScanAPI->ADFHasPaper();
  1064. if (S_FALSE == hr) {
  1065. LONG lPages = GetPageCount(pWiasContext);
  1066. //
  1067. // have we scanned more than 1 page?
  1068. //
  1069. if(lPagesScanned > 0){
  1070. //
  1071. // Pages is set to n, and we successfully scanned n pages, return S_OK
  1072. //
  1073. if(lPagesScanned == lPages){
  1074. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, We are out of paper, but we successfully scanned the requested amount"));
  1075. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, returning S_OK"));
  1076. return S_OK;
  1077. }
  1078. //
  1079. // Pages is set to 0, and 1 or more pages have been scanned, return S_OK
  1080. //
  1081. if(lPages == 0){
  1082. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, We are out of paper, but we successfully scanned more than 1 page"));
  1083. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, returning S_OK"));
  1084. return S_OK;
  1085. }
  1086. //
  1087. // Pages is set to n, and we successfully scanned lPagesScanned but
  1088. // that is less than n...and the file is OK, return WIA_STATUS_END_OF_MEDIA
  1089. //
  1090. if ((lPages > 0)&&(lPagesScanned < lPages)) {
  1091. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, We are out of paper, but we successfully scanned more than 1 page..but less than requested"));
  1092. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, returning WIA_STATUS_END_OF_MEDIA"));
  1093. return WIA_STATUS_END_OF_MEDIA;
  1094. }
  1095. }
  1096. }
  1097. }
  1098. }
  1099. //
  1100. // we are now finished scanning all documents
  1101. //
  1102. if (!pmdtc->bClassDrvAllocBuf) {
  1103. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvAcquireItemData, Freeing any allocated memory (entire scan operation complete)"));
  1104. if (NULL != pmdtc->pTransferBuffer) {
  1105. CoTaskMemFree(pmdtc->pTransferBuffer);
  1106. pmdtc->pTransferBuffer = NULL;
  1107. }
  1108. }
  1109. return hr;
  1110. }
  1111. /**************************************************************************\
  1112. * IsPreviewScan
  1113. *
  1114. * Get the current preview setting from the item properties.
  1115. * A helper for drvAcquireItemData.
  1116. *
  1117. * Arguments:
  1118. *
  1119. * pWiasContext - pointer to an Item context.
  1120. *
  1121. * Return Value:
  1122. *
  1123. * TRUE - Preview is set, FALSE - Final is set
  1124. *
  1125. * History:
  1126. *
  1127. * 8/10/2000 Original Version
  1128. *
  1129. \**************************************************************************/
  1130. BOOL CWIAScannerDevice::IsPreviewScan(BYTE *pWiasContext)
  1131. {
  1132. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1133. WIALOG_NO_RESOURCE_ID,
  1134. WIALOG_LEVEL3,
  1135. "CWIAScannerDevice::IsPreviewScan");
  1136. //
  1137. // Get a pointer to the root item, for property access.
  1138. //
  1139. BYTE *pRootItemCtx = NULL;
  1140. HRESULT hr = wiasGetRootItem(pWiasContext, &pRootItemCtx);
  1141. if (FAILED(hr)) {
  1142. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("IsPreviewScan, No Preview Property Found on ROOT item!"));
  1143. return FALSE;
  1144. }
  1145. //
  1146. // Get the current preview setting.
  1147. //
  1148. LONG lPreview = 0;
  1149. hr = wiasReadPropLong(pRootItemCtx, WIA_DPS_PREVIEW, &lPreview, NULL, true);
  1150. if (hr != S_OK) {
  1151. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("IsPreviewScan, Failed to read Preview Property."));
  1152. WIAS_LHRESULT(m_pIWiaLog, hr);
  1153. return FALSE;
  1154. }
  1155. return (lPreview > 0);
  1156. }
  1157. /**************************************************************************\
  1158. * IsADFEnabled
  1159. *
  1160. * Get the current Document Handling Select setting from the item properties.
  1161. *
  1162. * Arguments:
  1163. *
  1164. * pWiasContext - pointer to an Item context.
  1165. *
  1166. * Return Value:
  1167. *
  1168. * TRUE - enabled, FALSE - disabled
  1169. *
  1170. * History:
  1171. *
  1172. * 5/01/2001 Original Version
  1173. *
  1174. \**************************************************************************/
  1175. BOOL CWIAScannerDevice::IsADFEnabled(BYTE *pWiasContext)
  1176. {
  1177. HRESULT hr = S_OK;
  1178. BOOL bEnabled = FALSE;
  1179. //
  1180. // Get a pointer to the root item, for property access.
  1181. //
  1182. BYTE *pRootItemCtx = NULL;
  1183. hr = wiasGetRootItem(pWiasContext, &pRootItemCtx);
  1184. if (SUCCEEDED(hr)) {
  1185. //
  1186. // read Document Handling Select property value
  1187. //
  1188. LONG lDocumentHandlingSelect = FLATBED;
  1189. hr = wiasReadPropLong(pRootItemCtx,WIA_DPS_DOCUMENT_HANDLING_SELECT,&lDocumentHandlingSelect,NULL,TRUE);
  1190. if (FAILED(hr)) {
  1191. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("IsADFEnabled, wiasReadPropLong(WIA_DPS_DOCUMENT_HANDLING_SELECT) failed"));
  1192. WIAS_LHRESULT(m_pIWiaLog, hr);
  1193. } else {
  1194. if (lDocumentHandlingSelect & FEEDER) {
  1195. //
  1196. // FEEDER is set
  1197. //
  1198. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("IsADFEnabled - ADF Enabled"));
  1199. bEnabled = TRUE;
  1200. } else {
  1201. //
  1202. // FEEDER is not set, default to FLATBED (WIAFBDRV only supports simple Document feeders at this time)
  1203. //
  1204. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("IsADFEnabled - ADF Disabled"));
  1205. bEnabled = FALSE;
  1206. }
  1207. }
  1208. } else {
  1209. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("IsADFEnabled, wiasGetRootItem failed"));
  1210. WIAS_LHRESULT(m_pIWiaLog, hr);
  1211. }
  1212. return bEnabled;
  1213. }
  1214. /**************************************************************************\
  1215. * GetPageCount
  1216. *
  1217. * Get the requested number of pages to scan from the item properties.
  1218. * A helper for drvAcquireItemData.
  1219. *
  1220. * Arguments:
  1221. *
  1222. * pWiasContext - pointer to an Item context.
  1223. *
  1224. * Return Value:
  1225. *
  1226. * Number of pages to scan.
  1227. *
  1228. * History:
  1229. *
  1230. * 7/18/2000 Original Version
  1231. *
  1232. \**************************************************************************/
  1233. LONG CWIAScannerDevice::GetPageCount(BYTE *pWiasContext)
  1234. {
  1235. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1236. WIALOG_NO_RESOURCE_ID,
  1237. WIALOG_LEVEL3,
  1238. "CWIAScannerDevice::GetPageCount");
  1239. //
  1240. // Get a pointer to the root item, for property access.
  1241. //
  1242. BYTE *pRootItemCtx = NULL;
  1243. HRESULT hr = wiasGetRootItem(pWiasContext, &pRootItemCtx);
  1244. if (FAILED(hr)) {
  1245. return 1;
  1246. }
  1247. //
  1248. // Get the requested page count.
  1249. //
  1250. LONG lPagesRequested = 0;
  1251. hr = wiasReadPropLong(pRootItemCtx, WIA_DPS_PAGES, &lPagesRequested, NULL, true);
  1252. if (hr != S_OK) {
  1253. return 1;
  1254. }
  1255. return lPagesRequested;
  1256. }
  1257. /**************************************************************************\
  1258. * SetItemSize
  1259. *
  1260. * Calulate the new item size, and write the new Item Size property value.
  1261. *
  1262. * Arguments:
  1263. *
  1264. * pWiasContext - item
  1265. *
  1266. * Return Value:
  1267. *
  1268. * Status
  1269. *
  1270. * History:
  1271. *
  1272. * 7/18/2000 Original Version
  1273. *
  1274. \**************************************************************************/
  1275. HRESULT CWIAScannerDevice::SetItemSize(
  1276. BYTE *pWiasContext)
  1277. {
  1278. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1279. WIALOG_NO_RESOURCE_ID,
  1280. WIALOG_LEVEL3,
  1281. "CWIAScannerDevice::SetItemSize");
  1282. HRESULT hr = S_OK;
  1283. LONG lWidthInBytes = 0;
  1284. LONG lMinBufSize = 0;
  1285. GUID guidFormatID = GUID_NULL;
  1286. MINIDRV_TRANSFER_CONTEXT mdtc;
  1287. LONG lNumProperties = 3;
  1288. PROPVARIANT pv[3];
  1289. PROPSPEC ps[3] = {{PRSPEC_PROPID, WIA_IPA_ITEM_SIZE},
  1290. {PRSPEC_PROPID, WIA_IPA_BYTES_PER_LINE},
  1291. {PRSPEC_PROPID, WIA_IPA_MIN_BUFFER_SIZE}};
  1292. //
  1293. // Clear the MiniDrvTransferContext
  1294. //
  1295. memset(&mdtc,0,sizeof(MINIDRV_TRANSFER_CONTEXT));
  1296. //
  1297. // read format GUID
  1298. //
  1299. hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormatID, NULL, TRUE);
  1300. if (FAILED(hr)) {
  1301. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, ReadPropLong WIA_IPA_FORMAT error"));
  1302. return hr;
  1303. }
  1304. //
  1305. // read TYMED
  1306. //
  1307. hr = wiasReadPropLong(pWiasContext,WIA_IPA_TYMED, (LONG*)&mdtc.tymed, NULL, TRUE);
  1308. if (FAILED(hr)) {
  1309. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, ReadPropLong WIA_IPA_TYMED error"));
  1310. return hr;
  1311. }
  1312. if ((guidFormatID == WiaImgFmt_BMP)||(guidFormatID == WiaImgFmt_MEMORYBMP)) {
  1313. //
  1314. // wias works for DIB, or uncompressed standard TIFF formats
  1315. // Standard TIFFs are constructed using a DIB-like implementation.
  1316. // The data is stored as one huge strip, rather than multiple smaller
  1317. // strips.
  1318. //
  1319. hr = wiasGetImageInformation(pWiasContext, WIAS_INIT_CONTEXT, &mdtc);
  1320. if (FAILED(hr)) {
  1321. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, could not get image information"));
  1322. return hr;
  1323. }
  1324. } else {
  1325. //
  1326. // manually set the data transfer context members
  1327. //
  1328. mdtc.lImageSize = 0;
  1329. mdtc.lHeaderSize = 0;
  1330. mdtc.lItemSize = 0;
  1331. mdtc.cbWidthInBytes = 0;
  1332. }
  1333. //
  1334. // Set the MinBufferSize property. MinBufferSize is the minimum buffer
  1335. // that a client can request for a data transfer.
  1336. //
  1337. switch (mdtc.tymed) {
  1338. case TYMED_CALLBACK:
  1339. //
  1340. // callback uses driver's minimum buffer size.
  1341. // This is could be taken from the micro driver at
  1342. // initialization time.
  1343. //
  1344. lMinBufSize = m_MinBufferSize;
  1345. break;
  1346. case TYMED_FILE:
  1347. //
  1348. // file transfers, require that the minimum buffer size be the
  1349. // entire length of the file.
  1350. //
  1351. lMinBufSize = mdtc.lImageSize + mdtc.lHeaderSize;
  1352. break;
  1353. default:
  1354. //
  1355. // unknown TYMED
  1356. //
  1357. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, unknown tymed: 0x%08X", mdtc.tymed));
  1358. return E_INVALIDARG;
  1359. }
  1360. //
  1361. // Initialize propvar's. Then write the values. Don't need to call
  1362. // PropVariantClear when done, since there are only LONG values.
  1363. //
  1364. for (int i = 0; i < lNumProperties; i++) {
  1365. PropVariantInit(&pv[i]);
  1366. pv[i].vt = VT_I4;
  1367. }
  1368. pv[0].lVal = mdtc.lItemSize;
  1369. pv[1].lVal = mdtc.cbWidthInBytes;
  1370. pv[2].lVal = lMinBufSize;
  1371. //
  1372. // Write WIA_IPA_ITEM_SIZE, WIA_IPA_BYTES_PER_LINE, and WIA_IPA_MIN_BUFFER_SIZE
  1373. // property values
  1374. //
  1375. hr = wiasWriteMultiple(pWiasContext, lNumProperties, ps, pv);
  1376. if (SUCCEEDED(hr)) {
  1377. //
  1378. // Now update the MINIDRIVER TRANSFER CONTEXT with new values
  1379. //
  1380. //
  1381. // Get a pointer to the associated driver item.
  1382. //
  1383. IWiaDrvItem* pDrvItem = NULL;
  1384. hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
  1385. if (FAILED(hr)) {
  1386. return hr;
  1387. }
  1388. //
  1389. // Get driver item's context
  1390. //
  1391. PMINIDRIVERITEMCONTEXT pItemContext = NULL;
  1392. hr = pDrvItem->GetDeviceSpecContext((BYTE**)&pItemContext);
  1393. if (SUCCEEDED(hr)) {
  1394. if ((guidFormatID == WiaImgFmt_BMP)||(guidFormatID == WiaImgFmt_MEMORYBMP)) {
  1395. //
  1396. // Calculate how many scan lines will fit in the buffer.
  1397. //
  1398. pItemContext->lBytesPerScanLineRaw = ((mdtc.lWidthInPixels * mdtc.lDepth) + 7) / 8;
  1399. pItemContext->lBytesPerScanLine = (((mdtc.lWidthInPixels * mdtc.lDepth) + 31) / 8) & 0xfffffffc;
  1400. pItemContext->lTotalRequested = pItemContext->lBytesPerScanLineRaw * mdtc.lLines;
  1401. } else {
  1402. pItemContext->lBytesPerScanLineRaw = 0;
  1403. pItemContext->lBytesPerScanLine = 0;
  1404. pItemContext->lTotalRequested = 0;
  1405. }
  1406. } else {
  1407. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvWriteItemProperties, NULL item context"));
  1408. }
  1409. } else {
  1410. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, WriteMultiple failed"));
  1411. }
  1412. return hr;
  1413. }
  1414. /**************************************************************************\
  1415. * CWIAScannerDevice::drvInitItemProperties
  1416. *
  1417. * Initialize the device item properties. Called during item
  1418. * initialization. This is called by the WIA Class driver
  1419. * after the item tree has been built. It is called once for every
  1420. * item in the tree.
  1421. *
  1422. * Arguments:
  1423. *
  1424. * pWiasContext - Pointer to WIA context (item information).
  1425. * lFlags - Operation flags, unused.
  1426. * plDevErrVal - Pointer to the device error value.
  1427. *
  1428. *
  1429. * Return Value:
  1430. *
  1431. * Status
  1432. *
  1433. * History:
  1434. *
  1435. * 7/18/2000 Original Version
  1436. *
  1437. \**************************************************************************/
  1438. HRESULT _stdcall CWIAScannerDevice::drvInitItemProperties(
  1439. BYTE *pWiasContext,
  1440. LONG lFlags,
  1441. LONG *plDevErrVal)
  1442. {
  1443. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1444. WIALOG_NO_RESOURCE_ID,
  1445. WIALOG_LEVEL1,
  1446. "CWIAScannerDevice::drvInitItemProperties");
  1447. HRESULT hr = S_OK;
  1448. //
  1449. // This device doesn't touch hardware to initialize the device item
  1450. // properties, so set plDevErrVal to 0.
  1451. //
  1452. if (plDevErrVal) {
  1453. *plDevErrVal = 0;
  1454. }
  1455. //
  1456. // Get a pointer to the associated driver item.
  1457. //
  1458. IWiaDrvItem* pDrvItem;
  1459. hr = wiasGetDrvItem(pWiasContext, &pDrvItem);
  1460. if (FAILED(hr)) {
  1461. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasGetDrvItem failed"));
  1462. WIAS_LHRESULT(m_pIWiaLog, hr);
  1463. return hr;
  1464. }
  1465. //
  1466. // Set initial item properties.
  1467. //
  1468. LONG lItemType = 0;
  1469. pDrvItem->GetItemFlags(&lItemType);
  1470. if (lItemType & WiaItemTypeRoot) {
  1471. //
  1472. // This is for the root item.
  1473. //
  1474. //
  1475. // Build Root Item Properties, initializing global
  1476. // structures with their default and valid values
  1477. //
  1478. hr = BuildRootItemProperties();
  1479. if(FAILED(hr)) {
  1480. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, BuildRootItemProperties failed"));
  1481. WIAS_LHRESULT(m_pIWiaLog, hr);
  1482. DeleteRootItemProperties();
  1483. return hr;
  1484. }
  1485. //
  1486. // Add the device specific root item property names,
  1487. // using WIA service.
  1488. //
  1489. hr = wiasSetItemPropNames(pWiasContext,
  1490. m_NumRootItemProperties,
  1491. m_piRootItemDefaults,
  1492. m_pszRootItemDefaults);
  1493. if (FAILED(hr)) {
  1494. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasSetItemPropNames failed"));
  1495. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_NumRootItemPropeties = %d",m_NumRootItemProperties));
  1496. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_piRootItemDefaults = %x",m_piRootItemDefaults));
  1497. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_pszRootItemDefaults = %x",m_pszRootItemDefaults));
  1498. WIAS_LHRESULT(m_pIWiaLog, hr);
  1499. DeleteRootItemProperties();
  1500. return hr;
  1501. }
  1502. //
  1503. // Set the device specific root item properties to
  1504. // their default values using WIA service.
  1505. //
  1506. hr = wiasWriteMultiple(pWiasContext,
  1507. m_NumRootItemProperties,
  1508. m_psRootItemDefaults,
  1509. m_pvRootItemDefaults);
  1510. //
  1511. // Free PROPVARIANT array, This frees any memory that was allocated for a prop variant value.
  1512. //
  1513. // FreePropVariantArray(m_NumRootItemProperties,m_pvRootItemDefaults);
  1514. if (FAILED(hr)) {
  1515. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasWriteMultiple failed"));
  1516. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_NumRootItemPropeties = %d",m_NumRootItemProperties));
  1517. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_pszRootItemDefaults = %x",m_pszRootItemDefaults));
  1518. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_pvRootItemDefaults = %x",m_pvRootItemDefaults));
  1519. WIAS_LHRESULT(m_pIWiaLog, hr);
  1520. DeleteRootItemProperties();
  1521. return hr;
  1522. }
  1523. //
  1524. // Use WIA services to set the property access and
  1525. // valid value information from m_wpiItemDefaults.
  1526. //
  1527. hr = wiasSetItemPropAttribs(pWiasContext,
  1528. m_NumRootItemProperties,
  1529. m_psRootItemDefaults,
  1530. m_wpiRootItemDefaults);
  1531. if(FAILED(hr)){
  1532. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasSetItemPropAttribs failed"));
  1533. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_NumRootItemPropeties = %d",m_NumRootItemProperties));
  1534. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_psRootItemDefaults = %x",m_psRootItemDefaults));
  1535. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_wpiRootItemDefaults = %x",m_wpiRootItemDefaults));
  1536. WIAS_LHRESULT(m_pIWiaLog, hr);
  1537. }
  1538. //
  1539. // free allocated property arrays, for more memory
  1540. //
  1541. DeleteRootItemProperties();
  1542. } else {
  1543. //
  1544. // This is for the child item.(Top)
  1545. //
  1546. //
  1547. // Build Top Item Properties, initializing global
  1548. // structures with their default and valid values
  1549. //
  1550. hr = BuildTopItemProperties();
  1551. if(FAILED(hr)) {
  1552. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, BuildTopItemProperties failed"));
  1553. WIAS_LHRESULT(m_pIWiaLog, hr);
  1554. DeleteTopItemProperties();
  1555. return hr;
  1556. }
  1557. //
  1558. // Use the WIA service to set the item property names.
  1559. //
  1560. hr = wiasSetItemPropNames(pWiasContext,
  1561. m_NumItemProperties,
  1562. m_piItemDefaults,
  1563. m_pszItemDefaults);
  1564. if (FAILED(hr)) {
  1565. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasSetItemPropNames failed"));
  1566. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_NumItemPropeties = %d",m_NumItemProperties));
  1567. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_piItemDefaults = %x",m_piItemDefaults));
  1568. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_pszItemDefaults = %x",m_pszItemDefaults));
  1569. WIAS_LHRESULT(m_pIWiaLog, hr);
  1570. DeleteTopItemProperties();
  1571. return hr;
  1572. }
  1573. //
  1574. // Use WIA services to set the item properties to their default
  1575. // values.
  1576. //
  1577. hr = wiasWriteMultiple(pWiasContext,
  1578. m_NumItemProperties,
  1579. m_psItemDefaults,
  1580. (PROPVARIANT*)m_pvItemDefaults);
  1581. if (FAILED(hr)) {
  1582. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasWriteMultiple failed"));
  1583. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_NumItemPropeties = %d",m_NumItemProperties));
  1584. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_pszItemDefaults = %x",m_pszItemDefaults));
  1585. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_pvItemDefaults = %x",m_pvItemDefaults));
  1586. WIAS_LHRESULT(m_pIWiaLog, hr);
  1587. DeleteTopItemProperties();
  1588. return hr;
  1589. }
  1590. //
  1591. // Use WIA services to set the property access and
  1592. // valid value information from m_wpiItemDefaults.
  1593. //
  1594. hr = wiasSetItemPropAttribs(pWiasContext,
  1595. m_NumItemProperties,
  1596. m_psItemDefaults,
  1597. m_wpiItemDefaults);
  1598. if (FAILED(hr)) {
  1599. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasSetItemPropAttribs failed"));
  1600. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_NumItemPropeties = %d",m_NumItemProperties));
  1601. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_psItemDefaults = %x",m_psItemDefaults));
  1602. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitItemProperties, m_wpiItemDefaults = %x",m_wpiItemDefaults));
  1603. WIAS_LHRESULT(m_pIWiaLog, hr);
  1604. DeleteTopItemProperties();
  1605. return hr;
  1606. }
  1607. //
  1608. // Set item size properties.
  1609. //
  1610. hr = SetItemSize(pWiasContext);
  1611. if(FAILED(hr)){
  1612. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, SetItemSize failed"));
  1613. WIAS_LHRESULT(m_pIWiaLog, hr);
  1614. }
  1615. //
  1616. // free allocated property arrays, for more memory
  1617. //
  1618. DeleteTopItemProperties();
  1619. }
  1620. return hr;
  1621. }
  1622. /**************************************************************************\
  1623. * CWIAScannerDevice::drvValidateItemProperties
  1624. *
  1625. * Validate the device item properties. It is called when changes are made
  1626. * to an item's properties. Driver should not only check that the values
  1627. * are valid, but must update any valid values that may change as a result.
  1628. * If an a property is not being written by the application, and it's value
  1629. * is invalid, then "fold" it to a new value, else fail validation (because
  1630. * the application is setting the property to an invalid value).
  1631. *
  1632. * Arguments:
  1633. *
  1634. * pWiasContext - Pointer to the WIA item, unused.
  1635. * lFlags - Operation flags, unused.
  1636. * nPropSpec - The number of properties that are being written
  1637. * pPropSpec - An array of PropSpecs identifying the properties that
  1638. * are being written.
  1639. * plDevErrVal - Pointer to the device error value.
  1640. *
  1641. * Return Value:
  1642. *
  1643. * Status
  1644. *
  1645. * History:
  1646. *
  1647. * 7/18/2000 Original Version
  1648. ***************************************************************************/
  1649. HRESULT _stdcall CWIAScannerDevice::drvValidateItemProperties(
  1650. BYTE *pWiasContext,
  1651. LONG lFlags,
  1652. ULONG nPropSpec,
  1653. const PROPSPEC *pPropSpec,
  1654. LONG *plDevErrVal)
  1655. {
  1656. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1657. WIALOG_NO_RESOURCE_ID,
  1658. WIALOG_LEVEL1,
  1659. "CWIAScannerDevice::drvValidateItemProperties");
  1660. HRESULT hr = S_OK;
  1661. LONG lItemType = 0;
  1662. WIA_PROPERTY_CONTEXT Context;
  1663. if (plDevErrVal) {
  1664. *plDevErrVal = 0;
  1665. }
  1666. hr = wiasGetItemType(pWiasContext, &lItemType);
  1667. if (SUCCEEDED(hr)) {
  1668. if (lItemType & WiaItemTypeRoot) {
  1669. //
  1670. // Validate root item
  1671. //
  1672. hr = wiasCreatePropContext(nPropSpec,
  1673. (PROPSPEC*)pPropSpec,
  1674. 0,
  1675. NULL,
  1676. &Context);
  1677. if (SUCCEEDED(hr)) {
  1678. //
  1679. // Check ADF to see if the status settings need to be updated
  1680. // Also switch between FEEDER/FLATBED modes
  1681. //
  1682. hr = CheckADFStatus(pWiasContext, &Context);
  1683. if(FAILED(hr)) {
  1684. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, CheckADFStatus failed"));
  1685. WIAS_LHRESULT(m_pIWiaLog, hr);
  1686. }
  1687. //
  1688. // check Preview Property only if validation is successful so far....
  1689. //
  1690. if (SUCCEEDED(hr)) {
  1691. //
  1692. // Check Preview property to see if the settings are valid
  1693. //
  1694. hr = CheckPreview(pWiasContext, &Context);
  1695. if (FAILED(hr)) {
  1696. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, CheckPreview failed"));
  1697. WIAS_LHRESULT(m_pIWiaLog, hr);
  1698. }
  1699. }
  1700. } else {
  1701. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasCreatePropContext failed (Root Item)"));
  1702. WIAS_LHRESULT(m_pIWiaLog, hr);
  1703. }
  1704. //
  1705. // call WIA service helper to validate other properties
  1706. //
  1707. if (SUCCEEDED(hr)) {
  1708. hr = wiasValidateItemProperties(pWiasContext, nPropSpec, pPropSpec);
  1709. if (FAILED(hr)) {
  1710. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasValidateItemProperties failed."));
  1711. WIAS_LHRESULT(m_pIWiaLog, hr);
  1712. return hr;
  1713. }
  1714. }
  1715. } else {
  1716. //
  1717. // validate item properties here
  1718. //
  1719. //
  1720. // Create a property context needed by some WIA Service
  1721. // functions used below.
  1722. //
  1723. hr = wiasCreatePropContext(nPropSpec,
  1724. (PROPSPEC*)pPropSpec,
  1725. 0,
  1726. NULL,
  1727. &Context);
  1728. if (SUCCEEDED(hr)) {
  1729. //
  1730. // Check Current Intent first
  1731. //
  1732. hr = CheckIntent(pWiasContext, &Context);
  1733. if (SUCCEEDED(hr)) {
  1734. //
  1735. // Check if DataType is being written
  1736. //
  1737. hr = CheckDataType(pWiasContext, &Context);
  1738. if (SUCCEEDED(hr)) {
  1739. #ifdef _SERVICE_EXTENT_VALIDATION
  1740. //
  1741. // Use the WIA service to update the scan rect
  1742. // properties and valid values.
  1743. //
  1744. LONG lBedWidth = 0;
  1745. LONG lBedHeight = 0;
  1746. hr = m_pScanAPI->GetBedWidthAndHeight(&lBedWidth,&lBedHeight);
  1747. if(FAILED(hr)){
  1748. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, m_pScanAPI->GetBedWidthAndHeight failed"));
  1749. WIAS_LHRESULT(m_pIWiaLog, hr);
  1750. return hr;
  1751. }
  1752. hr = wiasUpdateScanRect(pWiasContext,
  1753. &Context,
  1754. lBedWidth,
  1755. lBedHeight);
  1756. #endif
  1757. if (SUCCEEDED(hr)) {
  1758. //
  1759. // Use the WIA Service to update the valid values
  1760. // for Format. These are based on the value of
  1761. // WIA_IPA_TYMED, so validation is also performed
  1762. // on the tymed property by the service.
  1763. //
  1764. hr = wiasUpdateValidFormat(pWiasContext,
  1765. &Context,
  1766. (IWiaMiniDrv*) this);
  1767. if (SUCCEEDED(hr)) {
  1768. //
  1769. // Check Preferred format
  1770. //
  1771. hr = CheckPreferredFormat(pWiasContext, &Context);
  1772. if(FAILED(hr)){
  1773. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, CheckPreferredFormat failed"));
  1774. WIAS_LHRESULT(m_pIWiaLog, hr);
  1775. }
  1776. } else {
  1777. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasUpdateValidFormat failed"));
  1778. WIAS_LHRESULT(m_pIWiaLog, hr);
  1779. }
  1780. } else {
  1781. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasUpdateScanRect failed"));
  1782. WIAS_LHRESULT(m_pIWiaLog, hr);
  1783. }
  1784. } else {
  1785. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, CheckDataType failed"));
  1786. WIAS_LHRESULT(m_pIWiaLog, hr);
  1787. }
  1788. } else {
  1789. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, CheckIntent failed"));
  1790. WIAS_LHRESULT(m_pIWiaLog, hr);
  1791. }
  1792. wiasFreePropContext(&Context);
  1793. } else {
  1794. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasCreatePropContext failed (Child Item)"));
  1795. WIAS_LHRESULT(m_pIWiaLog, hr);
  1796. }
  1797. //
  1798. // Update the item size
  1799. //
  1800. if (SUCCEEDED(hr)) {
  1801. hr = SetItemSize(pWiasContext);
  1802. if(FAILED(hr)){
  1803. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, SetItemSize failed"));
  1804. WIAS_LHRESULT(m_pIWiaLog, hr);
  1805. }
  1806. //
  1807. // call WIA service helper to validate other properties
  1808. //
  1809. if (SUCCEEDED(hr)) {
  1810. hr = wiasValidateItemProperties(pWiasContext, nPropSpec, pPropSpec);
  1811. if (FAILED(hr)) {
  1812. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasValidateItemProperties failed."));
  1813. WIAS_LHRESULT(m_pIWiaLog, hr);
  1814. return hr;
  1815. }
  1816. }
  1817. }
  1818. }
  1819. } else {
  1820. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasGetItemType failed"));
  1821. WIAS_LHRESULT(m_pIWiaLog, hr);
  1822. }
  1823. //
  1824. // log HRESULT sent back to caller
  1825. //
  1826. if(FAILED(hr)){
  1827. WIAS_LHRESULT(m_pIWiaLog, hr);
  1828. }
  1829. return hr;
  1830. }
  1831. /**************************************************************************\
  1832. * CWIAScannerDevice::drvWriteItemProperties
  1833. *
  1834. * Write the device item properties to the hardware. This is called by the
  1835. * WIA Class driver prior to drvAcquireItemData when the client requests
  1836. * a data transfer.
  1837. *
  1838. * Arguments:
  1839. *
  1840. * pWiasContext - Pointer to WIA item.
  1841. * lFlags - Operation flags, unused.
  1842. * pmdtc - Pointer to mini driver context. On entry, only the
  1843. * portion of the mini driver context which is derived
  1844. * from the item properties is filled in.
  1845. * plDevErrVal - Pointer to the device error value.
  1846. *
  1847. * Return Value:
  1848. *
  1849. * Status
  1850. *
  1851. * History:
  1852. *
  1853. * 7/18/2000 Original Version
  1854. *
  1855. \**************************************************************************/
  1856. HRESULT _stdcall CWIAScannerDevice::drvWriteItemProperties(
  1857. BYTE *pWiasContext,
  1858. LONG lFlags,
  1859. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  1860. LONG *plDevErrVal)
  1861. {
  1862. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1863. WIALOG_NO_RESOURCE_ID,
  1864. WIALOG_LEVEL1,
  1865. "CWIAScannerDevice::drvWriteItemProperties");
  1866. HRESULT hr = S_OK;
  1867. if (plDevErrVal) {
  1868. *plDevErrVal = 0;
  1869. }
  1870. LONG lNumProperties = 10;
  1871. PROPVARIANT pv[10];
  1872. //
  1873. // The order of these should not change. They are referenced below
  1874. // by index.
  1875. //
  1876. PROPSPEC ps[10] = {
  1877. {PRSPEC_PROPID, WIA_IPS_XRES},
  1878. {PRSPEC_PROPID, WIA_IPS_YRES},
  1879. {PRSPEC_PROPID, WIA_IPS_XPOS},
  1880. {PRSPEC_PROPID, WIA_IPS_YPOS},
  1881. {PRSPEC_PROPID, WIA_IPS_XEXTENT},
  1882. {PRSPEC_PROPID, WIA_IPS_YEXTENT},
  1883. {PRSPEC_PROPID, WIA_IPA_DATATYPE},
  1884. {PRSPEC_PROPID, WIA_IPS_BRIGHTNESS},
  1885. {PRSPEC_PROPID, WIA_IPS_CONTRAST},
  1886. {PRSPEC_PROPID, WIA_IPA_FORMAT}
  1887. };
  1888. //
  1889. // initialize propvariant structures
  1890. //
  1891. for (int i = 0; i< lNumProperties;i++) {
  1892. pv[i].vt = VT_I4;
  1893. }
  1894. //
  1895. // read child item properties
  1896. //
  1897. hr = wiasReadMultiple(pWiasContext, lNumProperties, ps, pv, NULL);
  1898. if (hr == S_OK) {
  1899. hr = m_pScanAPI->SetXYResolution(pv[0].lVal,pv[1].lVal);
  1900. if (FAILED(hr)) {
  1901. WIAS_LERROR(m_pIWiaLog,
  1902. WIALOG_NO_RESOURCE_ID,
  1903. ("drvWriteItemProperties, Setting x any y resolutions failed"));
  1904. WIAS_LHRESULT(m_pIWiaLog, hr);
  1905. return hr;
  1906. }
  1907. hr = m_pScanAPI->SetDataType(pv[6].lVal);
  1908. if (FAILED(hr)) {
  1909. WIAS_LERROR(m_pIWiaLog,
  1910. WIALOG_NO_RESOURCE_ID,
  1911. ("drvWriteItemProperties, Setting data type failed"));
  1912. WIAS_LHRESULT(m_pIWiaLog, hr);
  1913. return hr;
  1914. }
  1915. hr = m_pScanAPI->SetIntensity(pv[7].lVal);
  1916. if (FAILED(hr)) {
  1917. WIAS_LERROR(m_pIWiaLog,
  1918. WIALOG_NO_RESOURCE_ID,
  1919. ("drvWriteItemProperties, Setting intensity failed"));
  1920. WIAS_LHRESULT(m_pIWiaLog, hr);
  1921. return hr;
  1922. }
  1923. hr = m_pScanAPI->SetContrast(pv[8].lVal);
  1924. if (FAILED(hr)) {
  1925. WIAS_LERROR(m_pIWiaLog,
  1926. WIALOG_NO_RESOURCE_ID,
  1927. ("drvWriteItemProperties, Setting contrast failed"));
  1928. WIAS_LHRESULT(m_pIWiaLog, hr);
  1929. return hr;
  1930. }
  1931. hr = m_pScanAPI->SetSelectionArea(pv[2].lVal, pv[3].lVal, pv[4].lVal, pv[5].lVal);
  1932. if (FAILED(hr)) {
  1933. WIAS_LERROR(m_pIWiaLog,
  1934. WIALOG_NO_RESOURCE_ID,
  1935. ("drvWriteItemProperties, Setting selection area (extents) failed"));
  1936. WIAS_LHRESULT(m_pIWiaLog, hr);
  1937. return hr;
  1938. }
  1939. hr = m_pScanAPI->SetFormat((GUID*)pv[9].puuid);
  1940. if (FAILED(hr)) {
  1941. WIAS_LERROR(m_pIWiaLog,
  1942. WIALOG_NO_RESOURCE_ID,
  1943. ("drvWriteItemProperties, Setting current format failed"));
  1944. WIAS_LHRESULT(m_pIWiaLog, hr);
  1945. PropVariantClear(&pv[9]);
  1946. return hr;
  1947. }
  1948. PropVariantClear(&pv[9]);
  1949. }
  1950. return hr;
  1951. }
  1952. /**************************************************************************\
  1953. * CWIAScannerDevice::drvReadItemProperties
  1954. *
  1955. * Read the device item properties. When a client application tries to
  1956. * read a WIA Item's properties, the WIA Class driver will first notify
  1957. * the driver by calling this method.
  1958. *
  1959. * Arguments:
  1960. *
  1961. * pWiasContext - wia item
  1962. * lFlags - Operation flags, unused.
  1963. * nPropSpec - Number of elements in pPropSpec.
  1964. * pPropSpec - Pointer to property specification, showing which properties
  1965. * the application wants to read.
  1966. * plDevErrVal - Pointer to the device error value.
  1967. *
  1968. * Return Value:
  1969. *
  1970. * Status
  1971. *
  1972. * History:
  1973. *
  1974. * 7/18/2000 Original Version
  1975. *
  1976. \**************************************************************************/
  1977. HRESULT _stdcall CWIAScannerDevice::drvReadItemProperties(
  1978. BYTE *pWiasContext,
  1979. LONG lFlags,
  1980. ULONG nPropSpec,
  1981. const PROPSPEC *pPropSpec,
  1982. LONG *plDevErrVal)
  1983. {
  1984. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1985. WIALOG_NO_RESOURCE_ID,
  1986. WIALOG_LEVEL1,
  1987. "CWIAScannerDevice::drvReadItemProperties");
  1988. if (plDevErrVal) {
  1989. *plDevErrVal = 0;
  1990. }
  1991. return S_OK;
  1992. }
  1993. /**************************************************************************\
  1994. * CWIAScannerDevice::drvLockWiaDevice
  1995. *
  1996. * Lock access to the device.
  1997. *
  1998. * Arguments:
  1999. *
  2000. * pWiasContext - unused, can be NULL
  2001. * lFlags - Operation flags, unused.
  2002. * plDevErrVal - Pointer to the device error value.
  2003. *
  2004. *
  2005. * Return Value:
  2006. *
  2007. * Status
  2008. *
  2009. * History:
  2010. *
  2011. * 7/18/2000 Original Version
  2012. *
  2013. \**************************************************************************/
  2014. HRESULT _stdcall CWIAScannerDevice::drvLockWiaDevice(
  2015. BYTE *pWiasContext,
  2016. LONG lFlags,
  2017. LONG *plDevErrVal)
  2018. {
  2019. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2020. WIALOG_NO_RESOURCE_ID,
  2021. WIALOG_LEVEL1,
  2022. "CWIAScannerDevice::drvLockWiaDevice");
  2023. if (plDevErrVal) {
  2024. *plDevErrVal = 0;
  2025. }
  2026. return m_pStiDevice->LockDevice(m_dwLockTimeout);
  2027. }
  2028. /**************************************************************************\
  2029. * CWIAScannerDevice::drvUnLockWiaDevice
  2030. *
  2031. * Unlock access to the device.
  2032. *
  2033. * Arguments:
  2034. *
  2035. * pWiasContext - Pointer to the WIA item, unused.
  2036. * lFlags - Operation flags, unused.
  2037. * plDevErrVal - Pointer to the device error value.
  2038. *
  2039. * Return Value:
  2040. *
  2041. * Status
  2042. *
  2043. * History:
  2044. *
  2045. * 7/18/2000 Original Version
  2046. *
  2047. \**************************************************************************/
  2048. HRESULT _stdcall CWIAScannerDevice::drvUnLockWiaDevice(
  2049. BYTE *pWiasContext,
  2050. LONG lFlags,
  2051. LONG *plDevErrVal)
  2052. {
  2053. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2054. WIALOG_NO_RESOURCE_ID,
  2055. WIALOG_LEVEL1,
  2056. "CWIAScannerDevice::drvUnLockWiaDevice");
  2057. if (plDevErrVal) {
  2058. *plDevErrVal = 0;
  2059. }
  2060. return m_pStiDevice->UnLockDevice();
  2061. }
  2062. /**************************************************************************\
  2063. * CWIAScannerDevice::drvAnalyzeItem
  2064. *
  2065. * This device does not support image analysis, so return E_NOTIMPL.
  2066. *
  2067. * Arguments:
  2068. *
  2069. * pWiasContext - Pointer to the device item to be analyzed.
  2070. * lFlags - Operation flags.
  2071. * plDevErrVal - Pointer to the device error value.
  2072. *
  2073. * Return Value:
  2074. *
  2075. * Status
  2076. *
  2077. * History:
  2078. *
  2079. * 7/18/2000 Original Version
  2080. *
  2081. \**************************************************************************/
  2082. HRESULT _stdcall CWIAScannerDevice::drvAnalyzeItem(
  2083. BYTE *pWiasContext,
  2084. LONG lFlags,
  2085. LONG *plDevErrVal)
  2086. {
  2087. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2088. WIALOG_NO_RESOURCE_ID,
  2089. WIALOG_LEVEL1,
  2090. "CWIAScannerDevice::drvAnalyzeItem");
  2091. if (plDevErrVal) {
  2092. *plDevErrVal = 0;
  2093. }
  2094. return E_NOTIMPL;
  2095. }
  2096. /**************************************************************************\
  2097. * CWIAScannerDevice::drvFreeDrvItemContext
  2098. *
  2099. * Free any device specific context.
  2100. *
  2101. * Arguments:
  2102. *
  2103. * lFlags - Operation flags, unused.
  2104. * pDevSpecContext - Pointer to device specific context.
  2105. * plDevErrVal - Pointer to the device error value.
  2106. *
  2107. * Return Value:
  2108. *
  2109. * Status
  2110. *
  2111. * History:
  2112. *
  2113. * 7/18/2000 Original Version
  2114. *
  2115. \**************************************************************************/
  2116. HRESULT _stdcall CWIAScannerDevice::drvFreeDrvItemContext(
  2117. LONG lFlags,
  2118. BYTE *pSpecContext,
  2119. LONG *plDevErrVal)
  2120. {
  2121. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2122. WIALOG_NO_RESOURCE_ID,
  2123. WIALOG_LEVEL1,
  2124. "CWIAScannerDevice::drvFreeDrvItemContext");
  2125. if (plDevErrVal) {
  2126. *plDevErrVal = 0;
  2127. }
  2128. PMINIDRIVERITEMCONTEXT pContext = NULL;
  2129. pContext = (PMINIDRIVERITEMCONTEXT) pSpecContext;
  2130. if (pContext){
  2131. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvFreeDrvItemContext, Freeing my allocated context members"));
  2132. }
  2133. return S_OK;
  2134. }
  2135. /**************************************************************************\
  2136. * CWIAScannerDevice::drvInitializeWia
  2137. *
  2138. * Initialize the WIA mini driver. This will build up the driver item tree
  2139. * and perform any other initialization code that's needed for WIA.
  2140. *
  2141. * Arguments:
  2142. *
  2143. * pWiasContext - Pointer to the WIA item, unused.
  2144. * lFlags - Operation flags, unused.
  2145. * bstrDeviceID - Device ID.
  2146. * bstrRootFullItemName - Full item name.
  2147. * pIPropStg - Device info. properties.
  2148. * pStiDevice - STI device interface.
  2149. * pIUnknownOuter - Outer unknown interface.
  2150. * ppIDrvItemRoot - Pointer to returned root item.
  2151. * ppIUnknownInner - Pointer to returned inner unknown.
  2152. * plDevErrVal - Pointer to the device error value.
  2153. *
  2154. * Return Value:
  2155. *
  2156. * Status
  2157. *
  2158. * History:
  2159. *
  2160. * 7/18/2000 Original Version
  2161. *
  2162. \**************************************************************************/
  2163. HRESULT _stdcall CWIAScannerDevice::drvInitializeWia(
  2164. BYTE *pWiasContext,
  2165. LONG lFlags,
  2166. BSTR bstrDeviceID,
  2167. BSTR bstrRootFullItemName,
  2168. IUnknown *pStiDevice,
  2169. IUnknown *pIUnknownOuter,
  2170. IWiaDrvItem **ppIDrvItemRoot,
  2171. IUnknown **ppIUnknownInner,
  2172. LONG *plDevErrVal)
  2173. {
  2174. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2175. WIALOG_NO_RESOURCE_ID,
  2176. WIALOG_LEVEL1,
  2177. "CWIAScannerDevice::drvInitializeWia");
  2178. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitializeWia, bstrDeviceID = %ws", bstrDeviceID));
  2179. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitializeWia, bstrRootFullItemName = %ws",bstrRootFullItemName));
  2180. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitializeWia, lFlags = %d",lFlags));
  2181. HRESULT hr = S_OK;
  2182. if (plDevErrVal) {
  2183. *plDevErrVal = 0;
  2184. }
  2185. *ppIDrvItemRoot = NULL;
  2186. *ppIUnknownInner = NULL;
  2187. //
  2188. // Need to init names and STI pointer?
  2189. //
  2190. if (m_pStiDevice == NULL) {
  2191. //
  2192. // save STI device interface for locking
  2193. //
  2194. m_pStiDevice = (IStiDevice *)pStiDevice;
  2195. //
  2196. // Cache the device ID.
  2197. //
  2198. m_bstrDeviceID = SysAllocString(bstrDeviceID);
  2199. if (!m_bstrDeviceID) {
  2200. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, unable to allocate device ID string"));
  2201. return E_OUTOFMEMORY;
  2202. }
  2203. //
  2204. // Cache the root property stream name.
  2205. //
  2206. m_bstrRootFullItemName = SysAllocString(bstrRootFullItemName);
  2207. if (!m_bstrRootFullItemName) {
  2208. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, unable to allocate prop stream name"));
  2209. return E_OUTOFMEMORY;
  2210. }
  2211. }
  2212. //
  2213. // Initialize Capabilities array
  2214. //
  2215. hr = BuildCapabilities();
  2216. if(FAILED(hr)) {
  2217. DeleteCapabilitiesArrayContents();
  2218. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildCapabilities failed"));
  2219. WIAS_LHRESULT(m_pIWiaLog, hr);
  2220. return hr;
  2221. }
  2222. //
  2223. // Initialize SupportedFormats array
  2224. //
  2225. hr = BuildSupportedFormats();
  2226. if(FAILED(hr)) {
  2227. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildSupportedFormats failed"));
  2228. WIAS_LHRESULT(m_pIWiaLog, hr);
  2229. return hr;
  2230. }
  2231. //
  2232. // Initialize Supported Data Type array
  2233. //
  2234. hr = BuildSupportedDataTypes();
  2235. if(FAILED(hr)) {
  2236. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildSupportedDataTypes failed"));
  2237. WIAS_LHRESULT(m_pIWiaLog, hr);
  2238. return hr;
  2239. }
  2240. //
  2241. // Initialize Supported Intents array
  2242. //
  2243. hr = BuildSupportedIntents();
  2244. if(FAILED(hr)) {
  2245. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildSupportedIntents failed"));
  2246. WIAS_LHRESULT(m_pIWiaLog, hr);
  2247. return hr;
  2248. }
  2249. //
  2250. // Initialize Supported TYMED array
  2251. //
  2252. hr = BuildSupportedTYMED();
  2253. if(FAILED(hr)) {
  2254. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildSuportedTYMED failed"));
  2255. WIAS_LHRESULT(m_pIWiaLog, hr);
  2256. return hr;
  2257. }
  2258. //
  2259. // Initialize Supported compression types array
  2260. //
  2261. hr = BuildSupportedCompressions();
  2262. if(FAILED(hr)) {
  2263. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildSupportedCompressions"));
  2264. WIAS_LHRESULT(m_pIWiaLog, hr);
  2265. return hr;
  2266. }
  2267. //
  2268. // Initialize Supported Preview modes array
  2269. //
  2270. hr = BuildSupportedPreviewModes();
  2271. if(FAILED(hr)) {
  2272. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildSupportedPreviewModes"));
  2273. WIAS_LHRESULT(m_pIWiaLog, hr);
  2274. return hr;
  2275. }
  2276. //
  2277. // Initialize initial formats array
  2278. //
  2279. hr = BuildInitialFormats();
  2280. if(FAILED(hr)) {
  2281. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildInitialFormats failed"));
  2282. WIAS_LHRESULT(m_pIWiaLog, hr);
  2283. return hr;
  2284. }
  2285. //
  2286. // Initialize supported resolutions array
  2287. //
  2288. hr = BuildSupportedResolutions();
  2289. if(FAILED(hr)) {
  2290. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildSupportedResolutions failed"));
  2291. WIAS_LHRESULT(m_pIWiaLog, hr);
  2292. return hr;
  2293. }
  2294. //
  2295. // Build the device item tree, if it hasn't been built yet.
  2296. //
  2297. // Send a Device Command to yourself, or Call BuildItemTree manually
  2298. //
  2299. if (!m_pIDrvItemRoot) {
  2300. LONG lDevErrVal = 0;
  2301. hr = drvDeviceCommand(NULL, 0, &WIA_CMD_SYNCHRONIZE, NULL, &lDevErrVal);
  2302. if(FAILED(hr)){
  2303. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, drvDeviceCommand(WIA_CMD_SYNCHRONIZE) failed"));
  2304. WIAS_LHRESULT(m_pIWiaLog, hr);
  2305. }
  2306. }
  2307. //
  2308. // save root item pointer. (REMEMBER TO RELEASE THIS INTERFACE)
  2309. //
  2310. *ppIDrvItemRoot = m_pIDrvItemRoot;
  2311. return hr;
  2312. }
  2313. /**************************************************************************\
  2314. * CWIAScannerDevice::drvUnInitializeWia
  2315. *
  2316. * Gets called when a client connection is going away.
  2317. *
  2318. * Arguments:
  2319. *
  2320. * pWiasContext - Pointer to the WIA Root item context of the client's
  2321. * item tree.
  2322. *
  2323. * Return Value:
  2324. * Status
  2325. *
  2326. * History:
  2327. *
  2328. * 7/18/2000 Original Version
  2329. *
  2330. \**************************************************************************/
  2331. HRESULT _stdcall CWIAScannerDevice::drvUnInitializeWia(
  2332. BYTE *pWiasContext)
  2333. {
  2334. return S_OK;
  2335. }
  2336. /**************************************************************************\
  2337. * drvGetDeviceErrorStr
  2338. *
  2339. * Map a device error value to a string.
  2340. *
  2341. * Arguments:
  2342. *
  2343. * lFlags - Operation flags, unused.
  2344. * lDevErrVal - Device error value.
  2345. * ppszDevErrStr - Pointer to returned error string.
  2346. * plDevErrVal - Pointer to the device error value.
  2347. *
  2348. *
  2349. * Return Value:
  2350. *
  2351. * Status
  2352. *
  2353. * History:
  2354. *
  2355. * 7/18/2000 Original Version
  2356. *
  2357. \**************************************************************************/
  2358. HRESULT _stdcall CWIAScannerDevice::drvGetDeviceErrorStr(
  2359. LONG lFlags,
  2360. LONG lDevErrVal,
  2361. LPOLESTR *ppszDevErrStr,
  2362. LONG *plDevErr)
  2363. {
  2364. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2365. WIALOG_NO_RESOURCE_ID,
  2366. WIALOG_LEVEL1,
  2367. "CWIAScannerDevice::drvGetDeviceErrorStr");
  2368. HRESULT hr = S_OK;
  2369. //
  2370. // Map device errors to a string to be placed in the event log.
  2371. //
  2372. if (plDevErr) {
  2373. if (*ppszDevErrStr) {
  2374. //
  2375. // look up error strings in resource file.
  2376. //
  2377. switch (lDevErrVal) {
  2378. case 0:
  2379. *ppszDevErrStr = L"No Error"; // hard coded for now
  2380. *plDevErr = 0;
  2381. hr = S_OK;
  2382. break;
  2383. default:
  2384. *ppszDevErrStr = L"Device Error, Unknown Error";// hard coded for now
  2385. *plDevErr = 0;
  2386. hr = E_FAIL;
  2387. break;
  2388. }
  2389. }
  2390. }
  2391. return hr;
  2392. }
  2393. /**************************************************************************\
  2394. * drvDeviceCommand
  2395. *
  2396. * Issue a command to the device.
  2397. *
  2398. * Arguments:
  2399. *
  2400. * pWiasContext - Pointer to the WIA item.
  2401. * lFlags - Operation flags, unused.
  2402. * plCommand - Pointer to command GUID.
  2403. * ppWiaDrvItem - Optional pointer to returned item, unused.
  2404. * plDevErrVal - Pointer to the device error value.
  2405. *
  2406. * Return Value:
  2407. *
  2408. * Status
  2409. *
  2410. * History:
  2411. *
  2412. * 7/18/2000 Original Version
  2413. *
  2414. \**************************************************************************/
  2415. HRESULT _stdcall CWIAScannerDevice::drvDeviceCommand(
  2416. BYTE *pWiasContext,
  2417. LONG lFlags,
  2418. const GUID *plCommand,
  2419. IWiaDrvItem **ppWiaDrvItem,
  2420. LONG *plDevErrVal)
  2421. {
  2422. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2423. WIALOG_NO_RESOURCE_ID,
  2424. WIALOG_LEVEL1,
  2425. "CWIAScannerDevice::drvDeviceCommand");
  2426. if(plDevErrVal){
  2427. *plDevErrVal = 0;
  2428. }
  2429. HRESULT hr = S_OK;
  2430. //
  2431. // Check which command was issued
  2432. //
  2433. if (*plCommand == WIA_CMD_SYNCHRONIZE) {
  2434. //
  2435. // SYNCHRONIZE - Build the minidriver representation of
  2436. // the current item list, if it doesn't exist.
  2437. //
  2438. if (!m_pIDrvItemRoot) {
  2439. hr = BuildItemTree();
  2440. } else {
  2441. hr = S_OK;
  2442. }
  2443. } else {
  2444. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, unknown command sent to this device"));
  2445. hr = E_NOTIMPL;
  2446. }
  2447. return hr;
  2448. }
  2449. /**************************************************************************\
  2450. * CWIAScannerDevice::drvGetCapabilities
  2451. *
  2452. * Get supported device commands and events as an array of WIA_DEV_CAPS.
  2453. *
  2454. * Arguments:
  2455. *
  2456. * pWiasContext - Pointer to the WIA item, unused.
  2457. * lFlags - Operation flags.
  2458. * pcelt - Pointer to returned number of elements in
  2459. * returned GUID array.
  2460. * ppCapabilities - Pointer to returned GUID array.
  2461. * plDevErrVal - Pointer to the device error value.
  2462. *
  2463. * Return Value:
  2464. *
  2465. * Status
  2466. *
  2467. * History:
  2468. *
  2469. * 7/18/2000 Original Version
  2470. *
  2471. \**************************************************************************/
  2472. HRESULT _stdcall CWIAScannerDevice::drvGetCapabilities(
  2473. BYTE *pWiasContext,
  2474. LONG ulFlags,
  2475. LONG *pcelt,
  2476. WIA_DEV_CAP_DRV **ppCapabilities,
  2477. LONG *plDevErrVal)
  2478. {
  2479. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2480. WIALOG_NO_RESOURCE_ID,
  2481. WIALOG_LEVEL1,
  2482. "CWIAScannerDevice::drvGetCapabilites");
  2483. if(plDevErrVal){
  2484. *plDevErrVal = 0;
  2485. }
  2486. HRESULT hr = S_OK;
  2487. //
  2488. // Initialize Capabilities array
  2489. //
  2490. hr = BuildCapabilities();
  2491. if(FAILED(hr)) {
  2492. DeleteCapabilitiesArrayContents();
  2493. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetCapabilities, BuildCapabilities failed"));
  2494. WIAS_LHRESULT(m_pIWiaLog, hr);
  2495. return hr;
  2496. }
  2497. //
  2498. // Return depends on flags. Flags specify whether we should return
  2499. // commands, events, or both.
  2500. //
  2501. //
  2502. switch (ulFlags) {
  2503. case WIA_DEVICE_COMMANDS:
  2504. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvGetCapabilities, (WIA_DEVICE_COMMANDS)"));
  2505. //
  2506. // report commands only
  2507. //
  2508. *pcelt = m_NumSupportedCommands;
  2509. *ppCapabilities = &m_pCapabilities[m_NumSupportedEvents];
  2510. break;
  2511. case WIA_DEVICE_EVENTS:
  2512. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvGetCapabilities, (WIA_DEVICE_EVENTS)"));
  2513. //
  2514. // report events only
  2515. //
  2516. *pcelt = m_NumSupportedEvents;
  2517. *ppCapabilities = m_pCapabilities;
  2518. break;
  2519. case (WIA_DEVICE_COMMANDS | WIA_DEVICE_EVENTS):
  2520. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvGetCapabilities, (WIA_DEVICE_COMMANDS|WIA_DEVICE_EVENTS)"));
  2521. //
  2522. // report both events and commands
  2523. //
  2524. *pcelt = m_NumCapabilities;
  2525. *ppCapabilities = m_pCapabilities;
  2526. break;
  2527. default:
  2528. //
  2529. // invalid request
  2530. //
  2531. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetCapabilities, invalid flags"));
  2532. return E_INVALIDARG;
  2533. }
  2534. return hr;
  2535. }
  2536. /**************************************************************************\
  2537. * drvGetWiaFormatInfo
  2538. *
  2539. * Returns an array of WIA_FORMAT_INFO structs, which specify the format
  2540. * and media type pairs that are supported.
  2541. *
  2542. * Arguments:
  2543. *
  2544. * pWiasContext - Pointer to the WIA item context, unused.
  2545. * lFlags - Operation flags, unused.
  2546. * pcelt - Pointer to returned number of elements in
  2547. * returned WIA_FORMAT_INFO array.
  2548. * ppwfi - Pointer to returned WIA_FORMAT_INFO array.
  2549. * plDevErrVal - Pointer to the device error value.
  2550. *
  2551. * Return Value:
  2552. *
  2553. * Status
  2554. *
  2555. * History:
  2556. *
  2557. * 7/18/2000 Original Version
  2558. *
  2559. \**************************************************************************/
  2560. HRESULT _stdcall CWIAScannerDevice::drvGetWiaFormatInfo(
  2561. BYTE *pWiasContext,
  2562. LONG lFlags,
  2563. LONG *pcelt,
  2564. WIA_FORMAT_INFO **ppwfi,
  2565. LONG *plDevErrVal)
  2566. {
  2567. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2568. WIALOG_NO_RESOURCE_ID,
  2569. WIALOG_LEVEL1,
  2570. "CWIAScannerDevice::drvGetWiaFormatInfo");
  2571. HRESULT hr = S_OK;
  2572. if(NULL == m_pSupportedFormats){
  2573. hr = BuildSupportedFormats();
  2574. }
  2575. if(plDevErrVal){
  2576. *plDevErrVal = 0;
  2577. }
  2578. *pcelt = m_NumSupportedFormats;
  2579. *ppwfi = m_pSupportedFormats;
  2580. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvGetWiaFormatInfo, m_NumSupportedFormats = %d",m_NumSupportedFormats));
  2581. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvGetWiaFormatInfo, m_pSupportedFormats = %x",m_pSupportedFormats));
  2582. return hr;
  2583. }
  2584. /**************************************************************************\
  2585. * drvNotifyPnpEvent
  2586. *
  2587. * Pnp Event received by device manager. This is called when a Pnp event
  2588. * is received for this device.
  2589. *
  2590. * Arguments:
  2591. *
  2592. *
  2593. *
  2594. * Return Value:
  2595. *
  2596. * Status
  2597. *
  2598. * History:
  2599. *
  2600. * 7/18/2000 Original Version
  2601. *
  2602. \**************************************************************************/
  2603. HRESULT _stdcall CWIAScannerDevice::drvNotifyPnpEvent(
  2604. const GUID *pEventGUID,
  2605. BSTR bstrDeviceID,
  2606. ULONG ulReserved)
  2607. {
  2608. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2609. WIALOG_NO_RESOURCE_ID,
  2610. WIALOG_LEVEL1,
  2611. "CWIAScannerDevice::drvNotifyPnpEvent");
  2612. HRESULT hr = S_OK;
  2613. if (*pEventGUID == WIA_EVENT_DEVICE_DISCONNECTED) {
  2614. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvNotifyPnpEvent, (WIA_EVENT_DEVICE_DISCONNECTED)"));
  2615. hr = m_pScanAPI->DisableDevice();
  2616. if (FAILED(hr)) {
  2617. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvNotifyPnpEvent, disable failed"));
  2618. }
  2619. }
  2620. if (*pEventGUID == WIA_EVENT_POWER_SUSPEND){
  2621. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvNotifyPnpEvent, (WIA_EVENT_POWER_SUSPEND)"));
  2622. hr = m_pScanAPI->DisableDevice();
  2623. if (FAILED(hr)) {
  2624. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvNotifyPnpEvent, disable failed"));
  2625. }
  2626. }
  2627. if (*pEventGUID == WIA_EVENT_POWER_RESUME){
  2628. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvNotifyPnpEvent, (WIA_EVENT_POWER_RESUME)"));
  2629. hr = m_pScanAPI->EnableDevice();
  2630. if (FAILED(hr)) {
  2631. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvNotifyPnpEvent, enable failed"));
  2632. }
  2633. if (NULL != m_hSignalEvent) {
  2634. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvNotifyPnpEvent, (restarting interrrupt event system)"));
  2635. hr = SetNotificationHandle(m_hSignalEvent);
  2636. if (FAILED(hr)) {
  2637. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvNotifyPnpEvent, SetNotificationHandle failed"));
  2638. }
  2639. } else {
  2640. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvNotifyPnpEvent, (not restarting interrrupt event system), device may not need it."));
  2641. }
  2642. }
  2643. return hr;
  2644. }
  2645. /*******************************************************************************
  2646. *
  2647. * P R I V A T E M E T H O D S
  2648. *
  2649. *******************************************************************************/
  2650. /**************************************************************************\
  2651. * AlignInPlace
  2652. *
  2653. * DWORD align a data buffer in place.
  2654. *
  2655. * Arguments:
  2656. *
  2657. * pBuffer - Pointer to the data buffer.
  2658. * cbWritten - Size of the data in bytes.
  2659. * lBytesPerScanLine - Number of bytes per scan line in the output data.
  2660. * lBytesPerScanLineRaw - Number of bytes per scan line in the input data.
  2661. *
  2662. * Return Value:
  2663. *
  2664. * Status
  2665. *
  2666. * History:
  2667. *
  2668. * 7/18/2000 Original Version
  2669. *
  2670. \**************************************************************************/
  2671. UINT CWIAScannerDevice::AlignInPlace(
  2672. PBYTE pBuffer,
  2673. LONG cbWritten,
  2674. LONG lBytesPerScanLine,
  2675. LONG lBytesPerScanLineRaw)
  2676. {
  2677. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2678. WIALOG_NO_RESOURCE_ID,
  2679. WIALOG_LEVEL3,
  2680. "::AlignInPlace");
  2681. if (lBytesPerScanLineRaw % 4) {
  2682. UINT uiPadBytes = lBytesPerScanLine - lBytesPerScanLineRaw;
  2683. UINT uiDevLinesWritten = cbWritten / lBytesPerScanLineRaw;
  2684. PBYTE pSrc = pBuffer + cbWritten - 1;
  2685. PBYTE pDst = pBuffer + (uiDevLinesWritten * lBytesPerScanLine) - 1;
  2686. while (pSrc >= pBuffer) {
  2687. pDst -= uiPadBytes;
  2688. for (LONG i = 0; i < lBytesPerScanLineRaw; i++) {
  2689. *pDst-- = *pSrc--;
  2690. }
  2691. }
  2692. return uiDevLinesWritten * lBytesPerScanLine;
  2693. }
  2694. return cbWritten;
  2695. }
  2696. /**************************************************************************\
  2697. * UnlinkItemTree
  2698. *
  2699. * Call device manager to unlink and release our reference to
  2700. * all items in the driver item tree.
  2701. *
  2702. * Arguments:
  2703. *
  2704. *
  2705. *
  2706. * Return Value:
  2707. *
  2708. * Status
  2709. *
  2710. * History:
  2711. *
  2712. * 7/18/2000 Original Version
  2713. *
  2714. \**************************************************************************/
  2715. HRESULT _stdcall CWIAScannerDevice::DeleteItemTree(void)
  2716. {
  2717. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2718. WIALOG_NO_RESOURCE_ID,
  2719. WIALOG_LEVEL3,
  2720. "CWIAScannerDevice::DeleteItemTree");
  2721. HRESULT hr = S_OK;
  2722. //
  2723. // If no tree, return.
  2724. //
  2725. if (!m_pIDrvItemRoot) {
  2726. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("DeleteItemTree, no tree to delete..."));
  2727. return S_OK;
  2728. }
  2729. //
  2730. // Call device manager to unlink the driver item tree.
  2731. //
  2732. hr = m_pIDrvItemRoot->UnlinkItemTree(WiaItemTypeDisconnected);
  2733. if (SUCCEEDED(hr)) {
  2734. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("DeleteItemTree, m_pIDrvItemRoot is being released!!"));
  2735. m_pIDrvItemRoot->Release();
  2736. m_pIDrvItemRoot = NULL;
  2737. }
  2738. return hr;
  2739. }
  2740. /**************************************************************************\
  2741. * BuildItemTree
  2742. *
  2743. * The device uses the WIA Service functions to build up a tree of
  2744. * device items. This device supports only a single data acquisition item so
  2745. * build a device item tree with only one child off the root.
  2746. *
  2747. * Arguments:
  2748. *
  2749. *
  2750. *
  2751. * Return Value:
  2752. *
  2753. * Status
  2754. *
  2755. * History:
  2756. *
  2757. * 7/18/2000 Original Version
  2758. *
  2759. \**************************************************************************/
  2760. HRESULT _stdcall CWIAScannerDevice::BuildItemTree(void)
  2761. {
  2762. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2763. WIALOG_NO_RESOURCE_ID,
  2764. WIALOG_LEVEL3,
  2765. "CWIAScannerDevice::BuildItemTree");
  2766. //
  2767. // The device item tree must not exist.
  2768. //
  2769. WIAS_ASSERT( (g_hInst), (m_pIDrvItemRoot == NULL));
  2770. //
  2771. // Call the class driver to create the root item.
  2772. //
  2773. HRESULT hr = E_FAIL;
  2774. //
  2775. // Name the root.
  2776. //
  2777. BSTR bstrRootItemName = NULL;
  2778. hr = GetBSTRResourceString(IDS_ROOTITEM_NAME,&bstrRootItemName,TRUE);
  2779. if (SUCCEEDED(hr)) {
  2780. hr = wiasCreateDrvItem(WiaItemTypeFolder |
  2781. WiaItemTypeDevice |
  2782. WiaItemTypeRoot,
  2783. bstrRootItemName,
  2784. m_bstrRootFullItemName,
  2785. (IWiaMiniDrv *)this,
  2786. sizeof(MINIDRIVERITEMCONTEXT),
  2787. NULL,
  2788. &m_pIDrvItemRoot);
  2789. SysFreeString(bstrRootItemName);
  2790. }
  2791. if (FAILED(hr)) {
  2792. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, wiasCreateDrvItem failed"));
  2793. WIAS_LHRESULT(m_pIWiaLog, hr);
  2794. return hr;
  2795. }
  2796. //
  2797. // Create and add the Top/Front and Bottom/Back device items.
  2798. //
  2799. for (INT i = 0; i < NUM_DEVICE_ITEM; i++) {
  2800. //
  2801. // Build the item names.
  2802. //
  2803. BSTR bstrItemName = NULL;
  2804. hr = GetBSTRResourceString(IDS_TOPITEM_NAME,&bstrItemName,TRUE);
  2805. if (SUCCEEDED(hr)) {
  2806. // SBB - RAID 370299 - orenr - 2001/04/18 - Security fix -
  2807. // potential buffer overrun. Changed wcscpy and wcscat
  2808. // to use _snwprintf instead
  2809. WCHAR szFullItemName[MAX_PATH + 1] = {0};
  2810. _snwprintf(szFullItemName,
  2811. (sizeof(szFullItemName) / sizeof(WCHAR)) - 1,
  2812. L"%ls\\%ls",
  2813. m_bstrRootFullItemName,
  2814. bstrItemName);
  2815. //
  2816. // Call the class driver to create another driver item.
  2817. // This will be inserted as the child item.
  2818. //
  2819. PMINIDRIVERITEMCONTEXT pItemContext;
  2820. IWiaDrvItem *pItem = NULL;
  2821. hr = wiasCreateDrvItem(WiaItemTypeFile |
  2822. WiaItemTypeImage |
  2823. WiaItemTypeDevice,
  2824. bstrItemName,
  2825. szFullItemName,
  2826. (IWiaMiniDrv *)this,
  2827. sizeof(MINIDRIVERITEMCONTEXT),
  2828. (PBYTE*) &pItemContext,
  2829. &pItem);
  2830. if (SUCCEEDED(hr)) {
  2831. //
  2832. // Initialize device specific context.
  2833. //
  2834. memset(pItemContext, 0, sizeof(MINIDRIVERITEMCONTEXT));
  2835. pItemContext->lSize = sizeof(MINIDRIVERITEMCONTEXT);
  2836. //
  2837. // Call the class driver to add pItem to the folder
  2838. // m_pIDrvItemRoot (i.e. make pItem a child of
  2839. // m_pIDrvItemRoot).
  2840. //
  2841. hr = pItem->AddItemToFolder(m_pIDrvItemRoot);
  2842. if (FAILED(hr)) {
  2843. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, AddItemToFolder failed"));
  2844. WIAS_LHRESULT(m_pIWiaLog, hr);
  2845. }
  2846. //
  2847. // release and created items
  2848. //
  2849. pItem->Release();
  2850. } else {
  2851. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, wiasCreateDrvItem failed"));
  2852. WIAS_LHRESULT(m_pIWiaLog, hr);
  2853. }
  2854. //
  2855. // free the BSTR allocated by the BSTRResourceString helper
  2856. //
  2857. SysFreeString(bstrItemName);
  2858. } else {
  2859. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, unable to allocate item name"));
  2860. hr = E_OUTOFMEMORY;
  2861. }
  2862. break; // Error if here, quit iterating.
  2863. }
  2864. if (FAILED(hr)) {
  2865. DeleteItemTree();
  2866. }
  2867. return hr;
  2868. }
  2869. /**************************************************************************\
  2870. * DeleteRootItemProperties
  2871. *
  2872. * This helper deletes the arrays used for Property intialization.
  2873. *
  2874. * [Array Name] [Description] [Array Type]
  2875. *
  2876. * m_pszRootItemDefaults - Property name array (LPOLESTR)
  2877. * m_piRootItemDefaults - Property ID array (PROPID)
  2878. * m_pvRootItemDefaults - Property Variant array (PROPVARIANT)
  2879. * m_psRootItemDefaults - Property Spec array (PROPSPEC)
  2880. * m_wpiRootItemDefaults - WIA Property Info array (WIA_PROPERTY_INFO)
  2881. *
  2882. *
  2883. * Arguments:
  2884. *
  2885. * none
  2886. *
  2887. * Return Value:
  2888. *
  2889. * Status
  2890. *
  2891. * History:
  2892. *
  2893. * 7/18/2000 Original Version
  2894. *
  2895. \**************************************************************************/
  2896. HRESULT CWIAScannerDevice::DeleteRootItemProperties()
  2897. {
  2898. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2899. WIALOG_NO_RESOURCE_ID,
  2900. WIALOG_LEVEL1,
  2901. "CWIAScannerDevice::DeleteRootItemProperties");
  2902. HRESULT hr = S_OK;
  2903. //
  2904. // delete any allocated arrays
  2905. //
  2906. DeleteSupportedPreviewModesArrayContents();
  2907. if(NULL != m_pszRootItemDefaults){
  2908. delete [] m_pszRootItemDefaults;
  2909. m_pszRootItemDefaults = NULL;
  2910. }
  2911. if(NULL != m_piRootItemDefaults){
  2912. delete [] m_piRootItemDefaults;
  2913. m_piRootItemDefaults = NULL;
  2914. }
  2915. if(NULL != m_pvRootItemDefaults){
  2916. FreePropVariantArray(m_NumRootItemProperties,m_pvRootItemDefaults);
  2917. delete [] m_pvRootItemDefaults;
  2918. m_pvRootItemDefaults = NULL;
  2919. }
  2920. if(NULL != m_psRootItemDefaults){
  2921. delete [] m_psRootItemDefaults;
  2922. m_psRootItemDefaults = NULL;
  2923. }
  2924. if(NULL != m_wpiRootItemDefaults){
  2925. delete [] m_wpiRootItemDefaults;
  2926. m_wpiRootItemDefaults = NULL;
  2927. }
  2928. return hr;
  2929. }
  2930. /**************************************************************************\
  2931. * BuildRootItemProperties
  2932. *
  2933. * This helper creates/initializes the arrays used for Property intialization.
  2934. *
  2935. * [Array Name] [Description] [Array Type]
  2936. *
  2937. * m_pszRootItemDefaults - Property name array (LPOLESTR)
  2938. * m_piRootItemDefaults - Property ID array (PROPID)
  2939. * m_pvRootItemDefaults - Property Variant array (PROPVARIANT)
  2940. * m_psRootItemDefaults - Property Spec array (PROPSPEC)
  2941. * m_wpiRootItemDefaults - WIA Property Info array (WIA_PROPERTY_INFO)
  2942. *
  2943. *
  2944. * Arguments:
  2945. *
  2946. * none
  2947. *
  2948. * Return Value:
  2949. *
  2950. * Status
  2951. *
  2952. * History:
  2953. *
  2954. * 7/18/2000 Original Version
  2955. *
  2956. \**************************************************************************/
  2957. HRESULT CWIAScannerDevice::BuildRootItemProperties()
  2958. {
  2959. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2960. WIALOG_NO_RESOURCE_ID,
  2961. WIALOG_LEVEL1,
  2962. "CWIAScannerDevice::BuildRootItemProperties");
  2963. HRESULT hr = S_OK;
  2964. if(m_pScanAPI->ADFAttached() == S_OK){
  2965. m_bADFAttached = TRUE;
  2966. }
  2967. WIAPROPERTIES RootItemProperties;
  2968. memset(&RootItemProperties,0,sizeof(RootItemProperties));
  2969. // set host driver numeric values
  2970. RootItemProperties.NumSupportedPreviewModes = m_NumSupportedPreviewModes;
  2971. // set host driver allocated pointers
  2972. RootItemProperties.pSupportedPreviewModes = m_pSupportedPreviewModes;
  2973. hr = m_pScanAPI->BuildRootItemProperties(&RootItemProperties);
  2974. if(FAILED(hr)){
  2975. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildRootItemProperties, m_pScanAPI->BuildRootItemProperties failed"));
  2976. WIAS_LHRESULT(m_pIWiaLog, hr);
  2977. DeleteRootItemProperties();
  2978. return hr;
  2979. }
  2980. //
  2981. // assign pointers to members
  2982. //
  2983. m_NumRootItemProperties = RootItemProperties.NumItemProperties;
  2984. m_piRootItemDefaults = RootItemProperties.piItemDefaults;
  2985. m_psRootItemDefaults = RootItemProperties.psItemDefaults;
  2986. m_pszRootItemDefaults = RootItemProperties.pszItemDefaults;
  2987. m_pvRootItemDefaults = RootItemProperties.pvItemDefaults;
  2988. m_wpiRootItemDefaults = RootItemProperties.wpiItemDefaults;
  2989. return hr;
  2990. }
  2991. /**************************************************************************\
  2992. * DeleteTopItemProperties
  2993. *
  2994. * This helper deletes the arrays used for Property intialization.
  2995. *
  2996. * [Array Name] [Description] [Array Type]
  2997. *
  2998. * m_pszItemDefaults - Property name array (LPOLESTR)
  2999. * m_piItemDefaults - Property ID array (PROPID)
  3000. * m_pvItemDefaults - Property Variant array (PROPVARIANT)
  3001. * m_psItemDefaults - Property Spec array (PROPSPEC)
  3002. * m_wpiItemDefaults - WIA Property Info array (WIA_PROPERTY_INFO)
  3003. *
  3004. *
  3005. * Arguments:
  3006. *
  3007. * none
  3008. *
  3009. * Return Value:
  3010. *
  3011. * Status
  3012. *
  3013. * History:
  3014. *
  3015. * 7/18/2000 Original Version
  3016. *
  3017. \**************************************************************************/
  3018. HRESULT CWIAScannerDevice::DeleteTopItemProperties()
  3019. {
  3020. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3021. WIALOG_NO_RESOURCE_ID,
  3022. WIALOG_LEVEL1,
  3023. "CWIAScannerDevice::DeleteTopItemProperties");
  3024. HRESULT hr = S_OK;
  3025. //
  3026. // delete any allocated arrays
  3027. //
  3028. DeleteSupportedFormatsArrayContents();
  3029. DeleteSupportedDataTypesArrayContents();
  3030. DeleteSupportedCompressionsArrayContents();
  3031. DeleteSupportedTYMEDArrayContents();
  3032. DeleteInitialFormatsArrayContents();
  3033. DeleteSupportedResolutionsArrayContents();
  3034. if(NULL != m_pszItemDefaults){
  3035. delete [] m_pszItemDefaults;
  3036. m_pszItemDefaults = NULL;
  3037. }
  3038. if(NULL != m_piItemDefaults){
  3039. delete [] m_piItemDefaults;
  3040. m_piItemDefaults = NULL;
  3041. }
  3042. if(NULL != m_pvItemDefaults){
  3043. for(LONG lPropIndex = 0; lPropIndex < m_NumItemProperties; lPropIndex++){
  3044. //
  3045. // set CLSID pointers to NULL, because we freed the memory above.
  3046. // If this pointer is not NULL FreePropVariantArray would
  3047. // try to free it again.
  3048. //
  3049. if(m_pvItemDefaults[lPropIndex].vt == VT_CLSID){
  3050. m_pvItemDefaults[lPropIndex].puuid = NULL;
  3051. }
  3052. }
  3053. FreePropVariantArray(m_NumItemProperties,m_pvItemDefaults);
  3054. delete [] m_pvItemDefaults;
  3055. m_pvItemDefaults = NULL;
  3056. }
  3057. if(NULL != m_psItemDefaults){
  3058. delete [] m_psItemDefaults;
  3059. m_psItemDefaults = NULL;
  3060. }
  3061. if(NULL != m_wpiItemDefaults){
  3062. delete [] m_wpiItemDefaults;
  3063. m_wpiItemDefaults = NULL;
  3064. }
  3065. return hr;
  3066. }
  3067. /**************************************************************************\
  3068. * BuildTopItemProperties
  3069. *
  3070. * This helper creates/initializes the arrays used for Property intialization.
  3071. *
  3072. * [Array Name] [Description] [Array Type]
  3073. *
  3074. * m_pszItemDefaults - Property name array (LPOLESTR)
  3075. * m_piItemDefaults - Property ID array (PROPID)
  3076. * m_pvItemDefaults - Property Variant array (PROPVARIANT)
  3077. * m_psItemDefaults - Property Spec array (PROPSPEC)
  3078. * m_wpiItemDefaults - WIA Property Info array (WIA_PROPERTY_INFO)
  3079. *
  3080. * Arguments:
  3081. *
  3082. * none
  3083. *
  3084. * Return Value:
  3085. *
  3086. * Status
  3087. *
  3088. * History:
  3089. *
  3090. * 7/18/2000 Original Version
  3091. *
  3092. \**************************************************************************/
  3093. HRESULT CWIAScannerDevice::BuildTopItemProperties()
  3094. {
  3095. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3096. WIALOG_NO_RESOURCE_ID,
  3097. WIALOG_LEVEL1,
  3098. "CWIAScannerDevice::BuildTopItemProperties");
  3099. HRESULT hr = S_OK;
  3100. WIAPROPERTIES TopItemProperties;
  3101. memset(&TopItemProperties,0,sizeof(TopItemProperties));
  3102. // set host driver numeric values
  3103. TopItemProperties.NumInitialFormats = m_NumInitialFormats;
  3104. TopItemProperties.NumSupportedCompressionTypes = m_NumSupportedCompressionTypes;
  3105. TopItemProperties.NumSupportedDataTypes = m_NumSupportedDataTypes;
  3106. TopItemProperties.NumSupportedFormats = m_NumSupportedFormats;
  3107. TopItemProperties.NumSupportedIntents = m_NumSupportedIntents;
  3108. TopItemProperties.NumSupportedTYMED = m_NumSupportedTYMED;
  3109. TopItemProperties.NumSupportedResolutions = m_NumSupportedResolutions;
  3110. // set host driver allocated pointers
  3111. TopItemProperties.pInitialFormats = m_pInitialFormats;
  3112. TopItemProperties.pSupportedCompressionTypes = m_pSupportedCompressionTypes;
  3113. TopItemProperties.pSupportedDataTypes = m_pSupportedDataTypes;
  3114. TopItemProperties.pSupportedFormats = m_pSupportedFormats;
  3115. TopItemProperties.pSupportedIntents = m_pSupportedIntents;
  3116. TopItemProperties.pSupportedTYMED = m_pSupportedTYMED;
  3117. TopItemProperties.pSupportedResolutions = m_pSupportedResolutions;
  3118. TopItemProperties.bLegacyBWRestrictions = m_bLegacyBWRestriction;
  3119. hr = m_pScanAPI->BuildTopItemProperties(&TopItemProperties);
  3120. if(FAILED(hr)){
  3121. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildTopItemProperties, m_pScanAPI->BuildTopItemProperties failed"));
  3122. WIAS_LHRESULT(m_pIWiaLog, hr);
  3123. DeleteTopItemProperties();
  3124. return hr;
  3125. }
  3126. //
  3127. // assign pointers to members
  3128. //
  3129. m_NumItemProperties = TopItemProperties.NumItemProperties;
  3130. m_pszItemDefaults = TopItemProperties.pszItemDefaults;
  3131. m_piItemDefaults = TopItemProperties.piItemDefaults;
  3132. m_pvItemDefaults = TopItemProperties.pvItemDefaults;
  3133. m_psItemDefaults = TopItemProperties.psItemDefaults;
  3134. m_wpiItemDefaults = TopItemProperties.wpiItemDefaults;
  3135. return hr;
  3136. }
  3137. /**************************************************************************\
  3138. * BuildSupportedResolutions
  3139. *
  3140. * This helper initializes the supported resolution array
  3141. *
  3142. * Arguments:
  3143. *
  3144. * none
  3145. *
  3146. * Return Value:
  3147. *
  3148. * Status
  3149. *
  3150. * History:
  3151. *
  3152. * 7/18/2000 Original Version
  3153. *
  3154. \**************************************************************************/
  3155. HRESULT CWIAScannerDevice::BuildSupportedResolutions()
  3156. {
  3157. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3158. WIALOG_NO_RESOURCE_ID,
  3159. WIALOG_LEVEL1,
  3160. "CWIAScannerDevice::BuildSupportedResolutions");
  3161. HRESULT hr = S_OK;
  3162. if(NULL != m_pSupportedResolutions) {
  3163. //
  3164. // Supported intents have already been initialized,
  3165. // so return S_OK.
  3166. //
  3167. return hr;
  3168. }
  3169. m_NumSupportedResolutions = 6;
  3170. m_pSupportedResolutions = new LONG[m_NumSupportedResolutions];
  3171. if(m_pSupportedResolutions){
  3172. m_pSupportedResolutions[0] = 75;
  3173. m_pSupportedResolutions[1] = 100;
  3174. m_pSupportedResolutions[2] = 150;
  3175. m_pSupportedResolutions[3] = 200;
  3176. m_pSupportedResolutions[4] = 300;
  3177. m_pSupportedResolutions[5] = 600;
  3178. } else
  3179. hr = E_OUTOFMEMORY;
  3180. return hr;
  3181. }
  3182. /**************************************************************************\
  3183. * DeleteSupportedResolutionsArrayContents
  3184. *
  3185. * This helper deletes the supported resolutions array
  3186. *
  3187. * Arguments:
  3188. *
  3189. * none
  3190. *
  3191. * Return Value:
  3192. *
  3193. * Status
  3194. *
  3195. * History:
  3196. *
  3197. * 7/18/2000 Original Version
  3198. *
  3199. \**************************************************************************/
  3200. HRESULT CWIAScannerDevice::DeleteSupportedResolutionsArrayContents()
  3201. {
  3202. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3203. WIALOG_NO_RESOURCE_ID,
  3204. WIALOG_LEVEL1,
  3205. "CWIAScannerDevice::DeleteSupportedResolutionsArrayContents");
  3206. HRESULT hr = S_OK;
  3207. if(NULL != m_pSupportedResolutions)
  3208. delete [] m_pSupportedResolutions;
  3209. m_pSupportedResolutions = NULL;
  3210. m_NumSupportedResolutions = 0;
  3211. return hr;
  3212. }
  3213. /**************************************************************************\
  3214. * BuildSupportedIntents
  3215. *
  3216. * This helper initializes the supported intent array
  3217. *
  3218. * Arguments:
  3219. *
  3220. * none
  3221. *
  3222. * Return Value:
  3223. *
  3224. * Status
  3225. *
  3226. * History:
  3227. *
  3228. * 7/18/2000 Original Version
  3229. *
  3230. \**************************************************************************/
  3231. HRESULT CWIAScannerDevice::BuildSupportedIntents()
  3232. {
  3233. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3234. WIALOG_NO_RESOURCE_ID,
  3235. WIALOG_LEVEL1,
  3236. "CWIAScannerDevice::BuildSupportedIntents");
  3237. HRESULT hr = S_OK;
  3238. if(NULL != m_pSupportedIntents) {
  3239. //
  3240. // Supported intents have already been initialized,
  3241. // so return S_OK.
  3242. //
  3243. return hr;
  3244. }
  3245. m_NumSupportedIntents = 6;
  3246. m_pSupportedIntents = new LONG[m_NumSupportedIntents];
  3247. if(m_pSupportedIntents){
  3248. m_pSupportedIntents[0] = WIA_INTENT_NONE;
  3249. m_pSupportedIntents[1] = WIA_INTENT_IMAGE_TYPE_COLOR;
  3250. m_pSupportedIntents[2] = WIA_INTENT_IMAGE_TYPE_GRAYSCALE;
  3251. m_pSupportedIntents[3] = WIA_INTENT_IMAGE_TYPE_TEXT;
  3252. m_pSupportedIntents[4] = WIA_INTENT_MINIMIZE_SIZE;
  3253. m_pSupportedIntents[5] = WIA_INTENT_MAXIMIZE_QUALITY;
  3254. } else
  3255. hr = E_OUTOFMEMORY;
  3256. return hr;
  3257. }
  3258. /**************************************************************************\
  3259. * DeleteSupportedIntentsArrayContents
  3260. *
  3261. * This helper deletes the supported intent array
  3262. *
  3263. * Arguments:
  3264. *
  3265. * none
  3266. *
  3267. * Return Value:
  3268. *
  3269. * Status
  3270. *
  3271. * History:
  3272. *
  3273. * 7/18/2000 Original Version
  3274. *
  3275. \**************************************************************************/
  3276. HRESULT CWIAScannerDevice::DeleteSupportedIntentsArrayContents()
  3277. {
  3278. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3279. WIALOG_NO_RESOURCE_ID,
  3280. WIALOG_LEVEL1,
  3281. "CWIAScannerDevice::DeleteSupportedIntentsArrayContents");
  3282. HRESULT hr = S_OK;
  3283. if(NULL != m_pSupportedIntents)
  3284. delete [] m_pSupportedIntents;
  3285. m_pSupportedIntents = NULL;
  3286. m_NumSupportedIntents = 0;
  3287. return hr;
  3288. }
  3289. /**************************************************************************\
  3290. * BuildSupportedCompressions
  3291. *
  3292. * This helper initializes the supported compression types array
  3293. *
  3294. * Arguments:
  3295. *
  3296. * none
  3297. *
  3298. * Return Value:
  3299. *
  3300. * Status
  3301. *
  3302. * History:
  3303. *
  3304. * 7/18/2000 Original Version
  3305. *
  3306. \**************************************************************************/
  3307. HRESULT CWIAScannerDevice::BuildSupportedCompressions()
  3308. {
  3309. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3310. WIALOG_NO_RESOURCE_ID,
  3311. WIALOG_LEVEL1,
  3312. "CWIAScannerDevice::BuildSupportedCompressions");
  3313. HRESULT hr = S_OK;
  3314. if(NULL != m_pSupportedCompressionTypes) {
  3315. //
  3316. // Supported compression types have already been initialized,
  3317. // so return S_OK.
  3318. //
  3319. return hr;
  3320. }
  3321. m_NumSupportedCompressionTypes = 1;
  3322. m_pSupportedCompressionTypes = new LONG[m_NumSupportedCompressionTypes];
  3323. if(m_pSupportedCompressionTypes){
  3324. m_pSupportedCompressionTypes[0] = WIA_COMPRESSION_NONE;
  3325. } else
  3326. hr = E_OUTOFMEMORY;
  3327. return hr;
  3328. }
  3329. /**************************************************************************\
  3330. * DeleteSupportedCompressionsArrayContents
  3331. *
  3332. * This helper deletes the supported compression types array
  3333. *
  3334. * Arguments:
  3335. *
  3336. * none
  3337. *
  3338. * Return Value:
  3339. *
  3340. * Status
  3341. *
  3342. * History:
  3343. *
  3344. * 7/18/2000 Original Version
  3345. *
  3346. \**************************************************************************/
  3347. HRESULT CWIAScannerDevice::DeleteSupportedCompressionsArrayContents()
  3348. {
  3349. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3350. WIALOG_NO_RESOURCE_ID,
  3351. WIALOG_LEVEL1,
  3352. "CWIAScannerDevice::DeleteSupportedCompressionsArrayContents");
  3353. HRESULT hr = S_OK;
  3354. if (NULL != m_pSupportedCompressionTypes)
  3355. delete [] m_pSupportedCompressionTypes;
  3356. m_pSupportedCompressionTypes = NULL;
  3357. m_NumSupportedCompressionTypes = 0;
  3358. return hr;
  3359. }
  3360. /**************************************************************************\
  3361. * BuildSupportedPreviewModes
  3362. *
  3363. * This helper initializes the supported preview mode array
  3364. *
  3365. * Arguments:
  3366. *
  3367. * none
  3368. *
  3369. * Return Value:
  3370. *
  3371. * Status
  3372. *
  3373. * History:
  3374. *
  3375. * 8/17/2000 Original Version
  3376. *
  3377. \**************************************************************************/
  3378. HRESULT CWIAScannerDevice::BuildSupportedPreviewModes()
  3379. {
  3380. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3381. WIALOG_NO_RESOURCE_ID,
  3382. WIALOG_LEVEL1,
  3383. "CWIAScannerDevice::BuildSupportedPreviewModes");
  3384. HRESULT hr = S_OK;
  3385. if(NULL != m_pSupportedPreviewModes) {
  3386. //
  3387. // Supported preview modes have already been initialized,
  3388. // so return S_OK.
  3389. //
  3390. return hr;
  3391. }
  3392. m_NumSupportedPreviewModes = 2;
  3393. m_pSupportedPreviewModes = new LONG[m_NumSupportedPreviewModes];
  3394. if(m_pSupportedPreviewModes){
  3395. m_pSupportedPreviewModes[0] = WIA_FINAL_SCAN;
  3396. m_pSupportedPreviewModes[1] = WIA_PREVIEW_SCAN;
  3397. } else
  3398. hr = E_OUTOFMEMORY;
  3399. return hr;
  3400. }
  3401. /**************************************************************************\
  3402. * DeleteSupportedCompressionsArrayContents
  3403. *
  3404. * This helper deletes the supported compression types array
  3405. *
  3406. * Arguments:
  3407. *
  3408. * none
  3409. *
  3410. * Return Value:
  3411. *
  3412. * Status
  3413. *
  3414. * History:
  3415. *
  3416. * 8/17/2000 Original Version
  3417. *
  3418. \**************************************************************************/
  3419. HRESULT CWIAScannerDevice::DeleteSupportedPreviewModesArrayContents()
  3420. {
  3421. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3422. WIALOG_NO_RESOURCE_ID,
  3423. WIALOG_LEVEL1,
  3424. "CWIAScannerDevice::DeleteSupportedPreviewModesArrayContents");
  3425. HRESULT hr = S_OK;
  3426. if (NULL != m_pSupportedPreviewModes)
  3427. delete [] m_pSupportedPreviewModes;
  3428. m_pSupportedPreviewModes = NULL;
  3429. m_NumSupportedPreviewModes = 0;
  3430. return hr;
  3431. }
  3432. /**************************************************************************\
  3433. * BuildSupportedDataTypes
  3434. *
  3435. * This helper initializes the supported data types array
  3436. *
  3437. * Arguments:
  3438. *
  3439. * none
  3440. *
  3441. * Return Value:
  3442. *
  3443. * Status
  3444. *
  3445. * History:
  3446. *
  3447. * 7/18/2000 Original Version
  3448. *
  3449. \**************************************************************************/
  3450. HRESULT CWIAScannerDevice::BuildSupportedDataTypes()
  3451. {
  3452. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3453. WIALOG_NO_RESOURCE_ID,
  3454. WIALOG_LEVEL1,
  3455. "CWIAScannerDevice::BuildSupportedDataTypes");
  3456. HRESULT hr = S_OK;
  3457. if(NULL != m_pSupportedDataTypes) {
  3458. //
  3459. // Supported data types have already been initialized,
  3460. // so return S_OK.
  3461. //
  3462. return hr;
  3463. }
  3464. if (m_bLegacyBWRestriction) {
  3465. m_NumSupportedDataTypes = NUM_DATA_TYPES_LEGACY;
  3466. } else {
  3467. m_NumSupportedDataTypes = NUM_DATA_TYPES_NONLEGACY;
  3468. }
  3469. m_pSupportedDataTypes = new LONG[m_NumSupportedDataTypes];
  3470. if(m_pSupportedDataTypes){
  3471. m_pSupportedDataTypes[0] = WIA_DATA_THRESHOLD;
  3472. m_pSupportedDataTypes[1] = WIA_DATA_GRAYSCALE;
  3473. //
  3474. // Add color support to non-legacy devices only
  3475. //
  3476. if (m_NumSupportedDataTypes == NUM_DATA_TYPES_NONLEGACY) {
  3477. m_pSupportedDataTypes[2] = WIA_DATA_COLOR;
  3478. }
  3479. } else
  3480. hr = E_OUTOFMEMORY;
  3481. return hr;
  3482. }
  3483. /**************************************************************************\
  3484. * DeleteSupportedDataTypesArrayContents
  3485. *
  3486. * This helper deletes the supported data types array
  3487. *
  3488. * Arguments:
  3489. *
  3490. * none
  3491. *
  3492. * Return Value:
  3493. *
  3494. * Status
  3495. *
  3496. * History:
  3497. *
  3498. * 7/18/2000 Original Version
  3499. *
  3500. \**************************************************************************/
  3501. HRESULT CWIAScannerDevice::DeleteSupportedDataTypesArrayContents()
  3502. {
  3503. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3504. WIALOG_NO_RESOURCE_ID,
  3505. WIALOG_LEVEL1,
  3506. "CWIAScannerDevice::DeleteSupportedDataTypesArrayContents");
  3507. HRESULT hr = S_OK;
  3508. if(NULL != m_pSupportedDataTypes)
  3509. delete [] m_pSupportedDataTypes;
  3510. m_pSupportedDataTypes = NULL;
  3511. m_NumSupportedDataTypes = 0;
  3512. return hr;
  3513. }
  3514. /**************************************************************************\
  3515. * BuildInitialFormats
  3516. *
  3517. * This helper initializes the initial format array
  3518. *
  3519. * Arguments:
  3520. *
  3521. * none
  3522. *
  3523. * Return Value:
  3524. *
  3525. * Status
  3526. *
  3527. * History:
  3528. *
  3529. * 7/18/2000 Original Version
  3530. *
  3531. \**************************************************************************/
  3532. HRESULT CWIAScannerDevice::BuildInitialFormats()
  3533. {
  3534. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3535. WIALOG_NO_RESOURCE_ID,
  3536. WIALOG_LEVEL1,
  3537. "CWIAScannerDevice::BuildInitialFormats");
  3538. HRESULT hr = S_OK;
  3539. if(NULL != m_pInitialFormats) {
  3540. //
  3541. // Supported data types have already been initialized,
  3542. // so return S_OK.
  3543. //
  3544. return hr;
  3545. }
  3546. m_NumInitialFormats = 1;
  3547. m_pInitialFormats = new GUID[m_NumInitialFormats];
  3548. if(m_pInitialFormats){
  3549. m_pInitialFormats[0] = WiaImgFmt_MEMORYBMP;
  3550. } else
  3551. hr = E_OUTOFMEMORY;
  3552. return hr;
  3553. }
  3554. /**************************************************************************\
  3555. * DeleteInitialFormatsArrayContents
  3556. *
  3557. * This helper deletes the initial format array
  3558. *
  3559. * Arguments:
  3560. *
  3561. * none
  3562. *
  3563. * Return Value:
  3564. *
  3565. * Status
  3566. *
  3567. * History:
  3568. *
  3569. * 7/18/2000 Original Version
  3570. *
  3571. \**************************************************************************/
  3572. HRESULT CWIAScannerDevice::DeleteInitialFormatsArrayContents()
  3573. {
  3574. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3575. WIALOG_NO_RESOURCE_ID,
  3576. WIALOG_LEVEL1,
  3577. "CWIAScannerDevice::DeleteInitialFormatsArrayContents");
  3578. HRESULT hr = S_OK;
  3579. if(NULL != m_pInitialFormats)
  3580. delete [] m_pInitialFormats;
  3581. m_pInitialFormats = NULL;
  3582. m_NumInitialFormats = 0;
  3583. return hr;
  3584. }
  3585. /**************************************************************************\
  3586. * BuildSupportedFormats
  3587. *
  3588. * This helper initializes the supported format array
  3589. *
  3590. * Arguments:
  3591. *
  3592. * none
  3593. *
  3594. * Return Value:
  3595. *
  3596. * Status
  3597. *
  3598. * History:
  3599. *
  3600. * 7/18/2000 Original Version
  3601. *
  3602. \**************************************************************************/
  3603. HRESULT CWIAScannerDevice::BuildSupportedFormats()
  3604. {
  3605. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3606. WIALOG_NO_RESOURCE_ID,
  3607. WIALOG_LEVEL1,
  3608. "CWIAScannerDevice::BuildSupportedFormats");
  3609. HRESULT hr = S_OK;
  3610. if(NULL != m_pSupportedFormats) {
  3611. //
  3612. // Supported formats have already been initialized,
  3613. // so return S_OK.
  3614. //
  3615. return hr;
  3616. }
  3617. LONG lNumFileFormats = 0;
  3618. LONG lNumMemoryFormats = 0;
  3619. GUID *pFileFormats = NULL;
  3620. GUID *pMemoryFormats = NULL;
  3621. hr = m_pScanAPI->GetSupportedFileFormats(&pFileFormats, &lNumFileFormats);
  3622. if(SUCCEEDED(hr)){
  3623. hr = m_pScanAPI->GetSupportedMemoryFormats(&pMemoryFormats, &lNumMemoryFormats);
  3624. if (SUCCEEDED(hr)) {
  3625. m_NumSupportedFormats = lNumFileFormats + lNumMemoryFormats + 2;
  3626. m_pSupportedFormats = new WIA_FORMAT_INFO[m_NumSupportedFormats];
  3627. LONG lIndex = 0;
  3628. if (m_pSupportedFormats) {
  3629. // fill out file formats
  3630. m_pSupportedFormats[lIndex].guidFormatID = WiaImgFmt_BMP;
  3631. m_pSupportedFormats[lIndex].lTymed = TYMED_FILE;
  3632. lIndex++;
  3633. for(LONG lSrcIndex = 0;lSrcIndex < lNumFileFormats; lSrcIndex++){
  3634. m_pSupportedFormats[lIndex].guidFormatID = pFileFormats[lSrcIndex];
  3635. m_pSupportedFormats[lIndex].lTymed = TYMED_FILE;
  3636. lIndex ++;
  3637. }
  3638. //fill out memory formats
  3639. m_pSupportedFormats[lIndex].guidFormatID = WiaImgFmt_MEMORYBMP;
  3640. m_pSupportedFormats[lIndex].lTymed = TYMED_CALLBACK;
  3641. lIndex++;
  3642. for(lSrcIndex = 0;lSrcIndex < lNumMemoryFormats; lSrcIndex++){
  3643. m_pSupportedFormats[lIndex].guidFormatID = pMemoryFormats[lSrcIndex];
  3644. m_pSupportedFormats[lIndex].lTymed = TYMED_CALLBACK;
  3645. lIndex++;
  3646. }
  3647. } else{
  3648. hr = E_OUTOFMEMORY;
  3649. }
  3650. }
  3651. } else if(E_NOTIMPL == hr){
  3652. // do default processing of file formats
  3653. hr = DeleteSupportedFormatsArrayContents();
  3654. if (SUCCEEDED(hr)) {
  3655. m_NumSupportedFormats = 2;
  3656. m_pSupportedFormats = new WIA_FORMAT_INFO[m_NumSupportedFormats];
  3657. if (m_pSupportedFormats) {
  3658. m_pSupportedFormats[0].guidFormatID = WiaImgFmt_MEMORYBMP;
  3659. m_pSupportedFormats[0].lTymed = TYMED_CALLBACK;
  3660. m_pSupportedFormats[1].guidFormatID = WiaImgFmt_BMP;
  3661. m_pSupportedFormats[1].lTymed = TYMED_FILE;
  3662. } else
  3663. hr = E_OUTOFMEMORY;
  3664. }
  3665. } else {
  3666. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildSupportedFormats, GetSupportedFileFormats Failed "));
  3667. WIAS_LHRESULT(m_pIWiaLog, hr);
  3668. }
  3669. return hr;
  3670. }
  3671. /**************************************************************************\
  3672. * DeleteSupportedFormatsArrayContents
  3673. *
  3674. * This helper deletes the supported formats array
  3675. *
  3676. * Arguments:
  3677. *
  3678. * none
  3679. *
  3680. * Return Value:
  3681. *
  3682. * Status
  3683. *
  3684. * History:
  3685. *
  3686. * 7/18/2000 Original Version
  3687. *
  3688. \**************************************************************************/
  3689. HRESULT CWIAScannerDevice::DeleteSupportedFormatsArrayContents()
  3690. {
  3691. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3692. WIALOG_NO_RESOURCE_ID,
  3693. WIALOG_LEVEL1,
  3694. "CWIAScannerDevice::DeleteSupportedFormatsArrayContents");
  3695. HRESULT hr = S_OK;
  3696. if(NULL != m_pSupportedFormats)
  3697. delete [] m_pSupportedFormats;
  3698. m_pSupportedFormats = NULL;
  3699. m_NumSupportedFormats = 0;
  3700. return hr;
  3701. }
  3702. /**************************************************************************\
  3703. * BuildSupportedTYMED
  3704. *
  3705. * This helper initializes the supported TYMED array
  3706. *
  3707. * Arguments:
  3708. *
  3709. * none
  3710. *
  3711. * Return Value:
  3712. *
  3713. * Status
  3714. *
  3715. * History:
  3716. *
  3717. * 7/18/2000 Original Version
  3718. *
  3719. \**************************************************************************/
  3720. HRESULT CWIAScannerDevice::BuildSupportedTYMED()
  3721. {
  3722. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3723. WIALOG_NO_RESOURCE_ID,
  3724. WIALOG_LEVEL1,
  3725. "CWIAScannerDevice::BuildSupportedTYMED");
  3726. HRESULT hr = S_OK;
  3727. if(NULL != m_pSupportedTYMED) {
  3728. //
  3729. // Supported TYMED have already been initialized,
  3730. // so return S_OK.
  3731. //
  3732. return hr;
  3733. }
  3734. hr = DeleteSupportedTYMEDArrayContents();
  3735. if (SUCCEEDED(hr)) {
  3736. m_NumSupportedTYMED = 2;
  3737. m_pSupportedTYMED = new LONG[m_NumSupportedTYMED];
  3738. if (m_pSupportedTYMED) {
  3739. m_pSupportedTYMED[0] = TYMED_FILE;
  3740. m_pSupportedTYMED[1] = TYMED_CALLBACK;
  3741. } else
  3742. hr = E_OUTOFMEMORY;
  3743. }
  3744. return hr;
  3745. }
  3746. /**************************************************************************\
  3747. * DeleteSupportedTYMEDArrayContents
  3748. *
  3749. * This helper deletes the supported TYMED array
  3750. *
  3751. * Arguments:
  3752. *
  3753. * none
  3754. *
  3755. * Return Value:
  3756. *
  3757. * Status
  3758. *
  3759. * History:
  3760. *
  3761. * 7/18/2000 Original Version
  3762. *
  3763. \**************************************************************************/
  3764. HRESULT CWIAScannerDevice::DeleteSupportedTYMEDArrayContents()
  3765. {
  3766. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3767. WIALOG_NO_RESOURCE_ID,
  3768. WIALOG_LEVEL1,
  3769. "CWIAScannerDevice::DeleteSupportedTYMEDArrayContents");
  3770. HRESULT hr = S_OK;
  3771. if(NULL != m_pSupportedTYMED)
  3772. delete [] m_pSupportedTYMED;
  3773. m_pSupportedTYMED = NULL;
  3774. m_NumSupportedTYMED = 0;
  3775. return hr;
  3776. }
  3777. /**************************************************************************\
  3778. * BuildCapabilities
  3779. *
  3780. * This helper initializes the capabilities array
  3781. *
  3782. * Arguments:
  3783. *
  3784. * none
  3785. *
  3786. * Return Value:
  3787. *
  3788. * Status
  3789. *
  3790. * History:
  3791. *
  3792. * 7/18/2000 Original Version
  3793. *
  3794. \**************************************************************************/
  3795. HRESULT CWIAScannerDevice::BuildCapabilities()
  3796. {
  3797. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3798. WIALOG_NO_RESOURCE_ID,
  3799. WIALOG_LEVEL1,
  3800. "CWIAScannerDevice::BuildCapabilities");
  3801. HRESULT hr = S_OK;
  3802. if (NULL != m_pCapabilities) {
  3803. //
  3804. // Capabilities have already been initialized,
  3805. // so return S_OK.
  3806. //
  3807. return hr;
  3808. }
  3809. m_NumSupportedCommands = 0;
  3810. m_NumSupportedEvents = 0;
  3811. m_NumCapabilities = 0;
  3812. WIACAPABILITIES WIACaps;
  3813. memset(&WIACaps,0,sizeof(WIACaps));
  3814. WIACaps.pCapabilities = NULL; // set to NULL, to ask for number of
  3815. // capabilities
  3816. WIACaps.pNumSupportedCommands = &m_NumSupportedCommands;
  3817. WIACaps.pNumSupportedEvents = &m_NumSupportedEvents;
  3818. //
  3819. // ask for number of capabilities
  3820. //
  3821. hr = m_pScanAPI->BuildCapabilities(&WIACaps);
  3822. if (SUCCEEDED(hr)) {
  3823. LONG lDriverAddedEvents = m_NumSupportedEvents;
  3824. m_NumSupportedCommands = 1;
  3825. m_NumSupportedEvents = (lDriverAddedEvents + 2); // 2 required events (default events for all devices)
  3826. m_NumCapabilities = (m_NumSupportedCommands + m_NumSupportedEvents);
  3827. //
  3828. // allocate capabilities array memory
  3829. //
  3830. m_pCapabilities = new WIA_DEV_CAP_DRV[m_NumCapabilities];
  3831. if (m_pCapabilities) {
  3832. memset(&WIACaps,0,sizeof(WIACaps));
  3833. WIACaps.pCapabilities = m_pCapabilities;
  3834. WIACaps.pNumSupportedCommands = NULL;
  3835. WIACaps.pNumSupportedEvents = NULL;
  3836. //
  3837. // get capabilities from micro driver
  3838. //
  3839. hr = m_pScanAPI->BuildCapabilities(&WIACaps);
  3840. if (SUCCEEDED(hr)) {
  3841. LONG lStartIndex = lDriverAddedEvents;
  3842. //
  3843. // Initialize EVENTS
  3844. //
  3845. // WIA_EVENT_DEVICE_CONNECTED
  3846. GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_NAME,&(m_pCapabilities[lStartIndex].wszName),TRUE);
  3847. GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_DESC,&(m_pCapabilities[lStartIndex].wszDescription),TRUE);
  3848. m_pCapabilities[lStartIndex].guid = (GUID*)&WIA_EVENT_DEVICE_CONNECTED;
  3849. m_pCapabilities[lStartIndex].ulFlags = WIA_NOTIFICATION_EVENT;
  3850. m_pCapabilities[lStartIndex].wszIcon = WIA_ICON_DEVICE_CONNECTED;
  3851. lStartIndex++;
  3852. // WIA_EVENT_DEVICE_DISCONNECTED
  3853. GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_NAME,&(m_pCapabilities[lStartIndex].wszName),TRUE);
  3854. GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_DESC,&(m_pCapabilities[lStartIndex].wszDescription),TRUE);
  3855. m_pCapabilities[lStartIndex].guid = (GUID*)&WIA_EVENT_DEVICE_DISCONNECTED;
  3856. m_pCapabilities[lStartIndex].ulFlags = WIA_NOTIFICATION_EVENT;
  3857. m_pCapabilities[lStartIndex].wszIcon = WIA_ICON_DEVICE_DISCONNECTED;
  3858. lStartIndex++;
  3859. //
  3860. // Initialize COMMANDS
  3861. //
  3862. // WIA_CMD_SYNCHRONIZE
  3863. GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_NAME,&(m_pCapabilities[lStartIndex].wszName),TRUE);
  3864. GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_DESC,&(m_pCapabilities[lStartIndex].wszDescription),TRUE);
  3865. m_pCapabilities[lStartIndex].guid = (GUID*)&WIA_CMD_SYNCHRONIZE;
  3866. m_pCapabilities[lStartIndex].ulFlags = 0;
  3867. m_pCapabilities[lStartIndex].wszIcon = WIA_ICON_SYNCHRONIZE;
  3868. }
  3869. } else {
  3870. hr = E_OUTOFMEMORY;
  3871. }
  3872. }
  3873. return hr;
  3874. }
  3875. /**************************************************************************\
  3876. * DeleteCapabilitiesArrayContents
  3877. *
  3878. * This helper deletes the capabilities array
  3879. *
  3880. * Arguments:
  3881. *
  3882. * none
  3883. *
  3884. * Return Value:
  3885. *
  3886. * Status
  3887. *
  3888. * History:
  3889. *
  3890. * 7/18/2000 Original Version
  3891. *
  3892. \**************************************************************************/
  3893. HRESULT CWIAScannerDevice::DeleteCapabilitiesArrayContents()
  3894. {
  3895. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3896. WIALOG_NO_RESOURCE_ID,
  3897. WIALOG_LEVEL1,
  3898. "CWIAScannerDevice::DeleteCapabilitiesArrayContents");
  3899. HRESULT hr = S_OK;
  3900. if(NULL != m_pCapabilities) {
  3901. for (LONG i = 0; i < m_NumCapabilities;i++) {
  3902. CoTaskMemFree(m_pCapabilities[i].wszName);
  3903. CoTaskMemFree(m_pCapabilities[i].wszDescription);
  3904. }
  3905. delete [] m_pCapabilities;
  3906. m_pCapabilities = NULL;
  3907. }
  3908. return hr;
  3909. }
  3910. /**************************************************************************\
  3911. * GetBSTRResourceString
  3912. *
  3913. * This helper gets a BSTR from a resource location
  3914. *
  3915. * Arguments:
  3916. *
  3917. * lResourceID - Resource ID of the target BSTR value
  3918. * pBSTR - pointer to a BSTR value (caller must free this string)
  3919. * bLocal - TRUE - for local resources, FALSE - for wiaservc resources
  3920. *
  3921. * Return Value:
  3922. *
  3923. * Status
  3924. *
  3925. * History:
  3926. *
  3927. * 7/18/2000 Original Version
  3928. *
  3929. \**************************************************************************/
  3930. HRESULT CWIAScannerDevice::GetBSTRResourceString(LONG lResourceID,BSTR *pBSTR,BOOL bLocal)
  3931. {
  3932. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3933. WIALOG_NO_RESOURCE_ID,
  3934. WIALOG_LEVEL1,
  3935. "CWIAScannerDevice::GetBSTRResourceString");
  3936. HRESULT hr = S_OK;
  3937. TCHAR szStringValue[255];
  3938. if(bLocal) {
  3939. //
  3940. // We are looking for a resource in our own private resource file
  3941. //
  3942. LoadString(g_hInst,lResourceID,szStringValue,255);
  3943. //
  3944. // NOTE: caller must free this allocated BSTR
  3945. //
  3946. #ifdef UNICODE
  3947. *pBSTR = SysAllocString(szStringValue);
  3948. #else
  3949. WCHAR wszStringValue[255];
  3950. //
  3951. // convert szStringValue from char* to unsigned short* (ANSI only)
  3952. //
  3953. MultiByteToWideChar(CP_ACP,
  3954. MB_PRECOMPOSED,
  3955. szStringValue,
  3956. lstrlenA(szStringValue)+1,
  3957. wszStringValue,
  3958. (sizeof(wszStringValue)/sizeof(WCHAR)));
  3959. *pBSTR = SysAllocString(wszStringValue);
  3960. #endif
  3961. } else {
  3962. //
  3963. // We are looking for a resource in the wiaservc's resource file
  3964. //
  3965. hr = E_NOTIMPL;
  3966. }
  3967. return hr;
  3968. }
  3969. /**************************************************************************\
  3970. * GetOLESTRResourceString
  3971. *
  3972. * This helper gets a LPOLESTR from a resource location
  3973. *
  3974. * Arguments:
  3975. *
  3976. * lResourceID - Resource ID of the target BSTR value
  3977. * ppsz - pointer to a OLESTR value (caller must free this string)
  3978. * bLocal - TRUE - for local resources, FALSE - for wiaservc resources
  3979. *
  3980. * Return Value:
  3981. *
  3982. * Status
  3983. *
  3984. * History:
  3985. *
  3986. * 7/18/2000 Original Version
  3987. *
  3988. \**************************************************************************/
  3989. HRESULT CWIAScannerDevice::GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal)
  3990. {
  3991. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  3992. WIALOG_NO_RESOURCE_ID,
  3993. WIALOG_LEVEL1,
  3994. "CWIAScannerDevice::GetOLESTRResourceString");
  3995. HRESULT hr = S_OK;
  3996. TCHAR szStringValue[255];
  3997. if(bLocal) {
  3998. //
  3999. // We are looking for a resource in our own private resource file
  4000. //
  4001. LoadString(g_hInst,lResourceID,szStringValue,255);
  4002. //
  4003. // NOTE: caller must free this allocated BSTR
  4004. //
  4005. #ifdef UNICODE
  4006. *ppsz = NULL;
  4007. *ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(szStringValue));
  4008. if(*ppsz != NULL) {
  4009. wcscpy(*ppsz,szStringValue);
  4010. } else {
  4011. return E_OUTOFMEMORY;
  4012. }
  4013. #else
  4014. WCHAR wszStringValue[255];
  4015. //
  4016. // convert szStringValue from char* to unsigned short* (ANSI only)
  4017. //
  4018. MultiByteToWideChar(CP_ACP,
  4019. MB_PRECOMPOSED,
  4020. szStringValue,
  4021. lstrlenA(szStringValue)+1,
  4022. wszStringValue,
  4023. (sizeof(wszStringValue)/sizeof(WCHAR)));
  4024. *ppsz = NULL;
  4025. *ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(wszStringValue));
  4026. if(*ppsz != NULL) {
  4027. wcscpy(*ppsz,wszStringValue);
  4028. } else {
  4029. return E_OUTOFMEMORY;
  4030. }
  4031. #endif
  4032. } else {
  4033. //
  4034. // We are looking for a resource in the wiaservc's resource file
  4035. //
  4036. hr = E_NOTIMPL;
  4037. }
  4038. return hr;
  4039. }
  4040. /**************************************************************************\
  4041. * VerticalFlip
  4042. *
  4043. *
  4044. *
  4045. * Arguments:
  4046. *
  4047. *
  4048. *
  4049. * Return Value:
  4050. *
  4051. * Status
  4052. *
  4053. * History:
  4054. *
  4055. * 7/18/2000 Original Version
  4056. *
  4057. \**************************************************************************/
  4058. VOID CWIAScannerDevice::VerticalFlip(
  4059. PMINIDRIVERITEMCONTEXT pDrvItemContext,
  4060. PMINIDRV_TRANSFER_CONTEXT pDataTransferContext)
  4061. {
  4062. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  4063. WIALOG_NO_RESOURCE_ID,
  4064. WIALOG_LEVEL3,
  4065. "CWIAScannerDevice::VerticalFlip");
  4066. LONG iHeight = 0;
  4067. LONG iWidth = pDrvItemContext->lBytesPerScanLineRaw;
  4068. ULONG uiDepth = pDrvItemContext->lDepth;
  4069. LONG ScanLineWidth = pDrvItemContext->lBytesPerScanLine;
  4070. BITMAPINFO UNALIGNED *pbmi = NULL;
  4071. PBYTE pImageTop = NULL;
  4072. //
  4073. // find out if data is TYMED_FILE or TYMED_HGLOBAL
  4074. //
  4075. if (pDataTransferContext->tymed == TYMED_FILE) {
  4076. pbmi = (PBITMAPINFO)(pDataTransferContext->pTransferBuffer + sizeof(BITMAPFILEHEADER));
  4077. } else {
  4078. return;
  4079. }
  4080. //
  4081. // init memory pointer and height
  4082. //
  4083. pImageTop = pDataTransferContext->pTransferBuffer + pDataTransferContext->lHeaderSize;
  4084. #ifdef _64BIT_ALIGNMENT
  4085. BITMAPINFOHEADER UNALIGNED *pbmih = &pbmi->bmiHeader;
  4086. iHeight = pbmih->biHeight;
  4087. #else
  4088. iHeight = pbmi->bmiHeader.biHeight;
  4089. #endif
  4090. //
  4091. // try to allocate a temp scan line buffer
  4092. //
  4093. PBYTE pBuffer = (PBYTE)LocalAlloc(LPTR,ScanLineWidth);
  4094. if (pBuffer != NULL) {
  4095. LONG index = 0;
  4096. PBYTE pImageBottom = NULL;
  4097. pImageBottom = pImageTop + (iHeight-1) * ScanLineWidth;
  4098. for (index = 0;index < (iHeight/2);index++) {
  4099. memcpy(pBuffer,pImageTop,ScanLineWidth);
  4100. memcpy(pImageTop,pImageBottom,ScanLineWidth);
  4101. memcpy(pImageBottom,pBuffer,ScanLineWidth);
  4102. pImageTop += ScanLineWidth;
  4103. pImageBottom -= ScanLineWidth;
  4104. }
  4105. LocalFree(pBuffer);
  4106. } else {
  4107. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("VerticalFlip, LocalAlloc failed allocating %d bytes",ScanLineWidth));
  4108. }
  4109. }
  4110. /**************************************************************************\
  4111. * SwapBuffer24
  4112. *
  4113. * Place RGB bytes in correct order for DIB format.
  4114. *
  4115. * Arguments:
  4116. *
  4117. * pBuffer - Pointer to the data buffer.
  4118. * lByteCount - Size of the data in bytes.
  4119. *
  4120. * Return Value:
  4121. *
  4122. * Status
  4123. *
  4124. * History:
  4125. *
  4126. * 7/18/2000 Original Version
  4127. *
  4128. \**************************************************************************/
  4129. VOID CWIAScannerDevice::SwapBuffer24(PBYTE pBuffer, LONG lByteCount)
  4130. {
  4131. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  4132. WIALOG_NO_RESOURCE_ID,
  4133. WIALOG_LEVEL3,
  4134. "CWIAScannerDevice::::SwapBuffer24");
  4135. for (LONG i = 0; i < lByteCount; i+= 3) {
  4136. BYTE bTemp = pBuffer[i];
  4137. pBuffer[i] = pBuffer[i + 2];
  4138. pBuffer[i + 2] = bTemp;
  4139. }
  4140. }