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

📄 nscdevice.cpp

📁 美国国家半导体公司的扫描仪芯片LM9833的驱动程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:

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 + -