📄 impiopcserver.cpp
字号:
STDMETHODIMP CImpIOPCServer::AddGroup(LPCWSTR szName,
BOOL bActive,
DWORD dwRequestedUpdateRate,
OPCHANDLE hClientGroup,
LONG *pTimeBias,
FLOAT *pPercentDeadband,
DWORD dwLCID,
OPCHANDLE *phServerGroup,
DWORD *pRevisedUpdateRate,
REFIID riid,
LPUNKNOWN *ppUnk)
{
OPCHANDLE OPCHandle;
COPCDrvGroup *pNewGroup = NULL;
HRESULT hr;
// Make sure that we didn't get any bad pointers
//
if ((NULL == szName) ||
(NULL == ppUnk) ||
(NULL == phServerGroup))
{
return E_INVALIDARG;
}
// Default return in case of error
//
*ppUnk = NULL;
// Generate Unique Name (WCHAR) if not supplied by caller.
//
if (NULL == *szName)
{
CString strGeneratedName;
DWORD dwNumGroups = m_pParentServer->GetNumGroupHandles(),
i = 1;
char szNumGroups[15],
*pszGeneratedName = NULL;
int nLength = 0;
LPUNKNOWN lpTest = NULL;
// Macro required for ATL string conversions
//
USES_CONVERSION;
// We will try NumGroups + 1 different names. We SHOULD find one
// that isn't already configured.
//
while(i <= (dwNumGroups + 1))
{
strGeneratedName = g_strDefaultGeneratedGroupName;
ltoa((dwNumGroups + i), szNumGroups, 10);
strGeneratedName += szNumGroups;
nLength = strGeneratedName.GetLength();
pszGeneratedName = strGeneratedName.GetBuffer(nLength+1);
szName = A2W(pszGeneratedName);
strGeneratedName.ReleaseBuffer();
GetGroupByName(szName, IID_IUnknown, &lpTest);
if(NULL == lpTest)
{
break;
}
i++;
}
}
// Verify that the name provided is Unique
//
LPUNKNOWN lpTest;
GetGroupByName(szName, IID_IUnknown, &lpTest);
if(lpTest)
{
lpTest->Release();
return OPC_E_DUPLICATENAME;
}
// Create the new group and record our reference to it.
//
hr = m_pParentServer->GroupAlloc(&OPCHandle, &pNewGroup, this->m_pUnkOuter);
if (FAILED(hr))
{
return E_OUTOFMEMORY;
}
pNewGroup->AddRef();
// And request a 2nd interface for the caller
//
hr = pNewGroup->QueryInterface(riid, (LPVOID *)ppUnk);
if(FAILED(hr))
{
// If error - delete group and return
delete pNewGroup;
return E_FAIL;
}
// Copy the data to the new group
//
pNewGroup->m_ServerGroupHandle = OPCHandle;
pNewGroup->m_szName = WSTRClone(szName, NULL);
pNewGroup->m_ClientGroupHandle = hClientGroup;
pNewGroup->m_LCID = dwLCID;
pNewGroup->SetActive(bActive);
pNewGroup->SetUpdateRate(dwRequestedUpdateRate, pRevisedUpdateRate);
if (pPercentDeadband)
{
pNewGroup->m_Deadband = *pPercentDeadband;
}
if(pTimeBias)
{
pNewGroup->m_TimeBias = *pTimeBias;
}
// Add the new group to the map
//
m_pParentServer->GroupSet(pNewGroup);
// Return handle of the new group to the caller
//
*phServerGroup = OPCHandle;
// We now have a group in the server, so change the status to active
//
m_pParentServer->m_ServerState = OPC_STATUS_RUNNING;
return S_OK;
}
////////////////////////////////////////////////////////////////
// CImpIOPCServer::GetGroupByName()
//
// This function scans the set of groups known to this OPC
// server and returns a pointer to the IOPCGroup interface for
// the specified group.
//
// Returns:
// HRESULT - S_OK if the function succeeded
// - E_FAIL if the function failed. This will happen
// if the name passed to us was not found in
// the map.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIOPCServer::GetGroupByName(LPCWSTR szGroupName,
REFIID riid,
LPUNKNOWN *ppUnk)
{
HRESULT hr;
OPCHANDLE OPCHandle = 0;
COPCDrvGroup *pGroup = NULL;
POSITION posGroup = m_pParentServer->GetFirstGroupPosition();
int nNumGroups = m_pParentServer->GetNumGroupHandles();
*ppUnk = 0;
// Loop on the number of groups in the server until the name we are
// looking for is found. If we don't find it, we will return E_FAIL.
//
for (int i = 0; i < nNumGroups; i++)
{
m_pParentServer->GetNextGroup(posGroup, OPCHandle, pGroup);
if (!wcscmp(pGroup->m_szName, szGroupName))
{
// Then query for and return the requested interface
//
hr = pGroup->QueryInterface(riid, (LPVOID *)ppUnk);
if(FAILED(hr))
{
// If error - return
return E_FAIL;
}
return S_OK;
}
}
return E_FAIL;
}
////////////////////////////////////////////////////////////////
// CImpIOPCServer::RemoveGroup()
//
// This function removes the specified group from the server.
// Note that the group doesn't go away until the last reference
// to it is removed.
//
// Returns:
// HRESULT - S_OK if the function succeeded
// - E_FAIL if the function failed. This will happen
// if the handle passed to us was not found in
// the map.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIOPCServer::RemoveGroup(OPCHANDLE OPCHandle,
BOOL bForce)
{
COPCDrvGroup *pGroup = NULL;
// Lock the parent server object
//
m_pParentServer->Lock();
// Make sure the passed ServerHandle is valid
//
if (FALSE == m_pParentServer->IsGroupValid(OPCHandle))
{
return E_FAIL;
}
// Remove it from the map. (This will perform a Release().)
//
m_pParentServer->GroupFree(OPCHandle, bForce);
// If we have deleted the last groups in the server, then change the status to
// not configured.
//
if (0 == m_pParentServer->GetNumGroupHandles())
{
m_pParentServer->m_ServerState = OPC_STATUS_NOCONFIG;
}
// Unlock the parent server
//
m_pParentServer->UnLock();
return S_OK;
}
////////////////////////////////////////////////////////////////
// CImpIOPCServer::CreateGroupEnumerator()
//
// This function creates a string enumerator containing the
// group names for the server.
//
// Returns:
// HRESULT - S_OK if the function succeeded.
// - E_FAIL if the function failed.
// - E_OUTOFMEMORY if a memory allocator failed.
// - S_FALSE if there is nothing to enumerate (in
// the case that there are no groups).
// - E_INVALIDARG if a passed parameter is invalid.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIOPCServer::CreateGroupEnumerator(OPCENUMSCOPE dwScope,
REFIID riid,
LPUNKNOWN *ppUnk)
{
if (NULL == ppUnk)
{
return E_INVALIDARG;
}
if (riid == IID_IEnumUnknown)
{
// Note this logic is also used in XXXServer::QueryInterface
CImpIEnumUnknown *pEnumUnknown;
LPUNKNOWN *pGroupList;
int nGroupCount;
HRESULT hr;
// Get a snapshot of the group list
// (Note this does NOT do AddRefs to the groups - but see IXXXEnum below)
//
m_pParentServer->GetUnkList(dwScope, &pGroupList, &nGroupCount);
// Informthe caller if there is nothing to enumerate
//
if (0 == nGroupCount)
{
*ppUnk = NULL;
return S_FALSE;
}
// Create the Enumerator using the snapshot
// Note that the enumerator will AddRef the server
// and also all of the groups.
//
pEnumUnknown = new CImpIEnumUnknown(m_pUnkOuter, nGroupCount, pGroupList, pIMalloc);
m_pParentServer->FreeUnkList(pGroupList, nGroupCount);
if (pEnumUnknown == NULL)
{
*ppUnk = NULL;
return E_OUTOFMEMORY;
}
// Then QI for the interface ('pEnumString') actually is the interface
// but QI is the 'proper' way to get it.
// Note QI will do an AddRef of the Enum which will also do
// an AddRef of the 'parent' - i.e. the 'this' pointer passed above.
//
hr = pEnumUnknown->QueryInterface(riid, (LPVOID *)ppUnk);
if (FAILED(hr))
{
*ppUnk = NULL;
delete pEnumUnknown;
return E_FAIL;
}
return S_OK;
}
else if (riid == IID_IEnumString)
{
CImpIEnumString *pEnumString;
LPOLESTR *pGroupList;
int nGroupCount;
HRESULT hr;
// Get a snapshot of the group list
//
m_pParentServer->GetNameList(dwScope, &pGroupList, &nGroupCount);
// Informthe caller if there is nothing to enumerate
//
if (0 == nGroupCount)
{
*ppUnk = NULL;
return S_FALSE;
}
// Create the Enumerator using the snapshot
// Note that the enumerator will AddRef the server
//
pEnumString = new CImpIEnumString(m_pUnkOuter, nGroupCount, pGroupList, pIMalloc);
m_pParentServer->FreeNameList(pGroupList, nGroupCount);
if (pEnumString == NULL)
{
*ppUnk = NULL;
return E_OUTOFMEMORY;
}
// Then QI for the interface ('pEnumString') actually is the interface
// but QI is the 'proper' way to get it.
// Note QI will do an AddRef of the Enum which will also do
// an AddRef of the 'parent' - i.e. the 'this' pointer passed above.
//
hr = pEnumString->QueryInterface(riid, (LPVOID *)ppUnk);
if (FAILED(hr))
{
*ppUnk = NULL;
delete pEnumString;
return E_FAIL;
}
return S_OK;
}
// Unknow refiid, so return an error
//
*ppUnk = NULL;
return E_INVALIDARG;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -