⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nscdevice.cpp

📁 美国国家半导体公司的扫描仪芯片LM9833的驱动程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            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 + -