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

📄 impiopcbrowseserveraddressspace.cpp

📁 基于Intellution开发包的开发的OPC服务器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	for (long lIndex = 0; lIndex < g_lNumDataBlockProps; lIndex++)
	{
		if (SUCCEEDED(hr = SafeArrayGetElement(vPropertyData.parray,
											   &lIndex, &vTemp)))
		{
			// Change the variant to a bstr
			if (FAILED(hr = VariantChangeType(&vTemp, &vTemp, 0, VT_BSTR)))
			{
				VariantClear(&vTemp);
				return E_FAIL;
			}

			szData = vTemp.bstrVal;
			VariantClear(&vTemp);

			strncpy(pszPropertyData, szData, SIZE_OF_PROPERTY_DATA_STRINGS);
			pszPropertyData += SIZE_OF_PROPERTY_DATA_STRINGS;
		}
	}

	VariantClear(&vPropertyData);
	VariantClear(&vErrors);
	VariantClear(&vTemp);
	return S_OK;
}


////////////////////////////////////////////////////////////////
// void CImpIOPCBrowseServer::FreeMapMemory()
//
// @desc Frees all dynamic memory allocated and stored with a CMap.
//
// @parm CLongPtrMap * | pMap | Pointer to the map whose memory needs to be freed
//
// @retval	none
//
// TODO:	Nothing
//
////////////////////////////////////////////////////////////////
void CImpIOPCBrowseServer::FreeMapMemory(CLongPtrMap		*pMap)
{
	POSITION	posNext = pMap->GetStartPosition();
	int			nNumEntries	= pMap->GetCount();
	long		lKey;
	WCHAR		*pwcString;


	// Loop through the map and free all of the memory associated
	// with every entry in it.
	//
	for (long i = 0; i < nNumEntries; i++)
	{
		pMap->GetNextAssoc(posNext, lKey, pwcString);
		delete [] pwcString;
		pMap->RemoveKey(lKey);
	}
}


////////////////////////////////////////////////////////////////
// HRESULT CImpIOPCBrowseServer::GetHandleFromName()
//
// @desc This function searchs a given driver's channel and device list
//		 for a specific device name Or continues to search the devices
//		 datablock list for a given datablock name. It then returns that objects's
//		 handle when found.
//
// @parm	CString | szObjectName	| Device or datablock name to get the handle for
// @parm	long &	| lObjectHandle	| Returned handle
// @parm	BOOL	| bIsDataBlock	| Object name to searhc for
// 
// @retval	S_OK	success
// @retval	E_FAIL	failure, lObjectHandle will be 0
//
// @devnote This function should not need to be modified.
//
////////////////////////////////////////////////////////////////
HRESULT CImpIOPCBrowseServer::GetHandleFromName(CString		szObjectName,
												long		&lObjectHandle,
												BOOL		bIsDataBlock)	/* = FALSE */
{
	HRESULT		hr;
	VARIANT		vChanHandlesHolder,
				vChanNamesHolder,
				vChanHandles,
				vDevHandlesHolder,
				vDevNamesHolder,
				vDevHandles,
				vDevNames,
				vDBHandlesHolder,
				vDBNamesHolder,
				vDBHandles,
				vDBNames;
	long		lNumChannels	= 0L,
				lNumDevices		= 0L,
				lNumDataBlocks	= 0L,
				lChanHandle		= 0L,
				lDeviceHandle	= 0L;
	CString		szTempName;


	// Assume failure
	//
	lObjectHandle = 0L;

	// Make sure we have a pointer to the automation interface
	//
	if (NULL == m_pParentServer->m_pIDriver)
	{
		return E_FAIL;
	}

	//
	// We won't do an AddRef() on the OLE Automation interface pointer because the
	// calling function has already done that.
	//

	// Initialize the variants
	//
	VariantInit(&vChanHandlesHolder);
	VariantInit(&vChanNamesHolder);
	VariantInit(&vChanHandles);
	VariantInit(&vDevHandlesHolder);
	VariantInit(&vDevNamesHolder);
	VariantInit(&vDevHandles);
	VariantInit(&vDevNames);
	VariantInit(&vDBHandlesHolder);
	VariantInit(&vDBNamesHolder);
	VariantInit(&vDBHandles);
	VariantInit(&vDBNames);

	// Get a list of the channels available in this driver
	//
	hr = m_pParentServer->m_pIDriver->GetChannels(&vChanHandlesHolder, 
												  &vChanNamesHolder, 
												  &lNumChannels);
	if (FAILED(hr))
	{
		return E_FAIL;
	}

	// Loop through all of the channels. Then for every channel, we will get the
	// devices and loop through them to find a match on the device name. When it
	// finds a match, we will return the device handle to the caller.
	//
	for (long i = 0; i < lNumChannels; i++)
	{
		// Extract the channel handle and name
		hr	= SafeArrayGetElement(vChanHandlesHolder.parray,
								  &i, &vChanHandles);
		if (SUCCEEDED(hr))
		{
			// Get the channel handle and name
			lChanHandle = vChanHandles.lVal;

			// Get the list of devices for this channel
			hr = m_pParentServer->m_pIDriver->GetDevices(lChanHandle, 
														 &vDevHandlesHolder, 
														 &vDevNamesHolder, 
														 &lNumDevices);
			if (FAILED(hr))
			{
				goto Error;
			}

			// Loop through the devices in search of a specific name.
			//
			for (long j = 0; j < lNumDevices; j++)
			{
				if (SUCCEEDED(hr = SafeArrayGetElement(vDevHandlesHolder.parray,
													   &j, &vDevHandles)))
				{
					// Get the device handle
					lDeviceHandle = vDevHandles.lVal;

					if (bIsDataBlock)
					{
						// Get the list of datablocks for this device
						hr = m_pParentServer->m_pIDriver->GetDataBlocks(lDeviceHandle, 
																		&vDBHandlesHolder, 
																		&vDBNamesHolder, 
																		&lNumDataBlocks);
						if (FAILED(hr))
						{
							goto Error;
						}

						// Loop through the datablocks in search of a specific name.
						//
						for (long k = 0; k < lNumDataBlocks; k++)
						{
							if (SUCCEEDED(hr = SafeArrayGetElement(vDBHandlesHolder.parray,
													   &k, &vDBHandles)))
							{
								if (SUCCEEDED(hr = SafeArrayGetElement(vDBNamesHolder.parray,
													   &k, &vDBNames)))
								{
									szTempName = vDBNames.bstrVal;
									if (szTempName == szObjectName)
									{
										// We found it!
										lObjectHandle = vDBHandles.lVal;

										VariantClear(&vChanHandlesHolder);
										VariantClear(&vChanNamesHolder);
										VariantClear(&vChanHandles);
										VariantClear(&vDevHandlesHolder);
										VariantClear(&vDevNamesHolder);
										VariantClear(&vDevHandles);
										VariantClear(&vDevNames);
										VariantClear(&vDBHandlesHolder);
										VariantClear(&vDBNamesHolder);
										VariantClear(&vDBHandles);
										VariantClear(&vDBNames);
										return S_OK;
									}
								}
								else
								{
									goto Error;
								}
							}
							else
							{
								goto Error;
							}
						}
					}
					else
					{
						if (SUCCEEDED(hr = SafeArrayGetElement(vDevNamesHolder.parray,
													   &j, &vDevNames)))
						{
							szTempName = vDevNames.bstrVal;
							if (szTempName == szObjectName)
							{
								// We found it!
								lObjectHandle = vDevHandles.lVal;

								VariantClear(&vChanHandlesHolder);
								VariantClear(&vChanNamesHolder);
								VariantClear(&vChanHandles);
								VariantClear(&vDevHandlesHolder);
								VariantClear(&vDevNamesHolder);
								VariantClear(&vDevHandles);
								VariantClear(&vDevNames);
								VariantClear(&vDBHandlesHolder);
								VariantClear(&vDBNamesHolder);
								VariantClear(&vDBHandles);
								VariantClear(&vDBNames);
								return S_OK;
							}
						}
						else
						{
							goto Error;
						}
					}
				}
				else
				{
					goto Error;
				}

				// Reinitialize the variants for the next pass
				//
				VariantClear(&vDevNames);
				VariantClear(&vDevHandles);
			
			}	// END for (long j = 0; j < lNumDevices; j++)
		}
		else
		{
			goto Error;
		}

		// Reinitialize the variants for the next pass
		//
		VariantClear(&vChanHandles);

	}	// END for (long i = 0; i < lNumChannels; i++)

Error:
	// Clear the variant data and return failure
	//
	VariantClear(&vChanHandlesHolder);
	VariantClear(&vChanNamesHolder);
	VariantClear(&vChanHandles);
	VariantClear(&vDevHandlesHolder);
	VariantClear(&vDevNamesHolder);
	VariantClear(&vDevHandles);
	VariantClear(&vDevNames);
	VariantClear(&vDBHandlesHolder);
	VariantClear(&vDBNamesHolder);
	VariantClear(&vDBHandles);
	VariantClear(&vDBNames);

	return E_FAIL;
}


////////////////////////////////////////////////////////////////
// CImpIOPCBrowseServer::GetFilter()
//
// @desc Accepts a filter string and determines the filter type from
//		 that string. Also removes the wildcards from the filter string
//
// @parm	CString &		| szFilter		| Returned filter string
// @parm	FILTERTYPE &	| dwFilterType	| Returned filter type
//
// @retval	S_OK	if filtering is to be done.
// @retval	S_FALSE if no filtering is to be done.
//
////////////////////////////////////////////////////////////////
HRESULT	CImpIOPCBrowseServer::GetFilter(CString			&szFilter,		/* IN OUT */
										FILTERTYPE		&dwFilterType)	/* OUT */
{
	int	nIndex	= 0,
		nLength	= szFilter.GetLength();


	// If the filter string is empty, then there is no filtering to be done.
	//
	if (0 == nLength)
	{
		dwFilterType = FILTER_NONE;
		return S_FALSE;
	}

	// Get where the wildcard was found in the filter string.
	//
	nIndex = szFilter.FindOneOf("*");

	if (nIndex != -1)
	{
		// We found one
		if ("*" == szFilter)
		{
			dwFilterType = FILTER_NONE;
			szFilter.Empty();
			return S_FALSE;
		}
		if ((0 == nIndex) && ('*' == szFilter.GetAt(nLength-1)))
		{
			dwFilterType = FILTER_BOTHENDS;
			szFilter = szFilter.Left(nLength - 1);
			szFilter = szFilter.Mid(1);
			return S_OK;
		}
		if (0 == nIndex)
		{
			dwFilterType = FILTER_START;
			szFilter = szFilter.Mid(1);
			return S_OK;
		}
		if ((nLength - 1) == nIndex)
		{
			dwFilterType = FILTER_END;
			szFilter = szFilter.Left(nLength - 1);
			return S_OK;
		}
		
		dwFilterType = FILTER_NONE;
		szFilter.Empty();
		return S_FALSE;
	}

	// Well, the filter string isn't empty and it doesn't contain any
	// wildcards, so they must only want to find a string that is
	// equal to the filter string.
	//
	dwFilterType = FILTER_EQUAL;
	return S_OK;
}


////////////////////////////////////////////////////////////////
// CImpIOPCBrowseServer::FilterString()
//
// @desc Accepts a filter criteria string, filter type and a string 
//			to be filtered. If the string matches the filtering type and 
//			criteria, the function returns TRUE.
//
// @parm	CString		| strString		| String to test against filter
// @parm	CString		| szFilter		| Filter string/criteria
// @parm	FILTERTYPE	| dwFilterType	| Filter type
//
// @retval	TRUE	if the string matches the filter criteria
// @retval	FALSE	if the string does not match the filter criteria.
//
////////////////////////////////////////////////////////////////
BOOL CImpIOPCBrowseServer::FilterString(CString			strString,		/* IN */
										CString			szFilter,		/* IN */
										FILTERTYPE		dwFilterType)	/* IN */
{
	int		nLengthFilter	= szFilter.GetLength(),
			nLengthString	= strString.GetLength(),
			nIndex			= 0;


	// Return TRUE if we are not doing any filtering because all strings
	// will match for that condition
	//
	if (FILTER_NONE == dwFilterType)
	{
		return TRUE;
	}

	// If the length of the filter string is greater than the length of the
	// string to be matched on, then it can never match the criteria.
	// Example:
	//		Filter string = "Device11"
	//		Match string = "Dev"
	// Well, we are trying to find "Device11" inside of the "Dev" string, it
	// simply won't happen. The Match string needs to be larger than the filter
	// string.
	//
	if (nLengthFilter > nLengthString)
	{
		return FALSE;
	}

	switch(dwFilterType)
	{
	case FILTER_START:		// ex. "*ice"
		strString = strString.Mid(nLengthString - nLengthFilter);
		if (strString == szFilter)
		{
			return TRUE;
		}
		break;

	case FILTER_END:		// ex. "dev*"
		nIndex = strString.Find(szFilter);
		if (0 == nIndex)
		{
			return TRUE;
		}
		break;

	case FILTER_BOTHENDS:	// ex. "*ic*"
		if (-1 != strString.Find(szFilter))
		{
			return TRUE;
		}
		break;

	case FILTER_EQUAL:
		if (strString == szFilter)
		{
			return TRUE;
		}
		break;

	case FILTER_NONE:
		return TRUE;
		break;

	default:
		return FALSE;
		break;
	}

	return FALSE;
}


////////////////////////////////////////////////////////////////
// CreateEmptyStringEnumerator()
//
// @desc	Creates and empty IEnumString implementation object. This is
//			used when BrowseOPCItemIDs() returns S_FALSE because there is
//			nothing to enumerate.
//
// @parm	[in] IEnumString **	| ppEnumString | Returned enumerator
// 
// @retval	S_FALSE			success
// @retval	E_OUTOFMEMORY	The new operator failed
// @retval	E_FAIL			failure
//
////////////////////////////////////////////////////////////////
HRESULT CreateEmptyStringEnumerator(IEnumString		**ppEnumString)
{
	IEnumString		*pEnum;


	// Create an empty enumerator
	//
	pEnum = new CImpIEnumString(NULL,			// Parent
								(ULONG)0,		// # strings in enum
								NULL,			// Enum string array
								pIMalloc);		// IMalloc pointer
	if (NULL == pEnum)
	{
		*ppEnumString = NULL;
		return E_OUTOFMEMORY;
	}
	pEnum->AddRef();

	// Call QueryInterface() to get an interface pointer for the client.
	//
	if (FAILED(pEnum->QueryInterface(IID_IEnumString, (LPVOID *)ppEnumString)))
	{
		pEnum->Release();
		*ppEnumString = NULL;
		return E_FAIL;
	}

	// Reset the new enumerator and release our copy of it
	//
	(*ppEnumString)->Reset();
	pEnum->Release();
	return S_FALSE;
}

⌨️ 快捷键说明

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