mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-04-13 02:01:29 +03:00
Feat/msi (#7688)
* Feat. Msi, check is self-installed Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat. Msi. 1. Check if is self-installation. 2. Add firewall rule by custom action. Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat. Msi, github ci Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat. Msi, github ci Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat. Msi, github ci Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat. Msi, refact preprocess.py Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat. Msi Signed-off-by: fufesou <shuanglongchen@yeah.net> * Trivial, renames Signed-off-by: fufesou <shuanglongchen@yeah.net> --------- Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
@@ -5,6 +5,10 @@
|
||||
#include <shellapi.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <winternl.h>
|
||||
#include <netfw.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
|
||||
UINT __stdcall CustomActionHello(
|
||||
__in MSIHANDLE hInstall)
|
||||
@@ -206,3 +210,116 @@ LExit:
|
||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||
return WcaFinalize(er);
|
||||
}
|
||||
|
||||
// No use for now, it can be refer as an example of ShellExecuteW.
|
||||
void AddFirewallRuleCmdline(LPWSTR exeName, LPWSTR exeFile, LPCWSTR dir)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
HINSTANCE hi = 0;
|
||||
WCHAR cmdline[1024] = { 0, };
|
||||
WCHAR rulename[500] = { 0, };
|
||||
|
||||
StringCchPrintfW(rulename, sizeof(rulename) / sizeof(rulename[0]), L"%ls Service", exeName);
|
||||
if (hr < 0) {
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to make rulename: %ls", exeName);
|
||||
return;
|
||||
}
|
||||
|
||||
StringCchPrintfW(cmdline, sizeof(cmdline) / sizeof(cmdline[0]), L"advfirewall firewall add rule name=\"%ls\" dir=%ls action=allow program=\"%ls\" enable=yes", rulename, dir, exeFile);
|
||||
if (hr < 0) {
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to make cmdline: %ls", exeName);
|
||||
return;
|
||||
}
|
||||
|
||||
hi = ShellExecuteW(NULL, L"open", L"netsh", cmdline, NULL, SW_HIDE);
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew
|
||||
if ((int)hi <= 32) {
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to change firewall rule : %d, last error: %d", (int)hi, GetLastError());
|
||||
}
|
||||
else {
|
||||
WcaLog(LOGMSG_STANDARD, "Firewall rule \"%ls\" (%ls) is added", rulename, dir);
|
||||
}
|
||||
}
|
||||
|
||||
// No use for now, it can be refer as an example of ShellExecuteW.
|
||||
void RemoveFirewallRuleCmdline(LPWSTR exeName)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
HINSTANCE hi = 0;
|
||||
WCHAR cmdline[1024] = { 0, };
|
||||
WCHAR rulename[500] = { 0, };
|
||||
|
||||
StringCchPrintfW(rulename, sizeof(rulename) / sizeof(rulename[0]), L"%ls Service", exeName);
|
||||
if (hr < 0) {
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to make rulename: %ls", exeName);
|
||||
return;
|
||||
}
|
||||
|
||||
StringCchPrintfW(cmdline, sizeof(cmdline) / sizeof(cmdline[0]), L"advfirewall firewall delete rule name=\"%ls\"", rulename);
|
||||
if (hr < 0) {
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to make cmdline: %ls", exeName);
|
||||
return;
|
||||
}
|
||||
|
||||
hi = ShellExecuteW(NULL, L"open", L"netsh", cmdline, NULL, SW_HIDE);
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew
|
||||
if ((int)hi <= 32) {
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to change firewall rule \"%ls\" : %d, last error: %d", rulename, (int)hi, GetLastError());
|
||||
}
|
||||
else {
|
||||
WcaLog(LOGMSG_STANDARD, "Firewall rule \"%ls\" is removed", rulename);
|
||||
}
|
||||
}
|
||||
|
||||
bool AddFirewallRule(bool add, LPWSTR exeName, LPWSTR exeFile);
|
||||
UINT __stdcall AddFirewallRules(
|
||||
__in MSIHANDLE hInstall)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
DWORD er = ERROR_SUCCESS;
|
||||
|
||||
int nResult = 0;
|
||||
LPWSTR exeFile = NULL;
|
||||
LPWSTR exeName = NULL;
|
||||
WCHAR exeNameNoExt[500] = { 0, };
|
||||
LPWSTR pwz = NULL;
|
||||
LPWSTR pwzData = NULL;
|
||||
size_t szNameLen = 0;
|
||||
|
||||
hr = WcaInitialize(hInstall, "AddFirewallExceptions");
|
||||
ExitOnFailure(hr, "Failed to initialize");
|
||||
|
||||
hr = WcaGetProperty(L"CustomActionData", &pwzData);
|
||||
ExitOnFailure(hr, "failed to get CustomActionData");
|
||||
|
||||
pwz = pwzData;
|
||||
hr = WcaReadStringFromCaData(&pwz, &exeFile);
|
||||
ExitOnFailure(hr, "failed to read database key from custom action data: %ls", pwz);
|
||||
WcaLog(LOGMSG_STANDARD, "Try add firewall exceptions for file : %ls", exeFile);
|
||||
|
||||
exeName = PathFindFileNameW(exeFile + 1);
|
||||
hr = StringCchPrintfW(exeNameNoExt, 500, exeName);
|
||||
ExitOnFailure(hr, "Failed to copy exe name: %ls", exeName);
|
||||
szNameLen = wcslen(exeNameNoExt);
|
||||
if (szNameLen >= 4 && wcscmp(exeNameNoExt + szNameLen - 4, L".exe") == 0) {
|
||||
exeNameNoExt[szNameLen - 4] = L'\0';
|
||||
}
|
||||
|
||||
//if (exeFile[0] == L'1') {
|
||||
// AddFirewallRuleCmdline(exeNameNoExt, exeFile, L"in");
|
||||
// AddFirewallRuleCmdline(exeNameNoExt, exeFile, L"out");
|
||||
//}
|
||||
//else {
|
||||
// RemoveFirewallRuleCmdline(exeNameNoExt);
|
||||
//}
|
||||
|
||||
AddFirewallRule(exeFile[0] == L'1', exeNameNoExt, exeFile + 1);
|
||||
|
||||
LExit:
|
||||
if (pwzData) {
|
||||
ReleaseStr(pwzData);
|
||||
}
|
||||
|
||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||
return WcaFinalize(er);
|
||||
}
|
||||
|
||||
@@ -4,3 +4,4 @@ EXPORTS
|
||||
CustomActionHello
|
||||
RemoveInstallFolder
|
||||
TerminateProcesses
|
||||
AddFirewallRules
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CustomActions.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="FirewallRules.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
||||
430
res/msi/CustomActions/FirewallRules.cpp
Normal file
430
res/msi/CustomActions/FirewallRules.cpp
Normal file
@@ -0,0 +1,430 @@
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ics/c-adding-an-application-rule-edge-traversal
|
||||
|
||||
/********************************************************************
|
||||
Copyright (C) Microsoft. All Rights Reserved.
|
||||
|
||||
Abstract:
|
||||
This C++ file includes sample code that adds a firewall rule with
|
||||
EdgeTraversalOptions (one of the EdgeTraversalOptions values).
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include "pch.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <netfw.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#pragma comment(lib, "ole32.lib")
|
||||
#pragma comment(lib, "oleaut32.lib")
|
||||
|
||||
#define STRING_BUFFER_SIZE 500
|
||||
|
||||
|
||||
// Forward declarations
|
||||
HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2);
|
||||
void WFCOMCleanup(INetFwPolicy2* pNetFwPolicy2);
|
||||
HRESULT RemoveFirewallRule(
|
||||
__in INetFwPolicy2* pNetFwPolicy2,
|
||||
__in LPWSTR exeName);
|
||||
HRESULT AddFirewallRuleWithEdgeTraversal(__in INetFwPolicy2* pNetFwPolicy2,
|
||||
__in bool in,
|
||||
__in LPWSTR exeName,
|
||||
__in LPWSTR exeFile);
|
||||
|
||||
|
||||
bool AddFirewallRule(bool add, LPWSTR exeName, LPWSTR exeFile)
|
||||
{
|
||||
bool result = false;
|
||||
HRESULT hrComInit = S_OK;
|
||||
HRESULT hr = S_OK;
|
||||
INetFwPolicy2* pNetFwPolicy2 = NULL;
|
||||
|
||||
// Initialize COM.
|
||||
hrComInit = CoInitializeEx(
|
||||
0,
|
||||
COINIT_APARTMENTTHREADED
|
||||
);
|
||||
|
||||
// Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
|
||||
// initialized with a different mode. Since we don't care what the mode is,
|
||||
// we'll just use the existing mode.
|
||||
if (hrComInit != RPC_E_CHANGED_MODE)
|
||||
{
|
||||
if (FAILED(hrComInit))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "CoInitializeEx failed: 0x%08lx\n", hrComInit);
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve INetFwPolicy2
|
||||
hr = WFCOMInitialize(&pNetFwPolicy2);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (add) {
|
||||
// Add firewall rule with EdgeTraversalOption=DeferApp (Windows7+) if available
|
||||
// else add with Edge=True (Vista and Server 2008).
|
||||
hr = AddFirewallRuleWithEdgeTraversal(pNetFwPolicy2, true, exeName, exeFile);
|
||||
hr = AddFirewallRuleWithEdgeTraversal(pNetFwPolicy2, false, exeName, exeFile);
|
||||
}
|
||||
else {
|
||||
hr = RemoveFirewallRule(pNetFwPolicy2, exeName);
|
||||
}
|
||||
result = SUCCEEDED(hr);
|
||||
|
||||
Cleanup:
|
||||
|
||||
// Release INetFwPolicy2
|
||||
WFCOMCleanup(pNetFwPolicy2);
|
||||
|
||||
// Uninitialize COM.
|
||||
if (SUCCEEDED(hrComInit))
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BSTR MakeRuleName(__in LPWSTR exeName)
|
||||
{
|
||||
WCHAR pwszTemp[STRING_BUFFER_SIZE] = L"";
|
||||
HRESULT hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, L"%ls Service", exeName);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to compose a resource identifier string: 0x%08lx\n", hr);
|
||||
return NULL;
|
||||
}
|
||||
return SysAllocString(pwszTemp);
|
||||
}
|
||||
|
||||
HRESULT RemoveFirewallRule(
|
||||
__in INetFwPolicy2* pNetFwPolicy2,
|
||||
__in LPWSTR exeName)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
INetFwRules* pNetFwRules = NULL;
|
||||
|
||||
WCHAR pwszTemp[STRING_BUFFER_SIZE] = L"";
|
||||
|
||||
BSTR RuleName = NULL;
|
||||
|
||||
RuleName = MakeRuleName(exeName);
|
||||
if (NULL == RuleName)
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "\nERROR: Insufficient memory\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = pNetFwPolicy2->get_Rules(&pNetFwRules);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to retrieve firewall rules collection : 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// We need to "Remove()" twice, because both "in" and "out" rules are added?
|
||||
// There's no remarks for this case https://learn.microsoft.com/en-us/windows/win32/api/netfw/nf-netfw-inetfwrules-remove
|
||||
hr = pNetFwRules->Remove(RuleName);
|
||||
hr = pNetFwRules->Remove(RuleName);
|
||||
if (FAILED(hr)) {
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to remove firewall rule \"%ls\" : 0x%08lx\n", exeName, hr);
|
||||
}
|
||||
else {
|
||||
WcaLog(LOGMSG_STANDARD, "Firewall rule \"%ls\" is removed\n", exeName);
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
|
||||
SysFreeString(RuleName);
|
||||
|
||||
if (pNetFwRules != NULL)
|
||||
{
|
||||
pNetFwRules->Release();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Add firewall rule with EdgeTraversalOption=DeferApp (Windows7+) if available
|
||||
// else add with Edge=True (Vista and Server 2008).
|
||||
HRESULT AddFirewallRuleWithEdgeTraversal(
|
||||
__in INetFwPolicy2* pNetFwPolicy2,
|
||||
__in bool in,
|
||||
__in LPWSTR exeName,
|
||||
__in LPWSTR exeFile)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
INetFwRules* pNetFwRules = NULL;
|
||||
|
||||
INetFwRule* pNetFwRule = NULL;
|
||||
INetFwRule2* pNetFwRule2 = NULL;
|
||||
|
||||
WCHAR pwszTemp[STRING_BUFFER_SIZE] = L"";
|
||||
|
||||
BSTR RuleName = NULL;
|
||||
BSTR RuleGroupName = NULL;
|
||||
BSTR RuleDescription = NULL;
|
||||
BSTR RuleAppPath = NULL;
|
||||
|
||||
long CurrentProfilesBitMask = 0;
|
||||
|
||||
|
||||
// For localization purposes, the rule name, description, and group can be
|
||||
// provided as indirect strings. These indirect strings can be defined in an rc file.
|
||||
// Examples of the indirect string definitions in the rc file -
|
||||
// 127 "EdgeTraversalOptions Sample Application"
|
||||
// 128 "Allow inbound TCP traffic to application EdgeTraversalOptions.exe"
|
||||
// 129 "Allow EdgeTraversalOptions.exe to receive inbound traffic for TCP protocol
|
||||
// from remote machines located within your network as well as from
|
||||
// the Internet (i.e from outside of your Edge device like Firewall or NAT"
|
||||
|
||||
|
||||
// Examples of using indirect strings -
|
||||
// hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, L"@EdgeTraversalOptions.exe,-128");
|
||||
RuleName = MakeRuleName(exeName);
|
||||
if (NULL == RuleName)
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "\nERROR: Insufficient memory\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
// Examples of using indirect strings -
|
||||
// hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, L"@EdgeTraversalOptions.exe,-127");
|
||||
hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, exeName);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to compose a resource identifier string: 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
RuleGroupName = SysAllocString(pwszTemp); // Used for grouping together multiple rules
|
||||
if (NULL == RuleGroupName)
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "\nERROR: Insufficient memory\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
// Examples of using indirect strings -
|
||||
// hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, L"@EdgeTraversalOptions.exe,-129");
|
||||
hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, L"Allow %ls to receive \
|
||||
inbound traffic from remote machines located within your network as well as \
|
||||
from the Internet", exeName);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to compose a resource identifier string: 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
RuleDescription = SysAllocString(pwszTemp);
|
||||
if (NULL == RuleDescription)
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "\nERROR: Insufficient memory\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
RuleAppPath = SysAllocString(exeFile);
|
||||
if (NULL == RuleAppPath)
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "\nERROR: Insufficient memory\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = pNetFwPolicy2->get_Rules(&pNetFwRules);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to retrieve firewall rules collection : 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = CoCreateInstance(
|
||||
__uuidof(NetFwRule), //CLSID of the class whose object is to be created
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(INetFwRule), // Identifier of the Interface used for communicating with the object
|
||||
(void**)&pNetFwRule);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "CoCreateInstance for INetFwRule failed: 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = pNetFwRule->put_Name(RuleName);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Name failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = pNetFwRule->put_Grouping(RuleGroupName);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Grouping failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = pNetFwRule->put_Description(RuleDescription);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Description failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (in) {
|
||||
CurrentProfilesBitMask = NET_FW_PROFILE2_ALL;
|
||||
}
|
||||
else {
|
||||
// Retrieve Current Profiles bitmask
|
||||
hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// When possible we avoid adding firewall rules to the Public profile.
|
||||
// If Public is currently active and it is not the only active profile, we remove it from the bitmask
|
||||
if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) &&
|
||||
(CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC))
|
||||
{
|
||||
CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC;
|
||||
}
|
||||
}
|
||||
|
||||
hr = pNetFwRule->put_Direction(in ? NET_FW_RULE_DIR_IN : NET_FW_RULE_DIR_OUT);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Direction failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
||||
hr = pNetFwRule->put_Action(NET_FW_ACTION_ALLOW);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Action failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = pNetFwRule->put_ApplicationName(RuleAppPath);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_ApplicationName failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
//hr = pNetFwRule->put_Protocol(6); // TCP
|
||||
//if (FAILED(hr))
|
||||
//{
|
||||
// WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Protocol failed with error: 0x %x.\n", hr);
|
||||
// goto Cleanup;
|
||||
//}
|
||||
|
||||
hr = pNetFwRule->put_Profiles(CurrentProfilesBitMask);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Profiles failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
hr = pNetFwRule->put_Enabled(VARIANT_TRUE);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_Enabled failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (in) {
|
||||
// Check if INetFwRule2 interface is available (i.e Windows7+)
|
||||
// If supported, then use EdgeTraversalOptions
|
||||
// Else use the EdgeTraversal boolean flag.
|
||||
|
||||
if (SUCCEEDED(pNetFwRule->QueryInterface(__uuidof(INetFwRule2), (void**)&pNetFwRule2)))
|
||||
{
|
||||
hr = pNetFwRule2->put_EdgeTraversalOptions(NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_APP);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_EdgeTraversalOptions failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = pNetFwRule->put_EdgeTraversal(VARIANT_TRUE);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed INetFwRule::put_EdgeTraversal failed with error: 0x %x.\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr = pNetFwRules->Add(pNetFwRule);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "Failed to add firewall rule to the firewall rules collection : 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
WcaLog(LOGMSG_STANDARD, "Successfully added firewall rule !\n");
|
||||
|
||||
Cleanup:
|
||||
|
||||
SysFreeString(RuleName);
|
||||
SysFreeString(RuleGroupName);
|
||||
SysFreeString(RuleDescription);
|
||||
SysFreeString(RuleAppPath);
|
||||
|
||||
if (pNetFwRule2 != NULL)
|
||||
{
|
||||
pNetFwRule2->Release();
|
||||
}
|
||||
|
||||
if (pNetFwRule != NULL)
|
||||
{
|
||||
pNetFwRule->Release();
|
||||
}
|
||||
|
||||
if (pNetFwRules != NULL)
|
||||
{
|
||||
pNetFwRules->Release();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
// Instantiate INetFwPolicy2
|
||||
HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr = CoCreateInstance(
|
||||
__uuidof(NetFwPolicy2),
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(INetFwPolicy2),
|
||||
(void**)ppNetFwPolicy2);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
WcaLog(LOGMSG_STANDARD, "CoCreateInstance for INetFwPolicy2 failed: 0x%08lx\n", hr);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
// Release INetFwPolicy2
|
||||
void WFCOMCleanup(INetFwPolicy2* pNetFwPolicy2)
|
||||
{
|
||||
// Release the INetFwPolicy2 object (Vista+)
|
||||
if (pNetFwPolicy2 != NULL)
|
||||
{
|
||||
pNetFwPolicy2->Release();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user