Index: /trunk/src/VBox/Main/HostImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/HostImpl.cpp	(revision 12438)
+++ /trunk/src/VBox/Main/HostImpl.cpp	(revision 12439)
@@ -80,4 +80,9 @@
 # include <shlobj.h>
 # include <cfgmgr32.h>
+
+# ifdef VBOX_WITH_NETFLT
+
+# endif /* VBOX_WITH_NETFLT */
+#include <Netcfgn.h>
 #endif /* RT_OS_WINDOWS */
 
@@ -1150,4 +1155,598 @@
     return rc;
 }
+
+# ifdef VBOX_WITH_NETFLT
+
+#define VBOX_NETCFG_LOCK_TIME_OUT     5000
+
+/*TODO: should use some real VBox app name */
+#define VBOX_NETCFG_APP_NAME L"VirtualBox"
+
+/*
+ * Release reference
+ */
+static VOID vboxNetCfgWinReleaseRef (IN IUnknown* punk)
+{
+    if(punk)
+    {
+        punk->Release();
+    }
+
+    return;
+}
+
+/*
+ * Get a reference to INetCfg.
+ *
+ *    fGetWriteLock  [in]  If TRUE, Write lock.requested.
+ *    lpszAppName    [in]  Application name requesting the reference.
+ *    ppnc           [out] Reference to INetCfg.
+ *    lpszLockedBy   [in]  Optional. Application who holds the write lock.
+ *
+ * Returns:   S_OK on sucess, otherwise an error code.
+ */
+static HRESULT vboxNetCfgWinQueryINetCfg (IN BOOL fGetWriteLock,
+                      IN LPCWSTR lpszAppName,
+                      OUT INetCfg** ppnc,
+                      OUT LPWSTR *lpszLockedBy)
+{
+    INetCfg      *pnc = NULL;
+    INetCfgLock  *pncLock = NULL;
+    HRESULT      hr = S_OK;
+
+    /*
+     * Initialize the output parameters.
+     */
+    *ppnc = NULL;
+
+    if ( lpszLockedBy )
+    {
+        *lpszLockedBy = NULL;
+    }
+    /*
+     * Initialize COM
+     */
+    hr = CoInitialize( NULL );
+
+    if ( hr == S_OK )
+    {
+
+        /*
+         * Create the object implementing INetCfg.
+         */
+        hr = CoCreateInstance( CLSID_CNetCfg,
+                               NULL, CLSCTX_INPROC_SERVER,
+                               IID_INetCfg,
+                               (void**)&pnc );
+        if ( hr == S_OK )
+        {
+
+            if ( fGetWriteLock )
+            {
+
+                /*
+                 * Get the locking reference
+                 */
+                hr = pnc->QueryInterface( IID_INetCfgLock,
+                                          (LPVOID *)&pncLock );
+                if ( hr == S_OK )
+                {
+
+                    /*
+                     * Attempt to lock the INetCfg for read/write
+                     */
+                    hr = pncLock->AcquireWriteLock( VBOX_NETCFG_LOCK_TIME_OUT,
+                                                    lpszAppName,
+                                                    lpszLockedBy);
+                    if (hr == S_FALSE )
+                    {
+                        hr = NETCFG_E_NO_WRITE_LOCK;
+                    }
+                }
+            }
+
+            if ( hr == S_OK )
+            {
+
+                /*
+                 * Initialize the INetCfg object.
+                 */
+                hr = pnc->Initialize( NULL );
+
+                if ( hr == S_OK )
+                {
+                    *ppnc = pnc;
+                    pnc->AddRef();
+                }
+                else
+                {
+
+                    /*
+                     * Initialize failed, if obtained lock, release it
+                     */
+                    if ( pncLock )
+                    {
+                        pncLock->ReleaseWriteLock();
+                    }
+                }
+            }
+
+            vboxNetCfgWinReleaseRef( pncLock );
+            vboxNetCfgWinReleaseRef( pnc );
+        }
+
+        /*
+         * In case of error, uninitialize COM.
+         */
+        if ( hr != S_OK )
+        {
+            CoUninitialize();
+        }
+    }
+
+    return hr;
+}
+
+/*
+ * Get a reference to INetCfg.
+ *
+ *    pnc           [in] Reference to INetCfg to release.
+ *    fHasWriteLock [in] If TRUE, reference was held with write lock.
+ *
+ * Returns:   S_OK on sucess, otherwise an error code.
+ *
+ */
+static HRESULT vboxNetCfgWinReleaseINetCfg (IN INetCfg* pnc,
+                          IN BOOL fHasWriteLock)
+{
+    INetCfgLock    *pncLock = NULL;
+    HRESULT        hr = S_OK;
+
+    /*
+     * Uninitialize INetCfg
+     */
+    hr = pnc->Uninitialize();
+
+    /*
+     * If write lock is present, unlock it
+     */
+    if ( hr == S_OK && fHasWriteLock )
+    {
+
+        /*
+         * Get the locking reference
+         */
+        hr = pnc->QueryInterface( IID_INetCfgLock,
+                                  (LPVOID *)&pncLock);
+        if ( hr == S_OK )
+        {
+           hr = pncLock->ReleaseWriteLock();
+           vboxNetCfgWinReleaseRef( pncLock );
+        }
+    }
+
+    vboxNetCfgWinReleaseRef( pnc );
+
+    /*
+     * Uninitialize COM.
+     */
+    CoUninitialize();
+
+    return hr;
+}
+
+/*
+ * Get network component enumerator reference.
+ *
+ * Arguments:
+ *    pnc         [in]  Reference to INetCfg.
+ *    pguidClass  [in]  Class GUID of the network component.
+ *    ppencc      [out] Enumerator reference.
+ *
+ * Returns:   S_OK on sucess, otherwise an error code.
+ */
+static HRESULT vboxNetCfgWinGetComponentEnum (INetCfg* pnc,
+                            IN const GUID* pguidClass,
+                            OUT IEnumNetCfgComponent **ppencc)
+{
+    INetCfgClass  *pncclass;
+    HRESULT       hr;
+
+    *ppencc = NULL;
+
+    /*
+     * Get the class reference.
+     */
+    hr = pnc->QueryNetCfgClass( pguidClass,
+                                IID_INetCfgClass,
+                                (PVOID *)&pncclass );
+
+    if ( hr == S_OK )
+    {
+
+        /*
+         * Get the enumerator reference.
+         */
+        hr = pncclass->EnumComponents( ppencc );
+
+        /*
+         * We don't need the class reference any more.
+         */
+        vboxNetCfgWinReleaseRef( pncclass );
+    }
+
+    return hr;
+}
+
+/*
+ * Enumerates the first network component.
+ *
+ * Arguments:
+ *    pencc      [in]  Component enumerator reference.
+ *    ppncc      [out] Network component reference.
+ *
+ * Returns:   S_OK on sucess, otherwise an error code.
+ */
+static HRESULT vboxNetCfgWinGetFirstComponent (IN IEnumNetCfgComponent* pencc,
+                             OUT INetCfgComponent **ppncc)
+{
+    HRESULT  hr;
+    ULONG    ulCount;
+
+    *ppncc = NULL;
+
+    pencc->Reset();
+
+    hr = pencc->Next( 1,
+                      ppncc,
+                      &ulCount );
+    return hr;
+}
+
+/*
+ * Enumerate the next network component.
+ *
+ * The function behaves just like vboxNetCfgWinGetFirstComponent if
+ * it is called right after vboxNetCfgWinGetComponentEnum.
+ *
+ * Arguments:
+ *    pencc      [in]  Component enumerator reference.
+ *    ppncc      [out] Network component reference.
+ *
+ * Returns:   S_OK on sucess, otherwise an error code.
+ */
+static HRESULT vboxNetCfgWinGetNextComponent (IN IEnumNetCfgComponent* pencc,
+                            OUT INetCfgComponent **ppncc)
+{
+    HRESULT  hr;
+    ULONG    ulCount;
+
+    *ppncc = NULL;
+
+    hr = pencc->Next( 1,
+                      ppncc,
+                      &ulCount );
+    return hr;
+}
+
+/*
+ * Install a network component(protocols, clients and services)
+ *            given its INF file.
+ * Arguments:
+ *    pnc              [in] Reference to INetCfg.
+ *    lpszComponentId  [in] PnpID of the network component.
+ *    pguidClass       [in] Class GUID of the network component.
+ *
+ * Returns:   S_OK on sucess, otherwise an error code.
+ */
+static HRESULT vboxNetCfgWinInstallComponent(IN INetCfg* pnc,
+                           IN LPCWSTR szComponentId,
+                           IN const GUID* pguidClass)
+{
+    INetCfgClassSetup   *pncClassSetup = NULL;
+    INetCfgComponent    *pncc = NULL;
+    OBO_TOKEN           OboToken;
+    HRESULT             hr = S_OK;
+
+    /*
+     * OBO_TOKEN specifies on whose behalf this
+     * component is being installed.
+     * Set it to OBO_USER so that szComponentId will be installed
+     * on behalf of the user.
+     */
+
+    ZeroMemory( &OboToken,
+                sizeof(OboToken) );
+    OboToken.Type = OBO_USER;
+
+    /*
+     * Get component's setup class reference.
+     */
+    hr = pnc->QueryNetCfgClass ( pguidClass,
+                                 IID_INetCfgClassSetup,
+                                 (void**)&pncClassSetup );
+    if ( hr == S_OK ) {
+
+        hr = pncClassSetup->Install( szComponentId,
+                                     &OboToken,
+                                     0,
+                                     0,       /* Upgrade from build number. */
+                                     NULL,    /* Answerfile name */
+                                     NULL,    /* Answerfile section name */
+                                     &pncc ); /* Reference after the component */
+        if ( S_OK == hr ) {                   /* is installed. */
+
+            /*
+             * we don't need to use pncc (INetCfgComponent), release it
+             */
+            vboxNetCfgWinReleaseRef( pncc );
+        }
+
+        vboxNetCfgWinReleaseRef( pncClassSetup );
+    }
+
+    return hr;
+}
+
+/*
+ * Install a network component(protocols, clients and services)
+ *            given its INF file.
+ *
+ * Arguments:
+ *    pnc              [in] Reference to INetCfg.
+ *    lpszComponentId  [in] PnpID of the network component.
+ *    pguidClass       [in] Class GUID of the network component.
+ *    lpszInfFullPath  [in] INF file to install from.
+ *
+ * Returns:   S_OK on sucess, otherwise an error code.
+ */
+static HRESULT vboxNetCfgWinInstallNetComponent (IN INetCfg *pnc,
+                               IN LPCWSTR lpszComponentId,
+                               IN const GUID    *pguidClass,
+                               IN LPCWSTR lpszInfFullPath)
+{
+    DWORD     dwError;
+    HRESULT   hr = S_OK;
+    WCHAR     Drive[_MAX_DRIVE];
+    WCHAR     Dir[_MAX_DIR];
+    WCHAR     DirWithDrive[_MAX_DRIVE+_MAX_DIR];
+
+    /*
+     * If full path to INF has been specified, the INF
+     * needs to be copied using Setup API to ensure that any other files
+     * that the primary INF copies will be correctly found by Setup API
+     */
+
+    if ( lpszInfFullPath )
+    {
+
+        /*
+         * Get the path where the INF file is.
+         */
+        _wsplitpath( lpszInfFullPath, Drive, Dir, NULL, NULL );
+
+        wcscpy( DirWithDrive, Drive );
+        wcscat( DirWithDrive, Dir );
+
+        /*
+         * Copy the INF file and other files referenced in the INF file.
+         */
+        if ( !SetupCopyOEMInfW(lpszInfFullPath,
+                               DirWithDrive,  /* Other files are in the */
+                                              /* same dir. as primary INF */
+                               SPOST_PATH,    /* First param is path to INF */
+                               0,             /* Default copy style */
+                               NULL,          /* Name of the INF after */
+                                              /* it's copied to %windir%\inf */
+                               0,             /* Max buf. size for the above */
+                               NULL,          /* Required size if non-null */
+                               NULL) )        /* Optionally get the filename */
+                                              /* part of Inf name after it is copied. */
+        {
+            dwError = GetLastError();
+
+            hr = HRESULT_FROM_WIN32( dwError );
+        }
+    }
+
+    if ( S_OK == hr )
+    {
+
+        /*
+         * Install the network component.
+         */
+        hr = vboxNetCfgWinInstallComponent( pnc,
+                                 lpszComponentId,
+                                 pguidClass );
+        if ( hr == S_OK )
+        {
+
+            /*
+             * On success, apply the changes
+             */
+            hr = pnc->Apply();
+        }
+    }
+
+    return hr;
+}
+
+/*
+ * List installed network components of specific class.
+ *
+ * Arguments:
+ *    hwndTree      [in]  Tree handle in which to list.
+ *    pguidClass    [in]  Class GUID of the network compoent class.
+ *
+ * Returns:   None.
+ */
+static HRESULT vboxNetCfgWinQueryComponentInstalled(IN INetCfg *pnc, IN const GUID* pguidClass, IN LPWSTR pnpId, OUT bool * pResult)
+{
+    IEnumNetCfgComponent *pencc;
+    INetCfgComponent     *pncc;
+    HRESULT              hr;
+    LPWSTR           lpszId;
+
+
+    *pResult = false;
+
+
+        /*
+         * Get Component Enumerator Interface.
+         */
+        hr = vboxNetCfgWinGetComponentEnum( pnc,
+                pguidClass,
+                &pencc );
+        if ( hr == S_OK )
+        {
+
+            hr = vboxNetCfgWinGetFirstComponent( pencc, &pncc );
+
+            while( hr == S_OK )
+            {
+
+                hr = pncc->GetId( &lpszId );
+
+                if ( hr == S_OK )
+                {
+                    if(!wcscmp(lpszId, pnpId))
+                    {
+                        *pResult = true;
+                        vboxNetCfgWinReleaseRef( pncc );
+                        break;
+                    }
+                }
+
+                vboxNetCfgWinReleaseRef( pncc );
+
+                hr = vboxNetCfgWinGetNextComponent( pencc, &pncc );
+            }
+
+            vboxNetCfgWinReleaseRef( pencc );
+        }
+        else
+        {
+            Log(("Failed to get the network component enumerator."));
+        }
+
+
+    return hr;
+}
+
+/*
+ * Install a network component from an INF file.
+ *
+ * Arguments:
+ *    lpszInfFile [in]  INF file.
+ *    lpszPnpID   [in]  PnpID of the network component to install.
+ *    pguidClass  [in]  Class GUID of the network component.
+ *
+ * Returns:   None.
+ */
+static HRESULT vboxNetCfgWinInstallSpecifiedComponent (LPWSTR lpszInfFile,
+                                   LPWSTR lpszPnpID,
+                                   const GUID *pguidClass,
+                                   bool bForceInstall)
+{
+    INetCfg    *pnc;
+    LPWSTR     lpszApp;
+    HRESULT    hr;
+
+    hr = vboxNetCfgWinQueryINetCfg( TRUE,
+                       VBOX_NETCFG_APP_NAME,
+                       &pnc,
+                       &lpszApp );
+
+    if ( hr == S_OK )
+    {
+        bool bInstall = true;
+
+        if(!bForceInstall)
+        {
+            /* check if it is installed already */
+            bool bInstalled = false;
+            hr = vboxNetCfgWinQueryComponentInstalled(pnc, pguidClass, lpszPnpID, &bInstalled);
+            if(hr == S_OK && bInstalled)
+            {
+                /* no need to install */
+                bInstall = false;
+            }
+        }
+
+        if(bInstall)
+        {
+            /*
+             * Install the network component.
+             */
+            hr = vboxNetCfgWinInstallNetComponent( pnc,
+                                        lpszPnpID,
+                                        pguidClass,
+                                        lpszInfFile );
+            if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) )
+            {
+
+                hr = pnc->Apply();
+            }
+            else
+            {
+                if ( hr != HRESULT_FROM_WIN32(ERROR_CANCELLED) )
+                {
+                    Log(("Couldn't install the network component." ));
+                }
+            }
+
+        }
+        vboxNetCfgWinReleaseINetCfg( pnc,
+                          TRUE );
+    }
+    else
+    {
+        if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp )
+        {
+            Log(("%s currently holds the lock, try later.", lpszApp));
+
+            CoTaskMemFree( lpszApp );
+        }
+        else
+        {
+            Log(("Couldn't the get notify object interface."));
+        }
+    }
+
+    return hr;
+}
+
+/**
+ * increments the reference to the netflt - to - aHostNetworkInterface binding reference count
+ * the exec flow:
+ * 1. if netflt is NOT installed currently - install it
+ * 2. if the NetFlt is not bound to the specified adapter - bind it
+ * 3. increase the binding reference count -
+ */
+STDMETHODIMP
+Host::NetFltAcquire (IHostNetworkInterface *aHostNetworkInterface,
+                                           IProgress **aProgress)
+{
+    HRESULT rc = S_OK;
+
+    /* TODO: encorporate with the VBoxSVC helper infastructure */
+
+    return rc;
+}
+
+/**
+ * decrements the reference to the netflt - to - aHostNetworkInterface binding reference count
+ */
+STDMETHODIMP
+Host::NetFltRelease (IHostNetworkInterface *aHostNetworkInterface,
+                                           IProgress **aProgress)
+{
+    HRESULT rc = S_OK;
+
+    /* TODO: encorporate with the VBoxSVC helper infastructure */
+
+    return rc;
+}
+# endif /*VBOX_WITH_NETFLT*/
 
 #endif /* RT_OS_WINDOWS */
Index: /trunk/src/VBox/Main/include/HostImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/HostImpl.h	(revision 12438)
+++ /trunk/src/VBox/Main/include/HostImpl.h	(revision 12439)
@@ -99,4 +99,21 @@
                                            IHostNetworkInterface **aHostNetworkInterface,
                                            IProgress **aProgress);
+# ifdef VBOX_WITH_NETFLT
+    /*
+     * increments the reference to the netflt - to - aHostNetworkInterface binding reference count
+     * the exec flow:
+     * 1. if netflt is NOT installed currently - install it
+     * 2. if the NetFlt is not bound to the specified adapter - bind it
+     * 3. increase the binding reference count -
+     */
+    STDMETHOD(NetFltAcquire) (IHostNetworkInterface *aHostNetworkInterface,
+                                           IProgress **aProgress);
+
+    /*
+     * decrements the reference to the netflt - to - aHostNetworkInterface binding reference count
+     */
+    STDMETHOD(NetFltRelease) (IHostNetworkInterface *aHostNetworkInterface,
+                                           IProgress **aProgress);
+# endif /*VBOX_WITH_NETFLT*/
 #endif
     STDMETHOD(CreateUSBDeviceFilter) (INPTR BSTR aName, IHostUSBDeviceFilter **aFilter);
