?? impiopcbrowseserveraddressspace.cpp
字號:
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 + -