📄 nscdevice.cpp
字号:
PARAMETERS:
LPVOID lpBuffer
LPDWORD lpdwNumberOfBytes
LPOVERLAPPED lpOverlapped
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::RawReadCommand(LPVOID lpBuffer,
LPDWORD lpdwNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
HRESULT hres = STI_OK;
if (m_bWHQLTest) return WHQLRawWriteReadTest();
// NSC_TRACE("In UsdNSCDevice::RawReadCommand");
if (INVALID_HANDLE_VALUE != m_DeviceDataHandle)
{
BOOL fRet = FALSE;
IO_BLOCK* pIoBlock = (IO_BLOCK*)lpBuffer;
// USed only when the overlapped structure passed in is not valid
OVERLAPPED stOverlapped;
bool bPrivateEvent(false);
if (lpOverlapped == NULL)
{
lpOverlapped = &stOverlapped;
ZeroMemory(lpOverlapped, sizeof(OVERLAPPED));
lpOverlapped->hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
bPrivateEvent = true;
}
m_dwLastOperationError = NOERROR;
fRet = ::DeviceIoControl(m_DeviceDataHandle,
(DWORD) IOCTL_READ_REGISTERS,
(PVOID) pIoBlock,
(DWORD) sizeof(IO_BLOCK),
(PVOID) pIoBlock->pbyData,
(DWORD) pIoBlock->uLength*sizeof(BYTE),
lpdwNumberOfBytes,
lpOverlapped);
if (!fRet)
{
hres = GetNscOverlappedResult( lpOverlapped,
NS_READ_CMD_TIMEOUT,
lpdwNumberOfBytes);
}
if (bPrivateEvent)
{
::CloseHandle(lpOverlapped->hEvent);
}
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
if (!SUCCEEDED(hres))
{
DeviceReset();
LogError("RawReadCommand",*lpdwNumberOfBytes,0,0,0,0,0,hres);
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::RawWriteCommand
PARAMETERS:
LPVOID lpBuffer
DWORD dwNumberOfBytes
LPOVERLAPPED lpOverlapped
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::RawWriteCommand( LPVOID lpBuffer,
DWORD dwNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
// NSC_TRACE("In UsdNSCDevice::RawWriteCommand");
HRESULT hres = STI_OK;
if (m_bWHQLTest) return WHQLRawWriteReadTest();
if (INVALID_HANDLE_VALUE != m_DeviceDataHandle)
{
BOOL fRet = FALSE;;
DWORD dwBytesReturned = 0;
// so we will verify this with the actual hardware
IO_BLOCK* pIoBlock = (IO_BLOCK*)lpBuffer;
// USed only when the overlapped structure passed in is not valid
OVERLAPPED stOverlapped;
bool bPrivateEvent(false);
if (lpOverlapped == NULL)
{
lpOverlapped = &stOverlapped;
ZeroMemory(lpOverlapped, sizeof(OVERLAPPED));
lpOverlapped->hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
bPrivateEvent = true;
}
fRet = ::DeviceIoControl(m_DeviceDataHandle,
(DWORD) IOCTL_WRITE_REGISTERS,
(PVOID) pIoBlock,
(DWORD) sizeof(IO_BLOCK),
NULL,
0,
&dwBytesReturned,
lpOverlapped);
if (!fRet)
{
hres = GetNscOverlappedResult( lpOverlapped,
NS_WRITE_CMD_TIMEOUT,
&dwBytesReturned);
}
if (bPrivateEvent)
{
::CloseHandle(lpOverlapped->hEvent);
}
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
if (!SUCCEEDED(hres))
{
DeviceReset();
LogError("RawWriteCommand",dwNumberOfBytes,0,0,0,0,0,hres);
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::Initialize
PARAMETERS:
PSTIDEVICECONTROL pDcb
DWORD dwStiVersion
HKEY hParametersKey
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::Initialize(PSTIDEVICECONTROL pDcb,
DWORD dwStiVersion,
HKEY hParametersKey )
{
NSC_TRACE("In UsdNSCDevice::Initialize");
HRESULT hres = STI_OK;
if (!pDcb)
{
return STIERR_INVALID_PARAM;
}
// Before creating the mutxt it is necessary that we create
// a NULL DACL for the security descriptor if this code is running
// on W2k - otherwise we will use a NULL pointer for the
// security attributes
SECURITY_ATTRIBUTES sa;
{
char bSecurity[SECURITY_DESCRIPTOR_MIN_LENGTH];
memset(bSecurity,0,SECURITY_DESCRIPTOR_MIN_LENGTH);
PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR) bSecurity;
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
WriteToLog( STI_TRACE_ERROR,
L"%s : %s : 0x%X", // Message, Error, Code
L"UsdNSCDevice::Initializing the SD failed",
L"Device not Initialized in Thread (id)",
::GetCurrentThreadId()) ;
return STIERR_GENERIC;
}
// Add a NULL DACL to the security descriptor..
if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE))
{
WriteToLog( STI_TRACE_ERROR,
L"%s : %s : 0x%X", // Message, Error, Code
L"UsdNSCDevice::Setting the NULL DACL failed",
L"Device not Initialized in Thread (id)",
::GetCurrentThreadId()) ;
return STIERR_GENERIC;
}
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = TRUE;
}
// Create the mutex object that will be used for synchronizing access
// to the scanner
m_hMutex = CreateMutex(&sa, FALSE, NSCUSD_MUTEX);
if (m_hMutex == NULL)
{
m_dwLastOperationError = ::GetLastError();
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
return hres;
}
// Increment the refcount for the device control object that has
// been passed in to us.
m_pDcb = pDcb;
m_pDcb->AddRef();
hres = OpenDevice(GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, sa);
if (SUCCEEDED(hres))
{
// Get the currenlty selected event settings (which bits
// to recognize ) and other parameters from the registry
LoadDeviceData(hParametersKey);
// If the scanner is in reset mode bring it out of reset mode
hres = ResetModeCheckAndClear();
}
return hres;
}
///////////////////////////////////////////////////////////////
// Helper Functions
///////////////////////////////////////////////////////////////
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::OpenDevice
PARAMETERS:
DWORD dwAccess
DWORD dwShare
SECURITY_ATTRIBUTES& sa
RETURN VALUE:
HRESULT
NOTES:
*******************************************************************************/
HRESULT UsdNSCDevice::OpenDevice(DWORD dwAccess, DWORD dwShare,
SECURITY_ATTRIBUTES& sa)
{
NSC_TRACE("In UsdNSCDevice::OpenDevice");
m_bWHQLTest=false; //for tracking WHQL test
if (!m_pDcb)
{
return STIERR_NOT_INITIALIZED;
}
HRESULT hres = STI_OK;
UINT uiNameLen = 0;
WCHAR szDeviceNameW[MAX_PATH];
*szDeviceNameW = L'\0';
// Get the name of the device port we need to open
hres = m_pDcb->GetMyDevicePortName(szDeviceNameW,sizeof(szDeviceNameW)/sizeof(WCHAR));
if (!SUCCEEDED(hres) || !*szDeviceNameW) {
return hres;
}
// Convert name to SBCS for use in WIn95
uiNameLen = WideCharToMultiByte(CP_ACP, 0, szDeviceNameW, -1, NULL, NULL, 0, 0);
if (!uiNameLen) {
return STIERR_INVALID_PARAM;
}
// If name already exists delete it
delete m_pszDeviceNameA;
m_pszDeviceNameA = new CHAR[uiNameLen+1];
if (!m_pszDeviceNameA) {
return STIERR_INVALID_PARAM;
}
WideCharToMultiByte(CP_ACP, 0, szDeviceNameW, -1, m_pszDeviceNameA, uiNameLen, 0, 0);
// Open device using the CreateFile API Call
m_DeviceDataHandle = CreateFileA( m_pszDeviceNameA,
dwAccess, // Access mask
dwShare, // Share mode
NULL, // SA
OPEN_EXISTING, // Create disposition
FILE_FLAG_OVERLAPPED, // Attributes
NULL );
m_dwLastOperationError = ::GetLastError();
hres = (m_DeviceDataHandle != INVALID_HANDLE_VALUE) ?
S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,m_dwLastOperationError);
if (SUCCEEDED(hres))
{
//Create the bulk in mutex
m_hKickStartMutex = CreateMutex(&sa, FALSE, NSCUSD_KICKSTART_MUTEX);
if (m_hKickStartMutex == NULL)
{
m_dwLastOperationError = ::GetLastError();
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
return hres;
}
//Create unique polling mutex name based on index and port
CHAR device_name[MAX_PATH];
strcpy(device_name,m_pszDeviceNameA);
for (UINT i = 0; device_name[i]; i++)
if (device_name[i] == '\\') device_name[i] = '_';
for (int index = 0; index < NS_MAX_OPEN_APPS; index++)
{
CHAR mutex_name[MAX_PATH];
sprintf(mutex_name,"%s%s%d",
NSCUSD_POLLING_MUTEX,device_name,index);
::SetLastError(0);
m_hPollingMutex[index] = CreateMutex(&sa, FALSE, mutex_name);
if (m_hPollingMutex[index] == NULL)
{
m_dwLastOperationError = ::GetLastError();
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
return hres;
}
//if mutex already exists, block polling
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
if (::WaitForSingleObject(m_hPollingMutex[index], 0)
== WAIT_OBJECT_0) break; //have ownership, done
}
}
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::CloseDevice
PARAMETERS:
RETURN VALUE:
HRESULT
NOTES:
*******************************************************************************/
HRESULT UsdNSCDevice::CloseDevice()
{
NSC_TRACE("In UsdNSCDevice::CloseDevice");
m_bWHQLTest=false; //for tracking WHQL test
if( INVALID_HANDLE_VALUE != m_DeviceDataHandle )
{
CloseHandle( m_DeviceDataHandle );
m_DeviceDataHandle = INVALID_HANDLE_VALUE;
}
return STI_OK;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::GetNscOverlappedResult
PARAMETERS:
LPOVERLAPPED lpOverlapped
DWORD dwTimeout
LPDWORD lpBytesRead
RETURN VALUE:
NOTES:
*******************************************************************************/
HRESULT UsdNSCDevice::GetNscOverlappedResult(LPOVERLAPPED lpOverlapped,
DWORD dwTimeout,
LPDWORD lpBytesRead)
{
HRESULT hres = STI_OK;
m_dwLastOperationError = ::GetLastError();
if (m_dwLastOperationError == ERROR_IO_PENDING)
{
// Wait for the overlapped operation to complete
if (::WaitForSingleObject(lpOverlapped->hEvent, dwTimeout)
== WAIT_TIMEOUT)
{
// Timeout error
hres = STIERR_GENERIC;
}
else
{
// Get the actual number of bytes read using the
// GetOverlappedResult API
DWORD dwBytesRead = 0;
if (::GetOverlappedResult(m_DeviceDataHandle,
lpOverlapped,
&dwBytesRead,
FALSE))
{
ResetEvent(lpOverlapped->hEvent);
*lpBytesRead = dwBytesRead;
}
else
{
m_dwLastOperationError = ::GetLastError();
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
}
}
}
else
{
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
InterruptThreadFunc
PARAMETERS:
LPVOID lpParameter
RETURN VALUE:
VOID
NOTES:
*******************************************************************************/
VOID InterruptThreadFunc(LPVOID lpParameter)
{
// NSC_TRACE("In InterruptThreadFunc - Interrupt thread started");
::CoInitializeEx(NULL, COINIT_MULTITHREADED);
UsdNSCDevice *pThisDevice = (UsdNSCDevice*)lpParameter;
pThisDevice->ListenForInterrupts();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -