You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1116 lines
29 KiB
1116 lines
29 KiB
#include "testmcro.h"
|
|
#include "wiamicro.h"
|
|
#include "resource.h"
|
|
|
|
#include <STI.H>
|
|
#include <math.h>
|
|
#include <winioctl.h>
|
|
#include <usbscan.h>
|
|
|
|
#ifdef DEBUG
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
|
|
// #define BUTTON_SUPPORT // (uncomment this to allow BUTTON SUPPORT)
|
|
// button support is not functional in the test device
|
|
|
|
#define MAX_BUTTONS 1
|
|
#define MAX_BUTTON_NAME 255
|
|
|
|
HINSTANCE g_hInst; // instance of this MicroDriver (used for loading from a resource)
|
|
|
|
|
|
// note: MEMORYBMP, and BMP file will be added by wiafbdrv host driver.
|
|
// do not include them in your extended list.
|
|
//
|
|
|
|
// #define _USE_EXTENDED_FORMAT_LIST (uncomment this to allow Extented file and memory formats)
|
|
|
|
#define NUM_SUPPORTED_FILEFORMATS 1
|
|
GUID g_SupportedFileFormats[NUM_SUPPORTED_FILEFORMATS];
|
|
|
|
#define NUM_SUPPORTED_MEMORYFORMATS 2
|
|
GUID g_SupportedMemoryFormats[NUM_SUPPORTED_MEMORYFORMATS];
|
|
|
|
//
|
|
// Button GUID array used in Capability negotiation.
|
|
// Set your BUTTON guids here. These must match the GUIDS specified in
|
|
// your INF. The Scan Button GUID is public to all scanners with a
|
|
// scan button.
|
|
//
|
|
|
|
GUID g_Buttons[MAX_BUTTONS] ={{0xa6c5a715, 0x8c6e, 0x11d2,{ 0x97, 0x7a, 0x0, 0x0, 0xf8, 0x7a, 0x92, 0x6f}}};
|
|
BOOL g_bButtonNamesCreated = FALSE;
|
|
WCHAR* g_ButtonNames[MAX_BUTTONS];
|
|
|
|
INT g_PalIndex = 0; // simple palette index counter (test driver specific)
|
|
BOOL g_bDown = FALSE; // simple band direction bool (test drvier specific)
|
|
|
|
BOOL InitializeScanner(PSCANINFO pScanInfo);
|
|
VOID InitScannerDefaults(PSCANINFO pScanInfo);
|
|
BOOL SetScannerSettings(PSCANINFO pScanInfo);
|
|
VOID CheckButtonStatus(PVAL pValue);
|
|
VOID GetButtonPress(LONG *pButtonValue);
|
|
HRESULT GetInterruptEvent(PVAL pValue);
|
|
LONG GetButtonCount();
|
|
HRESULT GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal);
|
|
VOID ReadRegistryInformation(PVAL pValue);
|
|
|
|
BOOL APIENTRY DllMain( HANDLE hModule,DWORD dwreason, LPVOID lpReserved)
|
|
{
|
|
g_hInst = (HINSTANCE)hModule;
|
|
switch(dwreason) {
|
|
case DLL_PROCESS_ATTACH:
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
case DLL_PROCESS_DETACH:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* MicroEntry (MicroDriver Entry point)
|
|
*
|
|
* Called by the WIA driver to communicate with the MicroDriver.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* lCommand - MicroDriver Command, sent from the WIA driver
|
|
* pValue - VAL structure used for settings
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
WIAMICRO_API HRESULT MicroEntry(LONG lCommand, PVAL pValue)
|
|
{
|
|
HRESULT hr = E_NOTIMPL;
|
|
DWORD dwBytesWritten = 0;
|
|
INT index = 0;
|
|
|
|
//#define _DEBUG_COMMANDS
|
|
|
|
#ifdef _DEBUG_COMMANDS
|
|
if(lCommand != CMD_STI_GETSTATUS)
|
|
Trace(TEXT("Command Value (%d)"),lCommand);
|
|
#endif
|
|
|
|
if(pValue->pScanInfo == NULL) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
switch(lCommand) {
|
|
case CMD_INITIALIZE:
|
|
hr = S_OK;
|
|
|
|
//
|
|
// create any DeviceIO handles needed, use index (1 - MAX_IO_HANDLES) to store these handles.
|
|
// Index '0' is reserved by the WIA flatbed driver. The CreateFile Name is stored in the szVal
|
|
// member of the VAL structure.
|
|
//
|
|
|
|
// pValue->pScanInfo->DeviceIOHandles[1] = CreateFileA( pValue->szVal,
|
|
// GENERIC_READ | GENERIC_WRITE, // Access mask
|
|
// 0, // Share mode
|
|
// NULL, // SA
|
|
// OPEN_EXISTING, // Create disposition
|
|
// FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, // Attributes
|
|
// NULL );
|
|
|
|
//
|
|
// if your device supports buttons, create the BUTTON name information here..
|
|
//
|
|
|
|
if(!g_bButtonNamesCreated) {
|
|
for(index = 0; index < MAX_BUTTONS; index++){
|
|
g_ButtonNames[index] = (WCHAR*)CoTaskMemAlloc(MAX_BUTTON_NAME);
|
|
}
|
|
|
|
hr = GetOLESTRResourceString(IDS_SCAN_BUTTON_NAME,&g_ButtonNames[0],TRUE);
|
|
if(SUCCEEDED(hr)){
|
|
g_bButtonNamesCreated = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initialize the scanner's default settings
|
|
//
|
|
|
|
InitScannerDefaults(pValue->pScanInfo);
|
|
|
|
break;
|
|
case CMD_UNINITIALIZE:
|
|
|
|
//
|
|
// close any open handles created by the Micro driver
|
|
//
|
|
|
|
if(pValue->pScanInfo->DeviceIOHandles[1] != NULL){
|
|
CloseHandle(pValue->pScanInfo->DeviceIOHandles[1]);
|
|
}
|
|
|
|
|
|
//
|
|
// if your device supports buttons, free/destroy the BUTTON name information here..
|
|
//
|
|
|
|
if(g_bButtonNamesCreated) {
|
|
for(index = 0; index < MAX_BUTTONS; index++){
|
|
CoTaskMemFree(g_ButtonNames[index]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// close/unload libraries
|
|
//
|
|
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_RESETSCANNER:
|
|
|
|
//
|
|
// reset scanner
|
|
//
|
|
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_STI_DIAGNOSTIC:
|
|
case CMD_STI_DEVICERESET:
|
|
|
|
//
|
|
// reset device
|
|
//
|
|
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_STI_GETSTATUS:
|
|
|
|
//
|
|
// set status flag to ON-LINE
|
|
//
|
|
|
|
pValue->lVal = MCRO_STATUS_OK;
|
|
pValue->pGuid = (GUID*) &GUID_NULL;
|
|
|
|
//
|
|
// button polling support
|
|
//
|
|
|
|
#ifdef BUTTON_SUPPORT
|
|
CheckButtonStatus(pValue);
|
|
#endif
|
|
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_SETXRESOLUTION:
|
|
pValue->pScanInfo->Xresolution = pValue->lVal;
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_SETYRESOLUTION:
|
|
pValue->pScanInfo->Yresolution = pValue->lVal;
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_SETCONTRAST:
|
|
pValue->pScanInfo->Contrast = pValue->lVal;
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_SETINTENSITY:
|
|
pValue->pScanInfo->Intensity = pValue->lVal;
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_SETDATATYPE:
|
|
pValue->pScanInfo->DataType = pValue->lVal;
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_SETNEGATIVE:
|
|
pValue->pScanInfo->Negative = pValue->lVal;
|
|
hr = S_OK;
|
|
break;
|
|
case CMD_GETADFSTATUS:
|
|
case CMD_GETADFHASPAPER:
|
|
// pValue->lVal = MCRO_ERROR_PAPER_EMPTY;
|
|
// hr = S_OK;
|
|
break;
|
|
case CMD_GET_INTERRUPT_EVENT:
|
|
hr = GetInterruptEvent(pValue);
|
|
break;
|
|
case CMD_GETCAPABILITIES:
|
|
pValue->lVal = 0;
|
|
pValue->pGuid = NULL;
|
|
pValue->ppButtonNames = NULL;
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case CMD_SETSCANMODE:
|
|
hr = S_OK;
|
|
switch(pValue->lVal){
|
|
case SCANMODE_FINALSCAN:
|
|
Trace(TEXT("Final Scan"));
|
|
break;
|
|
case SCANMODE_PREVIEWSCAN:
|
|
Trace(TEXT("Preview Scan"));
|
|
break;
|
|
default:
|
|
Trace(TEXT("Unknown Scan Mode (%d)"),pValue->lVal);
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
break;
|
|
case CMD_SETSTIDEVICEHKEY:
|
|
ReadRegistryInformation(pValue);
|
|
break;
|
|
|
|
#ifdef _USE_EXTENDED_FORMAT_LIST
|
|
|
|
// note: MEMORYBMP, and BMP file will be added by wiafbdrv host driver.
|
|
// do not include them in your extended list.
|
|
//
|
|
|
|
case CMD_GETSUPPORTEDFILEFORMATS:
|
|
g_SupportedFileFormats[0] = WiaImgFmt_JPEG;
|
|
pValue->lVal = NUM_SUPPORTED_FILEFORMATS;
|
|
pValue->pGuid = g_SupportedFileFormats;
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case CMD_GETSUPPORTEDMEMORYFORMATS:
|
|
g_SupportedMemoryFormats[0] = WiaImgFmt_TIFF;
|
|
g_SupportedMemoryFormats[1] = WiaImgFmt_MYNEWFORMAT;
|
|
pValue->lVal = NUM_SUPPORTED_MEMORYFORMATS;
|
|
pValue->pGuid = g_SupportedMemoryFormats;
|
|
hr = S_OK;
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
Trace(TEXT("Unknown Command (%d)"),lCommand);
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* Scan (MicroDriver Entry point)
|
|
*
|
|
* Called by the WIA driver to acquire data from the MicroDriver.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pScanInfo - SCANINFO structure used for settings
|
|
* lPhase - Current Scan phase, SCAN_FIRST, SCAN_NEXT, SCAN_FINISH...
|
|
* pBuffer - data buffer to be filled with scanned data
|
|
* lLength - Maximum length of pBuffer
|
|
* plReceived - Number of actual bytes written to pBuffer.
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
WIAMICRO_API HRESULT Scan(PSCANINFO pScanInfo, LONG lPhase, PBYTE pBuffer, LONG lLength, LONG *plReceived)
|
|
{
|
|
if(pScanInfo == NULL) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
INT i = 0;
|
|
|
|
Trace(TEXT("------ Scan Requesting %d ------"),lLength);
|
|
switch (lPhase) {
|
|
case SCAN_FIRST:
|
|
if (!SetScannerSettings(pScanInfo)) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
Trace(TEXT("SCAN_FIRST"));
|
|
|
|
g_PalIndex = 0;
|
|
g_bDown = FALSE;
|
|
|
|
//
|
|
// first phase
|
|
//
|
|
|
|
Trace(TEXT("Start Scan.."));
|
|
|
|
case SCAN_NEXT: // SCAN_FIRST will fall through to SCAN_NEXT (because it is expecting data)
|
|
|
|
//
|
|
// next phase
|
|
//
|
|
|
|
if(lPhase == SCAN_NEXT)
|
|
Trace(TEXT("SCAN_NEXT"));
|
|
|
|
//
|
|
// get data from the scanner and set plReceived value
|
|
//
|
|
|
|
//
|
|
// read data
|
|
//
|
|
|
|
switch(pScanInfo->DataType) {
|
|
case WIA_DATA_THRESHOLD:
|
|
|
|
//
|
|
// make buffer alternate black/White, for sample 1-bit data
|
|
//
|
|
|
|
memset(pBuffer,0,lLength);
|
|
memset(pBuffer,255,lLength/2);
|
|
break;
|
|
case WIA_DATA_GRAYSCALE:
|
|
|
|
//
|
|
// make buffer grayscale data, for sample 8-bit data
|
|
//
|
|
|
|
if(!g_bDown){
|
|
g_PalIndex+=10;
|
|
if(g_PalIndex > 255){
|
|
g_PalIndex = 255;
|
|
g_bDown = TRUE;
|
|
}
|
|
}
|
|
else {
|
|
g_PalIndex-=10;
|
|
if(g_PalIndex < 0){
|
|
g_PalIndex = 0;
|
|
g_bDown = FALSE;
|
|
}
|
|
}
|
|
memset(pBuffer,g_PalIndex,lLength);
|
|
break;
|
|
case WIA_DATA_COLOR:
|
|
|
|
//
|
|
// make buffer red, for sample color data
|
|
//
|
|
|
|
for (i = 0;i+2<lLength;i+=3) {
|
|
memset(pBuffer+i,255,1);
|
|
memset(pBuffer+(i+1),0,1);
|
|
memset(pBuffer+(i+2),0,1);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//
|
|
// test device always returns the exact amount of scanned data
|
|
//
|
|
|
|
*plReceived = lLength;
|
|
break;
|
|
case SCAN_FINISHED:
|
|
default:
|
|
Trace(TEXT("SCAN_FINISHED"));
|
|
|
|
//
|
|
// stop scanner, do not set lRecieved, or write any data to pBuffer. Those values
|
|
// will be NULL. This lPhase is only to allow you to stop scanning, and return the
|
|
// scan head to the HOME position. SCAN_FINISHED will be called always for regular scans, and
|
|
// for cancelled scans.
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* SetPixelWindow (MicroDriver Entry point)
|
|
*
|
|
* Called by the WIA driver to set the scan selection area to the MicroDriver.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pScanInfo - SCANINFO structure used for settings
|
|
* pValue - VAL structure used for settings
|
|
* x - X Position of scan rect (upper left x coordinate)
|
|
* y - Y Position of scan rect (upper left y coordinate)
|
|
* xExtent - Width of scan rect (in pixels)
|
|
* yExtent - Height of scan rect (in pixels)
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
WIAMICRO_API HRESULT SetPixelWindow(PSCANINFO pScanInfo, LONG x, LONG y, LONG xExtent, LONG yExtent)
|
|
{
|
|
if(pScanInfo == NULL) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
pScanInfo->Window.xPos = x;
|
|
pScanInfo->Window.yPos = y;
|
|
pScanInfo->Window.xExtent = xExtent;
|
|
pScanInfo->Window.yExtent = yExtent;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ReadRegistryInformation (helper)
|
|
*
|
|
* Called by the MicroDriver to Read registry information from the device's
|
|
* installed device section. The HKEY passed in will be closed by the host
|
|
* driver after CMD_INITIALIZE is completed.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* none
|
|
*
|
|
* Return Value:
|
|
*
|
|
* void
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
VOID ReadRegistryInformation(PVAL pValue)
|
|
{
|
|
HKEY hKey = NULL;
|
|
if(NULL != pValue->pHandle){
|
|
hKey = (HKEY)*pValue->pHandle;
|
|
|
|
//
|
|
// Open DeviceData section to read driver specific information
|
|
//
|
|
|
|
HKEY hOpenKey = NULL;
|
|
if (RegOpenKeyEx(hKey, // handle to open key
|
|
TEXT("DeviceData"), // address of name of subkey to open
|
|
0, // options (must be NULL)
|
|
KEY_QUERY_VALUE|KEY_READ, // just want to QUERY a value
|
|
&hOpenKey // address of handle to open key
|
|
) == ERROR_SUCCESS) {
|
|
|
|
DWORD dwWritten = sizeof(DWORD);
|
|
DWORD dwType = REG_DWORD;
|
|
|
|
LONG lSampleEntry = 0;
|
|
RegQueryValueEx(hOpenKey,
|
|
TEXT("Sample Entry"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&lSampleEntry,
|
|
&dwWritten);
|
|
Trace(TEXT("lSampleEntry Value = %d"),lSampleEntry);
|
|
} else {
|
|
Trace(TEXT("Could not open DeviceData section"));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* InitScannerDefaults (helper)
|
|
*
|
|
* Called by the MicroDriver to Initialize the SCANINFO structure
|
|
*
|
|
* Arguments:
|
|
*
|
|
* none
|
|
*
|
|
* Return Value:
|
|
*
|
|
* void
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID InitScannerDefaults(PSCANINFO pScanInfo)
|
|
{
|
|
|
|
pScanInfo->ADF = 0; // set to no ADF in Test device
|
|
pScanInfo->RawDataFormat = WIA_PACKED_PIXEL;
|
|
pScanInfo->RawPixelOrder = WIA_ORDER_BGR;
|
|
pScanInfo->bNeedDataAlignment = TRUE;
|
|
|
|
pScanInfo->SupportedCompressionType = 0;
|
|
pScanInfo->SupportedDataTypes = SUPPORT_BW|SUPPORT_GRAYSCALE|SUPPORT_COLOR;
|
|
|
|
pScanInfo->BedWidth = 8500; // 1000's of an inch (WIA compatible unit)
|
|
pScanInfo->BedHeight = 11000; // 1000's of an inch (WIA compatible unit)
|
|
|
|
pScanInfo->OpticalXResolution = 300;
|
|
pScanInfo->OpticalYResolution = 300;
|
|
|
|
pScanInfo->IntensityRange.lMin = -127;
|
|
pScanInfo->IntensityRange.lMax = 127;
|
|
pScanInfo->IntensityRange.lStep = 1;
|
|
|
|
pScanInfo->ContrastRange.lMin = -127;
|
|
pScanInfo->ContrastRange.lMax = 127;
|
|
pScanInfo->ContrastRange.lStep = 1;
|
|
|
|
// Scanner settings
|
|
pScanInfo->Intensity = 0;
|
|
pScanInfo->Contrast = 0;
|
|
|
|
pScanInfo->Xresolution = 150;
|
|
pScanInfo->Yresolution = 150;
|
|
|
|
pScanInfo->Window.xPos = 0;
|
|
pScanInfo->Window.yPos = 0;
|
|
pScanInfo->Window.xExtent = (pScanInfo->Xresolution * pScanInfo->BedWidth)/1000;
|
|
pScanInfo->Window.yExtent = (pScanInfo->Yresolution * pScanInfo->BedHeight)/1000;
|
|
|
|
// Scanner options
|
|
pScanInfo->DitherPattern = 0;
|
|
pScanInfo->Negative = 0;
|
|
pScanInfo->Mirror = 0;
|
|
pScanInfo->AutoBack = 0;
|
|
pScanInfo->ColorDitherPattern = 0;
|
|
pScanInfo->ToneMap = 0;
|
|
pScanInfo->Compression = 0;
|
|
|
|
// Image Info
|
|
pScanInfo->DataType = WIA_DATA_GRAYSCALE;
|
|
pScanInfo->WidthPixels = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos);
|
|
|
|
switch(pScanInfo->DataType) {
|
|
case WIA_DATA_THRESHOLD:
|
|
pScanInfo->PixelBits = 1;
|
|
break;
|
|
case WIA_DATA_COLOR:
|
|
pScanInfo->PixelBits = 24;
|
|
break;
|
|
case WIA_DATA_GRAYSCALE:
|
|
default:
|
|
pScanInfo->PixelBits = 8;
|
|
break;
|
|
}
|
|
|
|
pScanInfo->WidthBytes = pScanInfo->Window.xExtent * (pScanInfo->PixelBits/8);
|
|
pScanInfo->Lines = pScanInfo->Window.yExtent;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* SetScannerSettings (helper)
|
|
*
|
|
* Called by the MicroDriver to set the values stored in the SCANINFO structure
|
|
* to the actual device.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* none
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* TRUE - Success, FALSE - Failure
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL SetScannerSettings(PSCANINFO pScanInfo)
|
|
{
|
|
if(pScanInfo->DataType == WIA_DATA_THRESHOLD) {
|
|
pScanInfo->PixelBits = 1;
|
|
pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/7);
|
|
|
|
//
|
|
// Set data type to device
|
|
//
|
|
|
|
// if the set fails..
|
|
// return FALSE;
|
|
}
|
|
else if(pScanInfo->DataType == WIA_DATA_GRAYSCALE) {
|
|
pScanInfo->PixelBits = 8;
|
|
pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/8);
|
|
|
|
//
|
|
// Set data type to device
|
|
//
|
|
|
|
// if the set fails..
|
|
// return FALSE;
|
|
|
|
}
|
|
else {
|
|
pScanInfo->PixelBits = 24;
|
|
pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/8);
|
|
|
|
//
|
|
// Set data type to device
|
|
//
|
|
|
|
// if the set fails..
|
|
// return FALSE;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
Trace(TEXT("ScanInfo"));
|
|
Trace(TEXT("x res = %d"),pScanInfo->Xresolution);
|
|
Trace(TEXT("y res = %d"),pScanInfo->Yresolution);
|
|
Trace(TEXT("bpp = %d"),pScanInfo->PixelBits);
|
|
Trace(TEXT("xpos = %d"),pScanInfo->Window.xPos);
|
|
Trace(TEXT("ypos = %d"),pScanInfo->Window.yPos);
|
|
Trace(TEXT("xext = %d"),pScanInfo->Window.xExtent);
|
|
Trace(TEXT("yext = %d"),pScanInfo->Window.yExtent);
|
|
#endif
|
|
|
|
//
|
|
// send other values to device, use the values set in pScanInfo to set them to your
|
|
// device.
|
|
//
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* InitializeScanner (helper)
|
|
*
|
|
* Called by the MicroDriver to Iniitialize any device specific operations
|
|
*
|
|
* Arguments:
|
|
*
|
|
* none
|
|
*
|
|
* Return Value:
|
|
*
|
|
* TRUE - Success, FALSE - Failure
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL InitializeScanner(PSCANINFO pScanInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Do any device initialization here...
|
|
// The test device does not need any.
|
|
//
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CheckButtonStatus (helper)
|
|
*
|
|
* Called by the MicroDriver to Set the current Button pressed value.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pValue - VAL structure used for settings
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* VOID
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
|
|
VOID CheckButtonStatus(PVAL pValue)
|
|
{
|
|
//
|
|
// Button Polling is done here...
|
|
//
|
|
|
|
//
|
|
// Check your device for button presses
|
|
//
|
|
|
|
LONG lButtonValue = 0;
|
|
|
|
GetButtonPress(&lButtonValue);
|
|
switch (lButtonValue) {
|
|
case 1:
|
|
pValue->pGuid = (GUID*) &guidScanButton;
|
|
Trace(TEXT("Scan Button Pressed!"));
|
|
break;
|
|
default:
|
|
pValue->pGuid = (GUID*) &GUID_NULL;
|
|
break;
|
|
}
|
|
}
|
|
/**************************************************************************\
|
|
* GetInterruptEvent (helper)
|
|
*
|
|
* Called by the MicroDriver to handle USB interrupt events.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pValue - VAL structure used for settings
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT GetInterruptEvent(PVAL pValue)
|
|
{
|
|
//
|
|
// Below is a simple example of how DeviceIOControl() can be used to
|
|
// determine interrupts with a USB device.
|
|
//
|
|
// The test device does not support events,
|
|
// So this should not be called.
|
|
//
|
|
|
|
BYTE InterruptData;
|
|
DWORD dwIndex;
|
|
DWORD dwError;
|
|
|
|
OVERLAPPED Overlapped;
|
|
ZeroMemory( &Overlapped, sizeof( Overlapped ));
|
|
Overlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
|
|
|
|
HANDLE hEventArray[2] = {pValue->handle, Overlapped.hEvent};
|
|
BOOL fLooping = TRUE;
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// use the Handle created in CMD_INITIALIZE.
|
|
//
|
|
|
|
HANDLE InterruptHandle = pValue->pScanInfo->DeviceIOHandles[1];
|
|
|
|
while (fLooping) {
|
|
|
|
//
|
|
// Set the wait event, for the interrupt
|
|
//
|
|
|
|
bRet = DeviceIoControl( InterruptHandle,
|
|
IOCTL_WAIT_ON_DEVICE_EVENT,
|
|
NULL,
|
|
0,
|
|
&InterruptData,
|
|
sizeof(InterruptData),
|
|
&dwError,
|
|
&Overlapped );
|
|
|
|
if ( bRet || ( !bRet && ( ::GetLastError() == ERROR_IO_PENDING ))) {
|
|
|
|
//
|
|
// Wait for the event to happen
|
|
//
|
|
|
|
dwIndex = WaitForMultipleObjects( 2,
|
|
hEventArray,
|
|
FALSE,
|
|
INFINITE );
|
|
|
|
//
|
|
// Trap the result of the event
|
|
//
|
|
|
|
switch ( dwIndex ) {
|
|
case WAIT_OBJECT_0+1:
|
|
DWORD dwBytesRet;
|
|
bRet = GetOverlappedResult( InterruptHandle, &Overlapped, &dwBytesRet, FALSE );
|
|
|
|
if ( dwBytesRet ) {
|
|
|
|
//
|
|
// assign the corresponding button GUID to the *pValue->pGuid
|
|
// member., and Set the event.
|
|
//
|
|
|
|
// Change detected - signal
|
|
if (*pValue->pHandle != INVALID_HANDLE_VALUE) {
|
|
switch ( InterruptData ) {
|
|
case 1:
|
|
*pValue->pGuid = guidScanButton;
|
|
Trace(TEXT("Scan Button Pressed!"));
|
|
break;
|
|
default:
|
|
*pValue->pGuid = GUID_NULL;
|
|
break;
|
|
}
|
|
Trace(TEXT("Setting This Event by Handle %d"),*pValue->pHandle);
|
|
|
|
//
|
|
// signal the event, after a button GUID was assigned.
|
|
//
|
|
|
|
SetEvent(*pValue->pHandle);
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
// reset the overlapped event
|
|
//
|
|
|
|
ResetEvent( Overlapped.hEvent );
|
|
break;
|
|
|
|
case WAIT_OBJECT_0:
|
|
// Fall through
|
|
default:
|
|
fLooping = FALSE;
|
|
}
|
|
}
|
|
else {
|
|
dwError = ::GetLastError();
|
|
break;
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* GetButtonPress (helper)
|
|
*
|
|
* Called by the MicroDriver to set the actual button value pressed
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pButtonValue - actual button pressed
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID GetButtonPress(LONG *pButtonValue)
|
|
{
|
|
|
|
//
|
|
// This where you can set your button value
|
|
//
|
|
|
|
pButtonValue = 0;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* GetButtonCount (helper)
|
|
*
|
|
* Called by the MicroDriver to get the number of buttons a device supports
|
|
*
|
|
* Arguments:
|
|
*
|
|
* none
|
|
*
|
|
* Return Value:
|
|
*
|
|
* LONG - number of supported buttons
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
LONG GetButtonCount()
|
|
{
|
|
LONG ButtonCount = 0;
|
|
|
|
//
|
|
// Since the test device does not have a button,
|
|
// set this value to 0. For a real device with a button,
|
|
// set (LONG ButtonCount = 1;)
|
|
//
|
|
|
|
//
|
|
// determine the button count of your device
|
|
//
|
|
|
|
return ButtonCount;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* GetOLDSTRResourceString (helper)
|
|
*
|
|
* Called by the MicroDriver to Load a resource string in OLESTR format
|
|
*
|
|
* Arguments:
|
|
*
|
|
* lResourceID - String resource ID
|
|
* ppsz - Pointer to a OLESTR to be filled with the loaded string
|
|
* value
|
|
* bLocal - Possible, other source for loading a resource string.
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HRESULT GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
TCHAR szStringValue[255];
|
|
if(bLocal) {
|
|
|
|
//
|
|
// We are looking for a resource in our own private resource file
|
|
//
|
|
|
|
INT NumTCHARs = LoadString(g_hInst,lResourceID,szStringValue,sizeof(szStringValue));
|
|
DWORD dwError = GetLastError();
|
|
|
|
if (NumTCHARs <= 0) {
|
|
|
|
#ifdef UNICODE
|
|
Trace(TEXT("NumTCHARs = %d dwError = %d Resource ID = %d (UNICODE)szString = %ws"),
|
|
NumTCHARs,
|
|
dwError,
|
|
lResourceID,
|
|
szStringValue);
|
|
#else
|
|
Trace(TEXT("NumTCHARs = %d dwError = %d Resource ID = %d (ANSI)szString = %s"),
|
|
NumTCHARs,
|
|
dwError,
|
|
lResourceID,
|
|
szStringValue);
|
|
#endif
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
//
|
|
// NOTE: caller must free this allocated BSTR
|
|
//
|
|
|
|
#ifdef UNICODE
|
|
|
|
*ppsz = NULL;
|
|
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(szStringValue));
|
|
if(*ppsz != NULL) {
|
|
wcscpy(*ppsz,szStringValue);
|
|
} else {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
#else
|
|
WCHAR wszStringValue[255];
|
|
ZeroMemory(wszStringValue,sizeof(wszStringValue));
|
|
|
|
//
|
|
// convert szStringValue from char* to unsigned short* (ANSI only)
|
|
//
|
|
|
|
MultiByteToWideChar(CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
szStringValue,
|
|
lstrlenA(szStringValue)+1,
|
|
wszStringValue,
|
|
(sizeof(wszStringValue)/sizeof(WCHAR)));
|
|
|
|
*ppsz = NULL;
|
|
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(wszStringValue));
|
|
if(*ppsz != NULL) {
|
|
wcscpy(*ppsz,wszStringValue);
|
|
} else {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
#endif
|
|
|
|
} else {
|
|
|
|
//
|
|
// looking another place for resources??
|
|
//
|
|
|
|
hr = E_NOTIMPL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* Trace
|
|
*
|
|
* Called by the MicroDriver to output strings to a debugger
|
|
*
|
|
* Arguments:
|
|
*
|
|
* format - formatted string to output
|
|
*
|
|
*
|
|
* Return Value:
|
|
*
|
|
* VOID
|
|
*
|
|
* History:
|
|
*
|
|
* 1/20/2000 Original Version
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID Trace(LPCTSTR format,...)
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
TCHAR Buffer[1024];
|
|
va_list arglist;
|
|
va_start(arglist, format);
|
|
wvsprintf(Buffer, format, arglist);
|
|
va_end(arglist);
|
|
OutputDebugString(Buffer);
|
|
OutputDebugString(TEXT("\n"));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|