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.

1659 lines
62 KiB

  1. #include "precomp.h"
  2. //
  3. // values that the WIA/TWAIN data source provides for capability negotation
  4. //
  5. TW_UINT16 g_ScannerUnits[] = {TWUN_INCHES,TWUN_PIXELS};
  6. TW_UINT16 g_ScannerBitOrder[] = {TWBO_MSBFIRST};
  7. TW_UINT16 g_ScannerXferMech[] = {TWSX_NATIVE, TWSX_FILE, TWSX_MEMORY};
  8. TW_UINT16 g_ScannerPixelFlavor[] = {TWPF_CHOCOLATE,TWPF_VANILLA};
  9. const TW_UINT32 NUM_SCANNERCAPDATA = 29;
  10. const TW_UINT32 NUM_SCANNERCAPDATA_NO_FEEDER_DETECTED = 26;
  11. CAPDATA SCANNER_CAPDATA[NUM_SCANNERCAPDATA] =
  12. {
  13. //
  14. // Every source must support all five DG_CONTROL / DAT_CAPABILITY operations on:
  15. //
  16. {CAP_XFERCOUNT, TWTY_INT16, TWON_ONEVALUE,
  17. sizeof(TW_INT16), 0, 0, -1, 0, 1, NULL, NULL
  18. },
  19. //
  20. // Every source must support DG_CONTROL / DAT_CAPABILITY, MSG_GET on:
  21. //
  22. {CAP_SUPPORTEDCAPS, TWTY_UINT16, TWON_ARRAY,
  23. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  24. },
  25. {CAP_UICONTROLLABLE, TWTY_BOOL, TWON_ONEVALUE,
  26. sizeof(TW_BOOL), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
  27. },
  28. //
  29. // Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
  30. // MSG_GET, MSG_GETCURRENT, and MSG_GETDEFAULT on:
  31. //
  32. {ICAP_COMPRESSION, TWTY_UINT16, TWON_ENUMERATION,
  33. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  34. },
  35. {ICAP_PLANARCHUNKY, TWTY_UINT16, TWON_ONEVALUE,
  36. sizeof(TW_UINT16), TWPC_CHUNKY, TWPC_CHUNKY, TWPC_CHUNKY, TWPC_PLANAR, 0, NULL, NULL
  37. },
  38. {ICAP_PHYSICALHEIGHT, TWTY_FIX32, TWON_ONEVALUE,
  39. sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
  40. },
  41. {ICAP_PHYSICALWIDTH, TWTY_FIX32, TWON_ONEVALUE,
  42. sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
  43. },
  44. {ICAP_PIXELFLAVOR, TWTY_UINT16, TWON_ENUMERATION,
  45. sizeof(TW_UINT16), 0, 0, 0, 1, 0, g_ScannerPixelFlavor, NULL
  46. },
  47. //
  48. // Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
  49. // MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT, MSG_RESET, and MSG_SET on:
  50. //
  51. {ICAP_BITDEPTH, TWTY_UINT16, TWON_ENUMERATION,
  52. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  53. },
  54. {ICAP_BITORDER, TWTY_UINT16, TWON_ENUMERATION,
  55. sizeof(TW_UINT16), 0, 0, 0, 0, 0, g_ScannerBitOrder, NULL
  56. },
  57. {ICAP_PIXELTYPE, TWTY_UINT16, TWON_ENUMERATION,
  58. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  59. },
  60. {ICAP_UNITS, TWTY_UINT16, TWON_ENUMERATION,
  61. sizeof(TW_UINT16), 0, 0, 0, 1, 0, g_ScannerUnits, NULL
  62. },
  63. {ICAP_XFERMECH, TWTY_UINT16, TWON_ENUMERATION,
  64. sizeof(TW_UINT16), 0, 0, 0, 2, 0, g_ScannerXferMech, NULL
  65. },
  66. {ICAP_XRESOLUTION, TWTY_FIX32, TWON_RANGE,
  67. sizeof(TW_FIX32), 100, 100, 75, 1200, 1, NULL, NULL
  68. },
  69. {ICAP_YRESOLUTION, TWTY_FIX32, TWON_RANGE,
  70. sizeof(TW_FIX32), 100, 100, 75, 1200, 1, NULL, NULL
  71. },
  72. //
  73. // The following capabilities are provided for application compatiblity only.
  74. //
  75. {ICAP_IMAGEFILEFORMAT, TWTY_UINT16, TWON_ENUMERATION,
  76. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  77. },
  78. {CAP_INDICATORS, TWTY_BOOL, TWON_ONEVALUE,
  79. sizeof(TW_BOOL), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
  80. },
  81. {CAP_ENABLEDSUIONLY, TWTY_BOOL, TWON_ONEVALUE,
  82. sizeof(TW_BOOL), FALSE, FALSE, FALSE, FALSE, 0, NULL, NULL
  83. },
  84. {CAP_DEVICEONLINE, TWTY_BOOL, TWON_ONEVALUE,
  85. sizeof(TW_UINT16), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
  86. },
  87. {ICAP_XNATIVERESOLUTION, TWTY_FIX32, TWON_ONEVALUE,
  88. sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
  89. },
  90. {ICAP_YNATIVERESOLUTION, TWTY_FIX32, TWON_ONEVALUE,
  91. sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
  92. },
  93. {ICAP_BRIGHTNESS, TWTY_FIX32, TWON_RANGE,
  94. sizeof(TW_FIX32), 0, 0, -1000, 1000, 1, NULL, NULL
  95. },
  96. {ICAP_CONTRAST, TWTY_FIX32, TWON_RANGE,
  97. sizeof(TW_FIX32), 0, 0, -1000, 1000, 1, NULL, NULL
  98. },
  99. {ICAP_XSCALING, TWTY_FIX32, TWON_RANGE,
  100. sizeof(TW_FIX32), 1, 1, 1, 1, 1, NULL, NULL
  101. },
  102. {ICAP_YSCALING, TWTY_FIX32, TWON_RANGE,
  103. sizeof(TW_FIX32), 1, 1, 1, 1, 1, NULL, NULL
  104. },
  105. {ICAP_THRESHOLD, TWTY_FIX32, TWON_RANGE,
  106. sizeof(TW_FIX32), 128, 128, 0, 255, 1, NULL, NULL
  107. },
  108. //
  109. // All sources must implement the advertised features supplied by their devices.
  110. // The following properties are supplied for TWAIN protocol only, this source
  111. // supports document feeders (if they are detected).
  112. //
  113. {CAP_FEEDERENABLED, TWTY_BOOL, TWON_ONEVALUE,
  114. sizeof(TW_BOOL), FALSE, FALSE, FALSE, TRUE, 0, NULL, NULL
  115. },
  116. {CAP_FEEDERLOADED, TWTY_BOOL, TWON_ONEVALUE,
  117. sizeof(TW_BOOL), FALSE, FALSE, FALSE, TRUE, 0, NULL, NULL
  118. },
  119. {CAP_AUTOFEED, TWTY_BOOL, TWON_ONEVALUE,
  120. sizeof(TW_BOOL), FALSE, FALSE, FALSE, TRUE, 0, NULL, NULL
  121. }
  122. };
  123. TW_UINT16 CWiaScannerDS::OpenDS(PTWAIN_MSG ptwMsg)
  124. {
  125. DBG_FN_DS(CWiaScannerDS::OpenDS());
  126. m_bUnknownPageLength = FALSE;
  127. m_bCacheImage = FALSE;
  128. m_bEnforceUIMode = FALSE;
  129. m_bUnknownPageLengthMultiPageOverRide = FALSE;
  130. if (ReadTwainRegistryDWORDValue(DWORD_REGVALUE_ENABLE_MULTIPAGE_SCROLLFED,
  131. DWORD_REGVALUE_ENABLE_MULTIPAGE_SCROLLFED_ON) == DWORD_REGVALUE_ENABLE_MULTIPAGE_SCROLLFED_ON) {
  132. m_bUnknownPageLengthMultiPageOverRide = TRUE;
  133. }
  134. TW_UINT16 twRc = TWRC_FAILURE;
  135. HRESULT hr = S_OK;
  136. twRc = CWiaDataSrc::OpenDS(ptwMsg);
  137. if (TWRC_SUCCESS != twRc)
  138. return twRc;
  139. BASIC_INFO BasicInfo;
  140. memset(&BasicInfo,0,sizeof(BasicInfo));
  141. BasicInfo.Size = sizeof(BasicInfo);
  142. hr = m_pDevice->GetBasicScannerInfo(&BasicInfo);
  143. if(FAILED(hr)){
  144. DBG_ERR(("CWiaScannerDS::OpenDS(), GetBasicScannerInfo() failed"));
  145. return TWRC_FAILURE;
  146. }
  147. DBG_TRC(("CWiaScannerDS::OpenDS(), Reported Basic Scanner Information from WIA device"));
  148. DBG_TRC(("BasicInfo.Size = %d",BasicInfo.Size));
  149. DBG_TRC(("BasicInfo.xBedSize = %d",BasicInfo.xBedSize));
  150. DBG_TRC(("BasicInfo.yBedSize = %d",BasicInfo.yBedSize));
  151. DBG_TRC(("BasicInfo.xOpticalRes = %d",BasicInfo.xOpticalRes));
  152. DBG_TRC(("BasicInfo.yOpticalRes = %d",BasicInfo.yOpticalRes));
  153. DBG_TRC(("BasicInfo.FeederCaps = %d",BasicInfo.FeederCaps));
  154. //
  155. // Update cap based on information we got
  156. //
  157. CCap * pCap = NULL;
  158. TW_UINT32 Value = 0;
  159. TW_FIX32 fix32;
  160. memset(&fix32,0,sizeof(fix32));
  161. //
  162. // Cache the scanner document handling capability
  163. //
  164. m_FeederCaps = BasicInfo.FeederCaps;
  165. //
  166. // create capability list
  167. //
  168. if(m_FeederCaps > 0){
  169. twRc = CreateCapList(NUM_SCANNERCAPDATA, SCANNER_CAPDATA);
  170. } else {
  171. twRc = CreateCapList(NUM_SCANNERCAPDATA_NO_FEEDER_DETECTED, SCANNER_CAPDATA);
  172. }
  173. if (TWCC_SUCCESS != twRc) {
  174. m_twStatus.ConditionCode = twRc;
  175. return TWRC_FAILURE;
  176. }
  177. if (m_FeederCaps > 0) {
  178. //
  179. // we have a scanner that has feeder capabilities
  180. //
  181. pCap = NULL;
  182. pCap = FindCap(CAP_FEEDERENABLED);
  183. if (pCap) {
  184. DBG_TRC(("Setting feeder enabled to TRUE, because we have a document feeder"));
  185. twRc = pCap->Set(FALSE, FALSE, TRUE, TRUE);
  186. }
  187. pCap = NULL;
  188. pCap = FindCap(CAP_FEEDERLOADED);
  189. if (pCap) {
  190. DBG_TRC(("Setting feeder loaded to TRUE, because we have a document feeder and assume it is loaded"));
  191. twRc = pCap->Set(TRUE, TRUE, TRUE, TRUE);
  192. }
  193. }
  194. //
  195. // Update the cached frame.
  196. //
  197. m_CurFrame.Left.Whole = m_CurFrame.Top.Whole = 0;
  198. m_CurFrame.Left.Frac = m_CurFrame.Top.Frac = 0;
  199. pCap = FindCap(ICAP_XNATIVERESOLUTION);
  200. if (pCap) {
  201. twRc = pCap->Set(BasicInfo.xOpticalRes, BasicInfo.xOpticalRes,
  202. BasicInfo.xOpticalRes, BasicInfo.xOpticalRes);
  203. }
  204. pCap = NULL;
  205. pCap = FindCap(ICAP_YNATIVERESOLUTION);
  206. if (pCap) {
  207. twRc = pCap->Set(BasicInfo.yOpticalRes, BasicInfo.yOpticalRes,
  208. BasicInfo.yOpticalRes, BasicInfo.yOpticalRes);
  209. }
  210. pCap = NULL;
  211. pCap = FindCap(ICAP_PHYSICALHEIGHT);
  212. if (pCap) {
  213. // bed size is in 1000th inches (we default to inches, so calculate the size correctly..)
  214. fix32 = FloatToFix32((FLOAT)(BasicInfo.yBedSize / 1000.00));
  215. memcpy(&Value, &fix32, sizeof(TW_UINT32));
  216. twRc = pCap->Set(Value, Value, Value, Value);
  217. m_CurFrame.Bottom = fix32;
  218. }
  219. pCap = NULL;
  220. pCap = FindCap(ICAP_PHYSICALWIDTH);
  221. if (pCap) {
  222. // bed size is in 1000th inches (we default to inches, so calculate the size correctly..)
  223. fix32 = FloatToFix32((FLOAT)(BasicInfo.xBedSize / 1000.00));
  224. memcpy(&Value, &fix32, sizeof(TW_UINT32));
  225. twRc = pCap->Set(Value, Value, Value, Value);
  226. m_CurFrame.Right = fix32;
  227. }
  228. //
  229. // By TWAIN standard, capability negotiations come before
  230. // data source enabling. For this reason, we have to
  231. // trigger the device have those information ready for us.
  232. //
  233. hr = m_pDevice->AcquireImages(NULL, FALSE);
  234. if (SUCCEEDED(hr)) {
  235. hr = m_pDevice->EnumAcquiredImage(0, &m_pCurrentIWiaItem);
  236. if (SUCCEEDED(hr)) {
  237. twRc = GetCommonSettings();
  238. if(TWRC_SUCCESS == twRc){
  239. twRc = GetSettings();
  240. }
  241. }
  242. }
  243. return twRc;
  244. }
  245. TW_UINT16 CWiaScannerDS::OnImageLayoutMsg(PTWAIN_MSG ptwMsg)
  246. {
  247. DBG_FN_DS(CWiaScannerDS::OnImageLayoutMsg());
  248. TW_UINT16 twRc = TWRC_SUCCESS;
  249. TW_IMAGELAYOUT *pLayout = (TW_IMAGELAYOUT*)ptwMsg->pData;
  250. switch (ptwMsg->MSG) {
  251. case MSG_GET:
  252. case MSG_GETDEFAULT:
  253. case MSG_GETCURRENT:
  254. switch (GetTWAINState()) {
  255. case DS_STATE_7:
  256. m_twStatus.ConditionCode = TWCC_SEQERROR;
  257. twRc = TWRC_FAILURE;
  258. break;
  259. default:
  260. {
  261. GetImageLayout(&m_CurImageLayout);
  262. pLayout->DocumentNumber = m_CurImageLayout.DocumentNumber;
  263. pLayout->PageNumber = m_CurImageLayout.PageNumber;
  264. pLayout->FrameNumber = m_CurImageLayout.FrameNumber;
  265. pLayout->Frame.Top.Whole = m_CurImageLayout.Frame.Top.Whole;
  266. pLayout->Frame.Top.Frac = m_CurImageLayout.Frame.Top.Frac;
  267. pLayout->Frame.Left.Whole = m_CurImageLayout.Frame.Left.Whole;
  268. pLayout->Frame.Left.Frac = m_CurImageLayout.Frame.Left.Frac;
  269. pLayout->Frame.Right.Whole = m_CurImageLayout.Frame.Right.Whole;
  270. pLayout->Frame.Right.Frac = m_CurImageLayout.Frame.Right.Frac;
  271. pLayout->Frame.Bottom.Whole = m_CurImageLayout.Frame.Bottom.Whole;
  272. pLayout->Frame.Bottom.Frac = m_CurImageLayout.Frame.Bottom.Frac;
  273. //pLayout->Frame = m_CurFrame; // BETTER BE IN CORRECT UNITS!!!!
  274. }
  275. break;
  276. }
  277. break;
  278. case MSG_SET:
  279. switch (GetTWAINState()) {
  280. case DS_STATE_5:
  281. case DS_STATE_6:
  282. case DS_STATE_7:
  283. m_twStatus.ConditionCode = TWCC_SEQERROR;
  284. twRc = TWRC_FAILURE;
  285. break;
  286. default:
  287. // do actual MSG_SET here..
  288. {
  289. DBG_TRC(("CWiaScannerDS::OnImageLayoutMsg(), MSG_SET TW_IMAGELAYOUT to set from Application"));
  290. DBG_TRC(("DocumentNumber = %d",pLayout->DocumentNumber));
  291. DBG_TRC(("PageNumber = %d",pLayout->PageNumber));
  292. DBG_TRC(("FrameNumber = %d",pLayout->FrameNumber));
  293. DBG_TRC(("Frame.Top.Whole = %d",pLayout->Frame.Top.Whole));
  294. DBG_TRC(("Frame.Top.Frac = %d",pLayout->Frame.Top.Frac));
  295. DBG_TRC(("Frame.Left.Whole = %d",pLayout->Frame.Left.Whole));
  296. DBG_TRC(("Frame.Left.Frac = %d",pLayout->Frame.Left.Frac));
  297. DBG_TRC(("Frame.Right.Whole = %d",pLayout->Frame.Right.Whole));
  298. DBG_TRC(("Frame.Right.Frac = %d",pLayout->Frame.Right.Frac));
  299. DBG_TRC(("Frame.Bottom.Whole = %d",pLayout->Frame.Bottom.Whole));
  300. DBG_TRC(("Frame.Bottom.Frac = %d",pLayout->Frame.Bottom.Frac));
  301. //
  302. // perform a really rough validation check on FRAME values.
  303. // validate possible incorrect settings by an application.
  304. //
  305. CCap *pXCap = FindCap(ICAP_PHYSICALWIDTH);
  306. TW_INT16 MaxWidthWhole = 8;
  307. if(pXCap){
  308. MaxWidthWhole = (TW_INT16)pXCap->GetCurrent();
  309. }
  310. if(pLayout->Frame.Right.Whole > MaxWidthWhole) {
  311. twRc = TWRC_FAILURE;
  312. m_twStatus.ConditionCode = TWCC_BADVALUE;
  313. DBG_TRC(("Frame.Right.Whole Value (%d) is greater than MAX Right value (%d)",pLayout->Frame.Right.Whole,MaxWidthWhole));
  314. }
  315. CCap *pYCap = FindCap(ICAP_PHYSICALHEIGHT);
  316. TW_INT16 MaxHeightWhole = 11;
  317. if(pYCap){
  318. MaxHeightWhole = (TW_INT16)pYCap->GetCurrent();
  319. }
  320. if(pLayout->Frame.Bottom.Whole > MaxHeightWhole) {
  321. twRc = TWRC_FAILURE;
  322. m_twStatus.ConditionCode = TWCC_BADVALUE;
  323. DBG_TRC(("Frame.Bottom.Whole Value (%d) is greater than MAX Bottom value (%d)",pLayout->Frame.Bottom.Whole,MaxHeightWhole));
  324. }
  325. if (twRc == TWRC_SUCCESS) {
  326. //
  327. // save SET values to ImageLayout member
  328. //
  329. m_CurImageLayout.DocumentNumber = pLayout->DocumentNumber;
  330. m_CurImageLayout.PageNumber = pLayout->PageNumber;
  331. m_CurImageLayout.FrameNumber = pLayout->FrameNumber;
  332. m_CurImageLayout.Frame.Top.Whole = pLayout->Frame.Top.Whole;
  333. m_CurImageLayout.Frame.Top.Frac = pLayout->Frame.Top.Frac;
  334. m_CurImageLayout.Frame.Left.Whole = pLayout->Frame.Left.Whole;
  335. m_CurImageLayout.Frame.Left.Frac = pLayout->Frame.Left.Frac;
  336. m_CurImageLayout.Frame.Right.Whole = pLayout->Frame.Right.Whole;
  337. m_CurImageLayout.Frame.Right.Frac = pLayout->Frame.Right.Frac;
  338. m_CurImageLayout.Frame.Bottom.Whole = pLayout->Frame.Bottom.Whole;
  339. m_CurImageLayout.Frame.Bottom.Frac = pLayout->Frame.Bottom.Frac;
  340. twRc = SetImageLayout(pLayout);
  341. }
  342. }
  343. break;
  344. }
  345. break;
  346. case MSG_RESET:
  347. switch (GetTWAINState()) {
  348. case DS_STATE_5:
  349. case DS_STATE_6:
  350. case DS_STATE_7:
  351. m_twStatus.ConditionCode = TWCC_SEQERROR;
  352. twRc = TWRC_FAILURE;
  353. break;
  354. default:
  355. // do actual MSG_RESET here..
  356. {
  357. #ifdef DEBUG
  358. DBG_TRC(("\n\nMSG_RESET - ImageLayout DocNum = %d, PgNum = %d, FrameNum = %d",
  359. pLayout->DocumentNumber,
  360. pLayout->PageNumber,
  361. pLayout->FrameNumber));
  362. DBG_TRC(("Frame Values\n Top = %d.%d\nLeft = %d.%d\nRight = %d.%d\nBottom = %d.%d",
  363. pLayout->Frame.Top.Whole,
  364. pLayout->Frame.Top.Frac,
  365. pLayout->Frame.Left.Whole,
  366. pLayout->Frame.Left.Frac,
  367. pLayout->Frame.Right.Whole,
  368. pLayout->Frame.Right.Frac,
  369. pLayout->Frame.Bottom.Whole,
  370. pLayout->Frame.Bottom.Frac));
  371. #endif
  372. m_CurImageLayout.Frame.Top.Whole = 0;
  373. m_CurImageLayout.Frame.Top.Frac = 0;
  374. m_CurImageLayout.Frame.Left.Whole = 0;
  375. m_CurImageLayout.Frame.Left.Frac = 0;
  376. m_CurImageLayout.Frame.Right.Whole = 8;
  377. m_CurImageLayout.Frame.Right.Frac = 5;
  378. m_CurImageLayout.Frame.Bottom.Whole = 11;
  379. m_CurImageLayout.Frame.Bottom.Frac = 0;
  380. }
  381. break;
  382. }
  383. break;
  384. default:
  385. twRc = TWRC_FAILURE;
  386. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  387. DSError();
  388. break;
  389. }
  390. return twRc;
  391. }
  392. TW_UINT16 CWiaScannerDS::CloseDS(PTWAIN_MSG ptwMsg)
  393. {
  394. DBG_FN_DS(CWiaScannerDS::CloseDS());
  395. DestroyCapList();
  396. return CWiaDataSrc::CloseDS(ptwMsg);
  397. }
  398. TW_UINT16 CWiaScannerDS::EnableDS(TW_USERINTERFACE *pUI)
  399. {
  400. DBG_FN_DS(CWiaScannerDS::EnableDS());
  401. TW_UINT16 twRc = TWRC_FAILURE;
  402. m_bUnknownPageLength = FALSE;
  403. if (DS_STATE_4 == GetTWAINState()) {
  404. HRESULT hr = S_OK;
  405. if(pUI->ShowUI){
  406. DBG_TRC(("CWiaScannerDS::EnableDS(), TWAIN UI MODE"));
  407. m_pDevice->FreeAcquiredImages();
  408. m_pCurrentIWiaItem = NULL;
  409. } else {
  410. DBG_TRC(("CWiaScannerDS::EnableDS(), TWAIN UI-LESS MODE"));
  411. m_pDevice->FreeAcquiredImages();
  412. m_pCurrentIWiaItem = NULL;
  413. }
  414. hr = m_pDevice->AcquireImages(HWND (pUI->ShowUI ? pUI->hParent : NULL),pUI->ShowUI);
  415. if (S_OK == hr) {
  416. twRc = TWRC_SUCCESS;
  417. LONG lNumImages = 0;
  418. m_pDevice->GetNumAcquiredImages(&lNumImages);
  419. if (lNumImages) {
  420. m_NumIWiaItems = (TW_UINT32)lNumImages;
  421. m_pIWiaItems = new (IWiaItem *[m_NumIWiaItems]);
  422. if (m_pIWiaItems) {
  423. hr = m_pDevice->GetAcquiredImageList(lNumImages, m_pIWiaItems, NULL);
  424. if (FAILED(hr)) {
  425. delete [] m_pIWiaItems;
  426. m_pIWiaItems = NULL;
  427. m_NumIWiaItems = 0;
  428. m_NextIWiaItemIndex = 0;
  429. m_twStatus.ConditionCode = TWCC_BUMMER;
  430. twRc = TWRC_FAILURE;
  431. }
  432. } else {
  433. m_NumIWiaItems = 0;
  434. m_twStatus.ConditionCode = TWCC_LOWMEMORY;
  435. twRc = TWRC_FAILURE;
  436. }
  437. }
  438. } else if(S_FALSE == hr) {
  439. return TWRC_CANCEL;
  440. } else {
  441. m_twStatus.ConditionCode = TWCC_OPERATIONERROR;
  442. twRc = TWRC_FAILURE;
  443. }
  444. if (TWRC_SUCCESS == twRc) {
  445. if (m_NumIWiaItems) {
  446. m_pCurrentIWiaItem = m_pIWiaItems[0];
  447. m_NextIWiaItemIndex = 1;
  448. //
  449. // Special case the devices that can acquire with an unknown page length setting.
  450. // WIA devices will be missing the YExtent property, or it will be set to 0.
  451. // TRUE will be returned from IsUnknownPageLengthDevice() if it this functionality
  452. // is supported.
  453. // Since TWAIN does not support unknown page lengths very well, we are required to
  454. // cache the page data, and image settings.
  455. // Note: unknown page length devices will be limited to DIB/BMP data types.
  456. // This will allow the TWAIN compatibility layer to calculate the
  457. // missing image information from the transferred data size.
  458. //
  459. if(IsUnknownPageLengthDevice()){
  460. twRc = TransferToMemory(WiaImgFmt_MEMORYBMP);
  461. if(TWRC_SUCCESS != twRc){
  462. return twRc;
  463. }
  464. m_bUnknownPageLength = TRUE;
  465. m_bCacheImage = TRUE;
  466. }
  467. //
  468. // transition to STATE_5
  469. //
  470. SetTWAINState(DS_STATE_5);
  471. NotifyXferReady();
  472. twRc = TWRC_SUCCESS;
  473. } else {
  474. NotifyCloseReq();
  475. //
  476. // transition to STATE_5
  477. //
  478. SetTWAINState(DS_STATE_5);
  479. twRc = TWRC_SUCCESS;
  480. }
  481. }
  482. }
  483. return twRc;
  484. }
  485. TW_UINT16 CWiaScannerDS::SetCapability(CCap *pCap,TW_CAPABILITY *ptwCap)
  486. {
  487. TW_UINT16 twRc = TWRC_SUCCESS;
  488. //
  489. // Use base class's function for now
  490. //
  491. twRc = CWiaDataSrc::SetCapability(pCap, ptwCap);
  492. if (twRc == TWRC_SUCCESS) {
  493. twRc = CWiaDataSrc::SetCommonSettings(pCap);
  494. if(twRc == TWRC_SUCCESS){
  495. twRc = SetSettings(pCap);
  496. }
  497. }
  498. return twRc;
  499. }
  500. TW_UINT16 CWiaScannerDS::TransferToFile(GUID guidFormatID)
  501. {
  502. TW_UINT16 twRc = TWRC_FAILURE;
  503. CCap *pPendingXfers = FindCap(CAP_XFERCOUNT);
  504. if(pPendingXfers){
  505. if(IsFeederEnabled()){
  506. DBG_TRC(("CWiaScannerDS::TransferToFile(), Scanner device is set to FEEDER mode for transfer"));
  507. pPendingXfers->SetCurrent((TW_UINT32)32767);
  508. } else {
  509. DBG_TRC(("CWiaScannerDS::TransferToFile(), Scanner device is set to FLATBED mode for transfer"));
  510. pPendingXfers->SetCurrent((TW_UINT32)0);
  511. }
  512. }
  513. if (m_bCacheImage) {
  514. m_bCacheImage = FALSE;
  515. //
  516. // acquire a cached image
  517. //
  518. HGLOBAL hDIB = NULL;
  519. twRc = CWiaDataSrc::GetCachedImage(&hDIB);
  520. if(TWRC_SUCCESS == twRc){
  521. //
  522. // cached data is always upside down orientation
  523. // because it was acquired using the TransferToMemory()
  524. // API. Call FlipDIB() to correct the image's orientation
  525. // and to adjust any negative heights that may exist.
  526. //
  527. FlipDIB(hDIB,TRUE);
  528. twRc = WriteDIBToFile(m_FileXferName, hDIB);
  529. GlobalFree(hDIB);
  530. hDIB = NULL;
  531. }
  532. } else {
  533. //
  534. // acquire a real image
  535. //
  536. twRc = CWiaDataSrc::TransferToFile(guidFormatID);
  537. }
  538. return twRc;
  539. }
  540. TW_UINT16 CWiaScannerDS::TransferToDIB(HGLOBAL *phDIB)
  541. {
  542. TW_UINT16 twRc = TWRC_FAILURE;
  543. CCap *pPendingXfers = FindCap(CAP_XFERCOUNT);
  544. if(pPendingXfers){
  545. if(IsFeederEnabled()){
  546. DBG_TRC(("CWiaScannerDS::TransferToDIB(), Scanner device is set to FEEDER mode for transfer"));
  547. pPendingXfers->SetCurrent((TW_UINT32)32767);
  548. } else {
  549. DBG_TRC(("CWiaScannerDS::TransferToDIB(), Scanner device is set to FLATBED mode for transfer"));
  550. pPendingXfers->SetCurrent((TW_UINT32)0);
  551. }
  552. }
  553. if (m_bCacheImage) {
  554. m_bCacheImage = FALSE;
  555. //
  556. // acquire a cached image
  557. //
  558. twRc = CWiaDataSrc::GetCachedImage(phDIB);
  559. if(TWRC_SUCCESS == twRc){
  560. //
  561. // cached data is always upside down orientation
  562. // because it was acquired using the TransferToMemory()
  563. // API. Call FlipDIB() to correct the image's orientation
  564. // and to adjust any negative heights that may exist.
  565. //
  566. FlipDIB(*phDIB,TRUE);
  567. twRc = TWRC_XFERDONE;
  568. }
  569. } else {
  570. //
  571. // acquire a real image
  572. //
  573. twRc = CWiaDataSrc::TransferToDIB(phDIB);
  574. }
  575. return twRc;
  576. }
  577. TW_UINT16 CWiaScannerDS::TransferToMemory(GUID guidFormatID)
  578. {
  579. TW_UINT16 twRc = TWRC_FAILURE;
  580. CCap *pPendingXfers = FindCap(CAP_XFERCOUNT);
  581. if(pPendingXfers){
  582. if(IsFeederEnabled()){
  583. DBG_TRC(("CWiaScannerDS::TransferToMemory(), Scanner device is set to FEEDER mode for transfer"));
  584. pPendingXfers->SetCurrent((TW_UINT32)32767);
  585. } else {
  586. DBG_TRC(("CWiaScannerDS::TransferToMemory(), Scanner device is set to FLATBED mode for transfer"));
  587. pPendingXfers->SetCurrent((TW_UINT32)0);
  588. }
  589. }
  590. if (m_bCacheImage) {
  591. m_bCacheImage = FALSE;
  592. //
  593. // acquire a cached image
  594. //
  595. //
  596. // cached data is already in the correct form to just pass
  597. // back because it was originally acquired using the TransferToMemory()
  598. // API.
  599. //
  600. twRc = CWiaDataSrc::GetCachedImage(&m_hMemXferBits);
  601. if(TWRC_FAILURE == twRc){
  602. DBG_ERR(("CWiaDataSrc::GetCachedImage(), failed to return cached data"));
  603. }
  604. } else {
  605. //
  606. // acquire a real image
  607. //
  608. twRc = CWiaDataSrc::TransferToMemory(guidFormatID);
  609. if(TWRC_FAILURE == twRc){
  610. DBG_ERR(("CWiaDataSrc::TransferToMemory(), failed to return data"));
  611. }
  612. }
  613. return twRc;
  614. }
  615. TW_UINT16 CWiaScannerDS::OnPendingXfersMsg(PTWAIN_MSG ptwMsg)
  616. {
  617. DBG_FN_DS(CWiaScannerDS::OnPendingXfersMsg());
  618. TW_UINT16 twRc = TWRC_SUCCESS;
  619. CCap *pXferCount;
  620. pXferCount = FindCap(CAP_XFERCOUNT);
  621. if (!pXferCount) {
  622. m_twStatus.ConditionCode = TWCC_BUMMER;
  623. return TWRC_FAILURE;
  624. }
  625. twRc = TWRC_SUCCESS;
  626. switch (ptwMsg->MSG) {
  627. case MSG_GET:
  628. switch (GetTWAINState()) {
  629. case DS_STATE_4:
  630. case DS_STATE_5:
  631. case DS_STATE_6:
  632. case DS_STATE_7:
  633. if(m_bUnknownPageLength){
  634. if(m_bUnknownPageLengthMultiPageOverRide){
  635. ((TW_PENDINGXFERS *)ptwMsg->pData)->Count = (TW_INT16)pXferCount->GetCurrent();
  636. DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_GET returning %d (unknown page length device detected) MULTI-PAGE enabled",((TW_PENDINGXFERS *)ptwMsg->pData)->Count));
  637. } else {
  638. DBG_WRN(("CWiaScannerDS::OnPendingXfersMsg(), MSG_GET returning 0 (unknown page length device detected)"));
  639. ((TW_PENDINGXFERS *)ptwMsg->pData)->Count = 0; // force 1 page only
  640. }
  641. } else {
  642. ((TW_PENDINGXFERS *)ptwMsg->pData)->Count = (TW_INT16)pXferCount->GetCurrent();
  643. DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_GET returning %d",((TW_PENDINGXFERS *)ptwMsg->pData)->Count));
  644. }
  645. break;
  646. default:
  647. twRc = TWRC_FAILURE;
  648. m_twStatus.ConditionCode = TWCC_SEQERROR;
  649. DSError();
  650. break;
  651. }
  652. break;
  653. case MSG_ENDXFER:
  654. if (DS_STATE_6 == GetTWAINState() || DS_STATE_7 == GetTWAINState()) {
  655. ResetMemXfer();
  656. TW_INT32 Count = 0;
  657. if (m_bUnknownPageLength) {
  658. if(m_bUnknownPageLengthMultiPageOverRide){
  659. DBG_WRN(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER (unknown page length device detected) MULTI-PAGE enabled"));
  660. //
  661. // check to see if we are in FEEDER mode
  662. //
  663. if (IsFeederEnabled()) {
  664. //
  665. // check for documents
  666. //
  667. if (IsFeederEmpty()) {
  668. Count = 0;
  669. } else {
  670. Count = pXferCount->GetCurrent();
  671. }
  672. } else {
  673. //
  674. // we must be in FLATBED mode, so force a single page transfer
  675. //
  676. Count = 0;
  677. }
  678. } else {
  679. DBG_WRN(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER returning 0 (unknown page length device detected)"));
  680. Count = 0; // force a single page transfer only
  681. }
  682. } else {
  683. //
  684. // check to see if we are in FEEDER mode
  685. //
  686. if (IsFeederEnabled()) {
  687. //
  688. // check for documents
  689. //
  690. if (IsFeederEmpty()) {
  691. Count = 0;
  692. } else {
  693. Count = pXferCount->GetCurrent();
  694. }
  695. } else {
  696. //
  697. // we must be in FLATBED mode, so force a single page transfer
  698. //
  699. Count = 0;
  700. }
  701. }
  702. if(Count == 32767){
  703. DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER, -1 or (32767) (feeder may have more documents)"));
  704. } else if (Count > 0){
  705. Count--;
  706. } else {
  707. Count = 0;
  708. }
  709. ((TW_PENDINGXFERS*)ptwMsg->pData)->Count = (SHORT)Count;
  710. pXferCount->SetCurrent((TW_UINT32)Count);
  711. if (Count == 0) {
  712. DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER, no more pages to transfer"));
  713. //
  714. // Transition to STATE_5
  715. //
  716. SetTWAINState(DS_STATE_5);
  717. NotifyCloseReq();
  718. } else if(Count == 32767){
  719. DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER, more pages to transfer"));
  720. //
  721. // Transition to STATE_6
  722. //
  723. SetTWAINState(DS_STATE_6);
  724. }
  725. } else {
  726. twRc = TWRC_FAILURE;
  727. m_twStatus.ConditionCode = TWCC_SEQERROR;
  728. DSError();
  729. }
  730. break;
  731. case MSG_RESET:
  732. if (DS_STATE_6 == GetTWAINState()) {
  733. //
  734. // Transition to STATE_5
  735. //
  736. SetTWAINState(DS_STATE_5);
  737. ((TW_PENDINGXFERS*)ptwMsg->pData)->Count = 0;
  738. ResetMemXfer();
  739. pXferCount->SetCurrent((TW_UINT32)0);
  740. } else {
  741. twRc = TWRC_FAILURE;
  742. m_twStatus.ConditionCode = TWCC_SEQERROR;
  743. DSError();
  744. }
  745. break;
  746. default:
  747. twRc = TWRC_FAILURE;
  748. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  749. DSError();
  750. break;
  751. }
  752. return twRc;
  753. }
  754. TW_UINT16 CWiaScannerDS::SetImageLayout(TW_IMAGELAYOUT *pImageLayout)
  755. {
  756. DBG_FN_DS(CWiaScannerDS::SetImageLayout());
  757. HRESULT hr = S_OK;
  758. LONG lXPos = 0;
  759. LONG lYPos = 0;
  760. LONG lXExtent = 0;
  761. LONG lYExtent = 0;
  762. LONG lXRes = 0;
  763. LONG lYRes = 0;
  764. BOOL bCheckStatus = FALSE;
  765. CWiahelper WIA;
  766. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  767. if (FAILED(hr)) {
  768. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to set IWiaItem for property reading"));
  769. }
  770. hr = WIA.ReadPropertyLong(WIA_IPS_XPOS,&lXPos);
  771. if(FAILED(hr)){
  772. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_XPOS"));
  773. return TWRC_FAILURE;
  774. }
  775. hr = WIA.ReadPropertyLong(WIA_IPS_YPOS,&lYPos);
  776. if(FAILED(hr)){
  777. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_YPOS"));
  778. return TWRC_FAILURE;
  779. }
  780. hr = WIA.ReadPropertyLong(WIA_IPS_XEXTENT,&lXExtent);
  781. if(FAILED(hr)){
  782. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_XEXTENT"));
  783. return TWRC_FAILURE;
  784. }
  785. hr = WIA.ReadPropertyLong(WIA_IPS_YEXTENT,&lYExtent);
  786. if(FAILED(hr)){
  787. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_YEXTENT"));
  788. return TWRC_FAILURE;
  789. }
  790. hr = WIA.ReadPropertyLong(WIA_IPS_XRES,&lXRes);
  791. if(FAILED(hr)){
  792. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_XRES"));
  793. return TWRC_FAILURE;
  794. }
  795. hr = WIA.ReadPropertyLong(WIA_IPS_YRES,&lYRes);
  796. if(FAILED(hr)){
  797. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_YRES"));
  798. return TWRC_FAILURE;
  799. }
  800. //
  801. // read the current values of the device
  802. //
  803. if (SUCCEEDED(hr)) {
  804. DBG_TRC(("==============================================================================="));
  805. DBG_TRC(("CWiaScannerDS::SetImageLayout(), WIA extents from device at %d dpi(x), %d dpi(y)",lXRes,lYRes));
  806. DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current X Position = %d",lXPos));
  807. DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current Y Position = %d",lYPos));
  808. DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current X Extent = %d",lXExtent));
  809. DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current Y Extent = %d",lYExtent));
  810. DBG_TRC(("==============================================================================="));
  811. DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN extents to convert.."));
  812. DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN X Position = %f",Fix32ToFloat(pImageLayout->Frame.Left)));
  813. DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN Y Position = %f",Fix32ToFloat(pImageLayout->Frame.Top)));
  814. DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN X Extent = %f",Fix32ToFloat(pImageLayout->Frame.Right)));
  815. DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN Y Extent = %f",Fix32ToFloat(pImageLayout->Frame.Bottom)));
  816. DBG_TRC(("==============================================================================="));
  817. lXPos = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Left),lXRes);
  818. lYPos = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Top),lYRes);
  819. lXExtent = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Right),lXRes);
  820. lYExtent = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Bottom),lYRes);
  821. DBG_TRC(("TWAIN -> WIA extent conversion at %d dpi(x), %d dpi(y)",lXRes,lYRes));
  822. DBG_TRC(("CWiaScannerDS::SetImageLayout(), New X Position = %d",lXPos));
  823. DBG_TRC(("CWiaScannerDS::SetImageLayout(), New Y Position = %d",lYPos));
  824. DBG_TRC(("CWiaScannerDS::SetImageLayout(), New X Extent = %d",lXExtent));
  825. DBG_TRC(("CWiaScannerDS::SetImageLayout(), New Y Extent = %d",lYExtent));
  826. DBG_TRC(("==============================================================================="));
  827. if (!m_bUnknownPageLength) {
  828. //
  829. // note: A failure to write the properties, isn't a large issue here, because
  830. // TWAIN UI-LESS mode expects clipping. They will reread properties
  831. // for application's validation section. All capabilities are validated
  832. // against their valid values, before setting here.
  833. //
  834. //
  835. // Write extents first, because TWAIN expects Height/Width settings to validate
  836. // the new Pos settings.
  837. //
  838. hr = WIA.WritePropertyLong(WIA_IPS_XEXTENT,lXExtent);
  839. if (FAILED(hr)) {
  840. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_XEXTENT"));
  841. bCheckStatus = TRUE;
  842. }
  843. hr = WIA.WritePropertyLong(WIA_IPS_YEXTENT,lYExtent);
  844. if (FAILED(hr)) {
  845. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_YEXTENT"));
  846. bCheckStatus = TRUE;
  847. }
  848. //
  849. // Write position settings...(top-of-page offsets)
  850. //
  851. hr = WIA.WritePropertyLong(WIA_IPS_XPOS,lXPos);
  852. if (FAILED(hr)) {
  853. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_XPOS"));
  854. bCheckStatus = TRUE;
  855. }
  856. hr = WIA.WritePropertyLong(WIA_IPS_YPOS,lYPos);
  857. if (FAILED(hr)) {
  858. DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_YPOS"));
  859. bCheckStatus = TRUE;
  860. }
  861. if (bCheckStatus) {
  862. DBG_TRC(("CWiaScannerDS::SetImageLayout(), some settings could not be set exactly, so return TWRC_CHECKSTATUS"));
  863. //return TWRC_CHECKSTATUS;
  864. }
  865. } else {
  866. DBG_WRN(("CWiaScannerDS::SetImageLayout(), ImageLayout is does not make since when using a UnknownPageLength Device"));
  867. //return TWRC_CHECKSTATUS;
  868. }
  869. } else {
  870. return TWRC_FAILURE;
  871. }
  872. //
  873. // Always return TWRC_CHECKSTATUS because we may have rounding errors.
  874. // According to the TWAIN spec, a return of TWRC_CHECKSTATUS tells the
  875. // calling application that we successfully set the settings, but there
  876. // may have been some changes (clipping etc.) So the Calling application
  877. // is required to requery for our current settings.
  878. //
  879. //
  880. // call GetImageLayout to update our TWAIN capabilities to match our new WIA settings.
  881. //
  882. GetImageLayout(&m_CurImageLayout);
  883. return TWRC_CHECKSTATUS; //return TWRC_SUCCESS;
  884. }
  885. TW_UINT16 CWiaScannerDS::GetImageLayout(TW_IMAGELAYOUT *pImageLayout)
  886. {
  887. DBG_FN_DS(CWiaScannerDS::GetImageLayout());
  888. HRESULT hr = S_OK;
  889. LONG lXPos = 0;
  890. LONG lYPos = 0;
  891. LONG lXExtent = 0;
  892. LONG lYExtent = 0;
  893. LONG lXRes = 0;
  894. LONG lYRes = 0;
  895. CWiahelper WIA;
  896. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  897. if (FAILED(hr)) {
  898. DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to set IWiaItem for property reading"));
  899. }
  900. hr = WIA.ReadPropertyLong(WIA_IPS_XPOS,&lXPos);
  901. if(FAILED(hr)){
  902. DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_XPOS"));
  903. return TWRC_FAILURE;
  904. }
  905. hr = WIA.ReadPropertyLong(WIA_IPS_YPOS,&lYPos);
  906. if(FAILED(hr)){
  907. DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_YPOS"));
  908. return TWRC_FAILURE;
  909. }
  910. hr = WIA.ReadPropertyLong(WIA_IPS_XEXTENT,&lXExtent);
  911. if(FAILED(hr)){
  912. DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_XEXTENT"));
  913. return TWRC_FAILURE;
  914. }
  915. hr = WIA.ReadPropertyLong(WIA_IPS_YEXTENT,&lYExtent);
  916. if(FAILED(hr)){
  917. DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_YEXTENT"));
  918. return TWRC_FAILURE;
  919. }
  920. hr = WIA.ReadPropertyLong(WIA_IPS_XRES,&lXRes);
  921. if(FAILED(hr)){
  922. DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_XRES"));
  923. return TWRC_FAILURE;
  924. }
  925. hr = WIA.ReadPropertyLong(WIA_IPS_YRES,&lYRes);
  926. if(FAILED(hr)){
  927. DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_YRES"));
  928. return TWRC_FAILURE;
  929. }
  930. if (SUCCEEDED(hr)) {
  931. if(lXRes <= 0){
  932. DBG_ERR(("CWiaScannerDS::GetImageLayout(), WIA_IPS_XRES returned an invalid value (%d)",lXRes));
  933. return TWRC_FAILURE;
  934. }
  935. if(lYRes <= 0){
  936. DBG_ERR(("CWiaScannerDS::GetImageLayout(), WIA_IPS_YRES returned an invalid value (%d)",lYRes));
  937. return TWRC_FAILURE;
  938. }
  939. pImageLayout->Frame.Top = FloatToFix32((float)((float)lYPos/(float)lYRes));
  940. pImageLayout->Frame.Left = FloatToFix32((float)((float)lXPos/(float)lXRes));
  941. pImageLayout->Frame.Right = FloatToFix32((float)((float)lXExtent/(float)lXRes));
  942. pImageLayout->Frame.Bottom = FloatToFix32((float)((float)lYExtent/(float)lYRes));
  943. } else {
  944. return TWRC_FAILURE;
  945. }
  946. if(m_bUnknownPageLength){
  947. DBG_WRN(("CWiaScannerDS::GetImageLayout(), ImageLayout is does not make since when using a UnknownPageLength Device"));
  948. return TWRC_CHECKSTATUS;
  949. }
  950. return TWRC_SUCCESS;
  951. }
  952. TW_UINT16 CWiaScannerDS::GetResolutions()
  953. {
  954. DBG_FN_DS(CWiaScannerDS::GetResolutions());
  955. HRESULT hr = S_OK;
  956. CWiahelper WIA;
  957. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  958. if (FAILED(hr)) {
  959. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to set IWiaItem for property reading"));
  960. return TWRC_FAILURE;
  961. }
  962. TW_UINT16 twRc = TWRC_FAILURE;
  963. TW_RANGE twOptionalYRange;
  964. memset(&twOptionalYRange,0,sizeof(twOptionalYRange));
  965. TW_UINT32 *pOptionalYResArray = NULL;
  966. TW_UINT32 OptionalYResNumValues = 0;
  967. BOOL bOptionalYResRange = FALSE;
  968. PROPVARIANT pv;
  969. memset(&pv,0,sizeof(pv));
  970. LONG lAccessFlags = 0;
  971. hr = WIA.ReadPropertyAttributes(WIA_IPS_XRES,&lAccessFlags,&pv);
  972. if (SUCCEEDED(hr)) {
  973. //
  974. // collect valid values for X resolutions
  975. //
  976. CCap *pCap = FindCap(ICAP_XRESOLUTION);
  977. if (pCap) {
  978. if (lAccessFlags & WIA_PROP_RANGE) {
  979. twRc = pCap->Set((TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
  980. (TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
  981. (TW_UINT32)pv.caul.pElems[WIA_RANGE_MIN],
  982. (TW_UINT32)pv.caul.pElems[WIA_RANGE_MAX],
  983. (TW_UINT32)pv.caul.pElems[WIA_RANGE_STEP]); // range
  984. //
  985. // save X resolution values in RANGE form (just in case the Y
  986. // resolution is WIA_PROP_NONE)
  987. //
  988. twOptionalYRange.ItemType = TWTY_UINT32;
  989. twOptionalYRange.CurrentValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM];
  990. twOptionalYRange.DefaultValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM];
  991. twOptionalYRange.MinValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_MIN];
  992. twOptionalYRange.MaxValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_MAX];
  993. twOptionalYRange.StepSize = (TW_UINT32)pv.caul.pElems[WIA_RANGE_STEP];
  994. bOptionalYResRange = TRUE;
  995. } else if (lAccessFlags & WIA_PROP_LIST) {
  996. TW_UINT32 *pResArray = new TW_UINT32[WIA_PROP_LIST_COUNT(&pv)];
  997. if (pResArray) {
  998. memset(pResArray,0,(sizeof(TW_UINT32)*WIA_PROP_LIST_COUNT(&pv)));
  999. pOptionalYResArray = new TW_UINT32[WIA_PROP_LIST_COUNT(&pv)];
  1000. if (pOptionalYResArray) {
  1001. memset(pOptionalYResArray,0,(sizeof(TW_UINT32)*WIA_PROP_LIST_COUNT(&pv)));
  1002. for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
  1003. pResArray[i] = (TW_UINT32)pv.caul.pElems[i+2];
  1004. //
  1005. // save the X resolution values in LIST form (just in case the Y
  1006. // resolution is WIA_PROP_NONE)
  1007. //
  1008. pOptionalYResArray[i] = (TW_UINT32)pv.caul.pElems[i+2];
  1009. }
  1010. //
  1011. // save the number of X resolutions saved
  1012. //
  1013. OptionalYResNumValues = (TW_UINT32)WIA_PROP_LIST_COUNT(&pv);
  1014. twRc = pCap->Set(0,0,WIA_PROP_LIST_COUNT(&pv),(BYTE*)pResArray,TRUE); // list
  1015. } else {
  1016. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to allocate optional Y Resolution Array Memory"));
  1017. twRc = TWRC_FAILURE;
  1018. }
  1019. delete [] pResArray;
  1020. pResArray = NULL;
  1021. } else {
  1022. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to allocate X Resolution Array Memory"));
  1023. twRc = TWRC_FAILURE;
  1024. }
  1025. } else if (lAccessFlags & WIA_PROP_NONE) {
  1026. //
  1027. // we are a "real" WIA_PROP_NONE value
  1028. //
  1029. LONG lCurrentValue = 0;
  1030. hr = WIA.ReadPropertyLong(WIA_IPS_XRES,&lCurrentValue);
  1031. if (SUCCEEDED(hr)) {
  1032. TW_UINT32 OneValueArray[1];
  1033. OneValueArray[0] = (TW_UINT32)lCurrentValue;
  1034. twRc = pCap->Set(0,0,1,(BYTE*)OneValueArray,TRUE); // list
  1035. } else {
  1036. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read X Resolution current value"));
  1037. twRc = TWRC_FAILURE;
  1038. }
  1039. }
  1040. }
  1041. PropVariantClear(&pv);
  1042. } else {
  1043. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read WIA_IPS_XRES attributes"));
  1044. twRc = TWRC_FAILURE;
  1045. }
  1046. if (TWRC_SUCCESS == twRc) {
  1047. memset(&pv,0,sizeof(pv));
  1048. lAccessFlags = 0;
  1049. hr = WIA.ReadPropertyAttributes(WIA_IPS_YRES,&lAccessFlags,&pv);
  1050. if (SUCCEEDED(hr)) {
  1051. //
  1052. // collect valid values for Y resolutions
  1053. //
  1054. CCap *pCap = FindCap(ICAP_YRESOLUTION);
  1055. if (pCap) {
  1056. if (lAccessFlags & WIA_PROP_RANGE) {
  1057. twRc = pCap->Set((TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
  1058. (TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
  1059. (TW_UINT32)pv.caul.pElems[WIA_RANGE_MIN],
  1060. (TW_UINT32)pv.caul.pElems[WIA_RANGE_MAX],
  1061. (TW_UINT32)pv.caul.pElems[WIA_RANGE_STEP]); // range
  1062. } else if (lAccessFlags & WIA_PROP_LIST) {
  1063. TW_UINT32 *pResArray = new TW_UINT32[WIA_PROP_LIST_COUNT(&pv)];
  1064. if (pResArray) {
  1065. memset(pResArray,0,(sizeof(TW_UINT32)*WIA_PROP_LIST_COUNT(&pv)));
  1066. for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
  1067. pResArray[i] = (TW_UINT32)pv.caul.pElems[i+2];
  1068. }
  1069. twRc = pCap->Set(0,0,WIA_PROP_LIST_COUNT(&pv),(BYTE*)pResArray,TRUE); // list
  1070. delete [] pResArray;
  1071. pResArray = NULL;
  1072. } else {
  1073. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to allocate Y Resolution Array Memory"));
  1074. twRc = TWRC_FAILURE;
  1075. }
  1076. } else if (lAccessFlags & WIA_PROP_NONE) {
  1077. if (pOptionalYResArray) {
  1078. //
  1079. // if we have an optional array allocated, then X Resolution must be in
  1080. // array form, so match it.
  1081. //
  1082. twRc = pCap->Set(0,0,OptionalYResNumValues,(BYTE*)pOptionalYResArray,TRUE); // list
  1083. } else if (bOptionalYResRange) {
  1084. //
  1085. // if the RANGE flag is set to TRUE, then X Resolution must be in range form, so match it.
  1086. //
  1087. twRc = pCap->Set(twOptionalYRange.DefaultValue,
  1088. twOptionalYRange.CurrentValue,
  1089. twOptionalYRange.MinValue,
  1090. twOptionalYRange.MaxValue,
  1091. twOptionalYRange.StepSize); // range
  1092. } else {
  1093. //
  1094. // we are a "real" WIA_PROP_NONE value
  1095. //
  1096. LONG lCurrentValue = 0;
  1097. hr = WIA.ReadPropertyLong(WIA_IPS_YRES,&lCurrentValue);
  1098. if (SUCCEEDED(hr)) {
  1099. TW_UINT32 OneValueArray[1];
  1100. OneValueArray[0] = (TW_UINT32)lCurrentValue;
  1101. twRc = pCap->Set(0,0,1,(BYTE*)OneValueArray,TRUE); // list
  1102. } else {
  1103. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read Y Resolution current value"));
  1104. twRc = TWRC_FAILURE;
  1105. }
  1106. }
  1107. }
  1108. }
  1109. PropVariantClear(&pv);
  1110. } else {
  1111. DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read WIA_IPS_YRES attributes"));
  1112. twRc = TWRC_FAILURE;
  1113. }
  1114. }
  1115. if (pOptionalYResArray) {
  1116. delete [] pOptionalYResArray;
  1117. pOptionalYResArray = NULL;
  1118. }
  1119. return twRc;
  1120. }
  1121. TW_UINT16 CWiaScannerDS::GetSettings()
  1122. {
  1123. DBG_FN_DS(CWiaScannerDS::GetSettings());
  1124. TW_UINT16 twRc = TWRC_SUCCESS;
  1125. twRc = GetImageLayout(&m_CurImageLayout);
  1126. if (TWRC_SUCCESS == twRc) {
  1127. twRc = GetResolutions();
  1128. }
  1129. return twRc;
  1130. }
  1131. TW_UINT16 CWiaScannerDS::SetSettings(CCap *pCap)
  1132. {
  1133. DBG_FN_DS(CWiaScannerDS::SetSettings());
  1134. HRESULT hr = S_OK;
  1135. LONG lValue = 0;
  1136. CWiahelper WIA;
  1137. IWiaItem *pIRootItem = NULL;
  1138. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  1139. if (FAILED(hr)) {
  1140. DBG_ERR(("CWiaScannerDS::SetSettings(), failed to set IWiaItem for property reading"));
  1141. }
  1142. //
  1143. // determine if it is a Capability that the device really needs to know
  1144. // about.
  1145. //
  1146. switch (pCap->GetCapId()) {
  1147. case CAP_FEEDERENABLED:
  1148. DBG_TRC(("CWiaScannerDS::SetCommonSettings(CAP_FEEDERENABLED)"));
  1149. lValue = (LONG)pCap->GetCurrent();
  1150. if(lValue){
  1151. DBG_TRC(("CWiaScannerDS::SetSettings(), Setting FEEDER mode"));
  1152. lValue = FEEDER;
  1153. } else {
  1154. DBG_TRC(("CWiaScannerDS::SetSettings(), Setting FLATBED mode Enabled"));
  1155. lValue = FLATBED;
  1156. }
  1157. hr = m_pCurrentIWiaItem->GetRootItem(&pIRootItem);
  1158. if(S_OK == hr){
  1159. hr = WIA.SetIWiaItem(pIRootItem);
  1160. if(SUCCEEDED(hr)){
  1161. //
  1162. // read current document handling select setting
  1163. //
  1164. LONG lCurrentDocumentHandlingSelect = 0;
  1165. hr = WIA.ReadPropertyLong(WIA_DPS_DOCUMENT_HANDLING_SELECT,&lCurrentDocumentHandlingSelect);
  1166. if(lValue == FEEDER){
  1167. lCurrentDocumentHandlingSelect &= ~FLATBED;
  1168. } else {
  1169. lCurrentDocumentHandlingSelect &= ~FEEDER;
  1170. }
  1171. //
  1172. // add the intended settings, and write them to the WIA device
  1173. //
  1174. lValue = lValue | lCurrentDocumentHandlingSelect;
  1175. hr = WIA.WritePropertyLong(WIA_DPS_DOCUMENT_HANDLING_SELECT,lValue);
  1176. if(SUCCEEDED(hr)){
  1177. //
  1178. // adjust ICAP_PHYSICALWIDTH and ICAP_PHYSICALHEIGHT
  1179. //
  1180. LONG lWidth = 0;
  1181. LONG lHeight = 0;
  1182. TW_UINT32 Value = 0;
  1183. CCap* pPhysicalCap = NULL;
  1184. TW_FIX32 fix32;
  1185. memset(&fix32,0,sizeof(fix32));
  1186. if(lValue & FEEDER){
  1187. //
  1188. // read current horizontal sheet feeder size
  1189. //
  1190. hr = WIA.ReadPropertyLong(WIA_DPS_HORIZONTAL_SHEET_FEED_SIZE,&lWidth);
  1191. } else {
  1192. //
  1193. // read current horizontal bed size
  1194. //
  1195. hr = WIA.ReadPropertyLong(WIA_DPS_HORIZONTAL_BED_SIZE,&lWidth);
  1196. }
  1197. if(SUCCEEDED(hr)){
  1198. //
  1199. // find the TWAIN capability ICAP_PHYSICALWIDTH
  1200. //
  1201. pPhysicalCap = FindCap(ICAP_PHYSICALWIDTH);
  1202. if(pPhysicalCap){
  1203. //
  1204. // set the current value, by reading the current setting from
  1205. // the WIA property WIA_DPS_HORIZONTAL_SHEET_FEED_SIZE and
  1206. // dividing by 1000.0 (because WIA units are in 1/1000th of
  1207. // an inch)
  1208. //
  1209. memset(&fix32,0,sizeof(fix32));
  1210. fix32 = FloatToFix32((FLOAT)(lWidth / 1000.00));
  1211. memcpy(&Value, &fix32, sizeof(TW_UINT32));
  1212. if(TWRC_SUCCESS == pPhysicalCap->Set(Value, Value, Value, Value)){
  1213. //
  1214. // if setting the new ICAP_PHYSICALWIDTH was successful, continue
  1215. // and attempt to set the ICAP_PHYSICALHEIGHT
  1216. //
  1217. if(lValue & FEEDER){
  1218. //
  1219. // read current vertical sheet feeder size
  1220. //
  1221. hr = WIA.ReadPropertyLong(WIA_DPS_VERTICAL_SHEET_FEED_SIZE,&lHeight);
  1222. } else {
  1223. //
  1224. // read current vertical bed size
  1225. //
  1226. hr = WIA.ReadPropertyLong(WIA_DPS_VERTICAL_BED_SIZE,&lHeight);
  1227. }
  1228. if (S_OK == hr){
  1229. //
  1230. // if the setting was successful, continue to attempt to set
  1231. // ICAP_PHYSICALHEIGHT setting.
  1232. //
  1233. pPhysicalCap = FindCap(ICAP_PHYSICALHEIGHT);
  1234. if (pPhysicalCap){
  1235. //
  1236. // set the current value, by reading the current setting from
  1237. // the WIA property WIA_DPS_VERTICAL_SHEET_FEED_SIZE and
  1238. // dividing by 1000.0 (because WIA units are in 1/1000th of
  1239. // an inch)
  1240. //
  1241. memset(&fix32,0,sizeof(fix32));
  1242. fix32 = FloatToFix32((FLOAT)(lHeight / 1000.00));
  1243. memcpy(&Value, &fix32, sizeof(TW_UINT32));
  1244. if (TWRC_SUCCESS != pPhysicalCap->Set(Value, Value, Value, Value)){
  1245. DBG_WRN(("CWiaScannerDS::SetSettings(), could not update TWAIN ICAP_PHYSICALHEIGHT settings"));
  1246. }
  1247. }
  1248. } else {
  1249. //
  1250. // allow this to pass, because we are either dealing with a "unknown length"
  1251. // device and it can not tell us the height, or the driver can not give us this
  1252. // value at this time.. (this is OK, because this setting is not fully needed for
  1253. // proper data transfers.) Worst case scenerio: The TWAIN compat layer will
  1254. // report the same height as the flatbed for the new ICAP_PHYSICALHEIGHT value.
  1255. //
  1256. hr = S_OK;
  1257. }
  1258. }
  1259. } else {
  1260. DBG_ERR(("CWiaScannerDS::SetSettings(), could not find ICAP_PHYSICALHEIGHT capability"));
  1261. }
  1262. } else {
  1263. DBG_ERR(("CWiaScannerDS::SetSettings(), failed to read physical sheet feeder size settings"));
  1264. }
  1265. }
  1266. }
  1267. pIRootItem->Release();
  1268. }
  1269. break;
  1270. case ICAP_XRESOLUTION:
  1271. DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_XRESOLUTION)"));
  1272. lValue = (LONG)pCap->GetCurrent();
  1273. DBG_TRC(("CWiaScannerDS::SetSettings(), Setting X Resolution to %d",lValue));
  1274. hr = WIA.WritePropertyLong(WIA_IPS_XRES,lValue);
  1275. break;
  1276. case ICAP_YRESOLUTION:
  1277. DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_YRESOLUTION)"));
  1278. lValue = (LONG)pCap->GetCurrent();
  1279. DBG_TRC(("CWiaScannerDS::SetSettings(), Setting Y Resolution to %d",lValue));
  1280. hr = WIA.WritePropertyLong(WIA_IPS_YRES,lValue);
  1281. break;
  1282. case ICAP_BRIGHTNESS:
  1283. DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_BRIGHTNESS)"));
  1284. lValue = (LONG)pCap->GetCurrent();
  1285. // to do: convert -1000 to 1000 range value in the range specified by the WIA driver
  1286. // and set that to lValue.
  1287. DBG_TRC(("CWiaScannerDS::SetSettings(), Setting WIA_IPS_BRIGHTNESS to %d",lValue));
  1288. break;
  1289. case ICAP_CONTRAST:
  1290. DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_CONTRAST)"));
  1291. lValue = (LONG)pCap->GetCurrent();
  1292. // to do: convert -1000 to 1000 range value in the range specified by the WIA driver
  1293. // and set that to lValue.
  1294. DBG_TRC(("CWiaScannerDS::SetSettings(), Setting WIA_IPS_CONTRAST to %d",lValue));
  1295. break;
  1296. default:
  1297. DBG_TRC(("CWiaScannerDS::SetSettings(), data source is not setting CAPID = %x to WIA device (it is not needed)",pCap->GetCapId()));
  1298. break;
  1299. }
  1300. if (SUCCEEDED(hr)) {
  1301. DBG_TRC(("CWiaScannerDS::SetSettings(), Settings were successfully sent to WIA device"));
  1302. } else {
  1303. DBG_ERR(("CWiaScannerDS::SetSettings(), Settings were unsuccessfully sent to WIA device"));
  1304. return TWRC_FAILURE;
  1305. }
  1306. return TWRC_SUCCESS;
  1307. }
  1308. BOOL CWiaScannerDS::IsUnknownPageLengthDevice()
  1309. {
  1310. DBG_FN_DS(CWiaScannerDS::IsUnknownPageLengthDevice());
  1311. HRESULT hr = S_OK;
  1312. BOOL bIsUnknownPageLengthDevice = FALSE;
  1313. CWiahelper WIA;
  1314. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  1315. if(FAILED(hr)){
  1316. DBG_ERR(("CWiaScannerDS::IsUnknownPageLengthDevice(), failed to set IWiaItem for property reading"));
  1317. return FALSE;
  1318. }
  1319. LONG lYExtent = 0;
  1320. hr = WIA.ReadPropertyLong(WIA_IPS_YEXTENT,&lYExtent);
  1321. if(FAILED(hr)){
  1322. DBG_ERR(("CWiaScannerDS::IsUnknownPageLengthDevice(), failed to read WIA_IPS_YEXTENT"));
  1323. }
  1324. if(SUCCEEDED(hr)){
  1325. if(S_FALSE == hr){ // property does not exist, so we have to support this feature
  1326. bIsUnknownPageLengthDevice = TRUE;
  1327. } else if(S_OK == hr){ // property exists, (need more information, so check the current value)
  1328. if(lYExtent == 0){ // property is set to 0, which means unknown page length is supported
  1329. bIsUnknownPageLengthDevice = TRUE;
  1330. }
  1331. }
  1332. }
  1333. if(bIsUnknownPageLengthDevice){
  1334. DBG_TRC(("CWiaScannerDS::IsUnknownPageLengthDevice(), device is set to do unknown page length"));
  1335. } else {
  1336. DBG_TRC(("CWiaScannerDS::IsUnknownPageLengthDevice(), device is not set to do unknown page length"));
  1337. }
  1338. return bIsUnknownPageLengthDevice;
  1339. }
  1340. BOOL CWiaScannerDS::IsFeederEnabled()
  1341. {
  1342. DBG_FN_DS(CWiaScannerDS::IsFeederEnabled());
  1343. HRESULT hr = S_OK;
  1344. BOOL bIsFeederEnabled = FALSE;
  1345. LONG lDocumentHandlingSelect = 0;
  1346. CWiahelper WIA;
  1347. IWiaItem *pIRootItem = NULL;
  1348. hr = m_pCurrentIWiaItem->GetRootItem(&pIRootItem);
  1349. if (SUCCEEDED(hr)) {
  1350. if (NULL != pIRootItem) {
  1351. hr = WIA.SetIWiaItem(pIRootItem);
  1352. if (FAILED(hr)) {
  1353. DBG_ERR(("CWiaScannerDS::IsFeederEnabled(), failed to set IWiaItem for property reading"));
  1354. }
  1355. if (SUCCEEDED(hr)) {
  1356. hr = WIA.ReadPropertyLong(WIA_DPS_DOCUMENT_HANDLING_SELECT,&lDocumentHandlingSelect);
  1357. if (FAILED(hr)) {
  1358. DBG_ERR(("CWiaScannerDS::IsFeederEnabled(), failed to read WIA_DPS_DOCUMENT_HANDLING_SELECT"));
  1359. }
  1360. if (S_OK == hr) {
  1361. if ((lDocumentHandlingSelect & FEEDER) == FEEDER) {
  1362. bIsFeederEnabled = TRUE;
  1363. }
  1364. } else if (S_FALSE == hr) {
  1365. DBG_WRN(("CWiaScannerDS::IsFeederEnabled(), WIA_DPS_DOCUMENT_HANDLING_SELECT was not found...defaulting to FLATBED"));
  1366. }
  1367. }
  1368. pIRootItem->Release();
  1369. pIRootItem = NULL;
  1370. }
  1371. } else {
  1372. DBG_ERR(("CWiaScannerDS::IsFeederEnabled(), failed to get ROOT IWiaItem from current IWiaItem"));
  1373. }
  1374. return bIsFeederEnabled;
  1375. }
  1376. BOOL CWiaScannerDS::IsFeederEmpty()
  1377. {
  1378. DBG_FN_DS(CWiaScannerDS::IsFeederEmpty());
  1379. HRESULT hr = S_OK;
  1380. BOOL bIsFeederEmpty = TRUE;
  1381. LONG lDocumentHandlingStatus = 0;
  1382. CWiahelper WIA;
  1383. IWiaItem *pIRootItem = NULL;
  1384. hr = m_pCurrentIWiaItem->GetRootItem(&pIRootItem);
  1385. if (SUCCEEDED(hr)) {
  1386. if (NULL != pIRootItem) {
  1387. hr = WIA.SetIWiaItem(pIRootItem);
  1388. if (FAILED(hr)) {
  1389. DBG_ERR(("CWiaScannerDS::IsFeederEmpty(), failed to set IWiaItem for property reading"));
  1390. }
  1391. if (SUCCEEDED(hr)) {
  1392. hr = WIA.ReadPropertyLong(WIA_DPS_DOCUMENT_HANDLING_STATUS,&lDocumentHandlingStatus);
  1393. if (FAILED(hr)) {
  1394. DBG_ERR(("CWiaScannerDS::IsFeederEmpty(), failed to read WIA_DPS_DOCUMENT_HANDLING_STATUS"));
  1395. }
  1396. if (S_OK == hr) {
  1397. if (lDocumentHandlingStatus & FEED_READY) {
  1398. bIsFeederEmpty = FALSE;
  1399. }
  1400. } else if (S_FALSE == hr) {
  1401. DBG_WRN(("CWiaScannerDS::IsFeederEmpty(), WIA_DPS_DOCUMENT_HANDLING_STATUS was not found"));
  1402. }
  1403. }
  1404. pIRootItem->Release();
  1405. pIRootItem = NULL;
  1406. }
  1407. } else {
  1408. DBG_ERR(("CWiaScannerDS::IsFeederEmpty(), failed to get ROOT IWiaItem from current IWiaItem"));
  1409. }
  1410. return bIsFeederEmpty;
  1411. }