1/*
2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/base/winfirewall.h"
12
13#include "webrtc/base/win32.h"
14
15#include <comdef.h>
16#include <netfw.h>
17
18#define RELEASE(lpUnk) do { \
19  if ((lpUnk) != NULL) { \
20    (lpUnk)->Release(); \
21    (lpUnk) = NULL; \
22  } \
23} while (0)
24
25namespace rtc {
26
27//////////////////////////////////////////////////////////////////////
28// WinFirewall
29//////////////////////////////////////////////////////////////////////
30
31WinFirewall::WinFirewall() : mgr_(NULL), policy_(NULL), profile_(NULL) {
32}
33
34WinFirewall::~WinFirewall() {
35  Shutdown();
36}
37
38bool WinFirewall::Initialize(HRESULT* result) {
39  if (mgr_) {
40    if (result) {
41      *result = S_OK;
42    }
43    return true;
44  }
45
46  HRESULT hr = CoCreateInstance(__uuidof(NetFwMgr),
47                                0, CLSCTX_INPROC_SERVER,
48                                __uuidof(INetFwMgr),
49                                reinterpret_cast<void **>(&mgr_));
50  if (SUCCEEDED(hr) && (mgr_ != NULL))
51    hr = mgr_->get_LocalPolicy(&policy_);
52  if (SUCCEEDED(hr) && (policy_ != NULL))
53    hr = policy_->get_CurrentProfile(&profile_);
54
55  if (result)
56    *result = hr;
57  return SUCCEEDED(hr) && (profile_ != NULL);
58}
59
60void WinFirewall::Shutdown() {
61  RELEASE(profile_);
62  RELEASE(policy_);
63  RELEASE(mgr_);
64}
65
66bool WinFirewall::Enabled() const {
67  if (!profile_)
68    return false;
69
70  VARIANT_BOOL fwEnabled = VARIANT_FALSE;
71  profile_->get_FirewallEnabled(&fwEnabled);
72  return (fwEnabled != VARIANT_FALSE);
73}
74
75bool WinFirewall::QueryAuthorized(const char* filename, bool* authorized)
76    const {
77  return QueryAuthorizedW(ToUtf16(filename).c_str(), authorized);
78}
79
80bool WinFirewall::QueryAuthorizedW(const wchar_t* filename, bool* authorized)
81    const {
82  *authorized = false;
83  bool success = false;
84
85  if (!profile_)
86    return false;
87
88  _bstr_t bfilename = filename;
89
90  INetFwAuthorizedApplications* apps = NULL;
91  HRESULT hr = profile_->get_AuthorizedApplications(&apps);
92  if (SUCCEEDED(hr) && (apps != NULL)) {
93    INetFwAuthorizedApplication* app = NULL;
94    hr = apps->Item(bfilename, &app);
95    if (SUCCEEDED(hr) && (app != NULL)) {
96      VARIANT_BOOL fwEnabled = VARIANT_FALSE;
97      hr = app->get_Enabled(&fwEnabled);
98      app->Release();
99
100      if (SUCCEEDED(hr)) {
101        success = true;
102        *authorized = (fwEnabled != VARIANT_FALSE);
103      }
104    } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
105      // No entry in list of authorized apps
106      success = true;
107    } else {
108      // Unexpected error
109    }
110    apps->Release();
111  }
112
113  return success;
114}
115
116bool WinFirewall::AddApplication(const char* filename,
117                                 const char* friendly_name,
118                                 bool authorized,
119                                 HRESULT* result) {
120  return AddApplicationW(ToUtf16(filename).c_str(),
121      ToUtf16(friendly_name).c_str(), authorized, result);
122}
123
124bool WinFirewall::AddApplicationW(const wchar_t* filename,
125                                  const wchar_t* friendly_name,
126                                  bool authorized,
127                                  HRESULT* result) {
128  INetFwAuthorizedApplications* apps = NULL;
129  HRESULT hr = profile_->get_AuthorizedApplications(&apps);
130  if (SUCCEEDED(hr) && (apps != NULL)) {
131    INetFwAuthorizedApplication* app = NULL;
132    hr = CoCreateInstance(__uuidof(NetFwAuthorizedApplication),
133                          0, CLSCTX_INPROC_SERVER,
134                          __uuidof(INetFwAuthorizedApplication),
135                          reinterpret_cast<void **>(&app));
136    if (SUCCEEDED(hr) && (app != NULL)) {
137      _bstr_t bstr = filename;
138      hr = app->put_ProcessImageFileName(bstr);
139      bstr = friendly_name;
140      if (SUCCEEDED(hr))
141        hr = app->put_Name(bstr);
142      if (SUCCEEDED(hr))
143        hr = app->put_Enabled(authorized ? VARIANT_TRUE : VARIANT_FALSE);
144      if (SUCCEEDED(hr))
145        hr = apps->Add(app);
146      app->Release();
147    }
148    apps->Release();
149  }
150  if (result)
151    *result = hr;
152  return SUCCEEDED(hr);
153}
154
155}  // namespace rtc
156