学习记录----使用COM组件枚举Windows系统防火墙规则

使用COM组件枚举Windows系统防火墙规则

参考资料

参考了官网给出的一个其他COM组件写了枚举,链接如下:
链接: https://learn.microsoft.com/en-us/windows/win32/api/iads/nf-iads-iadscollection-get__newenum

这个链接中的例子还有BUG,调试它的时候,它会崩溃在画红框这行,原因是和上一行蓝框的这行冲突了。
VariantClear(&var);它本身已经做了释放,但是下面又使用pDisp->Release();
两次操作导致var->pdispVal被释放了2次,因此产生了崩溃。
在这里插入图片描述

关键点:

  1. CoInitializeEx,COM组件初始化
  2. CoUninitialize,COM组件释放
  3. INetFwPolicy2,防火墙COM组件接口
  4. INetFwRules,防火墙规则组COM组件接口
  5. IUnknown,COM组件基类
  6. IEnumVARIANT,COM组件的枚举接口
  7. VariantInit,用于初始化VARIANT 结构
  8. VariantClear,用于清理VARIANT 结构
  9. get__NewEnum,获取枚举,入参作为返回需要使用的值,固定是基类IUnknown
  10. QueryInterface,用于获取接口,第一处调用的位置,用于获取一个枚举的接口
  11. VARIANT,VARIANT结构体主要是使用在COM(组件对象模型)中用于传递参数使用,它的存在主要是为了保持一个在COM参数传递方法的统一性,它几乎包含了所有普通常用类型的数据类型的传递。
  12. Next( 1, &var, &lFetch ),用于枚举数据,参数1是每次枚举的数量,参数2是返回元素的大小至少为参数1的数组,参数3是实际返回的数量。
  13. var.punkVal->QueryInterface
    IDispatch继承于IUnknown,其实这里使用的是IUnknown的QueryInterface查询接口,通过枚举返回了一个元素后,查询这个元素是否包含了防火墙规则信息IID_INetFwRule的接口
    官方例子使用的是var.pdispVal,其实这里使用var.punkVal也是一样的。

代码

我的demo代码,hr的异常判定没做。

#pragma once
#include <WinSock2.h>
#include <stdio.h>
#include <windows.h>
#include <WS2tcpip.h>
#include <netfw.h>
#include <process.h>
#include <tchar.h>
#include <time.h>
#include <atlstr.h>
#include <string>
#include <list>
#include <mutex>
using namespace std;
#pragma comment( lib, "ws2_32.lib")
#define ReleaseCOM( x ) { if(NULL !=(x)) { (x)->Release(); (x) = NULL; } }

int main()
{
	HRESULT m_hrCoInitialize = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE );
	if( RPC_E_CHANGED_MODE != m_hrCoInitialize )
	{
		if( FAILED( m_hrCoInitialize ) )
		{
			return 1;
		}
	}

	HRESULT hr = S_OK;
	INetFwPolicy2*	pNetFwPolicy2 = NULL;
	INetFwRules*	pNetFwRules = NULL;
	IUnknown		*pUnk = NULL;
	IEnumVARIANT	*pEnum = NULL;


	hr = CoCreateInstance( __uuidof( NetFwPolicy2 ), NULL, CLSCTX_INPROC_SERVER, __uuidof( INetFwPolicy2 ), ( void** )&pNetFwPolicy2 );
	hr = pNetFwPolicy2->get_Rules( &pNetFwRules );
	hr = pNetFwRules->get__NewEnum( &pUnk );
	hr = pUnk->QueryInterface( IID_IEnumVARIANT, ( void** )&pEnum );// 查询一个枚举接口

	// Enumerate the collection.
	BSTR bstr = NULL;
	VARIANT var;
	ULONG lFetch;
	IDispatch *pDisp = NULL;

	VariantInit( &var );
	while( S_OK == pEnum->Next( 1, &var, &lFetch )  )
	{
		INetFwRule*		pNetFwRule = NULL;
		if( lFetch == 1 )
		{
			var.punkVal->QueryInterface( IID_INetFwRule, ( void** )&pNetFwRule );
			pNetFwRule->get_Name( &bstr );
			printf( "Rule name: %S\n", bstr );
			SysFreeString( bstr );
 			pNetFwRule->Release();
			pNetFwRule = NULL;
		}
		VariantClear( &var );
	};

	ReleaseCOM( pEnum );
	ReleaseCOM( pUnk );
	ReleaseCOM( pNetFwRules );
	ReleaseCOM( pNetFwPolicy2 );

	if( SUCCEEDED( m_hrCoInitialize ) )
	{
		CoUninitialize();
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值