Source code of Windows XP (NT5)
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.

1292 lines
34 KiB

  1. // CWIA.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "CWIA.h"
  5. extern IGlobalInterfaceTable *g_pGIT;
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. CWIA::CWIA(DATA_ACQUIRE_INFO* pThreadDataInfo, IWiaItem *pRootItem)
  12. {
  13. m_bFinishedAcquire = FALSE;
  14. m_pIWiaRootItem = NULL;
  15. m_pIWiaFirstChildItem = NULL;
  16. if(pRootItem != NULL)
  17. m_pIWiaRootItem = pRootItem;
  18. }
  19. CWIA::~CWIA()
  20. {
  21. }
  22. VOID CWIA::CleanUp()
  23. {
  24. if(m_pIWiaRootItem != NULL)
  25. m_pIWiaRootItem->Release();
  26. if(m_pIWiaFirstChildItem != NULL)
  27. m_pIWiaFirstChildItem->Release();
  28. }
  29. VOID CWIA::SetRootItem(IWiaItem *pRootItem)
  30. {
  31. m_pIWiaRootItem = pRootItem;
  32. SetFirstChild();
  33. }
  34. BOOL CWIA::IsAcquireComplete()
  35. {
  36. return m_bFinishedAcquire;
  37. }
  38. HRESULT CWIA::EnumerateSupportedFormats(IWiaItem *pIWiaItem, WIA_FORMAT_INFO **ppSupportedFormats, ULONG *pulCount)
  39. {
  40. HRESULT hr = E_FAIL;
  41. *pulCount = 0;
  42. IWiaDataTransfer *pIWiaDataTransfer = NULL;
  43. IWiaItem *pTargetItem = pIWiaItem;
  44. if(pTargetItem == NULL) {
  45. //
  46. // use first child of root
  47. //
  48. pTargetItem = m_pIWiaFirstChildItem;
  49. }
  50. if(pTargetItem != NULL) {
  51. hr = pTargetItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer);
  52. if (SUCCEEDED(hr)) {
  53. IEnumWIA_FORMAT_INFO *pIEnumWIA_FORMAT_INFO;
  54. hr = pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO(&pIEnumWIA_FORMAT_INFO);
  55. if (SUCCEEDED(hr)) {
  56. hr = pIEnumWIA_FORMAT_INFO->Reset();
  57. if(SUCCEEDED(hr)) {
  58. hr = pIEnumWIA_FORMAT_INFO->GetCount(pulCount);
  59. if(SUCCEEDED(hr)) {
  60. //
  61. // caller of this routine must free the allocated memory
  62. //
  63. *ppSupportedFormats = (WIA_FORMAT_INFO*)GlobalAlloc(GPTR,(sizeof(WIA_FORMAT_INFO) * (*pulCount)));
  64. if(*ppSupportedFormats != NULL) {
  65. hr = pIEnumWIA_FORMAT_INFO->Next(*pulCount, *ppSupportedFormats, pulCount);
  66. if(hr != S_OK) {
  67. //
  68. // if this failed, write error to Last error buffer,
  69. // and let the procedure wind out
  70. //
  71. //
  72. // free allocated memory, because we failed
  73. //
  74. GlobalFree(*ppSupportedFormats);
  75. //
  76. // set pointer to NULL, to clean the exit path for
  77. // application
  78. //
  79. *ppSupportedFormats = NULL;
  80. SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIEnumWIA_FORMAT_INFO->Next() failed"));
  81. }
  82. } else {
  83. SaveErrorText(TEXT("EnumerateSupportedFileTypes, out of memory"));
  84. }
  85. } else {
  86. SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIEnumWIA_FORMAT_INFO->GetCount() failed"));
  87. }
  88. } else {
  89. SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIEnumWIA_FORMAT_INFO->Reset() failed"));
  90. }
  91. //
  92. // Release supported format enumerator interface
  93. //
  94. pIEnumWIA_FORMAT_INFO->Release();
  95. } else {
  96. SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO() failed"));
  97. }
  98. //
  99. // Release data transfer interface
  100. //
  101. pIWiaDataTransfer->Release();
  102. } else {
  103. SaveErrorText(TEXT("EnumerateSupportedFileTypes, QI for IWiaDataTransfer failed"));
  104. }
  105. }
  106. return hr;
  107. }
  108. BOOL CWIA::SetFirstChild()
  109. {
  110. HRESULT hr = E_FAIL;
  111. BOOL bSuccess = FALSE;
  112. IEnumWiaItem* pIEnumWiaItem = NULL;
  113. IWiaItem *pIWiaItem = NULL;
  114. hr = m_pIWiaRootItem->EnumChildItems(&pIEnumWiaItem);
  115. if(SUCCEEDED(hr)) {
  116. //
  117. // get first child item
  118. //
  119. hr = pIEnumWiaItem->Next(1,&pIWiaItem,NULL);
  120. if(hr == S_OK) {
  121. //
  122. // item was retrieved, so now assign you first child member
  123. //
  124. m_pIWiaFirstChildItem = pIWiaItem;
  125. //
  126. // assign success flag
  127. //
  128. bSuccess = TRUE;
  129. } else {
  130. //
  131. // save last error, for later request
  132. //
  133. SaveErrorText(TEXT("SetFirstChild, pIEnumWiaItem->Next failed"));
  134. m_hrLastError = hr;
  135. }
  136. //
  137. // release Item enumerator
  138. //
  139. pIEnumWiaItem->Release();
  140. }
  141. return bSuccess;
  142. }
  143. IWiaItem* CWIA::GetFirstChild()
  144. {
  145. return m_pIWiaFirstChildItem;
  146. }
  147. IWiaItem* CWIA::GetRootItem()
  148. {
  149. return m_pIWiaRootItem;
  150. }
  151. LONG CWIA::GetRootItemType(IWiaItem *pRootItem)
  152. {
  153. IWiaItem *pTargetRootItem = NULL;
  154. //
  155. // start with the requested RootItem first
  156. //
  157. pTargetRootItem = pRootItem;
  158. if(pTargetRootItem == NULL) {
  159. //
  160. // the requested root item is NULL, so try our
  161. // internal root item (m_pIWiaRootItem)
  162. //
  163. pTargetRootItem = m_pIWiaRootItem;
  164. }
  165. //
  166. // get Root item's type (ie. device type)
  167. //
  168. LONG lVal = -888;
  169. if (pTargetRootItem != NULL) {
  170. //
  171. // get an IWiaPropertyStorage Interface
  172. //
  173. IWiaPropertyStorage *pIWiaPropStg;
  174. HRESULT hr = S_OK;
  175. hr = pTargetRootItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  176. if (SUCCEEDED(hr)) {
  177. //
  178. // read Root Item's Type
  179. //
  180. hr = ReadPropLong(WIA_DIP_DEV_TYPE, pIWiaPropStg, &lVal);
  181. if(SUCCEEDED(hr)) {
  182. //
  183. // release the IWiaPropertyStorage Interface
  184. //
  185. pIWiaPropStg->Release();
  186. } else {
  187. //
  188. // save last error, for later request
  189. //
  190. SaveErrorText(TEXT("GetRootItemType, ReadPropLong(WIA_DIP_DEV_TYPE) failed"));
  191. m_hrLastError = hr;
  192. }
  193. } else {
  194. //
  195. // save last error, for later request
  196. //
  197. SaveErrorText(TEXT("GetRootItemType, ReadPropLong(WIA_DIP_DEV_TYPE) failed"));
  198. m_hrLastError = hr;
  199. }
  200. }
  201. return(GET_STIDEVICE_TYPE(lVal));
  202. }
  203. //
  204. // ERROR PROCESSING
  205. //
  206. VOID CWIA::SaveErrorText(TCHAR *pszText)
  207. {
  208. lstrcpy(m_szErrorText,pszText);
  209. }
  210. HRESULT CWIA::GetLastWIAError(TCHAR *pszErrorText)
  211. {
  212. if(pszErrorText != NULL)
  213. lstrcpy(pszErrorText, m_szErrorText);
  214. return m_hrLastError;
  215. }
  216. //
  217. // PROPERTY ACCESS HELPERS
  218. //
  219. HRESULT CWIA::WritePropLong(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, LONG lVal)
  220. {
  221. HRESULT hr = E_FAIL;
  222. PROPSPEC propspec[1];
  223. PROPVARIANT propvar[1];
  224. propspec[0].ulKind = PRSPEC_PROPID;
  225. propspec[0].propid = propid;
  226. propvar[0].vt = VT_I4;
  227. propvar[0].lVal = lVal;
  228. hr = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
  229. return hr;
  230. }
  231. HRESULT CWIA::ReadPropLong(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, LONG *plval)
  232. {
  233. HRESULT hr = E_FAIL;
  234. PROPSPEC PropSpec[1];
  235. PROPVARIANT PropVar[1];
  236. UINT cbSize = 0;
  237. memset(PropVar, 0, sizeof(PropVar));
  238. PropSpec[0].ulKind = PRSPEC_PROPID;
  239. PropSpec[0].propid = propid;
  240. hr = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
  241. if (SUCCEEDED(hr)) {
  242. *plval = PropVar[0].lVal;
  243. }
  244. return hr;
  245. }
  246. HRESULT CWIA::ReadRangeLong(IWiaItem *pIWiaItem, PROPID propid, ULONG ulFlag, LONG *plVal)
  247. {
  248. HRESULT hr = E_FAIL;
  249. IWiaItem *pTargetItem = NULL;
  250. PROPSPEC PropSpec[1];
  251. PROPVARIANT AttrPropVar;
  252. ULONG ulAccessFlags = 0;
  253. //
  254. // create a propspec
  255. //
  256. PropSpec[0].ulKind = PRSPEC_PROPID;
  257. PropSpec[0].propid = propid;
  258. pTargetItem = pIWiaItem;
  259. if(pTargetItem == NULL) {
  260. //
  261. // use first child of root
  262. //
  263. pTargetItem = m_pIWiaFirstChildItem;
  264. }
  265. if(pTargetItem != NULL) {
  266. //
  267. // get an IWiaPropertyStorage Interface
  268. //
  269. IWiaPropertyStorage *pIWiaPropStg;
  270. hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  271. if (SUCCEEDED(hr)) {
  272. //
  273. // get property's attributes
  274. //
  275. hr = pIWiaPropStg->GetPropertyAttributes(1, PropSpec, &ulAccessFlags, &AttrPropVar);
  276. if(SUCCEEDED(hr)) {
  277. *plVal = (LONG)AttrPropVar.caul.pElems[ulFlag];
  278. } else {
  279. //
  280. // save last error, for later request
  281. //
  282. SaveErrorText(TEXT("ReadRangeLong, GetPropertyAttributes() failed"));
  283. m_hrLastError = hr;
  284. }
  285. //
  286. // release the IWiaPropertyStorage Interface
  287. //
  288. pIWiaPropStg->Release();
  289. } else {
  290. //
  291. // save last error, for later request
  292. //
  293. SaveErrorText(TEXT("ReadRangeLong, QI for IWiaProperyStorage failed"));
  294. m_hrLastError = hr;
  295. }
  296. }
  297. return hr;
  298. }
  299. HRESULT CWIA::ReadLong(IWiaItem *pIWiaItem, PROPID propid, LONG *plVal)
  300. {
  301. HRESULT hr = E_FAIL;
  302. IWiaItem *pTargetItem = NULL;
  303. PROPSPEC PropSpec[1];
  304. //
  305. // create a propspec
  306. //
  307. PropSpec[0].ulKind = PRSPEC_PROPID;
  308. PropSpec[0].propid = propid;
  309. pTargetItem = pIWiaItem;
  310. if(pTargetItem == NULL) {
  311. //
  312. // use first child of root
  313. //
  314. pTargetItem = m_pIWiaFirstChildItem;
  315. }
  316. if(pTargetItem != NULL) {
  317. //
  318. // get an IWiaPropertyStorage Interface
  319. //
  320. IWiaPropertyStorage *pIWiaPropStg;
  321. hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  322. if (SUCCEEDED(hr)) {
  323. hr = ReadPropLong(propid,pIWiaPropStg,plVal);
  324. if(SUCCEEDED(hr)) {
  325. //
  326. // read has taken place
  327. //
  328. } else {
  329. //
  330. // save last error, for later request
  331. //
  332. SaveErrorText(TEXT("ReadLong, ReadPropLong() failed"));
  333. m_hrLastError = hr;
  334. }
  335. pIWiaPropStg->Release();
  336. } else {
  337. //
  338. // save last error, for later request
  339. //
  340. SaveErrorText(TEXT("ReadLong, QI for IWiaProperyStorage failed"));
  341. m_hrLastError = hr;
  342. }
  343. }
  344. return hr;
  345. }
  346. HRESULT CWIA::WriteLong(IWiaItem *pIWiaItem, PROPID propid, LONG lVal)
  347. {
  348. HRESULT hr = E_FAIL;
  349. IWiaItem *pTargetItem = NULL;
  350. PROPSPEC PropSpec[1];
  351. //
  352. // create a propspec
  353. //
  354. PropSpec[0].ulKind = PRSPEC_PROPID;
  355. PropSpec[0].propid = propid;
  356. pTargetItem = pIWiaItem;
  357. if(pTargetItem == NULL) {
  358. //
  359. // use first child of root
  360. //
  361. pTargetItem = m_pIWiaFirstChildItem;
  362. }
  363. if(pTargetItem != NULL) {
  364. //
  365. // get an IWiaPropertyStorage Interface
  366. //
  367. IWiaPropertyStorage *pIWiaPropStg;
  368. hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  369. if (SUCCEEDED(hr)) {
  370. hr = WritePropLong(propid,pIWiaPropStg,lVal);
  371. if(SUCCEEDED(hr)) {
  372. //
  373. // read has taken place
  374. //
  375. } else {
  376. //
  377. // save last error, for later request
  378. //
  379. SaveErrorText(TEXT("WriteLong, WritePropLong() failed"));
  380. m_hrLastError = hr;
  381. }
  382. pIWiaPropStg->Release();
  383. } else {
  384. //
  385. // save last error, for later request
  386. //
  387. SaveErrorText(TEXT("WriteLong, QI for IWiaProperyStorage failed"));
  388. m_hrLastError = hr;
  389. }
  390. }
  391. return hr;
  392. }
  393. HRESULT CWIA::ReadStr(IWiaItem *pIWiaItem, PROPID propid, BSTR *pbstr)
  394. {
  395. HRESULT hr = E_FAIL;
  396. IWiaItem *pTargetItem = NULL;
  397. PROPSPEC PropSpec[1];
  398. //
  399. // create a propspec
  400. //
  401. PropSpec[0].ulKind = PRSPEC_PROPID;
  402. PropSpec[0].propid = propid;
  403. pTargetItem = pIWiaItem;
  404. if(pTargetItem == NULL) {
  405. //
  406. // use first child of root
  407. //
  408. pTargetItem = m_pIWiaFirstChildItem;
  409. }
  410. if(pTargetItem != NULL) {
  411. //
  412. // get an IWiaPropertyStorage Interface
  413. //
  414. IWiaPropertyStorage *pIWiaPropStg;
  415. hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  416. if (SUCCEEDED(hr)) {
  417. hr = ReadPropStr(propid,pIWiaPropStg,pbstr);
  418. if(SUCCEEDED(hr)) {
  419. //
  420. // read has taken place
  421. //
  422. } else {
  423. //
  424. // save last error, for later request
  425. //
  426. SaveErrorText(TEXT("ReadStr, ReadPropStr() failed"));
  427. m_hrLastError = hr;
  428. }
  429. pIWiaPropStg->Release();
  430. } else {
  431. //
  432. // save last error, for later request
  433. //
  434. SaveErrorText(TEXT("ReadStr, QI for IWiaProperyStorage failed"));
  435. m_hrLastError = hr;
  436. }
  437. }
  438. return hr;
  439. }
  440. HRESULT CWIA::ReadGuid(IWiaItem *pIWiaItem, PROPID propid, GUID *pguidVal)
  441. {
  442. HRESULT hr = E_FAIL;
  443. IWiaItem *pTargetItem = NULL;
  444. PROPSPEC PropSpec[1];
  445. //
  446. // create a propspec
  447. //
  448. PropSpec[0].ulKind = PRSPEC_PROPID;
  449. PropSpec[0].propid = propid;
  450. pTargetItem = pIWiaItem;
  451. if(pTargetItem == NULL) {
  452. //
  453. // use first child of root
  454. //
  455. pTargetItem = m_pIWiaFirstChildItem;
  456. }
  457. if(pTargetItem != NULL) {
  458. //
  459. // get an IWiaPropertyStorage Interface
  460. //
  461. IWiaPropertyStorage *pIWiaPropStg;
  462. hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  463. if (SUCCEEDED(hr)) {
  464. hr = ReadPropGUID(propid,pIWiaPropStg,pguidVal);
  465. if(SUCCEEDED(hr)) {
  466. //
  467. // read has taken place
  468. //
  469. } else {
  470. //
  471. // save last error, for later request
  472. //
  473. SaveErrorText(TEXT("ReadGuid, ReadPropGuid() failed"));
  474. m_hrLastError = hr;
  475. }
  476. pIWiaPropStg->Release();
  477. } else {
  478. //
  479. // save last error, for later request
  480. //
  481. SaveErrorText(TEXT("ReadGuid, QI for IWiaProperyStorage failed"));
  482. m_hrLastError = hr;
  483. }
  484. }
  485. return hr;
  486. }
  487. HRESULT CWIA::WriteGuid(IWiaItem *pIWiaItem, PROPID propid, GUID guidVal)
  488. {
  489. HRESULT hr = E_FAIL;
  490. IWiaItem *pTargetItem = NULL;
  491. PROPSPEC PropSpec[1];
  492. //
  493. // create a propspec
  494. //
  495. PropSpec[0].ulKind = PRSPEC_PROPID;
  496. PropSpec[0].propid = propid;
  497. pTargetItem = pIWiaItem;
  498. if(pTargetItem == NULL) {
  499. //
  500. // use first child of root
  501. //
  502. pTargetItem = m_pIWiaFirstChildItem;
  503. }
  504. if(pTargetItem != NULL) {
  505. //
  506. // get an IWiaPropertyStorage Interface
  507. //
  508. IWiaPropertyStorage *pIWiaPropStg;
  509. hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  510. if (SUCCEEDED(hr)) {
  511. hr = WritePropGUID(propid,pIWiaPropStg,guidVal);
  512. if(SUCCEEDED(hr)) {
  513. //
  514. // read has taken place
  515. //
  516. } else {
  517. //
  518. // save last error, for later request
  519. //
  520. SaveErrorText(TEXT("WriteGuid, WritePropGuid() failed"));
  521. m_hrLastError = hr;
  522. }
  523. pIWiaPropStg->Release();
  524. } else {
  525. //
  526. // save last error, for later request
  527. //
  528. SaveErrorText(TEXT("WriteGuid, QI for IWiaProperyStorage failed"));
  529. m_hrLastError = hr;
  530. }
  531. }
  532. return hr;
  533. }
  534. HRESULT CWIA::DoBandedTransfer(DATA_ACQUIRE_INFO* pDataAcquireInfo)
  535. {
  536. HRESULT hr = S_OK;
  537. //
  538. // Write TYMED value to callback
  539. //
  540. hr = WriteLong(m_pIWiaFirstChildItem,WIA_IPA_TYMED,TYMED_CALLBACK);
  541. //
  542. // get IWiaDatatransfer interface
  543. //
  544. IWiaDataTransfer *pIBandTran = NULL;
  545. hr = m_pIWiaFirstChildItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIBandTran);
  546. if (SUCCEEDED(hr)) {
  547. //
  548. // create Banded callback
  549. //
  550. IWiaDataCallback* pIWiaDataCallback = NULL;
  551. CWiaDataCallback* pCBandedCB = new CWiaDataCallback();
  552. if (pCBandedCB) {
  553. hr = pCBandedCB->QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback);
  554. if (SUCCEEDED(hr)) {
  555. WIA_DATA_TRANSFER_INFO wiaDataTransInfo;
  556. pCBandedCB->Initialize(pDataAcquireInfo);
  557. ZeroMemory(&wiaDataTransInfo, sizeof(WIA_DATA_TRANSFER_INFO));
  558. wiaDataTransInfo.ulSize = sizeof(WIA_DATA_TRANSFER_INFO);
  559. wiaDataTransInfo.ulBufferSize = 524288;//262144; // calculate, or determine buffer size
  560. hr = pIBandTran->idtGetBandedData(&wiaDataTransInfo, pIWiaDataCallback);
  561. m_bFinishedAcquire = TRUE;
  562. pIBandTran->Release();
  563. if (hr == S_OK) {
  564. OutputDebugString(TEXT("IWiaData Transfer.(CALLBACK)..Success\n"));
  565. } else if (hr == S_FALSE) {
  566. OutputDebugString(TEXT("IWiaData Transfer.(CALLBACK)..Canceled by user\n"));
  567. } else {
  568. OutputDebugString(TEXT("* idtGetBandedData() Failed\n"));
  569. }
  570. //
  571. // release Callback object
  572. //
  573. pCBandedCB->Release();
  574. } else
  575. // TEXT("* pCBandedCB->QueryInterface(IID_IWiaDataCallback) Failed");
  576. return hr;
  577. } else
  578. return hr;
  579. // TEXT("* pCBandedCB failed to create..");
  580. } else
  581. return hr;
  582. // TEXT("* pIWiaItem->QueryInterface(IID_IWiaDataTransfer) Failed");
  583. return S_OK;
  584. }
  585. HRESULT CWIA::DoFileTransfer(DATA_ACQUIRE_INFO* pDataAcquireInfo)
  586. {
  587. HRESULT hr = S_OK;
  588. //
  589. // Write TYMED value to file
  590. //
  591. hr = WriteLong(m_pIWiaFirstChildItem,WIA_IPA_TYMED,TYMED_FILE);
  592. //
  593. // get IWiaDatatransfer interface
  594. //
  595. IWiaDataTransfer *pIBandTran = NULL;
  596. hr = m_pIWiaFirstChildItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIBandTran);
  597. if (SUCCEEDED(hr)) {
  598. //
  599. // create Banded callback
  600. //
  601. IWiaDataCallback* pIWiaDataCallback = NULL;
  602. CWiaDataCallback* pCBandedCB = new CWiaDataCallback();
  603. if (pCBandedCB) {
  604. hr = pCBandedCB->QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback);
  605. if (SUCCEEDED(hr)) {
  606. //
  607. // fill out STGMEDIUM
  608. //
  609. STGMEDIUM StgMedium;
  610. ZeroMemory(&StgMedium, sizeof(STGMEDIUM));
  611. StgMedium.tymed = TYMED_FILE;
  612. StgMedium.lpszFileName = NULL;
  613. StgMedium.pUnkForRelease = NULL;
  614. StgMedium.hGlobal = NULL;
  615. pCBandedCB->Initialize(pDataAcquireInfo);
  616. hr = pIBandTran->idtGetData(&StgMedium,pIWiaDataCallback);
  617. m_bFinishedAcquire = TRUE;
  618. pIBandTran->Release();
  619. if (hr == S_OK) {
  620. OutputDebugString(TEXT("IWiaData Transfer.(FILE)..Success\n"));
  621. //
  622. // We have completed the transfer...so now move the temporary file into
  623. // the needed location, with the users requested file name.
  624. //
  625. CString WIATempFile = StgMedium.lpszFileName;
  626. if(!CopyFile(WIATempFile,pDataAcquireInfo->szFileName,FALSE)){
  627. OutputDebugString(TEXT("Failed to copy temp file.."));
  628. }
  629. //
  630. // delete WIA created TEMP file
  631. //
  632. DeleteFile(WIATempFile);
  633. } else if (hr == S_FALSE) {
  634. OutputDebugString(TEXT("IWiaData Transfer.(FILE)..Canceled by user\n"));
  635. } else {
  636. OutputDebugString(TEXT("* idtGetData() Failed\n"));
  637. }
  638. //
  639. // release Callback object
  640. //
  641. pCBandedCB->Release();
  642. } else
  643. // TEXT("* pCBandedCB->QueryInterface(IID_IWiaDataCallback) Failed");
  644. return hr;
  645. } else
  646. return hr;
  647. // TEXT("* pCBandedCB failed to create..");
  648. } else
  649. return hr;
  650. // TEXT("* pIWiaItem->QueryInterface(IID_IWiaDataTransfer) Failed");
  651. return hr;
  652. }
  653. HRESULT CWIA::WritePropGUID(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, GUID guidVal)
  654. {
  655. HRESULT hr = E_FAIL;
  656. PROPSPEC propspec[1];
  657. PROPVARIANT propvar[1];
  658. propspec[0].ulKind = PRSPEC_PROPID;
  659. propspec[0].propid = propid;
  660. propvar[0].vt = VT_CLSID;
  661. propvar[0].puuid = &guidVal;
  662. hr = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
  663. return hr;
  664. }
  665. HRESULT CWIA::ReadPropGUID(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, GUID *pguidVal)
  666. {
  667. HRESULT hr = E_FAIL;
  668. PROPSPEC PropSpec[1];
  669. PROPVARIANT PropVar[1];
  670. UINT cbSize = 0;
  671. memset(PropVar, 0, sizeof(PropVar));
  672. PropSpec[0].ulKind = PRSPEC_PROPID;
  673. PropSpec[0].propid = propid;
  674. hr = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
  675. if (SUCCEEDED(hr)) {
  676. pguidVal = PropVar[0].puuid;
  677. }
  678. return hr;
  679. }
  680. HRESULT CWIA::ReadPropStr(PROPID propid,IWiaPropertyStorage *pIWiaPropStg,BSTR *pbstr)
  681. {
  682. HRESULT hr = S_OK;
  683. PROPSPEC PropSpec[1];
  684. PROPVARIANT PropVar[1];
  685. UINT cbSize = 0;
  686. *pbstr = NULL;
  687. memset(PropVar, 0, sizeof(PropVar));
  688. PropSpec[0].ulKind = PRSPEC_PROPID;
  689. PropSpec[0].propid = propid;
  690. hr = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
  691. if (SUCCEEDED(hr)) {
  692. if (PropVar[0].pwszVal) {
  693. *pbstr = SysAllocString(PropVar[0].pwszVal);
  694. } else {
  695. *pbstr = SysAllocString(L"");
  696. }
  697. if (*pbstr == NULL) {
  698. hr = E_OUTOFMEMORY;
  699. }
  700. PropVariantClear(PropVar);
  701. }
  702. return hr;
  703. }
  704. HRESULT CWIA::WritePropStr(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, BSTR bstr)
  705. {
  706. HRESULT hr = S_OK;
  707. PROPSPEC propspec[1];
  708. PROPVARIANT propvar[1];
  709. propspec[0].ulKind = PRSPEC_PROPID;
  710. propspec[0].propid = propid;
  711. propvar[0].vt = VT_BSTR;
  712. propvar[0].pwszVal = bstr;
  713. hr = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
  714. return hr;
  715. }
  716. //////////////////////////////////////////////////////////////////////////////////////////////
  717. HRESULT _stdcall CWiaDataCallback::QueryInterface(const IID& iid, void** ppv)
  718. {
  719. *ppv = NULL;
  720. if (iid == IID_IUnknown || iid == IID_IWiaDataCallback)
  721. *ppv = (IWiaDataCallback*) this;
  722. else
  723. return E_NOINTERFACE;
  724. AddRef();
  725. return S_OK;
  726. }
  727. ULONG _stdcall CWiaDataCallback::AddRef()
  728. {
  729. InterlockedIncrement((long*) &m_cRef);
  730. return m_cRef;
  731. }
  732. ULONG _stdcall CWiaDataCallback::Release()
  733. {
  734. ULONG ulRefCount = m_cRef - 1;
  735. if (InterlockedDecrement((long*) &m_cRef) == 0)
  736. {
  737. delete this;
  738. return 0;
  739. }
  740. return ulRefCount;
  741. }
  742. CWiaDataCallback::CWiaDataCallback()
  743. {
  744. m_cRef = 0;
  745. m_BytesTransfered = 0;
  746. m_pProgressFunc = NULL;
  747. m_bCanceled = FALSE;
  748. m_bBitmapCreated = FALSE;
  749. }
  750. CWiaDataCallback::~CWiaDataCallback()
  751. {
  752. }
  753. HRESULT _stdcall CWiaDataCallback::Initialize(DATA_ACQUIRE_INFO* pDataAcquireInfo)
  754. {
  755. m_pProgressFunc = pDataAcquireInfo->pProgressFunc;
  756. m_pDataAcquireInfo = pDataAcquireInfo;
  757. m_lPageCount = 0;
  758. return S_OK;
  759. }
  760. HRESULT _stdcall CWiaDataCallback::BandedDataCallback(LONG lMessage,
  761. LONG lStatus,
  762. LONG lPercentComplete,
  763. LONG lOffset,
  764. LONG lLength,
  765. LONG lReserved,
  766. LONG lResLength,
  767. BYTE* pbBuffer)
  768. {
  769. m_bCanceled = FALSE;
  770. //
  771. // process callback messages
  772. //
  773. switch (lMessage)
  774. {
  775. case IT_MSG_DATA_HEADER:
  776. {
  777. PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER)pbBuffer;
  778. m_MemBlockSize = pHeader->lBufferSize;
  779. //
  780. // If the Buffer is 0, then alloc a 64k chunk (default)
  781. //
  782. if(m_MemBlockSize <= 0)
  783. m_MemBlockSize = 65535;
  784. if(m_pDataAcquireInfo->bTransferToClipboard) {
  785. m_pDataAcquireInfo->hClipboardData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,m_MemBlockSize);
  786. } else {
  787. m_pDataAcquireInfo->hBitmapData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,m_MemBlockSize);
  788. }
  789. m_BytesTransfered = 0;
  790. m_cFormat = pHeader->guidFormatID;
  791. }
  792. break;
  793. case IT_MSG_DATA:
  794. {
  795. //
  796. // increment bytes transferred counter
  797. //
  798. m_BytesTransfered += lLength;
  799. if(m_BytesTransfered >= m_MemBlockSize){
  800. //
  801. // Alloc more memory for transfer buffer
  802. //
  803. m_MemBlockSize += (lLength * 2);
  804. if(m_pDataAcquireInfo->bTransferToClipboard) {
  805. if(m_pDataAcquireInfo->hClipboardData != NULL) {
  806. m_pDataAcquireInfo->hClipboardData = GlobalReAlloc(m_pDataAcquireInfo->hClipboardData,
  807. m_MemBlockSize, GMEM_MOVEABLE);
  808. }
  809. } else {
  810. if(m_pDataAcquireInfo->hBitmapData != NULL) {
  811. m_pDataAcquireInfo->hBitmapData = GlobalReAlloc(m_pDataAcquireInfo->hBitmapData,
  812. m_MemBlockSize, GMEM_MOVEABLE);
  813. }
  814. }
  815. }
  816. if(m_pDataAcquireInfo->bTransferToClipboard) {
  817. BYTE* pByte = (BYTE*)GlobalLock(m_pDataAcquireInfo->hClipboardData);
  818. memcpy(pByte + lOffset, pbBuffer, lLength);
  819. GlobalUnlock(m_pDataAcquireInfo->hClipboardData);
  820. } else {
  821. if(m_pDataAcquireInfo->hBitmapData != NULL) {
  822. BYTE* pByte = (BYTE*)GlobalLock(m_pDataAcquireInfo->hBitmapData);
  823. memcpy(pByte + lOffset, pbBuffer, lLength);
  824. GlobalUnlock(m_pDataAcquireInfo->hBitmapData);
  825. }
  826. }
  827. //
  828. // do any extra image processing here
  829. //
  830. if(!m_pDataAcquireInfo->bTransferToClipboard) {
  831. if(m_cFormat == WiaImgFmt_MEMORYBMP) {
  832. if(m_bBitmapCreated) {
  833. //
  834. // Add data to your bitmap
  835. //
  836. AddDataToHBITMAP(m_pDataAcquireInfo->hWnd,
  837. m_pDataAcquireInfo->hBitmapData,
  838. &m_pDataAcquireInfo->hBitmap,
  839. lOffset);
  840. } else {
  841. //
  842. // Create your bitmap for display
  843. //
  844. CreateHBITMAP(m_pDataAcquireInfo->hWnd,
  845. m_pDataAcquireInfo->hBitmapData,
  846. &m_pDataAcquireInfo->hBitmap,
  847. lOffset);
  848. }
  849. }
  850. else if(m_cFormat == WiaImgFmt_TIFF) {
  851. }
  852. }
  853. //
  854. // process progress monitor
  855. //
  856. if(m_pProgressFunc != NULL){
  857. if(lPercentComplete == 0)
  858. m_bCanceled = m_pProgressFunc(TEXT("Acquiring Image..."),lPercentComplete);
  859. else {
  860. TCHAR szBuffer[MAX_PATH];
  861. sprintf(szBuffer,TEXT("%d%% Complete..."),lPercentComplete);
  862. m_bCanceled = m_pProgressFunc(szBuffer,lPercentComplete);
  863. }
  864. }
  865. }
  866. break;
  867. case IT_MSG_STATUS:
  868. {
  869. //
  870. // process "Status" message
  871. //
  872. if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE) {
  873. if(m_pProgressFunc != NULL)
  874. m_bCanceled = m_pProgressFunc(TEXT("Transfer from device"),lPercentComplete);
  875. }
  876. else if (lStatus & IT_STATUS_PROCESSING_DATA) {
  877. if(m_pProgressFunc != NULL)
  878. m_bCanceled = m_pProgressFunc(TEXT("Processing Data"),lPercentComplete);
  879. }
  880. else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT) {
  881. if(m_pProgressFunc != NULL)
  882. m_bCanceled = m_pProgressFunc(TEXT("Transfer to Client"),lPercentComplete);
  883. }
  884. }
  885. break;
  886. case IT_MSG_NEW_PAGE:
  887. {
  888. //
  889. // process "New Page" message
  890. //
  891. PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER)pbBuffer;
  892. m_lPageCount = pHeader->lPageCount;
  893. if(m_pProgressFunc != NULL)
  894. m_bCanceled = m_pProgressFunc(TEXT("New Page"),lPercentComplete);
  895. }
  896. break;
  897. }
  898. //
  899. // check use canceled acquire
  900. //
  901. if(m_bCanceled)
  902. return S_FALSE;
  903. return S_OK;
  904. }
  905. void CWiaDataCallback::AddDataToHBITMAP(HWND hWnd, HGLOBAL hBitmapData, HBITMAP *phBitmap, LONG lOffset)
  906. {
  907. BYTE* pData = (BYTE*)GlobalLock(hBitmapData);
  908. if(pData) {
  909. HDC hdc = ::GetDC(hWnd);
  910. if(*phBitmap == NULL) {
  911. OutputDebugString(TEXT("HBITMAP is NULL...this is a bad thing\n"));
  912. return;
  913. }
  914. if(hdc == NULL) {
  915. OutputDebugString(TEXT("HDC is NULL...this is a bad thing\n"));
  916. return;
  917. }
  918. LPBITMAPINFO pbmi = (LPBITMAPINFO)pData;
  919. if(hdc != NULL){
  920. if(pbmi != NULL) {
  921. if(SetDIBits(hdc,
  922. *phBitmap,
  923. 0,
  924. (pbmi->bmiHeader.biHeight < 0?(-(pbmi->bmiHeader.biHeight)):pbmi->bmiHeader.biHeight),
  925. pData + sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * pbmi->bmiHeader.biClrUsed),
  926. pbmi,
  927. DIB_RGB_COLORS) == 0) {
  928. DWORD dwLastError = GetLastError();
  929. TCHAR buf[10];
  930. sprintf(buf,"GetLastError() code = %d\n",dwLastError);
  931. OutputDebugString("AddDataToHBITMAP, SetDIBits failed..with ");
  932. OutputDebugString(buf);
  933. }
  934. }
  935. }
  936. GlobalUnlock(hBitmapData);
  937. } else {
  938. OutputDebugString(TEXT("No bitmap memory available..\n"));
  939. }
  940. }
  941. void CWiaDataCallback::CreateHBITMAP(HWND hWnd, HGLOBAL hBitmapData, HBITMAP *phBitmap, LONG lOffset)
  942. {
  943. HDC hdc = NULL; // DC to draw to
  944. LPBITMAPINFO pbmi = NULL; // pointer to BITMAPINFO struct
  945. BITMAP bitmap;
  946. BYTE *pDib = NULL; // dib data
  947. BYTE *pData = (BYTE*)GlobalLock(hBitmapData);
  948. if(pData) {
  949. if(*phBitmap != NULL) {
  950. //
  951. // delete old bitmap, if one exists
  952. //
  953. OutputDebugString(TEXT("Destroying old HBITMAP..\n"));
  954. DeleteObject(*phBitmap);
  955. }
  956. //
  957. // get hdc
  958. //
  959. hdc = ::GetWindowDC(hWnd);
  960. if(hdc != NULL){
  961. //
  962. // set bitmap header information
  963. //
  964. pbmi = (LPBITMAPINFO)pData;
  965. if (pbmi != NULL) {
  966. //
  967. // create a HBITMAP object
  968. //
  969. *phBitmap = ::CreateDIBSection(hdc,pbmi,DIB_RGB_COLORS,(void **)&pDib,NULL,0);
  970. if (*phBitmap != NULL) {
  971. //
  972. // initialize it to white
  973. //
  974. memset(pDib,255,pbmi->bmiHeader.biSizeImage);
  975. //
  976. // get HBITMAP
  977. //
  978. ::GetObject(*phBitmap,sizeof(BITMAP),(LPSTR)&bitmap);
  979. m_bBitmapCreated = TRUE;
  980. } else {
  981. OutputDebugString(TEXT("HBITMAP is NULL..\n"));
  982. }
  983. } else {
  984. OutputDebugString(TEXT("BITMAPINFOHEADER is NULL..\n"));
  985. }
  986. //
  987. // release hdc
  988. //
  989. ::ReleaseDC(hWnd,hdc);
  990. } else {
  991. OutputDebugString(TEXT("DC is NULL\n"));
  992. }
  993. GlobalUnlock(hBitmapData);
  994. } else {
  995. OutputDebugString(TEXT("No bitmap memory available..\n"));
  996. }
  997. }
  998. //
  999. // global Interface access functions
  1000. //
  1001. HRESULT WriteInterfaceToGlobalInterfaceTable(DWORD *pdwCookie, IWiaItem *pIWiaItem)
  1002. {
  1003. HRESULT hr = S_OK;
  1004. hr = g_pGIT->RegisterInterfaceInGlobal(pIWiaItem, IID_IWiaItem, pdwCookie);
  1005. return hr;
  1006. }
  1007. HRESULT ReadInterfaceFromGlobalInterfaceTable(DWORD dwCookie, IWiaItem **ppIWiaItem)
  1008. {
  1009. HRESULT hr = S_OK;
  1010. hr = g_pGIT->GetInterfaceFromGlobal(dwCookie, IID_IWiaItem, (void**)ppIWiaItem);
  1011. return hr;
  1012. }