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.

525 lines
12 KiB

  1. /**************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 2002
  4. *
  5. * TITLE: scanapi.cpp
  6. *
  7. * VERSION: 1.1
  8. *
  9. * DATE: 05 March, 2002
  10. *
  11. * DESCRIPTION:
  12. * Fake Scanner device library. This is a fake scanner library, intended
  13. * to simulate a scanner device. This should only be used for testing
  14. * purposes.
  15. *
  16. ***************************************************************************/
  17. #include "pch.h"
  18. #include "scanapi.h"
  19. #include <time.h>
  20. CFakeScanAPI::CFakeScanAPI()
  21. {
  22. m_lLastEvent = ID_FAKE_NOEVENT;
  23. m_hrLastADFError = S_OK;
  24. m_bGreen = TRUE;
  25. m_dwBytesWrittenSoFAR = 0;
  26. m_TotalDataInDevice = 0;
  27. m_PagesInADF = MAX_PAGE_CAPACITY;
  28. memset(&m_RawDataInfo, 0,sizeof(RAW_DATA_INFORMATION));
  29. memset(&m_SrcDataInfo, 0,sizeof(RAW_DATA_INFORMATION));
  30. }
  31. CFakeScanAPI::~CFakeScanAPI()
  32. {
  33. }
  34. HRESULT CFakeScanAPI::FakeScanner_Initialize()
  35. {
  36. return S_OK;
  37. }
  38. HRESULT CFakeScanAPI::FakeScanner_GetRootPropertyInfo(PROOT_ITEM_INFORMATION pRootItemInfo)
  39. {
  40. HRESULT hr = S_OK;
  41. //
  42. // Fill in Root item property defaults
  43. //
  44. if (m_lMode == UNKNOWN_FEEDER_ONLY_SCANNER_MODE) {
  45. pRootItemInfo->DocumentFeederCaps = FEEDER;
  46. pRootItemInfo->DocumentFeederStatus = FEED_READY;
  47. pRootItemInfo->DocumentFeederHReg = CENTERED;
  48. pRootItemInfo->DocumentFeederReg = CENTERED;
  49. } else {
  50. pRootItemInfo->DocumentFeederCaps = FEEDER|FLATBED;
  51. pRootItemInfo->DocumentFeederStatus = FLAT_READY;
  52. pRootItemInfo->DocumentFeederHReg = LEFT_JUSTIFIED;
  53. pRootItemInfo->DocumentFeederReg = LEFT_JUSTIFIED;
  54. }
  55. pRootItemInfo->DocumentFeederWidth = 8500;
  56. pRootItemInfo->DocumentFeederHeight = 11000;
  57. pRootItemInfo->DocumentFeederHReg = LEFT_JUSTIFIED;
  58. pRootItemInfo->DocumentFeederReg = LEFT_JUSTIFIED;
  59. pRootItemInfo->DocumentFeederVReg = TOP_JUSTIFIED;
  60. pRootItemInfo->MaxPageCapacity = MAX_PAGE_CAPACITY;
  61. pRootItemInfo->MaxScanTime = MAX_SCANNING_TIME;
  62. pRootItemInfo->OpticalXResolution = 300;
  63. pRootItemInfo->OpticalYResolution = 300;
  64. pRootItemInfo->ScanBedWidth = 8500;
  65. pRootItemInfo->ScanBedHeight = 11000;
  66. //
  67. // copy firmware version in string form to WCHAR array
  68. //
  69. lstrcpyW(pRootItemInfo->FirmwareVersion,L"1.0a");
  70. return hr;
  71. }
  72. HRESULT CFakeScanAPI::FakeScanner_GetTopPropertyInfo(PTOP_ITEM_INFORMATION pTopItemInfo)
  73. {
  74. HRESULT hr = S_OK;
  75. pTopItemInfo->bUseResolutionList = TRUE; // use default resolution list
  76. pTopItemInfo->Brightness.lInc = 1;
  77. pTopItemInfo->Brightness.lMax = 1000;
  78. pTopItemInfo->Brightness.lMin = -1000;
  79. pTopItemInfo->Brightness.lNom = 0;
  80. pTopItemInfo->Contrast.lInc = 1;
  81. pTopItemInfo->Contrast.lMax = 1000;
  82. pTopItemInfo->Contrast.lMin = -1000;
  83. pTopItemInfo->Contrast.lNom = 0;
  84. pTopItemInfo->Threshold.lInc = 1;
  85. pTopItemInfo->Threshold.lMax = 1000;
  86. pTopItemInfo->Threshold.lMin = -1000;
  87. pTopItemInfo->Threshold.lNom = 0;
  88. pTopItemInfo->lMaxLampWarmupTime = MAX_LAMP_WARMUP_TIME;
  89. pTopItemInfo->lMinimumBufferSize = 262140;
  90. pTopItemInfo->XResolution.lInc = 1;
  91. pTopItemInfo->XResolution.lMax = 600;
  92. pTopItemInfo->XResolution.lMin = 75;
  93. pTopItemInfo->XResolution.lNom = 150;
  94. pTopItemInfo->YResolution.lInc = 1;
  95. pTopItemInfo->YResolution.lMax = 600;
  96. pTopItemInfo->YResolution.lMin = 75;
  97. pTopItemInfo->YResolution.lNom = 150;
  98. return hr;
  99. }
  100. HRESULT CFakeScanAPI::FakeScanner_Scan(LONG lState, PBYTE pData, DWORD dwBytesToRead, PDWORD pdwBytesWritten)
  101. {
  102. HRESULT hr = S_OK;
  103. switch (lState) {
  104. case SCAN_START:
  105. m_dwBytesWrittenSoFAR = 0;
  106. m_TotalDataInDevice = CalcRandomDeviceDataTotalBytes();
  107. break;
  108. case SCAN_CONTINUE:
  109. break;
  110. case SCAN_END:
  111. m_bGreen = TRUE; // set back to green
  112. return S_OK;
  113. default:
  114. break;
  115. }
  116. if (NULL != pData) {
  117. switch (m_RawDataInfo.bpp) {
  118. case 24:
  119. {
  120. //
  121. // write green data for color
  122. //
  123. BYTE *pTempData = pData;
  124. for (DWORD dwBytes = 0; dwBytes < dwBytesToRead; dwBytes+=3) {
  125. if (m_bGreen) {
  126. pTempData[0] = 0;
  127. pTempData[1] = 128; // green
  128. pTempData[2] = 0;
  129. } else {
  130. pTempData[0] = 0;
  131. pTempData[1] = 0;
  132. pTempData[2] = 128; // blue
  133. }
  134. pTempData += 3;
  135. }
  136. }
  137. break;
  138. case 1:
  139. case 8:
  140. default:
  141. //
  142. // write simple gray for grayscale,
  143. // write vertical B/W stripes for threshold
  144. //
  145. if (m_bGreen) {
  146. memset(pData,128,dwBytesToRead);
  147. } else {
  148. memset(pData,200,dwBytesToRead);
  149. }
  150. break;
  151. }
  152. }
  153. //
  154. // fill out bytes written
  155. //
  156. if (NULL != pdwBytesWritten) {
  157. *pdwBytesWritten = dwBytesToRead;
  158. }
  159. if (m_bGreen) {
  160. m_bGreen = FALSE;
  161. } else {
  162. m_bGreen = TRUE;
  163. }
  164. if (m_lMode == UNKNOWN_FEEDER_ONLY_SCANNER_MODE) {
  165. //
  166. // keep track of bytes written so far
  167. //
  168. if (m_TotalDataInDevice == 0) {
  169. //
  170. // no data left in device
  171. //
  172. *pdwBytesWritten = 0;
  173. return hr;
  174. }
  175. if ((LONG)dwBytesToRead > m_TotalDataInDevice) {
  176. //
  177. // only give what is left in device
  178. //
  179. *pdwBytesWritten = dwBytesToRead;
  180. m_TotalDataInDevice = 0;
  181. } else {
  182. //
  183. // give full amount requested
  184. //
  185. m_TotalDataInDevice -= dwBytesToRead;
  186. if (m_TotalDataInDevice < 0) {
  187. m_TotalDataInDevice = 0;
  188. }
  189. }
  190. }
  191. return hr;
  192. }
  193. HRESULT CFakeScanAPI::FakeScanner_SetDataType(LONG lDataType)
  194. {
  195. HRESULT hr = S_OK;
  196. switch (lDataType) {
  197. case WIA_DATA_COLOR:
  198. m_RawDataInfo.bpp = 24;
  199. break;
  200. case WIA_DATA_THRESHOLD:
  201. m_RawDataInfo.bpp = 1;
  202. break;
  203. case WIA_DATA_GRAYSCALE:
  204. m_RawDataInfo.bpp = 8;
  205. break;
  206. default:
  207. hr = E_INVALIDARG;
  208. break;
  209. }
  210. return hr;
  211. }
  212. HRESULT CFakeScanAPI::FakeScanner_SetXYResolution(LONG lXResolution, LONG lYResolution)
  213. {
  214. HRESULT hr = S_OK;
  215. m_RawDataInfo.lXRes = lXResolution;
  216. m_RawDataInfo.lYRes = lYResolution;
  217. return hr;
  218. }
  219. HRESULT CFakeScanAPI::FakeScanner_SetSelectionArea(LONG lXPos, LONG lYPos, LONG lXExt, LONG lYExt)
  220. {
  221. HRESULT hr = S_OK;
  222. //
  223. // record RAW data width and height
  224. //
  225. m_RawDataInfo.lWidthPixels = lXExt;
  226. m_RawDataInfo.lHeightPixels = lYExt;
  227. return hr;
  228. }
  229. HRESULT CFakeScanAPI::FakeScanner_SetContrast(LONG lContrast)
  230. {
  231. HRESULT hr = S_OK;
  232. //
  233. // do nothing.. we are not concerned with Contrast
  234. //
  235. return hr;
  236. }
  237. HRESULT CFakeScanAPI::FakeScanner_SetIntensity(LONG lIntensity)
  238. {
  239. HRESULT hr = S_OK;
  240. //
  241. // do nothing.. we are not concerned with Intensity
  242. //
  243. return hr;
  244. }
  245. HRESULT CFakeScanAPI::FakeScanner_DisableDevice()
  246. {
  247. return S_OK;
  248. }
  249. HRESULT CFakeScanAPI::FakeScanner_EnableDevice()
  250. {
  251. return S_OK;
  252. }
  253. HRESULT CFakeScanAPI::FakeScanner_DeviceOnline()
  254. {
  255. return S_OK;
  256. }
  257. HRESULT CFakeScanAPI::FakeScanner_Diagnostic()
  258. {
  259. return S_OK;
  260. }
  261. HRESULT CFakeScanAPI::FakeScanner_GetBedWidthAndHeight(PLONG pWidth, PLONG pHeight)
  262. {
  263. HRESULT hr = E_FAIL;
  264. //
  265. // get our Root item settings, so we can use the width and height values
  266. //
  267. ROOT_ITEM_INFORMATION RootItemInfo;
  268. hr = FakeScanner_GetRootPropertyInfo(&RootItemInfo);
  269. if (SUCCEEDED(hr)) {
  270. *pWidth = RootItemInfo.ScanBedWidth;
  271. *pHeight = RootItemInfo.ScanBedHeight;
  272. }
  273. return hr;
  274. }
  275. //
  276. // standard device operations
  277. //
  278. HRESULT CFakeScanAPI::FakeScanner_ResetDevice()
  279. {
  280. return S_OK;
  281. }
  282. HRESULT CFakeScanAPI::FakeScanner_SetEmulationMode(LONG lDeviceMode)
  283. {
  284. HRESULT hr = S_OK;
  285. switch (lDeviceMode) {
  286. case UNKNOWN_FEEDER_ONLY_SCANNER_MODE:
  287. m_lMode = UNKNOWN_FEEDER_ONLY_SCANNER_MODE;
  288. break;
  289. case FLATBED_SCANNER_MODE:
  290. m_lMode = FLATBED_SCANNER_MODE;
  291. break;
  292. default:
  293. m_lMode = 0;
  294. hr = E_INVALIDARG;
  295. break;
  296. }
  297. return hr;
  298. }
  299. //
  300. // Automatic document feeder functions
  301. //
  302. HRESULT CFakeScanAPI::FakeScanner_ADFHasPaper()
  303. {
  304. HRESULT hr = S_OK;
  305. //
  306. // check paper count
  307. //
  308. if (m_PagesInADF <= 0) {
  309. hr = S_FALSE;
  310. m_PagesInADF = MAX_PAGE_CAPACITY;
  311. }
  312. return hr;
  313. }
  314. HRESULT CFakeScanAPI::FakeScanner_ADFAvailable()
  315. {
  316. HRESULT hr = S_OK;
  317. //
  318. // check ADF on-line
  319. //
  320. if (!m_ADFIsAvailable) {
  321. hr = S_FALSE;
  322. }
  323. return hr;
  324. }
  325. HRESULT CFakeScanAPI::FakeScanner_ADFFeedPage()
  326. {
  327. HRESULT hr = S_OK;
  328. if (S_OK != FakeScanner_ADFHasPaper()) {
  329. //
  330. // set paper empty error code
  331. //
  332. hr = WIA_ERROR_PAPER_EMPTY;
  333. }
  334. //
  335. // update paper count for ADF
  336. //
  337. m_PagesInADF--;
  338. if (m_PagesInADF <0) {
  339. m_PagesInADF = 0;
  340. }
  341. return hr;
  342. }
  343. HRESULT CFakeScanAPI::FakeScanner_ADFUnFeedPage()
  344. {
  345. return S_OK;
  346. }
  347. HRESULT CFakeScanAPI::FakeScanner_ADFStatus()
  348. {
  349. return m_hrLastADFError;
  350. }
  351. HRESULT CFakeScanAPI::FakeScanner_ADFAttached()
  352. {
  353. return S_OK;
  354. }
  355. LONG CFakeScanAPI::WidthToDIBWidth(LONG lWidth)
  356. {
  357. return(lWidth+3)&0xfffffffc;
  358. }
  359. LONG CFakeScanAPI::CalcTotalImageSize()
  360. {
  361. LONG lTotalSize = 0;
  362. switch (m_RawDataInfo.bpp) {
  363. case 1:
  364. lTotalSize = ((m_RawDataInfo.lHeightPixels * m_RawDataInfo.lWidthPixels) + 7) / 8;
  365. break;
  366. case 8:
  367. lTotalSize = m_RawDataInfo.lHeightPixels * m_RawDataInfo.lWidthPixels;
  368. break;
  369. case 24:
  370. lTotalSize = (m_RawDataInfo.lHeightPixels * m_RawDataInfo.lWidthPixels) * 3;
  371. break;
  372. default:
  373. break;
  374. }
  375. return lTotalSize;
  376. }
  377. LONG CFakeScanAPI::CalcRawByteWidth()
  378. {
  379. LONG lRawWidthBytes = 0;
  380. switch (m_RawDataInfo.bpp) {
  381. case 1:
  382. lRawWidthBytes = ((m_RawDataInfo.lWidthPixels) + 7) / 8;
  383. break;
  384. case 8:
  385. lRawWidthBytes = m_RawDataInfo.lWidthPixels;
  386. break;
  387. case 24:
  388. lRawWidthBytes = (m_RawDataInfo.lWidthPixels) * 3;
  389. break;
  390. default:
  391. break;
  392. }
  393. return lRawWidthBytes;
  394. }
  395. LONG CFakeScanAPI::CalcSrcByteWidth()
  396. {
  397. LONG lSrcWidthBytes = 0;
  398. switch (m_SrcDataInfo.bpp) {
  399. case 1:
  400. lSrcWidthBytes = ((m_SrcDataInfo.lWidthPixels) + 7) / 8;
  401. break;
  402. case 8:
  403. lSrcWidthBytes = m_SrcDataInfo.lWidthPixels;
  404. break;
  405. case 24:
  406. lSrcWidthBytes = (m_SrcDataInfo.lWidthPixels) * 3;
  407. break;
  408. default:
  409. break;
  410. }
  411. return lSrcWidthBytes;
  412. }
  413. LONG CFakeScanAPI::CalcRandomDeviceDataTotalBytes()
  414. {
  415. LONG lTotalBytes = 0;
  416. srand((unsigned)time(NULL));
  417. LONG lPageLengthInches = ((rand()%17) + 5);// max 22 inches, and min of 5 inches
  418. LONG lImageHeight = m_RawDataInfo.lYRes * lPageLengthInches;
  419. lTotalBytes = (CalcRawByteWidth() * lImageHeight);
  420. return lTotalBytes;
  421. }
  422. HRESULT CreateFakeScanner(CFakeScanAPI **ppFakeScanAPI, LONG lMode)
  423. {
  424. HRESULT hr = S_OK;
  425. if (ppFakeScanAPI) {
  426. *ppFakeScanAPI = NULL;
  427. *ppFakeScanAPI = new CFakeScanAPI;
  428. if (NULL == *ppFakeScanAPI) {
  429. hr = E_OUTOFMEMORY;
  430. }
  431. CFakeScanAPI* pScanAPI = (CFakeScanAPI*)*ppFakeScanAPI;
  432. pScanAPI->FakeScanner_SetEmulationMode(lMode);
  433. }
  434. return hr;
  435. }