|
|
/******************************************************************************
wsti.cpp WDM Still Imaging interface
Copyright (C) Microsoft Corporation, 1997 - 1998 All rights reserved
Notes: THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
******************************************************************************/
#include "stillvue.h"
//
// globals defined in Stivar.h
//
extern PDEVLOG pdevPtr, // pointer to current device log device
pdevRoot; // base of the device log table
extern PSTR pszStr1,pszStr2,pszStr3, // utility strings
pszStr4; extern HINSTANCE hThisInstance; // instance of this app
extern HANDLE hNTLog; // NT log handle
extern HMENU hMenu; // current menu
extern int *pSuite; // pointer to test Suite to run
extern int nError, nICanScan, // global flags
nNextTest, // index into pSuite
nNameOnly, nScanCount, nTestID, nUnSubscribeSemaphore, // semaphore for StiSubscribe
nUnSubscribe; // flag to request UnSubscribe
//
// STI.H - STI_DEVICE_MJ_TYPE
//
STRINGTABLE StStiDeviceType[] = { 0, "StiDeviceTypeDefault",0, 1, "StiDeviceTypeScanner",0, 2, "StiDeviceTypeDigitalCamera",0, 0, "Unknown device type",-1 };
//
// STIERR.H - errors
//
STRINGTABLE StStiError[] = { STI_OK, "STI_OK",0, STI_NOTCONNECTED, "STI_NOTCONNECTED",0, STI_CHANGENOEFFECT, "STI_CHANGENOEFFECT",0, STIERR_OLD_VERSION, "STIERR_OLD_VERSION",0, STIERR_BETA_VERSION, "STIERR_BETA_VERSION",0, STIERR_BADDRIVER, "STIERR_BADDRIVER",0, STIERR_DEVICENOTREG, "STIERR_DEVICENOTREG",0, STIERR_OBJECTNOTFOUND, "STIERR_OBJECTNOTFOUND",0, STIERR_INVALID_PARAM, "STIERR_INVALID_PARAM",0, STIERR_NOINTERFACE, "STIERR_NOINTERFACE",0, STIERR_GENERIC, "STIERR_GENERIC", 0, STIERR_OUTOFMEMORY, "STIERR_OUTOFMEMORY", 0, STIERR_UNSUPPORTED, "STIERR_UNSUPPORTED", 0, STIERR_NOT_INITIALIZED, "STIERR_NOT_INITIALIZED", 0, STIERR_ALREADY_INITIALIZED, "STIERR_ALREADY_INITIALIZED", 0, STIERR_DEVICE_LOCKED, "STIERR_DEVICE_LOCKED", 0, STIERR_READONLY, "STIERR_READONLY", 0, STIERR_NOTINITIALIZED, "STIERR_NOTINITIALIZED", 0, STIERR_NEEDS_LOCK, "STIERR_NEEDS_LOCK", 0, STIERR_SHARING_VIOLATION, "STIERR_SHARING_VIOLATION", 0, STIERR_HANDLEEXISTS, "STIERR_HANDLEEXISTS", 0, STIERR_INVALID_DEVICE_NAME, "STIERR_INVALID_DEVICE_NAME", 0, STIERR_INVALID_HW_TYPE, "STIERR_INVALID_HW_TYPE", 0, STIERR_INVALID_HW_TYPE, "STIERR_INVALID_HW_TYPE", 0, STIERR_NOEVENTS, "STIERR_NOEVENTS", 0, 0, "Unknown STI error",-1 };
//
// WINNT.H - Predefined Value Types.
//
STRINGTABLE StRegValType[] = { 0, "REG_NONE",0, 1, "REG_SZ",0, 3, "REG_BINARY",0, 4, "REG_DWORD",0, 0, "Unknown reg type",-1 };
//
// global still image
//
PSTI pSti = NULL; // handle to Sti subsystem
PVOID pStiInfo = NULL; // Sti device info buffer
PSTI_DEVICE_INFORMATION pStiInfoPtr = NULL; // pointer to device in pStiBuffer
PSTIDEVICE pStiDevice = NULL; // Sti device being used
HANDLE hWaitEvent; // Subscribe Event handle
int nStiNumber = 0; // 0 based index into pStiInfo
DWORD dwStiTotal = 0; // total number of Sti devices found
WCHAR szInternalName[STI_MAX_INTERNAL_NAME_LENGTH]; // user selected Sti device name
WCHAR szFriendlyName[STI_MAX_INTERNAL_NAME_LENGTH]; // user selected Sti friendly name
/*****************************************************************************
define ACQUIRE to load device specific command handler for stub functions defined in STIDDK.CPP
*****************************************************************************/ #ifdef ACQUIRE
//
// device specific image acquire code
//
#include "acquire.cpp"
#else
//
// only exercise Sti services
//
#include "stisvc.cpp"
#endif
/*****************************************************************************
void IStillImageMenu(DWORD dwState) Enable or Disable the menus for the IStillDevice interface.
Parameters: MF_ENABLED or MF_GRAYED
Return: none
*****************************************************************************/ void IStillImageMenu(DWORD dwState) { EnableMenuItem(hMenu, IDM_IMAGE_RELEASE, dwState); EnableMenuItem(hMenu, IDM_GET_DEVLIST, dwState); EnableMenuItem(hMenu, IDM_CREATE_DEV, dwState); EnableMenuItem(hMenu, IDM_REGISTER_LAUNCH, dwState); EnableMenuItem(hMenu, IDM_UNREGISTER_LAUNCH, dwState); EnableMenuItem(hMenu, IDM_WRITE_ERRORLOG, dwState); }
/*****************************************************************************
void IStillNameMenu(DWORD dwState) Enable or Disable the menus for the IStillImage interface that only require a device name.
Parameters: MF_ENABLED or MF_GRAYED
Return: none
*****************************************************************************/ void IStillNameMenu(DWORD dwState) { EnableMenuItem(hMenu, IDM_GET_DEVINFO, dwState); EnableMenuItem(hMenu, IDM_GET_DEVVAL, dwState); EnableMenuItem(hMenu, IDM_SET_DEVVAL, dwState); EnableMenuItem(hMenu, IDM_GET_LAUNCHINFO, dwState); EnableMenuItem(hMenu, IDM_ENABLE_HWNOTIF, dwState); EnableMenuItem(hMenu, IDM_GET_HWNOTIF, dwState); EnableMenuItem(hMenu, IDM_REFRESH_DEVBUS, dwState); EnableMenuItem(hMenu, IDM_LAUNCH_APP_FOR_DEV, dwState); EnableMenuItem(hMenu, IDM_SETUP_DEVPARAMS, dwState); }
/*****************************************************************************
void IStillDeviceMenu(DWORD dwState) Enable or Disable the menus for the IStillDevice interface.
Parameters: MF_ENABLED or MF_GRAYED
Return: none
*****************************************************************************/ void IStillDeviceMenu(DWORD dwState) { EnableMenuItem(hMenu, IDM_GET_CAPS, dwState); EnableMenuItem(hMenu, IDM_GET_STATUS_A, dwState); EnableMenuItem(hMenu, IDM_GET_STATUS_B, dwState); EnableMenuItem(hMenu, IDM_GET_STATUS_C, dwState); EnableMenuItem(hMenu, IDM_DEVICERESET, dwState); EnableMenuItem(hMenu, IDM_DIAGNOSTIC, dwState); EnableMenuItem(hMenu, IDM_ESCAPE_A, dwState); EnableMenuItem(hMenu, IDM_ESCAPE_B, dwState); EnableMenuItem(hMenu, IDM_GET_LASTERRINFO, dwState); EnableMenuItem(hMenu, IDM_LOCKDEV, dwState); EnableMenuItem(hMenu, IDM_UNLOCKDEV, dwState); EnableMenuItem(hMenu, IDM_RAWREADDATA_A, dwState); EnableMenuItem(hMenu, IDM_RAWREADDATA_B, dwState); EnableMenuItem(hMenu, IDM_RAWWRITEDATA_A, dwState); EnableMenuItem(hMenu, IDM_RAWWRITEDATA_B, dwState); EnableMenuItem(hMenu, IDM_RAWREADCOMMAND_A, dwState); EnableMenuItem(hMenu, IDM_RAWREADCOMMAND_B, dwState); EnableMenuItem(hMenu, IDM_RAWWRITECOMMAND_A, dwState); EnableMenuItem(hMenu, IDM_RAWWRITECOMMAND_B, dwState); EnableMenuItem(hMenu, IDM_SUBSCRIBE, dwState); EnableMenuItem(hMenu, IDM_UNSUBSCRIBE, dwState); EnableMenuItem(hMenu, IDM_DEVICE_RELEASE, dwState); }
/*****************************************************************************
void IStillScanMenu(DWORD dwState) Enable or Disable the menus for scanning.
Parameters: MF_ENABLED or MF_GRAYED
Return: none
*****************************************************************************/ void IStillScanMenu(DWORD dwState) { EnableMenuItem(hMenu, IDM_LAMPON, dwState); EnableMenuItem(hMenu, IDM_LAMPOFF, dwState); EnableMenuItem(hMenu, IDM_SCAN, dwState); }
/*****************************************************************************
int NextStiDevice() Select next valid Sti device
Parameters: none
Return: number of next sti device (0 == first)
*****************************************************************************/ int NextStiDevice() { //
// select next device from static list (go to first at end of list)
//
nStiNumber++;
if ( nStiNumber >= (int) dwStiTotal ) { //
// point to head of list
//
nStiNumber = 0; }
//
// select next device from device log (go to first at end of list)
//
if ( pdevPtr->pNext ) { pdevPtr = pdevPtr->pNext; } else { //
// point to head of list
//
pdevPtr = pdevRoot; }
return nStiNumber; }
/*****************************************************************************
HRESULT StiCreateInstance(BOOL *) Opens Sti subsystem
Parameters: Pointer to receive PASS/FAIL status
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiCreateInstance(BOOL *bPass) { HRESULT hres = STI_OK; BOOL bReturn;
//
// close any open devices before enumeration
//
StiClose(&bReturn);
//
// The StiCreateInstance interface locates the primary still image interface.
// Use this call to optain the pointer to the IStillImage interface.
//
hres = StiCreateInstance( GetModuleHandle(NULL), // instance handle of this application
STI_VERSION, // Sti version
&pSti, // pointer to IStillImage interface
NULL // pointer to controlling unknown of OLE aggregation
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"StiCreateInstance",TRUE); *bPass = FALSE; return (STIERR_GENERIC); } *bPass = TRUE; DisplayOutput(" The Sti subsystem is opened"); DisplayOutput("");
//
// Enable the menu items for IStillImage interface calls available
//
IStillImageMenu(MF_ENABLED); EnableMenuItem(hMenu, IDM_CREATE_INSTANCE, MF_GRAYED);
return (hres); }
/*****************************************************************************
HRESULT StiClose(BOOL *) Close any open devices and Sti subsystem
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiClose(BOOL *bPass) { HRESULT hres = STI_OK;
*bPass = TRUE;
// stop subscribing
nUnSubscribe = 0;
// close any open devices and then close Sti subsystem
hres = StiDeviceRelease(bPass); hres = StiImageRelease(bPass);
//
// clear the internal device name and the friendly user name
//
ZeroMemory(szInternalName,STI_MAX_INTERNAL_NAME_LENGTH); ZeroMemory(szFriendlyName,STI_MAX_INTERNAL_NAME_LENGTH);
return (hres); }
/*****************************************************************************
HRESULT StiDeviceRelease(BOOL *) Close the Sti subsystem
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiDeviceRelease(BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK;
*bPass = TRUE;
//
// Need to UnSuscribe if the semaphore is set.
//
if ( nUnSubscribeSemaphore ) { //
// clear the semaphores
//
nUnSubscribe = nUnSubscribeSemaphore = 0;
// UnSubscribe is called when an application no longer wants to receive
// events from a device.
//
hres = pStiDevice->UnSubscribe();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnSubscribe",TRUE); hError = hres; *bPass = FALSE; }
//
// we're done with the event
//
CloseHandle(hWaitEvent);
DisplayOutput(" StiDeviceRelease has UnSubscribed"); } //
// The STI_DEVICE_INFORMATION array returned by GetDeviceList needs to
// be freed with LocalFree(). Also, resetting internal Sti device counter.
//
if ( pStiInfo ) LocalFree(pStiInfo); pStiInfo = pStiInfoPtr = NULL;
//
// close device if any are open
//
if ( pStiDevice ) { //
// Close an open device.
//
hres = pStiDevice->Release();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"Release (Device)",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device Released");
DisplayOutput("");
//
// clear the Sti device pointer
//
pStiDevice = NULL;
//
// disable IStiDevice menu items
//
IStillDeviceMenu(MF_GRAYED); IStillNameMenu(MF_GRAYED); IStillScanMenu(MF_GRAYED); EnableMenuItem(hMenu, IDM_IMAGE_RELEASE, MF_ENABLED); CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_UNCHECKED); }
return (hError); }
/*****************************************************************************
HRESULT StiImageRelease(BOOL *) Close the Sti subsystem
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiImageRelease(BOOL *bPass) { HRESULT hres = STI_OK;
*bPass = TRUE;
//
// if Sti subsystem is open, close it
//
if ( pSti ) { //
// Close the Still Imaging subsystem.
//
hres = pSti->Release();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"Release (Image)",TRUE); *bPass = FALSE; } else DisplayOutput(" Imaging subsystem Released");
DisplayOutput("");
//
// clear the Sti subsystem pointer
//
pSti = NULL;
//
// Disable the menu items for IStillImage interface calls
//
IStillNameMenu(MF_GRAYED); IStillImageMenu(MF_GRAYED); EnableMenuItem(hMenu, IDM_CREATE_INSTANCE, MF_ENABLED); }
return (hres); }
/*****************************************************************************
HRESULT StiEnum(BOOL *) Opens Sti subsystem and enumerates any still image devices found
Parameters: Pointer to receive PASS/FAIL status
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiEnum(BOOL *bPass) { HRESULT hres = STI_OK;
DWORD dwCounter; DWORD dwStiCount = 0;
PSTI_DEVICE_INFORMATION pI = NULL; BOOL bReturn;
PCSTR pszStringTablePtr = NULL;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); }
//
// Enumerate devices
//
dwStiTotal = 0; pStiInfo = NULL;
//
// The GetDeviceList interface is used to get a list of the installed still
// image devices. Use this call to obtain a STI_DEVICE_INFORMATION array
// filled with info on all currently installed Sti devices.
// * NOTE: the STI subsystem allocates memory for the Sti device information
// buffer, but the caller needs to free this memory with LocalFree().
//
hres = pSti->GetDeviceList( NULL, // Type (reserved, use NULL)
NULL, // Flags (reserved, use NULL)
&dwStiTotal, // address of variable to return number of devices found
&pStiInfo // Sti device info buffer
);
if ( ! SUCCEEDED(hres) || ! pStiInfo ) { StiDisplayError(hres,"GetDeviceList",TRUE); StiClose(&bReturn); *bPass = FALSE; return (STIERR_GENERIC); } *bPass = TRUE;
//
// Display Sti info on each device found
//
for ( dwCounter = 0,pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo; dwCounter < dwStiTotal; dwCounter++, pStiInfoPtr++ ) {
DisplayOutput(" Device number %2d",dwCounter + 1); pszStringTablePtr = StrFromTable(GET_STIDEVICE_TYPE(pStiInfoPtr->DeviceType), StStiDeviceType); DisplayOutput(" Device type %xh %s", GET_STIDEVICE_TYPE(pStiInfoPtr->DeviceType), pszStringTablePtr); DisplayOutput(" Device subtype %xh", GET_STIDEVICE_SUBTYPE(pStiInfoPtr->DeviceType)); DisplayOutput(" Internal name \"%S\"", pStiInfoPtr->szDeviceInternalName); DisplayOutput(" Device capabilities %xh", pStiInfoPtr->DeviceCapabilities); DisplayOutput(" Hardware configuration %xh", pStiInfoPtr->dwHardwareConfiguration); DisplayOutput(" Vendor description \"%S\"", pStiInfoPtr->pszVendorDescription); DisplayOutput(" Device description \"%S\"", pStiInfoPtr->pszDeviceDescription); DisplayOutput(" Port Name \"%S\"", pStiInfoPtr->pszPortName); DisplayOutput(" Prop provider \"%S\"", pStiInfoPtr->pszPropProvider); DisplayOutput(" Local name \"%S\"", pStiInfoPtr->pszLocalName); DisplayOutput(""); }
//
// point to most recently selected device again
//
pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo + nStiNumber;
DisplayOutput(" GetDeviceList found %d device%s",dwStiTotal, dwStiTotal == 1 ? "" : "s");
if ( dwStiTotal != dwCounter ) { DisplayOutput("* Get DeviceList actually returned %d devices",dwCounter); dwStiTotal = dwCounter; nError++; pdevPtr-nError++; } DisplayOutput("");
return (hres); }
/*****************************************************************************
HRESULT StiEnumPrivate(PVOID *, DWORD *) Call GetDeviceList and return pointer to struct
Parameters: Pointer to private DeviceList Pointer to number of devices found counter
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiEnumPrivate(PVOID *pPtr, DWORD *dwHowMany) { HRESULT hres = STI_OK; BOOL bReturn;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) return (STIERR_GENERIC);
//
// The GetDeviceList interface is used to get a list of the installed still
// image devices. Use this call to obtain a STI_DEVICE_INFORMATION array
// filled with info on all currently installed Sti devices.
// * NOTE: the STI subsystem allocates memory for the Sti device information
// buffer, but the caller needs to free this memory with LocalFree().
//
hres = pSti->GetDeviceList( NULL, // Type (reserved, use NULL)
NULL, // Flags (reserved, use NULL)
dwHowMany, // address of variable to return number of devices found
pPtr // Sti device info buffer
);
if ( ! SUCCEEDED(hres) || ! *pPtr ) { StiDisplayError(hres,"GetDeviceList",TRUE); StiClose(&bReturn); return (STIERR_GENERIC); }
return (hres); }
/*****************************************************************************
INT StiSelect(HWND hWnd,int nContext,BOOL *) Select and open a specific Still Image device
Parameters: handle to current window context we were called from pointer to receive Pass/Fail
Return: 0 on success, -1 on error
*****************************************************************************/ INT StiSelect(HWND hWnd,int nContext,BOOL *bPass) { HRESULT hres = STI_OK; BOOL bReturn;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (-1); } *bPass = TRUE;
//
// look for devices if count of available is 0
//
if ( dwStiTotal == 0 ) { StiEnum(&bReturn); }
//
// if still no devices, inform user and leave
//
if ( dwStiTotal == 0 ) {
ZeroMemory(szInternalName,sizeof(szInternalName)); ZeroMemory(szFriendlyName,sizeof(szFriendlyName));
DisplayOutput("* No Sti devices found!"); DisplayOutput(""); *bPass = FALSE; return (-1); }
switch ( nContext ) { case EVENT: //
// Sti push event or automated test
//
if ( nStiNumber == -1 ) { //
// we could not select the correct device, just return
//
nStiNumber = 0; return (0); } break; case MANUAL: //
// manual device selection
//
bReturn = fDialog(IDD_SELECT, hWnd, (FARPROC) SelectDevice);
//
// just return if user pressed CANCEL in dialog
//
if ( bReturn == FALSE ) { return (0); } break; }
//
// close any currently active imaging device
//
if ( pStiDevice ) StiDeviceRelease(&bReturn);
//
// get pointer to device selected in dialog
//
pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo + nStiNumber;
if ( ! *(pStiInfoPtr->szDeviceInternalName) ) { DisplayOutput("* Invalid device name !"); nError++; pdevPtr-nError++; *bPass = FALSE; return (-1); }
//
// copy the internal device name and the friendly user name
//
wcscpy(szInternalName,pStiInfoPtr->szDeviceInternalName); wcscpy(szFriendlyName,pStiInfoPtr->pszLocalName); IStillNameMenu(MF_ENABLED);
DisplayOutput(" Selected device %d \"%S\"",nStiNumber + 1,szInternalName); DisplayOutput(" Friendly name \"%S\"",szFriendlyName);
//
// Are we selecting the device or just its name?
//
if ( ! nNameOnly ) { //
// The CreateDevice interface creates an IStiDevice object.
// The IStiDevice object provides access to the IStiDevice interface
// and device specific Imaging functionality.
//
hres = pSti->CreateDevice( pStiInfoPtr->szDeviceInternalName, // internal device name
STI_DEVICE_CREATE_BOTH, // device creation mode
&pStiDevice, // pointer where IStiDevice object is to be stored
NULL ); // pointer to controlling unknown of OLE aggregation
if ( ! SUCCEEDED(hres) || ! pStiDevice ) { StiDisplayError(hres,"CreateDevice",TRUE); DisplayOutput("* \"%S\" (%S) cannot be tested", pStiInfoPtr->pszLocalName,pStiInfoPtr->szDeviceInternalName); DisplayOutput(""); *bPass = FALSE; return (-1); }
//
// enable Sti menu items
//
IStillDeviceMenu(MF_ENABLED); CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_CHECKED); EnableMenuItem(hMenu, IDM_IMAGE_RELEASE, MF_GRAYED);
//
// Do we have scan commands for this device?
//
if ( nICanScan = IsScanDevice(pStiInfoPtr) ) { IStillScanMenu(MF_ENABLED); } DisplayOutput(" \"%S\" is ready for Testing",szFriendlyName); } DisplayOutput("");
return (0); }
/******************************************************************************
BOOL FAR PASCAL SelectDevice(HWND,UINT,WPARAM,LPARAM) Put up a dialog for user to select a Still Image device
Parameters: The usual dialog box parameters.
Return: Result of the call.
******************************************************************************/ BOOL FAR PASCAL SelectDevice(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam) { PSTI_DEVICE_INFORMATION pTmpInfoPtr; DWORD dwCounter; int iIndex; static int iLastPick = 0;
switch ( msg ) {
case WM_INITDIALOG:
//
// fill dialog with Sti Device Internal Names
//
for ( dwCounter = 0, pTmpInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo; dwCounter < dwStiTotal;dwCounter++, pTmpInfoPtr++ ) { //
// convert UNICODE string to ANSI
//
wsprintf(pszStr1,"%ls",pTmpInfoPtr->pszLocalName);
iIndex = SendDlgItemMessage(hDlg,IDC_SELECT_DEVICE, CB_ADDSTRING,0,(LPARAM) (LPCTSTR) pszStr1); } SendDlgItemMessage(hDlg,IDC_SELECT_DEVICE,CB_SETCURSEL,iLastPick,0);
return (TRUE);
case WM_COMMAND: switch ( wParam ) { case IDOK: nStiNumber = SendDlgItemMessage(hDlg,IDC_SELECT_DEVICE, CB_GETCURSEL,0,0); nNameOnly = SendDlgItemMessage(hDlg,IDC_SELECT_NAME, BM_GETCHECK,0,0);
//
// ensure device number not greater than total
// (NOTE: dwStiTotal is 1's base, while nStiNumber is 0 based)
//
if ( nStiNumber >= (int) dwStiTotal ) nStiNumber = (int) dwStiTotal - 1; if ( nStiNumber < 0 ) nStiNumber = 0; iLastPick = nStiNumber;
EndDialog(hDlg, TRUE); return (TRUE);
case IDCANCEL: EndDialog(hDlg, FALSE); return (TRUE); }
} return (FALSE); }
/*****************************************************************************
void StiDisplayError(HRESULT,char *,BOOL) Display verbose error information
Parameters: HRESULT from failed call TRUE = record error as compliance failure
Return: none
*****************************************************************************/ void StiDisplayError(HRESULT hres,char *szCall,BOOL bFail) { PERRECORD pR = pdevPtr->pRecord; BOOL bReturn;
StiGetLastErrorInfo(&bReturn); LastError(TRUE);
//
// record the error
//
pR += nTestID; pR->nCount++;
// BUG BUG can't copy the string correctly to UNICODE string
// sprintf(pszStr4,"%s",StrFromTable(hres,StStiError));
// swprintf(pR->szErrorString,L"%s",pszStr4);
//
// compliance test failure error?
//
if ( bFail ) { nError++; pdevPtr-nError++; pR->bFatal = TRUE; DisplayOutput("* Sti Compliance test error"); tlLog(hNTLog,TL_LOG,"* Sti Compliance test error");
} else { DisplayOutput("* Allowed error"); } DisplayOutput("* %s returned %xh (%d)",szCall,hres,hres); if ( bFail ) tlLog(hNTLog,TL_LOG,"* %s returned %xh (%d)",szCall,hres,hres); DisplayOutput(" \"%s\"",StrFromTable(hres,StStiError)); if ( bFail ) tlLog(hNTLog,TL_LOG," \"%s\"",StrFromTable(hres,StStiError));
return; }
/******************************************************************************
int InitPrivateList(PDEVLOG,int *) Initialize private test structures
Parameters: pointer to Devicelog to initialize pointer to test suite
Return: total number of devices found (-1 on failure)
******************************************************************************/ int InitPrivateList(PDEVLOG *pDev,int *pSuiteList) { DWORD dwStiDevCount = 0; PVOID pList = NULL; PSTI_DEVICE_INFORMATION pInfoPrivatePtr = NULL; // pointer to device in pStiBuffer
PDEVLOG pPtr = NULL; PERRECORD precPtr = NULL; int i,k,nNumberTests,nTotalDevices; BOOL bReturn;
//
// get the current number of devices and their names
//
StiCreateInstance(&bReturn);
StiEnumPrivate(&pList,&dwStiDevCount); if ( ! pList ) { DisplayOutput("* No Sti device attached !"); } else { pInfoPrivatePtr = (PSTI_DEVICE_INFORMATION) pList; }
//
// create at least one list entry (even if no devices are found)
//
if ( ! dwStiDevCount ) { dwStiDevCount = 1; nTotalDevices = 0; } else nTotalDevices = (int) dwStiDevCount;
//
// create a device log for each device
//
pPtr = (PDEVLOG) calloc(dwStiDevCount,sizeof(DEVLOG)); if ( pPtr == NULL ) { FatalError("Could not initialize private structures"); return (-1); } *pDev = pPtr;
//
// count the number of tests in suite
//
for ( nNumberTests = 0;pSuiteList[nNumberTests] != -1;nNumberTests++ ) ;
//
// initialize linked list pointers and error records for each device log
//
for ( i = 0;i < (int) dwStiDevCount;i++,pPtr++,pInfoPrivatePtr++ ) { if ( i ) { (pPtr - 1)->pNext = pPtr; pPtr->pPrev = pPtr - 1; } if ( nTotalDevices ) { wcscpy(pPtr->szInternalName,pInfoPrivatePtr->szDeviceInternalName); wcscpy(pPtr->szLocalName,pInfoPrivatePtr->pszLocalName); } else { wcscpy(pPtr->szInternalName,L"* Invalid !"); wcscpy(pPtr->szLocalName,L"* No Sti device attached !"); }
//
// create one error log for each test (nNumberTests)
//
pPtr->pRecord = (PERRECORD) calloc(nNumberTests,sizeof(ERRECORD)); if ( pPtr->pRecord == NULL ) { FatalError("Could not initialize private structures"); return (-1); } //
// initialize linked list pointers and error records for each record
//
for ( k = 0,precPtr = pPtr->pRecord;k < nNumberTests;k++,precPtr++ ) { precPtr->nIndex = k; precPtr->nTest = pSuite[k]; if ( k ) { (precPtr - 1)->pNext = precPtr; precPtr->pPrev = precPtr - 1; } } }
//
// free the device list
//
LocalFree(pList); StiClose(&bReturn);
return (nTotalDevices); }
/******************************************************************************
int ClosePrivateList(PDEVLOG) Remove private test structures
Parameters: pointer to Devicelog to close
Return: 0 on success -1 on failure
******************************************************************************/ int ClosePrivateList(PDEVLOG *pDev) { PDEVLOG pPtr = (PDEVLOG) *pDev;
if ( pDev == NULL ) return (0);
//
// free each device log's error record
//
for ( ;pPtr->pNext;pPtr++ ) { if ( pPtr->pRecord ) free(pPtr->pRecord); }
//
// free the device log
//
if ( *pDev ) { free(*pDev); *pDev = NULL; }
return (0); }
/*****************************************************************************
HRESULT StiGetDeviceValue(LPWSTR,LPWSTR,DWORD *,BOOL *) Get driver information
Parameters: szDevname - internal device name szKeyname - key to access dwType - pointer to data type pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiGetDeviceValue(LPWSTR szDevname,LPWSTR szKeyname,LPBYTE pData, DWORD *dwType,DWORD cbData,BOOL *bPass) { HRESULT hres = STI_OK;
//
// WINNT.H - Predefined Value Types
//
STRINGTABLE StRegType[] = { REG_NONE, "REG_NONE",0, REG_SZ, "REG_SZ",0, REG_BINARY, "REG_BINARY",0, REG_DWORD, "REG_DWORD",0, 0, "Unknown Reg Type",-1 };
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
ZeroMemory(pData,cbData);
DisplayOutput(" GetDeviceValue for device \"%S\"",szDevname); DisplayOutput(" Key requested: \"%S\"",szKeyname);
//
// The GetDeviceValue function is used to retrieve data associated with a
// still image device. Essentially, data is associated with a device
// through a key/data type/value triplet. The only reserved standard
// ValueNames, as defined in STI.H, are the following:
//
// ICMProfiles - string containing a comma-sperated list of ICM profiles
// TwainDS - TWAIN data source display name
// ISISDriverName - ISIS driver name
//
hres = pSti->GetDeviceValue( szDevname, // internal device name
szKeyname, // value tag string
dwType, // pointer where data type will be stored
pData, // pointer where value will be stored
&cbData // size of value pointer storage
);
if ( !SUCCEEDED(hres) ) { //
// The only required registry item is STI_DEVICE_VALUE_ICM_PROFILE
//
if ( hres == STIERR_OBJECTNOTFOUND ) { if ( ! wcscmp(STI_DEVICE_VALUE_ICM_PROFILE,szKeyname) ) { //
// Only STI_DEVICE_VALUE_ICM_PROFILE is a required key
// Therefore, only this one Failure is a COMPLIANCE test failure
//
*bPass = FALSE; StiDisplayError(hres,"GetDeviceValue",TRUE); } else { StiDisplayError(hres,"GetDeviceValue",FALSE); } } else { *bPass = FALSE; StiDisplayError(hres,"GetDeviceValue",TRUE); } } else { DisplayOutput(" Reg Type %d %s",* dwType, StrFromTable(*dwType,StRegType)); DisplayOutput(" The following %d bytes were read from the Registry:", cbData); DisplayOutput(" \"%s\"",pData); } DisplayOutput("");
return (hres); }
/*****************************************************************************
HRESULT StiSetDeviceValue(LPWSTR,LPWSTR,LPWSTR,DWORD,BOOL *) Set driver information
Parameters: szDevname - internal device name szKeyname - key to access pData - value to write dwType - data type pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiSetDeviceValue(LPWSTR szDevname,LPWSTR szKeyname,LPBYTE pData, DWORD dwType,DWORD cbData,BOOL *bPass) { HRESULT hres = STI_OK;
//
// WINNT.H - Predefined Value Types
//
STRINGTABLE StRegType[] = { REG_NONE, "REG_NONE",0, REG_SZ, "REG_SZ",0, REG_BINARY, "REG_BINARY",0, REG_DWORD, "REG_DWORD",0, 0, "Unknown Reg Type",-1 };
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
DisplayOutput(" SetDeviceValue for device \"%S\"",szDevname); DisplayOutput(" Key \"%S",szKeyname);
//
// The SetDeviceValue function is used to associate any additional data
// with a still image device. It is used internally to store the values of
// strings that are required to communicate information to imaging APIs
// during use of push model behavoir. However, this function can be used
// to associate any ancillary data with a device. The only reserved
// ValueNames, as defined in STI.H, are the following:
//
// ICMProfiles - string containing a comma-sperated list of ICM profiles
// TwainDS - TWAIN data source display name
// ISISDriverName - ISIS driver name
//
hres = pSti->SetDeviceValue( szDevname, // internal device name
szKeyname, // value tag string
dwType, // data type sent
pData, // pointer to data to send
cbData // byte size of data
);
if ( !SUCCEEDED(hres) ) { //
// SetDeviceValue is not required under NT
//
StiDisplayError(hres,"SetDeviceValue",FALSE); } else { //pszStr1 = StrFromTable(dwType,StRegType);
DisplayOutput(" Reg Type %d %s",dwType,StrFromTable(dwType,StRegType)); DisplayOutput(" The following %d bytes were written to the Registry:", cbData); DisplayOutput(" \"%s\"",(char *) pData); } DisplayOutput("");
return (hres); }
/*****************************************************************************
HRESULT StiRegister(HWND,int,BOOL *) Register or Unregister the application to receive Sti Launch events.
Parameters: Handle to the window to display image in. Instance for access to string table int nOnOff == ON to register, OFF to unregister pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiRegister(HWND hWnd,HINSTANCE hInstance,int nOnOff,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; CHAR szModulePath[MAX_PATH+1]; WCHAR szModulePathW[MAX_PATH+1], szAppName[MEDSTRING]; DWORD cch;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Retrieve name of this application from STRING table
// and convert to UNICODE.
//
LoadString(hInstance,IDS_APPNAME,pszStr1,MEDSTRING); cch = MultiByteToWideChar(CP_ACP, 0, pszStr1, -1, szAppName,MEDSTRING); if ( ! cch ) { LastError(TRUE); *bPass = FALSE; return (STIERR_GENERIC); }
//
// Register/deregister app
//
if ( nOnOff == ON ) { //
// Register our application.
// Get full path to executable and convert to UNICODE.
//
cch = GetModuleFileName(NULL,szModulePath,sizeof(szModulePath));
if ( ! cch ) { LastError(TRUE); *bPass = FALSE; return (STIERR_GENERIC); } cch = MultiByteToWideChar(CP_ACP, 0, szModulePath, -1, szModulePathW, sizeof(szModulePathW));
//
// The RegisterLaunchApplication function should be called by
// applications that would like to be launched in response to an
// Sti push event. This function can be called more than once,
// and should be called each time the application rus in case
// the user relocates the application.
//
hres = pSti->RegisterLaunchApplication( szAppName, // short name of app
szModulePathW // full path to executable
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"RegisterLaunchApplication",TRUE); *bPass = FALSE; hError = hres; } else { DisplayOutput(" %s registered for Sti Launch Application",pszStr1); } } else { //
// Unregister our application
//
hres = pSti->UnregisterLaunchApplication( szAppName // short name of app
); if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnregisterLaunchApplication",TRUE); hError = hres; } else { DisplayOutput(" %s Unregistered from Sti Launch",pszStr1); } } DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiEvent(HWND hWnd) Handle a push model event. This function is called when the test app has been a) registered as a push event handler b) launched by a push event
Parameters: Handle to the window to display image in.
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiEvent(HWND hWnd) { HRESULT hres = STI_OK; WCHAR szDeviceName[STI_MAX_INTERNAL_NAME_LENGTH + 1], szEventName[LONGSTRING]; DWORD cch, dwEventCode = 0, cbData = LONGSTRING; int nCounter; BOOL bBadFlag = FALSE;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); }
ZeroMemory(szDeviceName,STI_MAX_INTERNAL_NAME_LENGTH + 1); ZeroMemory(szEventName,LONGSTRING);
//
// For an application started through push model launch,
// GetSTILaunchInformation returns the associated information. This
// information is used to determine which device to use and what
// event caused the application to be launched.
//
hres = pSti->GetSTILaunchInformation( szDeviceName, // pointer to where device name will be stored
&dwEventCode, // reserved
szEventName // pointer to where GUID will be stored
);
if ( !SUCCEEDED(hres) ) { StiDisplayError(hres,"GetSTILaunchInformation",TRUE); return (STIERR_GENERIC); }
ZeroMemory(pszStr2,LONGSTRING); ZeroMemory(pszStr4,LONGSTRING); cch = WideCharToMultiByte(CP_ACP,0, szDeviceName,-1, pszStr1,STI_MAX_INTERNAL_NAME_LENGTH + 1, pszStr2,&bBadFlag); if ( ! cch ) LastError(TRUE); if ( bBadFlag ) { DisplayOutput("* UNICODE translation error"); bBadFlag = FALSE; } DisplayOutput(" %s launched via Sti push",pszStr1); DisplayOutput(" Event code %d (%xh)",dwEventCode,dwEventCode);
cch = WideCharToMultiByte(CP_ACP,0, szEventName,-1, pszStr1,STI_MAX_INTERNAL_NAME_LENGTH + 1, pszStr2,&bBadFlag); if ( ! cch ) LastError(TRUE); if ( bBadFlag ) { DisplayOutput("* UNICODE translation error"); bBadFlag = FALSE; } DisplayOutput(" Event name %s",pszStr1);
//
// find the Sti device that sent the event
// set nStiNumber to -1 (no device), then set to event device when found
//
for ( nStiNumber = -1,nCounter = 0, pStiInfoPtr = (PSTI_DEVICE_INFORMATION) pStiInfo; nCounter < (int) dwStiTotal;pStiInfoPtr++,nCounter++ ) { if ( ! wcscmp(szDeviceName,pStiInfoPtr->szDeviceInternalName) ) nStiNumber = nCounter; } DisplayOutput("");
return (hres); }
/*****************************************************************************
HRESULT StiGetDeviceInfo(LPWSTR szDevName,BOOL *pPass) Display information about the selected device
Parameters: WCHAR string of the selected device pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiGetDeviceInfo(LPWSTR szDevname,BOOL *bPass) { HRESULT hres = STI_OK; PVOID pInfo = NULL; PSTI_DEVICE_INFORMATION pInfoPtr = NULL;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Given a device name, the GetDeviceInfo interface makes available a
// structure that describes the various attributes of the device.
// * NOTE: the STI subsystem allocates memory for the Sti device information
// buffer, but the caller needs to free this memory with LocalFree().
//
hres = pSti->GetDeviceInfo( szDevname, // pointer to the internal device name
&pInfo); // Sti device info buffer
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"GetDeviceInfo",TRUE); *bPass = FALSE; }
pInfoPtr = (PSTI_DEVICE_INFORMATION) pInfo;
DisplayOutput(" GetDeviceInfo for \"%S\"",szDevname); //pszStr1 = StrFromTable(GET_STIDEVICE_TYPE(pInfoPtr->DeviceType),StStiDeviceType);
DisplayOutput(" Device type %xh %s", GET_STIDEVICE_TYPE(pInfoPtr->DeviceType), StrFromTable(GET_STIDEVICE_TYPE(pInfoPtr->DeviceType),StStiDeviceType)); DisplayOutput(" Device subtype %xh", GET_STIDEVICE_SUBTYPE(pInfoPtr->DeviceType)); DisplayOutput(" Internal name \"%S\"", pInfoPtr->szDeviceInternalName); DisplayOutput(" Device capabilities %xh", pInfoPtr->DeviceCapabilities); DisplayOutput(" Hardware configuration %xh", pInfoPtr->dwHardwareConfiguration); DisplayOutput(" Vendor description \"%S\"", pInfoPtr->pszVendorDescription); DisplayOutput(" Device description \"%S\"", pInfoPtr->pszDeviceDescription); DisplayOutput(" Port Name \"%S\"", pInfoPtr->pszPortName); DisplayOutput(" Prop provider \"%S\"", pInfoPtr->pszPropProvider); DisplayOutput(" Local name \"%S\"", pInfoPtr->pszLocalName); DisplayOutput("");
// free the STI_DEVICE_INFORMATION buffer
if ( pInfo ) LocalFree(pInfo);
return (hres); }
/*****************************************************************************
HRESULT StiEnableHwNotification(LPWSTR,int *,BOOL *) Determine the current notification handling state and if requested, change it.
Parameters: internal device name pointer to state request (current state returned in pointer) ON = turn on polling OFF = turn off polling PEEK = return current polling state pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiEnableHwNotification(LPWSTR szDevnameW,int *nState,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; BOOL bState = OFF;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// GetHwNotificationState gets the current state of notification handling.
// The state parameter returns TRUE if the notification is enabled.
//
hres = pSti->GetHwNotificationState( szDevnameW, // internal device name
&bState // pointer where state will be stored
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"GetHwNotificationState",TRUE); *bPass = FALSE; hError = hres; } else { DisplayOutput(" Hardware Notification state is %s", bState ? "TRUE (ON)" : "FALSE (OFF)"); }
if ( *nState != PEEK ) { //
// EnableHwNotifications is used to turn event notification on and off.
// For polled devices, this function will turn polling on and off.
//
hres = pSti->EnableHwNotifications( szDevnameW, // internal device name
*nState // new state to be set
); if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"GetHwNotificationState",TRUE); *bPass = FALSE; return (hres); }
//
// Ensure the state was changed
//
hres = pSti->GetHwNotificationState( szDevnameW, // internal device name
&bState // pointer where state will be stored
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"GetHwNotificationState",TRUE); *bPass = FALSE; hError = hres; } else { DisplayOutput(" Hw state has been set to %s", bState ? "TRUE (ON)" : "FALSE (OFF)"); }
if ( bState ) { if ( GetMenuState(hMenu, IDM_ENABLE_HWNOTIF, NULL) == MF_UNCHECKED ) CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_CHECKED); } else { if ( GetMenuState(hMenu, IDM_ENABLE_HWNOTIF, NULL) == MF_CHECKED ) CheckMenuItem(hMenu, IDM_ENABLE_HWNOTIF, MF_UNCHECKED); } } DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiRefresh(LPWSTR,BOOL *) Refresh the bus for non-PNP devices
Parameters: internal device name pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiRefresh(LPWSTR szDevnameW,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; BOOL bState = OFF;
/**/ //
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// GetHwNotificationState gets the current state of notification handling.
// The state parameter returns TRUE if the notification is enabled.
//
hres = pSti->RefreshDeviceBus( szDevnameW // internal device name
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"RefreshDeviceBus",TRUE); *bPass = TRUE; hError = hres; } else DisplayOutput(" RefreshDeviceBus called on \"%S\"",szDevnameW);
DisplayOutput(""); /**/ return (hError); }
/*****************************************************************************
HRESULT StiWriteErrLog(DWORD,LPCWSTR,BOOL *) Write a string to the error log
Parameters: DWORD severity, which can be STI_TRACE_INFORMATION STI_TRACE_WARNING STI_TRACE_ERROR Wide character message to write to log. pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiWriteErrLog(DWORD dwSeverity,LPCWSTR pszMessage,BOOL *bPass) { HRESULT hres = STI_OK;
//
// check that Sti subsystem is loaded
//
if ( ! pSti ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"StiNotLoaded",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// WriteToErrorLog can be used to write debugging and diagnostic
// information into the Sti log file, located in the Windows directory
// STI_TRACE.LOG. The user can control whether informational, warning or
// error messages, or any combination of these three are put in the log
// file through the Scanners & Cameras control panel.
//
hres = pSti->WriteToErrorLog( dwSeverity, // severity of error
pszMessage // string to write to log
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"WriteToErrorLog",TRUE); *bPass = FALSE; } else DisplayOutput(" WriteToErrorLog wrote \"%S\"",pszMessage); DisplayOutput("");
return (hres); }
/*****************************************************************************
HRESULT StiGetStatus(int,BOOL *) Retrieve the user mode status of the driver.
Parameters: StatusMask to retrieve status for. Can be a combination of: STI_DEV_ONLINE_STATE STI_DEV_EVENTS_STATE pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiGetStatus(int nMask,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; DWORD dwTimeout = 2000; STI_DEVICE_STATUS StiStatus;
//
// STI.H - STI_DEVICE_MJ_TYPE
//
STRINGTABLE StStiStatusMask[] = { STI_DEVSTATUS_ONLINE_STATE, "STI_DEVSTATUS_ONLINE_STATE",0, STI_DEVSTATUS_EVENTS_STATE, "STI_DEVSTATUS_EVENTS_STATE",0, STI_DEVSTATUS_ONLINE_STATE | STI_DEVSTATUS_EVENTS_STATE, "STI_DEVSTATUS_ONLINE_STATE | STI_DEVSTATUS_EVENTS_STATE",0, 0, "Unknown status mask",-1 };
//
// check that an Sti device is selected
//
if ( pStiDevice == NULL ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before GetStatus
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for GetStatus");
//
// Get and display status
//
ZeroMemory(&StiStatus,sizeof(StiStatus)); //
// The STI_DEVICE_STATUS dwSize field MUST be set by the caller.
//
StiStatus.dwSize = sizeof(STI_DEVICE_STATUS); //
// The STI_DEVICE_STATUS StatusMask field MUST be set to the desired
// status to retrieve.
//
StiStatus.StatusMask = nMask;
DisplayOutput(" %s mask",StrFromTable(nMask,StStiStatusMask));
//
// The GetStatus interface gets the status from the user-mode
// minidriver. Status returned can indicate online status and/or
// device event activity.
//
hres = pStiDevice->GetStatus( &StiStatus // pointer to a STI_DEVICE_STATUS struct
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"GetStatus",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" GetStatus on %S",szFriendlyName); } //
// Is the device on?
//
if ( (StiStatus.dwOnlineState == 0) && (nMask & STI_DEVSTATUS_ONLINE_STATE) ) { DisplayOutput("* Device is TURNED OFF OR OFFLINE!!"); }
DisplayOutput(" %xh (%d) StatusMask", StiStatus.StatusMask,StiStatus.StatusMask); DisplayOutput(" %xh (%d) dwOnlineState", StiStatus.dwOnlineState,StiStatus.dwOnlineState); DisplayOutput(" %xh (%d) dwHardwareStatusCode", StiStatus.dwHardwareStatusCode,StiStatus.dwHardwareStatusCode); DisplayOutput(" %xh (%d) dwEventHandlingState", StiStatus.dwEventHandlingState,StiStatus.dwEventHandlingState); DisplayOutput(" %xh (%d) dwPollingInterval", StiStatus.dwPollingInterval,StiStatus.dwPollingInterval);
if ( StiStatus.dwSize != sizeof(STI_DEVICE_STATUS) ) { DisplayOutput("* Expected STI_DEVICE_STATUS dwSize %d, got %d", sizeof(STI_DEVICE_STATUS),StiStatus.dwSize); } }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiGetCaps(BOOL *) Return the device capabilities
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiGetCaps(BOOL *bPass) { HRESULT hres = STI_OK; STI_DEV_CAPS StiDevCaps = { 0};
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// The GetCapabilities function returns the capabilities of the device.
//
hres = pStiDevice->GetCapabilities( &StiDevCaps // pointer to a STI_DEV_CAPS struct
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"GetCapabilities",TRUE); *bPass = FALSE; } else { DisplayOutput(" GetCapabilities on \"%S\'",szFriendlyName);
DisplayOutput(" %xh (%d) dwGeneric", StiDevCaps.dwGeneric,StiDevCaps.dwGeneric); }
DisplayOutput("");
return (hres); }
/*****************************************************************************
HRESULT StiReset(BOOL *) Puts the device into a known state.
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiReset(BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; DWORD dwTimeout = 2000;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before DeviceReset
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for DeviceReset");
//
// The DeviceReset interface requests that a device be returned to a
// known state.
//
hres = pStiDevice->DeviceReset();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"DeviceReset",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" DeviceReset on \"%S\"",szFriendlyName); }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiDiagnostic(BOOL *) Return user mode driver diagnostic info
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiDiagnostic(BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; DIAG diag; DWORD dwTimeout = 2000;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before Diagnostic
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for Diagnostic");
//
// get diagnostic info
//
ZeroMemory(&diag,sizeof(diag)); //
// The DIAG dwSize field MUST be set by the caller.
//
diag.dwSize = sizeof(DIAG); //
// The dwBasicDiagCode of this structure should be initialized with
// the desired request code. Currently, only one request code is
// defined, STI_DIAGCODE_HWPRESENCE.
diag.dwBasicDiagCode = STI_DIAGCODE_HWPRESENCE; //
// There is also a vendor defined field called dwVendorDiagCode that
// can optionally be filled in.
//
diag.dwVendorDiagCode = 0;
//
// The Diagnostic interface executes the diagnostic method of the user
// mode minidriver.
//
hres = pStiDevice->Diagnostic( &diag // pointer to STI_DIAG structure
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"Diagnostic",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Diagnostic on \"%S\"",szFriendlyName); }
DisplayOutput(" %xh (%d) dwBasicDiagCode", diag.dwBasicDiagCode,diag.dwBasicDiagCode); DisplayOutput(" %xh (%d) dwVendorDiagCode", diag.dwVendorDiagCode,diag.dwVendorDiagCode); DisplayOutput(" %xh (%d) dwStatusMask", diag.dwStatusMask,diag.dwStatusMask);
if ( diag.dwSize != sizeof(DIAG) ) DisplayOutput("* Expected DIAG dwSize %d, got %d", sizeof(DIAG),diag.dwSize);
//
// any extended error info?
//
if ( diag.sErrorInfo.dwSize == 0 ) { DisplayOutput(" No Extended Errors"); } else { if ( diag.sErrorInfo.dwSize != sizeof(STI_ERROR_INFO) ) DisplayOutput("* Expected STI_ERROR_INFO dwSize %d, got %d", sizeof(STI_ERROR_INFO),diag.sErrorInfo.dwSize); DisplayOutput(" %xh (%d) sErrorInfo.dwGenericError", diag.sErrorInfo.dwGenericError,diag.sErrorInfo.dwGenericError); DisplayOutput(" %xh (%d) sErrorInfo.dwVendorError", diag.sErrorInfo.dwVendorError,diag.sErrorInfo.dwVendorError); if ( * diag.sErrorInfo.szExtendedErrorText ) DisplayOutput(" sErrorInfo.szExtendedErrorText %s", diag.sErrorInfo.szExtendedErrorText); } }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiGetLastErrorInfo(BOOL *) Get and display last error from Sti device.
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last Sti call
*****************************************************************************/ HRESULT StiGetLastErrorInfo(BOOL *bPass) { HRESULT hres = STI_OK; STI_ERROR_INFO StiError;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; DisplayOutput("* NoStiDevice !"); return (STIERR_GENERIC); } *bPass = TRUE;
//
// get last error info
//
ZeroMemory(&StiError,sizeof(StiError)); //
// The STI_ERROR_INFO dwSize field MUST be set by the caller.
//
StiError.dwSize = sizeof(STI_ERROR_INFO);
//
// The GetLastErrorInfo interface returns the last known error from
// the user-mode minidriver.
//
hres = pStiDevice->GetLastErrorInfo( &StiError // pointer to STI_ERROR_INFO structure
);
if ( ! SUCCEEDED(hres) ) { DisplayOutput("* NoStiDevice !"); *bPass = FALSE; } else DisplayOutput(" GetLastErrorInfo on %S",szFriendlyName);
//
// any extended error info?
//
if ( StiError.dwSize == 0 ) { DisplayOutput("No Extended Errors"); } else { if ( StiError.dwSize != sizeof(STI_ERROR_INFO) ) DisplayOutput("* Expected STI_ERROR_INFO dwSize %d, got %d", sizeof(STI_ERROR_INFO),StiError.dwSize); DisplayOutput(" %xh (%d) sErrorInfo.dwGenericError", StiError.dwGenericError,StiError.dwGenericError); DisplayOutput(" %xh (%d) sErrorInfo.dwVendorError", StiError.dwVendorError,StiError.dwVendorError); if ( * StiError.szExtendedErrorText ) DisplayOutput(" sErrorInfo.szExtendedErrorText %s", StiError.szExtendedErrorText); }
return (hres); }
/*****************************************************************************
HRESULT StiSubscribe(BOOL *) Demonstrate Subscribe, UnSubscribe and GetLastNotificationData
Parameters: pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiSubscribe(BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; STISUBSCRIBE sSubscribe; DWORD dwErr = 0x56565656; int nWait = TRUE; BOOL fWaiting = TRUE;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// create an unnamed event object for notification structure
//
hWaitEvent = CreateEvent(NULL, // security attributes
FALSE, // manual reset event flag
FALSE, // initial state flag
NULL ); // event-object name pointer
if ( ! hWaitEvent ) { *bPass = FALSE; return STIERR_GENERIC; }
//
// prepare the event notification structure
//
ZeroMemory(&sSubscribe,sizeof(sSubscribe)); //
// The STISUBSCRIBE dwSize field MUST be set by the caller.
//
sSubscribe.dwSize = sizeof(STISUBSCRIBE); //
// When flag is STI_SUBSCRIBE_FLAG_WINDOW, window handle is passed in as
// parameter. When flag is STI_SUBSCRIBE_FLAG_EVENT, event handle is
// passed in as a parameter.
//
sSubscribe.dwFlags = STI_SUBSCRIBE_FLAG_EVENT; //
// not used
//
sSubscribe.dwFilter = 0; //
// When STI_SUBSCRIBE_FLAG_WINDOW bit is set, following field should
// be set to handle of window which will receive notification message.
//
sSubscribe.hWndNotify = NULL; //
// Handle of WIN32 auto-reset event, which will be signalled whenever
// device has notification pending.
//
sSubscribe.hEvent = hWaitEvent; //
// Code of notification message, sent to window
//
sSubscribe.uiNotificationMessage = 0;
//
// Subscribe is called by an application that wants to start receiving event
// notifications from a device. This is useful for control center-style
// applications. Each call to Subscribe should be paired with a call to
// UnSubscribe.
//
hres = pStiDevice->Subscribe( &sSubscribe // pointer to STISUBSCRIBE structure
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"Subscribe",TRUE); CloseHandle(hWaitEvent); *bPass = FALSE; return (hres); }
//
// set the flag and semaphore for Subscribe mode
//
nUnSubscribe = nUnSubscribeSemaphore = 1;
//
// Now we wait for an event
//
DisplayOutput(" Subscribe on %S",szFriendlyName);
while ( nUnSubscribe ) {
dwErr = WaitForSingleObject(hWaitEvent,1000);
switch ( dwErr ) { case WAIT_OBJECT_0: { STINOTIFY sNotify;
//
// received a notification
//
DisplayOutput(" WAIT_OBJECT_0 %xh (%d)",dwErr,dwErr); DisplayOutput(" Received notification");
//
// prepare the notification description structure
//
ZeroMemory(&sNotify,sizeof(sNotify)); //
// The STINOTIFY dwSize field MUST be set by the caller.
//
sNotify.dwSize = sizeof(STINOTIFY);
//
// GetLastNotifyData returns information about the last
// event on the device.
//
hres = pStiDevice->GetLastNotificationData( &sNotify // pointer to STINOTIFY structure
); if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"GetLastNotificationData",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" GetLastNotificationData"); DisplayOutput(" GUID {%8x-%4x-%4x-%x}", sNotify.guidNotificationCode.Data1, sNotify.guidNotificationCode.Data2, sNotify.guidNotificationCode.Data3, sNotify.guidNotificationCode.Data4 ); } } break;
case WAIT_TIMEOUT: //
// no notification
//
DisplayOutput(" WAIT_TIMEOUT %xh (%d)",dwErr,dwErr); DisplayOutput(" (select UnSubscribe from the IStillDevice "\ "menu to quit)"); break; case WAIT_ABANDONED: DisplayOutput(" WAIT_ABANDONED %xh (%d)",dwErr,dwErr); break; default: DisplayOutput(" default %xh (%d)",dwErr,dwErr); break; } }
//
// if the device is gone, StiDeviceRelease has already been
// unsubscribed elsewhere in this app
//
if ( ! pStiDevice ) return (STIERR_GENERIC);
//
// UnSubscribe is called when an application no longer wants to receive
// events from a device.
//
hres = pStiDevice->UnSubscribe();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnSubscribe",TRUE); hError = hres; *bPass = FALSE; }
//
// we're done with the event
//
CloseHandle(hWaitEvent);
//
// clear the semaphore
//
nUnSubscribeSemaphore = 0;
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiEscape(DWORD,char *,BOOL *) The Escape function is dependent on the vendor's implementation. Even if a device does not require the Escape function, the driver must provide it. A non-functional Escape must return an error.
Parameters: DWORD EscapeFunction - driver defined code char *lpInData - pointer to data to be sent to device pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiEscape(DWORD EscapeFunction,char *lpInData,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; DWORD dwTimeout = 2000;
DWORD cbInDataSize, dwOutDataSize, pdwActualData; char pOutData[LONGSTRING];
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before Escape
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for Escape");
//
// Set up the command
//
cbInDataSize = strlen(lpInData + 1); //
// zero out other parameters (for clarity's sake only)
//
ZeroMemory(pOutData,LONGSTRING); dwOutDataSize = pdwActualData = 0;
//
// The Escape function executes a multiparameter I/O call. The semantics
// of this call is determined by the specific user-mode minidriver.
//
hres = pStiDevice->Escape( EscapeFunction, // General operation code. The meaning of this code
// varies in each user mode minidriver. There is no
// utilization of this code by the still image
// minidriver.
lpInData, // Pointer to an input memory buffer. If there are
// multiple areas of memory to be read from, they
// must be packaged in some sort of structure
// before being passed to this API.
cbInDataSize, // The length in bytes of the memory pointed to by
// lpInData
pOutData, // Pointer to a memory buffer usable for writing.
// Access to this memory is checked to be sure it
// is available for writing.
dwOutDataSize, // The length in bytes of the memory pointed to by
// lpOutData.
&pdwActualData // Pointer to a DWORD that gets the number of bytes
// actually transferred to pOutData. If this value
// is less than dwOutDataSize, then an error
// situation could exist.
);
if ( ! SUCCEEDED(hres) ) { hError = hres; if ( hres == STIERR_UNSUPPORTED ) { //
// COMPLIANCE test:
// if the escape IOCTL is NOT supported, the driver MUST
// return STIERR_UNSUPPORTED
//
StiDisplayError(hres,"Escape",FALSE); DisplayOutput(" Escape IOCTL %d unsupported",EscapeFunction); } else { StiDisplayError(hres,"Escape",TRUE); *bPass = FALSE; } } else { DisplayOutput(" Escape on %S",szFriendlyName);
DisplayOutput(" %xh (%d) EscapeFunction", EscapeFunction,EscapeFunction); DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x lpInData", lpInData[0], lpInData[1], lpInData[2], lpInData[3], lpInData[4], lpInData[5], lpInData[6], lpInData[7], lpInData[8], lpInData[9], lpInData[10], lpInData[11], lpInData[12], lpInData[13], lpInData[14], lpInData[15] ); DisplayOutput(" %xh (%d) cbInDataSize", cbInDataSize,cbInDataSize); DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x pOutData", pOutData[0], pOutData[1], pOutData[2], pOutData[3], pOutData[4], pOutData[5], pOutData[6], pOutData[7], pOutData[8], pOutData[9], pOutData[10], pOutData[11], pOutData[12], pOutData[13], pOutData[14], pOutData[15] ); DisplayOutput(" %xh (%d) dwOutDataSize", dwOutDataSize,dwOutDataSize); DisplayOutput(" %xh (%d) pdwActualData", pdwActualData,pdwActualData); } }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiRawReadData(char *,LPDWORD,BOOL *) Obtains data from a device.
The RawReadData function is dependent on the vendor's implementation. Even if a device does not require the RawReadData function, the driver must provide it. A non-functional RawReadData must return an error.
Parameters: char *lpBuffer - Location in memory to transfer the data coming in from the device. LPDWORD lpdwNumberOfBytes - number of bytes to be read pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiRawReadData(char *lpBuffer,LPDWORD lpdwNumberOfBytes,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; LPOVERLAPPED lpOverlapped; DWORD dwTimeout = 2000;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before RawReadData
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for RawReadData");
//
// Set up the command
//
lpOverlapped = NULL;
//
// The RawReadData interface reads data from a device. This is a
// general operation for obtaining data from a device. Depending on
// the user-mode minidriver for the device, command streams and data
// streams can be read with this call. Some devices may seperate
// commands from data by using RawReadCommand.
//
hres = pStiDevice->RawReadData( lpBuffer, // Location in memory to transfer the data
// coming from the device
lpdwNumberOfBytes, // Number of bytes requested to be read
lpOverlapped // This is used to signal that the operation
// of this call should be asynchronous. The
// value here conforms to the Win32 APIs.
);
if ( ! SUCCEEDED(hres) ) { if ( hres == STIERR_UNSUPPORTED ) { //
// COMPLIANCE test:
// if RawReadData is NOT supported, the driver MUST
// return STIERR_UNSUPPORTED
//
StiDisplayError(hres,"RawReadData",FALSE); DisplayOutput(" RawReadData unsupported"); } else { StiDisplayError(hres,"RawReadData",TRUE); *bPass = FALSE; } hError = hres; } else { DisplayOutput(" RawReadData on %S",szFriendlyName);
DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x lpBuffer", lpBuffer[0], lpBuffer[1], lpBuffer[2], lpBuffer[3], lpBuffer[4], lpBuffer[5], lpBuffer[6], lpBuffer[7], lpBuffer[8], lpBuffer[9], lpBuffer[10], lpBuffer[11], lpBuffer[12], lpBuffer[13], lpBuffer[14], lpBuffer[15] ); DisplayOutput(" %xh (%d) lpdwNumberOfBytes read", *lpdwNumberOfBytes,*lpdwNumberOfBytes); } }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiRawWriteData(char *,DWORD,BOOL *) Sends data to the device.
The RawWriteData function is dependent on the vendor's implementation. Even if a device does not require the RawWriteData function, the driver must provide it. A non-functional RawWriteData must return an error.
Parameters: char *lpBuffer - Location in memory to read from when sending data to a device. LPDWORD lpdwNumberOfBytes - number of bytes of data to be sent pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiRawWriteData(char *lpBuffer,DWORD dwNumberOfBytes,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; LPOVERLAPPED lpOverlapped; DWORD dwTimeout = 2000;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before RawWriteData
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for RawWriteData");
//
// Set up the command
//
lpOverlapped = NULL;
//
// The RawWriteData interface writes data to a device. This is a
// general operation for sending data to a device. Depending on
// the user-mode minidriver for the device, command streams and data
// streams can be written with this call. Some devices may seperate
// commands from data by using RawWriteCommand.
//
hres = pStiDevice->RawWriteData( lpBuffer, // Location in memory to read from when sending
// data to a device
dwNumberOfBytes, // Number of bytes of data to send
lpOverlapped // This is used to signal that the operation
// of this call should be asynchronous. The
// value here conforms to the Win32 APIs.
);
if ( ! SUCCEEDED(hres) ) { if ( hres == STIERR_UNSUPPORTED ) { //
// COMPLIANCE test:
// if RawWriteData is NOT supported, the driver MUST
// return STIERR_UNSUPPORTED
//
StiDisplayError(hres,"RawWriteData",FALSE); DisplayOutput(" RawWriteData unsupported"); } else { StiDisplayError(hres,"RawWriteData",TRUE); *bPass = FALSE; } hError = hres; } else { DisplayOutput(" RawWriteData on %S",szFriendlyName); DisplayOutput(" %xh (%d) dwNumberOfBytes sent", dwNumberOfBytes,dwNumberOfBytes); } }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiRawReadCommand(char *,LPDWORD,BOOL *) Obtains command information from the device. Unique to the IStiDevice interface.
The RawReadCommand function is dependent on the vendor's implementation. Even if a device does not require the RawReadCommand function, the driver must provide it. A non-functional RawReadCommand must return an error.
Parameters: char *lpBuffer - Location in memory to transfer the data coming in from the device. LPDWORD lpdwNumberOfBytes - number of bytes to be read pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiRawReadCommand(char *lpBuffer,LPDWORD lpdwNumberOfBytes,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; LPOVERLAPPED lpOverlapped; DWORD dwTimeout = 2000;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before RawReadCommand
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for RawReadCommand");
//
// Set up the command
//
lpOverlapped = NULL;
//
// The RawReadCommand interface reads command information from a
// device. The implementation of this call depends on the user-mode
// minidriver for the device. Many devices will not require
// separating commands and data. If this call is not used, the
// user-mode minidriver should return STIERR_UNSUPPORTED.
//
hres = pStiDevice->RawReadCommand( lpBuffer, // Location in memory to transfer the command
// information coming from the device
lpdwNumberOfBytes, // Number of command bytes requested to be read
lpOverlapped // This is used to signal that the operation
// of this call should be asynchronous. The
// value here conforms to the Win32 APIs.
);
if ( ! SUCCEEDED(hres) ) { if ( hres == STIERR_UNSUPPORTED ) { //
// COMPLIANCE test:
// if RawReadCommand is NOT supported, the driver MUST
// return STIERR_UNSUPPORTED
//
StiDisplayError(hres,"RawReadCommand",FALSE); DisplayOutput(" RawReadCommand unsupported"); } else { StiDisplayError(hres,"RawReadCommand",TRUE); *bPass = FALSE; } hError = hres; } else { DisplayOutput(" RawReadCommand on %S",szFriendlyName);
DisplayOutput(" %x %x %x %x %x %x %x %x - %x %x %x %x %x %x %x %x lpBuffer", lpBuffer[0], lpBuffer[1], lpBuffer[2], lpBuffer[3], lpBuffer[4], lpBuffer[5], lpBuffer[6], lpBuffer[7], lpBuffer[8], lpBuffer[9], lpBuffer[10], lpBuffer[11], lpBuffer[12], lpBuffer[13], lpBuffer[14], lpBuffer[15] ); DisplayOutput(" %xh (%d) lpdwNumberOfBytes read", *lpdwNumberOfBytes,*lpdwNumberOfBytes); } }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
/*****************************************************************************
HRESULT StiRawWriteCommand(char *,DWORD,BOOL *) Sends command information to the device. Unique to the IStiDevice interface.
The RawWriteCommand function is dependent on the vendor's implementation. Even if a device does not require the RawWriteCommand function, the driver must provide it. A non-functional RawWriteCommand must return an error.
Parameters: char *lpBuffer - Location in memory to read from when sending data to a device. LPDWORD lpdwNumberOfBytes - number of bytes of data to be sent pointer to receive Pass/Fail result
Return: HRESULT of last failed Sti call
*****************************************************************************/ HRESULT StiRawWriteCommand(char *lpBuffer,DWORD dwNumberOfBytes,BOOL *bPass) { HRESULT hres = STI_OK, hError = STI_OK; LPOVERLAPPED lpOverlapped; DWORD dwTimeout = 2000;
//
// check that an Sti device is selected
//
if ( ! pStiDevice ) { *bPass = FALSE; StiDisplayError(STIERR_GENERIC,"NoStiDevice",TRUE); return (STIERR_GENERIC); } *bPass = TRUE;
//
// Must lock device before RawWriteCommand
//
// The LockDevice locks the apparatus for a single application to access.
// Each LockDevice should be paired with a matching UnLockDevice call.
//
hres = pStiDevice->LockDevice( dwTimeout // timeout in milliseconds
);
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"LockDevice",TRUE); hError = hres; *bPass = FALSE; } else { DisplayOutput(" Device is locked for RawWriteCommand");
//
// Set up the command
//
lpOverlapped = NULL;
//
// The RawWriteCommand interface sends command information to the
// device. The implementation of this call depends on the user-mode
// minidriver for the device. Many devices will not require
// separating commands and data. If this call is not used, the
// user-mode minidriver should return STIERR_UNSUPPORTED.
//
hres = pStiDevice->RawWriteCommand( lpBuffer, // Location in memory to read from when writing
// command information to the device
dwNumberOfBytes, // Number of bytes of data to send
lpOverlapped // This is used to signal that the operation
// of this call should be asynchronous. The
// value here conforms to the Win32 APIs.
);
if ( ! SUCCEEDED(hres) ) { if ( hres == STIERR_UNSUPPORTED ) { //
// COMPLIANCE test:
// if RawWriteData is NOT supported, the driver MUST
// return STIERR_UNSUPPORTED
//
StiDisplayError(hres,"RawWriteCommand",FALSE); DisplayOutput(" RawWriteCommand unsupported"); } else { StiDisplayError(hres,"RawWriteCommand",TRUE); *bPass = FALSE; } hError = hres; } else { DisplayOutput(" RawWriteCommand on %S",szFriendlyName); DisplayOutput(" %xh (%d) dwNumberOfBytes sent", dwNumberOfBytes,dwNumberOfBytes); } }
//
// The UnLockDevice interface unlocks a device that was previously locked.
//
hres = pStiDevice->UnLockDevice();
if ( ! SUCCEEDED(hres) ) { StiDisplayError(hres,"UnLockDevice",TRUE); hError = hres; *bPass = FALSE; } else DisplayOutput(" Device is unlocked");
DisplayOutput("");
return (hError); }
|