📄 nscdevice.cpp
字号:
m_guidLastEvent = GUID_NULL;
}
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::GetNotificationData
PARAMETERS:
LPSTINOTIFY pBuffer
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
// SYNCHRONIZED
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::GetNotificationData( LPSTINOTIFY pBuffer )
{
NSC_TRACE("In UsdNSCDevice::GetNotificationData");
HRESULT hres = STI_OK;
TAKE_CRIT_SECT t(m_cs);
//
// If we have notification ready - return it's guid
//
if (!IsEqualIID(m_guidLastEvent,GUID_NULL))
{
pBuffer->guidNotificationCode = m_guidLastEvent;
m_guidLastEvent = GUID_NULL;
pBuffer->dwSize = sizeof(STINOTIFY);
}
else
{
hres = STIERR_NOEVENTS;
}
return hres ;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::Escape
PARAMETERS:
STI_RAW_CONTROL_CODE EscapeFunction
LPVOID pInData
DWORD cbInDataSize
LPVOID pOutData
DWORD cbOutDataSize
LPDWORD pcbActualData
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::Escape( STI_RAW_CONTROL_CODE EscapeFunction,
LPVOID pInData,
DWORD cbInDataSize,
LPVOID pOutData,
DWORD cbOutDataSize,
LPDWORD pcbActualData )
{
// NSC_TRACE("In UsdNSCDevice::Escape");
if (INVALID_HANDLE_VALUE == m_DeviceDataHandle)
{
return STIERR_NOT_INITIALIZED;
}
HRESULT hres = STI_OK;
m_dwLastOperationError = NOERROR;
m_bWHQLTest=false; //for tracking WHQL test
switch (EscapeFunction)
{
case 0:
m_bWHQLTest=true; //for tracking WHQL test
break; // for WHQL test
case IOCTL_ENABLE_REMOTEWAKEUP:
hres = SetRemoteWakeup(true);
break;
case IOCTL_DISABLE_REMOTEWAKEUP:
hres = SetRemoteWakeup(false);
break;
default :
{
// The escape command will be translated directly into an
// overlapped DeviceIOControl call
OVERLAPPED stOverlapped;
ZeroMemory(&stOverlapped, sizeof(OVERLAPPED));
stOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
BOOL fRet = ::DeviceIoControl( m_DeviceDataHandle,
EscapeFunction,
pInData,
cbInDataSize,
pOutData,
cbOutDataSize,
pcbActualData,
&stOverlapped );
if (!fRet)
{
hres = GetNscOverlappedResult( &stOverlapped,
NS_WRITE_CMD_TIMEOUT,
pcbActualData);
}
CloseHandle(stOverlapped.hEvent);
}
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::GetLastError
PARAMETERS:
LPDWORD pdwLastDeviceError
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
// SYNCHRONIZED
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::GetLastError( LPDWORD pdwLastDeviceError )
{
NSC_TRACE("In UsdNSCDevice::GetLastError");
HRESULT hres = STI_OK;
TAKE_CRIT_SECT t(m_cs);
if ( IsBadWritePtr( pdwLastDeviceError,4 ))
{
hres = STIERR_INVALID_PARAM;
}
else
{
*pdwLastDeviceError = m_dwLastOperationError;
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::GetLastErrorInfo
PARAMETERS:
STI_ERROR_INFO *pLastErrorInfo
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
// SYNCHRONIZED
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::GetLastErrorInfo(STI_ERROR_INFO *pLastErrorInfo)
{
NSC_TRACE("In UsdNSCDevice::GetLastErrorInfo");
HRESULT hres = STI_OK;
TAKE_CRIT_SECT t(m_cs);
if ( IsBadWritePtr( pLastErrorInfo,4 ))
{
hres = STIERR_INVALID_PARAM;
}
else
{
pLastErrorInfo->dwGenericError = m_dwLastOperationError;
pLastErrorInfo->dwVendorError = 0;
// Get the message string from the operating system
// for the error code
::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
m_dwLastOperationError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
pLastErrorInfo->szExtendedErrorText,
NS_MAX_ERRORSTRING,
NULL );
// pLastErrorInfo->szExtendedErrorText[0] = L'\0';
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::LockDevice
PARAMETERS:
VOID
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
// SYNCHRONIZED
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::LockDevice( VOID )
{
// NSC_TRACE("In UsdNSCDevice::LockDevice");
// The LockDevice function may be called from multiple processes
// at the same tiem to gain access to the scanner so it is necessary
// to use a synchronization mechanism that works across process
// so we use a named Mutex here to make sure that we can
// synchronize cross process access
HRESULT hres = STI_OK;
if (m_hMutex != NULL)
{
// Try to acquire the mutex within the timeout period
DWORD dwRetCode = ::WaitForSingleObject(m_hMutex, NS_MAX_LOCKTIMEOUT);
switch (dwRetCode)
{
case WAIT_ABANDONED:
//deliberate fallthrough
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
m_dwLastOperationError = hres = STIERR_DEVICE_LOCKED;
break;
case WAIT_FAILED:
m_dwLastOperationError = ::GetLastError();
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
break;
default:
hres = STIERR_GENERIC;
}
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::UnLockDevice
PARAMETERS:
VOID
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::UnLockDevice( VOID )
{
// NSC_TRACE("In UsdNSCDevice::UnLockDevice");
HRESULT hres = STI_OK;
if (m_hMutex != NULL)
{
hres = ::ReleaseMutex(m_hMutex) ? STI_OK : STIERR_GENERIC;
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
return hres;
}
BYTE bWrite[5];//TEST!!
DWORD dwWriteLen;//TEST!!
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::RawReadData
PARAMETERS:
LPVOID lpBuffer
LPDWORD lpdwNumberOfBytes
LPOVERLAPPED lpOverlapped
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::RawReadData( LPVOID lpBuffer,
LPDWORD lpdwNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
// NSC_TRACE("In UsdNSCDevice::RawReadData");
HRESULT hres = STI_OK;
if (m_bWHQLTest) return WHQLRawWriteReadTest();
DWORD Logct = *lpdwNumberOfBytes; //TEST!!!
if (INVALID_HANDLE_VALUE != m_DeviceDataHandle)
{
//mutex should always be available due to locks
if (::WaitForSingleObject(m_hKickStartMutex,m_dwKickStartTime) == WAIT_TIMEOUT)
{
hres = STIERR_GENERIC;
}
else
{
BOOL fRet = FALSE;
// 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 = ::ReadFile(m_DeviceDataHandle,
lpBuffer,
*lpdwNumberOfBytes,
lpdwNumberOfBytes,
lpOverlapped);
if (!fRet)
{
hres = GetNscOverlappedResult( lpOverlapped,
NS_READ_DATA_TIMEOUT,
lpdwNumberOfBytes);
}
if (bPrivateEvent)
{
::CloseHandle(lpOverlapped->hEvent);
}
ReleaseMutex(m_hKickStartMutex);
}
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
if (!SUCCEEDED(hres))
{
DeviceReset();
LogError("RawWriteData",dwWriteLen,bWrite[0],bWrite[1],bWrite[2],
bWrite[3],bWrite[4],0); //TEST!!!
BYTE b[5] = {0,0,0,0,0};
for (DWORD i = 0; i < Logct; i++)
b[i] = ((BYTE*)lpBuffer)[i];
LogError("RawReadData",Logct,b[0],b[1],b[2],b[3],b[4],hres); //TEST!!!
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::RawWriteData
PARAMETERS:
LPVOID lpBuffer
DWORD dwNumberOfBytes
LPOVERLAPPED lpOverlapped
RETURN VALUE:
STDMETHODIMP - This is a macro that indicates that we return HRESULT
NOTES:
*******************************************************************************/
STDMETHODIMP UsdNSCDevice::RawWriteData( LPVOID lpBuffer,
DWORD dwNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
// NSC_TRACE("In UsdNSCDevice::RawWriteData");
HRESULT hres = STI_OK;
if (m_bWHQLTest) return WHQLRawWriteReadTest();
dwWriteLen = dwNumberOfBytes; //TEST!!!
for (DWORD i = 0; i < 5; i++)
{
if (i < dwWriteLen) bWrite[i] = ((BYTE*)lpBuffer)[i]; //TEST!!!
else bWrite[i] = 0;
}
if (INVALID_HANDLE_VALUE != m_DeviceDataHandle)
{
BOOL fRet = FALSE;;
DWORD dwBytesReturned = 0;
// 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 = ::WriteFile(m_DeviceDataHandle,
lpBuffer,
dwNumberOfBytes,
&dwBytesReturned,
lpOverlapped);
if (!fRet)
{
hres = GetNscOverlappedResult( lpOverlapped,
NS_WRITE_DATA_TIMEOUT,
&dwBytesReturned);
}
if (bPrivateEvent)
{
::CloseHandle(lpOverlapped->hEvent);
}
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
if (!SUCCEEDED(hres))
{
DeviceReset();
LogError("RawWriteData",dwWriteLen,bWrite[0],bWrite[1],bWrite[2],
bWrite[3],bWrite[4],hres); //TEST!!!
}
return hres;
}
/*******************************************************************************
DESCRIPTION:
UsdNSCDevice::RawReadCommand
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -