📄 driver.cpp
字号:
/*****************************************************************************
M+
Copyright (c) 1998,1999 by National Semiconductor
All Rights Reserved.
M-
*****************************************************************************/
// File: Driver.cpp
//
#include "stdafx.h"
#include "driver.h"
#include <sti.h> // Still Image services
#include "usbscan.h" // STI USB Interface
#include <Winioctl.h> // IOCTL codes and Macros
#include "..\NSCStiu\NscUsbIO.h"
/*****************************************************************************
Global still image information
*****************************************************************************/
PSTI g_pSti = NULL; // handle to STI subsystem
PVOID g_pStiInfo = NULL; // STI device info buffer
PSTI_DEVICE_INFORMATION g_pStiInfoPtr = NULL; // pointer to device in pStiBuffer
int g_nStiNumber = 0; // 0 based index into g_pStiInfo
DWORD g_dwStiTotal = 0; // total number of STI devices found
PSTIDEVICE g_pStiDevice = NULL; // STI device being used
HANDLE g_hEvent = INVALID_HANDLE_VALUE;
// Interrupt event handle
/*****************************************************************************
Module specific Consts and # Defines
*****************************************************************************/
const LPWSTR MERLIN_DEVICE1 = L"LM9831 USB Scanner";
const LPWSTR MERLIN_DEVICE2 = L"LM9832 USB Scanner";
const LPWSTR MERLIN_DEVICE3 = L"TravelScan FS531";
const LPWSTR MERLIN_MANUFACTURER = L"Syscan Inc";
// The first byte for the bulk register reads is the mode
// byte and this is bit mapped
// Bit 0 , 1 - Read, 0 - Write
// Bit 1 , 1 - Inc, 0 - No Inc
const BYTE MODE_INC_READ = 0x03;
const BYTE MODE_NOINC_READ = 0x01;
const BYTE MODE_INC_WRITE = 0x02;
const BYTE MODE_NOINC_WRITE = 0x00;
#define COMMAND_BYTE_COUNT 4
#define LOCK_TIMEOUT 2000
/*****************************************************************************
Private STI api helper method prototypes
*****************************************************************************/
HRESULT StiImageRelease();
HRESULT StiDeviceRelease();
HRESULT StiWriteErrLog(DWORD,LPCWSTR);
/*****************************************************************************
CDriver Implementation
*****************************************************************************/
//
// Construct of class CDriver
//
CDriver::CDriver()
{
g_hEvent = INVALID_HANDLE_VALUE;
}
//
// Function CDriver destructor
//
CDriver::~CDriver()
{
CloseDriver();
}
//
// Function to initialize device driver
//
BOOL CDriver::InitDriver(void)
{
HRESULT hres = STI_OK;
// Close the driver if it has been already opened
CloseDriver();
//
// 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
&g_pSti, // pointer to IStillImage interface
NULL // pointer to controlling unknown of OLE aggregation
);
if (FAILED(hres))
return false;
// Get the device list and try to locate our device
DWORD dwCounter;
// Enumerate devices
g_dwStiTotal = 0;
g_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 = g_pSti->GetDeviceList(
NULL, // Type (reserved, use NULL)
NULL, // Flags (reserved, use NULL)
&g_dwStiTotal, // address of variable to return number of devices found
&g_pStiInfo // STI device info buffer
);
if (! SUCCEEDED(hres))
return false;
//
// Compare the info on each device found with the info for our
// device
//
for (dwCounter = 0,g_pStiInfoPtr = (PSTI_DEVICE_INFORMATION) g_pStiInfo;
dwCounter < g_dwStiTotal;
dwCounter++, g_pStiInfoPtr++)
{
// If the manufacturer Id matches and the device is either the Merlin
// I Scanner (LM9831) or the Merlin II scanner (LM9832) then we have
// found a match for our device
if (!wcsicmp(g_pStiInfoPtr->pszVendorDescription, MERLIN_MANUFACTURER) &&
( !wcsicmp(g_pStiInfoPtr->pszDeviceDescription, MERLIN_DEVICE1 )||
!wcsicmp(g_pStiInfoPtr->pszDeviceDescription, MERLIN_DEVICE2 )||
!wcsicmp(g_pStiInfoPtr->pszDeviceDescription, MERLIN_DEVICE3)
) )
{
//
// Open the device - it is now pointed to by g_pStiInfoPtr
// The CreateDevice interface creates an IStiDevice object.
// The IStiDevice object provides access to the IStiDevice interface
// and device specific Imaging functionality.
//
hres = g_pSti->CreateDevice(
g_pStiInfoPtr->szDeviceInternalName, // internal device name
STI_DEVICE_CREATE_STATUS, // device creation mode
&g_pStiDevice, // pointer where IStiDevice object is to be stored
NULL ); // pointer to controlling unknown of OLE aggregation
if (SUCCEEDED(hres)) return true;
}
}
return false;
}
// Close Driver
BOOL CDriver::CloseDriver()
{
HRESULT hres = STI_OK;
// We dont care if this fails we still
// have to close the STI Image Subsystem
// Storing the result just helps debugging
hres = StiDeviceRelease();
hres = StiImageRelease();
return SUCCEEDED(hres);
}
//Reg in
BOOL CDriver::RegIn(UCHAR Addr, UCHAR *pValue, UINT Len)
{
if (!g_pStiDevice)
return FALSE;
HRESULT hres = STI_OK;
IO_BLOCK stIoBlock;
stIoBlock.uOffset = Addr;
stIoBlock.uLength = Len;
stIoBlock.pbyData = pValue;
stIoBlock.uIndex = 0;
DWORD cbBytes = sizeof(UCHAR);
hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);
if (SUCCEEDED(hres))
{
hres = g_pStiDevice->RawReadCommand(&stIoBlock, &cbBytes, NULL);
g_pStiDevice->UnLockDevice();
}
return SUCCEEDED(hres);
}
//Reg out
BOOL CDriver::RegOut(UCHAR Addr,UCHAR* pValue, UINT Len)
{
if (!g_pStiDevice)
return FALSE;
HRESULT hres = STI_OK;
IO_BLOCK stIoBlock;
stIoBlock.uOffset = Addr;
stIoBlock.uLength = Len;
stIoBlock.pbyData = pValue;
stIoBlock.uIndex = 0;
DWORD cbBytes = sizeof(UCHAR);
hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);
if (SUCCEEDED(hres))
{
hres = g_pStiDevice->RawWriteCommand(&stIoBlock, cbBytes, NULL);
g_pStiDevice->UnLockDevice();
}
return SUCCEEDED(hres);
}
//Bulk in
BOOL CDriver::BulkIn(UCHAR Addr,UCHAR *pBuffer,UINT Len, bool bIncrement)
{
if (!g_pStiDevice)
return FALSE;
HRESULT hres = STI_OK;
// To read registers via the bulk in endpoint send the
// command byte stream on the Bulk out endpoint and then
// send in the read request on the bulk in endpoint
hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);
//must handle >= 64K size
const UINT Max_Bulk_In_Size=0xffff;
BYTE pCommandBytes[COMMAND_BYTE_COUNT];
DWORD cbBytes;
for (UINT i = 0; i < Len; i+=Max_Bulk_In_Size)
{
cbBytes = min(Max_Bulk_In_Size,Len-i);
if (SUCCEEDED(hres))
{
pCommandBytes[0] = bIncrement ? MODE_INC_READ : MODE_NOINC_READ;
pCommandBytes[1] = Addr+(bIncrement ? i : 0);
pCommandBytes[2] = (BYTE) (cbBytes >> 8);
pCommandBytes[3] = (BYTE) (cbBytes & 0xff);
hres = g_pStiDevice->RawWriteData(&pCommandBytes,
COMMAND_BYTE_COUNT,
NULL);
if (SUCCEEDED(hres) )
{
// cbBytes = 0; //TEST!!!!!!
hres = g_pStiDevice->RawReadData(&pBuffer[i], &cbBytes, NULL);
}
}
}
g_pStiDevice->UnLockDevice();
if (!SUCCEEDED(hres)) Reset();
return SUCCEEDED(hres);
}
//Bulk out
BOOL CDriver::BulkOut(UCHAR Addr,UCHAR *pBuffer,UINT Len, bool bIncrement)
{
if (!g_pStiDevice)
return FALSE;
HRESULT hres = STI_OK;
// To read registers via the bulk in endpoint send the
// command byte stream on the Bulk out endpoint and then
// send in the write request on the bulk out endpoint
hres = g_pStiDevice->LockDevice(LOCK_TIMEOUT);
const UINT Max_Bulk_Out_Size=60;
BYTE pCommandBytes[COMMAND_BYTE_COUNT+Max_Bulk_Out_Size];
DWORD cbBytes;
//must handle >= 60 size
for (UINT i = 0; i < Len; i+=Max_Bulk_Out_Size)
{
cbBytes = min(Max_Bulk_Out_Size,Len-i);
pCommandBytes[0] = bIncrement ? MODE_INC_WRITE : MODE_NOINC_WRITE;
pCommandBytes[1] = Addr+(bIncrement ? i : 0);
pCommandBytes[2] = (BYTE) (cbBytes >> 8);
pCommandBytes[3] = (BYTE) (cbBytes & 0xff);
for (UINT j = 0; j < cbBytes; j++)
pCommandBytes[COMMAND_BYTE_COUNT+j] = pBuffer[i+j];
if (SUCCEEDED(hres))
{
hres = g_pStiDevice->RawWriteData( &pCommandBytes,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -