Exemple #1
0
	void CopyToParamList(const list<wstring>& inList, ISC_StrParamList* paramList)
	{
		INIT_FUNCTION_SCOPE_LOGGER();
		try
		{
			paramList->len = inList.size();

			paramList->dataItems = new ISC_STRING[paramList->len];

			int i = 0;
			for (auto str : inList)
			{
				paramList->dataItems[i] = ToDoubleByte(str);
				LOGD("Setting parameter " << Utils::ToWide(paramList->dataItems[i], str.length()));
				i++;
			}
		}
		catch (exception ex)
		{
			LOGD(L"Exception - " << ToWstring(ex.what()));
		}
		catch (...)
		{
			LOGD(L"Unknown exception");
		}
	}
Exemple #2
0
	void CopyToParamList(const vector<long>& inList, ISC_LongParamList* const paramList)
	{
		INIT_FUNCTION_SCOPE_LOGGER();
		try
		{
			paramList->len = inList.size();
			paramList->dataItems = new long[paramList->len];

			int i = 0;
			for (auto num : inList)
			{
				paramList->dataItems[i] |= num;
				i++;
			}
		}
		catch (exception ex)
		{
			LOGD(L"Exception - " << ToWstring(ex.what()));
		}
		catch (...)
		{
			LOGD(L"Unknown exception");
		}
	}
bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters)
{
  ClearFilters();
  bool isRead = false;
  CPluginClient* client = CPluginClient::GetInstance();

  // Parse hide string
  int pos = 0;
  CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
  {
    for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters.end(); ++it)
    {
      CString filter((*it).c_str());
      // If the line is not commented out
      if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[')
      {
        int filterType = 0;

        // See http://adblockplus.org/en/filters for further documentation

        try
        {
          AddFilterElementHide(filter);
        }
        catch(...)
        {
#ifdef ENABLE_DEBUG_RESULT
          CPluginDebug::DebugResult(L"Error loading hide filter: " + ToWstring(filter));
#endif
        }
      }
    }
  }

  return isRead;
}
STDMETHODIMP CPluginUserSettings::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispparams, VARIANT* pVarResult,
                                         EXCEPINFO* pExcepinfo, UINT* pArgErr)
{
  try
  {
    if (!pDispparams)
    {
      return E_POINTER;
    }
    if (pDispparams->cNamedArgs != 0)
    {
      return DISP_E_NONAMEDARGS;
    }
    CPluginSettings* settings = CPluginSettings::GetInstance();
    switch (dispidMember)
    {
    case dispatchID_GetMessage:
      {
        if (pDispparams->cArgs != 2)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pDispparams->rgvarg[0].vt != VT_BSTR || pDispparams->rgvarg[1].vt != VT_BSTR)
        {
          return DISP_E_TYPEMISMATCH;
        }
        if (pVarResult)
        {
          CComBSTR key = pDispparams->rgvarg[0].bstrVal;
          CComBSTR section = pDispparams->rgvarg[1].bstrVal;
          Dictionary* dictionary = Dictionary::GetInstance();
          std::wstring message = dictionary->Lookup(
            ToUtf8String(ToWstring(section)),
            ToUtf8String(ToWstring(key))
          );

          pVarResult->vt = VT_BSTR;
          pVarResult->bstrVal = SysAllocString(message.c_str());
        }
      }
      break;
    case dispatchID_GetLanguageCount:
      {
        if (pDispparams->cArgs != 0)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pVarResult)
        {
          auto languageList = settings->GetFilterLanguageTitleList();

          pVarResult->vt = VT_I4;
          pVarResult->lVal = static_cast<LONG>(languageList.size());
        }
      }
      break;
    case dispatchID_GetLanguageByIndex:
      {
        if (pDispparams->cArgs != 1)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pDispparams->rgvarg[0].vt != VT_I4)
        {
          return DISP_E_TYPEMISMATCH;
        }
        if (pVarResult)
        {
          int index = pDispparams->rgvarg[0].lVal;

          auto languageTitleList = settings->GetFilterLanguageTitleList();

          if (index < 0  ||  index >= static_cast<int>(languageTitleList.size()))
            return DISP_E_BADINDEX;

          std::wstring language;

          int loopIndex = 0;
          for (auto it = languageTitleList.begin(); it != languageTitleList.end(); ++it)
          {
            if (loopIndex == index)
            {
              language = it->first;
              break;
            }
            ++loopIndex;
          }

          pVarResult->vt = VT_BSTR;
          pVarResult->bstrVal = SysAllocString(language.c_str());
        }
      }
      break;
    case dispatchID_GetLanguageTitleByIndex:
      {
        if (pDispparams->cArgs != 1)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pDispparams->rgvarg[0].vt != VT_I4)
        {
          return DISP_E_TYPEMISMATCH;
        }
        if (pVarResult)
        {
          int index = pDispparams->rgvarg[0].lVal;

          auto languageTitleList = settings->GetFilterLanguageTitleList();

          if (index < 0  ||  index >= static_cast<int>(languageTitleList.size()))
            return DISP_E_BADINDEX;

          std::wstring languageTitle;
          int loopIndex = 0;
          for (auto it = languageTitleList.begin(); it != languageTitleList.end(); ++it)
          {
            if (loopIndex == index)
            {
              languageTitle = it->second;
              break;
            }
            loopIndex++;
          }

          pVarResult->vt = VT_BSTR;
          pVarResult->bstrVal = SysAllocString(languageTitle.c_str());
        }
      }
      break;
    case dispatchID_SetLanguage:
      {
        if (pDispparams->cArgs != 1)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pDispparams->rgvarg[0].vt != VT_BSTR)
        {
          return DISP_E_TYPEMISMATCH;
        }
        CComBSTR url = pDispparams->rgvarg[0].bstrVal;
        settings->SetSubscription((BSTR)url);
      }
      break;
    case dispatchID_GetLanguage:
      {
        if (pDispparams->cArgs != 0)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pVarResult)
        {
          std::wstring url = settings->GetSubscription();
          pVarResult->vt = VT_BSTR;
          pVarResult->bstrVal = SysAllocString(url.c_str());
        }
      }
      break;
    case dispatchID_GetWhitelistDomains:
      {
        if (pDispparams->cArgs != 0)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pVarResult)
        {
          auto whiteListDomains = settings->GetWhiteListedDomainList();
          std::wstring commaSeparatedDomains;
          for (size_t i = 0; i < whiteListDomains.size(); i++)
          {
            if (!commaSeparatedDomains.empty())
            {
              commaSeparatedDomains += ',';
            }
            commaSeparatedDomains += whiteListDomains[i];
          }
          pVarResult->vt = VT_BSTR;
          pVarResult->bstrVal = SysAllocString(commaSeparatedDomains.c_str());
        }
      }
      break;
    case dispatchID_AddWhitelistDomain:
      {
        if (pDispparams->cArgs != 1)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pDispparams->rgvarg[0].vt != VT_BSTR)
        {
          return DISP_E_TYPEMISMATCH;
        }
        CComBSTR domain = pDispparams->rgvarg[0].bstrVal;
        if (domain.Length())
        {
          settings->AddWhiteListedDomain((BSTR)domain);
        }
      }
      break;
    case dispatchID_RemoveWhitelistDomain:
      {
        if (pDispparams->cArgs != 1)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pDispparams->rgvarg[0].vt != VT_BSTR)
        {
          return DISP_E_TYPEMISMATCH;
        }
        CComBSTR domain = pDispparams->rgvarg[0].bstrVal;
        if (domain.Length())
        {
          settings->RemoveWhiteListedDomain(std::wstring(domain));
        }
      }
      break;
    case dispatchID_GetAppLocale:
      {
        if (pDispparams->cArgs != 0)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pVarResult)
        {
          pVarResult->vt = VT_BSTR;
          pVarResult->bstrVal = SysAllocString(GetBrowserLanguage().c_str());
        }
      }
      break;
    case dispatchID_GetDocumentationLink:
      {
        if (pDispparams->cArgs != 0)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pVarResult)
        {
          pVarResult->vt = VT_BSTR;
          pVarResult->bstrVal = SysAllocString(CPluginClient::GetInstance()->GetDocumentationLink().c_str());
        }
      }
      break;
    case dispatchID_IsAcceptableAdsEnabled:
      {
        if (pDispparams->cArgs != 0)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pVarResult)
        {
          pVarResult->vt = VT_BOOL;
          pVarResult->boolVal = CPluginClient::GetInstance()->IsAcceptableAdsEnabled() ? VARIANT_TRUE : VARIANT_FALSE;
        }
      }
      break;
    case dispatchID_SetAcceptableAdsEnabled:
      {
        if (pDispparams->cArgs != 1)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pDispparams->rgvarg[0].vt != VT_BOOL)
        {
          return DISP_E_TYPEMISMATCH;
        }
        if (pDispparams->rgvarg[0].boolVal != VARIANT_FALSE)
        {
          CPluginClient* client = CPluginClient::GetInstance();
          client->AddSubscription(client->GetPref(L"subscriptions_exceptionsurl", L""));
        }
        else
        {
          CPluginClient* client = CPluginClient::GetInstance();
          client->RemoveSubscription(client->GetPref(L"subscriptions_exceptionsurl", L""));
        }
      }
      break;
    case dispatchID_IsUpdate:
      {
        if (pDispparams->cArgs != 0)
        {
          return DISP_E_BADPARAMCOUNT;
        }
        if (pVarResult)
        {
          pVarResult->vt = VT_BOOL;
          pVarResult->boolVal = CPluginClient::GetInstance()->GetPref(L"displayUpdatePage", false) ? VARIANT_TRUE : VARIANT_FALSE;
        }
      }
      break;
    default:
      return DISP_E_MEMBERNOTFOUND;
      break;
    }
  }
  catch (...)
  {
    return E_FAIL;
  }
  return S_OK;
}
Exemple #5
0
	string ToString(const ISC_STRING &msg) {
		return ToString(ToWstring(msg));
	}
bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const
{
  CString tagCString = ToCString(tag);

  CString id;
  CComBSTR bstrId;
  if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
  {
    id = bstrId;
  }

  CString classNames;
  CComBSTR bstrClassNames;
  if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
  {
    classNames = bstrClassNames;
  }

  CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
  {
    // Search tag/id filters
    if (!id.IsEmpty())
    {
      std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideTagsNamed::const_iterator> idItEnum =
        m_elementHideTagsId.equal_range(std::make_pair(tagCString, id));
      for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; idIt != idItEnum.second; idIt ++)
      {
        if (idIt->second.IsMatchFilterElementHide(pEl))
        {
#ifdef ENABLE_DEBUG_RESULT
          DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second.m_filterText)
            CPluginDebug::DebugResultHiding(tag, L"id:" + ToWstring(id), ToWstring(idIt->second.m_filterText));
#endif
          return true;
        }
      }

      // Search general id
      idItEnum = m_elementHideTagsId.equal_range(std::make_pair("", id));
      for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; idIt != idItEnum.second; idIt ++)
      {
        if (idIt->second.IsMatchFilterElementHide(pEl))
        {
#ifdef ENABLE_DEBUG_RESULT
          DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m_filterText)
            CPluginDebug::DebugResultHiding(tag, L"id:" + ToWstring(id), ToWstring(idIt->second.m_filterText));
#endif
          return true;
        }
      }
    }

    // Search tag/className filters
    if (!classNames.IsEmpty())
    {
      int pos = 0;
      CString className = classNames.Tokenize(L" \t\n\r", pos);
      while (pos >= 0)
      {
        std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideTagsNamed::const_iterator> classItEnum = 
          m_elementHideTagsClass.equal_range(std::make_pair(tagCString, className));

        for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.first; classIt != classItEnum.second; ++classIt)
        {
          if (classIt->second.IsMatchFilterElementHide(pEl))
          {
#ifdef ENABLE_DEBUG_RESULT
            DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt->second.m_filterText)
              CPluginDebug::DebugResultHiding(tag, L"class:" + ToWstring(className), ToWstring(classIt->second.m_filterText));
#endif
            return true;
          }
        }

        // Search general class name
        classItEnum = m_elementHideTagsClass.equal_range(std::make_pair("", className));
        for (TFilterElementHideTagsNamed::const_iterator classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt)
        {
          if (classIt->second.IsMatchFilterElementHide(pEl))
          {
#ifdef ENABLE_DEBUG_RESULT
            DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + ToWString(classIt->second.m_filterText));
            CPluginDebug::DebugResultHiding(tag, L"class:" + ToWstring(className), ToWstring(classIt->second.m_filterText));
#endif
            return true;
          }
        }

        // Next class name
        className = classNames.Tokenize(L" \t\n\r", pos);
      }
    }

    // Search tag filters
    std::pair<TFilterElementHideTags::const_iterator, TFilterElementHideTags::const_iterator> tagItEnum 
      = m_elementHideTags.equal_range(tagCString);
    for (TFilterElementHideTags::const_iterator tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++ tagIt)
    {
      if (tagIt->second.IsMatchFilterElementHide(pEl))
      {
#ifdef ENABLE_DEBUG_RESULT
        DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_filterText)
          CPluginDebug::DebugResultHiding(tag, L"-", ToWstring(tagIt->second.m_filterText));
#endif
        return true;
      }
    }
  }

  return false;
}
bool CPluginFilter::IsElementHidden(const std::wstring& tag, IHTMLElement* pEl, const std::wstring& domain, const std::wstring& indent) const
{
  std::wstring id;
  CComBSTR idBstr;
  if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr)
  {
    id = ToWstring(idBstr);
  }
  std::wstring classNames;
  CComBSTR classNamesBstr;
  if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr)
  {
    classNames = ToWstring(classNamesBstr);
  }

  CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
  {
    // Search tag/id filters
    if (!id.empty())
    {
      auto idItEnum = m_elementHideTagsId.equal_range(std::make_pair(tag, id));
      for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt)
      {
        if (idIt->second.IsMatchFilterElementHide(pEl))
        {
#ifdef ENABLE_DEBUG_RESULT
          DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/id) filter:" + idIt->second.m_filterText);
          CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filterText);
#endif
          return true;
        }
      }

      // Search general id
      idItEnum = m_elementHideTagsId.equal_range(std::make_pair(L"", id));
      for (auto idIt = idItEnum.first; idIt != idItEnum.second; ++idIt)
      {
        if (idIt->second.IsMatchFilterElementHide(pEl))
        {
#ifdef ENABLE_DEBUG_RESULT
          DEBUG_HIDE_EL(indent + L"HideEl::Found (?/id) filter:" + idIt->second.m_filterText);
          CPluginDebug::DebugResultHiding(tag, L"id:" + id, idIt->second.m_filterText);
#endif
          return true;
        }
      }
    }

    // Search tag/className filters
    if (!classNames.empty())
    {
      wchar_t* nextToken = nullptr;
      const wchar_t* token = wcstok_s(&classNames[0], L" \t\n\r", &nextToken);
      while (token != nullptr)
      {
        std::wstring className(token);
        auto classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(tag, className));
        for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++classIt)
        {
          if (classIt->second.IsMatchFilterElementHide(pEl))
          {
#ifdef ENABLE_DEBUG_RESULT
            DEBUG_HIDE_EL(indent + L"HideEl::Found (tag/class) filter:" + classIt->second.m_filterText);
            CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt->second.m_filterText);
#endif
            return true;
          }
        }

        // Search general class name
        classItEnum = m_elementHideTagsClass.equal_range(std::make_pair(L"", className));
        for (auto classIt = classItEnum.first; classIt != classItEnum.second; ++ classIt)
        {
          if (classIt->second.IsMatchFilterElementHide(pEl))
          {
#ifdef ENABLE_DEBUG_RESULT
            DEBUG_HIDE_EL(indent + L"HideEl::Found (?/class) filter:" + classIt->second.m_filterText);
            CPluginDebug::DebugResultHiding(tag, L"class:" + className, classIt->second.m_filterText);
#endif
            return true;
          }
        }
        token = wcstok_s(nullptr, L" \t\n\r", &nextToken);
      }
    }

    // Search tag filters
    auto tagItEnum = m_elementHideTags.equal_range(tag);
    for (auto tagIt = tagItEnum.first; tagIt != tagItEnum.second; ++tagIt)
    {
      if (tagIt->second.IsMatchFilterElementHide(pEl))
      {
#ifdef ENABLE_DEBUG_RESULT
        DEBUG_HIDE_EL(indent + L"HideEl::Found (tag) filter:" + tagIt->second.m_filterText);
        CPluginDebug::DebugResultHiding(tag, L"-", tagIt->second.m_filterText);
#endif
        return true;
      }
    }
  }

  return false;
}
bool CFilterElementHide::IsMatchFilterElementHide(IHTMLElement* pEl) const
{
  HRESULT hr;
  /*
   * If a tag id is specified, it must match
   */
  if (!m_tagId.empty())
  {
    CComBSTR idBstr;
    if (FAILED(pEl->get_id(&idBstr)) || !idBstr || m_tagId != ToWstring(idBstr))
    {
      return false;
    }
  }
  /*
   * If a class name is specified, it must match
   */
  if (!m_tagClassName.empty())
  {
    CComBSTR classNameListBstr;
    hr = pEl->get_className(&classNameListBstr);
    if (FAILED(hr) || !classNameListBstr)
    {
      return false; // We can't match a class name if there's no class name
    }
    std::wstring classNameList(ToWstring(classNameListBstr));
    if (classNameList.empty())
    {
      return false;
    }
    // TODO: Consider case of multiple classes. (m_tagClassName can be something like "foo.bar")
    /*
     * Match when 'm_tagClassName' appears as a token within classNameList
     */
    bool foundMatch = false;
    wchar_t* nextToken = nullptr;
    const wchar_t* token = wcstok_s(&classNameList[0], L" ", &nextToken);
    while (token != nullptr)
    {
      if (std::wstring(token) == m_tagClassName)
      {
        foundMatch = true;
        break;
      }
      token = wcstok_s(nullptr, L" ", &nextToken);
    }
    if (!foundMatch)
    {
      return false;
    }
  }
  /*
   * If a tag name is specified, it must match
   */
  if (!m_tag.empty())
  {
    CComBSTR tagNameBstr;
    if (FAILED(pEl->get_tagName(&tagNameBstr)) || !tagNameBstr)
    {
      return false;
    }
    if (m_tag != ToLowerString(ToWstring(tagNameBstr)))
    {
      return false;
    }
  }
  /*
   * Match each attribute
   */
  for (auto attrIt = m_attributeSelectors.begin(); attrIt != m_attributeSelectors.end(); ++attrIt)
  {
    std::wstring value;
    bool attrFound = false;
    if (attrIt->m_type == CFilterElementHideAttrType::STYLE)
    {
      CComPtr<IHTMLStyle> pStyle;
      if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle)
      {
        CComBSTR styleBstr;
        if (SUCCEEDED(pStyle->get_cssText(&styleBstr)) && styleBstr)
        {
          value = ToLowerString(ToWstring(styleBstr));
          attrFound = true;
        }
      }
    }
    else if (attrIt->m_type == CFilterElementHideAttrType::CLASS)
    {
      CComBSTR classNamesBstr;
      if (SUCCEEDED(pEl->get_className(&classNamesBstr)) && classNamesBstr)
      {
        value = ToWstring(classNamesBstr);
        attrFound = true;
      }
    }
    else if (attrIt->m_type == CFilterElementHideAttrType::ID)
    {
      CComBSTR idBstr;
      if (SUCCEEDED(pEl->get_id(&idBstr)) && idBstr)
      {
        value = ToWstring(idBstr);
        attrFound = true;
      }
    }
    else
    {
      CComBSTR attrArgument(attrIt->m_attr.length(), attrIt->m_attr.c_str());
      auto x = GetHtmlElementAttribute(*pEl, attrArgument);
      attrFound = x.isAttributeFound;
      if (attrFound)
      {
        value = x.attributeValue;
      }
    }

    if (attrFound)
    {
      if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT)
      {
        // TODO: IE rearranges the style attribute completely. Figure out if anything can be done about it.
        if (value != attrIt->m_value)
          return false;
      }
      else if (attrIt->m_pos == CFilterElementHideAttrPos::STARTING)
      {
        if (value.compare(0, attrIt->m_value.length(), attrIt->m_value) != 0)
          return false;
      }
      else if (attrIt->m_pos == CFilterElementHideAttrPos::ENDING)
      {
        size_t valueLength = value.length();
        size_t attrLength = attrIt->m_value.length();
        if (valueLength < attrLength)
          return false;
        if (value.compare(valueLength - attrLength, attrLength, attrIt->m_value) != 0)
          return false;
      }
      else if (attrIt->m_pos == CFilterElementHideAttrPos::ANYWHERE)
      {
        if (value.find(attrIt->m_value) == std::wstring::npos)
          return false;
      }
      else if (attrIt->m_value.empty())
      {
        return true;
      }
    }
    else
    {
      return false;
    }
  }

  if (m_predecessor)
  {
    CComPtr<IHTMLElement> pDomPredecessor;
    HRESULT hr = S_FALSE;
    switch (m_predecessor->m_type)
    {
    case ETraverserComplexType::TRAVERSER_TYPE_PARENT:
      hr = pEl->get_parentElement(&pDomPredecessor);
      break;
    case ETraverserComplexType::TRAVERSER_TYPE_IMMEDIATE:
      hr = S_FALSE;
      CComQIPtr<IHTMLDOMNode> pPrevSiblingNode = pEl;
      long type = 0;
      while (pPrevSiblingNode && type != 1)
      {
        IHTMLDOMNode* tmpNode;
        pPrevSiblingNode->get_previousSibling(&tmpNode);
        pPrevSiblingNode.Attach(tmpNode);
        if (pPrevSiblingNode)
        {
          hr = pPrevSiblingNode->get_nodeType(&type);
          if (hr != S_OK)
            pPrevSiblingNode.Release();
        }
      }

      if (pPrevSiblingNode)
        hr = pPrevSiblingNode.QueryInterface(&pDomPredecessor);
      else
        return false;
      break;
    }
    if (hr != S_OK)
      return false;
    return m_predecessor->IsMatchFilterElementHide(pDomPredecessor);
  }

  return true;
}