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.

1116 lines
29 KiB

  1. #include "testmcro.h"
  2. #include "wiamicro.h"
  3. #include "resource.h"
  4. #include <STI.H>
  5. #include <math.h>
  6. #include <winioctl.h>
  7. #include <usbscan.h>
  8. #ifdef DEBUG
  9. #include <stdio.h>
  10. #endif
  11. // #define BUTTON_SUPPORT // (uncomment this to allow BUTTON SUPPORT)
  12. // button support is not functional in the test device
  13. #define MAX_BUTTONS 1
  14. #define MAX_BUTTON_NAME 255
  15. HINSTANCE g_hInst; // instance of this MicroDriver (used for loading from a resource)
  16. // note: MEMORYBMP, and BMP file will be added by wiafbdrv host driver.
  17. // do not include them in your extended list.
  18. //
  19. // #define _USE_EXTENDED_FORMAT_LIST (uncomment this to allow Extented file and memory formats)
  20. #define NUM_SUPPORTED_FILEFORMATS 1
  21. GUID g_SupportedFileFormats[NUM_SUPPORTED_FILEFORMATS];
  22. #define NUM_SUPPORTED_MEMORYFORMATS 2
  23. GUID g_SupportedMemoryFormats[NUM_SUPPORTED_MEMORYFORMATS];
  24. //
  25. // Button GUID array used in Capability negotiation.
  26. // Set your BUTTON guids here. These must match the GUIDS specified in
  27. // your INF. The Scan Button GUID is public to all scanners with a
  28. // scan button.
  29. //
  30. GUID g_Buttons[MAX_BUTTONS] ={{0xa6c5a715, 0x8c6e, 0x11d2,{ 0x97, 0x7a, 0x0, 0x0, 0xf8, 0x7a, 0x92, 0x6f}}};
  31. BOOL g_bButtonNamesCreated = FALSE;
  32. WCHAR* g_ButtonNames[MAX_BUTTONS];
  33. INT g_PalIndex = 0; // simple palette index counter (test driver specific)
  34. BOOL g_bDown = FALSE; // simple band direction bool (test drvier specific)
  35. BOOL InitializeScanner(PSCANINFO pScanInfo);
  36. VOID InitScannerDefaults(PSCANINFO pScanInfo);
  37. BOOL SetScannerSettings(PSCANINFO pScanInfo);
  38. VOID CheckButtonStatus(PVAL pValue);
  39. VOID GetButtonPress(LONG *pButtonValue);
  40. HRESULT GetInterruptEvent(PVAL pValue);
  41. LONG GetButtonCount();
  42. HRESULT GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal);
  43. VOID ReadRegistryInformation(PVAL pValue);
  44. BOOL APIENTRY DllMain( HANDLE hModule,DWORD dwreason, LPVOID lpReserved)
  45. {
  46. g_hInst = (HINSTANCE)hModule;
  47. switch(dwreason) {
  48. case DLL_PROCESS_ATTACH:
  49. case DLL_THREAD_ATTACH:
  50. case DLL_THREAD_DETACH:
  51. case DLL_PROCESS_DETACH:
  52. break;
  53. }
  54. return TRUE;
  55. }
  56. /**************************************************************************\
  57. * MicroEntry (MicroDriver Entry point)
  58. *
  59. * Called by the WIA driver to communicate with the MicroDriver.
  60. *
  61. * Arguments:
  62. *
  63. * lCommand - MicroDriver Command, sent from the WIA driver
  64. * pValue - VAL structure used for settings
  65. *
  66. *
  67. * Return Value:
  68. *
  69. * Status
  70. *
  71. * History:
  72. *
  73. * 1/20/2000 Original Version
  74. *
  75. \**************************************************************************/
  76. WIAMICRO_API HRESULT MicroEntry(LONG lCommand, PVAL pValue)
  77. {
  78. HRESULT hr = E_NOTIMPL;
  79. DWORD dwBytesWritten = 0;
  80. INT index = 0;
  81. //#define _DEBUG_COMMANDS
  82. #ifdef _DEBUG_COMMANDS
  83. if(lCommand != CMD_STI_GETSTATUS)
  84. Trace(TEXT("Command Value (%d)"),lCommand);
  85. #endif
  86. if(pValue->pScanInfo == NULL) {
  87. return E_INVALIDARG;
  88. }
  89. switch(lCommand) {
  90. case CMD_INITIALIZE:
  91. hr = S_OK;
  92. //
  93. // create any DeviceIO handles needed, use index (1 - MAX_IO_HANDLES) to store these handles.
  94. // Index '0' is reserved by the WIA flatbed driver. The CreateFile Name is stored in the szVal
  95. // member of the VAL structure.
  96. //
  97. // pValue->pScanInfo->DeviceIOHandles[1] = CreateFileA( pValue->szVal,
  98. // GENERIC_READ | GENERIC_WRITE, // Access mask
  99. // 0, // Share mode
  100. // NULL, // SA
  101. // OPEN_EXISTING, // Create disposition
  102. // FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, // Attributes
  103. // NULL );
  104. //
  105. // if your device supports buttons, create the BUTTON name information here..
  106. //
  107. if(!g_bButtonNamesCreated) {
  108. for(index = 0; index < MAX_BUTTONS; index++){
  109. g_ButtonNames[index] = (WCHAR*)CoTaskMemAlloc(MAX_BUTTON_NAME);
  110. }
  111. hr = GetOLESTRResourceString(IDS_SCAN_BUTTON_NAME,&g_ButtonNames[0],TRUE);
  112. if(SUCCEEDED(hr)){
  113. g_bButtonNamesCreated = TRUE;
  114. }
  115. }
  116. //
  117. // Initialize the scanner's default settings
  118. //
  119. InitScannerDefaults(pValue->pScanInfo);
  120. break;
  121. case CMD_UNINITIALIZE:
  122. //
  123. // close any open handles created by the Micro driver
  124. //
  125. if(pValue->pScanInfo->DeviceIOHandles[1] != NULL){
  126. CloseHandle(pValue->pScanInfo->DeviceIOHandles[1]);
  127. }
  128. //
  129. // if your device supports buttons, free/destroy the BUTTON name information here..
  130. //
  131. if(g_bButtonNamesCreated) {
  132. for(index = 0; index < MAX_BUTTONS; index++){
  133. CoTaskMemFree(g_ButtonNames[index]);
  134. }
  135. }
  136. //
  137. // close/unload libraries
  138. //
  139. hr = S_OK;
  140. break;
  141. case CMD_RESETSCANNER:
  142. //
  143. // reset scanner
  144. //
  145. hr = S_OK;
  146. break;
  147. case CMD_STI_DIAGNOSTIC:
  148. case CMD_STI_DEVICERESET:
  149. //
  150. // reset device
  151. //
  152. hr = S_OK;
  153. break;
  154. case CMD_STI_GETSTATUS:
  155. //
  156. // set status flag to ON-LINE
  157. //
  158. pValue->lVal = MCRO_STATUS_OK;
  159. pValue->pGuid = (GUID*) &GUID_NULL;
  160. //
  161. // button polling support
  162. //
  163. #ifdef BUTTON_SUPPORT
  164. CheckButtonStatus(pValue);
  165. #endif
  166. hr = S_OK;
  167. break;
  168. case CMD_SETXRESOLUTION:
  169. pValue->pScanInfo->Xresolution = pValue->lVal;
  170. hr = S_OK;
  171. break;
  172. case CMD_SETYRESOLUTION:
  173. pValue->pScanInfo->Yresolution = pValue->lVal;
  174. hr = S_OK;
  175. break;
  176. case CMD_SETCONTRAST:
  177. pValue->pScanInfo->Contrast = pValue->lVal;
  178. hr = S_OK;
  179. break;
  180. case CMD_SETINTENSITY:
  181. pValue->pScanInfo->Intensity = pValue->lVal;
  182. hr = S_OK;
  183. break;
  184. case CMD_SETDATATYPE:
  185. pValue->pScanInfo->DataType = pValue->lVal;
  186. hr = S_OK;
  187. break;
  188. case CMD_SETNEGATIVE:
  189. pValue->pScanInfo->Negative = pValue->lVal;
  190. hr = S_OK;
  191. break;
  192. case CMD_GETADFSTATUS:
  193. case CMD_GETADFHASPAPER:
  194. // pValue->lVal = MCRO_ERROR_PAPER_EMPTY;
  195. // hr = S_OK;
  196. break;
  197. case CMD_GET_INTERRUPT_EVENT:
  198. hr = GetInterruptEvent(pValue);
  199. break;
  200. case CMD_GETCAPABILITIES:
  201. pValue->lVal = 0;
  202. pValue->pGuid = NULL;
  203. pValue->ppButtonNames = NULL;
  204. hr = S_OK;
  205. break;
  206. case CMD_SETSCANMODE:
  207. hr = S_OK;
  208. switch(pValue->lVal){
  209. case SCANMODE_FINALSCAN:
  210. Trace(TEXT("Final Scan"));
  211. break;
  212. case SCANMODE_PREVIEWSCAN:
  213. Trace(TEXT("Preview Scan"));
  214. break;
  215. default:
  216. Trace(TEXT("Unknown Scan Mode (%d)"),pValue->lVal);
  217. hr = E_FAIL;
  218. break;
  219. }
  220. break;
  221. case CMD_SETSTIDEVICEHKEY:
  222. ReadRegistryInformation(pValue);
  223. break;
  224. #ifdef _USE_EXTENDED_FORMAT_LIST
  225. // note: MEMORYBMP, and BMP file will be added by wiafbdrv host driver.
  226. // do not include them in your extended list.
  227. //
  228. case CMD_GETSUPPORTEDFILEFORMATS:
  229. g_SupportedFileFormats[0] = WiaImgFmt_JPEG;
  230. pValue->lVal = NUM_SUPPORTED_FILEFORMATS;
  231. pValue->pGuid = g_SupportedFileFormats;
  232. hr = S_OK;
  233. break;
  234. case CMD_GETSUPPORTEDMEMORYFORMATS:
  235. g_SupportedMemoryFormats[0] = WiaImgFmt_TIFF;
  236. g_SupportedMemoryFormats[1] = WiaImgFmt_MYNEWFORMAT;
  237. pValue->lVal = NUM_SUPPORTED_MEMORYFORMATS;
  238. pValue->pGuid = g_SupportedMemoryFormats;
  239. hr = S_OK;
  240. break;
  241. #endif
  242. default:
  243. Trace(TEXT("Unknown Command (%d)"),lCommand);
  244. break;
  245. }
  246. return hr;
  247. }
  248. /**************************************************************************\
  249. * Scan (MicroDriver Entry point)
  250. *
  251. * Called by the WIA driver to acquire data from the MicroDriver.
  252. *
  253. * Arguments:
  254. *
  255. * pScanInfo - SCANINFO structure used for settings
  256. * lPhase - Current Scan phase, SCAN_FIRST, SCAN_NEXT, SCAN_FINISH...
  257. * pBuffer - data buffer to be filled with scanned data
  258. * lLength - Maximum length of pBuffer
  259. * plReceived - Number of actual bytes written to pBuffer.
  260. *
  261. *
  262. * Return Value:
  263. *
  264. * Status
  265. *
  266. * History:
  267. *
  268. * 1/20/2000 Original Version
  269. *
  270. \**************************************************************************/
  271. WIAMICRO_API HRESULT Scan(PSCANINFO pScanInfo, LONG lPhase, PBYTE pBuffer, LONG lLength, LONG *plReceived)
  272. {
  273. if(pScanInfo == NULL) {
  274. return E_INVALIDARG;
  275. }
  276. INT i = 0;
  277. Trace(TEXT("------ Scan Requesting %d ------"),lLength);
  278. switch (lPhase) {
  279. case SCAN_FIRST:
  280. if (!SetScannerSettings(pScanInfo)) {
  281. return E_FAIL;
  282. }
  283. Trace(TEXT("SCAN_FIRST"));
  284. g_PalIndex = 0;
  285. g_bDown = FALSE;
  286. //
  287. // first phase
  288. //
  289. Trace(TEXT("Start Scan.."));
  290. case SCAN_NEXT: // SCAN_FIRST will fall through to SCAN_NEXT (because it is expecting data)
  291. //
  292. // next phase
  293. //
  294. if(lPhase == SCAN_NEXT)
  295. Trace(TEXT("SCAN_NEXT"));
  296. //
  297. // get data from the scanner and set plReceived value
  298. //
  299. //
  300. // read data
  301. //
  302. switch(pScanInfo->DataType) {
  303. case WIA_DATA_THRESHOLD:
  304. //
  305. // make buffer alternate black/White, for sample 1-bit data
  306. //
  307. memset(pBuffer,0,lLength);
  308. memset(pBuffer,255,lLength/2);
  309. break;
  310. case WIA_DATA_GRAYSCALE:
  311. //
  312. // make buffer grayscale data, for sample 8-bit data
  313. //
  314. if(!g_bDown){
  315. g_PalIndex+=10;
  316. if(g_PalIndex > 255){
  317. g_PalIndex = 255;
  318. g_bDown = TRUE;
  319. }
  320. }
  321. else {
  322. g_PalIndex-=10;
  323. if(g_PalIndex < 0){
  324. g_PalIndex = 0;
  325. g_bDown = FALSE;
  326. }
  327. }
  328. memset(pBuffer,g_PalIndex,lLength);
  329. break;
  330. case WIA_DATA_COLOR:
  331. //
  332. // make buffer red, for sample color data
  333. //
  334. for (i = 0;i+2<lLength;i+=3) {
  335. memset(pBuffer+i,255,1);
  336. memset(pBuffer+(i+1),0,1);
  337. memset(pBuffer+(i+2),0,1);
  338. }
  339. break;
  340. default:
  341. break;
  342. }
  343. //
  344. // test device always returns the exact amount of scanned data
  345. //
  346. *plReceived = lLength;
  347. break;
  348. case SCAN_FINISHED:
  349. default:
  350. Trace(TEXT("SCAN_FINISHED"));
  351. //
  352. // stop scanner, do not set lRecieved, or write any data to pBuffer. Those values
  353. // will be NULL. This lPhase is only to allow you to stop scanning, and return the
  354. // scan head to the HOME position. SCAN_FINISHED will be called always for regular scans, and
  355. // for cancelled scans.
  356. //
  357. break;
  358. }
  359. return S_OK;
  360. }
  361. /**************************************************************************\
  362. * SetPixelWindow (MicroDriver Entry point)
  363. *
  364. * Called by the WIA driver to set the scan selection area to the MicroDriver.
  365. *
  366. * Arguments:
  367. *
  368. * pScanInfo - SCANINFO structure used for settings
  369. * pValue - VAL structure used for settings
  370. * x - X Position of scan rect (upper left x coordinate)
  371. * y - Y Position of scan rect (upper left y coordinate)
  372. * xExtent - Width of scan rect (in pixels)
  373. * yExtent - Height of scan rect (in pixels)
  374. *
  375. *
  376. * Return Value:
  377. *
  378. * Status
  379. *
  380. * History:
  381. *
  382. * 1/20/2000 Original Version
  383. *
  384. \**************************************************************************/
  385. WIAMICRO_API HRESULT SetPixelWindow(PSCANINFO pScanInfo, LONG x, LONG y, LONG xExtent, LONG yExtent)
  386. {
  387. if(pScanInfo == NULL) {
  388. return E_INVALIDARG;
  389. }
  390. pScanInfo->Window.xPos = x;
  391. pScanInfo->Window.yPos = y;
  392. pScanInfo->Window.xExtent = xExtent;
  393. pScanInfo->Window.yExtent = yExtent;
  394. return S_OK;
  395. }
  396. /**************************************************************************\
  397. * ReadRegistryInformation (helper)
  398. *
  399. * Called by the MicroDriver to Read registry information from the device's
  400. * installed device section. The HKEY passed in will be closed by the host
  401. * driver after CMD_INITIALIZE is completed.
  402. *
  403. * Arguments:
  404. *
  405. * none
  406. *
  407. * Return Value:
  408. *
  409. * void
  410. *
  411. * History:
  412. *
  413. * 1/20/2000 Original Version
  414. *
  415. \**************************************************************************/
  416. VOID ReadRegistryInformation(PVAL pValue)
  417. {
  418. HKEY hKey = NULL;
  419. if(NULL != pValue->pHandle){
  420. hKey = (HKEY)*pValue->pHandle;
  421. //
  422. // Open DeviceData section to read driver specific information
  423. //
  424. HKEY hOpenKey = NULL;
  425. if (RegOpenKeyEx(hKey, // handle to open key
  426. TEXT("DeviceData"), // address of name of subkey to open
  427. 0, // options (must be NULL)
  428. KEY_QUERY_VALUE|KEY_READ, // just want to QUERY a value
  429. &hOpenKey // address of handle to open key
  430. ) == ERROR_SUCCESS) {
  431. DWORD dwWritten = sizeof(DWORD);
  432. DWORD dwType = REG_DWORD;
  433. LONG lSampleEntry = 0;
  434. RegQueryValueEx(hOpenKey,
  435. TEXT("Sample Entry"),
  436. NULL,
  437. &dwType,
  438. (LPBYTE)&lSampleEntry,
  439. &dwWritten);
  440. Trace(TEXT("lSampleEntry Value = %d"),lSampleEntry);
  441. } else {
  442. Trace(TEXT("Could not open DeviceData section"));
  443. }
  444. }
  445. }
  446. /**************************************************************************\
  447. * InitScannerDefaults (helper)
  448. *
  449. * Called by the MicroDriver to Initialize the SCANINFO structure
  450. *
  451. * Arguments:
  452. *
  453. * none
  454. *
  455. * Return Value:
  456. *
  457. * void
  458. *
  459. * History:
  460. *
  461. * 1/20/2000 Original Version
  462. *
  463. \**************************************************************************/
  464. VOID InitScannerDefaults(PSCANINFO pScanInfo)
  465. {
  466. pScanInfo->ADF = 0; // set to no ADF in Test device
  467. pScanInfo->RawDataFormat = WIA_PACKED_PIXEL;
  468. pScanInfo->RawPixelOrder = WIA_ORDER_BGR;
  469. pScanInfo->bNeedDataAlignment = TRUE;
  470. pScanInfo->SupportedCompressionType = 0;
  471. pScanInfo->SupportedDataTypes = SUPPORT_BW|SUPPORT_GRAYSCALE|SUPPORT_COLOR;
  472. pScanInfo->BedWidth = 8500; // 1000's of an inch (WIA compatible unit)
  473. pScanInfo->BedHeight = 11000; // 1000's of an inch (WIA compatible unit)
  474. pScanInfo->OpticalXResolution = 300;
  475. pScanInfo->OpticalYResolution = 300;
  476. pScanInfo->IntensityRange.lMin = -127;
  477. pScanInfo->IntensityRange.lMax = 127;
  478. pScanInfo->IntensityRange.lStep = 1;
  479. pScanInfo->ContrastRange.lMin = -127;
  480. pScanInfo->ContrastRange.lMax = 127;
  481. pScanInfo->ContrastRange.lStep = 1;
  482. // Scanner settings
  483. pScanInfo->Intensity = 0;
  484. pScanInfo->Contrast = 0;
  485. pScanInfo->Xresolution = 150;
  486. pScanInfo->Yresolution = 150;
  487. pScanInfo->Window.xPos = 0;
  488. pScanInfo->Window.yPos = 0;
  489. pScanInfo->Window.xExtent = (pScanInfo->Xresolution * pScanInfo->BedWidth)/1000;
  490. pScanInfo->Window.yExtent = (pScanInfo->Yresolution * pScanInfo->BedHeight)/1000;
  491. // Scanner options
  492. pScanInfo->DitherPattern = 0;
  493. pScanInfo->Negative = 0;
  494. pScanInfo->Mirror = 0;
  495. pScanInfo->AutoBack = 0;
  496. pScanInfo->ColorDitherPattern = 0;
  497. pScanInfo->ToneMap = 0;
  498. pScanInfo->Compression = 0;
  499. // Image Info
  500. pScanInfo->DataType = WIA_DATA_GRAYSCALE;
  501. pScanInfo->WidthPixels = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos);
  502. switch(pScanInfo->DataType) {
  503. case WIA_DATA_THRESHOLD:
  504. pScanInfo->PixelBits = 1;
  505. break;
  506. case WIA_DATA_COLOR:
  507. pScanInfo->PixelBits = 24;
  508. break;
  509. case WIA_DATA_GRAYSCALE:
  510. default:
  511. pScanInfo->PixelBits = 8;
  512. break;
  513. }
  514. pScanInfo->WidthBytes = pScanInfo->Window.xExtent * (pScanInfo->PixelBits/8);
  515. pScanInfo->Lines = pScanInfo->Window.yExtent;
  516. }
  517. /**************************************************************************\
  518. * SetScannerSettings (helper)
  519. *
  520. * Called by the MicroDriver to set the values stored in the SCANINFO structure
  521. * to the actual device.
  522. *
  523. * Arguments:
  524. *
  525. * none
  526. *
  527. *
  528. * Return Value:
  529. *
  530. * TRUE - Success, FALSE - Failure
  531. *
  532. * History:
  533. *
  534. * 1/20/2000 Original Version
  535. *
  536. \**************************************************************************/
  537. BOOL SetScannerSettings(PSCANINFO pScanInfo)
  538. {
  539. if(pScanInfo->DataType == WIA_DATA_THRESHOLD) {
  540. pScanInfo->PixelBits = 1;
  541. pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/7);
  542. //
  543. // Set data type to device
  544. //
  545. // if the set fails..
  546. // return FALSE;
  547. }
  548. else if(pScanInfo->DataType == WIA_DATA_GRAYSCALE) {
  549. pScanInfo->PixelBits = 8;
  550. pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/8);
  551. //
  552. // Set data type to device
  553. //
  554. // if the set fails..
  555. // return FALSE;
  556. }
  557. else {
  558. pScanInfo->PixelBits = 24;
  559. pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/8);
  560. //
  561. // Set data type to device
  562. //
  563. // if the set fails..
  564. // return FALSE;
  565. }
  566. #ifdef DEBUG
  567. Trace(TEXT("ScanInfo"));
  568. Trace(TEXT("x res = %d"),pScanInfo->Xresolution);
  569. Trace(TEXT("y res = %d"),pScanInfo->Yresolution);
  570. Trace(TEXT("bpp = %d"),pScanInfo->PixelBits);
  571. Trace(TEXT("xpos = %d"),pScanInfo->Window.xPos);
  572. Trace(TEXT("ypos = %d"),pScanInfo->Window.yPos);
  573. Trace(TEXT("xext = %d"),pScanInfo->Window.xExtent);
  574. Trace(TEXT("yext = %d"),pScanInfo->Window.yExtent);
  575. #endif
  576. //
  577. // send other values to device, use the values set in pScanInfo to set them to your
  578. // device.
  579. //
  580. return TRUE;
  581. }
  582. /**************************************************************************\
  583. * InitializeScanner (helper)
  584. *
  585. * Called by the MicroDriver to Iniitialize any device specific operations
  586. *
  587. * Arguments:
  588. *
  589. * none
  590. *
  591. * Return Value:
  592. *
  593. * TRUE - Success, FALSE - Failure
  594. *
  595. * History:
  596. *
  597. * 1/20/2000 Original Version
  598. *
  599. \**************************************************************************/
  600. BOOL InitializeScanner(PSCANINFO pScanInfo)
  601. {
  602. HRESULT hr = S_OK;
  603. //
  604. // Do any device initialization here...
  605. // The test device does not need any.
  606. //
  607. if (SUCCEEDED(hr)) {
  608. return TRUE;
  609. }
  610. return FALSE;
  611. }
  612. /**************************************************************************\
  613. * CheckButtonStatus (helper)
  614. *
  615. * Called by the MicroDriver to Set the current Button pressed value.
  616. *
  617. * Arguments:
  618. *
  619. * pValue - VAL structure used for settings
  620. *
  621. *
  622. * Return Value:
  623. *
  624. * VOID
  625. *
  626. * History:
  627. *
  628. * 1/20/2000 Original Version
  629. *
  630. \**************************************************************************/
  631. VOID CheckButtonStatus(PVAL pValue)
  632. {
  633. //
  634. // Button Polling is done here...
  635. //
  636. //
  637. // Check your device for button presses
  638. //
  639. LONG lButtonValue = 0;
  640. GetButtonPress(&lButtonValue);
  641. switch (lButtonValue) {
  642. case 1:
  643. pValue->pGuid = (GUID*) &guidScanButton;
  644. Trace(TEXT("Scan Button Pressed!"));
  645. break;
  646. default:
  647. pValue->pGuid = (GUID*) &GUID_NULL;
  648. break;
  649. }
  650. }
  651. /**************************************************************************\
  652. * GetInterruptEvent (helper)
  653. *
  654. * Called by the MicroDriver to handle USB interrupt events.
  655. *
  656. * Arguments:
  657. *
  658. * pValue - VAL structure used for settings
  659. *
  660. *
  661. * Return Value:
  662. *
  663. * Status
  664. *
  665. * History:
  666. *
  667. * 1/20/2000 Original Version
  668. *
  669. \**************************************************************************/
  670. HRESULT GetInterruptEvent(PVAL pValue)
  671. {
  672. //
  673. // Below is a simple example of how DeviceIOControl() can be used to
  674. // determine interrupts with a USB device.
  675. //
  676. // The test device does not support events,
  677. // So this should not be called.
  678. //
  679. BYTE InterruptData;
  680. DWORD dwIndex;
  681. DWORD dwError;
  682. OVERLAPPED Overlapped;
  683. ZeroMemory( &Overlapped, sizeof( Overlapped ));
  684. Overlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  685. HANDLE hEventArray[2] = {pValue->handle, Overlapped.hEvent};
  686. BOOL fLooping = TRUE;
  687. BOOL bRet = TRUE;
  688. //
  689. // use the Handle created in CMD_INITIALIZE.
  690. //
  691. HANDLE InterruptHandle = pValue->pScanInfo->DeviceIOHandles[1];
  692. while (fLooping) {
  693. //
  694. // Set the wait event, for the interrupt
  695. //
  696. bRet = DeviceIoControl( InterruptHandle,
  697. IOCTL_WAIT_ON_DEVICE_EVENT,
  698. NULL,
  699. 0,
  700. &InterruptData,
  701. sizeof(InterruptData),
  702. &dwError,
  703. &Overlapped );
  704. if ( bRet || ( !bRet && ( ::GetLastError() == ERROR_IO_PENDING ))) {
  705. //
  706. // Wait for the event to happen
  707. //
  708. dwIndex = WaitForMultipleObjects( 2,
  709. hEventArray,
  710. FALSE,
  711. INFINITE );
  712. //
  713. // Trap the result of the event
  714. //
  715. switch ( dwIndex ) {
  716. case WAIT_OBJECT_0+1:
  717. DWORD dwBytesRet;
  718. bRet = GetOverlappedResult( InterruptHandle, &Overlapped, &dwBytesRet, FALSE );
  719. if ( dwBytesRet ) {
  720. //
  721. // assign the corresponding button GUID to the *pValue->pGuid
  722. // member., and Set the event.
  723. //
  724. // Change detected - signal
  725. if (*pValue->pHandle != INVALID_HANDLE_VALUE) {
  726. switch ( InterruptData ) {
  727. case 1:
  728. *pValue->pGuid = guidScanButton;
  729. Trace(TEXT("Scan Button Pressed!"));
  730. break;
  731. default:
  732. *pValue->pGuid = GUID_NULL;
  733. break;
  734. }
  735. Trace(TEXT("Setting This Event by Handle %d"),*pValue->pHandle);
  736. //
  737. // signal the event, after a button GUID was assigned.
  738. //
  739. SetEvent(*pValue->pHandle);
  740. }
  741. break;
  742. }
  743. //
  744. // reset the overlapped event
  745. //
  746. ResetEvent( Overlapped.hEvent );
  747. break;
  748. case WAIT_OBJECT_0:
  749. // Fall through
  750. default:
  751. fLooping = FALSE;
  752. }
  753. }
  754. else {
  755. dwError = ::GetLastError();
  756. break;
  757. }
  758. }
  759. return S_OK;
  760. }
  761. /**************************************************************************\
  762. * GetButtonPress (helper)
  763. *
  764. * Called by the MicroDriver to set the actual button value pressed
  765. *
  766. * Arguments:
  767. *
  768. * pButtonValue - actual button pressed
  769. *
  770. *
  771. * Return Value:
  772. *
  773. * Status
  774. *
  775. * History:
  776. *
  777. * 1/20/2000 Original Version
  778. *
  779. \**************************************************************************/
  780. VOID GetButtonPress(LONG *pButtonValue)
  781. {
  782. //
  783. // This where you can set your button value
  784. //
  785. pButtonValue = 0;
  786. }
  787. /**************************************************************************\
  788. * GetButtonCount (helper)
  789. *
  790. * Called by the MicroDriver to get the number of buttons a device supports
  791. *
  792. * Arguments:
  793. *
  794. * none
  795. *
  796. * Return Value:
  797. *
  798. * LONG - number of supported buttons
  799. *
  800. * History:
  801. *
  802. * 1/20/2000 Original Version
  803. *
  804. \**************************************************************************/
  805. LONG GetButtonCount()
  806. {
  807. LONG ButtonCount = 0;
  808. //
  809. // Since the test device does not have a button,
  810. // set this value to 0. For a real device with a button,
  811. // set (LONG ButtonCount = 1;)
  812. //
  813. //
  814. // determine the button count of your device
  815. //
  816. return ButtonCount;
  817. }
  818. /**************************************************************************\
  819. * GetOLDSTRResourceString (helper)
  820. *
  821. * Called by the MicroDriver to Load a resource string in OLESTR format
  822. *
  823. * Arguments:
  824. *
  825. * lResourceID - String resource ID
  826. * ppsz - Pointer to a OLESTR to be filled with the loaded string
  827. * value
  828. * bLocal - Possible, other source for loading a resource string.
  829. *
  830. *
  831. * Return Value:
  832. *
  833. * Status
  834. *
  835. * History:
  836. *
  837. * 1/20/2000 Original Version
  838. *
  839. \**************************************************************************/
  840. HRESULT GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal)
  841. {
  842. HRESULT hr = S_OK;
  843. TCHAR szStringValue[255];
  844. if(bLocal) {
  845. //
  846. // We are looking for a resource in our own private resource file
  847. //
  848. INT NumTCHARs = LoadString(g_hInst,lResourceID,szStringValue,sizeof(szStringValue));
  849. DWORD dwError = GetLastError();
  850. if (NumTCHARs <= 0) {
  851. #ifdef UNICODE
  852. Trace(TEXT("NumTCHARs = %d dwError = %d Resource ID = %d (UNICODE)szString = %ws"),
  853. NumTCHARs,
  854. dwError,
  855. lResourceID,
  856. szStringValue);
  857. #else
  858. Trace(TEXT("NumTCHARs = %d dwError = %d Resource ID = %d (ANSI)szString = %s"),
  859. NumTCHARs,
  860. dwError,
  861. lResourceID,
  862. szStringValue);
  863. #endif
  864. return E_FAIL;
  865. }
  866. //
  867. // NOTE: caller must free this allocated BSTR
  868. //
  869. #ifdef UNICODE
  870. *ppsz = NULL;
  871. *ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(szStringValue));
  872. if(*ppsz != NULL) {
  873. wcscpy(*ppsz,szStringValue);
  874. } else {
  875. return E_OUTOFMEMORY;
  876. }
  877. #else
  878. WCHAR wszStringValue[255];
  879. ZeroMemory(wszStringValue,sizeof(wszStringValue));
  880. //
  881. // convert szStringValue from char* to unsigned short* (ANSI only)
  882. //
  883. MultiByteToWideChar(CP_ACP,
  884. MB_PRECOMPOSED,
  885. szStringValue,
  886. lstrlenA(szStringValue)+1,
  887. wszStringValue,
  888. (sizeof(wszStringValue)/sizeof(WCHAR)));
  889. *ppsz = NULL;
  890. *ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(wszStringValue));
  891. if(*ppsz != NULL) {
  892. wcscpy(*ppsz,wszStringValue);
  893. } else {
  894. return E_OUTOFMEMORY;
  895. }
  896. #endif
  897. } else {
  898. //
  899. // looking another place for resources??
  900. //
  901. hr = E_NOTIMPL;
  902. }
  903. return hr;
  904. }
  905. /**************************************************************************\
  906. * Trace
  907. *
  908. * Called by the MicroDriver to output strings to a debugger
  909. *
  910. * Arguments:
  911. *
  912. * format - formatted string to output
  913. *
  914. *
  915. * Return Value:
  916. *
  917. * VOID
  918. *
  919. * History:
  920. *
  921. * 1/20/2000 Original Version
  922. *
  923. \**************************************************************************/
  924. VOID Trace(LPCTSTR format,...)
  925. {
  926. #ifdef DEBUG
  927. TCHAR Buffer[1024];
  928. va_list arglist;
  929. va_start(arglist, format);
  930. wvsprintf(Buffer, format, arglist);
  931. va_end(arglist);
  932. OutputDebugString(Buffer);
  933. OutputDebugString(TEXT("\n"));
  934. #endif
  935. }