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.

3929 lines
148 KiB

  1. #include "precomp.h"
  2. // #define DEBUG_MEMXFER
  3. #define PRIVATE_CAP_ARRAY_PADDING 64 // 64 bytes padding
  4. const TCHAR WIA_STR[] = TEXT("WIA-");
  5. const CHAR* FAMILY_NAME = "Twain Data Source On WIA";
  6. CWiaDataSrc::CWiaDataSrc() :
  7. m_dsState(DS_STATE_0),
  8. m_hMemXferBits(NULL),
  9. m_pMemXferBits(NULL),
  10. m_pDevice(NULL),
  11. m_pIWiaItems(NULL),
  12. m_NumIWiaItems(0),
  13. m_NextIWiaItemIndex(0),
  14. m_NumCaps(0),
  15. m_CapList(NULL),
  16. m_hCachedImageData(NULL),
  17. m_bCacheImage(FALSE)
  18. {
  19. SetTWAINState(DS_STATE_3);
  20. memset(m_FileXferName,0,sizeof(m_FileXferName));
  21. memset(&m_AppIdentity,0,sizeof(m_AppIdentity));
  22. memset(&m_dsIdentity,0, sizeof(m_dsIdentity));
  23. memset(&m_CurFrame, 0,sizeof(m_CurFrame));
  24. memset(&m_CurImageLayout, 0,sizeof(m_CurImageLayout));
  25. memset(&m_MemoryTransferInfo,0,sizeof(m_MemoryTransferInfo));
  26. ResetMemXfer();
  27. m_twStatus.ConditionCode = TWCC_SUCCESS;
  28. m_CurImageLayout.DocumentNumber = 1;
  29. m_CurImageLayout.PageNumber = 1;
  30. m_CurImageLayout.FrameNumber = 1;
  31. m_CurImageLayout.Frame.Top.Whole = 0;
  32. m_CurImageLayout.Frame.Top.Frac = 0;
  33. m_CurImageLayout.Frame.Left.Whole = 0;
  34. m_CurImageLayout.Frame.Left.Frac = 0;
  35. m_CurImageLayout.Frame.Right.Whole = 8;
  36. m_CurImageLayout.Frame.Right.Frac = 5;
  37. m_CurImageLayout.Frame.Bottom.Whole = 11;
  38. m_CurImageLayout.Frame.Bottom.Frac = 0;
  39. m_pCurrentIWiaItem = NULL;
  40. }
  41. CWiaDataSrc::~CWiaDataSrc()
  42. {
  43. ResetMemXfer();
  44. if (m_pDevice){
  45. delete m_pDevice;
  46. m_pDevice = NULL;
  47. }
  48. if (m_pIWiaItems){
  49. delete [] m_pIWiaItems;
  50. m_pIWiaItems = NULL;
  51. }
  52. }
  53. TW_UINT16 CWiaDataSrc::IWiaDataSrc(LPCTSTR DeviceId)
  54. {
  55. if (!DeviceId) {
  56. m_twStatus.ConditionCode = TWCC_BADVALUE;
  57. return TWRC_FAILURE;
  58. }
  59. //
  60. // Initialize m_dsIdentity. This is required because
  61. // DG_CONTROL/DAT_IDENTITY/MSG_GET could be called
  62. // before we are opened.
  63. //
  64. m_pDevice = new CWiaDevice;
  65. if (!m_pDevice) {
  66. m_twStatus.ConditionCode = TWCC_LOWMEMORY;
  67. return TWRC_FAILURE;
  68. }
  69. TCHAR szTempString[MAX_PATH];
  70. memset(szTempString,0,sizeof(szTempString));
  71. HRESULT hr = S_OK;
  72. hr = m_pDevice->Initialize(DeviceId);
  73. if (FAILED(hr)) {
  74. m_twStatus.ConditionCode = TWCC_LOWMEMORY;
  75. delete m_pDevice;
  76. m_pDevice = NULL;
  77. DBG_ERR(("CWiaDataSrc::IWiaDataSrc(), WIA Device object Initialize failed"));
  78. return TWRC_FAILURE;
  79. }
  80. //
  81. // We don't need to attach a callback here because we will
  82. // close the device after we are done with it.
  83. //
  84. if (SUCCEEDED(hr)) {
  85. m_dsIdentity.Id = 0;
  86. m_dsIdentity.Version.MajorNum = 1;
  87. m_dsIdentity.Version.MinorNum = 0;
  88. m_dsIdentity.Version.Language = TWLG_USA;
  89. m_dsIdentity.Version.Country = TWCY_USA;
  90. m_dsIdentity.ProtocolMajor = TWON_PROTOCOLMAJOR;
  91. m_dsIdentity.ProtocolMinor = TWON_PROTOCOLMINOR;
  92. m_dsIdentity.SupportedGroups = DG_CONTROL | DG_IMAGE;
  93. lstrcpyA(m_dsIdentity.Version.Info,"26 June 2000");
  94. //
  95. // Use a specific product family name so that applications
  96. // can differentiate between a data source on WIA and
  97. // a *pure* TWAIN data source
  98. //
  99. lstrcpyA(m_dsIdentity.ProductFamily, FAMILY_NAME);
  100. lstrcpyA(m_dsIdentity.ProductName, "UnknownProduct");
  101. lstrcpyA(m_dsIdentity.Manufacturer, "UnknownMfg");
  102. #ifdef UNICODE
  103. //
  104. // UNICODE specific
  105. //
  106. // This assumes that ProductName, FamilyName and Manufacturer
  107. // are all in TW_STR32 (TWAIN data type for a string).
  108. //
  109. UINT Len = 0;
  110. memset(szTempString,0,sizeof(szTempString));
  111. hr = m_pDevice->GetDeviceDesc(szTempString,sizeof(szTempString),&Len);
  112. if (SUCCEEDED(hr)) {
  113. //
  114. // Add "WIA-" to beginning of ProductName string, to separate
  115. // TWAIN installed data sources, from WIA data sources
  116. //
  117. AddWIAPrefixToString(szTempString,sizeof(szTempString));
  118. Len += lstrlen(WIA_STR); // add prefix size to length
  119. //
  120. // set ProductName in TW_IDENTITY structure
  121. //
  122. WideCharToMultiByte(CP_ACP, 0, szTempString, Len + 1,m_dsIdentity.ProductName,
  123. (sizeof(m_dsIdentity.ProductName)/sizeof(m_dsIdentity.ProductName[0])),NULL, NULL);
  124. Len = 0;
  125. } else {
  126. DBG_ERR(("CWiaDataSrc::IWiaDataSrc(), GetDeviceDesc failed"));
  127. return TWRC_FAILURE;
  128. }
  129. memset(szTempString,0,sizeof(szTempString));
  130. hr = m_pDevice->GetDeviceVendorName(szTempString,sizeof(szTempString),&Len);
  131. if (SUCCEEDED(hr)) {
  132. //
  133. // set Manufacturer in TW_IDENTITY structure
  134. //
  135. WideCharToMultiByte(CP_ACP, 0, szTempString, Len + 1,m_dsIdentity.Manufacturer,
  136. (sizeof(m_dsIdentity.Manufacturer)/sizeof(m_dsIdentity.Manufacturer[0])),NULL, NULL);
  137. } else {
  138. DBG_ERR(("CWiaDataSrc::IWiaDataSrc(), GetDeviceVendorName failed"));
  139. return TWRC_FAILURE;
  140. }
  141. #else
  142. //
  143. // ANSI specific
  144. //
  145. memset(szTempString,0,sizeof(szTempString));
  146. hr = m_pDevice->GetDeviceDesc(szTempString,sizeof(szTempString),NULL);
  147. if (SUCCEEDED(hr) ) {
  148. //
  149. // Add "WIA-" to beginning of ProductName string, to separate
  150. // TWAIN installed data sources, from WIA data sources
  151. //
  152. AddWIAPrefixToString(szTempString,sizeof(szTempString));
  153. //
  154. // set ProductName in TW_IDENTITY structure
  155. //
  156. strncpy(m_dsIdentity.ProductName,szTempString,sizeof(TW_STR32) - 1);
  157. } else {
  158. DBG_ERR(("CWiaDataSrc::IWiaDataSrc(),GetDeviceDesc failed"));
  159. return TWRC_FAILURE;
  160. }
  161. memset(szTempString,0,sizeof(szTempString));
  162. hr = m_pDevice->GetDeviceVendorName(szTempString,sizeof(szTempString),NULL);
  163. if (SUCCEEDED(hr) ) {
  164. //
  165. // set Manufacturer in TW_IDENTITY structure
  166. //
  167. strncpy(m_dsIdentity.Manufacturer,szTempString,sizeof(TW_STR32) - 1);
  168. } else {
  169. DBG_ERR(("CWiaDataSrc::IWiaDataSrc(),GetDeviceVendorName failed"));
  170. }
  171. #endif
  172. }
  173. return(SUCCEEDED(hr)) ? TWRC_SUCCESS : TWRC_FAILURE;
  174. }
  175. TW_UINT16 CWiaDataSrc::AddWIAPrefixToString(LPTSTR szString,UINT uSize)
  176. {
  177. TCHAR szTempBuffer[512];
  178. memset(szTempBuffer,0,sizeof(szTempBuffer));
  179. _sntprintf(szTempBuffer,(sizeof(szTempBuffer)/sizeof(szTempBuffer[0])),TEXT("%s%s"),WIA_STR,szString);
  180. szTempBuffer[(sizeof(szTempBuffer)/sizeof(szTempBuffer[0])) - 1] = 0;
  181. //
  182. // copy, and truncate New string to TWAIN's required
  183. // restricted size.
  184. //
  185. memset(szString,0,uSize);
  186. #ifdef UNICODE
  187. wcsncpy(szString,szTempBuffer,(sizeof(TW_STR32) - 1));
  188. #else
  189. strncpy(szString,szTempBuffer,(sizeof(TW_STR32) - 1));
  190. #endif
  191. return TWRC_SUCCESS;
  192. }
  193. TW_UINT16 CWiaDataSrc::DSEntry(pTW_IDENTITY pOrigin,TW_UINT32 DG,TW_UINT16 DAT,
  194. TW_UINT16 MSG,TW_MEMREF pData)
  195. {
  196. TWAIN_MSG twMsg;
  197. twMsg.AppId = pOrigin;
  198. twMsg.DG = DG;
  199. twMsg.DAT = DAT;
  200. twMsg.MSG = MSG;
  201. twMsg.pData = pData;
  202. TW_UINT16 twRc = TWRC_SUCCESS;
  203. if (MSG_PROCESSEVENT == MSG) {
  204. //
  205. // Since we rely on WIA UI to provide the user interface and since
  206. // the WIA UI is a modal dialog box(meaning it has its own
  207. // messge loop), every event we receive here is not DS event.
  208. //
  209. //((TW_EVENT*)twMsg.pData)->TWMessage = MSG_NULL;
  210. twRc = TWRC_NOTDSEVENT;
  211. } else {
  212. //
  213. // Dispatch message based on group
  214. //
  215. switch (twMsg.DG) {
  216. case DG_CONTROL:
  217. twRc = DispatchControlMsg(&twMsg);
  218. break;
  219. case DG_IMAGE:
  220. twRc = DispatchImageMsg(&twMsg);
  221. break;
  222. default:
  223. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  224. twRc = TWRC_FAILURE;
  225. break;
  226. }
  227. DBG_TRC(("Sent to TWAIN Application, DG = %X, DT = %X, MSG = %X, ( TWRC = %X, TWCC = %X)",DG,DAT,MSG,twRc,m_twStatus.ConditionCode));
  228. }
  229. return twRc;
  230. }
  231. #ifdef _USE_NONSPRINTF_CONVERSION
  232. float CWiaDataSrc::Fix32ToFloat(TW_FIX32 fix32)
  233. {
  234. float ffloat = 0.0f;
  235. //
  236. // TWAIN spec implementation
  237. //
  238. ffloat = (float)fix32.Whole + (float)fix32.Frac / 65536.0f;
  239. /*
  240. //
  241. // original implementation
  242. //
  243. int iexp = 1;
  244. int frac = fix32.Frac;
  245. while(frac/10 > 0){
  246. iexp++;
  247. frac = (frac/10);
  248. }
  249. ffloat = (float)fix32.Whole + (float) ( (float) fix32.Frac / (float) pow(10,iexp));
  250. */
  251. return ffloat;
  252. }
  253. TW_FIX32 CWiaDataSrc::FloatToFix32(float ffloat)
  254. {
  255. TW_FIX32 fix32;
  256. memset(&fix32,0,sizeof(fix32));
  257. //
  258. // TWAIN spec implementation
  259. //
  260. TW_INT32 value = (TW_INT32) (ffloat * 65536.0f + 0.5f);
  261. fix32.Whole = (TW_INT16)(value >> 16);
  262. fix32.Frac = (TW_UINT16)(value & 0x0000ffffL);
  263. /*
  264. //
  265. // original implementation
  266. //
  267. fix32.Whole = (TW_INT16)ffloat;
  268. //float fVal = -((float)fix32.Whole - ffloat);
  269. float fVal = (ffloat - (float)fix32.Whole);
  270. fVal = (fVal * 100000.0f);
  271. fix32.Frac = (TW_UINT16)(fVal);
  272. */
  273. return fix32;
  274. }
  275. #else // _USE_NONSPRINTF_CONVERSION
  276. TW_FIX32 CWiaDataSrc::FloatToFix32(float f)
  277. {
  278. char fstr[64];
  279. memset(fstr,0,sizeof(fstr));
  280. char *p = NULL;
  281. TW_FIX32 f32;
  282. memset(&f32,0,sizeof(f32));
  283. sprintf(fstr, "%f", f);
  284. p = strchr(fstr, '.');
  285. if (p != NULL) {
  286. *p = '\0';
  287. f32.Whole = (TW_INT16)atoi(fstr);
  288. f32.Frac = (TW_UINT16)atoi(p + 1);
  289. }
  290. return f32;
  291. }
  292. float CWiaDataSrc::Fix32ToFloat(TW_FIX32 fix32)
  293. {
  294. // (full precision)
  295. char fstr[64];
  296. memset(fstr,0,sizeof(fstr));
  297. float fReturnValue = 0.0f;
  298. sprintf(fstr,"%d.%d",fix32.Whole,fix32.Frac);
  299. sscanf(fstr,"%f",&fReturnValue);
  300. // original (loses precision)
  301. // fReturnValue = (float)fix32.Whole + (float)(fix32.Frac / 65536.0);
  302. return fReturnValue;
  303. }
  304. #endif // _USE_NONSPRINTF_CONVERSION
  305. void CWiaDataSrc::NotifyCloseReq()
  306. {
  307. DBG_FN_DS(CWiaDataSrc::NotifyCloseReq());
  308. if(m_DSM.Notify(&m_dsIdentity, &m_AppIdentity,
  309. (TW_UINT32)DG_CONTROL, DAT_NULL,MSG_CLOSEDSREQ, (TW_MEMREF)NULL)){
  310. DBG_TRC(("CWiaDataSrc::NotifyCloseReq(), MSG_CLOSEDSREQ is sent to application"));
  311. } else {
  312. DBG_WRN(("CWiaDataSrc::NotifyCloseReq(), could not notify application for MSG_CLOSEDSREQ"));
  313. }
  314. }
  315. void CWiaDataSrc::NotifyXferReady()
  316. {
  317. DBG_FN_DS(CWiaDataSrc::NotifyXferReady());
  318. if (m_DSM.Notify(&m_dsIdentity,&m_AppIdentity,
  319. (TW_UINT32)DG_CONTROL,DAT_NULL,MSG_XFERREADY,(TW_MEMREF)NULL)) {
  320. DBG_TRC(("CWiaDataSrc::NotifyXferReady(), MSG_XFERREADY is sent to application"));
  321. //
  322. // transition to STATE_6
  323. //
  324. SetTWAINState(DS_STATE_6);
  325. } else {
  326. DBG_WRN(("CWiaDataSrc::NotifyXferReady(), could not notify application for MSG_XFERREADY"));
  327. }
  328. }
  329. void CWiaDataSrc::ResetMemXfer()
  330. {
  331. DBG_FN_DS(CWiaDataSrc::ResetMemXfer());
  332. if (IS_VALID_HANDLE(m_hMemXferBits)) {
  333. if (m_pMemXferBits) {
  334. if (GlobalUnlock(m_hMemXferBits)) {
  335. m_pMemXferBits = NULL;
  336. }
  337. }
  338. // Now free block always
  339. GlobalFree(m_hMemXferBits);
  340. }
  341. m_hMemXferBits = NULL;
  342. m_hCachedImageData = NULL;
  343. m_LinesTransferred = 0;
  344. }
  345. TW_UINT16 CWiaDataSrc::DispatchControlMsg(PTWAIN_MSG ptwMsg)
  346. {
  347. TW_UINT16 twRc = TWRC_SUCCESS;
  348. if (!ptwMsg) {
  349. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  350. return TWRC_FAILURE;
  351. }
  352. switch (ptwMsg->DAT) {
  353. case DAT_IDENTITY:
  354. twRc = OnIdentityMsg(ptwMsg);
  355. break;
  356. case DAT_USERINTERFACE:
  357. twRc = OnUserInterfaceMsg(ptwMsg);
  358. break;
  359. case DAT_CAPABILITY:
  360. twRc = OnCapabilityMsg(ptwMsg);
  361. break;
  362. case DAT_STATUS:
  363. twRc = OnStatusMsg(ptwMsg);
  364. break;
  365. case DAT_PENDINGXFERS:
  366. twRc = OnPendingXfersMsg(ptwMsg);
  367. break;
  368. case DAT_SETUPMEMXFER:
  369. twRc = OnSetupMemXferMsg(ptwMsg);
  370. break;
  371. case DAT_SETUPFILEXFER:
  372. twRc = OnSetupFileXferMsg(ptwMsg);
  373. break;
  374. case DAT_XFERGROUP:
  375. twRc = OnXferGroupMsg(ptwMsg);
  376. break;
  377. default:
  378. twRc = TWRC_FAILURE;
  379. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  380. }
  381. return twRc;
  382. }
  383. TW_UINT16 CWiaDataSrc::DispatchImageMsg(PTWAIN_MSG ptwMsg)
  384. {
  385. TW_UINT16 twRc = TWRC_SUCCESS;
  386. if (!ptwMsg) {
  387. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  388. return TWRC_FAILURE;
  389. }
  390. switch (ptwMsg->DAT) {
  391. case DAT_IMAGEINFO:
  392. twRc = OnImageInfoMsg(ptwMsg);
  393. break;
  394. case DAT_IMAGELAYOUT:
  395. twRc = OnImageLayoutMsg(ptwMsg);
  396. break;
  397. case DAT_IMAGEMEMXFER:
  398. twRc = OnImageMemXferMsg(ptwMsg);
  399. break;
  400. case DAT_IMAGENATIVEXFER:
  401. twRc = OnImageNativeXferMsg(ptwMsg);
  402. break;
  403. case DAT_IMAGEFILEXFER:
  404. twRc = OnImageFileXferMsg(ptwMsg);
  405. break;
  406. case DAT_PALETTE8:
  407. twRc = OnPalette8Msg(ptwMsg);
  408. break;
  409. case DAT_GRAYRESPONSE:
  410. twRc = OnGrayResponseMsg(ptwMsg);
  411. break;
  412. case DAT_RGBRESPONSE:
  413. twRc = OnRGBResponseMsg(ptwMsg);
  414. break;
  415. case DAT_CIECOLOR:
  416. twRc = OnCIEColorMsg(ptwMsg);;
  417. break;
  418. case DAT_JPEGCOMPRESSION:
  419. twRc = OnJPEGCompressionMsg(ptwMsg);
  420. break;
  421. default:
  422. twRc = TWRC_FAILURE;
  423. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  424. }
  425. return twRc;
  426. }
  427. TW_UINT16 CWiaDataSrc::OnPalette8Msg(PTWAIN_MSG ptwMsg)
  428. {
  429. DBG_FN_DS(CWiaDataSrc::OnPalette8Msg());
  430. TW_UINT16 twRc = TWRC_SUCCESS;
  431. switch (GetTWAINState()) {
  432. case DS_STATE_4:
  433. case DS_STATE_5:
  434. case DS_STATE_6:
  435. case DS_STATE_7:
  436. switch (ptwMsg->MSG) {
  437. case MSG_GET:
  438. // TWPA_RGB - color palette
  439. // TWPA_GRAY - grayscale palette
  440. // TWPA_CMY - CMY palette
  441. ((TW_PALETTE8 *)ptwMsg->pData)->NumColors = 0;
  442. ((TW_PALETTE8 *)ptwMsg->pData)->PaletteType = TWPA_RGB;
  443. break;
  444. case MSG_GETDEFAULT:
  445. case MSG_RESET:
  446. case MSG_SET:
  447. break;
  448. default:
  449. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  450. twRc = TWRC_FAILURE;
  451. DSError();
  452. }
  453. break;
  454. default:
  455. m_twStatus.ConditionCode = TWCC_SEQERROR;
  456. twRc = TWRC_FAILURE;
  457. DSError();
  458. break;
  459. }
  460. return twRc;
  461. }
  462. TW_UINT16 CWiaDataSrc::OnSetupMemXferMsg(PTWAIN_MSG ptwMsg)
  463. {
  464. DBG_FN_DS(CWiaDataSrc::OnSetupMemXferMsg());
  465. TW_UINT16 twRc = TWRC_SUCCESS;
  466. TW_SETUPMEMXFER *pMemSetup = (TW_SETUPMEMXFER *)ptwMsg->pData;
  467. switch (GetTWAINState()) {
  468. case DS_STATE_4:
  469. case DS_STATE_5:
  470. case DS_STATE_6:
  471. if (MSG_GET == ptwMsg->MSG) {
  472. if (pMemSetup) {
  473. pMemSetup->MinBufSize = MIN_MEMXFER_SIZE;
  474. pMemSetup->MaxBufSize = MAX_MEMXFER_SIZE;
  475. pMemSetup->Preferred = PREFERRED_MEMXFER_SIZE;
  476. } else {
  477. m_twStatus.ConditionCode = TWCC_BADVALUE;
  478. twRc = TWRC_FAILURE;
  479. }
  480. } else {
  481. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  482. twRc = TWRC_FAILURE;
  483. DSError();
  484. }
  485. break;
  486. default:
  487. m_twStatus.ConditionCode = TWCC_SEQERROR;
  488. twRc = TWRC_FAILURE;
  489. DSError();
  490. break;
  491. }
  492. return twRc;
  493. }
  494. TW_UINT16 CWiaDataSrc::OnSetupFileXferMsg(PTWAIN_MSG ptwMsg)
  495. {
  496. DBG_FN_DS(CWiaDataSrc::OnSetupFileXferMsg());
  497. TW_UINT16 twRc = TWRC_SUCCESS;
  498. CCap *pImageXferCap = NULL;
  499. TW_SETUPFILEXFER *pFileXfer = NULL;
  500. switch (GetTWAINState()) {
  501. case DS_STATE_4:
  502. case DS_STATE_5:
  503. case DS_STATE_6:
  504. pFileXfer = (TW_SETUPFILEXFER *)ptwMsg->pData;
  505. pImageXferCap = FindCap(ICAP_IMAGEFILEFORMAT);
  506. switch (ptwMsg->MSG) {
  507. case MSG_GET:
  508. case MSG_GETDEFAULT:
  509. case MSG_GETCURRENT:
  510. if (pImageXferCap) {
  511. pFileXfer->Format = (TW_UINT16)pImageXferCap->GetCurrent();
  512. pFileXfer->VRefNum = 0;
  513. pFileXfer->FileName[0] = 0;
  514. strcpy(pFileXfer->FileName, m_FileXferName);
  515. } else {
  516. twRc = TWRC_FAILURE;
  517. m_twStatus.ConditionCode = TWCC_BUMMER;
  518. }
  519. break;
  520. case MSG_SET:
  521. {
  522. strcpy(m_FileXferName, pFileXfer->FileName);
  523. pImageXferCap->SetCurrent((VOID*)&pFileXfer->Format);
  524. }
  525. break;
  526. default:
  527. twRc = TWRC_FAILURE;
  528. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  529. DSError();
  530. break;
  531. }
  532. break;
  533. default:
  534. twRc = TWRC_FAILURE;
  535. m_twStatus.ConditionCode = TWCC_SEQERROR;
  536. DSError();
  537. break;
  538. }
  539. return twRc;
  540. }
  541. TW_UINT16 CWiaDataSrc::OnXferGroupMsg(PTWAIN_MSG ptwMsg)
  542. {
  543. DBG_FN_DS(CWiaDataSrc::OnXferGroupMsg());
  544. TW_UINT16 twRc = TWRC_SUCCESS;
  545. switch (GetTWAINState()) {
  546. case DS_STATE_4:
  547. case DS_STATE_5:
  548. case DS_STATE_6:
  549. switch (ptwMsg->MSG) {
  550. case MSG_GET:
  551. case MSG_GETDEFAULT:
  552. case MSG_GETCURRENT:
  553. case MSG_RESET:
  554. *((TW_UINT16 *)ptwMsg->pData) = DG_IMAGE;
  555. break;
  556. case MSG_SET:
  557. break;
  558. default:
  559. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  560. twRc = TWRC_FAILURE;
  561. DSError();
  562. break;
  563. }
  564. break;
  565. default:
  566. m_twStatus.ConditionCode = TWCC_SEQERROR;
  567. twRc = TWRC_FAILURE;
  568. DSError();
  569. break;
  570. }
  571. return twRc;
  572. }
  573. TW_UINT16 CWiaDataSrc::OnImageInfoMsg(PTWAIN_MSG ptwMsg)
  574. {
  575. DBG_FN_DS(CWiaDataSrc::OnImageInfoMsg());
  576. TW_UINT16 twRc = TWRC_FAILURE;
  577. TW_IMAGEINFO *ptwImageInfo = NULL;
  578. if (DS_STATE_6 == GetTWAINState()) {
  579. if (MSG_GET == ptwMsg->MSG) {
  580. ptwImageInfo = (TW_IMAGEINFO *)ptwMsg->pData;
  581. HRESULT hr = S_OK;
  582. hr = m_pDevice->GetImageInfo(m_pCurrentIWiaItem, &m_MemoryTransferInfo);
  583. if (SUCCEEDED(hr)) {
  584. ptwImageInfo->ImageWidth = (TW_INT32)m_MemoryTransferInfo.mtiWidthPixels;
  585. ptwImageInfo->ImageLength = (TW_INT32)m_MemoryTransferInfo.mtiHeightPixels;
  586. ptwImageInfo->BitsPerPixel = (TW_INT16)m_MemoryTransferInfo.mtiBitsPerPixel;
  587. ptwImageInfo->SamplesPerPixel = (TW_INT16)m_MemoryTransferInfo.mtiNumChannels;
  588. ptwImageInfo->Planar = (TW_BOOL)m_MemoryTransferInfo.mtiPlanar;
  589. //
  590. // adjust height for unknown length acquisitions
  591. //
  592. if(ptwImageInfo->ImageLength == 0){
  593. DBG_WRN(("CWiaDataSrc::OnImageInfoMsg(), Possible unknown length device detected..checking cached height value"));
  594. ptwImageInfo->ImageLength = m_ImageHeight;
  595. if(ptwImageInfo->ImageLength == 0){
  596. DBG_WRN(("CWiaDataSrc::OnImageInfoMsg(), no cached height available, defaulting to -1 (ICAP_UNDEFINEDIMAGESIZE support only)"));
  597. ptwImageInfo->ImageLength = -1; // unknown page length (only valid if TWAIN applications support ICAP_UNDEFINEDIMAGESIZE)
  598. } else {
  599. DBG_TRC(("CWiaDataSrc::OnImageInfoMsg(), new height = %d",ptwImageInfo->ImageLength));
  600. }
  601. }
  602. //
  603. // set PixelType to corresponding TWAIN pixel type
  604. //
  605. switch(m_MemoryTransferInfo.mtiDataType) {
  606. case WIA_DATA_THRESHOLD:
  607. ptwImageInfo->PixelType = TWPT_BW;
  608. break;
  609. case WIA_DATA_GRAYSCALE:
  610. ptwImageInfo->PixelType = TWPT_GRAY;
  611. break;
  612. case WIA_DATA_COLOR:
  613. default:
  614. ptwImageInfo->PixelType = TWPT_RGB;
  615. break;
  616. }
  617. //
  618. // set compression to NONE
  619. //
  620. ptwImageInfo->Compression = TWCP_NONE;
  621. //
  622. // Unit conversion.......
  623. //
  624. ptwImageInfo->XResolution = FloatToFix32((float)m_MemoryTransferInfo.mtiXResolution);
  625. ptwImageInfo->YResolution = FloatToFix32((float)m_MemoryTransferInfo.mtiYResolution);
  626. twRc = TWRC_SUCCESS;
  627. } else {
  628. m_twStatus.ConditionCode = TWCC_OPERATIONERROR;
  629. twRc = TWRC_FAILURE;
  630. }
  631. if (TWRC_SUCCESS == twRc) {
  632. DBG_TRC(("CWiaDataSrc::OnImageInfoMsg(), Reported Image Information from data source"));
  633. DBG_TRC(("XResolution = %d.%d",ptwImageInfo->XResolution.Whole,ptwImageInfo->XResolution.Frac));
  634. DBG_TRC(("YResolution = %d.%d",ptwImageInfo->YResolution.Whole,ptwImageInfo->YResolution.Frac));
  635. DBG_TRC(("ImageWidth = %d",ptwImageInfo->ImageWidth));
  636. DBG_TRC(("ImageLength = %d",ptwImageInfo->ImageLength));
  637. DBG_TRC(("SamplesPerPixel = %d",ptwImageInfo->SamplesPerPixel));
  638. memset(ptwImageInfo->BitsPerSample,0,sizeof(ptwImageInfo->BitsPerSample));
  639. if (ptwImageInfo->BitsPerPixel < 24) {
  640. ptwImageInfo->BitsPerSample[0] = ptwImageInfo->BitsPerPixel;
  641. } else {
  642. for (int i = 0; i < ptwImageInfo->SamplesPerPixel; i++) {
  643. ptwImageInfo->BitsPerSample[i] = (ptwImageInfo->BitsPerPixel/ptwImageInfo->SamplesPerPixel);
  644. }
  645. }
  646. // (bpp / spp) = bps
  647. DBG_TRC(("BitsPerSample = [%d],[%d],[%d],[%d],[%d],[%d],[%d],[%d]",ptwImageInfo->BitsPerSample[0],
  648. ptwImageInfo->BitsPerSample[1],
  649. ptwImageInfo->BitsPerSample[2],
  650. ptwImageInfo->BitsPerSample[3],
  651. ptwImageInfo->BitsPerSample[4],
  652. ptwImageInfo->BitsPerSample[5],
  653. ptwImageInfo->BitsPerSample[6],
  654. ptwImageInfo->BitsPerSample[7]));
  655. DBG_TRC(("BitsPerPixel = %d",ptwImageInfo->BitsPerPixel));
  656. DBG_TRC(("Planar = %d",ptwImageInfo->Planar));
  657. DBG_TRC(("PixelType = %d",ptwImageInfo->PixelType));
  658. DBG_TRC(("Compression = %d",ptwImageInfo->Compression));
  659. }
  660. } else {
  661. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  662. twRc = TWRC_FAILURE;
  663. }
  664. } else {
  665. m_twStatus.ConditionCode = TWCC_SEQERROR;
  666. twRc = TWRC_FAILURE;
  667. }
  668. if (TWRC_SUCCESS != twRc) {
  669. DSError();
  670. }
  671. return twRc;
  672. }
  673. TW_UINT16 CWiaDataSrc::OnImageLayoutMsg(PTWAIN_MSG ptwMsg)
  674. {
  675. m_twStatus.ConditionCode = TWCC_BUMMER;
  676. return TWRC_FAILURE;
  677. }
  678. TW_UINT16 CWiaDataSrc::OnGrayResponseMsg(PTWAIN_MSG ptwMsg)
  679. {
  680. m_twStatus.ConditionCode = TWCC_BUMMER;
  681. return TWRC_FAILURE;
  682. }
  683. TW_UINT16 CWiaDataSrc::OnRGBResponseMsg(PTWAIN_MSG ptwMsg)
  684. {
  685. m_twStatus.ConditionCode = TWCC_BUMMER;
  686. return TWRC_FAILURE;
  687. }
  688. TW_UINT16 CWiaDataSrc::OnCIEColorMsg(PTWAIN_MSG ptwMsg)
  689. {
  690. m_twStatus.ConditionCode = TWCC_BUMMER;
  691. return TWRC_FAILURE;
  692. }
  693. TW_UINT16 CWiaDataSrc::OnJPEGCompressionMsg(PTWAIN_MSG ptwMsg)
  694. {
  695. m_twStatus.ConditionCode = TWCC_BUMMER;
  696. return TWRC_FAILURE;
  697. }
  698. TW_UINT16 CWiaDataSrc::OnIdentityMsg(PTWAIN_MSG ptwMsg)
  699. {
  700. DBG_FN_DS(CWiaDataSrc::OnIdentityMsg());
  701. TW_UINT16 twRc = TWRC_SUCCESS;
  702. if (ptwMsg) {
  703. switch (ptwMsg->MSG) {
  704. case MSG_OPENDS:
  705. #ifdef DEBUG_ME
  706. MessageBox(NULL,TEXT("MSG_OPENDS - Attach me to a debugger"),TEXT("Attach me to a debugger"),MB_OK);
  707. #endif
  708. twRc = OpenDS(ptwMsg);
  709. break;
  710. case MSG_CLOSEDS:
  711. twRc = CloseDS(ptwMsg);
  712. break;
  713. case MSG_GET:
  714. if (!IsBadWritePtr(ptwMsg->pData, sizeof(TW_IDENTITY))) {
  715. *(TW_IDENTITY*)ptwMsg->pData = m_dsIdentity;
  716. DBG_TRC(("CWiaDataSrc::OnIdentityMsg(), Reported TW_IDENTITY from data source"));
  717. DBG_TRC(("Id = %d",m_dsIdentity.Id));
  718. DBG_TRC(("Manufacturer = %s",m_dsIdentity.Manufacturer));
  719. DBG_TRC(("ProductFamily = %s",m_dsIdentity.ProductFamily));
  720. DBG_TRC(("ProductName = %s",m_dsIdentity.ProductName));
  721. DBG_TRC(("ProtocolMajor = %d",m_dsIdentity.ProtocolMajor));
  722. DBG_TRC(("ProtocolMinor = %d",m_dsIdentity.ProtocolMinor));
  723. DBG_TRC(("SupportedGrps = %d",m_dsIdentity.SupportedGroups));
  724. DBG_TRC(("Ver Country = %d",m_dsIdentity.Version.Country));
  725. DBG_TRC(("Ver Info = %s",m_dsIdentity.Version.Info));
  726. DBG_TRC(("Ver Language = %d",m_dsIdentity.Version.Language));
  727. DBG_TRC(("Ver MajorNum = %d",m_dsIdentity.Version.MajorNum));
  728. DBG_TRC(("Ver MinorNum = %d",m_dsIdentity.Version.MinorNum));
  729. twRc = TWRC_SUCCESS;
  730. } else {
  731. twRc = TWCC_BADVALUE;
  732. }
  733. break;
  734. default:
  735. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  736. twRc = TWRC_FAILURE;
  737. DSError();
  738. break;
  739. }
  740. }
  741. return twRc;
  742. }
  743. TW_UINT16 CWiaDataSrc::OnUserInterfaceMsg(PTWAIN_MSG ptwMsg)
  744. {
  745. DBG_FN_DS(CWiaDataSrc::OnUserInterfaceMsg());
  746. TW_UINT16 twRc = TWRC_SUCCESS;
  747. switch (ptwMsg->MSG) {
  748. case MSG_ENABLEDS:
  749. switch (GetTWAINState()) {
  750. case DS_STATE_5:
  751. case DS_STATE_6:
  752. case DS_STATE_7:
  753. m_twStatus.ConditionCode = TWCC_SEQERROR;
  754. twRc = TWRC_FAILURE;
  755. break;
  756. default:
  757. twRc = EnableDS((TW_USERINTERFACE*)ptwMsg->pData);
  758. break;
  759. }
  760. break;
  761. case MSG_DISABLEDS:
  762. twRc = DisableDS((TW_USERINTERFACE*)ptwMsg->pData);
  763. break;
  764. default:
  765. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  766. twRc = TWRC_FAILURE;
  767. DSError();
  768. break;
  769. }
  770. return twRc;
  771. }
  772. TW_UINT16 CWiaDataSrc::OnCapabilityMsg(PTWAIN_MSG ptwMsg)
  773. {
  774. DBG_FN_DS(CWiaDataSrc::OnCapabilityMsg());
  775. TW_UINT16 twRc = TWRC_SUCCESS;
  776. TW_UINT16 twCC = TWCC_SUCCESS;
  777. TW_CAPABILITY *ptwCap = (TW_CAPABILITY *)ptwMsg->pData;
  778. if (!ptwCap) {
  779. m_twStatus.ConditionCode = TWCC_BADCAP;
  780. return TWRC_FAILURE;
  781. }
  782. if (CAP_SUPPORTEDCAPS == ptwCap->Cap) {
  783. switch(ptwMsg->MSG) {
  784. case MSG_SET:
  785. case MSG_RESET:
  786. {
  787. //
  788. // MSG_SET, MSG_RESET shouldn't be able to be called on CAP_SUPPORTEDCAPS!!
  789. //
  790. twRc = TWRC_FAILURE;
  791. m_twStatus.ConditionCode = TWCC_CAPBADOPERATION;
  792. return twRc;
  793. }
  794. default:
  795. break;
  796. }
  797. //
  798. // get number of PRIVATE TWAIN capabilities from WIA driver
  799. // and add them to our CAP_SUPPORTEDCAPS list.
  800. //
  801. LONG lNumPrivateCaps = 0;
  802. LONG *pPrivateCapArray = NULL;
  803. lNumPrivateCaps = GetPrivateSupportedCapsFromWIADevice(&pPrivateCapArray);
  804. ptwCap->ConType = TWON_ARRAY;
  805. ptwCap->hContainer = GlobalAlloc(GHND, sizeof(TW_ARRAY) + sizeof(TW_UINT16) * (m_NumCaps + lNumPrivateCaps) );
  806. if (ptwCap->hContainer) {
  807. TW_ARRAY *pCapIdArray = (TW_ARRAY *) GlobalLock(ptwCap->hContainer);
  808. if (pCapIdArray) {
  809. TW_UINT32 i = 0;
  810. pCapIdArray->ItemType = TWTY_UINT16;
  811. TW_UINT16 *ItemList;
  812. ItemList = (TW_UINT16 *)pCapIdArray->ItemList;
  813. //
  814. // fill in TWAIN compat layer's supported CAPS first
  815. //
  816. for (i = 0; i < m_NumCaps; i++) {
  817. ItemList[i] = m_CapList[i].GetCapId();
  818. }
  819. //
  820. // fill in WIA driver's private supported CAPS next
  821. //
  822. int PrivateCapIndex = 0;
  823. for(i = m_NumCaps; i < (m_NumCaps + lNumPrivateCaps);i++){
  824. ItemList[i] = (TW_UINT16)pPrivateCapArray[PrivateCapIndex];
  825. DBG_TRC(("(%d) Private Capability ID reported = %x",(PrivateCapIndex + 1), ItemList[i]));
  826. PrivateCapIndex++;
  827. }
  828. //
  829. // finally set NumItems
  830. //
  831. pCapIdArray->NumItems = (m_NumCaps + lNumPrivateCaps);
  832. GlobalUnlock(ptwCap->hContainer);
  833. } else {
  834. GlobalFree(ptwCap->hContainer);
  835. ptwCap->hContainer = NULL;
  836. twRc = TWRC_FAILURE;
  837. m_twStatus.ConditionCode = TWCC_LOWMEMORY;
  838. }
  839. } else {
  840. twRc = TWRC_FAILURE;
  841. m_twStatus.ConditionCode = TWCC_LOWMEMORY;
  842. }
  843. //
  844. // delete Private capability array, if it was allocated
  845. //
  846. if(pPrivateCapArray){
  847. GlobalFree(pPrivateCapArray);
  848. pPrivateCapArray = NULL;
  849. }
  850. return twRc;
  851. }
  852. CCap *pCap = FindCap(ptwCap->Cap);
  853. if (!pCap) {
  854. DBG_TRC(("Couldn't find the CCap object for CAP ID %x in TWAIN Compat layer CAP list, try WIA driver's private TWAIN cap list", ptwCap->Cap));
  855. if (m_pDevice->TwainCapabilityPassThrough()) {
  856. return OnPrivateCapabilityMsg(ptwMsg);
  857. } else {
  858. m_twStatus.ConditionCode = TWCC_BADCAP;
  859. return TWRC_FAILURE;
  860. }
  861. }
  862. switch (ptwMsg->MSG) {
  863. case MSG_GET:
  864. if(ptwCap->Cap == ICAP_IMAGEDATASET)
  865. twCC = pCap->GetCurrent(ptwCap);
  866. else
  867. twCC = pCap->Get(ptwCap);
  868. break;
  869. case MSG_GETDEFAULT:
  870. twCC = pCap->GetDefault(ptwCap);
  871. break;
  872. case MSG_GETCURRENT:
  873. twCC = pCap->GetCurrent(ptwCap);
  874. break;
  875. case MSG_SET:
  876. switch (GetTWAINState()) {
  877. case DS_STATE_7:
  878. twCC = TWCC_SEQERROR;
  879. twRc = TWRC_FAILURE;
  880. break;
  881. default:
  882. twCC = SetCapability(pCap, ptwCap);
  883. break;
  884. }
  885. break;
  886. case MSG_RESET:
  887. switch (GetTWAINState()) {
  888. case DS_STATE_5:
  889. case DS_STATE_6:
  890. case DS_STATE_7:
  891. twCC = TWCC_SEQERROR;
  892. twRc = TWRC_FAILURE;
  893. break;
  894. default:
  895. {
  896. // ptwCap->Cap,
  897. // ptwCap->ConType,
  898. // ptwCap->hContainer);
  899. twCC = pCap->Reset();
  900. //
  901. // According to the TWAIN spec, a MSG_RESET can be sent down meaning more than just
  902. // RESET!!! It is stated that it can mean GET_DEFAULT/CURRENT, and RESET in a single call.
  903. // Applications choose to ignore the value returned if they don't care, But if they
  904. // attempt to read the value as the DEFAULT/CURRENT value...it must be set correctly in the
  905. // container.
  906. //
  907. //
  908. // fill the container with the current value, after the
  909. // RESET call.
  910. //
  911. twCC = pCap->GetCurrent(ptwCap);
  912. // ptwCap->ConType);
  913. }
  914. break;
  915. }
  916. break;
  917. default:
  918. twCC = TWCC_BADPROTOCOL;
  919. DSError();
  920. break;
  921. }
  922. m_twStatus.ConditionCode = twCC;
  923. if (TWCC_SUCCESS != twCC) {
  924. twRc = TWRC_FAILURE;
  925. }
  926. return twRc;
  927. }
  928. TW_UINT16 CWiaDataSrc::OnPrivateCapabilityMsg(PTWAIN_MSG ptwMsg)
  929. {
  930. DBG_FN_DS(CWiaDataSrc::OnPrivateCapabilityMsg());
  931. TW_UINT16 twRc = TWRC_FAILURE;
  932. m_twStatus.ConditionCode = TWCC_BADCAP;
  933. if (ptwMsg) {
  934. if (ptwMsg->MSG == MSG_SET) {
  935. TW_CAPABILITY *ptwCap = (TW_CAPABILITY *)ptwMsg->pData;
  936. if (ptwCap) {
  937. if ((NULL == ptwCap->hContainer)||(INVALID_HANDLE_VALUE == ptwCap->hContainer)) {
  938. return twRc;
  939. }
  940. }
  941. }
  942. if (m_pCurrentIWiaItem) {
  943. //
  944. // Get the IWiaItemExtras Interface
  945. //
  946. IWiaItemExtras *pIWiaItemExtras = NULL;
  947. HRESULT hr = m_pCurrentIWiaItem->QueryInterface(IID_IWiaItemExtras,(void **)&pIWiaItemExtras);
  948. if (S_OK == hr) {
  949. //
  950. // we have an IWiaItemExtras Interface, so lets talk to the WIA device about
  951. // the capability message
  952. //
  953. TW_CAPABILITY *ptwCap = (TW_CAPABILITY *)ptwMsg->pData;
  954. if (ptwCap) {
  955. //
  956. // Initialize the common header
  957. //
  958. TWAIN_CAPABILITY twCap;
  959. twCap.lSize = sizeof(twCap); // size of TWAIN_CAPABILITY structure
  960. twCap.lMSG = ptwMsg->MSG; // TWAIN message
  961. twCap.lCapID = ptwCap->Cap; // TWAIN capability ID
  962. twCap.lConType = ptwCap->ConType; // TWAIN container type
  963. twCap.lCC = TWCC_BADCAP; // TWAIN return code
  964. twCap.lRC = TWRC_FAILURE; // TWAIN condition code
  965. twCap.lDataSize= 0; // TWAIN capability data size
  966. twCap.Data[0] = 0; // TWAIN capability data (first byte)
  967. DBG_TRC(("== Private TWAIN_CAPABILITY data Header =="));
  968. DBG_TRC(("twCap.lSize = %d", twCap.lSize));
  969. DBG_TRC(("twCap.lMSG = %d", twCap.lMSG));
  970. DBG_TRC(("twCap.lCapID = %x", twCap.lCapID));
  971. DBG_TRC(("twCap.lConType = %d", twCap.lConType));
  972. DBG_TRC(("twCap.lCC = %d", twCap.lCC));
  973. DBG_TRC(("twCap.lRC = %d", twCap.lRC));
  974. DWORD dwInDataSize = 0;
  975. DWORD dwOutDataSize = 0;
  976. DWORD dwContainerSize = 0;
  977. DWORD dwActualOutDataSize = 0;
  978. BYTE *pInData = NULL;
  979. BYTE *pOutData = NULL;
  980. BYTE *pContainerData = NULL;
  981. TWAIN_CAPABILITY *pHeader = NULL;
  982. //
  983. // Depending on the Message type GET ot SET we do different things
  984. //
  985. //
  986. // For a SET or RESET message, we just send the IN buffer, with an OUT buffer
  987. // containing the header.
  988. //
  989. if ((ptwMsg->MSG == MSG_SET) ||
  990. (ptwMsg->MSG == MSG_RESET)) {
  991. dwContainerSize = 0;
  992. if (ptwMsg->MSG == MSG_SET) {
  993. //
  994. // only check container size, when the TWAIN message is a MSG_SET
  995. // MSG_RESET operations do not have containers attached.
  996. //
  997. dwContainerSize = (DWORD)GlobalSize(ptwCap->hContainer);
  998. }
  999. dwInDataSize = dwContainerSize + sizeof(twCap);
  1000. dwOutDataSize = sizeof(twCap);
  1001. dwActualOutDataSize = dwOutDataSize;
  1002. twCap.lDataSize = dwContainerSize;
  1003. DBG_TRC(("twCap.lDataSize = %d", twCap.lDataSize));
  1004. DBG_TRC(("== Processing MSG_SET or MSG_RESET Capability Message =="));
  1005. DBG_TRC(("dwInDataSize = %d",dwInDataSize));
  1006. DBG_TRC(("dwOutDataSize = %d",dwOutDataSize));
  1007. DBG_TRC(("dwActualOutDataSize = %d",dwActualOutDataSize));
  1008. DBG_TRC(("dwContainerSize = %d",dwContainerSize));
  1009. //
  1010. // allocate IN buffer and write TWAIN_CAPABILITY header
  1011. //
  1012. if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pInData,dwInDataSize)) {
  1013. if (ptwMsg->MSG == MSG_SET) {
  1014. //
  1015. // copy TWAIN container data to IN buffer
  1016. //
  1017. if (TWRC_SUCCESS == CopyContainerToPrivateCapBuffer(pInData,ptwCap->hContainer)) {
  1018. //
  1019. // container data was copied to IN buffer
  1020. //
  1021. DBG_TRC(("Container data was successfully copied, we are processing a MSG_SET"));
  1022. } else {
  1023. //
  1024. // could not copy TWAIN container data into private capability IN buffer
  1025. //
  1026. DBG_ERR(("could not copy TWAIN container data into private capability IN buffer"));
  1027. if(pInData){
  1028. GlobalFree(pInData);
  1029. pInData = NULL;
  1030. }
  1031. return twRc; // return here, becuase we can not continue
  1032. }
  1033. } else {
  1034. //
  1035. // no container data needs to be copied
  1036. //
  1037. DBG_TRC(("No Container data was copied, because we are processing a MSG_RESET"));
  1038. }
  1039. //
  1040. // allocate OUT buffer and write TWAIN_CAPABILITY header
  1041. //
  1042. if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pOutData,dwOutDataSize)) {
  1043. hr = pIWiaItemExtras->Escape(ESC_TWAIN_CAPABILITY,
  1044. pInData,
  1045. dwInDataSize,
  1046. pOutData,
  1047. dwOutDataSize,
  1048. &dwActualOutDataSize);
  1049. if (S_OK == hr) {
  1050. pHeader = (TWAIN_CAPABILITY*)pOutData;
  1051. DBG_TRC(("== Returned TWAIN_CAPABILITY data Header from WIA device =="));
  1052. DBG_TRC(("pHeader->lSize = %d", pHeader->lSize));
  1053. DBG_TRC(("pHeader->lMSG = %d", pHeader->lMSG));
  1054. DBG_TRC(("pHeader->lCapID = %x", pHeader->lCapID));
  1055. DBG_TRC(("pHeader->lConType = %d", pHeader->lConType));
  1056. DBG_TRC(("pHeader->lCC = %d", pHeader->lCC));
  1057. DBG_TRC(("pHeader->lRC = %d", pHeader->lRC));
  1058. DBG_TRC(("pHeader->lDataSize = %d", pHeader->lDataSize));
  1059. twRc = (TW_UINT16)pHeader->lRC;
  1060. m_twStatus.ConditionCode = (TW_UINT16)pHeader->lCC;
  1061. } else {
  1062. //
  1063. // pIWiaItemExtras->Escape call failed,
  1064. // a failure means that we do not respond with a success to the TWAIN application
  1065. //
  1066. DBG_ERR(("pIWiaItemExtras->Escape Failed"));
  1067. DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %p)",
  1068. ESC_TWAIN_CAPABILITY,
  1069. pInData,
  1070. dwInDataSize,
  1071. pOutData,
  1072. dwOutDataSize,
  1073. &dwActualOutDataSize));
  1074. }
  1075. } else {
  1076. //
  1077. // could not allocate memory for private capability OUT buffer
  1078. //
  1079. DBG_ERR(("could not allocate memory for private capability OUT buffer"));
  1080. }
  1081. } else {
  1082. //
  1083. // could not allocate memory for private capability IN buffer
  1084. //
  1085. DBG_ERR(("could not allocate memory for private capability IN buffer"));
  1086. }
  1087. } else if ((ptwMsg->MSG == MSG_GET) ||
  1088. (ptwMsg->MSG == MSG_GETCURRENT) ||
  1089. (ptwMsg->MSG == MSG_GETDEFAULT)) {
  1090. dwContainerSize = 0;
  1091. dwInDataSize = sizeof(twCap);
  1092. dwOutDataSize = dwInDataSize;
  1093. dwActualOutDataSize = dwInDataSize;
  1094. twCap.lDataSize = dwContainerSize;
  1095. DBG_TRC(("twCap.lDataSize = %d", twCap.lDataSize));
  1096. DBG_TRC(("== Processing MSG_GET, MSG_GETCURRENT, or MSG_GETDEFAULT Capability Message =="));
  1097. DBG_TRC(("dwInDataSize = %d",dwInDataSize));
  1098. DBG_TRC(("dwOutDataSize = %d",dwOutDataSize));
  1099. DBG_TRC(("dwActualOutDataSize = %d",dwActualOutDataSize));
  1100. DBG_TRC(("dwContainerSize = %d",dwContainerSize));
  1101. //
  1102. // allocate IN buffer and write TWAIN_CAPABILITY header
  1103. //
  1104. if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pInData,dwInDataSize)) {
  1105. //
  1106. // ask the WIA driver how large is the data, so
  1107. // we can allocate the proper OUT buffer
  1108. //
  1109. //
  1110. // allocate OUT buffer and write TWAIN_CAPABILITY header
  1111. //
  1112. if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pOutData,dwOutDataSize)) {
  1113. hr = pIWiaItemExtras->Escape(ESC_TWAIN_CAPABILITY,
  1114. pInData,
  1115. dwInDataSize,
  1116. pOutData,
  1117. dwOutDataSize,
  1118. &dwActualOutDataSize);
  1119. if (S_OK == hr) {
  1120. //
  1121. // make sure that the returned data is large enough to
  1122. // contain a proper header.
  1123. //
  1124. if (dwActualOutDataSize == dwInDataSize) {
  1125. pHeader = (TWAIN_CAPABILITY*)pOutData;
  1126. DBG_TRC(("== Returned TWAIN_CAPABILITY data Header from WIA device =="));
  1127. DBG_TRC(("pHeader->lSize = %d", pHeader->lSize));
  1128. DBG_TRC(("pHeader->lMSG = %d", pHeader->lMSG));
  1129. DBG_TRC(("pHeader->lCapID = %x", pHeader->lCapID));
  1130. DBG_TRC(("pHeader->lConType = %d", pHeader->lConType));
  1131. DBG_TRC(("pHeader->lCC = %d", pHeader->lCC));
  1132. DBG_TRC(("pHeader->lRC = %d", pHeader->lRC));
  1133. DBG_TRC(("pHeader->lDataSize = %d", pHeader->lDataSize));
  1134. if (pHeader->lDataSize > 0) {
  1135. //
  1136. // update common header data size from information returned
  1137. // to create OUT buffer header
  1138. //
  1139. twCap.lDataSize = pHeader->lDataSize;
  1140. //
  1141. // set new out data size to (data + header) size
  1142. //
  1143. dwOutDataSize = (pHeader->lDataSize + sizeof(twCap));
  1144. //
  1145. // update InBuffer header data size from the common header
  1146. //
  1147. pHeader = (TWAIN_CAPABILITY*)pInData;
  1148. pHeader->lDataSize = twCap.lDataSize;
  1149. //
  1150. // free old out buffer, before allocating new one
  1151. //
  1152. if (pOutData) {
  1153. GlobalFree(pOutData);
  1154. pOutData = NULL;
  1155. }
  1156. //
  1157. // allocate OUT buffer and write TWAIN_CAPABILITY header
  1158. //
  1159. if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pOutData,dwOutDataSize)) {
  1160. hr = pIWiaItemExtras->Escape(ESC_TWAIN_CAPABILITY,
  1161. pInData,
  1162. dwInDataSize,
  1163. pOutData,
  1164. dwOutDataSize,
  1165. &dwActualOutDataSize);
  1166. if (S_OK == hr) {
  1167. pHeader = (TWAIN_CAPABILITY*)pOutData;
  1168. DBG_TRC(("== Returned TWAIN_CAPABILITY data Header from WIA device =="));
  1169. DBG_TRC(("pHeader->lSize = %d", pHeader->lSize));
  1170. DBG_TRC(("pHeader->lMSG = %d", pHeader->lMSG));
  1171. DBG_TRC(("pHeader->lCapID = %x", pHeader->lCapID));
  1172. DBG_TRC(("pHeader->lConType = %d", pHeader->lConType));
  1173. DBG_TRC(("pHeader->lCC = %d", pHeader->lCC));
  1174. DBG_TRC(("pHeader->lRC = %d", pHeader->lRC));
  1175. DBG_TRC(("pHeader->lDataSize = %d", pHeader->lDataSize));
  1176. twRc = (TW_UINT16)pHeader->lRC;
  1177. m_twStatus.ConditionCode = (TW_UINT16)pHeader->lCC;
  1178. if (TWRC_SUCCESS == twRc) {
  1179. if (TWRC_SUCCESS == CopyPrivateCapBufferToContainer(&ptwCap->hContainer,pOutData,pHeader->lDataSize)) {
  1180. ptwCap->ConType = (TW_UINT16)pHeader->lConType;
  1181. } else {
  1182. //
  1183. // could not copy private capability buffer into TWAIN container data
  1184. //
  1185. DBG_ERR(("could not copy private capability buffer into TWAIN container data"));
  1186. }
  1187. } else {
  1188. //
  1189. // WIA driver failed the TWAIN capability request, by returning a TWAIN failure
  1190. // return code in the OUT header.
  1191. //
  1192. DBG_ERR(("WIA driver failed the TWAIN capability request, by returning a TWAIN failure return code in the OUT header."));
  1193. }
  1194. } else {
  1195. //
  1196. // pIWiaItemExtras->Escape call failed, (sending passthrough operation)
  1197. // a failure means that we do not respond with a success to the TWAIN application
  1198. //
  1199. DBG_ERR(("pIWiaItemExtras->Escape Failed (sending passthrough operation)"));
  1200. DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)",
  1201. ESC_TWAIN_CAPABILITY,
  1202. pInData,
  1203. dwInDataSize,
  1204. pOutData,
  1205. dwOutDataSize,
  1206. dwActualOutDataSize));
  1207. }
  1208. } else {
  1209. //
  1210. // could not allocate memory for private capability OUT buffer
  1211. //
  1212. DBG_ERR(("could not allocate memory for private capability OUT buffer"));
  1213. }
  1214. } else {
  1215. //
  1216. // OUT buffer size returned from the WIA driver is too small to contain a
  1217. // proper header.
  1218. //
  1219. DBG_ERR(("OUT buffer size (%d) returned from the WIA driver is too small to contain data",pHeader->lDataSize));
  1220. }
  1221. } else {
  1222. //
  1223. // OUT buffer size returned from the WIA driver is too small to contain a
  1224. // proper header.
  1225. //
  1226. DBG_ERR(("OUT buffer size (%d) returned from the WIA driver is too small to contain a proper header",dwActualOutDataSize));
  1227. }
  1228. } else {
  1229. //
  1230. // pIWiaItemExtras->Escape call failed, (requesting OUT buffer size)
  1231. // a failure means that we do not respond with a success to the TWAIN application
  1232. //
  1233. DBG_ERR(("pIWiaItemExtras->Escape Failed (requesting OUT buffer size)"));
  1234. DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)",
  1235. ESC_TWAIN_CAPABILITY,
  1236. pInData,
  1237. dwInDataSize,
  1238. pInData,
  1239. dwInDataSize,
  1240. dwActualOutDataSize));
  1241. }
  1242. } else {
  1243. //
  1244. // could not allocate memory for private capability OUT buffer
  1245. //
  1246. DBG_ERR(("could not allocate memory for private capability OUT buffer"));
  1247. }
  1248. } else {
  1249. //
  1250. // could not allocate memory for private capability IN buffer
  1251. //
  1252. DBG_ERR(("could not allocate memory for private capability IN buffer"));
  1253. }
  1254. }
  1255. //
  1256. // free IN buffer
  1257. //
  1258. if (pInData) {
  1259. GlobalFree(pInData);
  1260. pInData = NULL;
  1261. }
  1262. //
  1263. // free OUT buffer
  1264. //
  1265. if (pOutData) {
  1266. GlobalFree(pOutData);
  1267. pOutData = NULL;
  1268. }
  1269. } else {
  1270. //
  1271. // could not get TWAIN capability from TWAIN message
  1272. //
  1273. DBG_ERR(("could not get TWAIN capability from TWAIN message"));
  1274. }
  1275. //
  1276. // release IWiaItemExtras Interface
  1277. //
  1278. if (pIWiaItemExtras) {
  1279. pIWiaItemExtras->Release();
  1280. pIWiaItemExtras = NULL;
  1281. }
  1282. } else {
  1283. //
  1284. // QI for IWiaItemExtras Failed
  1285. //
  1286. DBG_ERR(("QueryInterface for IWiaItemExtras Failed"));
  1287. }
  1288. } else {
  1289. //
  1290. // no current item selected
  1291. //
  1292. DBG_ERR(("no current item selected for use"));
  1293. }
  1294. } else {
  1295. //
  1296. // imcoming TWAIN capability is NULL
  1297. //
  1298. DBG_ERR(("incoming TWAIN capability is NULL"));
  1299. }
  1300. return twRc;
  1301. }
  1302. TW_UINT16 CWiaDataSrc::AllocatePrivateCapBuffer(TWAIN_CAPABILITY *pHeader, BYTE** ppBuffer, DWORD dwSize)
  1303. {
  1304. DBG_FN_DS(CWiaDataSrc::AllocatePrivateCapBuffer());
  1305. if(dwSize < sizeof(TWAIN_CAPABILITY) || (!ppBuffer)|| (!pHeader)){
  1306. return TWRC_FAILURE;
  1307. }
  1308. *ppBuffer = (BYTE*)GlobalAlloc(GPTR,dwSize);
  1309. if(*ppBuffer){
  1310. memcpy(*ppBuffer, pHeader,sizeof(TWAIN_CAPABILITY));
  1311. } else {
  1312. return TWRC_FAILURE;
  1313. }
  1314. return TWRC_SUCCESS;
  1315. }
  1316. TW_UINT16 CWiaDataSrc::CopyContainerToPrivateCapBuffer(BYTE* pBuffer, HGLOBAL hContainer)
  1317. {
  1318. DBG_FN_DS(CWiaDataSrc::CopyContainerToPrivateCapBuffer());
  1319. if((!pBuffer)||(!hContainer)){
  1320. return TWRC_FAILURE;
  1321. }
  1322. DWORD dwContainerSize = (DWORD)GlobalSize(hContainer);
  1323. BYTE *pContainerBuffer = (BYTE*)GlobalLock(hContainer);
  1324. if(!pContainerBuffer){
  1325. return TWRC_FAILURE;
  1326. }
  1327. TWAIN_CAPABILITY *pHeader = (TWAIN_CAPABILITY*)pBuffer;
  1328. memcpy((BYTE*)pHeader->Data,pContainerBuffer,dwContainerSize);
  1329. //
  1330. // unlock handle before returning
  1331. //
  1332. GlobalUnlock(hContainer);
  1333. return TWRC_SUCCESS;
  1334. }
  1335. TW_UINT16 CWiaDataSrc::CopyPrivateCapBufferToContainer(HGLOBAL *phContainer, BYTE* pBuffer, DWORD dwSize)
  1336. {
  1337. DBG_FN_DS(CWiaDataSrc::CopyPrivateCapBufferToContainer());
  1338. if((!phContainer) || (!pBuffer) || (dwSize <= 0)){
  1339. return TWRC_FAILURE;
  1340. }
  1341. *phContainer = NULL;
  1342. *phContainer = (HGLOBAL)GlobalAlloc(GHND,dwSize);
  1343. if(!*phContainer){
  1344. return TWRC_FAILURE;
  1345. }
  1346. BYTE *pContainerBuffer = (BYTE*)GlobalLock(*phContainer);
  1347. if(!pContainerBuffer){
  1348. GlobalFree(*phContainer);
  1349. *phContainer = NULL;
  1350. return TWRC_FAILURE;
  1351. }
  1352. TWAIN_CAPABILITY *pHeader = (TWAIN_CAPABILITY*)pBuffer;
  1353. memcpy(pContainerBuffer,(BYTE*)pHeader->Data,dwSize);
  1354. //
  1355. // unlock handle before returning
  1356. //
  1357. GlobalUnlock(*phContainer);
  1358. return TWRC_SUCCESS;
  1359. }
  1360. TW_UINT16 CWiaDataSrc::SetCapability(CCap *pCap,TW_CAPABILITY *ptwCap)
  1361. {
  1362. DBG_FN_DS(CWiaDataSrc::SetCapability());
  1363. if (!pCap || !ptwCap) {
  1364. m_twStatus.ConditionCode = TWCC_BADCAP;
  1365. return TWRC_FAILURE;
  1366. }
  1367. return pCap->Set(ptwCap);
  1368. }
  1369. TW_UINT16 CWiaDataSrc::OnStatusMsg(PTWAIN_MSG ptwMsg)
  1370. {
  1371. DBG_FN_DS(CWiaDataSrc::OnStatusMsg());
  1372. TW_UINT16 twRc = TWRC_SUCCESS;
  1373. if (MSG_GET == ptwMsg->MSG) {
  1374. *((TW_STATUS*)ptwMsg->pData) = m_twStatus;
  1375. twRc = TWRC_SUCCESS;
  1376. } else {
  1377. twRc = TWRC_FAILURE;
  1378. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  1379. DSError();
  1380. }
  1381. return twRc;
  1382. }
  1383. TW_UINT16 CWiaDataSrc::OnPendingXfersMsg(PTWAIN_MSG ptwMsg)
  1384. {
  1385. m_twStatus.ConditionCode = TWCC_BUMMER;
  1386. return TWRC_FAILURE;
  1387. }
  1388. TW_UINT16 CWiaDataSrc::OnImageMemXferMsg(PTWAIN_MSG ptwMsg)
  1389. {
  1390. DBG_FN_DS(CWiaDataSrc::OnImageMemXferMsg());
  1391. TW_UINT16 twRc = TWRC_SUCCESS;
  1392. HRESULT hr = E_FAIL;
  1393. switch (GetTWAINState()) {
  1394. case DS_STATE_6:
  1395. case DS_STATE_7:
  1396. {
  1397. if (MSG_GET == ptwMsg->MSG) {
  1398. TW_IMAGEMEMXFER *pMemXfer = (TW_IMAGEMEMXFER *)ptwMsg->pData;
  1399. if ((m_hMemXferBits == NULL)) {
  1400. m_LinesTransferred = 0;
  1401. GUID guidFormat = GUID_NULL;
  1402. DBG_WRN(("Transferring %d bit data",m_MemoryTransferInfo.mtiBitsPerPixel));
  1403. if (m_MemoryTransferInfo.mtiBitsPerPixel > 32) {
  1404. //
  1405. // Load image into memory for memory transfer (hi-color images)
  1406. //
  1407. guidFormat = WiaImgFmt_RAWRGB;
  1408. } else {
  1409. //
  1410. // The TWAIN compatibility layer has the ability to transfer images
  1411. // 1,2,4,8,16,24 and 32 bit when using MEMORYBMP.
  1412. //
  1413. guidFormat = WiaImgFmt_MEMORYBMP;
  1414. }
  1415. twRc = TransferToMemory(guidFormat);
  1416. if (TWRC_SUCCESS != twRc) {
  1417. return twRc;
  1418. } else {
  1419. //
  1420. // transition to STATE_7
  1421. //
  1422. SetTWAINState(DS_STATE_7);
  1423. }
  1424. }
  1425. //
  1426. // turn off the Image caching flag
  1427. //
  1428. m_bCacheImage = FALSE;
  1429. //
  1430. // Lock down the memory and get the address to the bits
  1431. //
  1432. GetMemoryTransferBits((BYTE*)GlobalLock(m_hMemXferBits));
  1433. m_pMemXferBits = m_MemoryTransferInfo.mtipBits;
  1434. if (m_pMemXferBits) {
  1435. if(m_MemoryTransferInfo.mtiHeightPixels == 0){
  1436. m_MemoryTransferInfo.mtiHeightPixels = m_ImageHeight;
  1437. }
  1438. if(m_MemoryTransferInfo.mtiguidFormat == WiaImgFmt_MEMORYBMP){
  1439. //
  1440. // adjust the image information to report the actual information
  1441. // reported in the BITMAPINFO header.
  1442. //
  1443. //
  1444. // only change these values, if the current information does not
  1445. // match the image header. (always take the header's values)
  1446. //
  1447. if(m_MemoryTransferInfo.mtiHeightPixels != m_ImageHeight){
  1448. m_MemoryTransferInfo.mtiHeightPixels = m_ImageHeight;
  1449. }
  1450. if(m_MemoryTransferInfo.mtiWidthPixels != m_ImageWidth){
  1451. m_MemoryTransferInfo.mtiWidthPixels = m_ImageWidth;
  1452. }
  1453. }
  1454. DBG_TRC(("CWiaDataSrc::OnImageMemXferMsg(), Transferring (%d) of (%d) total lines of image data.",m_LinesTransferred,m_MemoryTransferInfo.mtiHeightPixels));
  1455. if (m_LinesTransferred >= (TW_UINT32)m_MemoryTransferInfo.mtiHeightPixels) {
  1456. //
  1457. // we have completed the transfer, or we are out
  1458. // of scan lines to copy..so return XFERDONE
  1459. //
  1460. //
  1461. // unlock memory before bailing
  1462. //
  1463. // Keep unlock and NULLing together
  1464. GlobalUnlock(m_hMemXferBits);
  1465. m_pMemXferBits = NULL;
  1466. ResetMemXfer();
  1467. m_twStatus.ConditionCode = TWCC_SUCCESS;
  1468. return TWRC_XFERDONE;
  1469. } else {
  1470. //
  1471. // looks like we are working with transfer data
  1472. //
  1473. BYTE * pAppBuffer = NULL;
  1474. if (pMemXfer->Memory.Flags & TWMF_HANDLE) {
  1475. DBG_TRC(("TWAIN Application wants to work with a HANDLE"));
  1476. //
  1477. // if the memory is a HANDLE, lock it first
  1478. //
  1479. pAppBuffer = (LPBYTE)GlobalLock(pMemXfer->Memory.TheMem);
  1480. } else if (pMemXfer->Memory.Flags & TWMF_POINTER) {
  1481. DBG_TRC(("TWAIN Application wants to work with a POINTER"));
  1482. //
  1483. // if the memory is a POINTER, then proceed
  1484. //
  1485. pAppBuffer = (LPBYTE)pMemXfer->Memory.TheMem;
  1486. } else {
  1487. DBG_TRC(("TWAIN Application gave us nothing to work with"));
  1488. //
  1489. // we have no memory, so set it to NULL
  1490. //
  1491. pAppBuffer = NULL;
  1492. }
  1493. //
  1494. // if (there is no Memory to write to), or
  1495. // (the app doesn't own the memory), or
  1496. // (the length is less than MIN_ ), or
  1497. // (the length is greater than MAX),
  1498. // return a FAILURE!, and a CC of BADVALUE
  1499. //
  1500. if (!pAppBuffer ||
  1501. !(pMemXfer->Memory.Flags & TWMF_APPOWNS) ||
  1502. pMemXfer->Memory.Length < MIN_MEMXFER_SIZE ||
  1503. pMemXfer->Memory.Length > MAX_MEMXFER_SIZE) {
  1504. twRc = TWRC_FAILURE;
  1505. m_twStatus.ConditionCode = TWCC_BADVALUE;
  1506. } else {
  1507. //
  1508. // set memory Xfer values
  1509. //
  1510. UINT ScanlinesToCopy = 0;
  1511. pMemXfer->BytesPerRow = GetLineSize(&m_MemoryTransferInfo);
  1512. ScanlinesToCopy = min(pMemXfer->Memory.Length / pMemXfer->BytesPerRow,
  1513. (TW_UINT32)(m_MemoryTransferInfo.mtiHeightPixels - m_LinesTransferred));
  1514. pMemXfer->Compression = TWCP_NONE;
  1515. pMemXfer->Columns = m_MemoryTransferInfo.mtiWidthPixels;
  1516. pMemXfer->Rows = ScanlinesToCopy;
  1517. pMemXfer->XOffset = 0;
  1518. pMemXfer->YOffset = m_LinesTransferred;
  1519. pMemXfer->BytesWritten = pMemXfer->BytesPerRow * ScanlinesToCopy;
  1520. #ifdef DEBUG_MEMXFER
  1521. DBG_TRC(("CWiaDataSrc::OnImageMemXferMsg(), Reports TW_IMAGEMEMXFER"));
  1522. DBG_TRC(("pMemXfer->Compression = %d",pMemXfer->Compression));
  1523. DBG_TRC(("pMemXfer->Columns = %d",pMemXfer->Columns));
  1524. DBG_TRC(("pMemXfer->Rows = %d",pMemXfer->Rows));
  1525. DBG_TRC(("pMemXfer->XOffset = %d",pMemXfer->XOffset));
  1526. DBG_TRC(("pMemXfer->YOffset = %d",pMemXfer->YOffset));
  1527. DBG_TRC(("pMemXfer->BytesPerRow = %d",pMemXfer->BytesPerRow));
  1528. DBG_TRC(("pMemXfer->BytesWritten = %d",pMemXfer->BytesWritten));
  1529. DBG_TRC(("pAppBuffer = %p, m_pMemXferBits = %p",pAppBuffer,m_pMemXferBits));
  1530. #endif
  1531. //
  1532. // Transfer one-line strips in a loop to Application supplied buffer
  1533. //
  1534. LPBYTE pTo = pAppBuffer;
  1535. LPBYTE pFrom = m_pMemXferBits + m_LinesTransferred * GetLineSize(&m_MemoryTransferInfo);
  1536. for (UINT i=0;i < ScanlinesToCopy;i++ ) {
  1537. //
  1538. // swap color values, if needed
  1539. //
  1540. if (m_MemoryTransferInfo.mtiBitsPerPixel == 24) {
  1541. for (ULONG ulIndex = 0; ulIndex < pMemXfer->BytesPerRow; ulIndex+= 3) {
  1542. // 1 2 3
  1543. // RED-GREEN-BLUE
  1544. //
  1545. BYTE bFirst = pFrom[ulIndex];
  1546. pFrom[ulIndex] = pFrom[ulIndex+2];
  1547. pFrom[ulIndex+2] = bFirst;
  1548. }
  1549. }
  1550. /*
  1551. if(m_MemoryTransferInfo.mtiBitsPerPixel == 48){
  1552. for(j = 0; j < pMemXfer->BytesPerRow; j+=6){
  1553. // 1 2 1 2 1 2
  1554. // REDRED-GREENGREEN-BLUEBLUE
  1555. //
  1556. BYTE bFirst = pFrom[j];
  1557. BYTE bSecond = pFrom[j+1];
  1558. pFrom[j] = pFrom[j+4];
  1559. pFrom[j+1] = pFrom[j+5];
  1560. pFrom[j+4] = bFirst;
  1561. pFrom[j+5] = bSecond;
  1562. }
  1563. }
  1564. */
  1565. //
  1566. // copy line to application supplied buffer
  1567. //
  1568. memcpy(pTo,pFrom,pMemXfer->BytesPerRow);
  1569. pFrom+=GetLineSize(&m_MemoryTransferInfo);
  1570. pTo+=pMemXfer->BytesPerRow;
  1571. }
  1572. //
  1573. // calculate lines transferred
  1574. //
  1575. m_LinesTransferred += ScanlinesToCopy;
  1576. if (m_LinesTransferred >= (TW_UINT32)m_MemoryTransferInfo.mtiHeightPixels) {
  1577. //
  1578. // we have completed the transfer, or we are out
  1579. // of scan lines to copy..so return XFERDONE
  1580. //
  1581. twRc = TWRC_XFERDONE;
  1582. m_twStatus.ConditionCode = TWCC_SUCCESS;
  1583. // Keep unlock and NULLing together
  1584. GlobalUnlock(m_hMemXferBits);
  1585. m_pMemXferBits = NULL;
  1586. ResetMemXfer();
  1587. //
  1588. // if we are working with an application provided HANDLE,
  1589. // GlobalUnlock it before continuing
  1590. //
  1591. if (pMemXfer->Memory.Flags & TWMF_HANDLE) {
  1592. GlobalUnlock(pMemXfer->Memory.TheMem);
  1593. }
  1594. return twRc;
  1595. }
  1596. //
  1597. // if we are working with an application provided HANDLE,
  1598. // GlobalUnlock it before continuing
  1599. //
  1600. if (pMemXfer->Memory.Flags & TWMF_HANDLE) {
  1601. GlobalUnlock(pMemXfer->Memory.TheMem);
  1602. }
  1603. }
  1604. }
  1605. //
  1606. // unlock buffer when finished
  1607. //
  1608. // Keep unlock and NULLing together
  1609. GlobalUnlock(m_hMemXferBits);
  1610. m_pMemXferBits = NULL;
  1611. } else {
  1612. //
  1613. // Could not lock down memory for transfer
  1614. //
  1615. m_twStatus.ConditionCode = TWCC_LOWMEMORY;
  1616. return TWRC_FAILURE;
  1617. }
  1618. } else {
  1619. //
  1620. // we recieved a message other than the expected MSG_GET
  1621. //
  1622. twRc = TWRC_FAILURE;
  1623. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  1624. }
  1625. }
  1626. break;
  1627. default:
  1628. {
  1629. twRc = TWRC_FAILURE;
  1630. m_twStatus.ConditionCode = TWCC_SEQERROR;
  1631. return twRc;
  1632. break;
  1633. }
  1634. break;
  1635. }
  1636. //
  1637. // if we failed, report it properly
  1638. //
  1639. if (TWRC_FAILURE == twRc)
  1640. DSError();
  1641. return twRc;
  1642. }
  1643. TW_UINT16 CWiaDataSrc::OnImageFileXferMsg(PTWAIN_MSG ptwMsg)
  1644. {
  1645. DBG_FN_DS(CWiaDataSrc::OnImageFileXferMsg());
  1646. TW_UINT16 twRc = TWRC_SUCCESS;
  1647. if (MSG_GET == ptwMsg->MSG) {
  1648. GUID guidFileFormat = WiaImgFmt_BMP;
  1649. CCap *pCap = FindCap(ICAP_IMAGEFILEFORMAT);
  1650. if(pCap){
  1651. guidFileFormat = ICAP_IMAGEFILEFORMAT_TO_WIA_IPA_FORMAT((TW_UINT16)pCap->GetCurrent());
  1652. }
  1653. twRc = TransferToFile(guidFileFormat);
  1654. if(TWRC_XFERDONE == twRc) {
  1655. SetTWAINState(DS_STATE_7);
  1656. } else {
  1657. DBG_ERR(("CWiaDataSrc::OnImageFileXferMsg(), TransferToFile() failed"));
  1658. }
  1659. } else {
  1660. twRc = TWRC_FAILURE;
  1661. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  1662. }
  1663. if (TWRC_FAILURE == twRc){
  1664. DSError();
  1665. }
  1666. return twRc;
  1667. }
  1668. TW_UINT16 CWiaDataSrc::OnImageNativeXferMsg(PTWAIN_MSG ptwMsg)
  1669. {
  1670. DBG_FN_DS(CWiaDataSrc::OnImageNativeXferMsg());
  1671. TW_UINT16 twRc = TWRC_SUCCESS;
  1672. HGLOBAL hDIB = NULL;
  1673. switch (GetTWAINState()) {
  1674. case DS_STATE_6:
  1675. {
  1676. if (MSG_GET == ptwMsg->MSG) {
  1677. twRc = TransferToDIB(&hDIB);
  1678. if (TWRC_XFERDONE == twRc) {
  1679. SetTWAINState(DS_STATE_7);
  1680. *(TW_UINT32*)ptwMsg->pData = (TW_UINT32)(INT_PTR)hDIB;
  1681. } else {
  1682. DBG_ERR(("CWiaDataSrc::OnImageNativeXferMsg(), TransferToDIB() failed"));
  1683. }
  1684. } else {
  1685. twRc = TWRC_FAILURE;
  1686. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  1687. }
  1688. }
  1689. break;
  1690. default:
  1691. twRc = TWRC_FAILURE;
  1692. m_twStatus.ConditionCode = TWCC_SEQERROR;
  1693. break;
  1694. }
  1695. if (TWRC_FAILURE == twRc){
  1696. DSError();
  1697. }
  1698. return twRc;
  1699. }
  1700. TW_UINT16 CWiaDataSrc::OpenDS(PTWAIN_MSG ptwMsg)
  1701. {
  1702. DBG_FN_DS(CWiaDataSrc::OpenDS());
  1703. TW_UINT16 twRc = TWRC_SUCCESS;
  1704. if (DS_STATE_3 == GetTWAINState()) {
  1705. //
  1706. // No multiple clients are allowed.
  1707. // This is enforced by making sure that our identity's id field
  1708. // has a value of 0.
  1709. if (m_dsIdentity.Id) {
  1710. m_twStatus.ConditionCode = TWCC_MAXCONNECTIONS;
  1711. twRc = TWRC_FAILURE;
  1712. } else {
  1713. //
  1714. // make a copy of the caller's identity
  1715. //
  1716. m_AppIdentity = *ptwMsg->AppId;
  1717. m_dsIdentity = *((TW_IDENTITY *)ptwMsg->pData);
  1718. HRESULT hr = S_OK;
  1719. hr = m_pDevice->Open(CWiaDataSrc::DeviceEventCallback,
  1720. (LPARAM)this);
  1721. if (FAILED(hr)) {
  1722. twRc = TWRC_FAILURE;
  1723. m_twStatus.ConditionCode = TWCC_BUMMER;
  1724. }
  1725. }
  1726. } else {
  1727. m_twStatus.ConditionCode = TWCC_SEQERROR;
  1728. twRc = TWRC_FAILURE;
  1729. }
  1730. if (TWRC_SUCCESS == twRc) {
  1731. //
  1732. // transition to STATE_4
  1733. //
  1734. SetTWAINState(DS_STATE_4);
  1735. }
  1736. if (TWRC_SUCCESS != twRc) {
  1737. }
  1738. return twRc;
  1739. }
  1740. TW_UINT16 CWiaDataSrc::CloseDS(PTWAIN_MSG ptwMsg)
  1741. {
  1742. DBG_FN_DS(CWiaDataSrc::CloseDS());
  1743. TW_UINT16 twRc = TWRC_SUCCESS;
  1744. switch (GetTWAINState()) {
  1745. case DS_STATE_7:
  1746. case DS_STATE_6:
  1747. case DS_STATE_5:
  1748. case DS_STATE_4:
  1749. m_pDevice->Close();
  1750. //DBG_TRC(("Calling ResetMemXfer because CLOSEDS was called"));
  1751. ResetMemXfer();
  1752. //
  1753. // We are up for sale again.
  1754. //
  1755. m_AppIdentity.Id = 0;
  1756. //
  1757. // transition to STATE_3
  1758. //
  1759. SetTWAINState(DS_STATE_3);
  1760. if (m_pIWiaItems)
  1761. delete [] m_pIWiaItems;
  1762. m_pIWiaItems = NULL;
  1763. m_NumIWiaItems = 0;
  1764. m_NextIWiaItemIndex = 0;
  1765. break;
  1766. default:
  1767. m_twStatus.ConditionCode = TWCC_SEQERROR;
  1768. twRc = TWRC_FAILURE;
  1769. DSError();
  1770. break;
  1771. }
  1772. return twRc;
  1773. }
  1774. TW_UINT16 CWiaDataSrc::EnableDS(TW_USERINTERFACE *pUI)
  1775. {
  1776. return TWRC_FAILURE;
  1777. }
  1778. TW_UINT16 CWiaDataSrc::DisableDS(TW_USERINTERFACE *pUI)
  1779. {
  1780. DBG_FN_DS(CWiaDataSrc::DisableDS());
  1781. TW_UINT16 twRc = TWRC_SUCCESS;
  1782. switch (GetTWAINState()) {
  1783. case DS_STATE_5:
  1784. //
  1785. // transition to STATE_4
  1786. //
  1787. SetTWAINState(DS_STATE_4);
  1788. break;
  1789. default:
  1790. twRc = TWRC_FAILURE;
  1791. m_twStatus.ConditionCode = TWCC_SEQERROR;
  1792. DSError();
  1793. break;
  1794. }
  1795. return twRc;
  1796. }
  1797. TW_UINT16 CWiaDataSrc::CreateCapList(TW_UINT32 NumCaps,PCAPDATA pCapData)
  1798. {
  1799. DBG_FN_DS(CWiaDataSrc::CreateCapList());
  1800. if (!NumCaps || !pCapData)
  1801. return TWCC_BADVALUE;
  1802. TW_UINT16 twCc = TWCC_SUCCESS;
  1803. DestroyCapList();
  1804. m_CapList = new CCap[NumCaps];
  1805. if (m_CapList) {
  1806. for (m_NumCaps = 0; m_NumCaps < NumCaps; m_NumCaps++) {
  1807. twCc = m_CapList[m_NumCaps].ICap(&pCapData[m_NumCaps]);
  1808. if (TWCC_SUCCESS != twCc) {
  1809. break;
  1810. }
  1811. }
  1812. m_NumCaps = NumCaps;
  1813. } else {
  1814. twCc = TWCC_LOWMEMORY;
  1815. }
  1816. if (TWCC_SUCCESS != twCc && m_CapList) {
  1817. DestroyCapList();
  1818. }
  1819. return twCc;
  1820. }
  1821. TW_UINT16 CWiaDataSrc::DestroyCapList()
  1822. {
  1823. DBG_FN_DS(CWiaDataSrc::DestroyCapList());
  1824. if (m_CapList) {
  1825. delete [] m_CapList;
  1826. m_CapList = NULL;
  1827. }
  1828. m_NumCaps = 0;
  1829. return TWCC_SUCCESS;
  1830. }
  1831. CCap * CWiaDataSrc::FindCap(TW_UINT16 CapId)
  1832. {
  1833. TW_UINT32 ui32;
  1834. for (ui32 = 0; ui32 < m_NumCaps; ui32++) {
  1835. if (m_CapList[ui32].GetCapId() == CapId)
  1836. return &m_CapList[ui32];
  1837. }
  1838. return NULL;
  1839. }
  1840. void CWiaDataSrc::DSError()
  1841. {
  1842. DBG_FN_DS(CWiaDataSrc::DSError());
  1843. NotifyCloseReq();
  1844. }
  1845. HRESULT CALLBACK CWiaDataSrc::DeviceEventCallback(LONG lEvent,LPARAM lParam)
  1846. {
  1847. CWiaDataSrc *pDataSrc = NULL;
  1848. pDataSrc = (CWiaDataSrc *)lParam;
  1849. if (pDataSrc) {
  1850. pDataSrc->NotifyCloseReq();
  1851. return S_OK;
  1852. }
  1853. return E_FAIL;
  1854. }
  1855. DS_STATE CWiaDataSrc::SetTWAINState(DS_STATE NewTWAINState)
  1856. {
  1857. DBG_TRC(("(Transitioning From TWAIN STATE %d to TWAIN STATE %d)",m_dsState,NewTWAINState));
  1858. m_dsState = NewTWAINState;
  1859. return m_dsState;
  1860. }
  1861. DS_STATE CWiaDataSrc::GetTWAINState()
  1862. {
  1863. return m_dsState;
  1864. }
  1865. TW_UINT16 CWiaDataSrc::SetStatusTWCC(TW_UINT16 NewConditionCode)
  1866. {
  1867. m_twStatus.ConditionCode = NewConditionCode;
  1868. return NewConditionCode;
  1869. }
  1870. float CWiaDataSrc::ConvertToTWAINUnits(LONG lValue, LONG lResolution)
  1871. {
  1872. float fReturnValue = 0.0f;
  1873. CCap *pUnits = FindCap(ICAP_UNITS);
  1874. if(pUnits){
  1875. switch (pUnits->GetCurrent()) {
  1876. case TWUN_INCHES:
  1877. fReturnValue = (float)lValue / (float)lResolution;
  1878. break;
  1879. case TWUN_CENTIMETERS:
  1880. fReturnValue = (float)((lValue * 2.54) / (float)lResolution);
  1881. break;
  1882. case TWUN_PICAS:
  1883. fReturnValue = (float)((lValue * 6.00) / (float)lResolution);
  1884. break;
  1885. case TWUN_POINTS:
  1886. fReturnValue = (float)(((float)lValue * 72.0) / (float)lResolution);
  1887. break;
  1888. case TWUN_PIXELS:
  1889. default:
  1890. fReturnValue = (float)lValue;
  1891. break;
  1892. }
  1893. }
  1894. return fReturnValue;
  1895. }
  1896. LONG CWiaDataSrc::ConvertFromTWAINUnits(float fValue, LONG lResolution)
  1897. {
  1898. LONG lReturnValue = 0;
  1899. CCap *pUnits = FindCap(ICAP_UNITS);
  1900. if (pUnits) {
  1901. switch (pUnits->GetCurrent()) {
  1902. case TWUN_INCHES:
  1903. lReturnValue = (LONG)((float)fValue * (float)lResolution);
  1904. break;
  1905. case TWUN_CENTIMETERS:
  1906. lReturnValue = (LONG)(((float)fValue / 2.54) * (float)lResolution);
  1907. break;
  1908. case TWUN_PICAS:
  1909. lReturnValue = (LONG)(((float)fValue / 6.00) * (float)lResolution);
  1910. break;
  1911. case TWUN_POINTS:
  1912. lReturnValue = (LONG)(((float)fValue / 72.0) * (float)lResolution);
  1913. break;
  1914. case TWUN_PIXELS:
  1915. default:
  1916. lReturnValue = (LONG)fValue;
  1917. break;
  1918. }
  1919. }
  1920. return lReturnValue;
  1921. }
  1922. DWORD CWiaDataSrc::ReadTwainRegistryDWORDValue(LPTSTR szRegValue, DWORD dwDefault)
  1923. {
  1924. DBG_FN_DS(CWiaDataSrc::ReadTwainRegistryDWORDValue());
  1925. DWORD dwValue = 0;
  1926. DWORD dwType = REG_DWORD;
  1927. DWORD dwDataSize = sizeof(DWORD);
  1928. DWORD dwDisposition = REG_OPENED_EXISTING_KEY;
  1929. HKEY hTwainRootKey = NULL;
  1930. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER,TWAIN_REG_KEY,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
  1931. NULL,&hTwainRootKey,&dwDisposition)){
  1932. if(dwDisposition == REG_CREATED_NEW_KEY){
  1933. DBG_WRN(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Created Root Twain Registry Key"));
  1934. }
  1935. if (ERROR_SUCCESS == RegQueryValueEx(hTwainRootKey,szRegValue,NULL,&dwType,(BYTE*)&dwValue,&dwDataSize)) {
  1936. #ifdef UNICODE
  1937. DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Reading %ws Registry Key Value = %d",szRegValue,dwValue));
  1938. #else
  1939. DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Reading %s Registry Key Value = %d",szRegValue,dwValue));
  1940. #endif
  1941. } else {
  1942. // reset sizes, just for safety
  1943. dwType = REG_DWORD;
  1944. dwDataSize = sizeof(DWORD);
  1945. dwValue = dwDefault;
  1946. if(ERROR_SUCCESS == RegSetValueEx(hTwainRootKey,szRegValue,NULL,dwType,(BYTE*)&dwDefault,dwDataSize)){
  1947. #ifdef UNICODE
  1948. DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Writing Default Value for %ws Registry Key Value = %d",szRegValue,dwDefault));
  1949. #else
  1950. DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Writing Default Value for %s Registry Key Value = %d",szRegValue,dwDefault));
  1951. #endif
  1952. } else {
  1953. #ifdef UNICODE
  1954. DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Error Reading %ws Registry Key Value",szRegValue));
  1955. #else
  1956. DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Error Reading %s Registry Key Value",szRegValue));
  1957. #endif
  1958. }
  1959. }
  1960. RegCloseKey(hTwainRootKey);
  1961. hTwainRootKey = NULL;
  1962. } else {
  1963. DBG_ERR(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), could not open Root TWAIN Registry Key"));
  1964. }
  1965. return dwValue;
  1966. }
  1967. LONG CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice(LONG **ppCapArray)
  1968. {
  1969. DBG_FN_DS(CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice());
  1970. if (!ppCapArray) {
  1971. DBG_ERR(("CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice(), ppCapArray is NULL"));
  1972. return 0;
  1973. }
  1974. *ppCapArray = NULL;
  1975. LONG lNumPrivateCaps = 0;
  1976. if (m_pDevice) {
  1977. if (m_pDevice->TwainCapabilityPassThrough()) {
  1978. if (m_pCurrentIWiaItem) {
  1979. //
  1980. // Get the IWiaItemExtras Interface
  1981. //
  1982. IWiaItemExtras *pIWiaItemExtras = NULL;
  1983. HRESULT hr = m_pCurrentIWiaItem->QueryInterface(IID_IWiaItemExtras,(void **)&pIWiaItemExtras);
  1984. if (S_OK == hr) {
  1985. //
  1986. // set data sizes
  1987. //
  1988. DWORD dwInDataSize = 0;
  1989. DWORD dwOutDataSize = 0;
  1990. DWORD dwActualOutDataSize = 0;
  1991. BYTE *pInData = NULL;
  1992. BYTE *pOutData = NULL;
  1993. LONG lCapabilityDataSize = sizeof(LONG);
  1994. pOutData = (BYTE*)&lCapabilityDataSize;
  1995. pInData = (BYTE*)&lCapabilityDataSize;
  1996. dwActualOutDataSize = sizeof(LONG);
  1997. dwInDataSize = dwActualOutDataSize;
  1998. dwOutDataSize = dwActualOutDataSize;
  1999. //
  2000. // ask how many bytes are needed to store the private TWAIN capabilities the WIA driver supports
  2001. //
  2002. hr = pIWiaItemExtras->Escape(ESC_TWAIN_PRIVATE_SUPPORTED_CAPS,
  2003. pInData,
  2004. dwInDataSize,
  2005. pOutData,
  2006. dwOutDataSize,
  2007. &dwActualOutDataSize);
  2008. if (S_OK == hr) {
  2009. lCapabilityDataSize = (LONG)(*pOutData);
  2010. lNumPrivateCaps = (lCapabilityDataSize / sizeof(LONG));
  2011. DBG_TRC(("WIA device reported %d private TWAIN supported CAPS",lNumPrivateCaps));
  2012. if (lNumPrivateCaps > 0) {
  2013. //
  2014. // allocate an array of LONGs for the WIA driver to fill with
  2015. // CAP ids.
  2016. //
  2017. dwOutDataSize = (lCapabilityDataSize + PRIVATE_CAP_ARRAY_PADDING);
  2018. dwActualOutDataSize = dwOutDataSize;
  2019. *ppCapArray = (LONG*)GlobalAlloc(GPTR,dwOutDataSize);
  2020. if (*ppCapArray) {
  2021. pOutData = (BYTE*)*ppCapArray;
  2022. //
  2023. // ask the WIA driver to fill the array of LONGS
  2024. //
  2025. hr = pIWiaItemExtras->Escape(ESC_TWAIN_PRIVATE_SUPPORTED_CAPS,
  2026. pInData,
  2027. dwInDataSize,
  2028. pOutData,
  2029. dwOutDataSize,
  2030. &dwActualOutDataSize);
  2031. if (FAILED(hr)) {
  2032. //
  2033. // pIWiaItemExtras->Escape call failed,
  2034. // a failure means that there are no private supported capabilities
  2035. //
  2036. DBG_ERR(("pIWiaItemExtras->Escape Failed (sending a request for the cability array data)"));
  2037. DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)",
  2038. ESC_TWAIN_PRIVATE_SUPPORTED_CAPS,
  2039. pInData,
  2040. dwInDataSize,
  2041. pOutData,
  2042. dwOutDataSize,
  2043. dwActualOutDataSize));
  2044. }
  2045. } else {
  2046. DBG_ERR(("could not allocate memory for private capability array of %d items (%d bytes - this includes padding)",lNumPrivateCaps,dwOutDataSize));
  2047. lNumPrivateCaps = 0;
  2048. *ppCapArray = NULL;
  2049. }
  2050. } else {
  2051. //
  2052. // no supported caps
  2053. //
  2054. DBG_TRC(("No private supported caps reported from WIA device"));
  2055. }
  2056. } else {
  2057. //
  2058. // pIWiaItemExtras->Escape call failed,
  2059. // a failure means that there are no private supported capabilities
  2060. //
  2061. DBG_ERR(("pIWiaItemExtras->Escape Failed (sending a request for the number of capabilities)"));
  2062. DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)",
  2063. ESC_TWAIN_PRIVATE_SUPPORTED_CAPS,
  2064. pInData,
  2065. dwInDataSize,
  2066. pOutData,
  2067. dwOutDataSize,
  2068. dwActualOutDataSize));
  2069. }
  2070. //
  2071. // release IWiaItemExtras Interface
  2072. //
  2073. if (pIWiaItemExtras) {
  2074. pIWiaItemExtras->Release();
  2075. pIWiaItemExtras = NULL;
  2076. }
  2077. } else {
  2078. //
  2079. // QI for IWiaItemExtras Failed
  2080. //
  2081. DBG_ERR(("QueryInterface for IWiaItemExtras Failed"));
  2082. }
  2083. } else {
  2084. //
  2085. // no current item selected
  2086. //
  2087. DBG_ERR(("no current item selected for use"));
  2088. }
  2089. }
  2090. } else {
  2091. //
  2092. // m_pDevice is NULL
  2093. //
  2094. DBG_ERR(("CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice(), m_pDevice is NULL"));
  2095. }
  2096. return lNumPrivateCaps;
  2097. }
  2098. TW_UINT16 CWiaDataSrc::TransferToFile(GUID guidFormatID)
  2099. {
  2100. DBG_FN_DS(CWiaDataSrc::TransferToFile());
  2101. TW_UINT16 twRc = TWRC_FAILURE;
  2102. HRESULT hr = E_FAIL;
  2103. CWiaDataCallback DataCallback;
  2104. CCap *pCap = NULL;
  2105. pCap = FindCap(CAP_INDICATORS);
  2106. if(pCap){
  2107. DataCallback.Initialize(NULL,pCap->GetCurrent());
  2108. } else {
  2109. DataCallback.Initialize(NULL,TRUE);
  2110. }
  2111. IWiaDataCallback *pIDataCB = NULL;
  2112. hr = DataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIDataCB);
  2113. if (SUCCEEDED(hr)) {
  2114. hr = m_pDevice->LoadImageToDisk(m_pCurrentIWiaItem, m_FileXferName, guidFormatID, pIDataCB);
  2115. if (SUCCEEDED(hr)) {
  2116. twRc = TWRC_XFERDONE;
  2117. m_twStatus.ConditionCode = TWCC_SUCCESS;
  2118. }
  2119. pIDataCB->Release();
  2120. pIDataCB = NULL;
  2121. }
  2122. //
  2123. // check for a cancel, or out-of-paper error (scanners could return this)
  2124. //
  2125. if ((S_FALSE == hr) || (WIA_ERROR_PAPER_EMPTY == hr)) {
  2126. m_twStatus.ConditionCode = TWCC_SUCCESS;
  2127. if(WIA_ERROR_PAPER_EMPTY == hr) {
  2128. DBG_TRC(("CWiaDataSrc::TransferToFile(), WIA_ERROR_PAPER_EMPTY returned from source."));
  2129. }
  2130. //
  2131. // set XFERCOUNT
  2132. //
  2133. CCap *pxferCap = FindCap(CAP_XFERCOUNT);
  2134. if (pxferCap) {
  2135. pxferCap->SetCurrent((TW_UINT32)0);
  2136. }
  2137. //
  2138. // return a cancel to abort the transfer.
  2139. // Applications will most commonly delete the current
  2140. // image, and keep the previous images.
  2141. //
  2142. twRc = TWRC_CANCEL;
  2143. } else if (FAILED(hr)) {
  2144. m_twStatus.ConditionCode = TWCC_FROM_HRESULT(hr);
  2145. twRc = TWRC_FAILURE;
  2146. }
  2147. return twRc;
  2148. }
  2149. TW_UINT16 CWiaDataSrc::TransferToDIB(HGLOBAL *phDIB)
  2150. {
  2151. DBG_FN_DS(CWiaDataSrc::TransferToDIB());
  2152. TW_UINT16 twRc = TWRC_FAILURE;
  2153. HRESULT hr = E_FAIL;
  2154. CWiaDataCallback DataCallback;
  2155. CCap *pCap = NULL;
  2156. pCap = FindCap(CAP_INDICATORS);
  2157. if(pCap){
  2158. DataCallback.Initialize(NULL,pCap->GetCurrent());
  2159. } else {
  2160. DataCallback.Initialize(NULL,TRUE);
  2161. }
  2162. IWiaDataCallback *pIDataCB = NULL;
  2163. hr = DataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIDataCB);
  2164. if (SUCCEEDED(hr)) {
  2165. hr = m_pDevice->LoadImage(m_pCurrentIWiaItem, WiaImgFmt_MEMORYBMP, pIDataCB); // memory bmp only
  2166. if (SUCCEEDED(hr)) {
  2167. if(SUCCEEDED(DataCallback.GetImage(phDIB, NULL))){
  2168. //
  2169. // DIB data (special case) - NATIVE TWAIN transfers are in DIB format always
  2170. // If we are acquiring DIB data, then we have to apply the
  2171. // height rules:
  2172. // positive = image is right side up
  2173. // negative = image is up side down
  2174. // zero = image has an unknown length (and assumed to be upside down)
  2175. if(FlipDIB(*phDIB)){
  2176. twRc = TWRC_XFERDONE;
  2177. m_ImageHeight = (TW_UINT32)DataCallback.GetImageHeight();
  2178. m_ImageWidth = (TW_UINT32)DataCallback.GetImageWidth();
  2179. }
  2180. }
  2181. }
  2182. pIDataCB->Release();
  2183. pIDataCB = NULL;
  2184. }
  2185. //
  2186. // check for a cancel, or out-of-paper error (scanners could return this)
  2187. //
  2188. if ((S_FALSE == hr) || (WIA_ERROR_PAPER_EMPTY == hr)) {
  2189. m_twStatus.ConditionCode = TWCC_SUCCESS;
  2190. if(WIA_ERROR_PAPER_EMPTY == hr) {
  2191. DBG_TRC(("CWiaDataSrc::TransferToDIB(), WIA_ERROR_PAPER_EMPTY returned from source."));
  2192. }
  2193. //
  2194. // set XFERCOUNT
  2195. //
  2196. CCap *pxferCap = FindCap(CAP_XFERCOUNT);
  2197. if (pxferCap) {
  2198. pxferCap->SetCurrent((TW_UINT32)0);
  2199. }
  2200. //
  2201. // return a cancel to abort the transfer.
  2202. // Applications will most commonly delete the current
  2203. // image, and keep the previous images.
  2204. //
  2205. twRc = TWRC_CANCEL;
  2206. } else if (FAILED(hr)) {
  2207. m_twStatus.ConditionCode = TWCC_FROM_HRESULT(hr);
  2208. twRc = TWRC_FAILURE;
  2209. }
  2210. return twRc;
  2211. }
  2212. TW_UINT16 CWiaDataSrc::TransferToMemory(GUID guidFormatID)
  2213. {
  2214. DBG_FN_DS(CWiaDataSrc::TransferToMemory());
  2215. //
  2216. // set WIA format in Transfer Information structure
  2217. //
  2218. m_MemoryTransferInfo.mtiguidFormat = guidFormatID;
  2219. TW_UINT16 twRc = TWRC_FAILURE;
  2220. HRESULT hr = E_FAIL;
  2221. CWiaDataCallback DataCallback;
  2222. CCap *pCap = NULL;
  2223. pCap = FindCap(CAP_INDICATORS);
  2224. if(pCap){
  2225. DataCallback.Initialize(NULL,pCap->GetCurrent());
  2226. } else {
  2227. DataCallback.Initialize(NULL,TRUE);
  2228. }
  2229. IWiaDataCallback *pIDataCB = NULL;
  2230. hr = DataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIDataCB);
  2231. if (SUCCEEDED(hr)) {
  2232. hr = m_pDevice->LoadImage(m_pCurrentIWiaItem, guidFormatID, pIDataCB);
  2233. if (SUCCEEDED(hr)) {
  2234. if(SUCCEEDED(DataCallback.GetImage(&m_hMemXferBits, NULL))){
  2235. //
  2236. // check for DIB data (special case)
  2237. // If we are acquiring DIB data, then we have to apply the
  2238. // height rules:
  2239. // positive = image is right side up
  2240. // negative = image is up side down
  2241. // zero = image has an unknown length (and assumed to be upside down)
  2242. if(WiaImgFmt_MEMORYBMP == guidFormatID){
  2243. //
  2244. // for memory transfers we need to make sure that the image
  2245. // is upside down in memory, so the application can assemble
  2246. // the bands correctly.
  2247. //
  2248. FlipDIB(m_hMemXferBits, TRUE);
  2249. }
  2250. m_ImageHeight = (TW_UINT32)DataCallback.GetImageHeight();
  2251. m_ImageWidth = (TW_UINT32)DataCallback.GetImageWidth();
  2252. m_hCachedImageData = m_hMemXferBits;
  2253. twRc = TWRC_SUCCESS;
  2254. }
  2255. }
  2256. pIDataCB->Release();
  2257. pIDataCB = NULL;
  2258. }
  2259. //
  2260. // check for a cancel, or out-of-paper error (scanners could return this)
  2261. //
  2262. if ((S_FALSE == hr) || (WIA_ERROR_PAPER_EMPTY == hr)) {
  2263. m_twStatus.ConditionCode = TWCC_SUCCESS;
  2264. if(WIA_ERROR_PAPER_EMPTY == hr) {
  2265. DBG_TRC(("CWiaDataSrc::TransferToMemory(), WIA_ERROR_PAPER_EMPTY returned from source."));
  2266. }
  2267. //
  2268. // set XFERCOUNT
  2269. //
  2270. CCap *pxferCap = FindCap(CAP_XFERCOUNT);
  2271. if (pxferCap) {
  2272. pxferCap->SetCurrent((TW_UINT32)0);
  2273. }
  2274. //
  2275. // return a cancel to abort the transfer.
  2276. // Applications will most commonly delete the current
  2277. // image, and keep the previous images.
  2278. //
  2279. twRc = TWRC_CANCEL;
  2280. } else if (FAILED(hr)) {
  2281. m_twStatus.ConditionCode = TWCC_FROM_HRESULT(hr);
  2282. twRc = TWRC_FAILURE;
  2283. }
  2284. return twRc;
  2285. }
  2286. TW_UINT16 CWiaDataSrc::GetCachedImage(HGLOBAL *phImage)
  2287. {
  2288. DBG_FN_DS(CWiaDataSrc::GetCachedImage());
  2289. TW_UINT16 twRc = TWRC_FAILURE;
  2290. if(phImage){
  2291. if (m_hCachedImageData) {
  2292. *phImage = m_hCachedImageData;
  2293. //
  2294. // since we are giving out the cached data
  2295. // reset the cache handle to NULL;
  2296. //
  2297. m_hCachedImageData = NULL;
  2298. m_hMemXferBits = NULL;
  2299. twRc = TWRC_SUCCESS;
  2300. }
  2301. }
  2302. return twRc;
  2303. }
  2304. TW_UINT16 CWiaDataSrc::TransferToThumbnail(HGLOBAL *phThumbnail)
  2305. {
  2306. DBG_FN_DS(CWiaDataSrc::TransferToThumbnail());
  2307. TW_UINT16 twRc = TWRC_FAILURE;
  2308. HRESULT hr = E_FAIL;
  2309. hr = m_pDevice->LoadThumbnail(m_pCurrentIWiaItem,phThumbnail,NULL);
  2310. if (SUCCEEDED(hr)) {
  2311. twRc = TWRC_XFERDONE;
  2312. }
  2313. return twRc;
  2314. }
  2315. TW_UINT16 CWiaDataSrc::GetCommonSettings()
  2316. {
  2317. DBG_FN_DS(CWiaDataSrc::GetCommonSettings());
  2318. TW_UINT16 twRc = TWRC_FAILURE;
  2319. //
  2320. // Some TWAIN applications make the assumption that the TWAIN data source
  2321. // defaults to BMP/DIB data formats. This is on the basis that TWAIN
  2322. // spec minimal requirements are BMP/DIB. WIA minimal requirements are
  2323. // BMP/DIB. Set the current Format GUID to MEMORYBMP, and TYMED to
  2324. // TYMED_CALLBACK. This will set the WIA driver to transfer bitmap data
  2325. // by default. This does not limit the data types in any way. A high
  2326. // end application will properly read the valid TWAIN values and configure
  2327. // the device to do the correct thing.
  2328. //
  2329. //
  2330. // before configuring TWAIN valid values, set the WIA device to TYMED_CALLBACK, MEMORYBMP.
  2331. //
  2332. HRESULT hr = S_OK;
  2333. CWiahelper WIA;
  2334. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  2335. if (FAILED(hr)) {
  2336. DBG_ERR(("CWiaDataSrc::GetCommonSettings(), failed to set IWiaItem for property writing"));
  2337. return twRc;
  2338. }
  2339. hr = WIA.WritePropertyLong(WIA_IPA_TYMED,TYMED_CALLBACK);
  2340. if(FAILED(hr)){
  2341. DBG_ERR(("CWiaDataSrc::GetCommonSettings(), failed to set TYMED_CALLBACK as a default setting"));
  2342. return twRc;
  2343. }
  2344. hr = WIA.WritePropertyGUID(WIA_IPA_FORMAT,WiaImgFmt_MEMORYBMP);
  2345. if(FAILED(hr)){
  2346. DBG_ERR(("CWiaDataSrc::GetCommonSettings(), failed to set WiaImgFmt_MEMORYBMP as a default setting"));
  2347. return twRc;
  2348. }
  2349. if (TWRC_SUCCESS == GetPixelTypes()) {
  2350. if (TWRC_SUCCESS == GetCompressionTypes()) {
  2351. if (TWRC_SUCCESS == GetBitDepths()) {
  2352. if (TWRC_SUCCESS == GetImageFileFormats()) {
  2353. twRc = TWRC_SUCCESS;
  2354. } else {
  2355. DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetImageFileFormats()"));
  2356. }
  2357. } else {
  2358. DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetBitDepths() failed"));
  2359. }
  2360. } else {
  2361. DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetCompressionTypes() failed"));
  2362. }
  2363. } else {
  2364. DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetPixelTypes() failed"));
  2365. }
  2366. return twRc;
  2367. }
  2368. TW_UINT16 CWiaDataSrc::GetCommonDefaultSettings()
  2369. {
  2370. DBG_FN_DS(CWiaDataSrc::GetCommonDefaultSettings());
  2371. TW_UINT16 twRc = TWRC_FAILURE;
  2372. CCap *pCap = NULL;
  2373. TW_UINT16 CapDataArray[1];
  2374. pCap = FindCap(ICAP_PIXELTYPE);
  2375. if (pCap) {
  2376. CapDataArray[0] = TWPT_RGB;
  2377. twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray);
  2378. if (TWRC_SUCCESS == twRc) {
  2379. pCap = FindCap(ICAP_COMPRESSION);
  2380. if (pCap) {
  2381. CapDataArray[0] = TWCP_NONE;
  2382. twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray);
  2383. pCap = FindCap(ICAP_BITDEPTH);
  2384. if (pCap) {
  2385. CapDataArray[0] = 24;
  2386. twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray);
  2387. if (TWRC_SUCCESS == twRc) {
  2388. pCap = FindCap(ICAP_IMAGEFILEFORMAT);
  2389. if (pCap) {
  2390. CapDataArray[0] = TWFF_BMP;
  2391. twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray);
  2392. if (TWRC_SUCCESS == twRc) {
  2393. }
  2394. }
  2395. }
  2396. }
  2397. }
  2398. }
  2399. }
  2400. return twRc;
  2401. }
  2402. TW_UINT16 CWiaDataSrc::GetPixelTypes()
  2403. {
  2404. DBG_FN_DS(CWiaScannerDS::GetPixelTypes());
  2405. TW_UINT16 twRc = TWRC_FAILURE;
  2406. CCap *pCap = FindCap(ICAP_PIXELTYPE);
  2407. if (pCap) {
  2408. HRESULT hr = S_OK;
  2409. CWiahelper WIA;
  2410. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  2411. if (FAILED(hr)) {
  2412. DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to set IWiaItem for property reading"));
  2413. return twRc;
  2414. }
  2415. TW_UINT32 ActualCount = 0;
  2416. TW_UINT32 CurrentIndex = 0;
  2417. TW_UINT32 DefaultIndex = 0;
  2418. TW_UINT16 *pPixelTypeArray = NULL;
  2419. //
  2420. // read current value, for default and current index settings
  2421. //
  2422. LONG lCurrentDataTypeValue = WIA_DATA_COLOR;
  2423. //
  2424. // read current WIA_IPA_DATATYPE setting
  2425. //
  2426. hr = WIA.ReadPropertyLong(WIA_IPA_DATATYPE,&lCurrentDataTypeValue);
  2427. if (SUCCEEDED(hr)) {
  2428. //
  2429. // read valid values for WIA_IPA_DATATYPE
  2430. //
  2431. PROPVARIANT pv;
  2432. memset(&pv,0,sizeof(pv));
  2433. LONG lAccessFlags = 0;
  2434. hr = WIA.ReadPropertyAttributes(WIA_IPA_DATATYPE,&lAccessFlags,&pv);
  2435. if (SUCCEEDED(hr)) {
  2436. if (lAccessFlags & WIA_PROP_LIST) {
  2437. //
  2438. // for each valid WIA value in the LIST, set a corresponding
  2439. // TWAIN value
  2440. //
  2441. pPixelTypeArray = new TW_UINT16[WIA_PROP_LIST_COUNT(&pv)];
  2442. if (pPixelTypeArray) {
  2443. memset(pPixelTypeArray,0,(sizeof(TW_UINT16)*WIA_PROP_LIST_COUNT(&pv)));
  2444. for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
  2445. switch (pv.caul.pElems[i+2]) {
  2446. case WIA_DATA_THRESHOLD:
  2447. pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_BW;
  2448. if (lCurrentDataTypeValue == WIA_DATA_THRESHOLD) {
  2449. CurrentIndex = ActualCount;
  2450. }
  2451. ActualCount++;
  2452. DBG_TRC(("WIA driver supports WIA_DATA_THERSHOLD -> TWPT_BW"));
  2453. break;
  2454. case WIA_DATA_GRAYSCALE:
  2455. pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_GRAY;
  2456. if (lCurrentDataTypeValue == WIA_DATA_GRAYSCALE) {
  2457. CurrentIndex = ActualCount;
  2458. }
  2459. ActualCount++;
  2460. DBG_TRC(("WIA driver supports WIA_DATA_GRAYSCALE -> TWPT_GRAY"));
  2461. break;
  2462. case WIA_DATA_COLOR:
  2463. pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_RGB;
  2464. if (lCurrentDataTypeValue == WIA_DATA_COLOR) {
  2465. CurrentIndex = ActualCount;
  2466. }
  2467. ActualCount++;
  2468. DBG_TRC(("WIA driver supports WIA_DATA_COLOR -> TWPT_RGB"));
  2469. break;
  2470. case WIA_DATA_DITHER:
  2471. case WIA_DATA_COLOR_THRESHOLD:
  2472. case WIA_DATA_COLOR_DITHER:
  2473. ////////////////////////////////
  2474. // NO TWAIN -> WIA CONVERSION //
  2475. ////////////////////////////////
  2476. //
  2477. // TWPT_PALETTE
  2478. // TWPT_CMY
  2479. // TWPT_CMYK
  2480. // TWPT_YUV
  2481. // TWPT_YUVK
  2482. // TWPT_CIEXYZ
  2483. default:
  2484. DBG_TRC(("WIA Data Type (%d) does not MAP to TWAIN a pixel type",pv.caul.pElems[i+2]));
  2485. break;
  2486. }
  2487. }
  2488. } else {
  2489. DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to allocate Pixel Type Array Memory"));
  2490. }
  2491. } else {
  2492. //
  2493. // we only have 1 value, so make it the current, default and valid value.
  2494. //
  2495. pPixelTypeArray = new TW_UINT16[1];
  2496. if (pPixelTypeArray) {
  2497. memset(pPixelTypeArray,0,(sizeof(TW_UINT16)));
  2498. switch (lCurrentDataTypeValue) {
  2499. case WIA_DATA_THRESHOLD:
  2500. pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_BW;
  2501. if (lCurrentDataTypeValue == WIA_DATA_THRESHOLD) {
  2502. CurrentIndex = ActualCount;
  2503. }
  2504. ActualCount++;
  2505. DBG_TRC(("WIA driver supports WIA_DATA_THERSHOLD -> TWPT_BW"));
  2506. break;
  2507. case WIA_DATA_GRAYSCALE:
  2508. pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_GRAY;
  2509. if (lCurrentDataTypeValue == WIA_DATA_GRAYSCALE) {
  2510. CurrentIndex = ActualCount;
  2511. }
  2512. ActualCount++;
  2513. DBG_TRC(("WIA driver supports WIA_DATA_GRAYSCALE -> TWPT_GRAY"));
  2514. break;
  2515. case WIA_DATA_COLOR:
  2516. pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_RGB;
  2517. if (lCurrentDataTypeValue == WIA_DATA_COLOR) {
  2518. CurrentIndex = ActualCount;
  2519. }
  2520. ActualCount++;
  2521. DBG_TRC(("WIA driver supports WIA_DATA_COLOR -> TWPT_RGB"));
  2522. break;
  2523. case WIA_DATA_DITHER:
  2524. case WIA_DATA_COLOR_THRESHOLD:
  2525. case WIA_DATA_COLOR_DITHER:
  2526. ////////////////////////////////
  2527. // NO TWAIN -> WIA CONVERSION //
  2528. ////////////////////////////////
  2529. //
  2530. // TWPT_PALETTE
  2531. // TWPT_CMY
  2532. // TWPT_CMYK
  2533. // TWPT_YUV
  2534. // TWPT_YUVK
  2535. // TWPT_CIEXYZ
  2536. default:
  2537. DBG_TRC(("WIA Data Type (%d) does not MAP to TWAIN a pixel type",lCurrentDataTypeValue));
  2538. break;
  2539. }
  2540. } else {
  2541. DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to allocate Pixel Type Array Memory"));
  2542. }
  2543. }
  2544. if (pPixelTypeArray) {
  2545. //
  2546. // default index is equal to current index, because we are stating that the WIA driver
  2547. // is a fresh start-up state.
  2548. //
  2549. DefaultIndex = CurrentIndex;
  2550. twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)pPixelTypeArray,TRUE); // list
  2551. delete [] pPixelTypeArray;
  2552. pPixelTypeArray = NULL;
  2553. //twRc = TWRC_SUCCESS;
  2554. }
  2555. PropVariantClear(&pv);
  2556. } else {
  2557. DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to read WIA_IPS_DATATYPE attributes"));
  2558. }
  2559. } else {
  2560. DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to read WIA_IPS_DATATYPE current value"));
  2561. }
  2562. }
  2563. return twRc;
  2564. }
  2565. TW_UINT16 CWiaDataSrc::GetBitDepths()
  2566. {
  2567. DBG_FN_DS(CWiaScannerDS::GetBitDepths());
  2568. TW_UINT16 twRc = TWRC_FAILURE;
  2569. CCap *pCap = FindCap(ICAP_BITDEPTH);
  2570. if (pCap) {
  2571. HRESULT hr = S_OK;
  2572. CWiahelper WIA;
  2573. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  2574. if (FAILED(hr)) {
  2575. DBG_ERR(("CWiaDataSrc::GetBitDepths(), failed to set IWiaItem for property reading"));
  2576. return twRc;
  2577. }
  2578. TW_UINT32 ActualCount = 0;
  2579. TW_UINT32 CurrentIndex = 0;
  2580. TW_UINT32 DefaultIndex = 0;
  2581. TW_UINT16 BitDepthArray[MAX_BITDEPTHS];
  2582. memset(BitDepthArray,0,sizeof(BitDepthArray));
  2583. //
  2584. // read current value, for default and current index settings
  2585. //
  2586. LONG lCurrentDataTypeValue = WIA_DATA_COLOR;
  2587. LONG lCurrentBitDepthValue = 24;
  2588. //
  2589. // read current WIA_IPA_DATATYPE setting
  2590. //
  2591. hr = WIA.ReadPropertyLong(WIA_IPA_DATATYPE,&lCurrentDataTypeValue);
  2592. if (SUCCEEDED(hr)) {
  2593. //
  2594. // read current WIA_IPA_DEPTH setting
  2595. //
  2596. hr = WIA.ReadPropertyLong(WIA_IPA_DEPTH,&lCurrentBitDepthValue);
  2597. if (SUCCEEDED(hr)) {
  2598. PROPVARIANT pv;
  2599. memset(&pv,0,sizeof(pv));
  2600. LONG lAccessFlags = 0;
  2601. //
  2602. // read valid values for WIA_IPA_DATATYPE
  2603. //
  2604. hr = WIA.ReadPropertyAttributes(WIA_IPA_DATATYPE,&lAccessFlags,&pv);
  2605. if (SUCCEEDED(hr)) {
  2606. //
  2607. // for each valid value, set it to the current setting, and read
  2608. // the valid values for WIA_IPA_DEPTH.
  2609. //
  2610. if (lAccessFlags & WIA_PROP_LIST) {
  2611. //
  2612. // set the WIA_IPA_DATATYPE to each valid value in the LIST
  2613. //
  2614. for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
  2615. hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,(LONG)pv.caul.pElems[i+2]);
  2616. if (SUCCEEDED(hr)) {
  2617. //
  2618. // read valid values for WIA_IPA_DEPTH
  2619. //
  2620. lAccessFlags = 0;
  2621. PROPVARIANT pvDepth;
  2622. memset(&pvDepth,0,sizeof(pvDepth));
  2623. hr = WIA.ReadPropertyAttributes(WIA_IPA_DEPTH,&lAccessFlags,&pvDepth);
  2624. if (SUCCEEDED(hr)) {
  2625. LONG lBitDepth = 0;
  2626. if (lAccessFlags & WIA_PROP_LIST) {
  2627. //
  2628. // copy each valid value in the LIST to the array
  2629. //
  2630. for (ULONG ulIndex = 0; ulIndex < WIA_PROP_LIST_COUNT(&pvDepth);ulIndex++) {
  2631. lBitDepth = pvDepth.caul.pElems[ulIndex+2];
  2632. for (ULONG BitDepthArrayIndex = 0; BitDepthArrayIndex < MAX_BITDEPTHS; BitDepthArrayIndex++) {
  2633. if (BitDepthArray[BitDepthArrayIndex] == 0) {
  2634. //
  2635. // the current slot is (0) zero, so add the new bit depth value
  2636. //
  2637. BitDepthArray[BitDepthArrayIndex] = (TW_UINT16)lBitDepth;
  2638. DBG_TRC(("WIA driver supports %d bit depth",lBitDepth));
  2639. ActualCount++;
  2640. //
  2641. // exit the loop
  2642. //
  2643. BitDepthArrayIndex = MAX_BITDEPTHS;
  2644. } else if (BitDepthArray[BitDepthArrayIndex] == (TW_UINT16)lBitDepth) {
  2645. //
  2646. // bit depth is already in the list, so exit the loop
  2647. //
  2648. BitDepthArrayIndex = MAX_BITDEPTHS;
  2649. }
  2650. }
  2651. }
  2652. } else if (lAccessFlags & WIA_PROP_NONE) {
  2653. //
  2654. // read the current value for WIA_IPA_DEPTH
  2655. // and copy it to the array
  2656. //
  2657. hr = WIA.ReadPropertyLong(WIA_IPA_DEPTH,&lBitDepth);
  2658. if (SUCCEEDED(hr)) {
  2659. for (ULONG BitDepthArrayIndex = 0; BitDepthArrayIndex < MAX_BITDEPTHS; BitDepthArrayIndex++) {
  2660. if (BitDepthArray[BitDepthArrayIndex] == 0) {
  2661. //
  2662. // the current slot is (0) zero, so add the new bit depth value
  2663. //
  2664. BitDepthArray[BitDepthArrayIndex] = (TW_UINT16)lBitDepth;
  2665. DBG_TRC(("WIA driver supports %d bit depth",lBitDepth));
  2666. ActualCount++;
  2667. //
  2668. // exit the loop
  2669. //
  2670. BitDepthArrayIndex = MAX_BITDEPTHS;
  2671. } else if (BitDepthArray[BitDepthArrayIndex] == (TW_UINT16)lBitDepth) {
  2672. //
  2673. // bit depth is already in the list, so exit the loop
  2674. //
  2675. BitDepthArrayIndex = MAX_BITDEPTHS;
  2676. }
  2677. }
  2678. } else {
  2679. DBG_ERR(("CWiaDataSrc::GetBitDepths(), ReadPropertyLong(WIA_IPA_DEPTH) failed"));
  2680. }
  2681. }
  2682. //
  2683. // clean up the PROPVARIANT structure
  2684. //
  2685. PropVariantClear(&pvDepth);
  2686. }
  2687. } else {
  2688. DBG_ERR(("CWiaDataSrc::GetBitDepths(), WritePropertyLong(WIA_IPA_DATATYPE) failed"));
  2689. }
  2690. }
  2691. } else {
  2692. //
  2693. // we only have 1 value, so make it the current, default and valid value.
  2694. //
  2695. BitDepthArray[0] = (TW_UINT16)lCurrentBitDepthValue;
  2696. ActualCount = 1;
  2697. DBG_TRC(("WIA driver supports %d bit depth",lCurrentBitDepthValue));
  2698. }
  2699. //
  2700. // set the current values back
  2701. //
  2702. hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,lCurrentDataTypeValue);
  2703. if (SUCCEEDED(hr)) {
  2704. hr = WIA.WritePropertyLong(WIA_IPA_DEPTH,lCurrentBitDepthValue);
  2705. }
  2706. for (ULONG BitDepthArrayIndex = 0; BitDepthArrayIndex < MAX_BITDEPTHS; BitDepthArrayIndex++) {
  2707. if (BitDepthArray[BitDepthArrayIndex] == (TW_UINT16)lCurrentBitDepthValue) {
  2708. CurrentIndex = BitDepthArrayIndex;
  2709. BitDepthArrayIndex = MAX_BITDEPTHS;
  2710. }
  2711. }
  2712. //
  2713. // default index is equal to current index, because we are stating that the WIA driver
  2714. // is a fresh start-up state.
  2715. //
  2716. DefaultIndex = CurrentIndex;
  2717. twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)BitDepthArray,TRUE); // list
  2718. //twRc = TWRC_SUCCESS;
  2719. PropVariantClear(&pv);
  2720. } else {
  2721. DBG_ERR(("CWiaDataSrc::GetBitDepths(), failed to read WIA_IPS_DATATYPE attributes"));
  2722. }
  2723. } else {
  2724. DBG_ERR(("CWiaDataSrc::GetBitDepths(), ReadPropertyLong(WIA_IPA_DEPTH) failed"));
  2725. }
  2726. } else {
  2727. DBG_ERR(("CWiaDataSrc::GetBitDepths(), ReadPropertyLong(WIA_IPA_DATATYPE) failed"));
  2728. }
  2729. }
  2730. return twRc;
  2731. }
  2732. TW_UINT16 CWiaDataSrc::GetImageFileFormats()
  2733. {
  2734. DBG_FN_DS(CWiaScannerDS::GetImageFileFormats());
  2735. TW_UINT16 twRc = TWRC_FAILURE;
  2736. CCap *pCap = FindCap(ICAP_IMAGEFILEFORMAT);
  2737. if (pCap) {
  2738. HRESULT hr = S_OK;
  2739. CWiahelper WIA;
  2740. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  2741. if (FAILED(hr)) {
  2742. DBG_ERR(("CWiaDataSrc::GetImageFileFormats(), failed to set IWiaItem for property reading"));
  2743. return twRc;
  2744. }
  2745. TW_UINT32 ActualCount = 0;
  2746. TW_UINT32 CurrentIndex = 0;
  2747. TW_UINT32 DefaultIndex = 0;
  2748. TW_UINT16 *pFileTypeArray = NULL;
  2749. IWiaDataTransfer *pIWiaDataTransfer = NULL;
  2750. TW_UINT32 TotalFileFormats = 0;
  2751. IEnumWIA_FORMAT_INFO *pIEnumWIA_FORMAT_INFO = NULL;
  2752. WIA_FORMAT_INFO pfe;
  2753. //
  2754. // read current value, for default and current index settings
  2755. //
  2756. GUID guidCurrentFileFormat = GUID_NULL;
  2757. hr = WIA.ReadPropertyGUID(WIA_IPA_FORMAT,&guidCurrentFileFormat);
  2758. if (SUCCEEDED(hr)) {
  2759. //
  2760. // collect valid values for image file format
  2761. //
  2762. hr = m_pCurrentIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer);
  2763. if (S_OK == hr) {
  2764. hr = pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO(&pIEnumWIA_FORMAT_INFO);
  2765. if (SUCCEEDED(hr)) {
  2766. //
  2767. // count supported FILE formats
  2768. //
  2769. do {
  2770. memset(&pfe,0,sizeof(pfe));
  2771. hr = pIEnumWIA_FORMAT_INFO->Next(1, &pfe, NULL);
  2772. if (hr == S_OK) {
  2773. if ((pfe.lTymed == TYMED_FILE) || (pfe.lTymed == TYMED_MULTIPAGE_FILE)) {
  2774. TotalFileFormats++;
  2775. }
  2776. }
  2777. } while (hr == S_OK);
  2778. //
  2779. // allocate supported FILE format array
  2780. //
  2781. pFileTypeArray = new TW_UINT16[TotalFileFormats];
  2782. if (pFileTypeArray) {
  2783. memset(pFileTypeArray,0,(sizeof(TW_UINT16) * TotalFileFormats));
  2784. //
  2785. // reset enuerator
  2786. //
  2787. hr = pIEnumWIA_FORMAT_INFO->Reset();
  2788. if (SUCCEEDED(hr)) {
  2789. do {
  2790. memset(&pfe,0,sizeof(pfe));
  2791. hr = pIEnumWIA_FORMAT_INFO->Next(1, &pfe, NULL);
  2792. if (hr == S_OK) {
  2793. if (pfe.lTymed == TYMED_MULTIPAGE_FILE) {
  2794. if (pfe.guidFormatID == WiaImgFmt_TIFF) {
  2795. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_TIFFMULTI;
  2796. if (guidCurrentFileFormat == WiaImgFmt_TIFF) {
  2797. CurrentIndex = ActualCount;
  2798. }
  2799. ActualCount++;
  2800. DBG_TRC(("WIA driver supports WiaImgFmt_TIFF (Multipage) -> TWFF_TIFFMULTI"));
  2801. }
  2802. }
  2803. if (pfe.lTymed == TYMED_FILE) {
  2804. if (pfe.guidFormatID == WiaImgFmt_BMP) {
  2805. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_BMP;
  2806. if (guidCurrentFileFormat == WiaImgFmt_BMP) {
  2807. CurrentIndex = ActualCount;
  2808. }
  2809. ActualCount++;
  2810. DBG_TRC(("WIA driver supports WiaImgFmt_BMP -> TWFF_BMP"));
  2811. } else if (pfe.guidFormatID == WiaImgFmt_JPEG) {
  2812. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_JFIF;
  2813. if (guidCurrentFileFormat == WiaImgFmt_JPEG) {
  2814. CurrentIndex = ActualCount;
  2815. }
  2816. ActualCount++;
  2817. DBG_TRC(("WIA driver supports WiaImgFmt_JPEG -> TWFF_JFIF"));
  2818. } else if (pfe.guidFormatID == WiaImgFmt_TIFF) {
  2819. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_TIFF;
  2820. if (guidCurrentFileFormat == WiaImgFmt_TIFF) {
  2821. CurrentIndex = ActualCount;
  2822. }
  2823. ActualCount++;
  2824. DBG_TRC(("WIA driver supports WiaImgFmt_TIFF -> TWFF_TIFF"));
  2825. } else if (pfe.guidFormatID == WiaImgFmt_PICT) {
  2826. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_PICT;
  2827. if (guidCurrentFileFormat == WiaImgFmt_PICT) {
  2828. CurrentIndex = ActualCount;
  2829. }
  2830. ActualCount++;
  2831. DBG_TRC(("WIA driver supports WiaImgFmt_PICT -> TWFF_PICT"));
  2832. } else if (pfe.guidFormatID == WiaImgFmt_PNG) {
  2833. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_PNG;
  2834. if (guidCurrentFileFormat == WiaImgFmt_PNG) {
  2835. CurrentIndex = ActualCount;
  2836. }
  2837. ActualCount++;
  2838. DBG_TRC(("WIA driver supports WiaImgFmt_PNG -> WiaImgFmt_PNG"));
  2839. } else if (pfe.guidFormatID == WiaImgFmt_EXIF) {
  2840. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_EXIF;
  2841. if (guidCurrentFileFormat == WiaImgFmt_EXIF) {
  2842. CurrentIndex = ActualCount;
  2843. }
  2844. ActualCount++;
  2845. DBG_TRC(("WIA driver supports WiaImgFmt_EXIF -> TWFF_EXIF"));
  2846. } else if (pfe.guidFormatID == WiaImgFmt_FLASHPIX) {
  2847. pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_FPX;
  2848. if (guidCurrentFileFormat == WiaImgFmt_FLASHPIX) {
  2849. CurrentIndex = ActualCount;
  2850. }
  2851. ActualCount++;
  2852. DBG_TRC(("WIA driver supports WiaImgFmt_FLASHPIX -> TWFF_FPX"));
  2853. } else if (pfe.guidFormatID == WiaImgFmt_UNDEFINED) {
  2854. DBG_TRC(("WIA File Format WiaImgFmt_UNDEFINED does not MAP to TWAIN a file format"));
  2855. } else if (pfe.guidFormatID == WiaImgFmt_EMF) {
  2856. DBG_TRC(("WIA File Format WiaImgFmt_EMF does not MAP to TWAIN a file format"));
  2857. } else if (pfe.guidFormatID == WiaImgFmt_WMF) {
  2858. DBG_TRC(("WIA File Format WiaImgFmt_WMF does not MAP to TWAIN a file format"));
  2859. } else if (pfe.guidFormatID == WiaImgFmt_GIF) {
  2860. DBG_TRC(("WIA File Format WiaImgFmt_GIF does not MAP to TWAIN a file format"));
  2861. } else if (pfe.guidFormatID == WiaImgFmt_PHOTOCD) {
  2862. DBG_TRC(("WIA File Format WiaImgFmt_PHOTOCD does not MAP to TWAIN a file format"));
  2863. } else if (pfe.guidFormatID == WiaImgFmt_ICO) {
  2864. DBG_TRC(("WIA File Format WiaImgFmt_ICO does not MAP to TWAIN a file format"));
  2865. } else if (pfe.guidFormatID == WiaImgFmt_CIFF) {
  2866. DBG_TRC(("WIA File Format WiaImgFmt_CIFF does not MAP to TWAIN a file format"));
  2867. } else if (pfe.guidFormatID == WiaImgFmt_JPEG2K) {
  2868. DBG_TRC(("WIA File Format WiaImgFmt_JPEG2K does not MAP to TWAIN a file format"));
  2869. } else if (pfe.guidFormatID == WiaImgFmt_JPEG2KX) {
  2870. DBG_TRC(("WIA File Format WiaImgFmt_JPEG2KX does not MAP to TWAIN a file format"));
  2871. } else {
  2872. }
  2873. ////////////////////////////////
  2874. // NO TWAIN -> WIA CONVERSION //
  2875. ////////////////////////////////
  2876. //
  2877. // TWFF_XBM
  2878. // TWFF_SPIFF
  2879. }
  2880. }
  2881. } while (hr == S_OK);
  2882. }
  2883. if (pFileTypeArray) {
  2884. //
  2885. // default index is equal to current index, because we are stating that the WIA driver
  2886. // is a fresh start-up state.
  2887. //
  2888. DefaultIndex = CurrentIndex;
  2889. twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)pFileTypeArray,TRUE); // list
  2890. delete [] pFileTypeArray;
  2891. pFileTypeArray = NULL;
  2892. //twRc = TWRC_SUCCESS;
  2893. }
  2894. }
  2895. pIEnumWIA_FORMAT_INFO->Release();
  2896. pIEnumWIA_FORMAT_INFO = NULL;
  2897. } else {
  2898. DBG_ERR(("CWiaDataSrc::GetImageFileFormats(), pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO() failed to enumerate supported file formats"));
  2899. }
  2900. pIWiaDataTransfer->Release();
  2901. pIWiaDataTransfer = NULL;
  2902. } else {
  2903. DBG_ERR(("CWiaDataSrc::GetImageFileFormats(), QueryInterface(IID_IWiaDataTransfer) failed"));
  2904. }
  2905. }
  2906. }
  2907. return twRc;
  2908. }
  2909. TW_UINT16 CWiaDataSrc::GetCompressionTypes()
  2910. {
  2911. DBG_FN_DS(CWiaScannerDS::GetCompressionTypes());
  2912. TW_UINT16 twRc = TWRC_FAILURE;
  2913. CCap *pCap = FindCap(ICAP_COMPRESSION);
  2914. if (pCap) {
  2915. #ifdef SUPPORT_COMPRESSION_TYPES
  2916. HRESULT hr = S_OK;
  2917. CWiahelper WIA;
  2918. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  2919. if (FAILED(hr)) {
  2920. DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to set IWiaItem for property reading"));
  2921. return twRc;
  2922. }
  2923. TW_UINT32 ActualCount = 0;
  2924. TW_UINT32 CurrentIndex = 0;
  2925. TW_UINT32 DefaultIndex = 0;
  2926. TW_UINT16 *pCompressionTypeArray = NULL;
  2927. //
  2928. // read current value, for default and current index settings
  2929. //
  2930. LONG lCurrentCompressionTypeValue = WIA_COMPRESSION_NONE;
  2931. hr = WIA.ReadPropertyLong(WIA_IPA_COMPRESSION,&lCurrentCompressionTypeValue);
  2932. if (SUCCEEDED(hr)) {
  2933. PROPVARIANT pv;
  2934. memset(&pv,0,sizeof(pv));
  2935. LONG lAccessFlags = 0;
  2936. hr = WIA.ReadPropertyAttributes(WIA_IPA_COMPRESSION,&lAccessFlags,&pv);
  2937. if (SUCCEEDED(hr)) {
  2938. //
  2939. // collect valid values for compression type
  2940. //
  2941. if (lAccessFlags & WIA_PROP_LIST) {
  2942. pCompressionTypeArray = new TW_UINT16[WIA_PROP_LIST_COUNT(&pv)];
  2943. if (pCompressionTypeArray) {
  2944. memset(pCompressionTypeArray,0,(sizeof(TW_UINT16)*WIA_PROP_LIST_COUNT(&pv)));
  2945. for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
  2946. switch (pv.caul.pElems[i+2]) {
  2947. case WIA_COMPRESSION_NONE:
  2948. pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_NONE;
  2949. if (lCurrentCompressionTypeValue == WIA_COMPRESSION_NONE) {
  2950. CurrentIndex = ActualCount;
  2951. }
  2952. ActualCount++;
  2953. DBG_TRC(("WIA driver supports WIA_COMPRESSION_NONE -> TWCP_NONE"));
  2954. break;
  2955. case WIA_COMPRESSION_G3:
  2956. pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_GROUP31D;
  2957. if (lCurrentCompressionTypeValue == WIA_COMPRESSION_G3) {
  2958. CurrentIndex = ActualCount;
  2959. }
  2960. ActualCount++;
  2961. DBG_TRC(("WIA driver supports WIA_COMPRESSION_G3 -> TWCP_GROUP31D"));
  2962. break;
  2963. case WIA_COMPRESSION_G4:
  2964. pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_GROUP4;
  2965. if (lCurrentCompressionTypeValue == WIA_COMPRESSION_G4) {
  2966. CurrentIndex = ActualCount;
  2967. }
  2968. ActualCount++;
  2969. DBG_TRC(("WIA driver supports WIA_COMPRESSION_G4 -> TWCP_GROUP4"));
  2970. break;
  2971. case WIA_COMPRESSION_JPEG:
  2972. pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_JPEG;
  2973. if (lCurrentCompressionTypeValue == WIA_COMPRESSION_JPEG) {
  2974. CurrentIndex = ActualCount;
  2975. }
  2976. ActualCount++;
  2977. DBG_TRC(("WIA driver supports WIA_COMPRESSION_JPEG -> TWCP_JPEG"));
  2978. break;
  2979. case WIA_COMPRESSION_BI_RLE4:
  2980. pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_RLE4;
  2981. if (lCurrentCompressionTypeValue == WIA_COMPRESSION_BI_RLE4) {
  2982. CurrentIndex = ActualCount;
  2983. }
  2984. ActualCount++;
  2985. DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE4 -> TWCP_RLE4"));
  2986. break;
  2987. case WIA_COMPRESSION_BI_RLE8:
  2988. pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_RLE8;
  2989. if (lCurrentCompressionTypeValue == WIA_COMPRESSION_BI_RLE8) {
  2990. CurrentIndex = ActualCount;
  2991. }
  2992. ActualCount++;
  2993. DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE8 -> TWCP_RLE8"));
  2994. break;
  2995. ////////////////////////////////
  2996. // NO TWAIN -> WIA CONVERSION //
  2997. ////////////////////////////////
  2998. //
  2999. // TWCP_PACKBITS
  3000. // TWCP_GROUP31D
  3001. // TWCP_GROUP31DEOL
  3002. // TWCP_GROUP32D
  3003. //
  3004. //
  3005. // TWCP_LZW
  3006. // TWCP_JBIG
  3007. default:
  3008. DBG_TRC(("WIA Compression Type (%d) does not MAP to TWAIN a compression type",pv.caul.pElems[i+2]));
  3009. break;
  3010. }
  3011. }
  3012. } else {
  3013. DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to allocate Compression Type Array Memory"));
  3014. }
  3015. } else {
  3016. //
  3017. // current value becomes the only valid value
  3018. //
  3019. CurrentIndex = 0;
  3020. ActualCount = 1;
  3021. pCompressionTypeArray = new TW_UINT16[1];
  3022. if (pCompressionTypeArray) {
  3023. switch (lCurrentCompressionTypeValue) {
  3024. case WIA_COMPRESSION_NONE:
  3025. pCompressionTypeArray[0] = (TW_UINT16)TWCP_NONE;
  3026. DBG_TRC(("WIA driver supports WIA_COMPRESSION_NONE -> TWCP_NONE"));
  3027. break;
  3028. case WIA_COMPRESSION_G3:
  3029. pCompressionTypeArray[0] = (TW_UINT16)TWCP_GROUP31D;
  3030. DBG_TRC(("WIA driver supports WIA_COMPRESSION_G3 -> TWCP_GROUP31D"));
  3031. break;
  3032. case WIA_COMPRESSION_G4:
  3033. pCompressionTypeArray[0] = (TW_UINT16)TWCP_GROUP4;
  3034. DBG_TRC(("WIA driver supports WIA_COMPRESSION_G4 -> TWCP_GROUP4"));
  3035. break;
  3036. case WIA_COMPRESSION_JPEG:
  3037. pCompressionTypeArray[0] = (TW_UINT16)TWCP_JPEG;
  3038. DBG_TRC(("WIA driver supports WIA_COMPRESSION_JPEG -> TWCP_JPEG"));
  3039. break;
  3040. case WIA_COMPRESSION_BI_RLE4:
  3041. pCompressionTypeArray[0] = (TW_UINT16)TWCP_RLE4;
  3042. DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE4 -> TWCP_RLE4"));
  3043. break;
  3044. case WIA_COMPRESSION_BI_RLE8:
  3045. pCompressionTypeArray[0] = (TW_UINT16)TWCP_RLE8;
  3046. DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE8 -> TWCP_RLE8"));
  3047. break;
  3048. ////////////////////////////////
  3049. // NO TWAIN -> WIA CONVERSION //
  3050. ////////////////////////////////
  3051. //
  3052. // TWCP_PACKBITS
  3053. // TWCP_GROUP31D
  3054. // TWCP_GROUP31DEOL
  3055. // TWCP_GROUP32D
  3056. //
  3057. //
  3058. // TWCP_LZW
  3059. // TWCP_JBIG
  3060. default:
  3061. DBG_TRC(("WIA Compression Type (%d) does not MAP to TWAIN a compression type",lCurrentCompressionTypeValue));
  3062. break;
  3063. }
  3064. }
  3065. }
  3066. if (pCompressionTypeArray) {
  3067. //
  3068. // default index is equal to current index, because we are stating that the WIA driver
  3069. // is a fresh start-up state.
  3070. //
  3071. DefaultIndex = CurrentIndex;
  3072. twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)pCompressionTypeArray,TRUE); // list
  3073. delete [] pCompressionTypeArray;
  3074. pCompressionTypeArray = NULL;
  3075. //twRc = TWRC_SUCCESS;
  3076. }
  3077. PropVariantClear(&pv);
  3078. } else {
  3079. DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to read WIA_IPA_COMPRESSION attributes"));
  3080. }
  3081. } else {
  3082. DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to read WIA_IPA_COMPRESSION current value"));
  3083. }
  3084. #else // SUPPORT_COMPRESSION_TYPES
  3085. //
  3086. // support only TWCP_NONE (no Compression)
  3087. //
  3088. TW_UINT16 CapDataArray[1];
  3089. CapDataArray[0] = TWCP_NONE;
  3090. twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray);
  3091. #endif // SUPPORT_COMPRESSION_TYPES
  3092. }
  3093. return twRc;
  3094. }
  3095. TW_UINT16 CWiaDataSrc::SetCommonSettings(CCap *pCap)
  3096. {
  3097. DBG_FN_DS(CWiaScannerDS::SetCommonSettings());
  3098. HRESULT hr = S_OK;
  3099. LONG lValue = 0;
  3100. CWiahelper WIA;
  3101. IWiaItem *pIRootItem = NULL;
  3102. hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
  3103. if (FAILED(hr)) {
  3104. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), failed to set IWiaItem for property reading"));
  3105. }
  3106. //
  3107. // determine if it is a Capability that the device really needs to know
  3108. // about.
  3109. //
  3110. switch (pCap->GetCapId()) {
  3111. case ICAP_PIXELTYPE:
  3112. DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_PIXELTYPE)"));
  3113. switch (pCap->GetCurrent()) {
  3114. case TWPT_BW:
  3115. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_THRESHOLD"));
  3116. hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,WIA_DATA_THRESHOLD);
  3117. if(FAILED(hr)){
  3118. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_THRESHOLD failed"));
  3119. }
  3120. break;
  3121. case TWPT_GRAY:
  3122. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_GRAYSCALE"));
  3123. hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,WIA_DATA_GRAYSCALE);
  3124. if(FAILED(hr)){
  3125. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_GRAYSCALE failed"));
  3126. }
  3127. break;
  3128. case TWPT_RGB:
  3129. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_COLOR"));
  3130. hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,WIA_DATA_COLOR);
  3131. if(FAILED(hr)){
  3132. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_COLOR failed"));
  3133. }
  3134. break;
  3135. case TWPT_PALETTE:
  3136. case TWPT_CMY:
  3137. case TWPT_CMYK:
  3138. case TWPT_YUV:
  3139. case TWPT_YUVK:
  3140. case TWPT_CIEXYZ:
  3141. default:
  3142. DBG_WRN(("CWiaDataSrc::SetCommonSettings(), An unsupported ICAP_PIXELTYPE (%d) was sent to this data source",(LONG)pCap->GetCurrent()));
  3143. break;
  3144. }
  3145. break;
  3146. case ICAP_BITDEPTH:
  3147. DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_BITDEPTH)"));
  3148. lValue = (LONG)pCap->GetCurrent();
  3149. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_BITDEPTH to %d",lValue));
  3150. hr = WIA.WritePropertyLong(WIA_IPA_DEPTH,lValue);
  3151. if(FAILED(hr)){
  3152. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_BITDEPTH to %d failed",lValue));
  3153. }
  3154. break;
  3155. case ICAP_IMAGEFILEFORMAT:
  3156. {
  3157. DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_IMAGEFILEFORMAT)"));
  3158. lValue = (LONG)pCap->GetCurrent();
  3159. LONG lTymed = TYMED_FILE;
  3160. if (lValue == TWFF_TIFFMULTI) {
  3161. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_TYMED to TYMED_MULTIPAGE_FILE"));
  3162. lTymed = TYMED_MULTIPAGE_FILE;
  3163. } else {
  3164. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_TYMED to TYMED_FILE"));
  3165. }
  3166. hr = WIA.WritePropertyLong(WIA_IPA_TYMED,lTymed);
  3167. GUID guidFormat = GUID_NULL;
  3168. if (SUCCEEDED(hr)) {
  3169. switch (lValue) {
  3170. case TWFF_TIFFMULTI:
  3171. case TWFF_TIFF:
  3172. guidFormat = WiaImgFmt_TIFF;
  3173. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_TIFF"));
  3174. break;
  3175. case TWFF_PICT:
  3176. guidFormat = WiaImgFmt_PICT;
  3177. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_PICT"));
  3178. break;
  3179. case TWFF_BMP:
  3180. guidFormat = WiaImgFmt_BMP;
  3181. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_BMP"));
  3182. break;
  3183. case TWFF_JFIF:
  3184. guidFormat = WiaImgFmt_JPEG;
  3185. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_JPEG"));
  3186. break;
  3187. case TWFF_FPX:
  3188. guidFormat = WiaImgFmt_FLASHPIX;
  3189. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_FLASHPIX"));
  3190. break;
  3191. case TWFF_PNG:
  3192. guidFormat = WiaImgFmt_PNG;
  3193. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_PNG"));
  3194. break;
  3195. case TWFF_EXIF:
  3196. guidFormat = WiaImgFmt_EXIF;
  3197. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_EXIF"));
  3198. break;
  3199. case TWFF_SPIFF:
  3200. case TWFF_XBM:
  3201. default:
  3202. break;
  3203. }
  3204. hr = WIA.WritePropertyGUID(WIA_IPA_FORMAT,guidFormat);
  3205. if (FAILED(hr)) {
  3206. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to %d failed",lValue));
  3207. }
  3208. } else {
  3209. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_TYMED to %d failed",lTymed));
  3210. }
  3211. }
  3212. break;
  3213. case ICAP_COMPRESSION:
  3214. {
  3215. DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_COMPRESSION)"));
  3216. lValue = (LONG)pCap->GetCurrent();
  3217. LONG lCompression = WIA_COMPRESSION_NONE;
  3218. switch (lValue) {
  3219. case TWCP_NONE:
  3220. lCompression = WIA_COMPRESSION_NONE;
  3221. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_NONE"));
  3222. break;
  3223. case TWCP_GROUP4:
  3224. lCompression = WIA_COMPRESSION_G4;
  3225. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_G4"));
  3226. break;
  3227. case TWCP_JPEG:
  3228. lCompression = WIA_COMPRESSION_JPEG;
  3229. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_JPEG"));
  3230. break;
  3231. case TWCP_RLE4:
  3232. lCompression = WIA_COMPRESSION_BI_RLE4;
  3233. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_BI_RLE4"));
  3234. break;
  3235. case TWCP_RLE8:
  3236. lCompression = WIA_COMPRESSION_BI_RLE8;
  3237. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_BI_RLE8"));
  3238. break;
  3239. case TWCP_GROUP31D:
  3240. case TWCP_GROUP31DEOL:
  3241. case TWCP_GROUP32D:
  3242. lCompression = WIA_COMPRESSION_G3;
  3243. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_G3"));
  3244. break;
  3245. case TWCP_LZW:
  3246. case TWCP_JBIG:
  3247. case TWCP_PACKBITS:
  3248. default:
  3249. break;
  3250. }
  3251. hr = WIA.WritePropertyLong(WIA_IPA_COMPRESSION,lCompression);
  3252. if(FAILED(hr)){
  3253. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to %d failed",lCompression));
  3254. }
  3255. }
  3256. break;
  3257. default:
  3258. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), data source is not setting CAPID = %x to WIA device (it is not needed)",pCap->GetCapId()));
  3259. break;
  3260. }
  3261. if (SUCCEEDED(hr)) {
  3262. DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Settings were successfully sent to WIA device"));
  3263. } else {
  3264. DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Settings were unsuccessfully sent to WIA device"));
  3265. return TWRC_FAILURE;
  3266. }
  3267. return TWRC_SUCCESS;
  3268. }
  3269. TW_UINT16 CWiaDataSrc::GetMemoryTransferBits(BYTE* pImageData)
  3270. {
  3271. DBG_FN_DS(CWiaScannerDS::GetMemoryTransferBits());
  3272. if(!pImageData){
  3273. return TWRC_FAILURE;
  3274. }
  3275. BYTE *pBits = pImageData;
  3276. if (m_MemoryTransferInfo.mtiguidFormat == WiaImgFmt_MEMORYBMP) {
  3277. BITMAPINFOHEADER* pbmh = (BITMAPINFOHEADER*)pImageData;
  3278. if (pbmh) {
  3279. pBits += sizeof(BITMAPINFOHEADER) + (pbmh->biClrUsed * sizeof(RGBQUAD));
  3280. }
  3281. }
  3282. m_MemoryTransferInfo.mtipBits = pBits;
  3283. return TWRC_SUCCESS;
  3284. }