📄 bcamadapter.cpp
字号:
{
ret = GetOverlappedResult( m_hDevice, &pOl->ol, &numBytes, true );
err = GetLastError();
}
delete pOl;
if (FailedDevIO( ret ) || numBytes < sizeof res)
throw BcamException( err );
return res.Data;
}
//------------------------------------------------------------------------------
// void CBcamAdapter::WriteQuad( ULONG Id, LARGE_INTEGER Adr, ULONG Data )
// Author: HNebelun
//------------------------------------------------------------------------------
/**
* \brief Write a quadlet on the local bus
*
* \param Id Identifier of the device
* \param Adr Offset of the register
* \param Data Value to write
* \throw BcamException on failure
*/
//------------------------------------------------------------------------------
void CBcamAdapter::WriteQuad( ID Id, LARGE_INTEGER Adr, DWORD Data )
{
BOOL ret;
ULONG numBytes;
DWORD err;
BaccArgWriteQuad arg;
arg.Adr.NodeID = (USHORT) Id;
arg.Adr.Adr_High = (USHORT) Adr.u.HighPart;
arg.Adr.Adr_Low = Adr.u.LowPart;
arg.Data = Data;
BcamAdapterOL *pOl = GetNewBcamAdapterOL();
ret = DeviceIoControl( m_hDevice,
IOCTL_BACC_WRITE_QUAD,
&arg, sizeof arg,
NULL, 0,
&numBytes,
&pOl->ol // NULL
);
err = GetLastError();
if (!ret && err == ERROR_IO_PENDING)
{
ret = GetOverlappedResult( m_hDevice, &pOl->ol, &numBytes, true );
err = GetLastError();
}
delete pOl;
if (FailedDevIO( ret ))
throw BcamException( err );
}
//------------------------------------------------------------------------------
// DWORD CBcamAdapter::ReadBlock( ID Id, LARGE_INTEGER Adr, DWORD NumQuads, DWORD Data[] )
// Author:
// Date: 21.11.2002
//------------------------------------------------------------------------------
/**
* \brief Read a block of quadlets
*
* \param Id Identifier of the device
* \param Adr Offset of the register
* \param NumQuads Number of quadlets to read
* \param Data[] Buffer receiving the data
* \return
*
* The number of quadlets read
*
*/
//------------------------------------------------------------------------------
DWORD CBcamAdapter::ReadBlock( ID Id, LARGE_INTEGER Adr, DWORD Data[], DWORD NumQuads )
{
BOOL ret;
ULONG numBytes;
DWORD err;
BaccArgReadBlock arg;
arg.Adr.NodeID = (USHORT) Id;
arg.Adr.Adr_High = (USHORT) Adr.u.HighPart;
arg.Adr.Adr_Low = Adr.u.LowPart;
arg.NumQuadlets = NumQuads;
BcamAdapterOL *pOl = GetNewBcamAdapterOL();
ret = DeviceIoControl( m_hDevice,
IOCTL_BACC_READ_BLOCK,
&arg, sizeof arg,
Data, NumQuads * sizeof Data[0],
&numBytes,
&pOl->ol // NULL
);
err = GetLastError();
if (!ret && err == ERROR_IO_PENDING)
{
ret = GetOverlappedResult( m_hDevice, &pOl->ol, &numBytes, true );
err = GetLastError();
}
delete pOl;
if (FailedDevIO( ret ))
throw BcamException( err );
return numBytes / sizeof Data[0];
}
//------------------------------------------------------------------------------
// void CBcamAdapter::WriteBlock( ID Id, LARGE_INTEGER Adr, DWORD NumQuads, const DWORD Data[] )
// Author:
// Date: 21.11.2002
//------------------------------------------------------------------------------
/**
* \brief Write a block of quadlets.
*
* \param Id Identifier of the device
* \param Adr Offset of the register
* \param NumQuads Number of quadlets to read
* \param Data[] Buffer with data to
*/
//------------------------------------------------------------------------------
void CBcamAdapter::WriteBlock( ID Id, LARGE_INTEGER Adr, const DWORD Data[], DWORD NumQuads )
{
BOOL ret;
ULONG numBytes;
DWORD err;
const ULONG argSize = sizeof (BaccArgWriteBlock) + (NumQuads-1) *sizeof Data[0];
BaccArgWriteBlock* pArg = (BaccArgWriteBlock*) _alloca( argSize );
if (! pArg)
throw BcamException( Bvc::ErrorNumber( E_MEMORY ) );
pArg->Adr.NodeID = (USHORT) Id;
pArg->Adr.Adr_High = (USHORT) Adr.u.HighPart;
pArg->Adr.Adr_Low = Adr.u.LowPart;
memcpy( pArg->Data, Data, NumQuads * 4 );
BcamAdapterOL *pOl = GetNewBcamAdapterOL();
ret = DeviceIoControl( m_hDevice,
IOCTL_BACC_WRITE_BLOCK,
pArg, argSize,
NULL, 0,
&numBytes,
&pOl->ol // NULL
);
err = GetLastError();
if (! ret && err == ERROR_IO_PENDING)
{
ret = GetOverlappedResult( m_hDevice, &pOl->ol, &numBytes, true );
err = GetLastError();
}
delete pOl;
if (FailedDevIO( ret ))
throw BcamException( err );
}
const ULONG NoParent = (ULONG)-1;
/**
* \brief Construct a CNode-tree of the BcamResGetTopology result
*
* \result Pointer to the root node
*
* \todo Extract information completely
**/
CNode* CBcamAdapter::BuildTree( BaccResGetTopology* pRes )
{
CNode *stack[64], **sp = stack;
std::bitset<MAX_PORTS> childs;
for (int i=0; i<(int) pRes->NumNodes; i++)
{
CNode *pNewNode = new CNode;
if (! pNewNode)
throw BcamException( Bvc::ErrorNumber( E_MEMORY ) );
ZeroMemory( pNewNode->m_pChild, sizeof pNewNode->m_pChild );
pNewNode->m_Id = pRes->Node[i].ID;
pNewNode->m_RefCount = 1;
pNewNode->m_VendorName = pRes->Node[i].Vendor;
pNewNode->m_ModelName = pRes->Node[i].Model;
pNewNode->m_Nuid = pRes->Node[i].NUID;
const ULONG flags = pRes->Node[i].Flags;
if ( flags & (FB_Dcam1_0 | FB_Dcam1_2 | FB_Dcam1_3))
pNewNode->m_Type = flags & FB_Bcam ? NT_Bcam : NT_Dcam;
else if (flags & FB_Sbp2)
pNewNode->m_Type = NT_Sbp2;
else
pNewNode->m_Type = NT_Unknown;
pNewNode->m_ParentPort = NoParent;
childs.reset();
int n=0;
int c;
for (c=0; c<MAX_PORTS; c++)
{
switch(GetPortState( pRes->Node+i, c ))
{
case Connected_to_Parent:
pNewNode-> m_ParentPort = c;
break;
case Connected_to_Child:
n++;
childs.set(c);
break;
}
if (GetPortState( pRes->Node+i, c ) != Not_Present)
pNewNode->m_NumPorts++;
}
//while (n)
while (c--)
{
if (childs[c])
{
// pop node of stack
assert( sp > stack );
pNewNode->m_pChild[c/*--n*/] = *--sp;
}
}
// push node onto stack
assert( sp - stack < sizeof stack / sizeof stack[0] );
*sp++ = pNewNode;
}
if (sp > stack)
{ // pop node of stack
assert( sp == stack + 1 );
return *--sp;
}
else
return NULL;
}
/**
* \brief Request the bus topology asynchronously
* \param hEvent Handle of an event to be set on completion
* \param pRes Pointer to a caller provided result structure
* \param pv Pointer to context
* \throws BcamException E_PARAMETER if pRes is null
*/
BcamAdapterOL* CBcamAdapter::GetTreeAsync( HANDLE hEvent, BaccResGetTopology* pRes, void* pv )
{
if (! pRes)
throw BcamException( Bvc::ErrorNumber( E_INVALIDARG ), _T( "CBcamAdapter::GetTreeAsync" ) );
BcamAdapterOL *pOL = GetNewBcamAdapterOL( hEvent, (FunctionCode_t) Topology, pRes, pv );
if (! pOL)
throw BcamException( Bvc::ErrorNumber( E_OUTOFMEMORY ), _T( "CBcamAdapter::GetTreeAsync" ) );
DWORD numBytes;
BOOL ret = DeviceIoControl( m_hDevice,
IOCTL_BACC_GET_TOPOLOGY,
NULL, 0,
pRes, pRes->Size,
&numBytes,
&pOL->ol
);
if (FailedDevIO( ret ) && ret != ERROR_IO_PENDING)
{
throw BcamException( ::GetLastError(), _T( "CBcamAdapter::GetTreeAsync" ) );
}
return pOL;
}
/**
* \brief Get response on GetTreeAsync
* \param pOL Pointer to the BcamAdapterOL used in the preceeding call
* \param ppv Adress of a pointer taking the context information
* \return Pointer to the root node
* \retval Null, if the structure passed was to small.
* \throw BcamException The value of ::GetLastError() is thrown
*/
CNode* CBcamAdapter::GetTree( BcamAdapterOL *pOL, void** ppv )
{
DWORD numBytes;
DWORD ret = ::GetOverlappedResult( m_hDevice, &pOL->ol, &numBytes, TRUE );
if (FailedDevIO( ret ))
throw BcamException( ::GetLastError(), _T( "CBcamAdapter::GetTree" ) );
BaccResGetTopology *pRes = pOL->pTopology;
if (ppv)
*ppv = pOL->pContext;
if (pOL->pTopology->Status)
return NULL; // pRes too small, required size in field size
else
return BuildTree( pRes );
}
/**
* \brief Create tree with the bus topology
*
* \result Pointer to the root node of the tree
**/
CNode* CBcamAdapter::GetTree() const
{
TRACE( _T( "CBcamAdapter::GetTree()\n" ) );
CNode *pRoot = NULL;
BOOL ret;
ULONG numBytes;
BaccResGetTopology res, *pRes = &res;
ret = DeviceIoControl( m_hDevice,
IOCTL_BACC_GET_TOPOLOGY,
NULL, 0,
pRes, sizeof *pRes,
&numBytes,
NULL
);
if (FailedDevIO( ret ))
throw BcamException( ::GetLastError() );
if (pRes->Status)
{
const ULONG reqSize = pRes->Size;
pRes = (BaccResGetTopology*) _alloca( reqSize );
if (! pRes)
throw BcamException( Bvc::ErrorNumber( E_MEMORY ) );
ret = DeviceIoControl( m_hDevice,
IOCTL_BACC_GET_TOPOLOGY,
NULL, 0,
pRes, reqSize,
&numBytes,
NULL
);
if (FailedDevIO( ret ))
{
throw BcamException( ::GetLastError() );
}
}
pRoot = BuildTree( pRes );
return pRoot;
}
/////////////////////////////////////////////////////////////////////////////
// implementation of class CNode
//
/*
Default constructor
*/
CNode::CNode()
: m_RefCount( 0 ), m_NumPorts(0)
{
TRACE( _T( "CNode::CNode: this = 0x%X\n" ), this );
ZeroMemory( m_pChild, sizeof m_pChild );
}
/*
Destructor
*/
CNode::~CNode()
{
TRACE( _T( "CNode::~CNode: this = 0x%X\n" ), this );
for (int i=0; i<MaxChilds; i++)
{
if (m_pChild[i])
m_pChild[i]->Release(), m_pChild[i]=NULL;
}
}
/**
The reference count is incremented.
\param port Specifies the connection port
\return Returns the child node if present
*/
CNode* CNode::Child( ULONG port ) const
{
if (port < MaxChilds)
{
CNode* pc = m_pChild[ port ];
if (pc)
pc->AddRef();
return pc;
}
return NULL;
}
/**
Counts how many ports are conntected to child nodes.
\return the number of child nodes
*/
ULONG CNode::NumChilds() const
{
if (m_pChild)
{
int c = 0;
for (int i=0; i<MaxChilds; i++)
{
if (m_pChild[i])
c++;
}
return c;
}
return 0;
}
/**
\return the physical ID
*/
ID CNode::PhysicalId() const
{
return m_Id;
}
/**
\return the vendor name
*/
CString CNode::VendorName() const
{
return m_VendorName;
}
/**
\return the model name
*/
CString CNode::ModelName() const
{
return m_ModelName;
}
/**
\return the node unique id
*/
CNode::NUID CNode::NodeID() const
{
return m_Nuid;
}
/**
\return the port number of the parent or -1
*/
ULONG CNode::Parent() const
{
return m_ParentPort;
}
/**
\return the node type
*/
NodeType CNode::Type() const
{
return m_Type;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -