VirtualBox

source: vbox/trunk/src/VBox/Main/NATEngineImpl.cpp@ 33825

Last change on this file since 33825 was 33825, checked in by vboxsync, 14 years ago

Main,NAT: Managing port-forwarding at runtime. (xTracker/#4835).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.0 KB
Line 
1/* $Id: NATEngineImpl.cpp 33825 2010-11-08 10:16:25Z vboxsync $ */
2/** @file
3 * Implementation of INATEngine in VBoxSVC.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "NATEngineImpl.h"
19#include "AutoCaller.h"
20#include "Logging.h"
21#include "MachineImpl.h"
22#include "GuestOSTypeImpl.h"
23
24#include <iprt/string.h>
25#include <iprt/cpp/utils.h>
26
27#include <VBox/err.h>
28#include <VBox/settings.h>
29
30
31// constructor / destructor
32////////////////////////////////////////////////////////////////////////////////
33
34NATEngine::NATEngine():mParent(NULL), mAdapter(NULL){}
35NATEngine::~NATEngine(){}
36
37HRESULT NATEngine::FinalConstruct()
38{
39 return S_OK;
40}
41
42HRESULT NATEngine::init(Machine *aParent, INetworkAdapter *aAdapter)
43{
44 AutoInitSpan autoInitSpan(this);
45 AssertReturn(autoInitSpan.isOk(), E_FAIL);
46 autoInitSpan.setSucceeded();
47 m_fModified = false;
48 mData.allocate();
49 mData->mNetwork.setNull();
50 mData->mBindIP.setNull();
51 unconst(mParent) = aParent;
52 unconst(mAdapter) = aAdapter;
53 return S_OK;
54}
55
56HRESULT NATEngine::init(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat)
57{
58 AutoInitSpan autoInitSpan(this);
59 AssertReturn(autoInitSpan.isOk(), E_FAIL);
60 Log(("init that:%p this:%p\n", aThat, this));
61
62 AutoCaller thatCaller (aThat);
63 AssertComRCReturnRC(thatCaller.rc());
64
65 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
66
67 mData.share(aThat->mData);
68 NATRuleMap::iterator it;
69 mNATRules.clear();
70 for (it = aThat->mNATRules.begin(); it != aThat->mNATRules.end(); ++it)
71 {
72 mNATRules.insert(std::make_pair(it->first, it->second));
73 }
74 unconst(mParent) = aParent;
75 unconst(mAdapter) = aAdapter;
76 unconst(mPeer) = aThat;
77 autoInitSpan.setSucceeded();
78 return S_OK;
79}
80
81HRESULT NATEngine::initCopy (Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat)
82{
83 AutoInitSpan autoInitSpan(this);
84 AssertReturn(autoInitSpan.isOk(), E_FAIL);
85
86 Log(("initCopy that:%p this:%p\n", aThat, this));
87
88 AutoCaller thatCaller (aThat);
89 AssertComRCReturnRC(thatCaller.rc());
90
91 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
92
93 mData.attachCopy(aThat->mData);
94 NATRuleMap::iterator it;
95 mNATRules.clear();
96 for (it = aThat->mNATRules.begin(); it != aThat->mNATRules.end(); ++it)
97 {
98 mNATRules.insert(std::make_pair(it->first, it->second));
99 }
100 unconst(mAdapter) = aAdapter;
101 unconst(mParent) = aParent;
102 autoInitSpan.setSucceeded();
103 return S_OK;
104}
105
106
107void NATEngine::FinalRelease()
108{
109 uninit();
110}
111
112void NATEngine::uninit()
113{
114 AutoUninitSpan autoUninitSpan(this);
115 if (autoUninitSpan.uninitDone())
116 return;
117
118 mNATRules.clear();
119 mData.free();
120 unconst(mPeer) = NULL;
121 unconst(mParent) = NULL;
122}
123
124bool NATEngine::isModified()
125{
126 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
127 bool fModified = m_fModified;
128 return fModified;
129}
130
131bool NATEngine::rollback()
132{
133 AutoCaller autoCaller(this);
134 AssertComRCReturn (autoCaller.rc(), false);
135
136 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
137 bool fChanged = m_fModified;
138
139 if (m_fModified)
140 {
141 /* we need to check all data to see whether anything will be changed
142 * after rollback */
143 mData.rollback();
144 }
145 m_fModified = false;
146 return fChanged;
147}
148
149void NATEngine::commit()
150{
151 AutoCaller autoCaller(this);
152 AssertComRCReturnVoid (autoCaller.rc());
153
154 /* sanity too */
155 AutoCaller peerCaller (mPeer);
156 AssertComRCReturnVoid (peerCaller.rc());
157
158 /* lock both for writing since we modify both (mPeer is "master" so locked
159 * first) */
160 AutoMultiWriteLock2 alock(mPeer, this COMMA_LOCKVAL_SRC_POS);
161 if (m_fModified)
162 {
163 mData.commit();
164 if (mPeer)
165 {
166 mPeer->mData.attach (mData);
167 mPeer->mNATRules.clear();
168 NATRuleMap::iterator it;
169 for (it = mNATRules.begin(); it != mNATRules.end(); ++it)
170 {
171 mPeer->mNATRules.insert(std::make_pair(it->first, it->second));
172 }
173 }
174 }
175 m_fModified = false;
176}
177
178STDMETHODIMP
179NATEngine::GetNetworkSettings(ULONG *aMtu, ULONG *aSockSnd, ULONG *aSockRcv, ULONG *aTcpWndSnd, ULONG *aTcpWndRcv)
180{
181 AutoCaller autoCaller(this);
182 if (FAILED(autoCaller.rc())) return autoCaller.rc();
183
184 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
185 if (aMtu)
186 *aMtu = mData->mMtu;
187 if (aSockSnd)
188 *aSockSnd = mData->mSockSnd;
189 if (aSockRcv)
190 *aSockRcv = mData->mSockRcv;
191 if (aTcpWndSnd)
192 *aTcpWndSnd = mData->mTcpSnd;
193 if (aTcpWndRcv)
194 *aTcpWndRcv = mData->mTcpRcv;
195
196 return S_OK;
197}
198
199STDMETHODIMP
200NATEngine::SetNetworkSettings(ULONG aMtu, ULONG aSockSnd, ULONG aSockRcv, ULONG aTcpWndSnd, ULONG aTcpWndRcv)
201{
202 AutoCaller autoCaller(this);
203 if (FAILED(autoCaller.rc())) return autoCaller.rc();
204
205 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
206 if ( aMtu || aSockSnd || aSockRcv
207 || aTcpWndSnd || aTcpWndRcv)
208 {
209 mData.backup();
210 m_fModified = true;
211 }
212 if (aMtu)
213 mData->mMtu = aMtu;
214 if (aSockSnd)
215 mData->mSockSnd = aSockSnd;
216 if (aSockRcv)
217 mData->mSockRcv = aSockSnd;
218 if (aTcpWndSnd)
219 mData->mTcpSnd = aTcpWndSnd;
220 if (aTcpWndRcv)
221 mData->mTcpRcv = aTcpWndRcv;
222
223 if (m_fModified)
224 mParent->setModified(Machine::IsModified_NetworkAdapters);
225 return S_OK;
226}
227
228STDMETHODIMP
229NATEngine::COMGETTER(Redirects)(ComSafeArrayOut(BSTR , aNatRules))
230{
231 CheckComArgOutSafeArrayPointerValid(aNatRules);
232
233 AutoCaller autoCaller(this);
234 if (FAILED(autoCaller.rc())) return autoCaller.rc();
235
236 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
237
238
239 SafeArray<BSTR> sf(mNATRules.size());
240 size_t i = 0;
241 NATRuleMap::const_iterator it;
242 for (it = mNATRules.begin();
243 it != mNATRules.end(); ++it, ++i)
244 {
245 settings::NATRule r = it->second;
246 BstrFmt bstr("%s,%d,%s,%d,%s,%d",
247 r.strName.c_str(),
248 r.u32Proto,
249 r.strHostIP.c_str(),
250 r.u16HostPort,
251 r.strGuestIP.c_str(),
252 r.u16GuestPort);
253 bstr.detachTo(&sf[i]);
254 }
255 sf.detachTo(ComSafeArrayOutArg(aNatRules));
256 return S_OK;
257}
258
259
260STDMETHODIMP
261NATEngine::AddRedirect(IN_BSTR aName, NATProtocol_T aProto, IN_BSTR aBindIp, USHORT aHostPort, IN_BSTR aGuestIP, USHORT aGuestPort)
262{
263
264 AutoCaller autoCaller(this);
265 if (FAILED(autoCaller.rc())) return autoCaller.rc();
266
267 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
268 Utf8Str name = aName;
269 settings::NATRule r;
270 const char *proto;
271 switch (aProto)
272 {
273 case NATProtocol_TCP:
274 proto = "tcp";
275 break;
276 case NATProtocol_UDP:
277 proto = "udp";
278 break;
279 default:
280 return E_INVALIDARG;
281 }
282 if (name.isEmpty())
283 name = Utf8StrFmt("%s_%d_%d", proto, aHostPort, aGuestPort);
284 r.strName = name.c_str();
285 r.u32Proto = aProto;
286 r.strHostIP = aBindIp;
287 r.u16HostPort = aHostPort;
288 r.strGuestIP = aGuestIP;
289 r.u16GuestPort = aGuestPort;
290 mNATRules.insert(std::make_pair(name, r));
291 mParent->setModified(Machine::IsModified_NetworkAdapters);
292 m_fModified = true;
293 alock.release();
294 mParent->onNATRedirectRuleChange(mAdapter, FALSE, Bstr(name).raw(), aProto, Bstr(r.strHostIP).raw(), r.u16HostPort, Bstr(r.strGuestIP).raw(), r.u16GuestPort);
295 return S_OK;
296}
297
298STDMETHODIMP
299NATEngine::RemoveRedirect(IN_BSTR aName)
300{
301 AutoCaller autoCaller(this);
302 if (FAILED(autoCaller.rc())) return autoCaller.rc();
303
304 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
305 NATRuleMap::iterator it = mNATRules.find(aName);
306 if (it == mNATRules.end())
307 return E_INVALIDARG;
308 mData.backup();
309 settings::NATRule r = it->second;
310 Utf8Str strHostIP = r.strHostIP;
311 Utf8Str strGuestIP = r.strGuestIP;
312 NATProtocol_T proto = r.u32Proto;
313 uint16_t u16HostPort = r.u16HostPort;
314 uint16_t u16GuestPort = r.u16GuestPort;
315
316 mNATRules.erase(it);
317 mParent->setModified(Machine::IsModified_NetworkAdapters);
318 m_fModified = true;
319 alock.release();
320 mParent->onNATRedirectRuleChange(mAdapter, TRUE, aName, proto, Bstr(strHostIP).raw(), u16HostPort, Bstr(strGuestIP).raw(), u16GuestPort);
321 return S_OK;
322}
323
324HRESULT NATEngine::loadSettings(const settings::NAT &data)
325{
326 AutoCaller autoCaller(this);
327 AssertComRCReturnRC(autoCaller.rc());
328
329 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
330 HRESULT rc = S_OK;
331 mData->mNetwork = data.strNetwork;
332 mData->mBindIP = data.strBindIP;
333 mData->mMtu = data.u32Mtu;
334 mData->mSockSnd = data.u32SockSnd;
335 mData->mTcpRcv = data.u32TcpRcv;
336 mData->mTcpSnd = data.u32TcpSnd;
337 /* TFTP */
338 mData->mTftpPrefix = data.strTftpPrefix;
339 mData->mTftpBootFile = data.strTftpBootFile;
340 mData->mTftpNextServer = data.strTftpNextServer;
341 /* DNS */
342 mData->mDnsPassDomain = data.fDnsPassDomain;
343 mData->mDnsProxy = data.fDnsProxy;
344 mData->mDnsUseHostResolver = data.fDnsUseHostResolver;
345 /* Alias */
346 mData->mAliasMode = (data.fAliasUseSamePorts ? NATAliasMode_AliasUseSamePorts : 0);
347 mData->mAliasMode |= (data.fAliasLog ? NATAliasMode_AliasLog : 0);
348 mData->mAliasMode |= (data.fAliasProxyOnly ? NATAliasMode_AliasProxyOnly : 0);
349 /* port forwarding */
350 mNATRules.clear();
351 for (settings::NATRuleList::const_iterator it = data.llRules.begin();
352 it != data.llRules.end(); ++it)
353 {
354 mNATRules.insert(std::make_pair(it->strName, *it));
355 }
356 m_fModified = false;
357 return rc;
358}
359
360
361HRESULT NATEngine::saveSettings(settings::NAT &data)
362{
363 AutoCaller autoCaller(this);
364 AssertComRCReturnRC(autoCaller.rc());
365
366 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
367 HRESULT rc = S_OK;
368 data.strNetwork = mData->mNetwork;
369 data.strBindIP = mData->mBindIP;
370 data.u32Mtu = mData->mMtu;
371 data.u32SockRcv = mData->mSockRcv;
372 data.u32SockSnd = mData->mSockSnd;
373 data.u32TcpRcv = mData->mTcpRcv;
374 data.u32TcpSnd = mData->mTcpSnd;
375 /* TFTP */
376 data.strTftpPrefix = mData->mTftpPrefix;
377 data.strTftpBootFile = mData->mTftpBootFile;
378 data.strTftpNextServer = mData->mTftpNextServer;
379 /* DNS */
380 data.fDnsPassDomain = !!mData->mDnsPassDomain;
381 data.fDnsProxy = !!mData->mDnsProxy;
382 data.fDnsUseHostResolver = !!mData->mDnsUseHostResolver;
383 /* Alias */
384 data.fAliasLog = !!(mData->mAliasMode & NATAliasMode_AliasLog);
385 data.fAliasProxyOnly = !!(mData->mAliasMode & NATAliasMode_AliasProxyOnly);
386 data.fAliasUseSamePorts = !!(mData->mAliasMode & NATAliasMode_AliasUseSamePorts);
387
388 for (NATRuleMap::iterator it = mNATRules.begin();
389 it != mNATRules.end(); ++it)
390 data.llRules.push_back(it->second);
391 m_fModified = false;
392 return rc;
393}
394
395
396STDMETHODIMP
397NATEngine::COMSETTER(Network)(IN_BSTR aNetwork)
398{
399 AutoCaller autoCaller(this);
400 AssertComRCReturnRC (autoCaller.rc());
401 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
402 if (Bstr(mData->mNetwork) != aNetwork)
403 {
404 mData.backup();
405 mData->mNetwork = aNetwork;
406 mParent->setModified(Machine::IsModified_NetworkAdapters);
407 m_fModified = true;
408 }
409 return S_OK;
410}
411
412STDMETHODIMP
413NATEngine::COMGETTER(Network)(BSTR *aNetwork)
414{
415 CheckComArgNotNull(aNetwork);
416 AutoCaller autoCaller(this);
417 AssertComRCReturnRC(autoCaller.rc());
418
419 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
420 if (!mData->mNetwork.isEmpty())
421 {
422 mData->mNetwork.cloneTo(aNetwork);
423 Log(("Getter (this:%p) Network: %s\n", this, mData->mNetwork.c_str()));
424 }
425 return S_OK;
426}
427
428STDMETHODIMP
429NATEngine::COMSETTER(HostIP) (IN_BSTR aBindIP)
430{
431 AutoCaller autoCaller(this);
432 AssertComRCReturnRC (autoCaller.rc());
433 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
434 if (Bstr(mData->mBindIP) != aBindIP)
435 {
436 mData.backup();
437 mData->mBindIP = aBindIP;
438 mParent->setModified(Machine::IsModified_NetworkAdapters);
439 m_fModified = true;
440 }
441 return S_OK;
442}
443STDMETHODIMP NATEngine::COMGETTER(HostIP) (BSTR *aBindIP)
444{
445 AutoCaller autoCaller(this);
446 AssertComRCReturnRC(autoCaller.rc());
447
448 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
449 if (!mData->mBindIP.isEmpty())
450 mData->mBindIP.cloneTo(aBindIP);
451 return S_OK;
452}
453
454
455STDMETHODIMP
456NATEngine::COMSETTER(TftpPrefix)(IN_BSTR aTftpPrefix)
457{
458 AutoCaller autoCaller(this);
459 AssertComRCReturnRC (autoCaller.rc());
460 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
461 if (Bstr(mData->mTftpPrefix) != aTftpPrefix)
462 {
463 mData.backup();
464 mData->mTftpPrefix = aTftpPrefix;
465 mParent->setModified(Machine::IsModified_NetworkAdapters);
466 m_fModified = true;
467 }
468 return S_OK;
469}
470
471STDMETHODIMP
472NATEngine::COMGETTER(TftpPrefix)(BSTR *aTftpPrefix)
473{
474 AutoCaller autoCaller(this);
475 AssertComRCReturnRC(autoCaller.rc());
476
477 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
478 if (!mData->mTftpPrefix.isEmpty())
479 {
480 mData->mTftpPrefix.cloneTo(aTftpPrefix);
481 Log(("Getter (this:%p) TftpPrefix: %s\n", this, mData->mTftpPrefix.c_str()));
482 }
483 return S_OK;
484}
485
486STDMETHODIMP
487NATEngine::COMSETTER(TftpBootFile)(IN_BSTR aTftpBootFile)
488{
489 AutoCaller autoCaller(this);
490 AssertComRCReturnRC (autoCaller.rc());
491 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
492 if (Bstr(mData->mTftpBootFile) != aTftpBootFile)
493 {
494 mData.backup();
495 mData->mTftpBootFile = aTftpBootFile;
496 mParent->setModified(Machine::IsModified_NetworkAdapters);
497 m_fModified = true;
498 }
499 return S_OK;
500}
501
502STDMETHODIMP
503NATEngine::COMGETTER(TftpBootFile)(BSTR *aTftpBootFile)
504{
505 AutoCaller autoCaller(this);
506 AssertComRCReturnRC(autoCaller.rc());
507
508 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
509 if (!mData->mTftpBootFile.isEmpty())
510 {
511 mData->mTftpBootFile.cloneTo(aTftpBootFile);
512 Log(("Getter (this:%p) BootFile: %s\n", this, mData->mTftpBootFile.c_str()));
513 }
514 return S_OK;
515}
516
517STDMETHODIMP
518NATEngine::COMSETTER(TftpNextServer)(IN_BSTR aTftpNextServer)
519{
520 AutoCaller autoCaller(this);
521 AssertComRCReturnRC (autoCaller.rc());
522 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
523 if (Bstr(mData->mTftpNextServer) != aTftpNextServer)
524 {
525 mData.backup();
526 mData->mTftpNextServer = aTftpNextServer;
527 mParent->setModified(Machine::IsModified_NetworkAdapters);
528 m_fModified = true;
529 }
530 return S_OK;
531}
532
533STDMETHODIMP
534NATEngine::COMGETTER(TftpNextServer)(BSTR *aTftpNextServer)
535{
536 AutoCaller autoCaller(this);
537 AssertComRCReturnRC(autoCaller.rc());
538
539 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
540 if (!mData->mTftpNextServer.isEmpty())
541 {
542 mData->mTftpNextServer.cloneTo(aTftpNextServer);
543 Log(("Getter (this:%p) NextServer: %s\n", this, mData->mTftpNextServer.c_str()));
544 }
545 return S_OK;
546}
547/* DNS */
548STDMETHODIMP
549NATEngine::COMSETTER(DnsPassDomain) (BOOL aDnsPassDomain)
550{
551 AutoCaller autoCaller(this);
552 AssertComRCReturnRC (autoCaller.rc());
553 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
554
555 if (mData->mDnsPassDomain != aDnsPassDomain)
556 {
557 mData.backup();
558 mData->mDnsPassDomain = aDnsPassDomain;
559 mParent->setModified(Machine::IsModified_NetworkAdapters);
560 m_fModified = true;
561 }
562 return S_OK;
563}
564STDMETHODIMP
565NATEngine::COMGETTER(DnsPassDomain)(BOOL *aDnsPassDomain)
566{
567 AutoCaller autoCaller(this);
568 AssertComRCReturnRC(autoCaller.rc());
569
570 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
571 *aDnsPassDomain = mData->mDnsPassDomain;
572 return S_OK;
573}
574STDMETHODIMP
575NATEngine::COMSETTER(DnsProxy)(BOOL aDnsProxy)
576{
577 AutoCaller autoCaller(this);
578 AssertComRCReturnRC (autoCaller.rc());
579 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
580
581 if (mData->mDnsProxy != aDnsProxy)
582 {
583 mData.backup();
584 mData->mDnsProxy = aDnsProxy;
585 mParent->setModified(Machine::IsModified_NetworkAdapters);
586 m_fModified = true;
587 }
588 return S_OK;
589}
590STDMETHODIMP
591NATEngine::COMGETTER(DnsProxy)(BOOL *aDnsProxy)
592{
593 AutoCaller autoCaller(this);
594 AssertComRCReturnRC(autoCaller.rc());
595
596 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
597 *aDnsProxy = mData->mDnsProxy;
598 return S_OK;
599}
600STDMETHODIMP
601NATEngine::COMGETTER(DnsUseHostResolver)(BOOL *aDnsUseHostResolver)
602{
603 AutoCaller autoCaller(this);
604 AssertComRCReturnRC (autoCaller.rc());
605 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
606 *aDnsUseHostResolver = mData->mDnsUseHostResolver;
607 return S_OK;
608}
609STDMETHODIMP
610NATEngine::COMSETTER(DnsUseHostResolver)(BOOL aDnsUseHostResolver)
611{
612 AutoCaller autoCaller(this);
613 AssertComRCReturnRC(autoCaller.rc());
614
615 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
616
617 if (mData->mDnsUseHostResolver != aDnsUseHostResolver)
618 {
619 mData.backup();
620 mData->mDnsUseHostResolver = aDnsUseHostResolver;
621 mParent->setModified(Machine::IsModified_NetworkAdapters);
622 m_fModified = true;
623 }
624 return S_OK;
625}
626
627STDMETHODIMP NATEngine::COMSETTER(AliasMode) (ULONG aAliasMode)
628{
629 AutoCaller autoCaller(this);
630 AssertComRCReturnRC(autoCaller.rc());
631
632 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
633
634 if (mData->mAliasMode != aAliasMode)
635 {
636 mData.backup();
637 mData->mAliasMode = aAliasMode;
638 mParent->setModified(Machine::IsModified_NetworkAdapters);
639 m_fModified = true;
640 }
641 return S_OK;
642}
643
644STDMETHODIMP NATEngine::COMGETTER(AliasMode) (ULONG *aAliasMode)
645{
646 AutoCaller autoCaller(this);
647 AssertComRCReturnRC (autoCaller.rc());
648 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
649 *aAliasMode = mData->mAliasMode;
650 return S_OK;
651}
652
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette