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

📄 bcamadapter.cpp

📁 BCAM 1394 Driver
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//-----------------------------------------------------------------------------
//  Company:  Basler Vision Technologies
//  Section:  Vision Components
//  Project:  1394 Driver
//  Subproject:  Bus Access Driver
//  $Header: BcamAdapter.cpp, 35, 06.07.2006 10:20:30, Nebelung, H.$
//-----------------------------------------------------------------------------
/**
  \file     BcamAdapter.cpp
  \brief   Implementation of the classes CBcamAdapter and CNode
 */
//-----------------------------------------------------------------------------


#include <stdafx.h>
#pragma warning( disable: 4786) //  identifier was truncated to '255' characters in the browser information
#pragma warning (disable: 4702) // unreachable code
#include "Bcam.h"
#include <setupapi.h>
#include <bacc_guid.h>
#include <BcamAdapter.h>
#ifndef BACC_GUID_INITIALIZED
#include <initguid.h>
#include <bacc_guid.h>
#endif

#include <malloc.h>
#include <assert.h>
#include <bitset>
using namespace std;
using namespace Bcam;

// we use the ATL implementation of InterlockedExchangePointer because of problems with the one in system headers
#if defined( _M_IX86 ) && ! defined(__ATLCONV_H__) || (_ATL_VER == 0x300)
#undef InterlockedExchangePointer
inline void* WINAPI InterlockedExchangePointer(void** pp, void* pNew) throw()
{
	return( reinterpret_cast<void*>( static_cast<long>( ::InterlockedExchange( reinterpret_cast<LONG*>( pp ), static_cast<LONG>( reinterpret_cast<long>( pNew ) ) ) ) ) );
}
#endif


enum {
  Topology = 123
};

struct /*Bcam::*/BcamAdapterOL
{
  OVERLAPPED ol;            ///< Win32-Api defined structure, needed for all calls
  Bcam::FunctionCode_t function;  ///< Function code to identify the function called
  BaccResGetTopology *pTopology;
  PVOID pContext;           ///< Pointer to user provided context 
};
//------------------------------------------------------------------------------
// static BcamOL* GetNewBcamBcamOL( FunctionCode_t func, PVOID pContext )
// Author: Hartmut nebelung
//------------------------------------------------------------------------------
/**
* \brief Create a BcamAdapterOL structure on the heap and initializes it.
*
* \param     func         The function code to identify the call.
* \param     pContext     The user defined context, may be NULL.
* \return    
*
* Returns an initialized BcamOL structure.
* 
*/
//------------------------------------------------------------------------------
static BcamAdapterOL* GetNewBcamAdapterOL( HANDLE hEvent, FunctionCode_t func, BaccResGetTopology *pRes, PVOID pContext )
{
  BcamAdapterOL* p = new BcamAdapterOL;
  if (NULL == p)
    throw BcamException( Bvc::ErrorNumber( E_OUTOFMEMORY ), _T( "GetNewBcamAdapterOL" ) );
  
  p->ol.hEvent = hEvent;
  p->ol.Internal = 0;
  p->ol.InternalHigh  = 0;
  p->ol.Offset = 0;
  p->ol.OffsetHigh = 0;
  p->pTopology = pRes;
  p->pContext = pContext;
  p->function = func;
  
  return p;
}

static BcamAdapterOL* GetNewBcamAdapterOL(  )
{
  BcamAdapterOL* p = new BcamAdapterOL;
  if (NULL == p)
    throw BcamException( Bvc::ErrorNumber( E_OUTOFMEMORY ), _T( "GetNewBcamAdapterOL" ) );
  
  p->ol.hEvent = NULL;
  p->ol.Internal = 0;
  p->ol.InternalHigh  = 0;
  p->ol.Offset = 0;
  p->ol.OffsetHigh = 0;
  p->pTopology = NULL;
  p->pContext = NULL;
  p->function = (FunctionCode_t) 0;
  
  return p;
}


// 1394api.h ++
  //
  // 1394 Add/Remove Virtual Device format
  //
  typedef struct _VIRT_DEVICE {
    ULONG           fulFlags;
    ULARGE_INTEGER  InstanceID;
    PSTR            DeviceID;
  } VIRT_DEVICE, *PVIRT_DEVICE;
// 1394api.h --

// 1394.h ++
//
// Definitions of Speed flags used throughout 1394 Bus APIs
//
#define SPEED_FLAGS_100                         0x01
#define SPEED_FLAGS_200                         0x02
#define SPEED_FLAGS_400                         0x04
#define SPEED_FLAGS_800                         0x08
#define SPEED_FLAGS_1600                        0x10
#define SPEED_FLAGS_3200                        0x20

#define SPEED_FLAGS_FASTEST                     0x80000000
// 1394.h --

// ntdd1394.h ++
#ifdef __cplusplus
extern "C" {
#endif

//
// registry definitions
//

#define BUS1394_VIRTUAL_DEVICE_LIST_KEY     L"Virtual Device List"
#define BUS1394_LOCAL_HOST_INSTANCE_KEY     L"LOCAL HOST EUI64"


//
// Various definitions
//

#define IOCTL_IEEE1394_API_REQUEST                  CTL_CODE( \
                                                FILE_DEVICE_UNKNOWN, \
                                                0x100, \
                                                METHOD_BUFFERED, \
                                                FILE_ANY_ACCESS \
                                                )

//
// IEEE 1394 Sbp2 Request packet.  It is how other
// device drivers communicate with the 1sbp2 trasnport.
//

typedef struct _IEEE1394_VDEV_PNP_REQUEST{

    ULONG fulFlags;
    ULONG Reserved;
    ULARGE_INTEGER InstanceId;
    UCHAR DeviceId;

} IEEE1394_VDEV_PNP_REQUEST,*PIEEE1394_VDEV_PNP_REQUEST;


typedef struct _IEEE1394_API_REQUEST {

    //
    // Holds the zero based Function number that corresponds to the request
    // that device drivers are asking the sbp2 port driver to carry out.
    //

    ULONG RequestNumber;

    //
    // Holds Flags that may be unique to this particular operation
    //

    ULONG Flags;

    //
    // Holds the structures used in performing the various 1394 APIs
    //

    union {

        IEEE1394_VDEV_PNP_REQUEST AddVirtualDevice;
        IEEE1394_VDEV_PNP_REQUEST RemoveVirtualDevice;

    } u;

} IEEE1394_API_REQUEST, *PIEEE1394_API_REQUEST;

//
// Request Number
//

#define IEEE1394_API_ADD_VIRTUAL_DEVICE             0x00000001
#define IEEE1394_API_REMOVE_VIRTUAL_DEVICE          0x00000002

//
// flags for the add/remove requests
//

#define IEEE1394_REQUEST_FLAG_UNICODE       0x00000001
#define IEEE1394_REQUEST_FLAG_PERSISTENT    0x00000002
#define IEEE1394_REQUEST_FLAG_USE_LOCAL_HOST_EUI        0x00000004

//
// definitions for the access/ownership 1394 scheme
//

#ifdef __cplusplus
}
#endif
// ntdd1394.h --
#ifndef TRACE
/// In case we are using WTL replace TRACE calls by AtlTrace
#define TRACE AtlTrace
#endif

#define E_MEMORY E_OUTOFMEMORY




//////////////////////////////////////////////////////////////////////
/// Possible values of port connection state
enum PortConnection 
{
  Not_Present         = 0,     ///< Port is not present
  Not_Connected       = 1,     ///< Port is not connected
  Connected_to_Parent = 2,     ///< Port is connected to parent
  Connected_to_Child  = 3      ///< Port is connected to child
};

//------------------------------------------------------------------------------
// static inline ULONG GetPortState( NODE *pn, size_t port )
// Author: HNebelun
//------------------------------------------------------------------------------
/**
 * \brief Connection state of a port
 *
 * \param     *pn   Pointer to the node array
 * \param     port  Number of the port
 * \return    
 *
 * connection state
 * 
 */
//------------------------------------------------------------------------------
static ULONG GetPortState( NODE *pn, size_t port )
{
  const unsigned _Nb = PORTS_PER_DWORD;
  const PULONG _A = pn->Ports;
  assert( port <= MAX_PORTS );

  return (_A[port / _Nb] >>  2 * (port % _Nb)) & PORT_MASK;
}

/////////////////////////////////////////////////////////////////////
/**
 * \brief Analyze result of device I/O control call
 *
 * \param     b result of a device I/O control call
 * \return    true if failed, false otherwise
 */
//------------------------------------------------------------------------------
inline bool FailedDevIO( BOOL b ) 
{
  return b == 0;
}

//------------------------------------------------------------------------------
// bool IsFullDeviceName(CString DeviceName)
// Author: 
// Date: 26.10.2002
//------------------------------------------------------------------------------
/**
 * \brief is a given device name a "full" device name, i.e. does it contain the driver interface GUID?
 * 
 * Check if a given device name is a full device name (as it is passed in by the plug and play manager) 
 * or if it is a friendly device name not containing the driver interface GUID
 *
 * \param     DeviceName device name to check
 * \return    true, if the device name is not a friendly device name
 *
 */
//------------------------------------------------------------------------------
static bool IsFullDeviceName(CString DeviceName)
{
	int first = DeviceName.Find('#');
	assert(first > 0);
	int l = DeviceName.GetLength();
	int second  = DeviceName.Right(l - (first+1)).Find('#') + first + 1;
	return(second > first);
}

//------------------------------------------------------------------------------
// CString FullDeviceName(CString DeviceName)
// Author: 
// Date: 8.1.2003
//------------------------------------------------------------------------------
/**
 * \brief given a friendly device name return a full device name
 *
 * Friendly device names don't contain the driver's interface GUID. This function 
 * converts a friendly device name into a full device name, 
 * as it is used by the system. 
 *
 * \param     DeviceName a friendly device name
 * \return    the full device name
 *
 */
//------------------------------------------------------------------------------
static CString FullDeviceName( CString DeviceName )
{

	if (!IsFullDeviceName( DeviceName ))
	{
		struct _GUID guid = GUID_BACC_DEVICE;
		CString guidString;
		guidString.Format( _T( "#{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}" ),
      guid.Data1,	guid.Data2, guid.Data3, 
		  guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], 
		  guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); 
		return _T( "\\\\?\\v1394#" ) + DeviceName + guidString;
	}
	else return DeviceName;
}
//------------------------------------------------------------------------------
// CString FriendlyDeviceName(CString DeviceName)
// Date: 26.10.2002
//------------------------------------------------------------------------------
/**
 * \brief Retrieves the friendly device name for a given full device name
 *
 * Friendly device names don't contain the driver's interface GUID. This 
 * function converts a full device named used by the system into a 
 * friendly device name
 *
 * \param   DeviceName the full device name
 * \return   the friendly device name 
 *
 */
//------------------------------------------------------------------------------
static CString FriendlyDeviceName( CString DeviceName )
{
	if (IsFullDeviceName( DeviceName ))
	{
		int first = DeviceName.Find('#');
		assert(first > 0);
		int l = DeviceName.GetLength();
		int second = DeviceName.Right(l - (first+1)).Find('#') + first + 1;
		assert(second > 0);
		int third = DeviceName.Right(l - (second+1)).Find('#') + second + 1;
		assert(third > 0);
		assert(DeviceName[third+1] == '{');
		return DeviceName.Left(third).Right(third-(first+1));
	}
	else return DeviceName;
}

using namespace std;
using namespace Bcam;

CTopology::CTopology( unsigned long initialSize )
: 
  m_pTopology( NULL ),
  m_pOL( NULL ),
  m_IoPending( false )
{
  m_Event.Create();
  SetSize( initialSize );
}

CTopology::~CTopology()
{
  delete []m_pTopology;
  delete m_pOL;
}
CTopology::operator HANDLE()
{
  return m_Event;
}

unsigned long CTopology::RequiredSize() const
{
  if (! m_pTopology)
    throw BcamException( Bvc::ErrorNumber( E_FAIL ), _T( "CTopology::RequiredSize" ) );

  return ((BaccResGetTopology*)m_pTopology)->Size;
}

CBcamAdapter* CTopology::Attach( CBcamAdapter* p )
{
  if (m_IoPending)
    throw BcamException( Bvc::ErrorNumber( E_UNEXPECTED ), _T( "CTopology::Attach" ) );
  return (CBcamAdapter*) InterlockedExchangePointer( (void**)&m_pAdapter, p );
}

CBcamAdapter* CTopology::Detach()
{
  if (m_IoPending)
    throw BcamException( Bvc::ErrorNumber( E_UNEXPECTED ), _T( "CTopology::Detach" ) );
  return Attach( NULL );
}

void CTopology::SetSize( unsigned long Size )
{
  if (m_pOL || m_IoPending)
    throw BcamException( Bvc::ErrorNumber( E_UNEXPECTED ), _T( "CTopology::SetSize" ) );

  if (Size < sizeof *m_pTopology)
    Size = sizeof *m_pTopology;

  void* pv = new BYTE[Size];
  delete m_pTopology;
  m_pTopology = (BaccResGetTopology*)pv;
  m_pTopology->Size = Size;
}

unsigned long CTopology::Wait( unsigned long Timeout ) const
{
  return WaitForSingleObject( m_Event, Timeout );
};

void CTopology::GetTreeRequest( void* pContext )
{
  if (!m_pTopology || m_pOL || m_IoPending || !m_pAdapter)
    throw BcamException( Bvc::ErrorNumber( E_UNEXPECTED ), _T( "CTopology::BuildTreeAsync" ) );

  m_pOL = m_pAdapter->GetTreeAsync( m_Event, m_pTopology, pContext );
  m_IoPending = true;

}

CNode* CTopology::GetTreeResponse( void**ppContext )
{
  if (! m_IoPending || !m_pAdapter)
    throw BcamException( Bvc::ErrorNumber( E_UNEXPECTED ), _T( "CTopology::GetTree" ) );

  CNode *p = m_pAdapter->GetTree( m_pOL, ppContext );
  
  m_IoPending = false;
  delete m_pOL;
  m_pOL = NULL;

  if (m_pTopology->Status)
    return NULL; // wrong buffer size
  else
    return p;
}

void CTopology::Cancel()
{
  BOOL ret = CancelIo( m_pAdapter->GetDevice() );
  if (FailedDevIO( ret ))
    throw BcamException( ::GetLastError(), _T( "CTopology::Cancel" ) );
}


//------------------------------------------------------------------------------
// class CBcamDevCreator
// Author: HNebelun
//------------------------------------------------------------------------------
/**
 * \brief   Utility class helping to create Bcam Adapters
 *
 * The intention is to use a sigleton object, that creates for each 1394Bus object
 * a 1394 Basler Virtual Device on construction and destroys them on destruction.
 * The virtual devices can then be found in the DeviceManager in the 1394 Basler 
 * Virtual Device class entry.
 */
//------------------------------------------------------------------------------
class CBcamDevCreator
{
public:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -