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.

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