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.

3102 lines
98 KiB

  1. /******************************************************************************
  2. wsti.cpp
  3. WDM Still Imaging interface
  4. Copyright (C) Microsoft Corporation, 1997 - 1998
  5. All rights reserved
  6. Notes:
  7. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  8. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  9. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  10. PURPOSE.
  11. ******************************************************************************/
  12. #include "stillvue.h"
  13. //
  14. // globals defined in Stivar.h
  15. //
  16. extern PDEVLOG pdevPtr, // pointer to current device log device
  17. pdevRoot; // base of the device log table
  18. extern PSTR pszStr1,pszStr2,pszStr3, // utility strings
  19. pszStr4;
  20. extern HINSTANCE hThisInstance; // instance of this app
  21. extern HANDLE hNTLog; // NT log handle
  22. extern HMENU hMenu; // current menu
  23. extern int *pSuite; // pointer to test Suite to run
  24. extern int nError, nICanScan, // global flags
  25. nNextTest, // index into pSuite
  26. nNameOnly, nScanCount,
  27. nTestID,
  28. nUnSubscribeSemaphore, // semaphore for StiSubscribe
  29. nUnSubscribe; // flag to request UnSubscribe
  30. //
  31. // STI.H - STI_DEVICE_MJ_TYPE
  32. //
  33. STRINGTABLE StStiDeviceType[] =
  34. {
  35. 0, "StiDeviceTypeDefault",0,
  36. 1, "StiDeviceTypeScanner",0,
  37. 2, "StiDeviceTypeDigitalCamera",0,
  38. 0, "Unknown device type",-1
  39. };
  40. //
  41. // STIERR.H - errors
  42. //
  43. STRINGTABLE StStiError[] =
  44. {
  45. STI_OK, "STI_OK",0,
  46. STI_NOTCONNECTED, "STI_NOTCONNECTED",0,
  47. STI_CHANGENOEFFECT, "STI_CHANGENOEFFECT",0,
  48. STIERR_OLD_VERSION, "STIERR_OLD_VERSION",0,
  49. STIERR_BETA_VERSION, "STIERR_BETA_VERSION",0,
  50. STIERR_BADDRIVER, "STIERR_BADDRIVER",0,
  51. STIERR_DEVICENOTREG, "STIERR_DEVICENOTREG",0,
  52. STIERR_OBJECTNOTFOUND, "STIERR_OBJECTNOTFOUND",0,
  53. STIERR_INVALID_PARAM, "STIERR_INVALID_PARAM",0,
  54. STIERR_NOINTERFACE, "STIERR_NOINTERFACE",0,
  55. STIERR_GENERIC, "STIERR_GENERIC", 0,
  56. STIERR_OUTOFMEMORY, "STIERR_OUTOFMEMORY", 0,
  57. STIERR_UNSUPPORTED, "STIERR_UNSUPPORTED", 0,
  58. STIERR_NOT_INITIALIZED, "STIERR_NOT_INITIALIZED", 0,
  59. STIERR_ALREADY_INITIALIZED, "STIERR_ALREADY_INITIALIZED", 0,
  60. STIERR_DEVICE_LOCKED, "STIERR_DEVICE_LOCKED", 0,
  61. STIERR_READONLY, "STIERR_READONLY", 0,
  62. STIERR_NOTINITIALIZED, "STIERR_NOTINITIALIZED", 0,
  63. STIERR_NEEDS_LOCK, "STIERR_NEEDS_LOCK", 0,
  64. STIERR_SHARING_VIOLATION, "STIERR_SHARING_VIOLATION", 0,
  65. STIERR_HANDLEEXISTS, "STIERR_HANDLEEXISTS", 0,
  66. STIERR_INVALID_DEVICE_NAME, "STIERR_INVALID_DEVICE_NAME", 0,
  67. STIERR_INVALID_HW_TYPE, "STIERR_INVALID_HW_TYPE", 0,
  68. STIERR_INVALID_HW_TYPE, "STIERR_INVALID_HW_TYPE", 0,
  69. STIERR_NOEVENTS, "STIERR_NOEVENTS", 0,
  70. 0, "Unknown STI error",-1
  71. };
  72. //
  73. // WINNT.H - Predefined Value Types.
  74. //
  75. STRINGTABLE StRegValType[] =
  76. {
  77. 0, "REG_NONE",0,
  78. 1, "REG_SZ",0,
  79. 3, "REG_BINARY",0,
  80. 4, "REG_DWORD",0,
  81. 0, "Unknown reg type",-1
  82. };
  83. //
  84. // global still image
  85. //
  86. PSTI pSti = NULL; // handle to Sti subsystem
  87. PVOID pStiInfo = NULL; // Sti device info buffer
  88. PSTI_DEVICE_INFORMATION pStiInfoPtr = NULL; // pointer to device in pStiBuffer
  89. PSTIDEVICE pStiDevice = NULL; // Sti device being used
  90. HANDLE hWaitEvent; // Subscribe Event handle
  91. int nStiNumber = 0; // 0 based index into pStiInfo
  92. DWORD dwStiTotal = 0; // total number of Sti devices found
  93. WCHAR szInternalName[STI_MAX_INTERNAL_NAME_LENGTH];
  94. // user selected Sti device name
  95. WCHAR szFriendlyName[STI_MAX_INTERNAL_NAME_LENGTH];
  96. // user selected Sti friendly name
  97. /*****************************************************************************
  98. define ACQUIRE to load device specific command handler for stub
  99. functions defined in STIDDK.CPP
  100. *****************************************************************************/
  101. #ifdef ACQUIRE
  102. //
  103. // device specific image acquire code
  104. //
  105. #include "acquire.cpp"
  106. #else
  107. //
  108. // only exercise Sti services
  109. //
  110. #include "stisvc.cpp"
  111. #endif
  112. /*****************************************************************************
  113. void IStillImageMenu(DWORD dwState)
  114. Enable or Disable the menus for the IStillDevice interface.
  115. Parameters:
  116. MF_ENABLED or MF_GRAYED
  117. Return:
  118. none
  119. *****************************************************************************/
  120. void IStillImageMenu(DWORD dwState)
  121. {
  122. EnableMenuItem(hMenu, IDM_IMAGE_RELEASE, dwState);
  123. EnableMenuItem(hMenu, IDM_GET_DEVLIST, dwState);
  124. EnableMenuItem(hMenu, IDM_CREATE_DEV, dwState);
  125. EnableMenuItem(hMenu, IDM_REGISTER_LAUNCH, dwState);
  126. EnableMenuItem(hMenu, IDM_UNREGISTER_LAUNCH, dwState);
  127. EnableMenuItem(hMenu, IDM_WRITE_ERRORLOG, dwState);
  128. }
  129. /*****************************************************************************
  130. void IStillNameMenu(DWORD dwState)
  131. Enable or Disable the menus for the IStillImage interface that only
  132. require a device name.
  133. Parameters:
  134. MF_ENABLED or MF_GRAYED
  135. Return:
  136. none
  137. *****************************************************************************/
  138. void IStillNameMenu(DWORD dwState)
  139. {
  140. EnableMenuItem(hMenu, IDM_GET_DEVINFO, dwState);
  141. EnableMenuItem(hMenu, IDM_GET_DEVVAL, dwState);
  142. EnableMenuItem(hMenu, IDM_SET_DEVVAL, dwState);
  143. EnableMenuItem(hMenu, IDM_GET_LAUNCHINFO, dwState);
  144. EnableMenuItem(hMenu, IDM_ENABLE_HWNOTIF, dwState);
  145. EnableMenuItem(hMenu, IDM_GET_HWNOTIF, dwState);
  146. EnableMenuItem(hMenu, IDM_REFRESH_DEVBUS, dwState);
  147. EnableMenuItem(hMenu, IDM_LAUNCH_APP_FOR_DEV, dwState);
  148. EnableMenuItem(hMenu, IDM_SETUP_DEVPARAMS, dwState);
  149. }
  150. /*****************************************************************************
  151. void IStillDeviceMenu(DWORD dwState)
  152. Enable or Disable the menus for the IStillDevice interface.
  153. Parameters:
  154. MF_ENABLED or MF_GRAYED
  155. Return:
  156. none
  157. *****************************************************************************/
  158. void IStillDeviceMenu(DWORD dwState)
  159. {
  160. EnableMenuItem(hMenu, IDM_GET_CAPS, dwState);
  161. EnableMenuItem(hMenu, IDM_GET_STATUS_A, dwState);
  162. EnableMenuItem(hMenu, IDM_GET_STATUS_B, dwState);
  163. EnableMenuItem(hMenu, IDM_GET_STATUS_C, dwState);
  164. EnableMenuItem(hMenu, IDM_DEVICERESET, dwState);
  165. EnableMenuItem(hMenu, IDM_DIAGNOSTIC, dwState);
  166. EnableMenuItem(hMenu, IDM_ESCAPE_A, dwState);
  167. EnableMenuItem(hMenu, IDM_ESCAPE_B, dwState);
  168. EnableMenuItem(hMenu, IDM_GET_LASTERRINFO, dwState);
  169. EnableMenuItem(hMenu, IDM_LOCKDEV, dwState);
  170. EnableMenuItem(hMenu, IDM_UNLOCKDEV, dwState);
  171. EnableMenuItem(hMenu, IDM_RAWREADDATA_A, dwState);
  172. EnableMenuItem(hMenu, IDM_RAWREADDATA_B, dwState);
  173. EnableMenuItem(hMenu, IDM_RAWWRITEDATA_A, dwState);
  174. EnableMenuItem(hMenu, IDM_RAWWRITEDATA_B, dwState);
  175. EnableMenuItem(hMenu, IDM_RAWREADCOMMAND_A, dwState);
  176. EnableMenuItem(hMenu, IDM_RAWREADCOMMAND_B, dwState);
  177. EnableMenuItem(hMenu, IDM_RAWWRITECOMMAND_A, dwState);
  178. EnableMenuItem(hMenu, IDM_RAWWRITECOMMAND_B, dwState);
  179. EnableMenuItem(hMenu, IDM_SUBSCRIBE, dwState);
  180. EnableMenuItem(hMenu, IDM_UNSUBSCRIBE, dwState);
  181. EnableMenuItem(hMenu, IDM_DEVICE_RELEASE, dwState);
  182. }
  183. /*****************************************************************************
  184. void IStillScanMenu(DWORD dwState)
  185. Enable or Disable the menus for scanning.
  186. Parameters:
  187. MF_ENABLED or MF_GRAYED
  188. Return:
  189. none
  190. *****************************************************************************/
  191. void IStillScanMenu(DWORD dwState)
  192. {
  193. EnableMenuItem(hMenu, IDM_LAMPON, dwState);
  194. EnableMenuItem(hMenu, IDM_LAMPOFF, dwState);
  195. EnableMenuItem(hMenu, IDM_SCAN, dwState);
  196. }
  197. /*****************************************************************************
  198. int NextStiDevice()
  199. Select next valid Sti device
  200. Parameters:
  201. none
  202. Return:
  203. number of next sti device (0 == first)
  204. *****************************************************************************/
  205. int NextStiDevice()
  206. {
  207. //
  208. // select next device from static list (go to first at end of list)
  209. //
  210. nStiNumber++;
  211. if ( nStiNumber >= (int) dwStiTotal ) {
  212. //
  213. // point to head of list
  214. //
  215. nStiNumber = 0;
  216. }
  217. //
  218. // select next device from device log (go to first at end of list)
  219. //
  220. if ( pdevPtr->pNext ) {
  221. pdevPtr = pdevPtr->pNext;
  222. } else {
  223. //
  224. // point to head of list
  225. //
  226. pdevPtr = pdevRoot;
  227. }
  228. return nStiNumber;
  229. }
  230. /*****************************************************************************
  231. HRESULT StiCreateInstance(BOOL *)
  232. Opens Sti subsystem
  233. Parameters:
  234. Pointer to receive PASS/FAIL status
  235. Return:
  236. HRESULT of last Sti call
  237. *****************************************************************************/
  238. HRESULT StiCreateInstance(BOOL *bPass)
  239. {
  240. HRESULT hres = STI_OK;
  241. BOOL bReturn;
  242. //
  243. // close any open devices before enumeration
  244. //
  245. StiClose(&bReturn);
  246. //
  247. // The StiCreateInstance interface locates the primary still image interface.
  248. // Use this call to optain the pointer to the IStillImage interface.
  249. //
  250. hres = StiCreateInstance(
  251. GetModuleHandle(NULL), // instance handle of this application
  252. STI_VERSION, // Sti version
  253. &pSti, // pointer to IStillImage interface
  254. NULL // pointer to controlling unknown of OLE aggregation
  255. );
  256. if ( ! SUCCEEDED(hres) ) {
  257. StiDisplayError(hres,"StiCreateInstance",TRUE);
  258. *bPass = FALSE;
  259. return (STIERR_GENERIC);
  260. }
  261. *bPass = TRUE;
  262. DisplayOutput(" The Sti subsystem is opened");
  263. DisplayOutput("");
  264. //
  265. // Enable the menu items for IStillImage interface calls available
  266. //
  267. IStillImageMenu(MF_ENABLED);
  268. EnableMenuItem(hMenu, IDM_CREATE_INSTANCE, MF_GRAYED);
  269. return (hres);
  270. }
  271. /*****************************************************************************
  272. HRESULT StiClose(BOOL *)
  273. Close any open devices and Sti subsystem
  274. Parameters:
  275. pointer to receive Pass/Fail result
  276. Return:
  277. HRESULT of last Sti call
  278. *****************************************************************************/
  279. HRESULT StiClose(BOOL *bPass)
  280. {
  281. HRESULT hres = STI_OK;
  282. *bPass = TRUE;
  283. // stop subscribing
  284. nUnSubscribe = 0;
  285. // close any open devices and then close Sti subsystem
  286. hres = StiDeviceRelease(bPass);
  287. hres = StiImageRelease(bPass);
  288. //
  289. // clear the internal device name and the friendly user name
  290. //
  291. ZeroMemory(szInternalName,STI_MAX_INTERNAL_NAME_LENGTH);
  292. ZeroMemory(szFriendlyName,STI_MAX_INTERNAL_NAME_LENGTH);
  293. return (hres);
  294. }
  295. /*****************************************************************************
  296. HRESULT StiDeviceRelease(BOOL *)
  297. Close the Sti subsystem
  298. Parameters:
  299. pointer to receive Pass/Fail result
  300. Return:
  301. HRESULT of last failed Sti call
  302. *****************************************************************************/
  303. HRESULT StiDeviceRelease(BOOL *bPass)
  304. {
  305. HRESULT hres = STI_OK,
  306. hError = STI_OK;
  307. *bPass = TRUE;
  308. //
  309. // Need to UnSuscribe if the semaphore is set.
  310. //
  311. if ( nUnSubscribeSemaphore ) {
  312. //
  313. // clear the semaphores
  314. //
  315. nUnSubscribe = nUnSubscribeSemaphore = 0;
  316. // UnSubscribe is called when an application no longer wants to receive
  317. // events from a device.
  318. //
  319. hres = pStiDevice->UnSubscribe();
  320. if ( ! SUCCEEDED(hres) ) {
  321. StiDisplayError(hres,"UnSubscribe",TRUE);
  322. hError = hres;
  323. *bPass = FALSE;
  324. }
  325. //
  326. // we're done with the event
  327. //
  328. CloseHandle(hWaitEvent);
  329. DisplayOutput(" StiDeviceRelease has UnSubscribed");
  330. }
  331. //
  332. // The STI_DEVICE_INFORMATION array returned by GetDeviceList needs to
  333. // be freed with LocalFree(). Also, resetting internal Sti device counter.
  334. //
  335. if ( pStiInfo )
  336. LocalFree(pStiInfo);
  337. pStiInfo = pStiInfoPtr = NULL;
  338. //
  339. // close device if any are open
  340. //
  341. if ( pStiDevice ) {
  342. //
  343. // Close an open device.
  344. //
  345. hres = pStiDevice->Release();
  346. if ( ! SUCCEEDED(hres) ) {
  347. StiDisplayError(hres,"Release (Device)",TRUE);
  348. hError = hres;
  349. *bPass = FALSE;
  350. } else
  351. DisplayOutput(" Device Released");
  352. DisplayOutput("");
  353. //
  354. // clear the Sti device pointer
  355. //
  356. pStiDevice = NULL;
  357. //
  358. // disable IStiDevice menu items
  359. //
  360. IStillDeviceMenu(MF_GRAYED);
  361. IStillNameMenu(MF_GRAYED);
  362. IStillScanMenu(MF_GRAYED);
  363. EnableMenuItem(hMenu, IDM_IMAGE_RELEASE, MF_ENABLED);
  364. CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_UNCHECKED);
  365. }
  366. return (hError);
  367. }
  368. /*****************************************************************************
  369. HRESULT StiImageRelease(BOOL *)
  370. Close the Sti subsystem
  371. Parameters:
  372. pointer to receive Pass/Fail result
  373. Return:
  374. HRESULT of last Sti call
  375. *****************************************************************************/
  376. HRESULT StiImageRelease(BOOL *bPass)
  377. {
  378. HRESULT hres = STI_OK;
  379. *bPass = TRUE;
  380. //
  381. // if Sti subsystem is open, close it
  382. //
  383. if ( pSti ) {
  384. //
  385. // Close the Still Imaging subsystem.
  386. //
  387. hres = pSti->Release();
  388. if ( ! SUCCEEDED(hres) ) {
  389. StiDisplayError(hres,"Release (Image)",TRUE);
  390. *bPass = FALSE;
  391. } else
  392. DisplayOutput(" Imaging subsystem Released");
  393. DisplayOutput("");
  394. //
  395. // clear the Sti subsystem pointer
  396. //
  397. pSti = NULL;
  398. //
  399. // Disable the menu items for IStillImage interface calls
  400. //
  401. IStillNameMenu(MF_GRAYED);
  402. IStillImageMenu(MF_GRAYED);
  403. EnableMenuItem(hMenu, IDM_CREATE_INSTANCE, MF_ENABLED);
  404. }
  405. return (hres);
  406. }
  407. /*****************************************************************************
  408. HRESULT StiEnum(BOOL *)
  409. Opens Sti subsystem and enumerates any still image devices found
  410. Parameters:
  411. Pointer to receive PASS/FAIL status
  412. Return:
  413. HRESULT of last Sti call
  414. *****************************************************************************/
  415. HRESULT StiEnum(BOOL *bPass)
  416. {
  417. HRESULT hres = STI_OK;
  418. DWORD dwCounter;
  419. DWORD dwStiCount = 0;
  420. PSTI_DEVICE_INFORMATION pI = NULL;
  421. BOOL bReturn;
  422. PCSTR pszStringTablePtr = NULL;
  423. //
  424. // check that Sti subsystem is loaded
  425. //
  426. if ( ! pSti ) {
  427. *bPass = FALSE;
  428. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  429. return (STIERR_GENERIC);
  430. }
  431. //
  432. // Enumerate devices
  433. //
  434. dwStiTotal = 0;
  435. pStiInfo = NULL;
  436. //
  437. // The GetDeviceList interface is used to get a list of the installed still
  438. // image devices. Use this call to obtain a STI_DEVICE_INFORMATION array
  439. // filled with info on all currently installed Sti devices.
  440. // * NOTE: the STI subsystem allocates memory for the Sti device information
  441. // buffer, but the caller needs to free this memory with LocalFree().
  442. //
  443. hres = pSti->GetDeviceList(
  444. NULL, // Type (reserved, use NULL)
  445. NULL, // Flags (reserved, use NULL)
  446. &dwStiTotal, // address of variable to return number of devices found
  447. &pStiInfo // Sti device info buffer
  448. );
  449. if ( ! SUCCEEDED(hres) || ! pStiInfo ) {
  450. StiDisplayError(hres,"GetDeviceList",TRUE);
  451. StiClose(&bReturn);
  452. *bPass = FALSE;
  453. return (STIERR_GENERIC);
  454. }
  455. *bPass = TRUE;
  456. //
  457. // Display Sti info on each device found
  458. //
  459. for ( dwCounter = 0,pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo;
  460. dwCounter < dwStiTotal;
  461. dwCounter++, pStiInfoPtr++ ) {
  462. DisplayOutput(" Device number %2d",dwCounter + 1);
  463. pszStringTablePtr = StrFromTable(GET_STIDEVICE_TYPE(pStiInfoPtr->DeviceType),
  464. StStiDeviceType);
  465. DisplayOutput(" Device type %xh %s",
  466. GET_STIDEVICE_TYPE(pStiInfoPtr->DeviceType),
  467. pszStringTablePtr);
  468. DisplayOutput(" Device subtype %xh",
  469. GET_STIDEVICE_SUBTYPE(pStiInfoPtr->DeviceType));
  470. DisplayOutput(" Internal name \"%S\"",
  471. pStiInfoPtr->szDeviceInternalName);
  472. DisplayOutput(" Device capabilities %xh",
  473. pStiInfoPtr->DeviceCapabilities);
  474. DisplayOutput(" Hardware configuration %xh",
  475. pStiInfoPtr->dwHardwareConfiguration);
  476. DisplayOutput(" Vendor description \"%S\"",
  477. pStiInfoPtr->pszVendorDescription);
  478. DisplayOutput(" Device description \"%S\"",
  479. pStiInfoPtr->pszDeviceDescription);
  480. DisplayOutput(" Port Name \"%S\"",
  481. pStiInfoPtr->pszPortName);
  482. DisplayOutput(" Prop provider \"%S\"",
  483. pStiInfoPtr->pszPropProvider);
  484. DisplayOutput(" Local name \"%S\"",
  485. pStiInfoPtr->pszLocalName);
  486. DisplayOutput("");
  487. }
  488. //
  489. // point to most recently selected device again
  490. //
  491. pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo + nStiNumber;
  492. DisplayOutput(" GetDeviceList found %d device%s",dwStiTotal,
  493. dwStiTotal == 1 ? "" : "s");
  494. if ( dwStiTotal != dwCounter ) {
  495. DisplayOutput("* Get DeviceList actually returned %d devices",dwCounter);
  496. dwStiTotal = dwCounter;
  497. nError++;
  498. pdevPtr-nError++;
  499. }
  500. DisplayOutput("");
  501. return (hres);
  502. }
  503. /*****************************************************************************
  504. HRESULT StiEnumPrivate(PVOID *, DWORD *)
  505. Call GetDeviceList and return pointer to struct
  506. Parameters:
  507. Pointer to private DeviceList
  508. Pointer to number of devices found counter
  509. Return:
  510. HRESULT of last Sti call
  511. *****************************************************************************/
  512. HRESULT StiEnumPrivate(PVOID *pPtr, DWORD *dwHowMany)
  513. {
  514. HRESULT hres = STI_OK;
  515. BOOL bReturn;
  516. //
  517. // check that Sti subsystem is loaded
  518. //
  519. if ( ! pSti )
  520. return (STIERR_GENERIC);
  521. //
  522. // The GetDeviceList interface is used to get a list of the installed still
  523. // image devices. Use this call to obtain a STI_DEVICE_INFORMATION array
  524. // filled with info on all currently installed Sti devices.
  525. // * NOTE: the STI subsystem allocates memory for the Sti device information
  526. // buffer, but the caller needs to free this memory with LocalFree().
  527. //
  528. hres = pSti->GetDeviceList(
  529. NULL, // Type (reserved, use NULL)
  530. NULL, // Flags (reserved, use NULL)
  531. dwHowMany, // address of variable to return number of devices found
  532. pPtr // Sti device info buffer
  533. );
  534. if ( ! SUCCEEDED(hres) || ! *pPtr ) {
  535. StiDisplayError(hres,"GetDeviceList",TRUE);
  536. StiClose(&bReturn);
  537. return (STIERR_GENERIC);
  538. }
  539. return (hres);
  540. }
  541. /*****************************************************************************
  542. INT StiSelect(HWND hWnd,int nContext,BOOL *)
  543. Select and open a specific Still Image device
  544. Parameters:
  545. handle to current window
  546. context we were called from
  547. pointer to receive Pass/Fail
  548. Return:
  549. 0 on success, -1 on error
  550. *****************************************************************************/
  551. INT StiSelect(HWND hWnd,int nContext,BOOL *bPass)
  552. {
  553. HRESULT hres = STI_OK;
  554. BOOL bReturn;
  555. //
  556. // check that Sti subsystem is loaded
  557. //
  558. if ( ! pSti ) {
  559. *bPass = FALSE;
  560. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  561. return (-1);
  562. }
  563. *bPass = TRUE;
  564. //
  565. // look for devices if count of available is 0
  566. //
  567. if ( dwStiTotal == 0 ) {
  568. StiEnum(&bReturn);
  569. }
  570. //
  571. // if still no devices, inform user and leave
  572. //
  573. if ( dwStiTotal == 0 ) {
  574. ZeroMemory(szInternalName,sizeof(szInternalName));
  575. ZeroMemory(szFriendlyName,sizeof(szFriendlyName));
  576. DisplayOutput("* No Sti devices found!");
  577. DisplayOutput("");
  578. *bPass = FALSE;
  579. return (-1);
  580. }
  581. switch ( nContext ) {
  582. case EVENT:
  583. //
  584. // Sti push event or automated test
  585. //
  586. if ( nStiNumber == -1 ) {
  587. //
  588. // we could not select the correct device, just return
  589. //
  590. nStiNumber = 0;
  591. return (0);
  592. }
  593. break;
  594. case MANUAL:
  595. //
  596. // manual device selection
  597. //
  598. bReturn = fDialog(IDD_SELECT, hWnd, (FARPROC) SelectDevice);
  599. //
  600. // just return if user pressed CANCEL in dialog
  601. //
  602. if ( bReturn == FALSE ) {
  603. return (0);
  604. }
  605. break;
  606. }
  607. //
  608. // close any currently active imaging device
  609. //
  610. if ( pStiDevice )
  611. StiDeviceRelease(&bReturn);
  612. //
  613. // get pointer to device selected in dialog
  614. //
  615. pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo + nStiNumber;
  616. if ( ! *(pStiInfoPtr->szDeviceInternalName) ) {
  617. DisplayOutput("* Invalid device name !");
  618. nError++;
  619. pdevPtr-nError++;
  620. *bPass = FALSE;
  621. return (-1);
  622. }
  623. //
  624. // copy the internal device name and the friendly user name
  625. //
  626. wcscpy(szInternalName,pStiInfoPtr->szDeviceInternalName);
  627. wcscpy(szFriendlyName,pStiInfoPtr->pszLocalName);
  628. IStillNameMenu(MF_ENABLED);
  629. DisplayOutput(" Selected device %d \"%S\"",nStiNumber + 1,szInternalName);
  630. DisplayOutput(" Friendly name \"%S\"",szFriendlyName);
  631. //
  632. // Are we selecting the device or just its name?
  633. //
  634. if ( ! nNameOnly ) {
  635. //
  636. // The CreateDevice interface creates an IStiDevice object.
  637. // The IStiDevice object provides access to the IStiDevice interface
  638. // and device specific Imaging functionality.
  639. //
  640. hres = pSti->CreateDevice(
  641. pStiInfoPtr->szDeviceInternalName,
  642. // internal device name
  643. STI_DEVICE_CREATE_BOTH, // device creation mode
  644. &pStiDevice, // pointer where IStiDevice object is to be stored
  645. NULL ); // pointer to controlling unknown of OLE aggregation
  646. if ( ! SUCCEEDED(hres) || ! pStiDevice ) {
  647. StiDisplayError(hres,"CreateDevice",TRUE);
  648. DisplayOutput("* \"%S\" (%S) cannot be tested",
  649. pStiInfoPtr->pszLocalName,pStiInfoPtr->szDeviceInternalName);
  650. DisplayOutput("");
  651. *bPass = FALSE;
  652. return (-1);
  653. }
  654. //
  655. // enable Sti menu items
  656. //
  657. IStillDeviceMenu(MF_ENABLED);
  658. CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_CHECKED);
  659. EnableMenuItem(hMenu, IDM_IMAGE_RELEASE, MF_GRAYED);
  660. //
  661. // Do we have scan commands for this device?
  662. //
  663. if ( nICanScan = IsScanDevice(pStiInfoPtr) ) {
  664. IStillScanMenu(MF_ENABLED);
  665. }
  666. DisplayOutput(" \"%S\" is ready for Testing",szFriendlyName);
  667. }
  668. DisplayOutput("");
  669. return (0);
  670. }
  671. /******************************************************************************
  672. BOOL FAR PASCAL SelectDevice(HWND,UINT,WPARAM,LPARAM)
  673. Put up a dialog for user to select a Still Image device
  674. Parameters:
  675. The usual dialog box parameters.
  676. Return:
  677. Result of the call.
  678. ******************************************************************************/
  679. BOOL FAR PASCAL SelectDevice(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
  680. {
  681. PSTI_DEVICE_INFORMATION
  682. pTmpInfoPtr;
  683. DWORD dwCounter;
  684. int iIndex;
  685. static int iLastPick = 0;
  686. switch ( msg ) {
  687. case WM_INITDIALOG:
  688. //
  689. // fill dialog with Sti Device Internal Names
  690. //
  691. for ( dwCounter = 0, pTmpInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo;
  692. dwCounter < dwStiTotal;dwCounter++, pTmpInfoPtr++ ) {
  693. //
  694. // convert UNICODE string to ANSI
  695. //
  696. wsprintf(pszStr1,"%ls",pTmpInfoPtr->pszLocalName);
  697. iIndex = SendDlgItemMessage(hDlg,IDC_SELECT_DEVICE,
  698. CB_ADDSTRING,0,(LPARAM) (LPCTSTR) pszStr1);
  699. }
  700. SendDlgItemMessage(hDlg,IDC_SELECT_DEVICE,CB_SETCURSEL,iLastPick,0);
  701. return (TRUE);
  702. case WM_COMMAND:
  703. switch ( wParam ) {
  704. case IDOK:
  705. nStiNumber = SendDlgItemMessage(hDlg,IDC_SELECT_DEVICE,
  706. CB_GETCURSEL,0,0);
  707. nNameOnly = SendDlgItemMessage(hDlg,IDC_SELECT_NAME,
  708. BM_GETCHECK,0,0);
  709. //
  710. // ensure device number not greater than total
  711. // (NOTE: dwStiTotal is 1's base, while nStiNumber is 0 based)
  712. //
  713. if ( nStiNumber >= (int) dwStiTotal )
  714. nStiNumber = (int) dwStiTotal - 1;
  715. if ( nStiNumber < 0 )
  716. nStiNumber = 0;
  717. iLastPick = nStiNumber;
  718. EndDialog(hDlg, TRUE);
  719. return (TRUE);
  720. case IDCANCEL:
  721. EndDialog(hDlg, FALSE);
  722. return (TRUE);
  723. }
  724. }
  725. return (FALSE);
  726. }
  727. /*****************************************************************************
  728. void StiDisplayError(HRESULT,char *,BOOL)
  729. Display verbose error information
  730. Parameters:
  731. HRESULT from failed call
  732. TRUE = record error as compliance failure
  733. Return:
  734. none
  735. *****************************************************************************/
  736. void StiDisplayError(HRESULT hres,char *szCall,BOOL bFail)
  737. {
  738. PERRECORD pR = pdevPtr->pRecord;
  739. BOOL bReturn;
  740. StiGetLastErrorInfo(&bReturn);
  741. LastError(TRUE);
  742. //
  743. // record the error
  744. //
  745. pR += nTestID;
  746. pR->nCount++;
  747. // BUG BUG can't copy the string correctly to UNICODE string
  748. // sprintf(pszStr4,"%s",StrFromTable(hres,StStiError));
  749. // swprintf(pR->szErrorString,L"%s",pszStr4);
  750. //
  751. // compliance test failure error?
  752. //
  753. if ( bFail ) {
  754. nError++;
  755. pdevPtr-nError++;
  756. pR->bFatal = TRUE;
  757. DisplayOutput("* Sti Compliance test error");
  758. tlLog(hNTLog,TL_LOG,"* Sti Compliance test error");
  759. } else {
  760. DisplayOutput("* Allowed error");
  761. }
  762. DisplayOutput("* %s returned %xh (%d)",szCall,hres,hres);
  763. if ( bFail )
  764. tlLog(hNTLog,TL_LOG,"* %s returned %xh (%d)",szCall,hres,hres);
  765. DisplayOutput(" \"%s\"",StrFromTable(hres,StStiError));
  766. if ( bFail )
  767. tlLog(hNTLog,TL_LOG," \"%s\"",StrFromTable(hres,StStiError));
  768. return;
  769. }
  770. /******************************************************************************
  771. int InitPrivateList(PDEVLOG,int *)
  772. Initialize private test structures
  773. Parameters:
  774. pointer to Devicelog to initialize
  775. pointer to test suite
  776. Return:
  777. total number of devices found (-1 on failure)
  778. ******************************************************************************/
  779. int InitPrivateList(PDEVLOG *pDev,int *pSuiteList)
  780. {
  781. DWORD dwStiDevCount = 0;
  782. PVOID pList = NULL;
  783. PSTI_DEVICE_INFORMATION
  784. pInfoPrivatePtr = NULL; // pointer to device in pStiBuffer
  785. PDEVLOG pPtr = NULL;
  786. PERRECORD precPtr = NULL;
  787. int i,k,nNumberTests,nTotalDevices;
  788. BOOL bReturn;
  789. //
  790. // get the current number of devices and their names
  791. //
  792. StiCreateInstance(&bReturn);
  793. StiEnumPrivate(&pList,&dwStiDevCount);
  794. if ( ! pList ) {
  795. DisplayOutput("* No Sti device attached !");
  796. } else {
  797. pInfoPrivatePtr = (PSTI_DEVICE_INFORMATION) pList;
  798. }
  799. //
  800. // create at least one list entry (even if no devices are found)
  801. //
  802. if ( ! dwStiDevCount ) {
  803. dwStiDevCount = 1;
  804. nTotalDevices = 0;
  805. } else
  806. nTotalDevices = (int) dwStiDevCount;
  807. //
  808. // create a device log for each device
  809. //
  810. pPtr = (PDEVLOG) calloc(dwStiDevCount,sizeof(DEVLOG));
  811. if ( pPtr == NULL ) {
  812. FatalError("Could not initialize private structures");
  813. return (-1);
  814. }
  815. *pDev = pPtr;
  816. //
  817. // count the number of tests in suite
  818. //
  819. for ( nNumberTests = 0;pSuiteList[nNumberTests] != -1;nNumberTests++ )
  820. ;
  821. //
  822. // initialize linked list pointers and error records for each device log
  823. //
  824. for ( i = 0;i < (int) dwStiDevCount;i++,pPtr++,pInfoPrivatePtr++ ) {
  825. if ( i ) {
  826. (pPtr - 1)->pNext = pPtr;
  827. pPtr->pPrev = pPtr - 1;
  828. }
  829. if ( nTotalDevices ) {
  830. wcscpy(pPtr->szInternalName,pInfoPrivatePtr->szDeviceInternalName);
  831. wcscpy(pPtr->szLocalName,pInfoPrivatePtr->pszLocalName);
  832. } else {
  833. wcscpy(pPtr->szInternalName,L"* Invalid !");
  834. wcscpy(pPtr->szLocalName,L"* No Sti device attached !");
  835. }
  836. //
  837. // create one error log for each test (nNumberTests)
  838. //
  839. pPtr->pRecord = (PERRECORD) calloc(nNumberTests,sizeof(ERRECORD));
  840. if ( pPtr->pRecord == NULL ) {
  841. FatalError("Could not initialize private structures");
  842. return (-1);
  843. }
  844. //
  845. // initialize linked list pointers and error records for each record
  846. //
  847. for ( k = 0,precPtr = pPtr->pRecord;k < nNumberTests;k++,precPtr++ ) {
  848. precPtr->nIndex = k;
  849. precPtr->nTest = pSuite[k];
  850. if ( k ) {
  851. (precPtr - 1)->pNext = precPtr;
  852. precPtr->pPrev = precPtr - 1;
  853. }
  854. }
  855. }
  856. //
  857. // free the device list
  858. //
  859. LocalFree(pList);
  860. StiClose(&bReturn);
  861. return (nTotalDevices);
  862. }
  863. /******************************************************************************
  864. int ClosePrivateList(PDEVLOG)
  865. Remove private test structures
  866. Parameters:
  867. pointer to Devicelog to close
  868. Return:
  869. 0 on success
  870. -1 on failure
  871. ******************************************************************************/
  872. int ClosePrivateList(PDEVLOG *pDev)
  873. {
  874. PDEVLOG pPtr = (PDEVLOG) *pDev;
  875. if ( pDev == NULL )
  876. return (0);
  877. //
  878. // free each device log's error record
  879. //
  880. for ( ;pPtr->pNext;pPtr++ ) {
  881. if ( pPtr->pRecord )
  882. free(pPtr->pRecord);
  883. }
  884. //
  885. // free the device log
  886. //
  887. if ( *pDev ) {
  888. free(*pDev);
  889. *pDev = NULL;
  890. }
  891. return (0);
  892. }
  893. /*****************************************************************************
  894. HRESULT StiGetDeviceValue(LPWSTR,LPWSTR,DWORD *,BOOL *)
  895. Get driver information
  896. Parameters:
  897. szDevname - internal device name
  898. szKeyname - key to access
  899. dwType - pointer to data type
  900. pointer to receive Pass/Fail result
  901. Return:
  902. HRESULT of last Sti call
  903. *****************************************************************************/
  904. HRESULT StiGetDeviceValue(LPWSTR szDevname,LPWSTR szKeyname,LPBYTE pData,
  905. DWORD *dwType,DWORD cbData,BOOL *bPass)
  906. {
  907. HRESULT hres = STI_OK;
  908. //
  909. // WINNT.H - Predefined Value Types
  910. //
  911. STRINGTABLE StRegType[] =
  912. {
  913. REG_NONE, "REG_NONE",0,
  914. REG_SZ, "REG_SZ",0,
  915. REG_BINARY, "REG_BINARY",0,
  916. REG_DWORD, "REG_DWORD",0,
  917. 0, "Unknown Reg Type",-1
  918. };
  919. //
  920. // check that Sti subsystem is loaded
  921. //
  922. if ( ! pSti ) {
  923. *bPass = FALSE;
  924. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  925. return (STIERR_GENERIC);
  926. }
  927. *bPass = TRUE;
  928. ZeroMemory(pData,cbData);
  929. DisplayOutput(" GetDeviceValue for device \"%S\"",szDevname);
  930. DisplayOutput(" Key requested: \"%S\"",szKeyname);
  931. //
  932. // The GetDeviceValue function is used to retrieve data associated with a
  933. // still image device. Essentially, data is associated with a device
  934. // through a key/data type/value triplet. The only reserved standard
  935. // ValueNames, as defined in STI.H, are the following:
  936. //
  937. // ICMProfiles - string containing a comma-sperated list of ICM profiles
  938. // TwainDS - TWAIN data source display name
  939. // ISISDriverName - ISIS driver name
  940. //
  941. hres = pSti->GetDeviceValue(
  942. szDevname, // internal device name
  943. szKeyname, // value tag string
  944. dwType, // pointer where data type will be stored
  945. pData, // pointer where value will be stored
  946. &cbData // size of value pointer storage
  947. );
  948. if ( !SUCCEEDED(hres) ) {
  949. //
  950. // The only required registry item is STI_DEVICE_VALUE_ICM_PROFILE
  951. //
  952. if ( hres == STIERR_OBJECTNOTFOUND ) {
  953. if ( ! wcscmp(STI_DEVICE_VALUE_ICM_PROFILE,szKeyname) ) {
  954. //
  955. // Only STI_DEVICE_VALUE_ICM_PROFILE is a required key
  956. // Therefore, only this one Failure is a COMPLIANCE test failure
  957. //
  958. *bPass = FALSE;
  959. StiDisplayError(hres,"GetDeviceValue",TRUE);
  960. } else {
  961. StiDisplayError(hres,"GetDeviceValue",FALSE);
  962. }
  963. } else {
  964. *bPass = FALSE;
  965. StiDisplayError(hres,"GetDeviceValue",TRUE);
  966. }
  967. } else {
  968. DisplayOutput(" Reg Type %d %s",* dwType,
  969. StrFromTable(*dwType,StRegType));
  970. DisplayOutput(" The following %d bytes were read from the Registry:",
  971. cbData);
  972. DisplayOutput(" \"%s\"",pData);
  973. }
  974. DisplayOutput("");
  975. return (hres);
  976. }
  977. /*****************************************************************************
  978. HRESULT StiSetDeviceValue(LPWSTR,LPWSTR,LPWSTR,DWORD,BOOL *)
  979. Set driver information
  980. Parameters:
  981. szDevname - internal device name
  982. szKeyname - key to access
  983. pData - value to write
  984. dwType - data type
  985. pointer to receive Pass/Fail result
  986. Return:
  987. HRESULT of last Sti call
  988. *****************************************************************************/
  989. HRESULT StiSetDeviceValue(LPWSTR szDevname,LPWSTR szKeyname,LPBYTE pData,
  990. DWORD dwType,DWORD cbData,BOOL *bPass)
  991. {
  992. HRESULT hres = STI_OK;
  993. //
  994. // WINNT.H - Predefined Value Types
  995. //
  996. STRINGTABLE StRegType[] =
  997. {
  998. REG_NONE, "REG_NONE",0,
  999. REG_SZ, "REG_SZ",0,
  1000. REG_BINARY, "REG_BINARY",0,
  1001. REG_DWORD, "REG_DWORD",0,
  1002. 0, "Unknown Reg Type",-1
  1003. };
  1004. //
  1005. // check that Sti subsystem is loaded
  1006. //
  1007. if ( ! pSti ) {
  1008. *bPass = FALSE;
  1009. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  1010. return (STIERR_GENERIC);
  1011. }
  1012. *bPass = TRUE;
  1013. DisplayOutput(" SetDeviceValue for device \"%S\"",szDevname);
  1014. DisplayOutput(" Key \"%S",szKeyname);
  1015. //
  1016. // The SetDeviceValue function is used to associate any additional data
  1017. // with a still image device. It is used internally to store the values of
  1018. // strings that are required to communicate information to imaging APIs
  1019. // during use of push model behavoir. However, this function can be used
  1020. // to associate any ancillary data with a device. The only reserved
  1021. // ValueNames, as defined in STI.H, are the following:
  1022. //
  1023. // ICMProfiles - string containing a comma-sperated list of ICM profiles
  1024. // TwainDS - TWAIN data source display name
  1025. // ISISDriverName - ISIS driver name
  1026. //
  1027. hres = pSti->SetDeviceValue(
  1028. szDevname, // internal device name
  1029. szKeyname, // value tag string
  1030. dwType, // data type sent
  1031. pData, // pointer to data to send
  1032. cbData // byte size of data
  1033. );
  1034. if ( !SUCCEEDED(hres) ) {
  1035. //
  1036. // SetDeviceValue is not required under NT
  1037. //
  1038. StiDisplayError(hres,"SetDeviceValue",FALSE);
  1039. } else {
  1040. //pszStr1 = StrFromTable(dwType,StRegType);
  1041. DisplayOutput(" Reg Type %d %s",dwType,StrFromTable(dwType,StRegType));
  1042. DisplayOutput(" The following %d bytes were written to the Registry:",
  1043. cbData);
  1044. DisplayOutput(" \"%s\"",(char *) pData);
  1045. }
  1046. DisplayOutput("");
  1047. return (hres);
  1048. }
  1049. /*****************************************************************************
  1050. HRESULT StiRegister(HWND,int,BOOL *)
  1051. Register or Unregister the application to receive Sti Launch events.
  1052. Parameters:
  1053. Handle to the window to display image in.
  1054. Instance for access to string table
  1055. int nOnOff == ON to register, OFF to unregister
  1056. pointer to receive Pass/Fail result
  1057. Return:
  1058. HRESULT of last failed Sti call
  1059. *****************************************************************************/
  1060. HRESULT StiRegister(HWND hWnd,HINSTANCE hInstance,int nOnOff,BOOL *bPass)
  1061. {
  1062. HRESULT hres = STI_OK,
  1063. hError = STI_OK;
  1064. CHAR szModulePath[MAX_PATH+1];
  1065. WCHAR szModulePathW[MAX_PATH+1],
  1066. szAppName[MEDSTRING];
  1067. DWORD cch;
  1068. //
  1069. // check that Sti subsystem is loaded
  1070. //
  1071. if ( ! pSti ) {
  1072. *bPass = FALSE;
  1073. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  1074. return (STIERR_GENERIC);
  1075. }
  1076. *bPass = TRUE;
  1077. //
  1078. // Retrieve name of this application from STRING table
  1079. // and convert to UNICODE.
  1080. //
  1081. LoadString(hInstance,IDS_APPNAME,pszStr1,MEDSTRING);
  1082. cch = MultiByteToWideChar(CP_ACP, 0,
  1083. pszStr1, -1,
  1084. szAppName,MEDSTRING);
  1085. if ( ! cch ) {
  1086. LastError(TRUE);
  1087. *bPass = FALSE;
  1088. return (STIERR_GENERIC);
  1089. }
  1090. //
  1091. // Register/deregister app
  1092. //
  1093. if ( nOnOff == ON ) {
  1094. //
  1095. // Register our application.
  1096. // Get full path to executable and convert to UNICODE.
  1097. //
  1098. cch = GetModuleFileName(NULL,szModulePath,sizeof(szModulePath));
  1099. if ( ! cch ) {
  1100. LastError(TRUE);
  1101. *bPass = FALSE;
  1102. return (STIERR_GENERIC);
  1103. }
  1104. cch = MultiByteToWideChar(CP_ACP, 0,
  1105. szModulePath, -1,
  1106. szModulePathW, sizeof(szModulePathW));
  1107. //
  1108. // The RegisterLaunchApplication function should be called by
  1109. // applications that would like to be launched in response to an
  1110. // Sti push event. This function can be called more than once,
  1111. // and should be called each time the application rus in case
  1112. // the user relocates the application.
  1113. //
  1114. hres = pSti->RegisterLaunchApplication(
  1115. szAppName, // short name of app
  1116. szModulePathW // full path to executable
  1117. );
  1118. if ( ! SUCCEEDED(hres) ) {
  1119. StiDisplayError(hres,"RegisterLaunchApplication",TRUE);
  1120. *bPass = FALSE;
  1121. hError = hres;
  1122. } else {
  1123. DisplayOutput(" %s registered for Sti Launch Application",pszStr1);
  1124. }
  1125. } else {
  1126. //
  1127. // Unregister our application
  1128. //
  1129. hres = pSti->UnregisterLaunchApplication(
  1130. szAppName // short name of app
  1131. );
  1132. if ( ! SUCCEEDED(hres) ) {
  1133. StiDisplayError(hres,"UnregisterLaunchApplication",TRUE);
  1134. hError = hres;
  1135. } else {
  1136. DisplayOutput(" %s Unregistered from Sti Launch",pszStr1);
  1137. }
  1138. }
  1139. DisplayOutput("");
  1140. return (hError);
  1141. }
  1142. /*****************************************************************************
  1143. HRESULT StiEvent(HWND hWnd)
  1144. Handle a push model event.
  1145. This function is called when the test app has been
  1146. a) registered as a push event handler
  1147. b) launched by a push event
  1148. Parameters:
  1149. Handle to the window to display image in.
  1150. Return:
  1151. HRESULT of last Sti call
  1152. *****************************************************************************/
  1153. HRESULT StiEvent(HWND hWnd)
  1154. {
  1155. HRESULT hres = STI_OK;
  1156. WCHAR szDeviceName[STI_MAX_INTERNAL_NAME_LENGTH + 1],
  1157. szEventName[LONGSTRING];
  1158. DWORD cch,
  1159. dwEventCode = 0,
  1160. cbData = LONGSTRING;
  1161. int nCounter;
  1162. BOOL bBadFlag = FALSE;
  1163. //
  1164. // check that Sti subsystem is loaded
  1165. //
  1166. if ( ! pSti ) {
  1167. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  1168. return (STIERR_GENERIC);
  1169. }
  1170. ZeroMemory(szDeviceName,STI_MAX_INTERNAL_NAME_LENGTH + 1);
  1171. ZeroMemory(szEventName,LONGSTRING);
  1172. //
  1173. // For an application started through push model launch,
  1174. // GetSTILaunchInformation returns the associated information. This
  1175. // information is used to determine which device to use and what
  1176. // event caused the application to be launched.
  1177. //
  1178. hres = pSti->GetSTILaunchInformation(
  1179. szDeviceName, // pointer to where device name will be stored
  1180. &dwEventCode, // reserved
  1181. szEventName // pointer to where GUID will be stored
  1182. );
  1183. if ( !SUCCEEDED(hres) ) {
  1184. StiDisplayError(hres,"GetSTILaunchInformation",TRUE);
  1185. return (STIERR_GENERIC);
  1186. }
  1187. ZeroMemory(pszStr2,LONGSTRING);
  1188. ZeroMemory(pszStr4,LONGSTRING);
  1189. cch = WideCharToMultiByte(CP_ACP,0,
  1190. szDeviceName,-1,
  1191. pszStr1,STI_MAX_INTERNAL_NAME_LENGTH + 1,
  1192. pszStr2,&bBadFlag);
  1193. if ( ! cch )
  1194. LastError(TRUE);
  1195. if ( bBadFlag ) {
  1196. DisplayOutput("* UNICODE translation error");
  1197. bBadFlag = FALSE;
  1198. }
  1199. DisplayOutput(" %s launched via Sti push",pszStr1);
  1200. DisplayOutput(" Event code %d (%xh)",dwEventCode,dwEventCode);
  1201. cch = WideCharToMultiByte(CP_ACP,0,
  1202. szEventName,-1,
  1203. pszStr1,STI_MAX_INTERNAL_NAME_LENGTH + 1,
  1204. pszStr2,&bBadFlag);
  1205. if ( ! cch )
  1206. LastError(TRUE);
  1207. if ( bBadFlag ) {
  1208. DisplayOutput("* UNICODE translation error");
  1209. bBadFlag = FALSE;
  1210. }
  1211. DisplayOutput(" Event name %s",pszStr1);
  1212. //
  1213. // find the Sti device that sent the event
  1214. // set nStiNumber to -1 (no device), then set to event device when found
  1215. //
  1216. for ( nStiNumber = -1,nCounter = 0,
  1217. pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo;
  1218. nCounter < (int) dwStiTotal;pStiInfoPtr++,nCounter++ ) {
  1219. if ( ! wcscmp(szDeviceName,pStiInfoPtr->szDeviceInternalName) )
  1220. nStiNumber = nCounter;
  1221. }
  1222. DisplayOutput("");
  1223. return (hres);
  1224. }
  1225. /*****************************************************************************
  1226. HRESULT StiGetDeviceInfo(LPWSTR szDevName,BOOL *pPass)
  1227. Display information about the selected device
  1228. Parameters:
  1229. WCHAR string of the selected device
  1230. pointer to receive Pass/Fail result
  1231. Return:
  1232. HRESULT of last Sti call
  1233. *****************************************************************************/
  1234. HRESULT StiGetDeviceInfo(LPWSTR szDevname,BOOL *bPass)
  1235. {
  1236. HRESULT hres = STI_OK;
  1237. PVOID pInfo = NULL;
  1238. PSTI_DEVICE_INFORMATION pInfoPtr = NULL;
  1239. //
  1240. // check that Sti subsystem is loaded
  1241. //
  1242. if ( ! pSti ) {
  1243. *bPass = FALSE;
  1244. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  1245. return (STIERR_GENERIC);
  1246. }
  1247. *bPass = TRUE;
  1248. //
  1249. // Given a device name, the GetDeviceInfo interface makes available a
  1250. // structure that describes the various attributes of the device.
  1251. // * NOTE: the STI subsystem allocates memory for the Sti device information
  1252. // buffer, but the caller needs to free this memory with LocalFree().
  1253. //
  1254. hres = pSti->GetDeviceInfo(
  1255. szDevname, // pointer to the internal device name
  1256. &pInfo); // Sti device info buffer
  1257. if ( ! SUCCEEDED(hres) ) {
  1258. StiDisplayError(hres,"GetDeviceInfo",TRUE);
  1259. *bPass = FALSE;
  1260. }
  1261. pInfoPtr = (PSTI_DEVICE_INFORMATION) pInfo;
  1262. DisplayOutput(" GetDeviceInfo for \"%S\"",szDevname);
  1263. //pszStr1 = StrFromTable(GET_STIDEVICE_TYPE(pInfoPtr->DeviceType),StStiDeviceType);
  1264. DisplayOutput(" Device type %xh %s",
  1265. GET_STIDEVICE_TYPE(pInfoPtr->DeviceType),
  1266. StrFromTable(GET_STIDEVICE_TYPE(pInfoPtr->DeviceType),StStiDeviceType));
  1267. DisplayOutput(" Device subtype %xh",
  1268. GET_STIDEVICE_SUBTYPE(pInfoPtr->DeviceType));
  1269. DisplayOutput(" Internal name \"%S\"",
  1270. pInfoPtr->szDeviceInternalName);
  1271. DisplayOutput(" Device capabilities %xh",
  1272. pInfoPtr->DeviceCapabilities);
  1273. DisplayOutput(" Hardware configuration %xh",
  1274. pInfoPtr->dwHardwareConfiguration);
  1275. DisplayOutput(" Vendor description \"%S\"",
  1276. pInfoPtr->pszVendorDescription);
  1277. DisplayOutput(" Device description \"%S\"",
  1278. pInfoPtr->pszDeviceDescription);
  1279. DisplayOutput(" Port Name \"%S\"",
  1280. pInfoPtr->pszPortName);
  1281. DisplayOutput(" Prop provider \"%S\"",
  1282. pInfoPtr->pszPropProvider);
  1283. DisplayOutput(" Local name \"%S\"",
  1284. pInfoPtr->pszLocalName);
  1285. DisplayOutput("");
  1286. // free the STI_DEVICE_INFORMATION buffer
  1287. if ( pInfo )
  1288. LocalFree(pInfo);
  1289. return (hres);
  1290. }
  1291. /*****************************************************************************
  1292. HRESULT StiEnableHwNotification(LPWSTR,int *,BOOL *)
  1293. Determine the current notification handling state and if requested,
  1294. change it.
  1295. Parameters:
  1296. internal device name
  1297. pointer to state request (current state returned in pointer)
  1298. ON = turn on polling
  1299. OFF = turn off polling
  1300. PEEK = return current polling state
  1301. pointer to receive Pass/Fail result
  1302. Return:
  1303. HRESULT of last failed Sti call
  1304. *****************************************************************************/
  1305. HRESULT StiEnableHwNotification(LPWSTR szDevnameW,int *nState,BOOL *bPass)
  1306. {
  1307. HRESULT hres = STI_OK,
  1308. hError = STI_OK;
  1309. BOOL bState = OFF;
  1310. //
  1311. // check that Sti subsystem is loaded
  1312. //
  1313. if ( ! pSti ) {
  1314. *bPass = FALSE;
  1315. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  1316. return (STIERR_GENERIC);
  1317. }
  1318. *bPass = TRUE;
  1319. //
  1320. // GetHwNotificationState gets the current state of notification handling.
  1321. // The state parameter returns TRUE if the notification is enabled.
  1322. //
  1323. hres = pSti->GetHwNotificationState(
  1324. szDevnameW, // internal device name
  1325. &bState // pointer where state will be stored
  1326. );
  1327. if ( ! SUCCEEDED(hres) ) {
  1328. StiDisplayError(hres,"GetHwNotificationState",TRUE);
  1329. *bPass = FALSE;
  1330. hError = hres;
  1331. } else {
  1332. DisplayOutput(" Hardware Notification state is %s",
  1333. bState ? "TRUE (ON)" : "FALSE (OFF)");
  1334. }
  1335. if ( *nState != PEEK ) {
  1336. //
  1337. // EnableHwNotifications is used to turn event notification on and off.
  1338. // For polled devices, this function will turn polling on and off.
  1339. //
  1340. hres = pSti->EnableHwNotifications(
  1341. szDevnameW, // internal device name
  1342. *nState // new state to be set
  1343. );
  1344. if ( ! SUCCEEDED(hres) ) {
  1345. StiDisplayError(hres,"GetHwNotificationState",TRUE);
  1346. *bPass = FALSE;
  1347. return (hres);
  1348. }
  1349. //
  1350. // Ensure the state was changed
  1351. //
  1352. hres = pSti->GetHwNotificationState(
  1353. szDevnameW, // internal device name
  1354. &bState // pointer where state will be stored
  1355. );
  1356. if ( ! SUCCEEDED(hres) ) {
  1357. StiDisplayError(hres,"GetHwNotificationState",TRUE);
  1358. *bPass = FALSE;
  1359. hError = hres;
  1360. } else {
  1361. DisplayOutput(" Hw state has been set to %s",
  1362. bState ? "TRUE (ON)" : "FALSE (OFF)");
  1363. }
  1364. if ( bState ) {
  1365. if ( GetMenuState(hMenu, IDM_ENABLE_HWNOTIF, NULL) == MF_UNCHECKED )
  1366. CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_CHECKED);
  1367. } else {
  1368. if ( GetMenuState(hMenu, IDM_ENABLE_HWNOTIF, NULL) == MF_CHECKED )
  1369. CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_UNCHECKED);
  1370. }
  1371. }
  1372. DisplayOutput("");
  1373. return (hError);
  1374. }
  1375. /*****************************************************************************
  1376. HRESULT StiRefresh(LPWSTR,BOOL *)
  1377. Refresh the bus for non-PNP devices
  1378. Parameters:
  1379. internal device name
  1380. pointer to receive Pass/Fail result
  1381. Return:
  1382. HRESULT of last failed Sti call
  1383. *****************************************************************************/
  1384. HRESULT StiRefresh(LPWSTR szDevnameW,BOOL *bPass)
  1385. {
  1386. HRESULT hres = STI_OK,
  1387. hError = STI_OK;
  1388. BOOL bState = OFF;
  1389. /**/
  1390. //
  1391. // check that Sti subsystem is loaded
  1392. //
  1393. if ( ! pSti ) {
  1394. *bPass = FALSE;
  1395. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  1396. return (STIERR_GENERIC);
  1397. }
  1398. *bPass = TRUE;
  1399. //
  1400. // GetHwNotificationState gets the current state of notification handling.
  1401. // The state parameter returns TRUE if the notification is enabled.
  1402. //
  1403. hres = pSti->RefreshDeviceBus(
  1404. szDevnameW // internal device name
  1405. );
  1406. if ( ! SUCCEEDED(hres) ) {
  1407. StiDisplayError(hres,"RefreshDeviceBus",TRUE);
  1408. *bPass = TRUE;
  1409. hError = hres;
  1410. } else
  1411. DisplayOutput(" RefreshDeviceBus called on \"%S\"",szDevnameW);
  1412. DisplayOutput("");
  1413. /**/
  1414. return (hError);
  1415. }
  1416. /*****************************************************************************
  1417. HRESULT StiWriteErrLog(DWORD,LPCWSTR,BOOL *)
  1418. Write a string to the error log
  1419. Parameters:
  1420. DWORD severity, which can be
  1421. STI_TRACE_INFORMATION
  1422. STI_TRACE_WARNING
  1423. STI_TRACE_ERROR
  1424. Wide character message to write to log.
  1425. pointer to receive Pass/Fail result
  1426. Return:
  1427. HRESULT of last Sti call
  1428. *****************************************************************************/
  1429. HRESULT StiWriteErrLog(DWORD dwSeverity,LPCWSTR pszMessage,BOOL *bPass)
  1430. {
  1431. HRESULT hres = STI_OK;
  1432. //
  1433. // check that Sti subsystem is loaded
  1434. //
  1435. if ( ! pSti ) {
  1436. *bPass = FALSE;
  1437. StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE);
  1438. return (STIERR_GENERIC);
  1439. }
  1440. *bPass = TRUE;
  1441. //
  1442. // WriteToErrorLog can be used to write debugging and diagnostic
  1443. // information into the Sti log file, located in the Windows directory
  1444. // STI_TRACE.LOG. The user can control whether informational, warning or
  1445. // error messages, or any combination of these three are put in the log
  1446. // file through the Scanners & Cameras control panel.
  1447. //
  1448. hres = pSti->WriteToErrorLog(
  1449. dwSeverity, // severity of error
  1450. pszMessage // string to write to log
  1451. );
  1452. if ( ! SUCCEEDED(hres) ) {
  1453. StiDisplayError(hres,"WriteToErrorLog",TRUE);
  1454. *bPass = FALSE;
  1455. } else
  1456. DisplayOutput(" WriteToErrorLog wrote \"%S\"",pszMessage);
  1457. DisplayOutput("");
  1458. return (hres);
  1459. }
  1460. /*****************************************************************************
  1461. HRESULT StiGetStatus(int,BOOL *)
  1462. Retrieve the user mode status of the driver.
  1463. Parameters:
  1464. StatusMask to retrieve status for. Can be a combination of:
  1465. STI_DEV_ONLINE_STATE
  1466. STI_DEV_EVENTS_STATE
  1467. pointer to receive Pass/Fail result
  1468. Return:
  1469. HRESULT of last failed Sti call
  1470. *****************************************************************************/
  1471. HRESULT StiGetStatus(int nMask,BOOL *bPass)
  1472. {
  1473. HRESULT hres = STI_OK,
  1474. hError = STI_OK;
  1475. DWORD dwTimeout = 2000;
  1476. STI_DEVICE_STATUS StiStatus;
  1477. //
  1478. // STI.H - STI_DEVICE_MJ_TYPE
  1479. //
  1480. STRINGTABLE StStiStatusMask[] =
  1481. {
  1482. STI_DEVSTATUS_ONLINE_STATE, "STI_DEVSTATUS_ONLINE_STATE",0,
  1483. STI_DEVSTATUS_EVENTS_STATE, "STI_DEVSTATUS_EVENTS_STATE",0,
  1484. STI_DEVSTATUS_ONLINE_STATE | STI_DEVSTATUS_EVENTS_STATE,
  1485. "STI_DEVSTATUS_ONLINE_STATE | STI_DEVSTATUS_EVENTS_STATE",0,
  1486. 0, "Unknown status mask",-1
  1487. };
  1488. //
  1489. // check that an Sti device is selected
  1490. //
  1491. if ( pStiDevice == NULL ) {
  1492. *bPass = FALSE;
  1493. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  1494. return (STIERR_GENERIC);
  1495. }
  1496. *bPass = TRUE;
  1497. //
  1498. // Must lock device before GetStatus
  1499. //
  1500. // The LockDevice locks the apparatus for a single application to access.
  1501. // Each LockDevice should be paired with a matching UnLockDevice call.
  1502. //
  1503. hres = pStiDevice->LockDevice(
  1504. dwTimeout // timeout in milliseconds
  1505. );
  1506. if ( ! SUCCEEDED(hres) ) {
  1507. StiDisplayError(hres,"LockDevice",TRUE);
  1508. hError = hres;
  1509. *bPass = FALSE;
  1510. } else {
  1511. DisplayOutput(" Device is locked for GetStatus");
  1512. //
  1513. // Get and display status
  1514. //
  1515. ZeroMemory(&StiStatus,sizeof(StiStatus));
  1516. //
  1517. // The STI_DEVICE_STATUS dwSize field MUST be set by the caller.
  1518. //
  1519. StiStatus.dwSize = sizeof(STI_DEVICE_STATUS);
  1520. //
  1521. // The STI_DEVICE_STATUS StatusMask field MUST be set to the desired
  1522. // status to retrieve.
  1523. //
  1524. StiStatus.StatusMask = nMask;
  1525. DisplayOutput(" %s mask",StrFromTable(nMask,StStiStatusMask));
  1526. //
  1527. // The GetStatus interface gets the status from the user-mode
  1528. // minidriver. Status returned can indicate online status and/or
  1529. // device event activity.
  1530. //
  1531. hres = pStiDevice->GetStatus(
  1532. &StiStatus // pointer to a STI_DEVICE_STATUS struct
  1533. );
  1534. if ( ! SUCCEEDED(hres) ) {
  1535. StiDisplayError(hres,"GetStatus",TRUE);
  1536. hError = hres;
  1537. *bPass = FALSE;
  1538. } else {
  1539. DisplayOutput(" GetStatus on %S",szFriendlyName);
  1540. }
  1541. //
  1542. // Is the device on?
  1543. //
  1544. if ( (StiStatus.dwOnlineState == 0) &&
  1545. (nMask & STI_DEVSTATUS_ONLINE_STATE) ) {
  1546. DisplayOutput("* Device is TURNED OFF OR OFFLINE!!");
  1547. }
  1548. DisplayOutput(" %xh (%d) StatusMask",
  1549. StiStatus.StatusMask,StiStatus.StatusMask);
  1550. DisplayOutput(" %xh (%d) dwOnlineState",
  1551. StiStatus.dwOnlineState,StiStatus.dwOnlineState);
  1552. DisplayOutput(" %xh (%d) dwHardwareStatusCode",
  1553. StiStatus.dwHardwareStatusCode,StiStatus.dwHardwareStatusCode);
  1554. DisplayOutput(" %xh (%d) dwEventHandlingState",
  1555. StiStatus.dwEventHandlingState,StiStatus.dwEventHandlingState);
  1556. DisplayOutput(" %xh (%d) dwPollingInterval",
  1557. StiStatus.dwPollingInterval,StiStatus.dwPollingInterval);
  1558. if ( StiStatus.dwSize != sizeof(STI_DEVICE_STATUS) ) {
  1559. DisplayOutput("* Expected STI_DEVICE_STATUS dwSize %d, got %d",
  1560. sizeof(STI_DEVICE_STATUS),StiStatus.dwSize);
  1561. }
  1562. }
  1563. //
  1564. // The UnLockDevice interface unlocks a device that was previously locked.
  1565. //
  1566. hres = pStiDevice->UnLockDevice();
  1567. if ( ! SUCCEEDED(hres) ) {
  1568. StiDisplayError(hres,"UnLockDevice",TRUE);
  1569. hError = hres;
  1570. *bPass = FALSE;
  1571. } else
  1572. DisplayOutput(" Device is unlocked");
  1573. DisplayOutput("");
  1574. return (hError);
  1575. }
  1576. /*****************************************************************************
  1577. HRESULT StiGetCaps(BOOL *)
  1578. Return the device capabilities
  1579. Parameters:
  1580. pointer to receive Pass/Fail result
  1581. Return:
  1582. HRESULT of last Sti call
  1583. *****************************************************************************/
  1584. HRESULT StiGetCaps(BOOL *bPass)
  1585. {
  1586. HRESULT hres = STI_OK;
  1587. STI_DEV_CAPS StiDevCaps = { 0};
  1588. //
  1589. // check that an Sti device is selected
  1590. //
  1591. if ( ! pStiDevice ) {
  1592. *bPass = FALSE;
  1593. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  1594. return (STIERR_GENERIC);
  1595. }
  1596. *bPass = TRUE;
  1597. //
  1598. // The GetCapabilities function returns the capabilities of the device.
  1599. //
  1600. hres = pStiDevice->GetCapabilities(
  1601. &StiDevCaps // pointer to a STI_DEV_CAPS struct
  1602. );
  1603. if ( ! SUCCEEDED(hres) ) {
  1604. StiDisplayError(hres,"GetCapabilities",TRUE);
  1605. *bPass = FALSE;
  1606. } else {
  1607. DisplayOutput(" GetCapabilities on \"%S\'",szFriendlyName);
  1608. DisplayOutput(" %xh (%d) dwGeneric",
  1609. StiDevCaps.dwGeneric,StiDevCaps.dwGeneric);
  1610. }
  1611. DisplayOutput("");
  1612. return (hres);
  1613. }
  1614. /*****************************************************************************
  1615. HRESULT StiReset(BOOL *)
  1616. Puts the device into a known state.
  1617. Parameters:
  1618. pointer to receive Pass/Fail result
  1619. Return:
  1620. HRESULT of last failed Sti call
  1621. *****************************************************************************/
  1622. HRESULT StiReset(BOOL *bPass)
  1623. {
  1624. HRESULT hres = STI_OK,
  1625. hError = STI_OK;
  1626. DWORD dwTimeout = 2000;
  1627. //
  1628. // check that an Sti device is selected
  1629. //
  1630. if ( ! pStiDevice ) {
  1631. *bPass = FALSE;
  1632. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  1633. return (STIERR_GENERIC);
  1634. }
  1635. *bPass = TRUE;
  1636. //
  1637. // Must lock device before DeviceReset
  1638. //
  1639. // The LockDevice locks the apparatus for a single application to access.
  1640. // Each LockDevice should be paired with a matching UnLockDevice call.
  1641. //
  1642. hres = pStiDevice->LockDevice(
  1643. dwTimeout // timeout in milliseconds
  1644. );
  1645. if ( ! SUCCEEDED(hres) ) {
  1646. StiDisplayError(hres,"LockDevice",TRUE);
  1647. hError = hres;
  1648. *bPass = FALSE;
  1649. } else {
  1650. DisplayOutput(" Device is locked for DeviceReset");
  1651. //
  1652. // The DeviceReset interface requests that a device be returned to a
  1653. // known state.
  1654. //
  1655. hres = pStiDevice->DeviceReset();
  1656. if ( ! SUCCEEDED(hres) ) {
  1657. StiDisplayError(hres,"DeviceReset",TRUE);
  1658. hError = hres;
  1659. *bPass = FALSE;
  1660. } else
  1661. DisplayOutput(" DeviceReset on \"%S\"",szFriendlyName);
  1662. }
  1663. //
  1664. // The UnLockDevice interface unlocks a device that was previously locked.
  1665. //
  1666. hres = pStiDevice->UnLockDevice();
  1667. if ( ! SUCCEEDED(hres) ) {
  1668. StiDisplayError(hres,"UnLockDevice",TRUE);
  1669. hError = hres;
  1670. *bPass = FALSE;
  1671. } else
  1672. DisplayOutput(" Device is unlocked");
  1673. DisplayOutput("");
  1674. return (hError);
  1675. }
  1676. /*****************************************************************************
  1677. HRESULT StiDiagnostic(BOOL *)
  1678. Return user mode driver diagnostic info
  1679. Parameters:
  1680. pointer to receive Pass/Fail result
  1681. Return:
  1682. HRESULT of last failed Sti call
  1683. *****************************************************************************/
  1684. HRESULT StiDiagnostic(BOOL *bPass)
  1685. {
  1686. HRESULT hres = STI_OK,
  1687. hError = STI_OK;
  1688. DIAG diag;
  1689. DWORD dwTimeout = 2000;
  1690. //
  1691. // check that an Sti device is selected
  1692. //
  1693. if ( ! pStiDevice ) {
  1694. *bPass = FALSE;
  1695. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  1696. return (STIERR_GENERIC);
  1697. }
  1698. *bPass = TRUE;
  1699. //
  1700. // Must lock device before Diagnostic
  1701. //
  1702. // The LockDevice locks the apparatus for a single application to access.
  1703. // Each LockDevice should be paired with a matching UnLockDevice call.
  1704. //
  1705. hres = pStiDevice->LockDevice(
  1706. dwTimeout // timeout in milliseconds
  1707. );
  1708. if ( ! SUCCEEDED(hres) ) {
  1709. StiDisplayError(hres,"LockDevice",TRUE);
  1710. hError = hres;
  1711. *bPass = FALSE;
  1712. } else {
  1713. DisplayOutput(" Device is locked for Diagnostic");
  1714. //
  1715. // get diagnostic info
  1716. //
  1717. ZeroMemory(&diag,sizeof(diag));
  1718. //
  1719. // The DIAG dwSize field MUST be set by the caller.
  1720. //
  1721. diag.dwSize = sizeof(DIAG);
  1722. //
  1723. // The dwBasicDiagCode of this structure should be initialized with
  1724. // the desired request code. Currently, only one request code is
  1725. // defined, STI_DIAGCODE_HWPRESENCE.
  1726. diag.dwBasicDiagCode = STI_DIAGCODE_HWPRESENCE;
  1727. //
  1728. // There is also a vendor defined field called dwVendorDiagCode that
  1729. // can optionally be filled in.
  1730. //
  1731. diag.dwVendorDiagCode = 0;
  1732. //
  1733. // The Diagnostic interface executes the diagnostic method of the user
  1734. // mode minidriver.
  1735. //
  1736. hres = pStiDevice->Diagnostic(
  1737. &diag // pointer to STI_DIAG structure
  1738. );
  1739. if ( ! SUCCEEDED(hres) ) {
  1740. StiDisplayError(hres,"Diagnostic",TRUE);
  1741. hError = hres;
  1742. *bPass = FALSE;
  1743. } else {
  1744. DisplayOutput(" Diagnostic on \"%S\"",szFriendlyName);
  1745. }
  1746. DisplayOutput(" %xh (%d) dwBasicDiagCode",
  1747. diag.dwBasicDiagCode,diag.dwBasicDiagCode);
  1748. DisplayOutput(" %xh (%d) dwVendorDiagCode",
  1749. diag.dwVendorDiagCode,diag.dwVendorDiagCode);
  1750. DisplayOutput(" %xh (%d) dwStatusMask",
  1751. diag.dwStatusMask,diag.dwStatusMask);
  1752. if ( diag.dwSize != sizeof(DIAG) )
  1753. DisplayOutput("* Expected DIAG dwSize %d, got %d",
  1754. sizeof(DIAG),diag.dwSize);
  1755. //
  1756. // any extended error info?
  1757. //
  1758. if ( diag.sErrorInfo.dwSize == 0 ) {
  1759. DisplayOutput(" No Extended Errors");
  1760. } else {
  1761. if ( diag.sErrorInfo.dwSize != sizeof(STI_ERROR_INFO) )
  1762. DisplayOutput("* Expected STI_ERROR_INFO dwSize %d, got %d",
  1763. sizeof(STI_ERROR_INFO),diag.sErrorInfo.dwSize);
  1764. DisplayOutput(" %xh (%d) sErrorInfo.dwGenericError",
  1765. diag.sErrorInfo.dwGenericError,diag.sErrorInfo.dwGenericError);
  1766. DisplayOutput(" %xh (%d) sErrorInfo.dwVendorError",
  1767. diag.sErrorInfo.dwVendorError,diag.sErrorInfo.dwVendorError);
  1768. if ( * diag.sErrorInfo.szExtendedErrorText )
  1769. DisplayOutput(" sErrorInfo.szExtendedErrorText %s",
  1770. diag.sErrorInfo.szExtendedErrorText);
  1771. }
  1772. }
  1773. //
  1774. // The UnLockDevice interface unlocks a device that was previously locked.
  1775. //
  1776. hres = pStiDevice->UnLockDevice();
  1777. if ( ! SUCCEEDED(hres) ) {
  1778. StiDisplayError(hres,"UnLockDevice",TRUE);
  1779. hError = hres;
  1780. *bPass = FALSE;
  1781. } else
  1782. DisplayOutput(" Device is unlocked");
  1783. DisplayOutput("");
  1784. return (hError);
  1785. }
  1786. /*****************************************************************************
  1787. HRESULT StiGetLastErrorInfo(BOOL *)
  1788. Get and display last error from Sti device.
  1789. Parameters:
  1790. pointer to receive Pass/Fail result
  1791. Return:
  1792. HRESULT of last Sti call
  1793. *****************************************************************************/
  1794. HRESULT StiGetLastErrorInfo(BOOL *bPass)
  1795. {
  1796. HRESULT hres = STI_OK;
  1797. STI_ERROR_INFO StiError;
  1798. //
  1799. // check that an Sti device is selected
  1800. //
  1801. if ( ! pStiDevice ) {
  1802. *bPass = FALSE;
  1803. DisplayOutput("* NoStiDevice !");
  1804. return (STIERR_GENERIC);
  1805. }
  1806. *bPass = TRUE;
  1807. //
  1808. // get last error info
  1809. //
  1810. ZeroMemory(&StiError,sizeof(StiError));
  1811. //
  1812. // The STI_ERROR_INFO dwSize field MUST be set by the caller.
  1813. //
  1814. StiError.dwSize = sizeof(STI_ERROR_INFO);
  1815. //
  1816. // The GetLastErrorInfo interface returns the last known error from
  1817. // the user-mode minidriver.
  1818. //
  1819. hres = pStiDevice->GetLastErrorInfo(
  1820. &StiError // pointer to STI_ERROR_INFO structure
  1821. );
  1822. if ( ! SUCCEEDED(hres) ) {
  1823. DisplayOutput("* NoStiDevice !");
  1824. *bPass = FALSE;
  1825. } else
  1826. DisplayOutput(" GetLastErrorInfo on %S",szFriendlyName);
  1827. //
  1828. // any extended error info?
  1829. //
  1830. if ( StiError.dwSize == 0 ) {
  1831. DisplayOutput("No Extended Errors");
  1832. } else {
  1833. if ( StiError.dwSize != sizeof(STI_ERROR_INFO) )
  1834. DisplayOutput("* Expected STI_ERROR_INFO dwSize %d, got %d",
  1835. sizeof(STI_ERROR_INFO),StiError.dwSize);
  1836. DisplayOutput(" %xh (%d) sErrorInfo.dwGenericError",
  1837. StiError.dwGenericError,StiError.dwGenericError);
  1838. DisplayOutput(" %xh (%d) sErrorInfo.dwVendorError",
  1839. StiError.dwVendorError,StiError.dwVendorError);
  1840. if ( * StiError.szExtendedErrorText )
  1841. DisplayOutput(" sErrorInfo.szExtendedErrorText %s",
  1842. StiError.szExtendedErrorText);
  1843. }
  1844. return (hres);
  1845. }
  1846. /*****************************************************************************
  1847. HRESULT StiSubscribe(BOOL *)
  1848. Demonstrate Subscribe, UnSubscribe and GetLastNotificationData
  1849. Parameters:
  1850. pointer to receive Pass/Fail result
  1851. Return:
  1852. HRESULT of last failed Sti call
  1853. *****************************************************************************/
  1854. HRESULT StiSubscribe(BOOL *bPass)
  1855. {
  1856. HRESULT hres = STI_OK,
  1857. hError = STI_OK;
  1858. STISUBSCRIBE sSubscribe;
  1859. DWORD dwErr = 0x56565656;
  1860. int nWait = TRUE;
  1861. BOOL fWaiting = TRUE;
  1862. //
  1863. // check that an Sti device is selected
  1864. //
  1865. if ( ! pStiDevice ) {
  1866. *bPass = FALSE;
  1867. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  1868. return (STIERR_GENERIC);
  1869. }
  1870. *bPass = TRUE;
  1871. //
  1872. // create an unnamed event object for notification structure
  1873. //
  1874. hWaitEvent = CreateEvent(NULL, // security attributes
  1875. FALSE, // manual reset event flag
  1876. FALSE, // initial state flag
  1877. NULL ); // event-object name pointer
  1878. if ( ! hWaitEvent ) {
  1879. *bPass = FALSE;
  1880. return STIERR_GENERIC;
  1881. }
  1882. //
  1883. // prepare the event notification structure
  1884. //
  1885. ZeroMemory(&sSubscribe,sizeof(sSubscribe));
  1886. //
  1887. // The STISUBSCRIBE dwSize field MUST be set by the caller.
  1888. //
  1889. sSubscribe.dwSize = sizeof(STISUBSCRIBE);
  1890. //
  1891. // When flag is STI_SUBSCRIBE_FLAG_WINDOW, window handle is passed in as
  1892. // parameter. When flag is STI_SUBSCRIBE_FLAG_EVENT, event handle is
  1893. // passed in as a parameter.
  1894. //
  1895. sSubscribe.dwFlags = STI_SUBSCRIBE_FLAG_EVENT;
  1896. //
  1897. // not used
  1898. //
  1899. sSubscribe.dwFilter = 0;
  1900. //
  1901. // When STI_SUBSCRIBE_FLAG_WINDOW bit is set, following field should
  1902. // be set to handle of window which will receive notification message.
  1903. //
  1904. sSubscribe.hWndNotify = NULL;
  1905. //
  1906. // Handle of WIN32 auto-reset event, which will be signalled whenever
  1907. // device has notification pending.
  1908. //
  1909. sSubscribe.hEvent = hWaitEvent;
  1910. //
  1911. // Code of notification message, sent to window
  1912. //
  1913. sSubscribe.uiNotificationMessage = 0;
  1914. //
  1915. // Subscribe is called by an application that wants to start receiving event
  1916. // notifications from a device. This is useful for control center-style
  1917. // applications. Each call to Subscribe should be paired with a call to
  1918. // UnSubscribe.
  1919. //
  1920. hres = pStiDevice->Subscribe(
  1921. &sSubscribe // pointer to STISUBSCRIBE structure
  1922. );
  1923. if ( ! SUCCEEDED(hres) ) {
  1924. StiDisplayError(hres,"Subscribe",TRUE);
  1925. CloseHandle(hWaitEvent);
  1926. *bPass = FALSE;
  1927. return (hres);
  1928. }
  1929. //
  1930. // set the flag and semaphore for Subscribe mode
  1931. //
  1932. nUnSubscribe = nUnSubscribeSemaphore = 1;
  1933. //
  1934. // Now we wait for an event
  1935. //
  1936. DisplayOutput(" Subscribe on %S",szFriendlyName);
  1937. while ( nUnSubscribe ) {
  1938. dwErr = WaitForSingleObject(hWaitEvent,1000);
  1939. switch ( dwErr ) {
  1940. case WAIT_OBJECT_0:
  1941. {
  1942. STINOTIFY sNotify;
  1943. //
  1944. // received a notification
  1945. //
  1946. DisplayOutput(" WAIT_OBJECT_0 %xh (%d)",dwErr,dwErr);
  1947. DisplayOutput(" Received notification");
  1948. //
  1949. // prepare the notification description structure
  1950. //
  1951. ZeroMemory(&sNotify,sizeof(sNotify));
  1952. //
  1953. // The STINOTIFY dwSize field MUST be set by the caller.
  1954. //
  1955. sNotify.dwSize = sizeof(STINOTIFY);
  1956. //
  1957. // GetLastNotifyData returns information about the last
  1958. // event on the device.
  1959. //
  1960. hres = pStiDevice->GetLastNotificationData(
  1961. &sNotify // pointer to STINOTIFY structure
  1962. );
  1963. if ( ! SUCCEEDED(hres) ) {
  1964. StiDisplayError(hres,"GetLastNotificationData",TRUE);
  1965. hError = hres;
  1966. *bPass = FALSE;
  1967. } else {
  1968. DisplayOutput(" GetLastNotificationData");
  1969. DisplayOutput(" GUID {%8x-%4x-%4x-%x}",
  1970. sNotify.guidNotificationCode.Data1,
  1971. sNotify.guidNotificationCode.Data2,
  1972. sNotify.guidNotificationCode.Data3,
  1973. sNotify.guidNotificationCode.Data4
  1974. );
  1975. }
  1976. }
  1977. break;
  1978. case WAIT_TIMEOUT:
  1979. //
  1980. // no notification
  1981. //
  1982. DisplayOutput(" WAIT_TIMEOUT %xh (%d)",dwErr,dwErr);
  1983. DisplayOutput(" (select UnSubscribe from the IStillDevice "\
  1984. "menu to quit)");
  1985. break;
  1986. case WAIT_ABANDONED:
  1987. DisplayOutput(" WAIT_ABANDONED %xh (%d)",dwErr,dwErr);
  1988. break;
  1989. default:
  1990. DisplayOutput(" default %xh (%d)",dwErr,dwErr);
  1991. break;
  1992. }
  1993. }
  1994. //
  1995. // if the device is gone, StiDeviceRelease has already been
  1996. // unsubscribed elsewhere in this app
  1997. //
  1998. if ( ! pStiDevice )
  1999. return (STIERR_GENERIC);
  2000. //
  2001. // UnSubscribe is called when an application no longer wants to receive
  2002. // events from a device.
  2003. //
  2004. hres = pStiDevice->UnSubscribe();
  2005. if ( ! SUCCEEDED(hres) ) {
  2006. StiDisplayError(hres,"UnSubscribe",TRUE);
  2007. hError = hres;
  2008. *bPass = FALSE;
  2009. }
  2010. //
  2011. // we're done with the event
  2012. //
  2013. CloseHandle(hWaitEvent);
  2014. //
  2015. // clear the semaphore
  2016. //
  2017. nUnSubscribeSemaphore = 0;
  2018. DisplayOutput("");
  2019. return (hError);
  2020. }
  2021. /*****************************************************************************
  2022. HRESULT StiEscape(DWORD,char *,BOOL *)
  2023. The Escape function is dependent on the vendor's implementation.
  2024. Even if a device does not require the Escape function, the driver
  2025. must provide it. A non-functional Escape must return an error.
  2026. Parameters:
  2027. DWORD EscapeFunction - driver defined code
  2028. char *lpInData - pointer to data to be sent to device
  2029. pointer to receive Pass/Fail result
  2030. Return:
  2031. HRESULT of last failed Sti call
  2032. *****************************************************************************/
  2033. HRESULT StiEscape(DWORD EscapeFunction,char *lpInData,BOOL *bPass)
  2034. {
  2035. HRESULT hres = STI_OK,
  2036. hError = STI_OK;
  2037. DWORD dwTimeout = 2000;
  2038. DWORD cbInDataSize,
  2039. dwOutDataSize,
  2040. pdwActualData;
  2041. char pOutData[LONGSTRING];
  2042. //
  2043. // check that an Sti device is selected
  2044. //
  2045. if ( ! pStiDevice ) {
  2046. *bPass = FALSE;
  2047. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  2048. return (STIERR_GENERIC);
  2049. }
  2050. *bPass = TRUE;
  2051. //
  2052. // Must lock device before Escape
  2053. //
  2054. // The LockDevice locks the apparatus for a single application to access.
  2055. // Each LockDevice should be paired with a matching UnLockDevice call.
  2056. //
  2057. hres = pStiDevice->LockDevice(
  2058. dwTimeout // timeout in milliseconds
  2059. );
  2060. if ( ! SUCCEEDED(hres) ) {
  2061. StiDisplayError(hres,"LockDevice",TRUE);
  2062. hError = hres;
  2063. *bPass = FALSE;
  2064. } else {
  2065. DisplayOutput(" Device is locked for Escape");
  2066. //
  2067. // Set up the command
  2068. //
  2069. cbInDataSize = strlen(lpInData + 1);
  2070. //
  2071. // zero out other parameters (for clarity's sake only)
  2072. //
  2073. ZeroMemory(pOutData,LONGSTRING);
  2074. dwOutDataSize = pdwActualData = 0;
  2075. //
  2076. // The Escape function executes a multiparameter I/O call. The semantics
  2077. // of this call is determined by the specific user-mode minidriver.
  2078. //
  2079. hres = pStiDevice->Escape(
  2080. EscapeFunction, // General operation code. The meaning of this code
  2081. // varies in each user mode minidriver. There is no
  2082. // utilization of this code by the still image
  2083. // minidriver.
  2084. lpInData, // Pointer to an input memory buffer. If there are
  2085. // multiple areas of memory to be read from, they
  2086. // must be packaged in some sort of structure
  2087. // before being passed to this API.
  2088. cbInDataSize, // The length in bytes of the memory pointed to by
  2089. // lpInData
  2090. pOutData, // Pointer to a memory buffer usable for writing.
  2091. // Access to this memory is checked to be sure it
  2092. // is available for writing.
  2093. dwOutDataSize, // The length in bytes of the memory pointed to by
  2094. // lpOutData.
  2095. &pdwActualData // Pointer to a DWORD that gets the number of bytes
  2096. // actually transferred to pOutData. If this value
  2097. // is less than dwOutDataSize, then an error
  2098. // situation could exist.
  2099. );
  2100. if ( ! SUCCEEDED(hres) ) {
  2101. hError = hres;
  2102. if ( hres == STIERR_UNSUPPORTED ) {
  2103. //
  2104. // COMPLIANCE test:
  2105. // if the escape IOCTL is NOT supported, the driver MUST
  2106. // return STIERR_UNSUPPORTED
  2107. //
  2108. StiDisplayError(hres,"Escape",FALSE);
  2109. DisplayOutput(" Escape IOCTL %d unsupported",EscapeFunction);
  2110. } else {
  2111. StiDisplayError(hres,"Escape",TRUE);
  2112. *bPass = FALSE;
  2113. }
  2114. } else {
  2115. DisplayOutput(" Escape on %S",szFriendlyName);
  2116. DisplayOutput(" %xh (%d) EscapeFunction",
  2117. EscapeFunction,EscapeFunction);
  2118. DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x lpInData",
  2119. lpInData[0],
  2120. lpInData[1],
  2121. lpInData[2],
  2122. lpInData[3],
  2123. lpInData[4],
  2124. lpInData[5],
  2125. lpInData[6],
  2126. lpInData[7],
  2127. lpInData[8],
  2128. lpInData[9],
  2129. lpInData[10],
  2130. lpInData[11],
  2131. lpInData[12],
  2132. lpInData[13],
  2133. lpInData[14],
  2134. lpInData[15]
  2135. );
  2136. DisplayOutput(" %xh (%d) cbInDataSize",
  2137. cbInDataSize,cbInDataSize);
  2138. DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x pOutData",
  2139. pOutData[0],
  2140. pOutData[1],
  2141. pOutData[2],
  2142. pOutData[3],
  2143. pOutData[4],
  2144. pOutData[5],
  2145. pOutData[6],
  2146. pOutData[7],
  2147. pOutData[8],
  2148. pOutData[9],
  2149. pOutData[10],
  2150. pOutData[11],
  2151. pOutData[12],
  2152. pOutData[13],
  2153. pOutData[14],
  2154. pOutData[15]
  2155. );
  2156. DisplayOutput(" %xh (%d) dwOutDataSize",
  2157. dwOutDataSize,dwOutDataSize);
  2158. DisplayOutput(" %xh (%d) pdwActualData",
  2159. pdwActualData,pdwActualData);
  2160. }
  2161. }
  2162. //
  2163. // The UnLockDevice interface unlocks a device that was previously locked.
  2164. //
  2165. hres = pStiDevice->UnLockDevice();
  2166. if ( ! SUCCEEDED(hres) ) {
  2167. StiDisplayError(hres,"UnLockDevice",TRUE);
  2168. hError = hres;
  2169. *bPass = FALSE;
  2170. } else
  2171. DisplayOutput(" Device is unlocked");
  2172. DisplayOutput("");
  2173. return (hError);
  2174. }
  2175. /*****************************************************************************
  2176. HRESULT StiRawReadData(char *,LPDWORD,BOOL *)
  2177. Obtains data from a device.
  2178. The RawReadData function is dependent on the vendor's implementation.
  2179. Even if a device does not require the RawReadData function, the driver
  2180. must provide it. A non-functional RawReadData must return an error.
  2181. Parameters:
  2182. char *lpBuffer - Location in memory to transfer the data coming in
  2183. from the device.
  2184. LPDWORD lpdwNumberOfBytes - number of bytes to be read
  2185. pointer to receive Pass/Fail result
  2186. Return:
  2187. HRESULT of last failed Sti call
  2188. *****************************************************************************/
  2189. HRESULT StiRawReadData(char *lpBuffer,LPDWORD lpdwNumberOfBytes,BOOL *bPass)
  2190. {
  2191. HRESULT hres = STI_OK,
  2192. hError = STI_OK;
  2193. LPOVERLAPPED lpOverlapped;
  2194. DWORD dwTimeout = 2000;
  2195. //
  2196. // check that an Sti device is selected
  2197. //
  2198. if ( ! pStiDevice ) {
  2199. *bPass = FALSE;
  2200. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  2201. return (STIERR_GENERIC);
  2202. }
  2203. *bPass = TRUE;
  2204. //
  2205. // Must lock device before RawReadData
  2206. //
  2207. // The LockDevice locks the apparatus for a single application to access.
  2208. // Each LockDevice should be paired with a matching UnLockDevice call.
  2209. //
  2210. hres = pStiDevice->LockDevice(
  2211. dwTimeout // timeout in milliseconds
  2212. );
  2213. if ( ! SUCCEEDED(hres) ) {
  2214. StiDisplayError(hres,"LockDevice",TRUE);
  2215. hError = hres;
  2216. *bPass = FALSE;
  2217. } else {
  2218. DisplayOutput(" Device is locked for RawReadData");
  2219. //
  2220. // Set up the command
  2221. //
  2222. lpOverlapped = NULL;
  2223. //
  2224. // The RawReadData interface reads data from a device. This is a
  2225. // general operation for obtaining data from a device. Depending on
  2226. // the user-mode minidriver for the device, command streams and data
  2227. // streams can be read with this call. Some devices may seperate
  2228. // commands from data by using RawReadCommand.
  2229. //
  2230. hres = pStiDevice->RawReadData(
  2231. lpBuffer, // Location in memory to transfer the data
  2232. // coming from the device
  2233. lpdwNumberOfBytes, // Number of bytes requested to be read
  2234. lpOverlapped // This is used to signal that the operation
  2235. // of this call should be asynchronous. The
  2236. // value here conforms to the Win32 APIs.
  2237. );
  2238. if ( ! SUCCEEDED(hres) ) {
  2239. if ( hres == STIERR_UNSUPPORTED ) {
  2240. //
  2241. // COMPLIANCE test:
  2242. // if RawReadData is NOT supported, the driver MUST
  2243. // return STIERR_UNSUPPORTED
  2244. //
  2245. StiDisplayError(hres,"RawReadData",FALSE);
  2246. DisplayOutput(" RawReadData unsupported");
  2247. } else {
  2248. StiDisplayError(hres,"RawReadData",TRUE);
  2249. *bPass = FALSE;
  2250. }
  2251. hError = hres;
  2252. } else {
  2253. DisplayOutput(" RawReadData on %S",szFriendlyName);
  2254. DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x lpBuffer",
  2255. lpBuffer[0],
  2256. lpBuffer[1],
  2257. lpBuffer[2],
  2258. lpBuffer[3],
  2259. lpBuffer[4],
  2260. lpBuffer[5],
  2261. lpBuffer[6],
  2262. lpBuffer[7],
  2263. lpBuffer[8],
  2264. lpBuffer[9],
  2265. lpBuffer[10],
  2266. lpBuffer[11],
  2267. lpBuffer[12],
  2268. lpBuffer[13],
  2269. lpBuffer[14],
  2270. lpBuffer[15]
  2271. );
  2272. DisplayOutput(" %xh (%d) lpdwNumberOfBytes read",
  2273. *lpdwNumberOfBytes,*lpdwNumberOfBytes);
  2274. }
  2275. }
  2276. //
  2277. // The UnLockDevice interface unlocks a device that was previously locked.
  2278. //
  2279. hres = pStiDevice->UnLockDevice();
  2280. if ( ! SUCCEEDED(hres) ) {
  2281. StiDisplayError(hres,"UnLockDevice",TRUE);
  2282. hError = hres;
  2283. *bPass = FALSE;
  2284. } else
  2285. DisplayOutput(" Device is unlocked");
  2286. DisplayOutput("");
  2287. return (hError);
  2288. }
  2289. /*****************************************************************************
  2290. HRESULT StiRawWriteData(char *,DWORD,BOOL *)
  2291. Sends data to the device.
  2292. The RawWriteData function is dependent on the vendor's
  2293. implementation. Even if a device does not require the RawWriteData
  2294. function, the driver must provide it. A non-functional RawWriteData
  2295. must return an error.
  2296. Parameters:
  2297. char *lpBuffer - Location in memory to read from when sending data to
  2298. a device.
  2299. LPDWORD lpdwNumberOfBytes - number of bytes of data to be sent
  2300. pointer to receive Pass/Fail result
  2301. Return:
  2302. HRESULT of last failed Sti call
  2303. *****************************************************************************/
  2304. HRESULT StiRawWriteData(char *lpBuffer,DWORD dwNumberOfBytes,BOOL *bPass)
  2305. {
  2306. HRESULT hres = STI_OK,
  2307. hError = STI_OK;
  2308. LPOVERLAPPED lpOverlapped;
  2309. DWORD dwTimeout = 2000;
  2310. //
  2311. // check that an Sti device is selected
  2312. //
  2313. if ( ! pStiDevice ) {
  2314. *bPass = FALSE;
  2315. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  2316. return (STIERR_GENERIC);
  2317. }
  2318. *bPass = TRUE;
  2319. //
  2320. // Must lock device before RawWriteData
  2321. //
  2322. // The LockDevice locks the apparatus for a single application to access.
  2323. // Each LockDevice should be paired with a matching UnLockDevice call.
  2324. //
  2325. hres = pStiDevice->LockDevice(
  2326. dwTimeout // timeout in milliseconds
  2327. );
  2328. if ( ! SUCCEEDED(hres) ) {
  2329. StiDisplayError(hres,"LockDevice",TRUE);
  2330. hError = hres;
  2331. *bPass = FALSE;
  2332. } else {
  2333. DisplayOutput(" Device is locked for RawWriteData");
  2334. //
  2335. // Set up the command
  2336. //
  2337. lpOverlapped = NULL;
  2338. //
  2339. // The RawWriteData interface writes data to a device. This is a
  2340. // general operation for sending data to a device. Depending on
  2341. // the user-mode minidriver for the device, command streams and data
  2342. // streams can be written with this call. Some devices may seperate
  2343. // commands from data by using RawWriteCommand.
  2344. //
  2345. hres = pStiDevice->RawWriteData(
  2346. lpBuffer, // Location in memory to read from when sending
  2347. // data to a device
  2348. dwNumberOfBytes, // Number of bytes of data to send
  2349. lpOverlapped // This is used to signal that the operation
  2350. // of this call should be asynchronous. The
  2351. // value here conforms to the Win32 APIs.
  2352. );
  2353. if ( ! SUCCEEDED(hres) ) {
  2354. if ( hres == STIERR_UNSUPPORTED ) {
  2355. //
  2356. // COMPLIANCE test:
  2357. // if RawWriteData is NOT supported, the driver MUST
  2358. // return STIERR_UNSUPPORTED
  2359. //
  2360. StiDisplayError(hres,"RawWriteData",FALSE);
  2361. DisplayOutput(" RawWriteData unsupported");
  2362. } else {
  2363. StiDisplayError(hres,"RawWriteData",TRUE);
  2364. *bPass = FALSE;
  2365. }
  2366. hError = hres;
  2367. } else {
  2368. DisplayOutput(" RawWriteData on %S",szFriendlyName);
  2369. DisplayOutput(" %xh (%d) dwNumberOfBytes sent",
  2370. dwNumberOfBytes,dwNumberOfBytes);
  2371. }
  2372. }
  2373. //
  2374. // The UnLockDevice interface unlocks a device that was previously locked.
  2375. //
  2376. hres = pStiDevice->UnLockDevice();
  2377. if ( ! SUCCEEDED(hres) ) {
  2378. StiDisplayError(hres,"UnLockDevice",TRUE);
  2379. hError = hres;
  2380. *bPass = FALSE;
  2381. } else
  2382. DisplayOutput(" Device is unlocked");
  2383. DisplayOutput("");
  2384. return (hError);
  2385. }
  2386. /*****************************************************************************
  2387. HRESULT StiRawReadCommand(char *,LPDWORD,BOOL *)
  2388. Obtains command information from the device. Unique to the IStiDevice
  2389. interface.
  2390. The RawReadCommand function is dependent on the vendor's implementation.
  2391. Even if a device does not require the RawReadCommand function, the
  2392. driver must provide it. A non-functional RawReadCommand must return an
  2393. error.
  2394. Parameters:
  2395. char *lpBuffer - Location in memory to transfer the data coming in
  2396. from the device.
  2397. LPDWORD lpdwNumberOfBytes - number of bytes to be read
  2398. pointer to receive Pass/Fail result
  2399. Return:
  2400. HRESULT of last failed Sti call
  2401. *****************************************************************************/
  2402. HRESULT StiRawReadCommand(char *lpBuffer,LPDWORD lpdwNumberOfBytes,BOOL *bPass)
  2403. {
  2404. HRESULT hres = STI_OK,
  2405. hError = STI_OK;
  2406. LPOVERLAPPED lpOverlapped;
  2407. DWORD dwTimeout = 2000;
  2408. //
  2409. // check that an Sti device is selected
  2410. //
  2411. if ( ! pStiDevice ) {
  2412. *bPass = FALSE;
  2413. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  2414. return (STIERR_GENERIC);
  2415. }
  2416. *bPass = TRUE;
  2417. //
  2418. // Must lock device before RawReadCommand
  2419. //
  2420. // The LockDevice locks the apparatus for a single application to access.
  2421. // Each LockDevice should be paired with a matching UnLockDevice call.
  2422. //
  2423. hres = pStiDevice->LockDevice(
  2424. dwTimeout // timeout in milliseconds
  2425. );
  2426. if ( ! SUCCEEDED(hres) ) {
  2427. StiDisplayError(hres,"LockDevice",TRUE);
  2428. hError = hres;
  2429. *bPass = FALSE;
  2430. } else {
  2431. DisplayOutput(" Device is locked for RawReadCommand");
  2432. //
  2433. // Set up the command
  2434. //
  2435. lpOverlapped = NULL;
  2436. //
  2437. // The RawReadCommand interface reads command information from a
  2438. // device. The implementation of this call depends on the user-mode
  2439. // minidriver for the device. Many devices will not require
  2440. // separating commands and data. If this call is not used, the
  2441. // user-mode minidriver should return STIERR_UNSUPPORTED.
  2442. //
  2443. hres = pStiDevice->RawReadCommand(
  2444. lpBuffer, // Location in memory to transfer the command
  2445. // information coming from the device
  2446. lpdwNumberOfBytes, // Number of command bytes requested to be read
  2447. lpOverlapped // This is used to signal that the operation
  2448. // of this call should be asynchronous. The
  2449. // value here conforms to the Win32 APIs.
  2450. );
  2451. if ( ! SUCCEEDED(hres) ) {
  2452. if ( hres == STIERR_UNSUPPORTED ) {
  2453. //
  2454. // COMPLIANCE test:
  2455. // if RawReadCommand is NOT supported, the driver MUST
  2456. // return STIERR_UNSUPPORTED
  2457. //
  2458. StiDisplayError(hres,"RawReadCommand",FALSE);
  2459. DisplayOutput(" RawReadCommand unsupported");
  2460. } else {
  2461. StiDisplayError(hres,"RawReadCommand",TRUE);
  2462. *bPass = FALSE;
  2463. }
  2464. hError = hres;
  2465. } else {
  2466. DisplayOutput(" RawReadCommand on %S",szFriendlyName);
  2467. DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x lpBuffer",
  2468. lpBuffer[0],
  2469. lpBuffer[1],
  2470. lpBuffer[2],
  2471. lpBuffer[3],
  2472. lpBuffer[4],
  2473. lpBuffer[5],
  2474. lpBuffer[6],
  2475. lpBuffer[7],
  2476. lpBuffer[8],
  2477. lpBuffer[9],
  2478. lpBuffer[10],
  2479. lpBuffer[11],
  2480. lpBuffer[12],
  2481. lpBuffer[13],
  2482. lpBuffer[14],
  2483. lpBuffer[15]
  2484. );
  2485. DisplayOutput(" %xh (%d) lpdwNumberOfBytes read",
  2486. *lpdwNumberOfBytes,*lpdwNumberOfBytes);
  2487. }
  2488. }
  2489. //
  2490. // The UnLockDevice interface unlocks a device that was previously locked.
  2491. //
  2492. hres = pStiDevice->UnLockDevice();
  2493. if ( ! SUCCEEDED(hres) ) {
  2494. StiDisplayError(hres,"UnLockDevice",TRUE);
  2495. hError = hres;
  2496. *bPass = FALSE;
  2497. } else
  2498. DisplayOutput(" Device is unlocked");
  2499. DisplayOutput("");
  2500. return (hError);
  2501. }
  2502. /*****************************************************************************
  2503. HRESULT StiRawWriteCommand(char *,DWORD,BOOL *)
  2504. Sends command information to the device. Unique to the IStiDevice
  2505. interface.
  2506. The RawWriteCommand function is dependent on the vendor's
  2507. implementation. Even if a device does not require the RawWriteCommand
  2508. function, the driver must provide it. A non-functional RawWriteCommand
  2509. must return an error.
  2510. Parameters:
  2511. char *lpBuffer - Location in memory to read from when sending data to
  2512. a device.
  2513. LPDWORD lpdwNumberOfBytes - number of bytes of data to be sent
  2514. pointer to receive Pass/Fail result
  2515. Return:
  2516. HRESULT of last failed Sti call
  2517. *****************************************************************************/
  2518. HRESULT StiRawWriteCommand(char *lpBuffer,DWORD dwNumberOfBytes,BOOL *bPass)
  2519. {
  2520. HRESULT hres = STI_OK,
  2521. hError = STI_OK;
  2522. LPOVERLAPPED lpOverlapped;
  2523. DWORD dwTimeout = 2000;
  2524. //
  2525. // check that an Sti device is selected
  2526. //
  2527. if ( ! pStiDevice ) {
  2528. *bPass = FALSE;
  2529. StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE);
  2530. return (STIERR_GENERIC);
  2531. }
  2532. *bPass = TRUE;
  2533. //
  2534. // Must lock device before RawWriteCommand
  2535. //
  2536. // The LockDevice locks the apparatus for a single application to access.
  2537. // Each LockDevice should be paired with a matching UnLockDevice call.
  2538. //
  2539. hres = pStiDevice->LockDevice(
  2540. dwTimeout // timeout in milliseconds
  2541. );
  2542. if ( ! SUCCEEDED(hres) ) {
  2543. StiDisplayError(hres,"LockDevice",TRUE);
  2544. hError = hres;
  2545. *bPass = FALSE;
  2546. } else {
  2547. DisplayOutput(" Device is locked for RawWriteCommand");
  2548. //
  2549. // Set up the command
  2550. //
  2551. lpOverlapped = NULL;
  2552. //
  2553. // The RawWriteCommand interface sends command information to the
  2554. // device. The implementation of this call depends on the user-mode
  2555. // minidriver for the device. Many devices will not require
  2556. // separating commands and data. If this call is not used, the
  2557. // user-mode minidriver should return STIERR_UNSUPPORTED.
  2558. //
  2559. hres = pStiDevice->RawWriteCommand(
  2560. lpBuffer, // Location in memory to read from when writing
  2561. // command information to the device
  2562. dwNumberOfBytes, // Number of bytes of data to send
  2563. lpOverlapped // This is used to signal that the operation
  2564. // of this call should be asynchronous. The
  2565. // value here conforms to the Win32 APIs.
  2566. );
  2567. if ( ! SUCCEEDED(hres) ) {
  2568. if ( hres == STIERR_UNSUPPORTED ) {
  2569. //
  2570. // COMPLIANCE test:
  2571. // if RawWriteData is NOT supported, the driver MUST
  2572. // return STIERR_UNSUPPORTED
  2573. //
  2574. StiDisplayError(hres,"RawWriteCommand",FALSE);
  2575. DisplayOutput(" RawWriteCommand unsupported");
  2576. } else {
  2577. StiDisplayError(hres,"RawWriteCommand",TRUE);
  2578. *bPass = FALSE;
  2579. }
  2580. hError = hres;
  2581. } else {
  2582. DisplayOutput(" RawWriteCommand on %S",szFriendlyName);
  2583. DisplayOutput(" %xh (%d) dwNumberOfBytes sent",
  2584. dwNumberOfBytes,dwNumberOfBytes);
  2585. }
  2586. }
  2587. //
  2588. // The UnLockDevice interface unlocks a device that was previously locked.
  2589. //
  2590. hres = pStiDevice->UnLockDevice();
  2591. if ( ! SUCCEEDED(hres) ) {
  2592. StiDisplayError(hres,"UnLockDevice",TRUE);
  2593. hError = hres;
  2594. *bPass = FALSE;
  2595. } else
  2596. DisplayOutput(" Device is unlocked");
  2597. DisplayOutput("");
  2598. return (hError);
  2599. }