~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Main/src-server/win/NetIf-win.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: NetIf-win.cpp 35368 2010-12-30 13:38:23Z vboxsync $ */
 
2
/** @file
 
3
 * Main - NetIfList, Windows implementation.
 
4
 */
 
5
 
 
6
/*
 
7
 * Copyright (C) 2008-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
 
 
19
 
 
20
/*******************************************************************************
 
21
*   Header Files                                                               *
 
22
*******************************************************************************/
 
23
#define LOG_GROUP LOG_GROUP_MAIN
 
24
 
 
25
#include <iprt/asm.h>
 
26
#include <iprt/err.h>
 
27
#include <list>
 
28
 
 
29
#define _WIN32_DCOM
 
30
#include <winsock2.h>
 
31
#include <ws2tcpip.h>
 
32
#include <windows.h>
 
33
 
 
34
#ifdef VBOX_WITH_NETFLT
 
35
#include "VBox/WinNetConfig.h"
 
36
#include "devguid.h"
 
37
#endif
 
38
 
 
39
#include <iphlpapi.h>
 
40
 
 
41
#include "Logging.h"
 
42
#include "HostNetworkInterfaceImpl.h"
 
43
#include "ProgressImpl.h"
 
44
#include "VirtualBoxImpl.h"
 
45
#include "netif.h"
 
46
 
 
47
#ifdef VBOX_WITH_NETFLT
 
48
#include <Wbemidl.h>
 
49
#include <comdef.h>
 
50
 
 
51
#include "svchlp.h"
 
52
 
 
53
#include <shellapi.h>
 
54
#define INITGUID
 
55
#include <guiddef.h>
 
56
#include <devguid.h>
 
57
#include <objbase.h>
 
58
#include <setupapi.h>
 
59
#include <shlobj.h>
 
60
#include <cfgmgr32.h>
 
61
 
 
62
#define VBOX_APP_NAME L"VirtualBox"
 
63
 
 
64
static int getDefaultInterfaceIndex()
 
65
{
 
66
    PMIB_IPFORWARDTABLE pIpTable;
 
67
    DWORD dwSize = sizeof(MIB_IPFORWARDTABLE) * 20;
 
68
    DWORD dwRC = NO_ERROR;
 
69
    int iIndex = -1;
 
70
 
 
71
    pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
 
72
    if (GetIpForwardTable(pIpTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
 
73
    {
 
74
        RTMemFree(pIpTable);
 
75
        pIpTable = (MIB_IPFORWARDTABLE *)RTMemAlloc(dwSize);
 
76
        if (!pIpTable)
 
77
            return -1;
 
78
    }
 
79
    dwRC = GetIpForwardTable(pIpTable, &dwSize, 0);
 
80
    if (dwRC == NO_ERROR)
 
81
    {
 
82
        for (unsigned int i = 0; i < pIpTable->dwNumEntries; i++)
 
83
            if (pIpTable->table[i].dwForwardDest == 0)
 
84
            {
 
85
                iIndex = pIpTable->table[i].dwForwardIfIndex;
 
86
                break;
 
87
            }
 
88
    }
 
89
    RTMemFree(pIpTable);
 
90
    return iIndex;
 
91
}
 
92
 
 
93
static int collectNetIfInfo(Bstr &strName, Guid &guid, PNETIFINFO pInfo, int iDefault)
 
94
{
 
95
    DWORD dwRc;
 
96
    int rc = VINF_SUCCESS;
 
97
    /*
 
98
     * Most of the hosts probably have less than 10 adapters,
 
99
     * so we'll mostly succeed from the first attempt.
 
100
     */
 
101
    ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;
 
102
    PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
 
103
    if (!pAddresses)
 
104
        return VERR_NO_MEMORY;
 
105
    dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
 
106
    if (dwRc == ERROR_BUFFER_OVERFLOW)
 
107
    {
 
108
        /* Impressive! More than 10 adapters! Get more memory and try again. */
 
109
        RTMemFree(pAddresses);
 
110
        pAddresses = (PIP_ADAPTER_ADDRESSES)RTMemAlloc(uBufLen);
 
111
        if (!pAddresses)
 
112
            return VERR_NO_MEMORY;
 
113
        dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen);
 
114
    }
 
115
    if (dwRc == NO_ERROR)
 
116
    {
 
117
        PIP_ADAPTER_ADDRESSES pAdapter;
 
118
        for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next)
 
119
        {
 
120
            char *pszUuid = RTStrDup(pAdapter->AdapterName);
 
121
            size_t len = strlen(pszUuid) - 1;
 
122
            if (pszUuid[0] == '{' && pszUuid[len] == '}')
 
123
            {
 
124
                pszUuid[len] = 0;
 
125
                if (!RTUuidCompareStr(&pInfo->Uuid, pszUuid + 1))
 
126
                {
 
127
                    bool fIPFound, fIPv6Found;
 
128
                    PIP_ADAPTER_UNICAST_ADDRESS pAddr;
 
129
                    fIPFound = fIPv6Found = false;
 
130
                    for (pAddr = pAdapter->FirstUnicastAddress; pAddr; pAddr = pAddr->Next)
 
131
                    {
 
132
                        switch (pAddr->Address.lpSockaddr->sa_family)
 
133
                        {
 
134
                            case AF_INET:
 
135
                                if (!fIPFound)
 
136
                                {
 
137
                                    fIPFound = true;
 
138
                                    memcpy(&pInfo->IPAddress,
 
139
                                        &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr,
 
140
                                        sizeof(pInfo->IPAddress));
 
141
                                }
 
142
                                break;
 
143
                            case AF_INET6:
 
144
                                if (!fIPv6Found)
 
145
                                {
 
146
                                    fIPv6Found = true;
 
147
                                    memcpy(&pInfo->IPv6Address,
 
148
                                        ((struct sockaddr_in6 *)pAddr->Address.lpSockaddr)->sin6_addr.s6_addr,
 
149
                                        sizeof(pInfo->IPv6Address));
 
150
                                }
 
151
                                break;
 
152
                        }
 
153
                    }
 
154
                    PIP_ADAPTER_PREFIX pPrefix;
 
155
                    fIPFound = fIPv6Found = false;
 
156
                    for (pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
 
157
                    {
 
158
                        switch (pPrefix->Address.lpSockaddr->sa_family)
 
159
                        {
 
160
                            case AF_INET:
 
161
                                if (!fIPFound)
 
162
                                {
 
163
                                    if (pPrefix->PrefixLength <= sizeof(pInfo->IPNetMask) * 8)
 
164
                                    {
 
165
                                        fIPFound = true;
 
166
                                        ASMBitSetRange(&pInfo->IPNetMask, 0, pPrefix->PrefixLength);
 
167
                                    }
 
168
                                    else
 
169
                                        Log(("collectNetIfInfo: Unexpected IPv4 prefix length of %d\n",
 
170
                                             pPrefix->PrefixLength));
 
171
                                }
 
172
                                break;
 
173
                            case AF_INET6:
 
174
                                if (!fIPv6Found)
 
175
                                {
 
176
                                    if (pPrefix->PrefixLength <= sizeof(pInfo->IPv6NetMask) * 8)
 
177
                                    {
 
178
                                        fIPv6Found = true;
 
179
                                        ASMBitSetRange(&pInfo->IPv6NetMask, 0, pPrefix->PrefixLength);
 
180
                                    }
 
181
                                    else
 
182
                                        Log(("collectNetIfInfo: Unexpected IPv6 prefix length of %d\n",
 
183
                                             pPrefix->PrefixLength));
 
184
                                }
 
185
                                break;
 
186
                        }
 
187
                    }
 
188
                    if (sizeof(pInfo->MACAddress) != pAdapter->PhysicalAddressLength)
 
189
                        Log(("collectNetIfInfo: Unexpected physical address length: %u\n", pAdapter->PhysicalAddressLength));
 
190
                    else
 
191
                        memcpy(pInfo->MACAddress.au8, pAdapter->PhysicalAddress, sizeof(pInfo->MACAddress));
 
192
                    pInfo->enmMediumType = NETIF_T_ETHERNET;
 
193
                    pInfo->enmStatus = pAdapter->OperStatus == IfOperStatusUp ? NETIF_S_UP : NETIF_S_DOWN;
 
194
                    pInfo->bIsDefault = (pAdapter->IfIndex == iDefault);
 
195
                    RTStrFree(pszUuid);
 
196
                    break;
 
197
                }
 
198
            }
 
199
            RTStrFree(pszUuid);
 
200
        }
 
201
 
 
202
        ADAPTER_SETTINGS Settings;
 
203
        HRESULT hr = VBoxNetCfgWinGetAdapterSettings((const GUID *)guid.raw(), &Settings);
 
204
        if (hr == S_OK)
 
205
        {
 
206
            if (Settings.ip)
 
207
            {
 
208
                pInfo->IPAddress.u = Settings.ip;
 
209
                pInfo->IPNetMask.u = Settings.mask;
 
210
            }
 
211
            pInfo->bDhcpEnabled = Settings.bDhcp;
 
212
        }
 
213
        else
 
214
        {
 
215
            pInfo->bDhcpEnabled = false;
 
216
        }
 
217
    }
 
218
    RTMemFree(pAddresses);
 
219
 
 
220
    return VINF_SUCCESS;
 
221
}
 
222
 
 
223
/* svc helper func */
 
224
 
 
225
struct StaticIpConfig
 
226
{
 
227
    ULONG  IPAddress;
 
228
    ULONG  IPNetMask;
 
229
};
 
230
 
 
231
struct StaticIpV6Config
 
232
{
 
233
    BSTR           IPV6Address;
 
234
    ULONG          IPV6NetMaskLength;
 
235
};
 
236
 
 
237
struct NetworkInterfaceHelperClientData
 
238
{
 
239
    SVCHlpMsg::Code msgCode;
 
240
    /* for SVCHlpMsg::CreateHostOnlyNetworkInterface */
 
241
    Bstr name;
 
242
    ComObjPtr<HostNetworkInterface> iface;
 
243
    ComObjPtr<VirtualBox> vBox;
 
244
    /* for SVCHlpMsg::RemoveHostOnlyNetworkInterface */
 
245
    Guid guid;
 
246
 
 
247
    union
 
248
    {
 
249
        StaticIpConfig StaticIP;
 
250
        StaticIpV6Config StaticIPV6;
 
251
    } u;
 
252
 
 
253
 
 
254
};
 
255
 
 
256
static HRESULT netIfNetworkInterfaceHelperClient(SVCHlpClient *aClient,
 
257
                                                 Progress *aProgress,
 
258
                                                 void *aUser, int *aVrc)
 
259
{
 
260
    LogFlowFuncEnter();
 
261
    LogFlowFunc(("aClient={%p}, aProgress={%p}, aUser={%p}\n",
 
262
                 aClient, aProgress, aUser));
 
263
 
 
264
    AssertReturn(   (aClient == NULL && aProgress == NULL && aVrc == NULL)
 
265
                 || (aClient != NULL && aProgress != NULL && aVrc != NULL),
 
266
                 E_POINTER);
 
267
    AssertReturn(aUser, E_POINTER);
 
268
 
 
269
    std::auto_ptr<NetworkInterfaceHelperClientData>
 
270
        d(static_cast<NetworkInterfaceHelperClientData *>(aUser));
 
271
 
 
272
    if (aClient == NULL)
 
273
    {
 
274
        /* "cleanup only" mode, just return (it will free aUser) */
 
275
        return S_OK;
 
276
    }
 
277
 
 
278
    HRESULT rc = S_OK;
 
279
    int vrc = VINF_SUCCESS;
 
280
 
 
281
    switch (d->msgCode)
 
282
    {
 
283
        case SVCHlpMsg::CreateHostOnlyNetworkInterface:
 
284
        {
 
285
            LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
 
286
            LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
 
287
 
 
288
            /* write message and parameters */
 
289
            vrc = aClient->write(d->msgCode);
 
290
            if (RT_FAILURE(vrc)) break;
 
291
//            vrc = aClient->write(Utf8Str(d->name));
 
292
//            if (RT_FAILURE(vrc)) break;
 
293
 
 
294
            /* wait for a reply */
 
295
            bool endLoop = false;
 
296
            while (!endLoop)
 
297
            {
 
298
                SVCHlpMsg::Code reply = SVCHlpMsg::Null;
 
299
 
 
300
                vrc = aClient->read(reply);
 
301
                if (RT_FAILURE(vrc)) break;
 
302
 
 
303
                switch (reply)
 
304
                {
 
305
                    case SVCHlpMsg::CreateHostOnlyNetworkInterface_OK:
 
306
                    {
 
307
                        /* read the GUID */
 
308
                        Guid guid;
 
309
                        Utf8Str name;
 
310
                        vrc = aClient->read(name);
 
311
                        if (RT_FAILURE(vrc)) break;
 
312
                        vrc = aClient->read(guid);
 
313
                        if (RT_FAILURE(vrc)) break;
 
314
 
 
315
                        LogFlowFunc(("Network connection GUID = {%RTuuid}\n", guid.raw()));
 
316
 
 
317
                        /* initialize the object returned to the caller by
 
318
                         * CreateHostOnlyNetworkInterface() */
 
319
                        rc = d->iface->init(Bstr(name), guid, HostNetworkInterfaceType_HostOnly);
 
320
                        if (SUCCEEDED(rc))
 
321
                        {
 
322
                            rc = d->iface->setVirtualBox(d->vBox);
 
323
                            if (SUCCEEDED(rc))
 
324
                            {
 
325
                                rc = d->iface->updateConfig();
 
326
                            }
 
327
                        }
 
328
                        endLoop = true;
 
329
                        break;
 
330
                    }
 
331
                    case SVCHlpMsg::Error:
 
332
                    {
 
333
                        /* read the error message */
 
334
                        Utf8Str errMsg;
 
335
                        vrc = aClient->read(errMsg);
 
336
                        if (RT_FAILURE(vrc)) break;
 
337
 
 
338
                        rc = E_FAIL;//TODO: setError(E_FAIL, errMsg);
 
339
                        endLoop = true;
 
340
                        break;
 
341
                    }
 
342
                    default:
 
343
                    {
 
344
                        endLoop = true;
 
345
                        rc = E_FAIL;//TODO: ComAssertMsgFailedBreak((
 
346
                            //"Invalid message code %d (%08lX)\n",
 
347
                            //reply, reply),
 
348
                            //rc = E_FAIL);
 
349
                    }
 
350
                }
 
351
            }
 
352
 
 
353
            break;
 
354
        }
 
355
        case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
 
356
        {
 
357
            LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
 
358
            LogFlowFunc(("Network connection GUID = {%RTuuid}\n", d->guid.raw()));
 
359
 
 
360
            /* write message and parameters */
 
361
            vrc = aClient->write(d->msgCode);
 
362
            if (RT_FAILURE(vrc)) break;
 
363
            vrc = aClient->write(d->guid);
 
364
            if (RT_FAILURE(vrc)) break;
 
365
 
 
366
            /* wait for a reply */
 
367
            bool endLoop = false;
 
368
            while (!endLoop)
 
369
            {
 
370
                SVCHlpMsg::Code reply = SVCHlpMsg::Null;
 
371
 
 
372
                vrc = aClient->read(reply);
 
373
                if (RT_FAILURE(vrc)) break;
 
374
 
 
375
                switch (reply)
 
376
                {
 
377
                    case SVCHlpMsg::OK:
 
378
                    {
 
379
                        /* no parameters */
 
380
                        rc = S_OK;
 
381
                        endLoop = true;
 
382
                        break;
 
383
                    }
 
384
                    case SVCHlpMsg::Error:
 
385
                    {
 
386
                        /* read the error message */
 
387
                        Utf8Str errMsg;
 
388
                        vrc = aClient->read(errMsg);
 
389
                        if (RT_FAILURE(vrc)) break;
 
390
 
 
391
                        rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
 
392
                        endLoop = true;
 
393
                        break;
 
394
                    }
 
395
                    default:
 
396
                    {
 
397
                        endLoop = true;
 
398
                        rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
 
399
                            //"Invalid message code %d (%08lX)\n",
 
400
                            //reply, reply),
 
401
                            //rc = E_FAIL);
 
402
                    }
 
403
                }
 
404
            }
 
405
 
 
406
            break;
 
407
        }
 
408
        case SVCHlpMsg::EnableDynamicIpConfig: /* see usage in code */
 
409
        {
 
410
            LogFlowFunc(("EnableDynamicIpConfig:\n"));
 
411
            LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
 
412
 
 
413
            /* write message and parameters */
 
414
            vrc = aClient->write(d->msgCode);
 
415
            if (RT_FAILURE(vrc)) break;
 
416
            vrc = aClient->write(d->guid);
 
417
            if (RT_FAILURE(vrc)) break;
 
418
 
 
419
            /* wait for a reply */
 
420
            bool endLoop = false;
 
421
            while (!endLoop)
 
422
            {
 
423
                SVCHlpMsg::Code reply = SVCHlpMsg::Null;
 
424
 
 
425
                vrc = aClient->read(reply);
 
426
                if (RT_FAILURE(vrc)) break;
 
427
 
 
428
                switch (reply)
 
429
                {
 
430
                    case SVCHlpMsg::OK:
 
431
                    {
 
432
                        /* no parameters */
 
433
                        rc = d->iface->updateConfig();
 
434
                        endLoop = true;
 
435
                        break;
 
436
                    }
 
437
                    case SVCHlpMsg::Error:
 
438
                    {
 
439
                        /* read the error message */
 
440
                        Utf8Str errMsg;
 
441
                        vrc = aClient->read(errMsg);
 
442
                        if (RT_FAILURE(vrc)) break;
 
443
 
 
444
                        rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
 
445
                        endLoop = true;
 
446
                        break;
 
447
                    }
 
448
                    default:
 
449
                    {
 
450
                        endLoop = true;
 
451
                        rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
 
452
                            //"Invalid message code %d (%08lX)\n",
 
453
                            //reply, reply),
 
454
                            //rc = E_FAIL);
 
455
                    }
 
456
                }
 
457
            }
 
458
 
 
459
            break;
 
460
        }
 
461
        case SVCHlpMsg::EnableStaticIpConfig: /* see usage in code */
 
462
        {
 
463
            LogFlowFunc(("EnableStaticIpConfig:\n"));
 
464
            LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
 
465
 
 
466
            /* write message and parameters */
 
467
            vrc = aClient->write(d->msgCode);
 
468
            if (RT_FAILURE(vrc)) break;
 
469
            vrc = aClient->write(d->guid);
 
470
            if (RT_FAILURE(vrc)) break;
 
471
            vrc = aClient->write(d->u.StaticIP.IPAddress);
 
472
            if (RT_FAILURE(vrc)) break;
 
473
            vrc = aClient->write(d->u.StaticIP.IPNetMask);
 
474
            if (RT_FAILURE(vrc)) break;
 
475
 
 
476
            /* wait for a reply */
 
477
            bool endLoop = false;
 
478
            while (!endLoop)
 
479
            {
 
480
                SVCHlpMsg::Code reply = SVCHlpMsg::Null;
 
481
 
 
482
                vrc = aClient->read(reply);
 
483
                if (RT_FAILURE(vrc)) break;
 
484
 
 
485
                switch (reply)
 
486
                {
 
487
                    case SVCHlpMsg::OK:
 
488
                    {
 
489
                        /* no parameters */
 
490
                        rc = d->iface->updateConfig();
 
491
                        endLoop = true;
 
492
                        break;
 
493
                    }
 
494
                    case SVCHlpMsg::Error:
 
495
                    {
 
496
                        /* read the error message */
 
497
                        Utf8Str errMsg;
 
498
                        vrc = aClient->read(errMsg);
 
499
                        if (RT_FAILURE(vrc)) break;
 
500
 
 
501
                        rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
 
502
                        endLoop = true;
 
503
                        break;
 
504
                    }
 
505
                    default:
 
506
                    {
 
507
                        endLoop = true;
 
508
                        rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
 
509
                            //"Invalid message code %d (%08lX)\n",
 
510
                            //reply, reply),
 
511
                            //rc = E_FAIL);
 
512
                    }
 
513
                }
 
514
            }
 
515
 
 
516
            break;
 
517
        }
 
518
        case SVCHlpMsg::EnableStaticIpConfigV6: /* see usage in code */
 
519
        {
 
520
            LogFlowFunc(("EnableStaticIpConfigV6:\n"));
 
521
            LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
 
522
 
 
523
            /* write message and parameters */
 
524
            vrc = aClient->write(d->msgCode);
 
525
            if (RT_FAILURE(vrc)) break;
 
526
            vrc = aClient->write(d->guid);
 
527
            if (RT_FAILURE(vrc)) break;
 
528
            vrc = aClient->write(Utf8Str(d->u.StaticIPV6.IPV6Address));
 
529
            if (RT_FAILURE(vrc)) break;
 
530
            vrc = aClient->write(d->u.StaticIPV6.IPV6NetMaskLength);
 
531
            if (RT_FAILURE(vrc)) break;
 
532
 
 
533
            /* wait for a reply */
 
534
            bool endLoop = false;
 
535
            while (!endLoop)
 
536
            {
 
537
                SVCHlpMsg::Code reply = SVCHlpMsg::Null;
 
538
 
 
539
                vrc = aClient->read(reply);
 
540
                if (RT_FAILURE(vrc)) break;
 
541
 
 
542
                switch (reply)
 
543
                {
 
544
                    case SVCHlpMsg::OK:
 
545
                    {
 
546
                        /* no parameters */
 
547
                        rc = d->iface->updateConfig();
 
548
                        endLoop = true;
 
549
                        break;
 
550
                    }
 
551
                    case SVCHlpMsg::Error:
 
552
                    {
 
553
                        /* read the error message */
 
554
                        Utf8Str errMsg;
 
555
                        vrc = aClient->read(errMsg);
 
556
                        if (RT_FAILURE(vrc)) break;
 
557
 
 
558
                        rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
 
559
                        endLoop = true;
 
560
                        break;
 
561
                    }
 
562
                    default:
 
563
                    {
 
564
                        endLoop = true;
 
565
                        rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
 
566
                            //"Invalid message code %d (%08lX)\n",
 
567
                            //reply, reply),
 
568
                            //rc = E_FAIL);
 
569
                    }
 
570
                }
 
571
            }
 
572
 
 
573
            break;
 
574
        }
 
575
        case SVCHlpMsg::DhcpRediscover: /* see usage in code */
 
576
        {
 
577
            LogFlowFunc(("DhcpRediscover:\n"));
 
578
            LogFlowFunc(("Network connection name = '%ls'\n", d->name.raw()));
 
579
 
 
580
            /* write message and parameters */
 
581
            vrc = aClient->write(d->msgCode);
 
582
            if (RT_FAILURE(vrc)) break;
 
583
            vrc = aClient->write(d->guid);
 
584
            if (RT_FAILURE(vrc)) break;
 
585
 
 
586
            /* wait for a reply */
 
587
            bool endLoop = false;
 
588
            while (!endLoop)
 
589
            {
 
590
                SVCHlpMsg::Code reply = SVCHlpMsg::Null;
 
591
 
 
592
                vrc = aClient->read(reply);
 
593
                if (RT_FAILURE(vrc)) break;
 
594
 
 
595
                switch (reply)
 
596
                {
 
597
                    case SVCHlpMsg::OK:
 
598
                    {
 
599
                        /* no parameters */
 
600
                        rc = d->iface->updateConfig();
 
601
                        endLoop = true;
 
602
                        break;
 
603
                    }
 
604
                    case SVCHlpMsg::Error:
 
605
                    {
 
606
                        /* read the error message */
 
607
                        Utf8Str errMsg;
 
608
                        vrc = aClient->read(errMsg);
 
609
                        if (RT_FAILURE(vrc)) break;
 
610
 
 
611
                        rc = E_FAIL; // TODO: setError(E_FAIL, errMsg);
 
612
                        endLoop = true;
 
613
                        break;
 
614
                    }
 
615
                    default:
 
616
                    {
 
617
                        endLoop = true;
 
618
                        rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
 
619
                            //"Invalid message code %d (%08lX)\n",
 
620
                            //reply, reply),
 
621
                            //rc = E_FAIL);
 
622
                    }
 
623
                }
 
624
            }
 
625
 
 
626
            break;
 
627
        }
 
628
        default:
 
629
            rc = E_FAIL; // TODO: ComAssertMsgFailedBreak((
 
630
//                "Invalid message code %d (%08lX)\n",
 
631
//                d->msgCode, d->msgCode),
 
632
//                rc = E_FAIL);
 
633
    }
 
634
 
 
635
    if (aVrc)
 
636
        *aVrc = vrc;
 
637
 
 
638
    LogFlowFunc(("rc=0x%08X, vrc=%Rrc\n", rc, vrc));
 
639
    LogFlowFuncLeave();
 
640
    return rc;
 
641
}
 
642
 
 
643
 
 
644
int netIfNetworkInterfaceHelperServer(SVCHlpClient *aClient,
 
645
                                      SVCHlpMsg::Code aMsgCode)
 
646
{
 
647
    LogFlowFuncEnter();
 
648
    LogFlowFunc(("aClient={%p}, aMsgCode=%d\n", aClient, aMsgCode));
 
649
 
 
650
    AssertReturn(aClient, VERR_INVALID_POINTER);
 
651
 
 
652
    int vrc = VINF_SUCCESS;
 
653
    HRESULT hrc;
 
654
 
 
655
    switch (aMsgCode)
 
656
    {
 
657
        case SVCHlpMsg::CreateHostOnlyNetworkInterface:
 
658
        {
 
659
            LogFlowFunc(("CreateHostOnlyNetworkInterface:\n"));
 
660
 
 
661
//            Utf8Str name;
 
662
//            vrc = aClient->read(name);
 
663
//            if (RT_FAILURE(vrc)) break;
 
664
 
 
665
            Guid guid;
 
666
            Utf8Str errMsg;
 
667
            Bstr name;
 
668
            Bstr bstrErr;
 
669
 
 
670
            hrc = VBoxNetCfgWinCreateHostOnlyNetworkInterface(NULL, false, guid.asOutParam(), name.asOutParam(), bstrErr.asOutParam());
 
671
 
 
672
            if (hrc == S_OK)
 
673
            {
 
674
                ULONG ip, mask;
 
675
                hrc = VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(&ip, &mask);
 
676
                if (hrc == S_OK)
 
677
                {
 
678
                    /* ip returned by VBoxNetCfgWinGenHostOnlyNetworkNetworkIp is a network ip,
 
679
                     * i.e. 192.168.xxx.0, assign  192.168.xxx.1 for the hostonly adapter */
 
680
                    ip = ip | (1 << 24);
 
681
                    hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID*)guid.raw(), ip, mask);
 
682
                }
 
683
 
 
684
                /* write success followed by GUID */
 
685
                vrc = aClient->write(SVCHlpMsg::CreateHostOnlyNetworkInterface_OK);
 
686
                if (RT_FAILURE(vrc)) break;
 
687
                vrc = aClient->write(Utf8Str(name));
 
688
                if (RT_FAILURE(vrc)) break;
 
689
                vrc = aClient->write(guid);
 
690
                if (RT_FAILURE(vrc)) break;
 
691
            }
 
692
            else
 
693
            {
 
694
                vrc = VERR_GENERAL_FAILURE;
 
695
                errMsg = Utf8Str(bstrErr);
 
696
                /* write failure followed by error message */
 
697
                if (errMsg.isEmpty())
 
698
                    errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
 
699
                vrc = aClient->write(SVCHlpMsg::Error);
 
700
                if (RT_FAILURE(vrc)) break;
 
701
                vrc = aClient->write(errMsg);
 
702
                if (RT_FAILURE(vrc)) break;
 
703
            }
 
704
 
 
705
            break;
 
706
        }
 
707
        case SVCHlpMsg::RemoveHostOnlyNetworkInterface:
 
708
        {
 
709
            LogFlowFunc(("RemoveHostOnlyNetworkInterface:\n"));
 
710
 
 
711
            Guid guid;
 
712
            Bstr bstrErr;
 
713
 
 
714
            vrc = aClient->read(guid);
 
715
            if (RT_FAILURE(vrc)) break;
 
716
 
 
717
            Utf8Str errMsg;
 
718
            hrc = VBoxNetCfgWinRemoveHostOnlyNetworkInterface((const GUID*)guid.raw(), bstrErr.asOutParam());
 
719
 
 
720
            if (hrc == S_OK)
 
721
            {
 
722
                /* write parameter-less success */
 
723
                vrc = aClient->write(SVCHlpMsg::OK);
 
724
                if (RT_FAILURE(vrc)) break;
 
725
            }
 
726
            else
 
727
            {
 
728
                vrc = VERR_GENERAL_FAILURE;
 
729
                errMsg = Utf8Str(bstrErr);
 
730
                /* write failure followed by error message */
 
731
                if (errMsg.isEmpty())
 
732
                    errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
 
733
                vrc = aClient->write(SVCHlpMsg::Error);
 
734
                if (RT_FAILURE(vrc)) break;
 
735
                vrc = aClient->write(errMsg);
 
736
                if (RT_FAILURE(vrc)) break;
 
737
            }
 
738
 
 
739
            break;
 
740
        }
 
741
        case SVCHlpMsg::EnableStaticIpConfigV6:
 
742
        {
 
743
            LogFlowFunc(("EnableStaticIpConfigV6:\n"));
 
744
 
 
745
            Guid guid;
 
746
            Utf8Str ipV6;
 
747
            ULONG maskLengthV6;
 
748
            vrc = aClient->read(guid);
 
749
            if (RT_FAILURE(vrc)) break;
 
750
            vrc = aClient->read(ipV6);
 
751
            if (RT_FAILURE(vrc)) break;
 
752
            vrc = aClient->read(maskLengthV6);
 
753
            if (RT_FAILURE(vrc)) break;
 
754
 
 
755
            Utf8Str errMsg;
 
756
            vrc = VERR_NOT_IMPLEMENTED;
 
757
 
 
758
            if (RT_SUCCESS(vrc))
 
759
            {
 
760
                /* write success followed by GUID */
 
761
                vrc = aClient->write(SVCHlpMsg::OK);
 
762
                if (RT_FAILURE(vrc)) break;
 
763
            }
 
764
            else
 
765
            {
 
766
                /* write failure followed by error message */
 
767
                if (errMsg.isEmpty())
 
768
                    errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
 
769
                vrc = aClient->write(SVCHlpMsg::Error);
 
770
                if (RT_FAILURE(vrc)) break;
 
771
                vrc = aClient->write(errMsg);
 
772
                if (RT_FAILURE(vrc)) break;
 
773
            }
 
774
 
 
775
            break;
 
776
        }
 
777
        case SVCHlpMsg::EnableStaticIpConfig:
 
778
        {
 
779
            LogFlowFunc(("EnableStaticIpConfig:\n"));
 
780
 
 
781
            Guid guid;
 
782
            ULONG ip, mask;
 
783
            vrc = aClient->read(guid);
 
784
            if (RT_FAILURE(vrc)) break;
 
785
            vrc = aClient->read(ip);
 
786
            if (RT_FAILURE(vrc)) break;
 
787
            vrc = aClient->read(mask);
 
788
            if (RT_FAILURE(vrc)) break;
 
789
 
 
790
            Utf8Str errMsg;
 
791
            hrc = VBoxNetCfgWinEnableStaticIpConfig((const GUID *)guid.raw(), ip, mask);
 
792
 
 
793
            if (hrc == S_OK)
 
794
            {
 
795
                /* write success followed by GUID */
 
796
                vrc = aClient->write(SVCHlpMsg::OK);
 
797
                if (RT_FAILURE(vrc)) break;
 
798
            }
 
799
            else
 
800
            {
 
801
                vrc = VERR_GENERAL_FAILURE;
 
802
                /* write failure followed by error message */
 
803
                if (errMsg.isEmpty())
 
804
                    errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
 
805
                vrc = aClient->write(SVCHlpMsg::Error);
 
806
                if (RT_FAILURE(vrc)) break;
 
807
                vrc = aClient->write(errMsg);
 
808
                if (RT_FAILURE(vrc)) break;
 
809
            }
 
810
 
 
811
            break;
 
812
        }
 
813
        case SVCHlpMsg::EnableDynamicIpConfig:
 
814
        {
 
815
            LogFlowFunc(("EnableDynamicIpConfig:\n"));
 
816
 
 
817
            Guid guid;
 
818
            vrc = aClient->read(guid);
 
819
            if (RT_FAILURE(vrc)) break;
 
820
 
 
821
            Utf8Str errMsg;
 
822
            hrc = VBoxNetCfgWinEnableDynamicIpConfig((const GUID *)guid.raw());
 
823
 
 
824
            if (hrc == S_OK)
 
825
            {
 
826
                /* write success followed by GUID */
 
827
                vrc = aClient->write(SVCHlpMsg::OK);
 
828
                if (RT_FAILURE(vrc)) break;
 
829
            }
 
830
            else
 
831
            {
 
832
                vrc = VERR_GENERAL_FAILURE;
 
833
                /* write failure followed by error message */
 
834
                if (errMsg.isEmpty())
 
835
                    errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
 
836
                vrc = aClient->write(SVCHlpMsg::Error);
 
837
                if (RT_FAILURE(vrc)) break;
 
838
                vrc = aClient->write(errMsg);
 
839
                if (RT_FAILURE(vrc)) break;
 
840
            }
 
841
 
 
842
            break;
 
843
        }
 
844
        case SVCHlpMsg::DhcpRediscover:
 
845
        {
 
846
            LogFlowFunc(("DhcpRediscover:\n"));
 
847
 
 
848
            Guid guid;
 
849
            vrc = aClient->read(guid);
 
850
            if (RT_FAILURE(vrc)) break;
 
851
 
 
852
            Utf8Str errMsg;
 
853
            hrc = VBoxNetCfgWinDhcpRediscover((const GUID *)guid.raw());
 
854
 
 
855
            if (hrc == S_OK)
 
856
            {
 
857
                /* write success followed by GUID */
 
858
                vrc = aClient->write(SVCHlpMsg::OK);
 
859
                if (RT_FAILURE(vrc)) break;
 
860
            }
 
861
            else
 
862
            {
 
863
                vrc = VERR_GENERAL_FAILURE;
 
864
                /* write failure followed by error message */
 
865
                if (errMsg.isEmpty())
 
866
                    errMsg = Utf8StrFmt("Unspecified error (%Rrc)", vrc);
 
867
                vrc = aClient->write(SVCHlpMsg::Error);
 
868
                if (RT_FAILURE(vrc)) break;
 
869
                vrc = aClient->write(errMsg);
 
870
                if (RT_FAILURE(vrc)) break;
 
871
            }
 
872
 
 
873
            break;
 
874
        }
 
875
        default:
 
876
            AssertMsgFailedBreakStmt(
 
877
                ("Invalid message code %d (%08lX)\n", aMsgCode, aMsgCode),
 
878
                VERR_GENERAL_FAILURE);
 
879
    }
 
880
 
 
881
    LogFlowFunc(("vrc=%Rrc\n", vrc));
 
882
    LogFlowFuncLeave();
 
883
    return vrc;
 
884
}
 
885
 
 
886
/** @todo REMOVE. OBSOLETE NOW. */
 
887
/**
 
888
 * Returns TRUE if the Windows version is 6.0 or greater (i.e. it's Vista and
 
889
 * later OSes) and it has the UAC (User Account Control) feature enabled.
 
890
 */
 
891
static BOOL IsUACEnabled()
 
892
{
 
893
    LONG rc = 0;
 
894
 
 
895
    OSVERSIONINFOEX info;
 
896
    ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
 
897
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
 
898
    rc = GetVersionEx((OSVERSIONINFO *) &info);
 
899
    AssertReturn(rc != 0, FALSE);
 
900
 
 
901
    LogFlowFunc(("dwMajorVersion=%d, dwMinorVersion=%d\n",
 
902
                 info.dwMajorVersion, info.dwMinorVersion));
 
903
 
 
904
    /* we are interested only in Vista (and newer versions...). In all
 
905
     * earlier versions UAC is not present. */
 
906
    if (info.dwMajorVersion < 6)
 
907
        return FALSE;
 
908
 
 
909
    /* the default EnableLUA value is 1 (Enabled) */
 
910
    DWORD dwEnableLUA = 1;
 
911
 
 
912
    HKEY hKey;
 
913
    rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
 
914
                       "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
 
915
                       0, KEY_QUERY_VALUE, &hKey);
 
916
 
 
917
    Assert(rc == ERROR_SUCCESS || rc == ERROR_PATH_NOT_FOUND);
 
918
    if (rc == ERROR_SUCCESS)
 
919
    {
 
920
 
 
921
        DWORD cbEnableLUA = sizeof(dwEnableLUA);
 
922
        rc = RegQueryValueExA(hKey, "EnableLUA", NULL, NULL,
 
923
                              (LPBYTE) &dwEnableLUA, &cbEnableLUA);
 
924
 
 
925
        RegCloseKey(hKey);
 
926
 
 
927
        Assert(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND);
 
928
    }
 
929
 
 
930
    LogFlowFunc(("rc=%d, dwEnableLUA=%d\n", rc, dwEnableLUA));
 
931
 
 
932
    return dwEnableLUA == 1;
 
933
}
 
934
 
 
935
/* end */
 
936
 
 
937
static int vboxNetWinAddComponent(std::list<ComObjPtr<HostNetworkInterface> > * pPist,
 
938
                                  INetCfgComponent * pncc, HostNetworkInterfaceType enmType,
 
939
                                  int iDefaultInterface)
 
940
{
 
941
    LPWSTR              lpszName;
 
942
    GUID                IfGuid;
 
943
    HRESULT hr;
 
944
    int rc = VERR_GENERAL_FAILURE;
 
945
 
 
946
    hr = pncc->GetDisplayName(&lpszName);
 
947
    Assert(hr == S_OK);
 
948
    if (hr == S_OK)
 
949
    {
 
950
        Bstr name(lpszName);
 
951
 
 
952
        hr = pncc->GetInstanceGuid(&IfGuid);
 
953
        Assert(hr == S_OK);
 
954
        if (hr == S_OK)
 
955
        {
 
956
            NETIFINFO Info;
 
957
            memset(&Info, 0, sizeof(Info));
 
958
            Info.Uuid = *(Guid(IfGuid).raw());
 
959
            rc = collectNetIfInfo(name, Guid(IfGuid), &Info, iDefaultInterface);
 
960
            if (RT_FAILURE(rc))
 
961
            {
 
962
                Log(("vboxNetWinAddComponent: collectNetIfInfo() -> %Rrc\n", rc));
 
963
            }
 
964
            /* create a new object and add it to the list */
 
965
            ComObjPtr<HostNetworkInterface> iface;
 
966
            iface.createObject();
 
967
            /* remove the curly bracket at the end */
 
968
            if (SUCCEEDED(iface->init(name, enmType, &Info)))
 
969
            {
 
970
                if (Info.bIsDefault)
 
971
                    pPist->push_front(iface);
 
972
                else
 
973
                    pPist->push_back(iface);
 
974
                rc = VINF_SUCCESS;
 
975
            }
 
976
            else
 
977
            {
 
978
                Assert(0);
 
979
            }
 
980
        }
 
981
        CoTaskMemFree(lpszName);
 
982
    }
 
983
 
 
984
    return rc;
 
985
}
 
986
 
 
987
#endif /* VBOX_WITH_NETFLT */
 
988
 
 
989
 
 
990
static int netIfListHostAdapters(std::list<ComObjPtr<HostNetworkInterface> > &list)
 
991
{
 
992
#ifndef VBOX_WITH_NETFLT
 
993
    /* VBoxNetAdp is available only when VBOX_WITH_NETFLT is enabled */
 
994
    return VERR_NOT_IMPLEMENTED;
 
995
#else /* #  if defined VBOX_WITH_NETFLT */
 
996
    INetCfg              *pNc;
 
997
    INetCfgComponent     *pMpNcc;
 
998
    LPWSTR               lpszApp = NULL;
 
999
    HRESULT              hr;
 
1000
    IEnumNetCfgComponent  *pEnumComponent;
 
1001
 
 
1002
    /* we are using the INetCfg API for getting the list of miniports */
 
1003
    hr = VBoxNetCfgWinQueryINetCfg(FALSE,
 
1004
                       VBOX_APP_NAME,
 
1005
                       &pNc,
 
1006
                       &lpszApp);
 
1007
    Assert(hr == S_OK);
 
1008
    if (hr == S_OK)
 
1009
    {
 
1010
        hr = VBoxNetCfgWinGetComponentEnum(pNc, &GUID_DEVCLASS_NET, &pEnumComponent);
 
1011
        if (hr == S_OK)
 
1012
        {
 
1013
            while ((hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pMpNcc)) == S_OK)
 
1014
            {
 
1015
                ULONG uComponentStatus;
 
1016
                hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
 
1017
                if (hr == S_OK)
 
1018
                {
 
1019
                    if (uComponentStatus == 0)
 
1020
                    {
 
1021
                        LPWSTR pId;
 
1022
                        hr = pMpNcc->GetId(&pId);
 
1023
                        Assert(hr == S_OK);
 
1024
                        if (hr == S_OK)
 
1025
                        {
 
1026
                            if (!_wcsnicmp(pId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2))
 
1027
                            {
 
1028
                                vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_HostOnly, -1);
 
1029
                            }
 
1030
                            CoTaskMemFree(pId);
 
1031
                        }
 
1032
                    }
 
1033
                }
 
1034
                VBoxNetCfgWinReleaseRef(pMpNcc);
 
1035
            }
 
1036
            Assert(hr == S_OK || hr == S_FALSE);
 
1037
 
 
1038
            VBoxNetCfgWinReleaseRef(pEnumComponent);
 
1039
        }
 
1040
        else
 
1041
        {
 
1042
            LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
 
1043
        }
 
1044
 
 
1045
        VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
 
1046
    }
 
1047
    else if (lpszApp)
 
1048
    {
 
1049
        CoTaskMemFree(lpszApp);
 
1050
    }
 
1051
#endif /* #  if defined VBOX_WITH_NETFLT */
 
1052
    return VINF_SUCCESS;
 
1053
}
 
1054
 
 
1055
int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *pInfo)
 
1056
{
 
1057
#ifndef VBOX_WITH_NETFLT
 
1058
    return VERR_NOT_IMPLEMENTED;
 
1059
#else
 
1060
    Bstr name;
 
1061
    HRESULT hr = pIf->COMGETTER(Name)(name.asOutParam());
 
1062
    if (hr == S_OK)
 
1063
    {
 
1064
        Bstr                IfGuid;
 
1065
        hr = pIf->COMGETTER(Id)(IfGuid.asOutParam());
 
1066
        Assert(hr == S_OK);
 
1067
        if (hr == S_OK)
 
1068
        {
 
1069
            memset(pInfo, 0, sizeof(NETIFINFO));
 
1070
            Guid guid(IfGuid);
 
1071
            pInfo->Uuid = *(guid.raw());
 
1072
 
 
1073
            return collectNetIfInfo(name, guid, pInfo, getDefaultInterfaceIndex());
 
1074
        }
 
1075
    }
 
1076
    return VERR_GENERAL_FAILURE;
 
1077
#endif
 
1078
}
 
1079
 
 
1080
int NetIfGetConfigByName(PNETIFINFO)
 
1081
{
 
1082
    return VERR_NOT_IMPLEMENTED;
 
1083
}
 
1084
 
 
1085
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox,
 
1086
                                        IHostNetworkInterface **aHostNetworkInterface,
 
1087
                                        IProgress **aProgress)
 
1088
{
 
1089
#ifndef VBOX_WITH_NETFLT
 
1090
    return VERR_NOT_IMPLEMENTED;
 
1091
#else
 
1092
    /* create a progress object */
 
1093
    ComObjPtr<Progress> progress;
 
1094
    progress.createObject();
 
1095
 
 
1096
    ComPtr<IHost> host;
 
1097
    HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
 
1098
    if (SUCCEEDED(rc))
 
1099
    {
 
1100
        rc = progress->init(pVBox, host,
 
1101
                            Bstr(_T("Creating host only network interface")).raw(),
 
1102
                            FALSE /* aCancelable */);
 
1103
        if (SUCCEEDED(rc))
 
1104
        {
 
1105
            if (FAILED(rc)) return rc;
 
1106
            progress.queryInterfaceTo(aProgress);
 
1107
 
 
1108
            /* create a new uninitialized host interface object */
 
1109
            ComObjPtr<HostNetworkInterface> iface;
 
1110
            iface.createObject();
 
1111
            iface.queryInterfaceTo(aHostNetworkInterface);
 
1112
 
 
1113
            /* create the networkInterfaceHelperClient() argument */
 
1114
            std::auto_ptr<NetworkInterfaceHelperClientData>
 
1115
                d(new NetworkInterfaceHelperClientData());
 
1116
            AssertReturn(d.get(), E_OUTOFMEMORY);
 
1117
 
 
1118
            d->msgCode = SVCHlpMsg::CreateHostOnlyNetworkInterface;
 
1119
//            d->name = aName;
 
1120
            d->iface = iface;
 
1121
            d->vBox = pVBox;
 
1122
 
 
1123
            rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
 
1124
                                             netIfNetworkInterfaceHelperClient,
 
1125
                                             static_cast<void *>(d.get()),
 
1126
                                             progress);
 
1127
 
 
1128
            if (SUCCEEDED(rc))
 
1129
            {
 
1130
                /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
 
1131
                d.release();
 
1132
            }
 
1133
        }
 
1134
    }
 
1135
 
 
1136
    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
 
1137
#endif
 
1138
}
 
1139
 
 
1140
int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVBox, IN_GUID aId,
 
1141
                                        IProgress **aProgress)
 
1142
{
 
1143
#ifndef VBOX_WITH_NETFLT
 
1144
    return VERR_NOT_IMPLEMENTED;
 
1145
#else
 
1146
    /* create a progress object */
 
1147
    ComObjPtr<Progress> progress;
 
1148
    progress.createObject();
 
1149
    ComPtr<IHost> host;
 
1150
    HRESULT rc = pVBox->COMGETTER(Host)(host.asOutParam());
 
1151
    if (SUCCEEDED(rc))
 
1152
    {
 
1153
        rc = progress->init(pVBox, host,
 
1154
                           Bstr(_T("Removing host network interface")).raw(),
 
1155
                           FALSE /* aCancelable */);
 
1156
        if (SUCCEEDED(rc))
 
1157
        {
 
1158
            if (FAILED(rc)) return rc;
 
1159
            progress.queryInterfaceTo(aProgress);
 
1160
 
 
1161
            /* create the networkInterfaceHelperClient() argument */
 
1162
            std::auto_ptr<NetworkInterfaceHelperClientData>
 
1163
                d(new NetworkInterfaceHelperClientData());
 
1164
            AssertReturn(d.get(), E_OUTOFMEMORY);
 
1165
 
 
1166
            d->msgCode = SVCHlpMsg::RemoveHostOnlyNetworkInterface;
 
1167
            d->guid = aId;
 
1168
 
 
1169
            rc = pVBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
 
1170
                                             netIfNetworkInterfaceHelperClient,
 
1171
                                             static_cast<void *>(d.get()),
 
1172
                                             progress);
 
1173
 
 
1174
            if (SUCCEEDED(rc))
 
1175
            {
 
1176
                /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
 
1177
                d.release();
 
1178
            }
 
1179
        }
 
1180
    }
 
1181
 
 
1182
    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
 
1183
#endif
 
1184
}
 
1185
 
 
1186
int NetIfEnableStaticIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG ip, ULONG mask)
 
1187
{
 
1188
#ifndef VBOX_WITH_NETFLT
 
1189
    return VERR_NOT_IMPLEMENTED;
 
1190
#else
 
1191
    HRESULT rc;
 
1192
    Bstr guid;
 
1193
    rc = pIf->COMGETTER(Id)(guid.asOutParam());
 
1194
    if (SUCCEEDED(rc))
 
1195
    {
 
1196
//        ComPtr<VirtualBox> vBox;
 
1197
//        rc = pIf->getVirtualBox(vBox.asOutParam());
 
1198
//        if (SUCCEEDED(rc))
 
1199
        {
 
1200
            /* create a progress object */
 
1201
            ComObjPtr<Progress> progress;
 
1202
            progress.createObject();
 
1203
//            ComPtr<IHost> host;
 
1204
//            HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
 
1205
//            if (SUCCEEDED(rc))
 
1206
            {
 
1207
                rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
 
1208
                                    Bstr("Enabling Dynamic Ip Configuration").raw(),
 
1209
                                    FALSE /* aCancelable */);
 
1210
                if (SUCCEEDED(rc))
 
1211
                {
 
1212
                    if (FAILED(rc)) return rc;
 
1213
//                    progress.queryInterfaceTo(aProgress);
 
1214
 
 
1215
                    /* create the networkInterfaceHelperClient() argument */
 
1216
                    std::auto_ptr<NetworkInterfaceHelperClientData>
 
1217
                        d(new NetworkInterfaceHelperClientData());
 
1218
                    AssertReturn(d.get(), E_OUTOFMEMORY);
 
1219
 
 
1220
                    d->msgCode = SVCHlpMsg::EnableStaticIpConfig;
 
1221
                    d->guid = Guid(guid);
 
1222
                    d->iface = pIf;
 
1223
                    d->u.StaticIP.IPAddress = ip;
 
1224
                    d->u.StaticIP.IPNetMask = mask;
 
1225
 
 
1226
                    rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
 
1227
                                                    netIfNetworkInterfaceHelperClient,
 
1228
                                                    static_cast<void *>(d.get()),
 
1229
                                                    progress);
 
1230
 
 
1231
                    if (SUCCEEDED(rc))
 
1232
                    {
 
1233
                        /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
 
1234
                        d.release();
 
1235
 
 
1236
                        progress->WaitForCompletion(-1);
 
1237
                    }
 
1238
                }
 
1239
            }
 
1240
        }
 
1241
    }
 
1242
 
 
1243
    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
 
1244
#endif
 
1245
}
 
1246
 
 
1247
int NetIfEnableStaticIpConfigV6(VirtualBox *vBox, HostNetworkInterface * pIf, IN_BSTR aOldIPV6Address, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength)
 
1248
{
 
1249
#ifndef VBOX_WITH_NETFLT
 
1250
    return VERR_NOT_IMPLEMENTED;
 
1251
#else
 
1252
    HRESULT rc;
 
1253
    Bstr guid;
 
1254
    rc = pIf->COMGETTER(Id)(guid.asOutParam());
 
1255
    if (SUCCEEDED(rc))
 
1256
    {
 
1257
//        ComPtr<VirtualBox> vBox;
 
1258
//        rc = pIf->getVirtualBox(vBox.asOutParam());
 
1259
//        if (SUCCEEDED(rc))
 
1260
        {
 
1261
            /* create a progress object */
 
1262
            ComObjPtr<Progress> progress;
 
1263
            progress.createObject();
 
1264
//            ComPtr<IHost> host;
 
1265
//            HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
 
1266
//            if (SUCCEEDED(rc))
 
1267
            {
 
1268
                rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
 
1269
                                    Bstr("Enabling Dynamic Ip Configuration").raw(),
 
1270
                                    FALSE /* aCancelable */);
 
1271
                if (SUCCEEDED(rc))
 
1272
                {
 
1273
                    if (FAILED(rc)) return rc;
 
1274
//                    progress.queryInterfaceTo(aProgress);
 
1275
 
 
1276
                    /* create the networkInterfaceHelperClient() argument */
 
1277
                    std::auto_ptr<NetworkInterfaceHelperClientData>
 
1278
                        d(new NetworkInterfaceHelperClientData());
 
1279
                    AssertReturn(d.get(), E_OUTOFMEMORY);
 
1280
 
 
1281
                    d->msgCode = SVCHlpMsg::EnableStaticIpConfigV6;
 
1282
                    d->guid = guid;
 
1283
                    d->iface = pIf;
 
1284
                    d->u.StaticIPV6.IPV6Address = aIPV6Address;
 
1285
                    d->u.StaticIPV6.IPV6NetMaskLength = aIPV6MaskPrefixLength;
 
1286
 
 
1287
                    rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
 
1288
                                                    netIfNetworkInterfaceHelperClient,
 
1289
                                                    static_cast<void *>(d.get()),
 
1290
                                                    progress);
 
1291
 
 
1292
                    if (SUCCEEDED(rc))
 
1293
                    {
 
1294
                        /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
 
1295
                        d.release();
 
1296
 
 
1297
                        progress->WaitForCompletion(-1);
 
1298
                    }
 
1299
                }
 
1300
            }
 
1301
        }
 
1302
    }
 
1303
 
 
1304
    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
 
1305
#endif
 
1306
}
 
1307
 
 
1308
int NetIfEnableDynamicIpConfig(VirtualBox *vBox, HostNetworkInterface * pIf)
 
1309
{
 
1310
#ifndef VBOX_WITH_NETFLT
 
1311
    return VERR_NOT_IMPLEMENTED;
 
1312
#else
 
1313
    HRESULT rc;
 
1314
    Bstr guid;
 
1315
    rc = pIf->COMGETTER(Id)(guid.asOutParam());
 
1316
    if (SUCCEEDED(rc))
 
1317
    {
 
1318
//        ComPtr<VirtualBox> vBox;
 
1319
//        rc = pIf->getVirtualBox(vBox.asOutParam());
 
1320
//        if (SUCCEEDED(rc))
 
1321
        {
 
1322
            /* create a progress object */
 
1323
            ComObjPtr<Progress> progress;
 
1324
            progress.createObject();
 
1325
//            ComPtr<IHost> host;
 
1326
//            HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
 
1327
//            if (SUCCEEDED(rc))
 
1328
            {
 
1329
                rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
 
1330
                                    Bstr("Enabling Dynamic Ip Configuration").raw(),
 
1331
                                    FALSE /* aCancelable */);
 
1332
                if (SUCCEEDED(rc))
 
1333
                {
 
1334
                    if (FAILED(rc)) return rc;
 
1335
//                    progress.queryInterfaceTo(aProgress);
 
1336
 
 
1337
                    /* create the networkInterfaceHelperClient() argument */
 
1338
                    std::auto_ptr<NetworkInterfaceHelperClientData>
 
1339
                        d(new NetworkInterfaceHelperClientData());
 
1340
                    AssertReturn(d.get(), E_OUTOFMEMORY);
 
1341
 
 
1342
                    d->msgCode = SVCHlpMsg::EnableDynamicIpConfig;
 
1343
                    d->guid = guid;
 
1344
                    d->iface = pIf;
 
1345
 
 
1346
                    rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
 
1347
                                                    netIfNetworkInterfaceHelperClient,
 
1348
                                                    static_cast<void *>(d.get()),
 
1349
                                                    progress);
 
1350
 
 
1351
                    if (SUCCEEDED(rc))
 
1352
                    {
 
1353
                        /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
 
1354
                        d.release();
 
1355
 
 
1356
                        progress->WaitForCompletion(-1);
 
1357
                    }
 
1358
                }
 
1359
            }
 
1360
        }
 
1361
    }
 
1362
 
 
1363
    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
 
1364
#endif
 
1365
}
 
1366
 
 
1367
int NetIfDhcpRediscover(VirtualBox *vBox, HostNetworkInterface * pIf)
 
1368
{
 
1369
#ifndef VBOX_WITH_NETFLT
 
1370
    return VERR_NOT_IMPLEMENTED;
 
1371
#else
 
1372
    HRESULT rc;
 
1373
    Bstr guid;
 
1374
    rc = pIf->COMGETTER(Id)(guid.asOutParam());
 
1375
    if (SUCCEEDED(rc))
 
1376
    {
 
1377
//        ComPtr<VirtualBox> vBox;
 
1378
//        rc = pIf->getVirtualBox(vBox.asOutParam());
 
1379
//        if (SUCCEEDED(rc))
 
1380
        {
 
1381
            /* create a progress object */
 
1382
            ComObjPtr<Progress> progress;
 
1383
            progress.createObject();
 
1384
//            ComPtr<IHost> host;
 
1385
//            HRESULT rc = vBox->COMGETTER(Host)(host.asOutParam());
 
1386
//            if (SUCCEEDED(rc))
 
1387
            {
 
1388
                rc = progress->init(vBox, (IHostNetworkInterface*)pIf,
 
1389
                                    Bstr("Enabling Dynamic Ip Configuration").raw(),
 
1390
                                    FALSE /* aCancelable */);
 
1391
                if (SUCCEEDED(rc))
 
1392
                {
 
1393
                    if (FAILED(rc)) return rc;
 
1394
//                    progress.queryInterfaceTo(aProgress);
 
1395
 
 
1396
                    /* create the networkInterfaceHelperClient() argument */
 
1397
                    std::auto_ptr<NetworkInterfaceHelperClientData>
 
1398
                        d(new NetworkInterfaceHelperClientData());
 
1399
                    AssertReturn(d.get(), E_OUTOFMEMORY);
 
1400
 
 
1401
                    d->msgCode = SVCHlpMsg::DhcpRediscover;
 
1402
                    d->guid = guid;
 
1403
                    d->iface = pIf;
 
1404
 
 
1405
                    rc = vBox->startSVCHelperClient(IsUACEnabled() == TRUE /* aPrivileged */,
 
1406
                                                    netIfNetworkInterfaceHelperClient,
 
1407
                                                    static_cast<void *>(d.get()),
 
1408
                                                    progress);
 
1409
 
 
1410
                    if (SUCCEEDED(rc))
 
1411
                    {
 
1412
                        /* d is now owned by netIfNetworkInterfaceHelperClient(), so release it */
 
1413
                        d.release();
 
1414
 
 
1415
                        progress->WaitForCompletion(-1);
 
1416
                    }
 
1417
                }
 
1418
            }
 
1419
        }
 
1420
    }
 
1421
 
 
1422
    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
 
1423
#endif
 
1424
}
 
1425
 
 
1426
int NetIfList(std::list<ComObjPtr<HostNetworkInterface> > &list)
 
1427
{
 
1428
#ifndef VBOX_WITH_NETFLT
 
1429
    return VERR_NOT_IMPLEMENTED;
 
1430
#else /* #  if defined VBOX_WITH_NETFLT */
 
1431
    INetCfg              *pNc;
 
1432
    INetCfgComponent     *pMpNcc;
 
1433
    INetCfgComponent     *pTcpIpNcc;
 
1434
    LPWSTR               lpszApp;
 
1435
    HRESULT              hr;
 
1436
    IEnumNetCfgBindingPath      *pEnumBp;
 
1437
    INetCfgBindingPath          *pBp;
 
1438
    IEnumNetCfgBindingInterface *pEnumBi;
 
1439
    INetCfgBindingInterface *pBi;
 
1440
    int                  iDefault = getDefaultInterfaceIndex();
 
1441
 
 
1442
    /* we are using the INetCfg API for getting the list of miniports */
 
1443
    hr = VBoxNetCfgWinQueryINetCfg(FALSE,
 
1444
                       VBOX_APP_NAME,
 
1445
                       &pNc,
 
1446
                       &lpszApp);
 
1447
    Assert(hr == S_OK);
 
1448
    if (hr == S_OK)
 
1449
    {
 
1450
# ifdef VBOX_NETFLT_ONDEMAND_BIND
 
1451
        /* for the protocol-based approach for now we just get all miniports the MS_TCPIP protocol binds to */
 
1452
        hr = pNc->FindComponent(L"MS_TCPIP", &pTcpIpNcc);
 
1453
# else
 
1454
        /* for the filter-based approach we get all miniports our filter (sun_VBoxNetFlt)is bound to */
 
1455
        hr = pNc->FindComponent(L"sun_VBoxNetFlt", &pTcpIpNcc);
 
1456
#  ifndef VBOX_WITH_HARDENING
 
1457
        if (hr != S_OK)
 
1458
        {
 
1459
            /* TODO: try to install the netflt from here */
 
1460
        }
 
1461
#  endif
 
1462
 
 
1463
# endif
 
1464
 
 
1465
        if (hr == S_OK)
 
1466
        {
 
1467
            hr = VBoxNetCfgWinGetBindingPathEnum(pTcpIpNcc, EBP_BELOW, &pEnumBp);
 
1468
            Assert(hr == S_OK);
 
1469
            if (hr == S_OK)
 
1470
            {
 
1471
                hr = VBoxNetCfgWinGetFirstBindingPath(pEnumBp, &pBp);
 
1472
                Assert(hr == S_OK || hr == S_FALSE);
 
1473
                while (hr == S_OK)
 
1474
                {
 
1475
                    /* S_OK == enabled, S_FALSE == disabled */
 
1476
                    if (pBp->IsEnabled() == S_OK)
 
1477
                    {
 
1478
                        hr = VBoxNetCfgWinGetBindingInterfaceEnum(pBp, &pEnumBi);
 
1479
                        Assert(hr == S_OK);
 
1480
                        if ( hr == S_OK )
 
1481
                        {
 
1482
                            hr = VBoxNetCfgWinGetFirstBindingInterface(pEnumBi, &pBi);
 
1483
                            Assert(hr == S_OK);
 
1484
                            while (hr == S_OK)
 
1485
                            {
 
1486
                                hr = pBi->GetLowerComponent( &pMpNcc );
 
1487
                                Assert(hr == S_OK);
 
1488
                                if (hr == S_OK)
 
1489
                                {
 
1490
                                    ULONG uComponentStatus;
 
1491
                                    hr = pMpNcc->GetDeviceStatus(&uComponentStatus);
 
1492
                                    if (hr == S_OK)
 
1493
                                    {
 
1494
                                        if (uComponentStatus == 0)
 
1495
                                        {
 
1496
                                            vboxNetWinAddComponent(&list, pMpNcc, HostNetworkInterfaceType_Bridged, iDefault);
 
1497
                                        }
 
1498
                                    }
 
1499
                                    VBoxNetCfgWinReleaseRef( pMpNcc );
 
1500
                                }
 
1501
                                VBoxNetCfgWinReleaseRef(pBi);
 
1502
 
 
1503
                                hr = VBoxNetCfgWinGetNextBindingInterface(pEnumBi, &pBi);
 
1504
                            }
 
1505
                            VBoxNetCfgWinReleaseRef(pEnumBi);
 
1506
                        }
 
1507
                    }
 
1508
                    VBoxNetCfgWinReleaseRef(pBp);
 
1509
 
 
1510
                    hr = VBoxNetCfgWinGetNextBindingPath(pEnumBp, &pBp);
 
1511
                }
 
1512
                VBoxNetCfgWinReleaseRef(pEnumBp);
 
1513
            }
 
1514
            VBoxNetCfgWinReleaseRef(pTcpIpNcc);
 
1515
        }
 
1516
        else
 
1517
        {
 
1518
            LogRel(("failed to get the sun_VBoxNetFlt component, error (0x%x)", hr));
 
1519
        }
 
1520
 
 
1521
        VBoxNetCfgWinReleaseINetCfg(pNc, FALSE);
 
1522
    }
 
1523
 
 
1524
    netIfListHostAdapters(list);
 
1525
 
 
1526
    return VINF_SUCCESS;
 
1527
#endif /* #  if defined VBOX_WITH_NETFLT */
 
1528
}