]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
new-loopback-dll-20040622
authorJeffrey Altman <jaltman@mit.edu>
Wed, 23 Jun 2004 08:48:18 +0000 (08:48 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Wed, 23 Jun 2004 08:48:18 +0000 (08:48 +0000)
Construct a new afsloopback.dll which contains the routines
for installing, removing, and verifying the existance of
a loopback adapter.  This dll will be used by both the NSIS
and the Wix installers.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

Update the wix installer to use the new version of instloop.exe
which uses the new afsloopback.dll

17 files changed:
src/NTMakefile
src/WINNT/install/NSIS/NTMakefile
src/WINNT/install/NSIS/loopback_install.cpp [deleted file]
src/WINNT/install/NSIS/loopback_install.def [deleted file]
src/WINNT/install/loopback/NTMakefile [new file with mode: 0644]
src/WINNT/install/loopback/instloop.c [new file with mode: 0644]
src/WINNT/install/loopback/loopbackutils.cpp [new file with mode: 0644]
src/WINNT/install/loopback/loopbackutils.h [new file with mode: 0644]
src/WINNT/install/loopback/renameconnection.cpp [new file with mode: 0644]
src/WINNT/install/loopback/wmi.cpp [new file with mode: 0644]
src/WINNT/install/wix/config.wxi
src/WINNT/install/wix/custom/NTMakefile
src/WINNT/install/wix/custom/instloop.c [deleted file]
src/WINNT/install/wix/custom/renameconnection.cpp [deleted file]
src/WINNT/install/wix/custom/wmi.cpp [deleted file]
src/WINNT/install/wix/openafs.wxs
src/config/NTMakefile

index ac03c9cd5816b92280c292f2d7fee31944e6413b..32101b647e5258bbaac98728a2a515dee98bfd2d 100644 (file)
@@ -601,6 +601,13 @@ mkdir:
        -mkdir $(DESTDIR)\free\bin
        -@copy $(SRC)\config\NTLANG.BAT .
 
+loopback:
+   echo ***** Making Loopback Adapter Utility DLL
+   $(DOCD) $(SRC)\WINNT\install\$@
+   $(CD) $(SRC)\WINNT\install\$@
+   $(NTMAKE)
+   $(CD) ..\..\..\..
+
 NSIS:
    echo ***** Making NSIS Installer
    $(DOCD) $(SRC)\WINNT\install\$@
@@ -627,11 +634,11 @@ InstallShield5:
        $(NTMAKE)
        $(CD) ..\..\..\..
 
-media: install InstallShield5 NSIS
+media: install loopback InstallShield5 NSIS wix
 
-install-nsis: install NSIS
+install-nsis: install loopback NSIS
 
-install-wix: install wix
+install-wix: install loopback wix
 
 install-is5: install InstallShield5
 
index c032d8a80d0487adae588972fb2e9eec71169500..b90525f31fb812aa59a1c7866d55e370a8c838bf 100644 (file)
@@ -22,12 +22,6 @@ $(OUT)\Killer.obj: Killer.cpp
 $(EXEDIR)\Killer.exe: $(OUT)\Killer.obj
       $(EXECONLINK) $(OUT)\Killer.obj
 
-$(OUT)\loopback_install.obj: loopback_install.cpp
-      $(C2OBJ) -I$(NTDDKDIR) loopback_install.cpp
-
-$(EXEDIR)\loopback_install.dll: $(OUT)\loopback_install.obj
-      $(DLLCONLINK) /DEF:loopback_install.def  $(OUT)\loopback_install.obj $(LOOPBACK_LIBS)
-
 prebuild:
 !IF ("$(AFSDEV_BUILDTYPE)" == "FREE")
 !IF ("$(AFSVER_CL)"=="1310")
@@ -87,7 +81,7 @@ prebuild:
 build: prebuild
    "C:\Program Files\NSIS\makensis.exe" /DINCLUDEDIR=$(OUT) OpenAFS.nsi
 
-install: $(OUT)\Service.obj $(EXEDIR)\Service.exe $(OUT)\Killer.obj $(EXEDIR)\Killer.exe $(EXEDIR)\loopback_install.dll build
+install: $(OUT)\Service.obj $(EXEDIR)\Service.exe $(OUT)\Killer.obj $(EXEDIR)\Killer.exe build
 
 #clean:
 #   $(DEL) $(OUT)\Service.obj
diff --git a/src/WINNT/install/NSIS/loopback_install.cpp b/src/WINNT/install/NSIS/loopback_install.cpp
deleted file mode 100644 (file)
index fcefd20..0000000
+++ /dev/null
@@ -1,1266 +0,0 @@
-/**
- * Copyright (c) 2003 Lingo Systems Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-// Modified 7/18/03 by Ben Creech for NCSU ITECS
-// to add command-line parameters and turn into a non-console app.
-
-// devcon -r install %SYSTEMROOT%\Inf\Netloop.inf *MSLOOP
-
-
-// Win2k
-#define _WIN32_DCOM
-#define UNICODE
-#define _UNICODE
-
-#include <windows.h>
-#include <shellapi.h>
-#include <wchar.h>
-#include <tchar.h>
-
-// The following two headers are from the Microsoft DDK
-#include <netcfgx.h>
-#include <netcfgn.h>
-
-#include <objbase.h>
-#include <setupapi.h>
-
-#include <devguid.h>
-#include <cfgmgr32.h>
-#include <regstr.h>
-#include <newdev.h>
-
-#include <string.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <wbemcli.h>     // WMI interface declarations
-
-#include <Msi.h>
-#include <Msiquery.h>
-
-#define DEFAULT_IPADDR     L"10.99.173.207"
-#define DEFAULT_SUBNETMASK L"255.255.255.254"
-
-bool bQuiet;
-
-//
-// UpdateDriverForPlugAndPlayDevices
-//
-typedef BOOL (WINAPI *UpdateDriverForPlugAndPlayDevicesProto)(HWND hwndParent,
-                                                         LPCTSTR hwid,
-                                                         LPCTSTR FullInfPath,
-                                                         DWORD InstallFlags,
-                                                         PBOOL bRebootRequired OPTIONAL
-                                                         );
-
-#define UPDATEDRIVERFORPLUGANDPLAYDEVICES "UpdateDriverForPlugAndPlayDevicesA"
-
-void display_usage();
-
-void EasyErrorBox (int hr, WCHAR *format, ...)
-{
-
-    LPWSTR   systemMessage;
-    WCHAR    buf[400];
-    ULONG    offset;
-    va_list  ap; 
-
-       if (bQuiet) return;
-
-    if(hr)
-        swprintf( buf, L"Error %#lx: ", hr );
-    else
-        buf[0] = 0;
-
-    offset = (ULONG) wcslen( buf );
-    va_start( ap, format );
-    vswprintf( buf+offset, format,ap );
-    va_end( ap );
-    if(hr) 
-    {
-        FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                       FORMAT_MESSAGE_FROM_SYSTEM |
-                       FORMAT_MESSAGE_IGNORE_INSERTS,
-                       NULL,
-                       hr,
-                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                       (LPWSTR)&systemMessage,
-                       0,
-                       NULL );
-        if(systemMessage)
-        {
-            offset = (ULONG) wcslen( buf );
-            swprintf( buf+offset, L"\n\nPossible cause:\n\n" );
-            offset = (ULONG) wcslen( buf );
-            wcscat( buf+offset, systemMessage );
-            LocalFree( (HLOCAL)systemMessage );
-        }
-        else
-        {
-            switch(hr)
-            {
-            case WBEM_E_FAILED: systemMessage = L"WBEM request failed."; break;
-            case WBEM_E_TYPE_MISMATCH: systemMessage = L"WBEM type mismatch."; break;
-            }
-            if(systemMessage)
-            {
-                offset = (ULONG) wcslen( buf );
-                swprintf( buf+offset, L"\n\nPossible cause:\n\n" );
-                offset = (ULONG) wcslen( buf );
-                wcscat( buf+offset, systemMessage );
-            }
-        }
-
-
-        MessageBoxW( NULL, buf, L"Error", MB_ICONERROR | MB_OK );
-    } 
-    else 
-    {
-        MessageBoxW( NULL, buf, L"loopback_install", MB_ICONINFORMATION | MB_OK );
-    }
-}
-
-// RSM4: Converted this to stdcall so NSIS System::Call can call it (It defaults to stdcall)
-DWORD _stdcall loopback_isInstalled()
-{
-    TCHAR * hwid = _T("*MSLOOP");
-    HDEVINFO DeviceInfoSet;
-    SP_DEVINFO_DATA DeviceInfoData;
-    DWORD i,err;
-    bool found;
-    
-    //
-    // Create a Device Information Set with all present devices.
-    //
-    DeviceInfoSet = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system
-    if (DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        EasyErrorBox(GetLastError(), L"GetClassDevs(All Present Devices) failed\n");
-        return false; // nothing installed?
-    }
-    
-    //
-    //  Enumerate through all Devices.
-    //
-    found = FALSE;
-    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-    for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++)
-    {
-        DWORD DataT;
-        TCHAR  *p, *buffer = NULL;
-        DWORD buffersize = 0;
-        
-        //
-        // We won't know the size of the HardwareID buffer until we call
-        // this function. So call it with a null to begin with, and then 
-        // use the required buffer size to Alloc the nessicary space.
-        // Keep calling we have success or an unknown failure.
-        //
-        while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,&DataT,(PBYTE)buffer,buffersize,&buffersize))
-        {
-            if (GetLastError() == ERROR_INVALID_DATA)
-            {
-                // May be a Legacy Device with no hwid. Continue.
-                break;
-            }
-            else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-            {
-                // We need to change the buffer size.
-                if (buffer) 
-                    LocalFree(buffer);
-                buffer = (TCHAR *)LocalAlloc(LPTR,buffersize);
-            }
-            else
-            {
-                // What the ... ?
-                EasyErrorBox(GetLastError(), L"Failed to detect Loopback adapter: GetDeviceRegistryProperty() returned an unknown error.");
-                goto cleanup_DeviceInfo;
-            }            
-        }
-        
-        if (GetLastError() == ERROR_INVALID_DATA) 
-            continue;
-        
-        // Compare each entry in the buffer multi-sz list with our hwid.
-        for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1)
-        {
-            if (!_tcsicmp(hwid,p))
-            {
-                found = TRUE;
-                break;
-            }
-        }
-        
-        if (buffer) LocalFree(buffer);
-        if (found) break;
-    }
-    
-    //  Cleanup.
-cleanup_DeviceInfo:
-    err = GetLastError();
-    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
-    SetLastError(err);
-    
-    return found;
-}
-
-
-// RSM4: Added 
-bool disable_loopback()
-{
-    TCHAR * hwid = _T("*MSLOOP");
-    HDEVINFO DeviceInfoSet;
-    SP_DEVINFO_DATA DeviceInfoData;
-    SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)};
-    DWORD i,err;
-    bool found,status=FALSE;
-    
-    //
-    // Create a Device Information Set with all present devices.
-    //
-    DeviceInfoSet = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system
-    if (DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        EasyErrorBox(GetLastError(), L"GetClassDevs(All Present Devices) failed\n");
-        return false; // nothing installed?
-    }
-    
-    //
-    //  Enumerate through all Devices.
-    //
-    found = FALSE;
-    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-    for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++)
-    {
-        DWORD DataT;
-        TCHAR * p, *buffer = NULL;
-        DWORD buffersize = 0;
-        
-        //
-        // We won't know the size of the HardwareID buffer until we call
-        // this function. So call it with a null to begin with, and then 
-        // use the required buffer size to Alloc the nessicary space.
-        // Keep calling we have success or an unknown failure.
-        //
-        while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,&DataT,(PBYTE)buffer,buffersize,&buffersize))
-        {
-            if (GetLastError() == ERROR_INVALID_DATA)
-            {
-                // May be a Legacy Device with no hwid. Continue.
-                break;
-            }
-            else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-            {
-                // We need to change the buffer size.
-                if (buffer) 
-                    LocalFree(buffer);
-                buffer = (TCHAR *)LocalAlloc(LPTR,buffersize);
-            }
-            else
-            {
-                // What the ... ?
-                EasyErrorBox(GetLastError(), L"Failed to detect Loopback adapter: GetDeviceRegistryProperty() returned an unknown error.");
-                goto cleanup_DeviceInfo;
-            }            
-        }
-        
-        if (GetLastError() == ERROR_INVALID_DATA) 
-            continue;
-        
-        // Compare each entry in the buffer multi-sz list with our hwid.
-        for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1)
-        {
-            if (!_tcsicmp(hwid,p))
-            {
-                found = TRUE;
-                break;
-            }
-        }
-        
-        if (buffer) LocalFree(buffer);
-        if (found) break;
-    }
-    
-    // If we found the device, disable it...
-    if (found)
-    {
-       //
-       // Set the PropChangeParams structure.
-       //
-       PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
-       PropChangeParams.Scope = DICS_FLAG_GLOBAL;
-       PropChangeParams.StateChange = DICS_DISABLE; 
-
-       if (SetupDiSetClassInstallParams(DeviceInfoSet,
-          &DeviceInfoData,
-          (SP_CLASSINSTALL_HEADER *)&PropChangeParams,
-          sizeof(PropChangeParams)))
-          {
-             //
-             // Call the ClassInstaller and perform the change.
-             //
-             if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
-                DeviceInfoSet,
-             &DeviceInfoData))
-                   status=TRUE;
-             else
-                EasyErrorBox(GetLastError(), L"Could not disable LoopBack adapter: SetupDiSetClassInstallParams failed");
-          }
-      else
-          EasyErrorBox(GetLastError(), L"Could not disable LoopBack adapter: SetupDiSetClassInstallParams failed");
-
-    }
-    
-    
-    //  Cleanup.
-cleanup_DeviceInfo:
-    err = GetLastError();
-    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
-    SetLastError(err);
-    
-    return status;
-}
-
-
-bool loopback_install(int *rebootNeeded)
-{
-    SP_DEVINFO_DATA DeviceInfoData;
-    GUID ClassGUID;
-    HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
-    TCHAR ClassName[MAX_CLASS_NAME_LEN];
-    TCHAR hwIdList[LINE_LEN+4];
-    TCHAR InfPath[MAX_PATH];
-    bool success = false;
-    TCHAR * hwid = _T("*MSLOOP");
-    TCHAR * inf = _T("INF\\NETLOOP.INF");
-    DWORD flags = 0;
-    HMODULE newdevMod = NULL;
-    UpdateDriverForPlugAndPlayDevicesProto UpdateFn;
-    
-    TCHAR *systemRoot = _tgetenv(_T("SYSTEMROOT"));
-    SetCurrentDirectory(systemRoot);
-
-    // Inf must be a full pathname
-    if(GetFullPathName(inf,MAX_PATH,InfPath,NULL) >= MAX_PATH) {
-        puts("Failed to configure Loopback adapter: inf pathname too long");
-        return false;
-    }
-
-    // List of hardware ID's must be double zero-terminated
-    ZeroMemory(hwIdList,sizeof(hwIdList));
-    lstrcpyn(hwIdList,hwid,LINE_LEN);
-
-    // Use the INF File to extract the Class GUID.
-    if (!SetupDiGetINFClass(InfPath,&ClassGUID,ClassName,sizeof(ClassName),0))
-    {
-        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: Failed to read INF for %s\n", InfPath);
-        goto final;
-    }
-
-    //
-    // Create the container for the to-be-created Device Information Element.
-    //
-    DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);
-    if(DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: Failed to create device info list for %s\n", ClassName);
-        goto final;
-    }
-
-    //
-    // Now create the element.
-    // Use the Class GUID and Name from the INF file.
-    //
-    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-    if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData))
-        goto final;
-
-    //
-    // Add the hwid to the Device's hwid property.
-    //
-    if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)hwIdList, (lstrlen(hwIdList)+1+1)*sizeof(TCHAR)))
-        goto final;
-
-    //
-    // Transform the registry element into an actual devnode
-    // in the PnP HW tree.
-    //
-    if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData))
-    {
-        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: Failed to call class installer for %s\n", inf);
-        goto final;
-    }
-
-    inf = InfPath;
-    flags |= INSTALLFLAG_FORCE;
-
-    // make use of UpdateDriverForPlugAndPlayDevices
-    newdevMod = LoadLibrary(TEXT("newdev.dll"));
-    if(!newdevMod)
-    {
-        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: Failed to load newdev.dll\n", inf);
-        goto final;
-    }
-
-    UpdateFn = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(newdevMod,UPDATEDRIVERFORPLUGANDPLAYDEVICES);
-    if(!UpdateFn)
-    {
-        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: Failed to read the driver updating function from newdev.dll\n", inf);
-        goto final;
-    }
-
-    if(!UpdateFn(NULL,hwid,inf,flags,rebootNeeded))
-    {
-        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: Failed to update the driver for %s\n", inf);
-        goto final;
-    }
-
-    success = true;
-
-final:
-
-    if(newdevMod) {
-        FreeLibrary(newdevMod);
-    }
-
-    if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
-        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
-    }
-
-    return success;
-}
-
-//+---------------------------------------------------------------------------
-//    getWriteLock [in]  whether to get write lock
-//    ppnc          [in]  pointer to pointer to INetCfg object
-//
-// Returns:   S_OK on success, otherwise an error code
-HRESULT getInetCfg(bool getWriteLock, WCHAR *appName, INetCfg** ppnc, WCHAR **holdingAppName)
-{
-    HRESULT hr=S_OK;
-
-    // Initialize the output parameters.
-    *ppnc = NULL;
-
-    // Create the object implementing INetCfg.
-    //
-    INetCfg* pnc;
-    hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER,
-                          IID_INetCfg, (void**)&pnc);
-    if (SUCCEEDED(hr))
-    {
-        INetCfgLock * pncLock = NULL;
-        if (getWriteLock)
-        {
-            // Get the locking interface
-            hr = pnc->QueryInterface(IID_INetCfgLock,
-                                     (LPVOID *)&pncLock);
-            if (SUCCEEDED(hr))
-            {
-                // Attempt to lock the INetCfg for read/write
-                static const ULONG c_cmsTimeout = 15000;
-
-                hr = pncLock->AcquireWriteLock(c_cmsTimeout,
-                                               appName,
-                                               holdingAppName);
-                if (S_FALSE == hr)
-                {
-                    hr = NETCFG_E_NO_WRITE_LOCK;
-                    EasyErrorBox(hr, L"Failed to configure Loopback adapter: Could not lock INetcfg, it is already locked by '%s'", *holdingAppName);
-                }
-            }
-        }
-
-        if (SUCCEEDED(hr))
-        {
-            // Initialize the INetCfg object.
-            //
-            hr = pnc->Initialize(NULL);
-            if (SUCCEEDED(hr))
-            {
-                *ppnc = pnc;
-                pnc->AddRef();
-            }
-            else
-            {
-                // initialize failed, if obtained lock, release it
-                if (pncLock)
-                {
-                    pncLock->ReleaseWriteLock();
-                }
-            }
-        }
-        if(pncLock) pncLock->Release();
-        if(pnc) pnc->Release();
-    }
-
-
-    return hr;
-}
-
-//+---------------------------------------------------------------------------
-//    hasWriteLock [in]  whether write lock needs to be released.
-//    pnc           [in]  pointer to INetCfg object
-
-HRESULT releaseInetCfg(INetCfg* pnc, bool hasWriteLock)
-{
-    HRESULT hr = S_OK;
-
-    // uninitialize INetCfg
-    hr = pnc->Uninitialize();
-
-    // if write lock is present, unlock it
-    if (SUCCEEDED(hr) && hasWriteLock)
-    {
-        INetCfgLock* pncLock;
-
-        // Get the locking interface
-        hr = pnc->QueryInterface(IID_INetCfgLock,
-                                 (LPVOID *)&pncLock);
-        if (SUCCEEDED(hr))
-        {
-            hr = pncLock->ReleaseWriteLock();
-            if(pncLock) pncLock->Release();
-        }
-    }
-
-    if(pnc) pnc->Release();
-
-    return hr;
-}
-
-bool ChangeBinding(WCHAR *inf, WCHAR *binding, bool bind)
-{
-
-    INetCfg                   *pnc;
-    INetCfgComponent          *pncc;
-    INetCfgComponentBindings  *pnccb;
-    INetCfgComponent          *pnccToChange;
-    WCHAR *                   lpszApp;
-    HRESULT                   hr;
-    bool                      fChange=false;
-
-
-    hr = getInetCfg(TRUE, L"loopback_install", &pnc, &lpszApp);
-    if(hr == S_OK) 
-    {
-        // Get a reference to the network component.
-        hr = pnc->FindComponent(inf, &pncc);
-        if(hr == S_OK) 
-        {
-            // Get a reference to the component's binding.
-            hr = pncc->QueryInterface(IID_INetCfgComponentBindings, (PVOID *)&pnccb);
-            if(hr == S_OK) 
-            {
-                // Get a reference to the selected component.
-                hr = pnc->FindComponent(binding, &pnccToChange);
-                if(hr == S_OK) 
-                {
-                    if(bind) 
-                    {
-                        // Bind the component to the selected component.
-                        hr = pnccb->BindTo(pnccToChange);
-                        fChange = (fChange || hr == S_OK);
-
-                        if(hr != S_OK) EasyErrorBox(hr, L"Failed to configure Loopback adapter: %s couldn't be bound to %s.", inf, binding);
-                    }
-                    else 
-                    {
-                        // Unbind the component from the selected component.
-                        hr = pnccb->UnbindFrom(pnccToChange);
-                        fChange = (fChange || hr == S_OK);
-
-                        if(hr != S_OK) EasyErrorBox(hr, L"Failed to configure Loopback adapter: %s couldn't be unbound from %s.", inf, binding);
-                        //else EasyErrorBox(hr, L"%s will be unbound from %s.", inf, binding);
-                    }
-
-                    pnccToChange->Release();
-                } 
-                else 
-                {
-                    if(bind) // Don't have to unbind something thats not installed, so only print an error if we're binding it
-                        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: Couldn't get an interface pointer to %s. %s will not be bound to it. (Maybe this is not installed on your system.)", binding, inf);
-                }
-
-                pnccb->Release();
-            }
-            else 
-            {
-                EasyErrorBox(hr, L"Failed to configure Loopback adapter: Couldn't get a binding interface of %s.", inf);
-            }
-
-            pncc->Release();
-        }
-        else 
-        {
-            EasyErrorBox(hr, L"Couldn't get an interface pointer to %s.", inf);
-        }
-
-        //
-        // If one or more network components have been bound/unbound,
-        // apply the changes.
-        //
-
-        if(fChange) 
-        {
-            hr = pnc->Apply();
-
-            fChange = hr == S_OK;
-        }
-
-        releaseInetCfg(pnc, true);
-    }
-    else 
-    {
-        if((hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp) 
-        {
-            EasyErrorBox(hr, L"%s currently holds the lock, try later.", lpszApp);
-            CoTaskMemFree(lpszApp);
-        }
-        else 
-        {
-            EasyErrorBox(hr, L"Couldn't get the notify object interface.");
-        }
-    }
-
-    return fChange;
-}
-
-// Unbind microsoft services so our NetBIOS will be functional:
-// ms_msclient will be unbound from *msloop
-// ms_server will be unbound from *MSLOOP
-int loopback_unbindmsnet()
-{
-    // Unbind microsoft's NetBIOS hogs
-    // Whats interesting is that CIFS shares on that device still work
-    // even when the client for microsoft networks is not bound to that
-    // device
-    ChangeBinding(L"ms_msclient", L"*MSLOOP", false);
-    ChangeBinding(L"ms_server", L"*MSLOOP", false);
-
-    // Bind TCP/IP
-    ChangeBinding(L"ms_tcpip", L"*MSLOOP", true);
-    return 1;
-}
-
-//
-// Debugging function to help us print variant records
-// This is copied from some microsoft sample
-//
-#define BLOCKSIZE (32 * sizeof(WCHAR))
-#define CVTBUFSIZE (309+40) /* # of digits in max. dp value + slop  (this size stolen from cvt.h in c runtime library) */
-LPWSTR ValueToString(VARIANT *pValue, WCHAR **pbuf)
-{
-   DWORD iNeed = 0;
-   DWORD iVSize = 0;
-   DWORD iCurBufSize = 0;
-
-   WCHAR *vbuf = NULL;
-   WCHAR *buf = NULL;
-
-
-   switch (pValue->vt) 
-   {
-
-   case VT_NULL: 
-         buf = (WCHAR *)malloc(BLOCKSIZE);
-         wcscpy(buf, L"<null>");
-         break;
-
-   case VT_BOOL: {
-         VARIANT_BOOL b = pValue->boolVal;
-         buf = (WCHAR *)malloc(BLOCKSIZE);
-
-         if (!b) {
-            wcscpy(buf, L"FALSE");
-         } else {
-            wcscpy(buf, L"TRUE");
-         }
-         break;
-      }
-
-   case VT_UI1: {
-         BYTE b = pValue->bVal;
-             buf = (WCHAR *)malloc(BLOCKSIZE);
-         if (b >= 32) {
-            swprintf(buf, L"'%c' (%d, 0x%X)", b, b, b);
-         } else {
-            swprintf(buf, L"%d (0x%X)", b, b);
-         }
-         break;
-      }
-
-   case VT_I2: {
-         SHORT i = pValue->iVal;
-         buf = (WCHAR *)malloc(BLOCKSIZE);
-         swprintf(buf, L"%d (0x%X)", i, i);
-         break;
-      }
-
-   case VT_I4: {
-         LONG l = pValue->lVal;
-         buf = (WCHAR *)malloc(BLOCKSIZE);
-         swprintf(buf, L"%d (0x%X)", l, l);
-         break;
-      }
-
-   case VT_R4: {
-         float f = pValue->fltVal;
-         buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
-         swprintf(buf, L"%10.4f", f);
-         break;
-      }
-
-   case VT_R8: {
-         double d = pValue->dblVal;
-         buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
-         swprintf(buf, L"%10.4f", d);
-         break;
-      }
-
-   case VT_BSTR: {
-                LPWSTR pWStr = pValue->bstrVal;
-                buf = (WCHAR *)malloc((wcslen(pWStr) * sizeof(WCHAR)) + sizeof(WCHAR) + (2 * sizeof(WCHAR)));
-            swprintf(buf, L"\"%wS\"", pWStr);
-                break;
-               }
-
-       // the sample GUI is too simple to make it necessary to display
-       // these 'complicated' types--so ignore them.
-   case VT_DISPATCH:  // Currently only used for embedded objects
-   case VT_BOOL|VT_ARRAY: 
-   case VT_UI1|VT_ARRAY: 
-   case VT_I2|VT_ARRAY: 
-   case VT_I4|VT_ARRAY: 
-   case VT_R4|VT_ARRAY: 
-   case VT_R8|VT_ARRAY: 
-   case VT_BSTR|VT_ARRAY: 
-   case VT_DISPATCH | VT_ARRAY: 
-         break;
-
-   default:
-         buf = (WCHAR *)malloc(BLOCKSIZE);
-         wcscpy(buf, L"<conversion error>");
-
-   }
-
-   *pbuf = buf;   
-   return buf;
-}
-
-void VariantInitStringArray(VARIANT &var, BSTR str)
-{
-    DWORD hr;
-    BSTR *arrayContents;
-    var.vt = VT_BSTR|VT_ARRAY;
-    var.parray = SafeArrayCreateVector(VT_BSTR, 0, 1);
-    if((hr = SafeArrayAccessData(var.parray, (void **)&arrayContents))) { EasyErrorBox (0, L"Failed to access contents"); exit(1); }
-    arrayContents[0] = str;
-}
-
-
-WCHAR *EnableStatic_strerror(int err)
-{
-    switch(err)
-    {
-    case 0:   return L"Successful completion, no reboot required.";
-    case 1:   return L"Successful completion, reboot required.";
-    case 64:  return L"Method not supported on this platform.";
-    case 65:  return L"Unknown failure.";
-    case 66:  return L"Invalid subnet mask.";
-    case 67:  return L"An error occurred while processing an instance that was returned.";
-    case 68:  return L"Invalid input parameter.";
-    case 69:  return L"More than five gateways specified.";
-    case 70:  return L"Invalid IP address.";
-    case 71:  return L"Invalid gateway IP address.";
-    case 72:  return L"An error occurred while accessing the registry for the requested information.";
-    case 73:  return L"Invalid domain name.";
-    case 74:  return L"Invalid host name.";
-    case 75:  return L"No primary or secondary WINS server defined.";
-    case 76:  return L"Invalid file.";
-    case 77:  return L"Invalid system path.";
-    case 78:  return L"File copy failed.";
-    case 79:  return L"Invalid security parameter.";
-    case 80:  return L"Unable to configure TCP/IP service.";
-    case 81:  return L"Unable to configure DHCP service.";
-    case 82:  return L"Unable to renew DHCP lease.";
-    case 83:  return L"Unable to release DHCP lease.";
-    case 84:  return L"IP not enabled on adapter.";
-    case 85:  return L"IPX not enabled on adapter.";
-    case 86:  return L"Frame/network number bounds error.";
-    case 87:  return L"Invalid frame type.";
-    case 88:  return L"Invalid network number.";
-    case 89:  return L"Duplicate network number.";
-    case 90:  return L"Parameter out of bounds.";
-    case 91:  return L"Access denied.";
-    case 92:  return L"Out of memory.";
-    case 93:  return L"Already exists.";
-    case 94:  return L"Path, file, or object not found.";
-    case 95:  return L"Unable to notify service.";
-    case 96:  return L"Unable to notify DNS service.";
-    case 97:  return L"Interface not configurable.";
-    case 98:  return L"Not all DHCP leases could be released or renewed.";
-    case 100: return L"DHCP not enabled on adapter.";
-    default:  return L"See online for the description of this error";
-    }
-}
-
-// Change the loopback to use a static IP: 127.0.0.2
-// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/retrieving_class_or_instance_data.asp
-// GetObject()
-// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/iwbemservices_getobject.asp
-// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_networkadapter.asp
-// EnableStatic()
-// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/enablestatic_method_in_class_win32_networkadapterconfiguration.asp
-// #define loopback_adapter_path "Win32_NetworkAdapter"
-int loopback_configure(int *needReboot, WCHAR *loopbackIP, WCHAR *loopbackNetmask)
-{
-       HRESULT  hRes;
-       BSTR propName = NULL, val = NULL;
-       VARIANT pVal;
-       ULONG uReturned;
-    int result=1;
-
-       IEnumWbemClassObject *pEnumServices = NULL;
-       IWbemLocator *pIWbemLocator = NULL;
-       HRESULT hr = S_OK;
-
-       //------------------------
-    // Create an instance of the WbemLocator interface.
-    if(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pIWbemLocator) == S_OK)
-    {
-               //------------------------
-               // Use the pointer returned in step two to connect to
-               //     the server using the passed in namespace.
-        // It is very important never to pass any string not allocated using SysAllocString to any COM function
-               BSTR pNamespace = SysAllocString(L"\\\\.\\root\\cimv2");
-        IWbemServices *pIWbemServices = NULL;
-
-               if((hr = pIWbemLocator->ConnectServer(pNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices)) == S_OK) 
-               {       
-                       CoSetProxyBlanket(pIWbemServices,
-                               RPC_C_AUTHN_WINNT,
-                               RPC_C_AUTHZ_NONE,
-                               NULL,
-                               RPC_C_AUTHN_LEVEL_CALL,
-                               RPC_C_IMP_LEVEL_IMPERSONATE,
-                               NULL,
-                               EOAC_NONE
-                       );
-
-            BSTR className = SysAllocString(L"Win32_NetworkAdapterConfiguration");
-            // Lets lookup the class first
-            IWbemClassObject *pClass = NULL;
-            if((hRes = pIWbemServices->GetObject(className, 0, NULL, &pClass, NULL)) == S_OK)
-            {
-                BSTR methodName = SysAllocString(L"EnableStatic");
-
-
-                /** // Uncomment this debugging code to check the qualifiers of your EnableStatic method
-                IWbemQualifierSet *quals=NULL;
-                hr = pClass->GetMethodQualifierSet(methodName, &quals);
-                if(hr == WBEM_S_NO_ERROR)
-                {
-                    BSTR qualName, qualValue;
-
-                    quals->BeginEnumeration(0);
-                    while(quals->Next(0, &qualName, &pVal, NULL) == S_OK)
-                    {
-                        printf("qualifier: %ws = %ws\n", qualName, ValueToString(&pVal, &qualValue));
-                    }
-                    quals->Release();
-                }
-                */
-
-                IWbemClassObject * pInClass = NULL;
-                hr = pClass->GetMethod(methodName, 0, &pInClass, NULL);
-                if(hr == WBEM_S_NO_ERROR)
-                {
-                    // WBEM_E_ACCESS_DENIED
-                       //----------------------
-                       // execute the query.
-                       BSTR qLang = SysAllocString(L"WQL");
-                    BSTR query = SysAllocString(L"select * from Win32_NetworkAdapterConfiguration where ServiceName = \"msloop\"");
-                       if((hRes = pIWbemServices->ExecQuery(qLang, query, 0L, NULL, &pEnumServices)) == S_OK)
-                       {
-                       IWbemClassObject *pInstance = NULL;
-
-                        //----------------------
-                               // Only configure the first one; if there are multiple loopback adapters they are up to something
-                        // and we'd rather not interfere (or this tool mistakenly installed a second one)
-                               if(((hRes = pEnumServices->Next(5000, 1, &pInstance, &uReturned)) == S_OK) && (uReturned == 1))
-                               {
-                            // Lookup the "index" (the primary key for Win32_NetworkAdapterConfiguration)
-                            BSTR varName = SysAllocString(L"Index");
-                            if(S_OK == pInstance->Get(varName, 0, &pVal, NULL, NULL))
-                            {
-                                // Create an instance of the input parameters of this method
-                                IWbemClassObject * pInInst = NULL;                            
-                                hr = pInClass->SpawnInstance(0, &pInInst);
-                                if(hr == WBEM_S_NO_ERROR)
-                                {
-                                    // Now fill that instance in with useful parameters.
-                                    BSTR ipAddressStr = SysAllocString(L"IPAddress");
-                                    BSTR subnetMaskStr = SysAllocString(L"SubnetMask");
-                                    BSTR loopbackIPCopy = SysAllocString(loopbackIP);
-                                    BSTR loopbackNetMaskCopy = SysAllocString(loopbackNetmask);
-
-                                    // Two string arrays: one with the ip addresses, the other with subnet masks
-                                    VARIANT ipVar, maskVar;
-                                    
-                                    // Create the IP Address array and put our ip address into it
-                                    VariantInitStringArray(ipVar, loopbackIPCopy);
-
-                                    // Create the subnet mask array and put our subnet mask into it
-                                    VariantInitStringArray(maskVar, loopbackNetMaskCopy);
-                                    
-                                    // Write the parameters into the params object
-                                    hr = pInInst->Put(ipAddressStr, 0, &ipVar, 0);    if(hr) EasyErrorBox(hr, L"Args->Put(IPAddress) failed\n");
-                                    hr = pInInst->Put(subnetMaskStr, 0, &maskVar, 0); if(hr) EasyErrorBox(hr, L"Args->Put(SubnetMask) failed\n");
-
-                                    /** // Uncomment this debugging code to view the parameters before the method is called
-                                    BSTR pInText=NULL;
-                                    pInInst->GetObjectText(0, &pInText);
-                                    printf("Parameters: %ws\n", pInText);
-                                    */
-
-                                    // Call the method
-                                    IWbemClassObject * pOutInst = NULL;
-                                    
-                                    // Compute the object path and copy it into a COM string
-                                    WCHAR objectPathBuf[255];
-                                    wsprintfW(objectPathBuf, L"Win32_NetworkAdapterConfiguration.Index=%d", pVal.intVal);
-                                    BSTR objectPath = SysAllocString(objectPathBuf);
-
-                                    // Go go go!
-                                    hr = pIWbemServices->ExecMethod(objectPath, methodName, 0, NULL, pInInst, &pOutInst, NULL);
-                                    if(hr == WBEM_S_NO_ERROR)
-                                    {
-                                        // Extract the return value (from the field called "ReturnValue")
-                                        VARIANT retVal;
-                                        BSTR retValName = SysAllocString(L"ReturnValue");
-                                        hr = pOutInst->Get(retValName, 0, &retVal, 0, 0);
-                                        if(hr == WBEM_S_NO_ERROR)
-                                        {
-                                            // If it returns 1, we should reboot
-                                            if(retVal.intVal == 1)
-                                            {
-                                                *needReboot = 1;
-                                            }
-                                            else if(retVal.intVal == 0)
-                                            {
-                                                // Everything is great
-                                            }
-                                            else
-                                            {
-                                                                                               if (retVal.intVal == 81) { // "Unable to configure DHCP"; seems to be returned superfluously sometimes
-                                                    // Just print it out without bugging the user; that way admins can see it but they can also ignore it
-                                                                                                       EasyErrorBox (0, L"Failed to configure Loopback adapter: EnableStatic() returns %d: %s\n", retVal.intVal, EnableStatic_strerror(retVal.intVal));
-                                                                                                       result = 0;
-                                                                                               } else {
-                                                    // For descriptions of these error codes try:
-                                                    // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/enablestatic_method_in_class_win32_networkadapterconfiguration.asp
-                                                                                                       EasyErrorBox(hr, L"Failed to configure Loopback adapter: EnableStatic() returns %d (%s)", retVal.intVal, EnableStatic_strerror(retVal.intVal));
-                                                                                                       result = 0;
-                                                                                               }
-                                            }
-                                        }
-                                        else
-                                        {
-                                            // This shouldn't happen, methinks
-                                            BSTR objText=NULL;
-                                            pOutInst->GetObjectText(0, &objText);
-                                            EasyErrorBox(hr, L"Successfully called EnableStatic(); result = %ws but unable to get ReturnValue\n", objText);
-                                                                                       result = 0;
-                                        }
-                                    }
-                                    else
-                                    {
-                                        // After all that work, we still couldn't execute the method?  Probably a BSTR was allocated using SysAllocString but thats just my prophesy
-                                        EasyErrorBox(hr, L"Failed to configure Loopback adapter: ExecMethod() failed\n");
-                                                                               result = 0;
-                                    }
-
-                                    if(pOutInst)
-                                    {
-                                        pOutInst->Release();
-                                        pOutInst = NULL;
-                                    }
-
-                                    // Release some resources; this function isn't likely to be part of a long running
-                                    // program, but I've seen stranger things.
-                                    SafeArrayDestroy(ipVar.parray);
-                                    SafeArrayDestroy(maskVar.parray);
-                                    SysFreeString(ipAddressStr);
-                                    SysFreeString(subnetMaskStr);
-                                    SysFreeString(loopbackNetMaskCopy);
-                                    SysFreeString(loopbackIPCopy);
-                                }
-                                else
-                                {
-                                    EasyErrorBox(hr, L"Failed to configure Loopback adapter: Failed to Spawn an instance of the method's parameters\n");
-                                                                       result = 0;
-                                }
-
-                                if(pInInst)
-                                {
-                                    pInInst->Release();
-                                    pInInst = NULL;
-                                }
-                            }
-                            else
-                            {
-                                EasyErrorBox(hr, L"Failed to configure Loopback adapter: Unable to read ServiceName\n");
-                                                               result = 0;
-                            }
-
-                                       // done with the ClassObject
-                                       if (pInstance)
-                                       { 
-                                               pInstance->Release(); 
-                                               pInstance = NULL;
-                                       }
-
-                            SysFreeString(varName);
-
-                               }
-
-                               // did the while loop exit due to an error?
-                               if((hRes != S_OK) && 
-                                  (hRes != 1))
-                               {
-                                       EasyErrorBox(hRes, L"Failed to configure Loopback adapter: pEnumServices->Next() failed %s\n");
-                                                       result = 0;
-                               }
-
-                               if (pEnumServices)
-                               { 
-                                       pEnumServices->Release(); 
-                                       pEnumServices = NULL;
-                               }
-                       }
-                       else
-                       {
-                           EasyErrorBox(hRes, L"Failed to configure Loopback adapter: ExecQuery('%s', '%s') failed\n", qLang, query);
-                                               result = 0;
-                       }
-
-                       SysFreeString(qLang);
-                       SysFreeString(query);
-                }
-                else
-                {
-                    EasyErrorBox(hRes, L"Failed to configure Loopback adapter: GetMethod(\"EnableStatic\") failed\n");
-                                       result = 0;
-                }
-
-                SysFreeString(methodName);
-            }
-            else
-            {
-                EasyErrorBox(hRes, L"Failed to configure Loopback adapter: GetObject(\"Win32_NetworkAdapterConfiguration\") failed\n");
-                               result = 0;
-            }
-
-            SysFreeString(className);
-        }
-
-        SysFreeString(pNamespace);
-    }
-    else
-    {
-        EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: CoCreateInstance(CLSID_WbemLocator) failed.\n");
-        result = 0;
-    } 
-
-   return result;
-}
-
-class ARGS {
-public:
-       bool bQuiet;
-       LPWSTR lpIPAddr;
-       LPWSTR lpSubnetMask;
-       ARGS () : bQuiet (0), lpIPAddr (0), lpSubnetMask (0) { }
-       ~ARGS () {
-               if (lpIPAddr) free (lpIPAddr);
-               if (lpSubnetMask) free (lpSubnetMask);
-       }
-};
-
-void wcsMallocAndCpy (LPWSTR * dst, const LPWSTR src) {
-       *dst = (LPWSTR) malloc ((wcslen (src) + 1) * sizeof (WCHAR));
-       wcscpy (*dst, src);
-}
-
-int process_args (LPWSTR lpCmdLine, ARGS & args) {
-       int i, iNumArgs;
-       LPWSTR * argvW;
-
-       argvW = CommandLineToArgvW (lpCmdLine, &iNumArgs);
-       for (i = 0; i < iNumArgs; i++)
-       {
-               if (wcsstr (argvW[i], L"help")
-                       || !_wcsicmp (argvW[i], L"?")
-                       || (wcslen(argvW[i]) == 2 && argvW[i][1] == L'?'))
-               {
-                       display_usage();
-                       GlobalFree (argvW);
-                       return 0;
-               }
-
-               if (!_wcsicmp (argvW[i], L"q") || !_wcsicmp (argvW[i], L"quiet")) {
-                       args.bQuiet = true;
-                       continue;
-               }
-
-               if (!args.lpIPAddr) {
-                       wcsMallocAndCpy (&args.lpIPAddr, argvW[i]);
-                       continue;
-               }
-
-               if (!args.lpSubnetMask) {
-                       wcsMallocAndCpy (&args.lpSubnetMask, argvW[i]);
-                       continue;
-               }
-
-               display_usage();
-               GlobalFree (argvW);
-               return 0;
-       }
-
-       if (!args.lpIPAddr)
-               wcsMallocAndCpy (&args.lpIPAddr, DEFAULT_IPADDR);
-       if (!args.lpSubnetMask)
-               wcsMallocAndCpy (&args.lpSubnetMask, DEFAULT_SUBNETMASK);
-
-       GlobalFree (argvW);
-       return 1;
-}
-
-void display_usage() {
-       EasyErrorBox (0,
-               L"Installation utility for the MS Loopback Adapter\r\n\r\n"
-               L"Usage:\r\n"
-               L"RunDll32 loopback_install.dll doLoopBackEntry [q|quiet] [IP address] [Subnet Mask]\r\n"
-               L"  \"Quiet\" supresses error messages\r\n"
-               L"  \"IP address\" defaults to %s\r\n"
-               L"  \"Subnet Mask\" defaults to %s\r\n",
-               DEFAULT_IPADDR, DEFAULT_SUBNETMASK);
-}
-
-int doLoopBack (LPWSTR lpIPAddr, LPWSTR lpSubnetMask) {
-       int rc;
-    // initialize COM
-       // This and CoInitializeSecurity fail when running under the MSI
-       // engine, but there seems to be no ill effect (the security is now
-       // set on the specific object via CoSetProxyBlanket in loopback_configure)
-    if(CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ))
-    {
-               //Don't fail (MSI install will have already initialized COM)
-        //EasyErrorBox(0, L"Failed to initialize COM.");
-        //return 1;
-    }
-
-       // Initialize COM security (otherwise we'll get permission denied when we try to use WMI or NetCfg)
-    CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
-
-    int rebootNeeded = 0;
-    
-    if(loopback_isInstalled() || loopback_install(&rebootNeeded))
-    {
-        rc = loopback_unbindmsnet();
-               if (!rc) return 1;
-        rc = loopback_configure(&rebootNeeded, lpIPAddr, lpSubnetMask);
-               if (!rc) return 1;
-    }
-
-       CoUninitialize();
-
-       if(rebootNeeded) {
-        EasyErrorBox(0, L"Please reboot.\n");
-        return 2;
-    }
-    return 0;
-}
-
-void CALLBACK doLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdShow)
-{
-       ARGS args;
-
-       if (!process_args(lpCmdLine, args)) return;
-       bQuiet = args.bQuiet; // laziness
-
-       doLoopBack (args.lpIPAddr, args.lpSubnetMask);
-}
-
-void CALLBACK disableLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdSHow)
-{
-   ARGS args;
-       int rc;
-
-    // initialize COM
-       // This and CoInitializeSecurity fail when running under the MSI
-       // engine, but there seems to be no ill effect (the security is now
-       // set on the specific object via CoSetProxyBlanket in loopback_configure)
-    if(CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ))
-    {
-               //Don't fail (MSI install will have already initialized COM)
-        //EasyErrorBox(0, L"Failed to initialize COM.");
-        //return 1;
-    }
-
-       // Initialize COM security (otherwise we'll get permission denied when we try to use WMI or NetCfg)
-    CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
-
-   disable_loopback();
-
-       CoUninitialize();
-   
-   
-}
-
-UINT __stdcall installLoopbackMSI (MSIHANDLE hInstall)
-{
-       LPWSTR szValueBuf;
-       DWORD cbValueBuf = 256;
-       ARGS args;
-       UINT rc;
-
-       szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR));
-       while (rc = MsiGetPropertyW(hInstall, L"CustomActionData", szValueBuf, &cbValueBuf)) {
-               free (szValueBuf);
-               if (rc == ERROR_MORE_DATA) {
-                       cbValueBuf++;
-                       szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR));
-               } else return ERROR_INSTALL_FAILURE;
-       }
-
-       if (!process_args(szValueBuf, args)) return ERROR_INSTALL_FAILURE;
-               
-       rc = doLoopBack (args.lpIPAddr, args.lpSubnetMask);
-
-       if (rc == 1) return ERROR_INSTALL_FAILURE;
-
-       if (rc == 2) {
-               MsiDoActionW (hInstall, L"ScheduleReboot");
-       }
-
-       return ERROR_SUCCESS;
-}
diff --git a/src/WINNT/install/NSIS/loopback_install.def b/src/WINNT/install/NSIS/loopback_install.def
deleted file mode 100644 (file)
index defe319..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-LIBRARY     LOOPBACK_INSTALL
-
-DESCRIPTION "Microsoft Loopback Adapter Installer for OpenAFS"
-
-EXPORTS
-    doLoopBackEntryW
-    disableLoopBackEntryW
-    loopback_isInstalled
-
-    
diff --git a/src/WINNT/install/loopback/NTMakefile b/src/WINNT/install/loopback/NTMakefile
new file mode 100644 (file)
index 0000000..5870521
--- /dev/null
@@ -0,0 +1,58 @@
+# rcsid : $Id$
+
+RELDIR=WINNT\install\loopback
+!INCLUDE ..\..\..\config\NTMakefile.$(SYS_NAME)
+!INCLUDE ..\..\..\config\NTMakefile.version
+
+MEDIABINDIR = $(DESTDIR)\WinInstall\Config
+
+EXEFILE = $(MEDIABINDIR)\instloop.exe
+
+DLLFILE = $(MEDIABINDIR)\afsloopback.dll
+
+DLLEXPORTS=\
+       -EXPORT:UnInstallLoopBack \
+       -EXPORT:IsLoopbackInstalled \
+       -EXPORT:InstallLoopBack \
+       -EXPORT:doLoopBackEntryW \
+       -EXPORT:uninstallLoopBackEntryW \
+       -EXPORT:installLoopbackMSI
+
+DLLLIBFILES=\
+       setupapi.lib msi.lib uuid.lib Shell32.lib ole32.lib advapi32.lib wbemuuid.lib
+
+LINK=link
+
+# afsloopback.dll
+
+DLLSOURCEFILES = loopbackutils.cpp renameconnection.cpp wmi.cpp
+DLLOBJFILES =  $(OUT)\loopbackutils.obj $(OUT)\renameconnection.obj $(OUT)\wmi.obj
+
+$(OUT)\loopbackutils.obj: loopbackutils.cpp
+       $(CPP2OBJ) -c -DUNICODE -D_UNICODE /Fo$@ $**
+
+$(OUT)\renameconnection.obj: renameconnection.cpp
+       $(CPP2OBJ) -c -DUNICODE -D_UNICODE /Fo$@ $**
+
+$(OUT)\wmi.obj: wmi.cpp
+       $(CPP2OBJ)  -I$(NTDDKDIR) -c -DUNICODE -D_UNICODE /Fo$@ $**
+
+$(DLLFILE): $(DLLOBJFILES)
+       $(LINK) -DLL $(DLLEXPORTS) -OUT:$@ $(DLLOBJFILES) $(DLLLIBFILES)
+
+# instloop.exe
+
+EXESOURCEFILES = instloop.c
+EXEOBJFILES = $(OUT)\instloop.obj
+EXELIBFILES = $(MEDIABINDIR)\afsloopback.lib
+
+$(OUT)\instloop.obj: instloop.c
+       $(C2OBJ) -c -DUNICODE -D_UNICODE /Fo$@ $**
+
+$(EXEFILE): $(EXEOBJFILES) $(EXELIBFILES)
+       $(LINK) /OUT:$@ $(EXEOBJFILES) $(EXELIBFILES)
+
+
+install:  $(DLLFILE) $(EXEFILE)
+
+clean  ::
diff --git a/src/WINNT/install/loopback/instloop.c b/src/WINNT/install/loopback/instloop.c
new file mode 100644 (file)
index 0000000..bb7427a
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+
+Copyright 2004 by the Massachusetts Institute of Technology
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the Massachusetts
+Institute of Technology (M.I.T.) not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+
+#include <windows.h>
+#include <stdio.h>
+#define INITGUID
+#include <guiddef.h>
+#include <devguid.h>
+#include <setupapi.h>
+#include <tchar.h>
+#include "loopbackutils.h"
+
+#undef REDIRECT_STDOUT
+
+static void
+ShowUsage(void)
+{
+    printf("instloop [-i [name [ip mask]] | -u]\n\n");
+    printf("    -i  install the %s\n", DRIVER_DESC);
+    _tprintf(_T("        (if unspecified, uses name %s,\n"), DEFAULT_NAME);
+    _tprintf(_T("         ip %s, and mask %s)\n"), DEFAULT_IP, DEFAULT_MASK);    
+    printf("    -u  uninstall the %s\n", DRIVER_DESC);
+}
+
+static void
+DisplayStartup(BOOL bInstall)
+{
+    printf("%snstalling the %s\n"
+           " (Note: This may take up to a minute or two...)\n",
+           bInstall ? "I" : "Un",
+           DRIVER_DESC);
+    
+}
+
+static void
+DisplayResult(BOOL bInstall, DWORD rc)
+{
+    if (rc)
+    {
+        printf("Could not %sinstall the %s\n", bInstall ? "" : "un",
+               DRIVER_DESC);
+        SLEEP;
+        PAUSE;
+    }
+}
+
+
+int _tmain(int argc, TCHAR *argv[])
+{
+    DWORD rc = 0;
+#ifdef REDIRECT_STDOUT
+    FILE *fh = NULL;
+#endif
+
+    PAUSE;
+
+#ifdef REDIRECT_STDOUT
+    fh = freopen("instlog.txt","a+", stdout);
+#endif
+
+    if (argc > 1)
+    {
+        if (_tcsicmp(argv[1], _T("-i")) == 0)
+        {
+            TCHAR* name = DEFAULT_NAME;
+            TCHAR* ip = DEFAULT_IP;
+            TCHAR* mask = DEFAULT_MASK;
+
+            if (argc > 2)
+            {
+                name = argv[2];
+                if (argc > 3)
+                {
+                    if (argc < 5)
+                    {
+                        ShowUsage();
+#ifdef REDIRECT_STDOUT
+                        fflush(fh); fclose(fh);
+#endif
+                        return 1;
+                    }
+                    else
+                    {
+                        ip = argv[3];
+                        mask = argv[4];
+                    }
+                }
+            }
+            DisplayStartup(TRUE);
+                       if(IsLoopbackInstalled()) {
+                               printf("Loopback already installed\n");
+                               rc = 0; /* don't signal an error. */
+                       } else {
+                   rc = InstallLoopBack(name, ip, mask);
+                       }
+            DisplayResult(TRUE, rc);
+#ifdef REDIRECT_STDOUT
+            fflush(fh); fclose(fh);
+#endif
+            return rc;
+        }
+        else if (_tcsicmp(argv[1], _T("-u")) == 0)
+        {
+            DisplayStartup(FALSE);
+            rc = UnInstallLoopBack();
+            DisplayResult(FALSE, rc);
+#ifdef REDIRECT_STDOUT
+            fflush(fh); fclose(fh);
+#endif
+            return rc;
+        }
+        ShowUsage();
+#ifdef REDIRECT_STDOUT
+        fflush(fh); fclose(fh);
+#endif
+        return 1;
+    }
+    ShowUsage();
+#ifdef REDIRECT_STDOUT
+    fflush(fh); fclose(fh);
+#endif
+    return 0;
+}
+
diff --git a/src/WINNT/install/loopback/loopbackutils.cpp b/src/WINNT/install/loopback/loopbackutils.cpp
new file mode 100644 (file)
index 0000000..e460af3
--- /dev/null
@@ -0,0 +1,629 @@
+/*
+   Copyright 2004 by the Massachusetts Institute of Technology              
+                                                                            
+   All rights reserved.                                                     
+                                                                            
+   Permission to use, copy, modify, and distribute this software and its    
+   documentation for any purpose and without fee is hereby granted,         
+   provided that the above copyright notice appear in all copies and that   
+   both that copyright notice and this permission notice appear in          
+   supporting documentation, and that the name of the Massachusetts         
+   Institute of Technology (M.I.T.) not be used in advertising or publicity 
+   pertaining to distribution of the software without specific, written     
+   prior permission.                                                        
+                                                                            
+   M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING  
+   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 
+   M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR   
+   ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,      
+   WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,   
+   ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS      
+   SOFTWARE.                                                                
+*/
+
+#define _WIN32_DCOM
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct Args {
+       bool bQuiet;
+       LPWSTR lpIPAddr;
+       LPWSTR lpSubnetMask;
+    LPWSTR lpConnectionName;
+       Args () : bQuiet (0), lpIPAddr (0), lpSubnetMask (0), lpConnectionName (0) { }
+       ~Args () {
+               if (lpIPAddr) free (lpIPAddr);
+               if (lpSubnetMask) free (lpSubnetMask);
+        if (lpConnectionName) free (lpConnectionName);
+       }
+};
+
+#include <shellapi.h>
+#define INITGUID
+#include <guiddef.h>
+#include <devguid.h>
+#include <objbase.h>
+#include <setupapi.h>
+#include <tchar.h>
+#include <Msi.h>
+#include <Msiquery.h>
+#include "loopbackutils.h"
+
+extern "C" DWORD UnInstallLoopBack(void)
+{
+    BOOL ok;
+    DWORD ret = 0;
+    GUID netGuid;
+    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
+    SP_DEVINFO_DATA DeviceInfoData;
+    TCHAR* deviceDesc;
+    DWORD index = 0;
+    BOOL found = FALSE;
+    DWORD size = 0;
+
+    // initialize the structure size
+    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+
+    // copy the net class GUID
+    memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
+
+    // return a device info set contains all installed devices of the Net class
+    hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT);
+
+    if (hDeviceInfo == INVALID_HANDLE_VALUE)
+        return GetLastError();
+
+    deviceDesc = (TCHAR *)malloc(MAX_PATH*sizeof(TCHAR));
+    // enumerate the driver info list
+    while (SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData))
+    {
+        // try to get the DeviceDesc registry property
+        ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData,
+                                              SPDRP_DEVICEDESC,
+                                              NULL, (PBYTE)deviceDesc,
+                                              MAX_PATH * sizeof(TCHAR), &size);
+        if (!ok)
+        {
+            ret = GetLastError();
+            if (ret != ERROR_INSUFFICIENT_BUFFER)
+                break;
+            // if the buffer is too small, reallocate
+            free(deviceDesc);
+            deviceDesc = (TCHAR *)malloc(size);
+            ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
+                                                  &DeviceInfoData,
+                                                  SPDRP_DEVICEDESC,
+                                                  NULL, (PBYTE)deviceDesc,
+                                                  size, NULL);
+            if (!ok)
+                break;
+        }
+
+        // case insensitive comparison
+        _tcslwr(deviceDesc);
+        if( _tcsstr(deviceDesc, DRIVER))
+        {
+            found = TRUE;
+            break;
+        }
+
+        index++;
+    }
+
+    free(deviceDesc);
+    
+    if (found == FALSE)
+    {
+        ret = GetLastError();
+        printf("The %s does not seem to be installed\n", DRIVER_DESC);
+        goto cleanup;
+    }
+
+    ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+    ok = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+cleanup:
+    // clean up the device info set
+    if (hDeviceInfo != INVALID_HANDLE_VALUE)
+        SetupDiDestroyDeviceInfoList(hDeviceInfo);
+
+    return ret;
+}
+
+BOOL IsLoopbackInstalled(void)
+{
+    TCHAR * hwid = _T("*MSLOOP");
+    HDEVINFO DeviceInfoSet;
+    SP_DEVINFO_DATA DeviceInfoData;
+    DWORD i,err;
+    BOOL found;
+    
+    //
+    // Create a Device Information Set with all present devices.
+    //
+    DeviceInfoSet = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system
+    if (DeviceInfoSet == INVALID_HANDLE_VALUE)
+    {
+        return FALSE; // nothing installed?
+    }
+    
+    //
+    //  Enumerate through all Devices.
+    //
+    found = FALSE;
+    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+    for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++)
+    {
+        DWORD DataT;
+        TCHAR *p, *buffer = NULL;
+        DWORD buffersize = 0;
+        
+        //
+        // We won't know the size of the HardwareID buffer until we call
+        // this function. So call it with a null to begin with, and then 
+        // use the required buffer size to Alloc the nessicary space.
+        // Keep calling we have success or an unknown failure.
+        //
+        while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,&DataT,(PBYTE)buffer,buffersize,&buffersize))
+        {
+            if (GetLastError() == ERROR_INVALID_DATA)
+            {
+                // May be a Legacy Device with no hwid. Continue.
+                break;
+            }
+            else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                // We need to change the buffer size.
+                if (buffer) 
+                    LocalFree(buffer);
+                buffer = (TCHAR *)LocalAlloc(LPTR,buffersize);
+            }
+            else
+            {
+                goto cleanup_DeviceInfo;
+            }            
+        }
+        
+        if (GetLastError() == ERROR_INVALID_DATA) 
+            continue;
+        
+        // Compare each entry in the buffer multi-sz list with our hwid.
+        for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1)
+        {
+            if (!_tcsicmp(hwid,p))
+            {
+                found = TRUE;
+                break;
+            }
+        }
+        
+        if (buffer) LocalFree(buffer);
+        if (found) break;
+    }
+    
+    //  Cleanup.
+cleanup_DeviceInfo:
+    err = GetLastError();
+    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
+    SetLastError(err);
+    
+    return found;
+}
+
+
+extern "C" DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask)
+{
+    BOOL ok;
+    DWORD ret = 0;
+    GUID netGuid;
+    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
+    SP_DEVINFO_DATA DeviceInfoData;
+    SP_DRVINFO_DATA DriverInfoData;
+    SP_DEVINSTALL_PARAMS  DeviceInstallParams;
+    TCHAR className[MAX_PATH];
+    TCHAR temp[MAX_PATH];
+    DWORD index = 0;
+    BOOL found = FALSE;
+    BOOL registered = FALSE;
+    BOOL destroyList = FALSE;
+
+    HKEY hkey = NULL;
+    DWORD cbSize;
+    DWORD dwValueType;
+    TCHAR pCfgGuidString[40];
+
+    // initialize the structure size
+    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+    DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
+
+    // copy the net class GUID
+    memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
+
+    // create an empty device info set associated with the net class GUID
+    hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL);
+    if (hDeviceInfo == INVALID_HANDLE_VALUE)
+        return GetLastError();
+
+    // get the class name from GUID
+    ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    // create a device info element and add the new device instance
+    // key to registry
+    ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL,
+                                 DICD_GENERATE_ID, &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    // select the newly created device info to be the currently
+    // selected member
+    ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    // build a list of class drivers
+    ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData,
+                                    SPDIT_CLASSDRIVER);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    destroyList = TRUE;
+
+    // enumerate the driver info list
+    while (SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData,
+                                 SPDIT_CLASSDRIVER, index, &DriverInfoData))
+    {
+        // if the manufacture is microsoft
+        if (_tcsicmp(DriverInfoData.MfgName, MANUFACTURE) == 0)
+        {
+            // case insensitive search for loopback
+            _tcscpy(temp, DriverInfoData.Description);
+            _tcslwr(temp);
+            if( _tcsstr(temp, DRIVER))
+            {
+                found = TRUE;
+                break;
+            }
+        }
+        index++;
+    }
+
+    if (!found)
+    {
+        ret = GetLastError();
+        printf("Could not find the %s driver to install\n", DRIVER_DESC);
+        goto cleanup;
+    }
+
+    // set the loopback driver to be the currently selected
+    ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData,
+                                  &DriverInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    // register the phantom device to repare for install
+    ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo,
+                                   &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    // registered, but remove if errors occur in the following code
+    registered = TRUE;
+
+    // ask the installer if we can install the device
+    ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo,
+                                   &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        if (ret != ERROR_DI_DO_DEFAULT)
+        {
+            goto cleanup;
+        }
+        else
+            ret = 0;
+    }
+
+    // install the files first
+    ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo,
+                                   &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    // get the device install parameters and disable filecopy
+    DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+    ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
+                                       &DeviceInstallParams);
+    if (ok)
+    {
+        DeviceInstallParams.Flags |= DI_NOFILECOPY;
+        ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
+                                           &DeviceInstallParams);
+        if (!ok)
+        {
+            ret = GetLastError();
+            goto cleanup;
+        }
+    }
+
+    //
+    // Register any device-specific co-installers for this device,
+    //
+
+    ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS,
+                                   hDeviceInfo,
+                                   &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    //
+    // install any  installer-specified interfaces.
+    // and then do the real install
+    //
+    ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES,
+                                   hDeviceInfo,
+                                   &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+    PAUSE;
+    ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE,
+                                   hDeviceInfo,
+                                   &DeviceInfoData);
+    if (!ok)
+    {
+        ret = GetLastError();
+        PAUSE;
+        goto cleanup;
+    }
+
+    /* Skip to the end if we aren't setting the name */
+    if (!pConnectionName) goto cleanup;
+
+    // Figure out NetCfgInstanceId
+    hkey = SetupDiOpenDevRegKey(hDeviceInfo,
+                                &DeviceInfoData,
+                                DICS_FLAG_GLOBAL,
+                                0,
+                                DIREG_DRV,
+                                KEY_READ);
+    if (hkey == INVALID_HANDLE_VALUE)
+    {
+        ret = GetLastError();
+        goto cleanup;
+    }
+
+    cbSize = sizeof(pCfgGuidString);
+    ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL,
+                          &dwValueType, (LPBYTE)pCfgGuidString, &cbSize);
+    RegCloseKey(hkey);
+
+    ret = RenameConnection(pCfgGuidString, pConnectionName);
+    if (ret)
+    {
+        printf("Could not set the connection name to \"%S\"\n",
+               pConnectionName);
+        goto cleanup;
+    }
+
+    if (!ip) goto cleanup;
+    ret = SetIpAddress(pCfgGuidString, ip, mask);
+    if (ret)
+    {
+        printf("Could not set the ip address and network mask\n");
+        goto cleanup;
+    }
+    ret = LoopbackBindings(pCfgGuidString);
+    if (ret)
+    {
+        printf("Could not properly set the bindings\n");
+        goto cleanup;
+    }
+    ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE );
+    if (ret)
+    {
+        printf("Could not update hosts file\n");
+        goto cleanup;
+    }
+    ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE );
+    if (ret)
+    {
+        printf("Could not update lmhosts file\n");
+        goto cleanup;
+    }
+
+
+cleanup:
+    // an error has occured, but the device is registered, we must remove it
+    if (ret != 0 && registered)
+        SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
+
+    found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData);
+
+    // destroy the driver info list
+    if (destroyList)
+        SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData,
+                                     SPDIT_CLASSDRIVER);
+    // clean up the device info set
+    if (hDeviceInfo != INVALID_HANDLE_VALUE)
+        SetupDiDestroyDeviceInfoList(hDeviceInfo);
+
+    return ret;
+};
+
+/* The following functions provide the RunDll32 interface 
+ *    RunDll32 loopback_install.dll doLoopBackEntry [Interface Name] [IP address] [Subnet Mask]
+ */
+
+static void wcsMallocAndCpy (LPWSTR * dst, const LPWSTR src) {
+       *dst = (LPWSTR) malloc ((wcslen (src) + 1) * sizeof (WCHAR));
+       wcscpy (*dst, src);
+}
+
+static void display_usage()
+{
+    MessageBoxW( NULL, 
+                 L"Installation utility for the MS Loopback Adapter\r\n\r\n"
+                 L"Usage:\r\n"
+                 L"RunDll32 loopback_install.dll doLoopBackEntry [q|quiet] [Connection Name] [IP address] [Submask]\r\n",
+                 L"loopback_install", MB_ICONINFORMATION | MB_OK );
+}
+
+static int process_args (LPWSTR lpCmdLine, Args & args) {
+       int i, iNumArgs;
+       LPWSTR * argvW;
+
+       argvW = CommandLineToArgvW (lpCmdLine, &iNumArgs);
+       for (i = 0; i < iNumArgs; i++)
+       {
+               if (wcsstr (argvW[i], L"help")
+                       || !_wcsicmp (argvW[i], L"?")
+                       || (wcslen(argvW[i]) == 2 && argvW[i][1] == L'?'))
+               {
+                       display_usage();
+                       GlobalFree (argvW);
+                       return 0;
+               }
+
+               if (!_wcsicmp (argvW[i], L"q") || !_wcsicmp (argvW[i], L"quiet")) {
+                       args.bQuiet = true;
+                       continue;
+               }
+
+               if (!args.lpConnectionName) {
+                       wcsMallocAndCpy (&args.lpConnectionName, argvW[i]);
+                       continue;
+               }
+
+               if (!args.lpIPAddr) {
+                       wcsMallocAndCpy (&args.lpIPAddr, argvW[i]);
+                       continue;
+               }
+
+               if (!args.lpSubnetMask) {
+                       wcsMallocAndCpy (&args.lpSubnetMask, argvW[i]);
+                       continue;
+               }
+
+               display_usage();
+               GlobalFree (argvW);
+               return 0;
+       }
+
+       if (!args.lpConnectionName)
+               wcsMallocAndCpy (&args.lpConnectionName, DEFAULT_NAME);
+       if (!args.lpIPAddr)
+               wcsMallocAndCpy (&args.lpIPAddr, DEFAULT_IP);
+       if (!args.lpSubnetMask)
+               wcsMallocAndCpy (&args.lpSubnetMask, DEFAULT_MASK);
+
+       GlobalFree (argvW);
+       return 1;
+}
+
+void CALLBACK doLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdShow)
+{
+       Args args;
+
+       if (!process_args(lpCmdLine, args)) 
+        return;
+
+       InstallLoopBack(args.lpConnectionName, args.lpIPAddr, args.lpSubnetMask);
+}
+
+void CALLBACK uninstallLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdSHow)
+{
+    Args args;
+
+    // initialize COM
+       // This and CoInitializeSecurity fail when running under the MSI
+       // engine, but there seems to be no ill effect (the security is now
+       // set on the specific object via CoSetProxyBlanket in loopback_configure)
+    if(CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ))
+    {
+               //Don't fail (MSI install will have already initialized COM)
+        //EasyErrorBox(0, L"Failed to initialize COM.");
+        //return 1;
+    }
+
+       // Initialize COM security (otherwise we'll get permission denied when we try to use WMI or NetCfg)
+    CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
+
+    UnInstallLoopBack();
+
+       CoUninitialize();
+}
+
+/* And an MSI installer interface */
+
+UINT __stdcall installLoopbackMSI (MSIHANDLE hInstall)
+{
+       LPWSTR szValueBuf;
+       DWORD cbValueBuf = 256;
+       Args args;
+       UINT rc;
+
+       szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR));
+       while (rc = MsiGetPropertyW(hInstall, L"CustomActionData", szValueBuf, &cbValueBuf)) {
+               free (szValueBuf);
+               if (rc == ERROR_MORE_DATA) {
+                       cbValueBuf++;
+                       szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR));
+               } 
+        else 
+            return ERROR_INSTALL_FAILURE;
+       }
+
+       if (!process_args(szValueBuf, args)) 
+        return ERROR_INSTALL_FAILURE;
+               
+       rc = InstallLoopBack (args.lpConnectionName, args.lpIPAddr, args.lpSubnetMask);
+
+       if (rc == 1) 
+        return ERROR_INSTALL_FAILURE;
+
+       if (rc == 2) {
+               MsiDoActionW (hInstall, L"ScheduleReboot");
+       }
+
+       return ERROR_SUCCESS;
+}
+
diff --git a/src/WINNT/install/loopback/loopbackutils.h b/src/WINNT/install/loopback/loopbackutils.h
new file mode 100644 (file)
index 0000000..1a763d1
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+
+Copyright 2004 by the Massachusetts Institute of Technology
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the Massachusetts
+Institute of Technology (M.I.T.) not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask);
+BOOL IsLoopbackInstalled(void);
+DWORD UnInstallLoopBack(void);
+int RenameConnection(PCWSTR GuidString, PCWSTR pszNewName);
+DWORD SetIpAddress(LPCWSTR guid, LPCWSTR ip, LPCWSTR mask);
+HRESULT LoopbackBindings (LPCWSTR loopback_guid);
+BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre );
+#ifdef  __cplusplus
+}
+#endif
+
+#define DRIVER_DESC "Microsoft Loopback Adapter"
+#define DRIVER _T("loopback")
+#define MANUFACTURE _T("microsoft")
+#define DEFAULT_NAME _T("AFS")
+#define DEFAULT_IP _T("10.254.254.253")
+#define DEFAULT_MASK _T("255.255.255.252")
+
+#ifdef USE_PAUSE
+#define PAUSE                                          \
+    do {                                               \
+        char c;                                        \
+        printf("PAUSED - PRESS ENTER TO CONTINUE\n");  \
+        scanf("%c", &c);                               \
+    } while(0)
+#else
+#define PAUSE
+#endif
+
+/*#define USE_SLEEP*/
+
+#ifdef USE_SLEEP
+#define SLEEP Sleep(10*1000)
+#else
+#define SLEEP
+#endif
+
diff --git a/src/WINNT/install/loopback/renameconnection.cpp b/src/WINNT/install/loopback/renameconnection.cpp
new file mode 100644 (file)
index 0000000..4046871
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+
+Copyright 2004 by the Massachusetts Institute of Technology
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the Massachusetts
+Institute of Technology (M.I.T.) not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+
+#include <afx.h>
+#include <windows.h>
+#include <shellapi.h>
+#include <objbase.h>
+#include <shlobj.h>
+#include <wtypes.h>
+
+#define NETSHELL_LIBRARY _T("netshell.dll")
+
+// Use the IShellFolder API to rename the connection.
+static HRESULT rename_shellfolder(PCWSTR wGuid, PCWSTR wNewName)
+{
+    // This is the GUID for the network connections folder. It is constant.
+    // {7007ACC7-3202-11D1-AAD2-00805FC1270E}
+    const GUID CLSID_NetworkConnections = {
+        0x7007ACC7, 0x3202, 0x11D1, {
+           0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
+       }
+    };
+    LPITEMIDLIST pidl;
+    IShellFolder *pShellFolder;
+    IMalloc *pShellMalloc;
+
+    // Build the display name in the form "::{GUID}".
+    if (wcslen(wGuid) >= MAX_PATH)
+        return E_INVALIDARG;
+    WCHAR szAdapterGuid[MAX_PATH + 2];
+    swprintf(szAdapterGuid, L"::%ls", wGuid);
+
+    // Initialize COM.
+    CoInitialize(NULL);
+
+    // Get the shell allocator.
+    HRESULT hr = SHGetMalloc(&pShellMalloc);
+    if (SUCCEEDED(hr))
+    {
+        // Create an instance of the network connections folder.
+        hr = CoCreateInstance(CLSID_NetworkConnections, NULL,
+                             CLSCTX_INPROC_SERVER, IID_IShellFolder,
+                             reinterpret_cast<LPVOID *>(&pShellFolder));
+    }
+    // Parse the display name.
+    if (SUCCEEDED(hr))
+    {
+        hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL,
+                                           &pidl, NULL);
+    }
+    if (SUCCEEDED(hr))
+    {
+       hr = pShellFolder->SetNameOf(NULL, pidl, wNewName, SHGDN_NORMAL,
+                                    &pidl);
+       pShellMalloc->Free(pidl);
+    }
+    CoUninitialize();
+    return hr;
+}
+
+extern "C" int RenameConnection(PCWSTR GuidString, PCWSTR NewName)
+{
+    typedef HRESULT (WINAPI *lpHrRenameConnection)(const GUID *, PCWSTR);
+    lpHrRenameConnection RenameConnectionFunc = NULL;
+    HRESULT status;
+
+    // First try the IShellFolder interface, which was unimplemented
+    // for the network connections folder before XP.
+    status = rename_shellfolder(GuidString, NewName);
+    if (status == E_NOTIMPL)
+    {
+       // The IShellFolder interface is not implemented on this platform.
+        // Try the (undocumented) HrRenameConnection API in the netshell
+        // library.
+       CLSID clsid;
+        HINSTANCE hNetShell;
+       status = CLSIDFromString((LPOLESTR) GuidString, &clsid);
+       if (FAILED(status))
+           return -1;
+       hNetShell = LoadLibrary(NETSHELL_LIBRARY);
+       if (hNetShell == NULL)
+           return -1;
+       RenameConnectionFunc =
+         (lpHrRenameConnection) GetProcAddress(hNetShell,
+                                               "HrRenameConnection");
+       if (RenameConnectionFunc == NULL)
+       {
+           FreeLibrary(hNetShell);
+           return -1;
+       }
+       status = RenameConnectionFunc(&clsid, NewName);
+       FreeLibrary(hNetShell);
+    }
+    if (FAILED(status))
+       return -1;
+    return 0;
+}
diff --git a/src/WINNT/install/loopback/wmi.cpp b/src/WINNT/install/loopback/wmi.cpp
new file mode 100644 (file)
index 0000000..9848155
--- /dev/null
@@ -0,0 +1,805 @@
+/*
+
+Copyright 2004 by the Massachusetts Institute of Technology
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the Massachusetts
+Institute of Technology (M.I.T.) not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+
+//**************************************************************************
+//
+// Description:
+//
+//      Call EnableStatic method of Win32_NetworkAdapterConfiguration
+//      for some network adapter GUID.
+//
+// Note:
+//
+//     The EnableStatic method is notsupported on Win9x platforms.
+//
+//**************************************************************************
+
+#define _WIN32_DCOM
+#include <windows.h>
+#include <comdef.h>
+#include <wbemidl.h>
+#include <tchar.h>
+
+#include <devguid.h>
+
+/* These two are from the Windows DDK */
+#include <netcfgx.h>
+#include <netcfgn.h>
+
+#include <shlobj.h>
+//#include <objbase.h>
+
+//#ifndef TEST
+//inline void printf(char*, ...) {}
+//#else
+#include <stdio.h>
+//#endif
+
+#define CLEANUP_ON_FAILURE(hr) \
+    do { if (!SUCCEEDED(hr)) goto cleanup; } while (0)
+
+#define CLEANUP_ON_AND_SET(check, var, value) \
+    do { if (check) { (var) = (value); goto cleanup; } } while (0)
+
+#define ETCDIR "\\drivers\\etc"
+
+#define EACCES (13)
+#define ENOENT (2)
+
+DWORD AdjustMaxLana(DWORD dwMaxLana);
+
+typedef
+HRESULT
+(*FindNetworkAdapterConfigurationInstance_t)(
+    IN  PVOID pContext,
+    IN  IWbemServices *pSvc,
+    OUT BSTR* pPath
+    );
+
+HRESULT
+FindNetworkAdapterConfigurationInstanceByGUID(
+    IN  PVOID pContext,
+    IN  IWbemServices *pSvc,
+    OUT BSTR* pPath
+    )
+{
+    HRESULT hr = 0;
+    BOOL bFound = FALSE;
+    BSTR Language = 0;
+    BSTR Query = 0;
+    IEnumWbemClassObject* pEnum = 0;
+    IWbemClassObject* pObj = 0;
+    VARIANT Value;
+    VariantInit(&Value);
+    LPCWSTR adapter_guid = (LPCWSTR)pContext;
+
+    // Check arguments
+    if (!pPath || !adapter_guid || *pPath)
+        return E_INVALIDARG;
+
+    *pPath = 0;
+
+    // Query for all network adapters
+    Language = SysAllocString(L"WQL");
+    Query = SysAllocString(L"select * from Win32_NetworkAdapterConfiguration");
+
+    // Issue the query.
+    hr = pSvc->ExecQuery(Language,
+                         Query,
+                         WBEM_FLAG_FORWARD_ONLY,         // Flags
+                         0,                              // Context
+                         &pEnum);
+    if (!SUCCEEDED(hr))
+    {
+        printf("ExecQuery() error (0x%08X)\n", hr);
+        goto cleanup;
+    }
+
+    // Retrieve the objects in the result set.
+    while (!bFound)
+    {
+        ULONG uReturned = 0;
+
+        hr = pEnum->Next(0,                  // Time out
+                         1,                  // One object
+                         &pObj,
+                         &uReturned);
+        CLEANUP_ON_FAILURE(hr);
+
+        if (uReturned == 0)
+            break;
+
+        // Use the object.
+        hr  = pObj->Get(L"SettingID", // property name
+                        0L,
+                        &Value,       // output to this variant
+                        NULL,
+                        NULL);
+        CLEANUP_ON_FAILURE(hr);
+
+        bFound = !wcscmp(adapter_guid, V_BSTR(&Value));
+        
+        if (bFound)
+        {
+            printf("Found adapter: %S\n", V_BSTR(&Value));
+            VariantClear(&Value);
+            hr = pObj->Get(L"__RELPATH", // property name
+                           0L,
+                           &Value,       // output to this variant
+                           NULL,
+                           NULL);
+            CLEANUP_ON_FAILURE(hr);
+
+            *pPath = SysAllocString(V_BSTR(&Value));
+            
+        }
+        
+        VariantClear(&Value);
+        
+        // Release it.
+        // ===========
+        pObj->Release();    // Release objects not owned.
+        pObj = 0;
+    }
+
+
+    // All done.
+ cleanup:
+    SysFreeString(Query);
+    SysFreeString(Language);
+    VariantClear(&Value);
+    if (pEnum)
+        pEnum->Release();
+    if (pObj)
+        pObj->Release();
+
+    return *pPath ? 0 : ( SUCCEEDED(hr) ? WBEM_E_NOT_FOUND : hr );
+}
+
+HRESULT
+SetupStringAsSafeArray(LPCWSTR s, VARIANT* v)
+{
+    HRESULT hr = 0;
+    BSTR b = 0;
+    SAFEARRAY* array = 0;
+    long index[] = {0};
+
+    if (V_VT(v) != VT_EMPTY)
+        return E_INVALIDARG;
+
+    b = SysAllocString(s);
+    CLEANUP_ON_AND_SET(!b, hr, E_OUTOFMEMORY);
+
+    array = SafeArrayCreateVector(VT_BSTR, 0, 1);
+    CLEANUP_ON_AND_SET(!array, hr, E_OUTOFMEMORY);
+
+    hr = SafeArrayPutElement(array, index, b);
+    CLEANUP_ON_FAILURE(hr);
+
+    V_VT(v) = VT_ARRAY|VT_BSTR;
+    V_ARRAY(v) = array;
+
+ cleanup:
+    if (b)
+        SysFreeString(b);
+    if (!SUCCEEDED(hr))
+    {
+        if (array)
+            SafeArrayDestroy(array);
+    }
+    return hr;
+}
+
+
+HRESULT
+WMIEnableStatic(
+    FindNetworkAdapterConfigurationInstance_t pFindInstance,
+    PVOID pContext,
+    LPCWSTR ip,
+    LPCWSTR mask
+    )
+{
+    HRESULT hr = 0;
+
+    IWbemLocator* pLocator = 0;
+    IWbemServices* pNamespace = 0;
+    IWbemClassObject* pClass = 0;
+    IWbemClassObject* pOutInst = 0;
+    IWbemClassObject* pInClass = 0;
+    IWbemClassObject* pInInst = 0;
+
+    BSTR NamespacePath = 0;
+    BSTR ClassPath = 0;
+    BSTR InstancePath = 0;
+    BSTR MethodName = 0; // needs to be BSTR for ExecMethod()
+
+    VARIANT v_ip_list;
+    VariantInit(&v_ip_list);
+
+    VARIANT v_mask_list;
+    VariantInit(&v_mask_list);
+
+    VARIANT v_ret_value;
+    VariantInit(&v_ret_value);
+
+    int count;
+
+    // end of declarations & NULL initialization
+
+    NamespacePath = SysAllocString(L"root\\cimv2");
+    CLEANUP_ON_AND_SET(!NamespacePath, hr, E_OUTOFMEMORY);
+
+    ClassPath = SysAllocString(L"Win32_NetWorkAdapterConfiguration");
+    CLEANUP_ON_AND_SET(!ClassPath, hr, E_OUTOFMEMORY);
+
+    MethodName = SysAllocString(L"EnableStatic");
+    CLEANUP_ON_AND_SET(!MethodName, hr, E_OUTOFMEMORY);
+
+    // Initialize COM and connect up to CIMOM
+
+    hr = CoInitializeEx(0, COINIT_MULTITHREADED);
+    CLEANUP_ON_FAILURE(hr);
+
+    hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
+                              RPC_C_AUTHN_LEVEL_CONNECT,
+                              RPC_C_IMP_LEVEL_IMPERSONATE,
+                              NULL, EOAC_NONE, 0);
+    CLEANUP_ON_FAILURE(hr);
+
+    hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
+                          IID_IWbemLocator, (LPVOID *) &pLocator);
+    CLEANUP_ON_FAILURE(hr);
+
+    hr = pLocator->ConnectServer(NamespacePath, NULL, NULL, NULL, 0,
+                                 NULL, NULL, &pNamespace);
+    CLEANUP_ON_FAILURE(hr);
+
+    printf("Connected to WMI\n");
+
+    // Set the proxy so that impersonation of the client occurs.
+    hr = CoSetProxyBlanket(pNamespace,
+                           RPC_C_AUTHN_WINNT,
+                           RPC_C_AUTHZ_NONE,
+                           NULL,
+                           RPC_C_AUTHN_LEVEL_CALL,
+                           RPC_C_IMP_LEVEL_IMPERSONATE,
+                           NULL,
+                           EOAC_NONE);
+    CLEANUP_ON_FAILURE(hr);
+
+    // Get the class object
+    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
+    CLEANUP_ON_FAILURE(hr);
+
+    // Get the instance
+    hr = pFindInstance(pContext, pNamespace, &InstancePath);
+    CLEANUP_ON_FAILURE(hr);
+
+    printf("Found Adapter Instance: %S\n", InstancePath);
+
+#if 0
+    // Use the adapter instance index to set MAXLANA in the registry.
+    {
+        DWORD dwIndex;
+        if (swscanf(InstancePath, L"Win32_NetworkAdapterConfiguration.Index=%u", &dwIndex)==1)
+        {
+            DWORD ret = 0; 
+            printf("Setting MAXLANA to at least %u\n",dwIndex+1);
+            ret = AdjustMaxLana(dwIndex+1);
+            if (ret) printf("AdjustMaxLana returned the error code %u.\n",ret);
+        }
+    }
+#endif
+
+    // Get the input argument and set the property
+    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
+    CLEANUP_ON_FAILURE(hr);
+
+    hr = pInClass->SpawnInstance(0, &pInInst);
+    CLEANUP_ON_FAILURE(hr);
+
+    // Set up parameters
+    hr = SetupStringAsSafeArray(ip, &v_ip_list);
+    CLEANUP_ON_FAILURE(hr);
+
+    hr = pInInst->Put(L"IPAddress", 0, &v_ip_list, 0);
+    CLEANUP_ON_FAILURE(hr);
+
+    hr = SetupStringAsSafeArray(mask, &v_mask_list);
+    CLEANUP_ON_FAILURE(hr);
+
+    hr = pInInst->Put(L"SubNetMask", 0, &v_mask_list, 0);
+    CLEANUP_ON_FAILURE(hr);
+
+    // Sleep for a twenty seconds
+    printf("Calling ExecMethod in 20 seconds...\r");
+    Sleep(10000);
+    printf("Calling ExecMethod in 10 seconds...\r");
+    Sleep(5000);  
+    printf("Calling ExecMethod in  5 seconds...\r");
+    Sleep(2000);
+
+//    printf("Skipping ExecMethod\n");
+//    hr = 0;
+//    goto cleanup;
+
+    // Try up to five times, sleeping 3 seconds between tries
+    for (count=0; count<5; count++)
+    {
+        if (count>0) printf("Trying again in 3 seconds...\n");
+
+       Sleep(3000);
+  
+        printf("Calling ExecMethod NOW...          \n");     
+
+        // Call the method
+
+        hr = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL, pInInst,
+                                  &pOutInst, NULL);   
+
+        if (!SUCCEEDED(hr))
+        {
+           printf("ExecMethod failed (0x%08X)\n", hr);
+           continue;
+        }
+
+        // Get the EnableStatic method return value
+        hr = pOutInst->Get(L"ReturnValue", 0, &v_ret_value, 0, 0);
+
+        if (!SUCCEEDED(hr))
+        {
+          printf("WARNING: Could not determine return value for EnableStatic (0x%08X)\n", hr);
+          continue;
+        }
+
+        hr = V_I4(&v_ret_value);                
+
+
+        if(hr != 0)
+            printf("EnableStatic failed (0x%08X)\n", hr);
+        else
+        {
+            printf("EnableStatic succeeded\n");
+            break;
+        }
+
+    }
+
+
+
+ cleanup:
+    // Free up resources
+    VariantClear(&v_ret_value);
+    VariantClear(&v_ip_list);
+    VariantClear(&v_mask_list);
+
+    SysFreeString(NamespacePath);
+    SysFreeString(ClassPath);
+    SysFreeString(InstancePath);
+    SysFreeString(MethodName);
+
+    if (pClass) pClass->Release();
+    if (pInInst) pInInst->Release();
+    if (pInClass) pInClass->Release();
+    if (pOutInst) pOutInst->Release();
+    if (pLocator) pLocator->Release();
+    if (pNamespace) pNamespace->Release();
+
+    CoUninitialize();
+    return hr;
+}
+
+
+/**********************************************************
+* LoopbackBindings :  unbind all other 
+*       protocols except TCP/IP, netbios, netbt. 
+*/
+extern "C" HRESULT LoopbackBindings (LPCWSTR loopback_guid)
+{
+    HRESULT                    hr = 0;
+    INetCfg                    *pCfg = NULL;
+    INetCfgLock                *pLock = NULL;
+    INetCfgComponent *pAdapter = NULL;
+    IEnumNetCfgComponent *pEnumComponent = NULL;
+    BOOL                       bLockGranted = FALSE;
+    BOOL                       bInitialized = FALSE;
+    BOOL                       bConfigChanged = FALSE;
+    LPWSTR                     swName = NULL;
+    GUID            g;
+    wchar_t         device_guid[100];
+    DWORD                      lenDeviceId;    
+    
+    printf("\nRunning LoopbackBindings()...\n");
+    
+    hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ); 
+    CLEANUP_ON_FAILURE(hr);
+    
+    hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void**)&pCfg );
+    CLEANUP_ON_FAILURE(hr);
+    
+    hr = pCfg->QueryInterface( IID_INetCfgLock, (void**)&pLock );
+    CLEANUP_ON_FAILURE(hr);
+    
+    hr = pLock->AcquireWriteLock( 1000, L"AFS Configuration", NULL );
+    CLEANUP_ON_FAILURE(hr);
+    bLockGranted = TRUE;
+    
+    hr = pCfg->Initialize( NULL );
+    CLEANUP_ON_FAILURE(hr);
+    bInitialized = TRUE;
+    
+    hr = pCfg->EnumComponents( &GUID_DEVCLASS_NET, &pEnumComponent );
+    CLEANUP_ON_FAILURE(hr);
+    
+    
+    while( pEnumComponent->Next( 1, &pAdapter, NULL ) == S_OK )
+    {
+        pAdapter->GetDisplayName( &swName );
+        pAdapter->GetInstanceGuid( &g );
+        StringFromGUID2(g, device_guid, 99);
+        
+        if(!wcscmp( device_guid, loopback_guid )) // found loopback adapter
+        {
+            INetCfgComponentBindings *pBindings;
+            INetCfgBindingPath *pPath;
+            IEnumNetCfgBindingPath *pEnumPaths;
+            INetCfgComponent *upper;
+            
+            wprintf(L"LoopbackBindings found: %s\n", device_guid );
+            
+            hr = pAdapter->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings);
+            if(hr==S_OK)
+            {
+                hr = pBindings->EnumBindingPaths( EBP_ABOVE, &pEnumPaths );
+                if(hr==S_OK)
+                {
+                    while(pEnumPaths->Next( 1, &pPath, NULL ) == S_OK)
+                    {
+                        pPath->GetOwner( &upper );
+                        
+                        LPWSTR swId = NULL, swName = NULL;
+                        
+                        upper->GetDisplayName( &swName );
+                        upper->GetId( &swId );
+                        
+                        wprintf(L"Looking at %s (%s)... \n",swName, swId);
+                                                                        
+                        {
+                            wprintf(L"  Moving to the end of binding order...");
+                            INetCfgComponentBindings *pBindings2;
+                            hr = upper->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings2);
+                            if (hr==S_OK)
+                            {
+                                printf("...");
+                                hr = pBindings2->MoveAfter(pPath, NULL);                                
+                                pBindings2->Release();                               
+                                bConfigChanged=TRUE;
+                            }
+                            if (hr==S_OK) printf("success\n"); else printf("failed: 0x%0lx\n",hr);                                                        
+                                                                                                            
+                        }                        
+                        
+                        if ( !_wcsicmp(swId, L"ms_netbios")  || 
+                            !_wcsicmp(swId, L"ms_tcpip")    ||
+                            !_wcsicmp(swId, L"ms_netbt")      )
+                        {
+                            if (pPath->IsEnabled()!=S_OK)
+                            {
+                                wprintf(L"  Enabling %s: ",swName);
+                                hr = pPath->Enable(TRUE);
+                                if (hr==S_OK) printf("success\n"); else printf("failed: %ld\n",hr);
+                                bConfigChanged=TRUE;
+                            }
+                            
+                            
+                        }
+                        else //if (!_wcsicmp(swId, L"ms_server") || (!_wcsicmp(swId, L"ms_msclient")) 
+                        {
+                            if (pPath->IsEnabled()==S_OK)
+                            {
+                                wprintf(L"  Disabling %s: ",swName);
+                                hr = pPath->Enable(FALSE);
+                                if (hr==S_OK) printf("success\n"); else printf("failed: %ld\n",hr);
+                                bConfigChanged=TRUE;
+                            }
+                        }
+                        
+                        CoTaskMemFree( swName );
+                        CoTaskMemFree( swId );
+                        
+                        pPath->Release();
+                    }
+                    pEnumPaths->Release();
+                }
+                pBindings->Release();
+            } // hr==S_OK for QueryInterface IID_INetCfgComponentBindings
+        }
+        
+        CoTaskMemFree( swName );
+        
+        pAdapter->Release();
+    }
+    
+    pEnumComponent->Release();    
+    
+    hr = 0;
+    
+cleanup:
+    
+    if(bConfigChanged) pCfg->Apply();
+    
+    if(pAdapter) pAdapter->Release();
+    
+    if(bInitialized) pCfg->Uninitialize();
+    if(bLockGranted) pLock->ReleaseWriteLock();
+    
+    if(pLock) pLock->Release();
+    if(pCfg) pCfg->Release();
+    
+    if (hr) printf ("LoopbackBindings() is returning %u\n",hr);
+    return hr;
+}
+
+        
+        extern "C"
+            DWORD
+SetIpAddress(
+    LPCWSTR guid,
+    LPCWSTR ip,
+    LPCWSTR mask
+    )
+{
+    printf("\nRunning SetIpAddress()...\n");
+    HRESULT hr = 0;
+
+    hr = WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
+                        (PVOID)guid, ip, mask);
+    return hr;
+}
+
+/* Set MAXLANA in the registry to the specified value, unless the existing registry value is larger */
+DWORD AdjustMaxLana(DWORD dwMaxLana)
+{
+
+    LONG ret = 0;
+    HKEY hNetBiosParamKey = NULL;
+    DWORD dwType, dwExistingMaxLana, dwSize;
+
+    printf ("Making sure MaxLana is at least %u...\n", dwMaxLana);
+
+    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\NetBIOS\\Parameters"), 
+        0, KEY_ALL_ACCESS , &hNetBiosParamKey);
+    if (ret) return ret;
+
+
+    
+    dwSize = 4;
+    ret = RegQueryValueEx(hNetBiosParamKey, _T("MaxLana"), 0, &dwType, (LPBYTE) &dwExistingMaxLana, &dwSize);
+    if ((ret) && (ret != ERROR_MORE_DATA) && (ret != ERROR_FILE_NOT_FOUND)) 
+    {
+        RegCloseKey(hNetBiosParamKey);
+        return ret;
+    }
+
+    if ((dwType != REG_DWORD) || (ret)) dwExistingMaxLana = 0;
+
+    printf ("  MaxLana is currently %u\n", dwExistingMaxLana);
+
+    if (dwExistingMaxLana < dwMaxLana) 
+    {
+        printf ("  Changing to %u\n", dwMaxLana);
+        ret = RegSetValueEx(hNetBiosParamKey, _T("MaxLana"), 0, REG_DWORD, (const BYTE*)&dwMaxLana, 4);
+        if (ret) 
+        {
+            RegCloseKey(hNetBiosParamKey);
+            return ret;
+        }       
+
+    }
+
+    RegCloseKey(hNetBiosParamKey);
+    return 0;
+
+
+}
+
+extern "C" 
+BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre )
+{
+    char szIp[2048], szName[2048];
+    char etcPath[MAX_PATH];
+       char tempPath[MAX_PATH];
+       char buffer[2048], temp[2048];
+       char *str;
+       HRESULT rv;
+       DWORD fa,len;
+       FILE *hFile, *hTemp;
+       
+    _snprintf(szIp, 2047, "%S", swIp);
+    _snprintf(szName, 2047, "%S", swName);
+    strupr(szName);
+    printf("Starting UpdateHostsFile() on %s file\n",szFilename);
+
+       rv = SHGetFolderPathA( NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT , etcPath );
+       if(rv != S_OK) return FALSE;
+
+       strcat( etcPath, ETCDIR );
+
+       fa = GetFileAttributesA( etcPath );
+
+       if(fa == INVALID_FILE_ATTRIBUTES)
+       {
+               // the directory doesn't exist
+               // it should be there. non-existence implies more things are wrong
+               printf( "Path does not exist : %s\n", etcPath );
+               return FALSE;
+       }
+
+       strcpy( tempPath, etcPath );
+       strcat( etcPath, "\\" );
+       strcat( etcPath, szFilename );
+
+       fa = GetFileAttributesA( etcPath );
+
+       if(fa == INVALID_FILE_ATTRIBUTES)
+       {
+               printf( "No %s file found. Creating...", szFilename);
+
+               hFile = fopen( etcPath, "w" );
+               if(!hFile)
+               {
+                       printf("FAILED : can't create %s file\nErrno is %d\n",etcPath,errno);
+                       return FALSE;
+               }
+
+               fprintf(hFile, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
+
+               fclose( hFile );
+
+               printf("done\n");
+       }
+       else // the file exists. parse and update
+       {
+
+               printf( "Updating %s file ...",szFilename );
+
+               hFile = fopen( etcPath, "r");
+               if(!hFile)
+               {
+                       printf("FAILED : can't open %s file\nErrno is %d\n",etcPath,errno);
+                       return FALSE;
+               }
+
+               strcat( tempPath, szFilename );
+               strcat( tempPath, ".tmp" );
+               hTemp = fopen( tempPath, "w");
+               if(!hTemp)
+               {
+                       printf("FAILED : can't create temp file %s\nErrno is %d\n",tempPath,errno);
+                       fclose(hFile);
+                       return FALSE;
+               }
+
+               while(fgets( buffer, 2046, hFile))
+               {
+                       strcpy( temp, buffer );
+                       strupr( temp );
+
+            if ((strlen(temp)<1) || (*(temp+strlen(temp)-1)!='\n')) strcat(temp, "\n");
+
+                       if(!(str = strstr(temp, szName)))
+                       {
+                               fputs( buffer, hTemp );
+                       }
+                       else
+                       {
+                               // check for FOOBAFS or AFSY
+                               //if(str <= temp || (*(str-1) != '-' && !isspace(*(str+strlen(szName)))))
+                               if ( (str == temp) || (!*(str+strlen(szName))) || (!isspace(*(str-1))) || (!isspace(*(str+strlen(szName)))) )
+                    fputs( buffer, hTemp );
+                       }
+               }
+
+
+               len = 2048;
+               GetComputerNameA( buffer, &len );
+               buffer[11] = 0;
+               fprintf( hTemp, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
+
+               fclose( hTemp );
+               fclose( hFile );
+
+               strcpy(buffer, etcPath);
+               strcat(buffer, ".old");
+
+        errno = 0;
+               
+        if ((unlink( buffer ) != 0) && (errno == EACCES))
+        {
+            printf("FAILED : Can't delete %s file\nErrno is %d",buffer,errno);            
+            return FALSE;
+            
+        }
+        
+        if ((errno) && (errno != ENOENT)) printf("WEIRD : errno after unlink is %d...",errno);
+
+               if(rename( etcPath, buffer) != 0)
+               {
+                       printf("FAILED : Can't rename old %s file\nErrno is %d\n",etcPath,errno);
+                       return FALSE;
+               }
+
+               if(rename( tempPath, etcPath ) != 0)
+               {
+                       printf("FAILED : Can't rename new %s file\nErrno is %d\n",tempPath,errno);
+                       return FALSE;
+               }
+
+               printf("done\n");
+       }
+
+       return TRUE;
+}
+
+#ifdef TEST
+#if 0
+int
+wmain(
+    int argc,
+    wchar_t* argv[]
+    )
+{
+    if (argc < 3)
+    {
+        printf("usage: %S ip mask\n"
+               "  example: %S 10.0.0.1 255.0.0.0", argv[0], argv[0]);
+        return 0;
+    }
+
+    return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
+                           L"{B4981E32-551C-4164-96B6-B8874BD2E555}",
+                           argv[1], argv[2]);
+}
+#else
+int
+wmain(
+    int argc,
+    wchar_t* argv[]
+    )
+{
+    if (argc < 4)
+    {
+        printf("usage: %S adapter_guid ip mask\n"
+               "  example: %S {B4981E32-551C-4164-96B6-B8874BD2E555} "
+               "10.0.0.1 255.0.0.0", argv[0], argv[0]);
+        return 0;
+    }
+
+    return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
+                           argv[1], argv[2], argv[3]);
+}
+#endif
+#endif
+
index 9529478fc2b36d0fe29662cb50225997448a7006..a01c389483d3fcc4aa2850dadbae64f8092aa886 100644 (file)
@@ -20,7 +20,8 @@
        
       
       Directory specs: (all dir. specs end in a '\')
-       MediaBinDir    : Installer binaries (instloop.exe etc.)
+       MediaDllDir    : Installer Dlls
+       MediaBinDir    : Installer Exes
        SrcDir         : openafs\src\
        DestDir        : $(DEST)\
        BinDir         : $(DEST)\bin\
     <?ifndef SrcDir?>
         <?define SrcDir="$(env.AFSROOT)\src\"?>
     <?endif?>
+    <?ifndef MediaDllDir?>
+        <?define MediaDllDir="$(var.DestDir)WinInstall\Dll\"?>
+    <?endif?>
     <?ifndef MediaBinDir?>
-        <?define MediaBinDir="$(var.DestDir)WinInstall\Dll\"?>
+        <?define MediaBinDir="$(var.DestDir)WinInstall\Config\"?>
     <?endif?>
     <?ifndef BinDir?>
         <?define BinDir="$(var.DestDir)bin\"?>
index 38b6b8630491c6096c45911f14e9c296b60a55ff..7c37a0d559ea669b271b5d1dc4ce36be057187d3 100644 (file)
@@ -6,8 +6,6 @@ RELDIR=WINNT\install\wix\custom
 
 MEDIABINDIR = $(DESTDIR)\WinInstall\Dll
 
-EXEFILE = $(MEDIABINDIR)\instloop.exe
-
 DLLFILE = $(MEDIABINDIR)\afscustom.dll
 
 DLLEXPORTS=\
@@ -32,25 +30,6 @@ $(DLLFILE): $(OUT)\afscustom.obj
        $(LINK) -DLL $(DLLEXPORTS) \
          -OUT:$@ $** $(DLLLIBFILES)
 
-# instloop.exe
-
-SOURCEFILES = instloop.c renameconnection.cpp wmi.cpp
-OBJFILES = $(OUT)\instloop.obj $(OUT)\renameconnection.obj $(OUT)\wmi.obj
-EXELIBFILES = setupapi.lib msi.lib uuid.lib Shell32.lib ole32.lib advapi32.lib wbemuuid.lib
-
-$(OUT)\instloop.obj: instloop.c
-       $(CC) -ML -c -DUNICODE -D_UNICODE /Fo$@ $**
-
-$(OUT)\renameconnection.obj: renameconnection.cpp
-       $(CC) -ML -c -DUNICODE -D_UNICODE /Fo$@ $**
-
-$(OUT)\wmi.obj: wmi.cpp
-       $(CC)  -I$(NTDDKDIR) -ML -c -DUNICODE -D_UNICODE /Fo$@ $**
-
-$(EXEFILE): $(OBJFILES)
-       $(LINK) /OUT:$@ $(OBJFILES) $(EXELIBFILES)
-
-
-install: $(EXEFILE) $(DLLFILE)
+install: $(DLLFILE)
 
 clean  ::
diff --git a/src/WINNT/install/wix/custom/instloop.c b/src/WINNT/install/wix/custom/instloop.c
deleted file mode 100644 (file)
index 5efc202..0000000
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
-
-Copyright 2004 by the Massachusetts Institute of Technology
-
-All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of the Massachusetts
-Institute of Technology (M.I.T.) not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-
-M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-*/
-
-#include <windows.h>
-#include <stdio.h>
-#define INITGUID
-#include <guiddef.h>
-#include <devguid.h>
-#include <setupapi.h>
-#include <tchar.h>
-
-#undef REDIRECT_STDOUT
-
-#ifdef USE_PAUSE
-#define PAUSE                                          \
-    do {                                               \
-        char c;                                        \
-        printf("PAUSED - PRESS ENTER TO CONTINUE\n");  \
-        scanf("%c", &c);                               \
-    } while(0)
-#else
-#define PAUSE
-#endif
-
-/*#define USE_SLEEP*/
-
-#ifdef USE_SLEEP
-#define SLEEP Sleep(10*1000)
-#else
-#define SLEEP
-#endif
-
-
-static void ShowUsage(void);
-DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask);
-DWORD UnInstallLoopBack(void);
-int RenameConnection(PCWSTR GuidString, PCWSTR pszNewName);
-DWORD SetIpAddress(LPCWSTR guid, LPCWSTR ip, LPCWSTR mask);
-HRESULT LoopbackBindings (LPCWSTR loopback_guid);
-BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre );
-
-#define DRIVER_DESC "Microsoft Loopback Adapter"
-#define DRIVER _T("loopback")
-#define MANUFACTURE _T("microsoft")
-#define DEFAULT_NAME _T("AFS")
-#define DEFAULT_IP _T("10.254.254.253")
-#define DEFAULT_MASK _T("255.255.255.252")
-
-static void
-ShowUsage(void)
-{
-    printf("instloop [-i [name [ip mask]] | -u]\n\n");
-    printf("    -i  install the %s\n", DRIVER_DESC);
-    _tprintf(_T("        (if unspecified, uses name %s,\n"), DEFAULT_NAME);
-    _tprintf(_T("         ip %s, and mask %s)\n"), DEFAULT_IP, DEFAULT_MASK);    
-    printf("    -u  uninstall the %s\n", DRIVER_DESC);
-}
-
-static void
-DisplayStartup(BOOL bInstall)
-{
-    printf("%snstalling the %s\n"
-           " (Note: This may take up to a minute or two...)\n",
-           bInstall ? "I" : "Un",
-           DRIVER_DESC);
-    
-}
-
-static void
-DisplayResult(BOOL bInstall, DWORD rc)
-{
-    if (rc)
-    {
-        printf("Could not %sinstall the %s\n", bInstall ? "" : "un",
-               DRIVER_DESC);
-        SLEEP;
-        PAUSE;
-    }
-}
-
-
-int _tmain(int argc, TCHAR *argv[])
-{
-    DWORD rc = 0;
-#ifdef REDIRECT_STDOUT
-    FILE *fh = NULL;
-#endif
-
-    PAUSE;
-
-#ifdef REDIRECT_STDOUT
-    fh = freopen("instlog.txt","a+", stdout);
-#endif
-
-    if (argc > 1)
-    {
-        if (_tcsicmp(argv[1], _T("-i")) == 0)
-        {
-            TCHAR* name = DEFAULT_NAME;
-            TCHAR* ip = DEFAULT_IP;
-            TCHAR* mask = DEFAULT_MASK;
-
-            if (argc > 2)
-            {
-                name = argv[2];
-                if (argc > 3)
-                {
-                    if (argc < 5)
-                    {
-                        ShowUsage();
-#ifdef REDIRECT_STDOUT
-                        fflush(fh); fclose(fh);
-#endif
-                        return 1;
-                    }
-                    else
-                    {
-                        ip = argv[3];
-                        mask = argv[4];
-                    }
-                }
-            }
-            DisplayStartup(TRUE);
-                       if(IsLoopbackInstalled()) {
-                               printf("Loopback already installed\n");
-                               rc = 0; /* don't signal an error. */
-                       } else {
-                   rc = InstallLoopBack(name, ip, mask);
-                       }
-            DisplayResult(TRUE, rc);
-#ifdef REDIRECT_STDOUT
-            fflush(fh); fclose(fh);
-#endif
-            return rc;
-        }
-        else if (_tcsicmp(argv[1], _T("-u")) == 0)
-        {
-            DisplayStartup(FALSE);
-            rc = UnInstallLoopBack();
-            DisplayResult(FALSE, rc);
-#ifdef REDIRECT_STDOUT
-            fflush(fh); fclose(fh);
-#endif
-            return rc;
-        }
-        ShowUsage();
-#ifdef REDIRECT_STDOUT
-        fflush(fh); fclose(fh);
-#endif
-        return 1;
-    }
-    ShowUsage();
-#ifdef REDIRECT_STDOUT
-    fflush(fh); fclose(fh);
-#endif
-    return 0;
-}
-
-
-DWORD UnInstallLoopBack(void)
-{
-    BOOL ok;
-    DWORD ret = 0;
-    GUID netGuid;
-    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
-    SP_DEVINFO_DATA DeviceInfoData;
-    TCHAR* deviceDesc;
-    DWORD index = 0;
-    BOOL found = FALSE;
-    DWORD size = 0;
-
-    // initialize the structure size
-    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-
-    // copy the net class GUID
-    memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
-
-    // return a device info set contains all installed devices of the Net class
-    hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT);
-
-    if (hDeviceInfo == INVALID_HANDLE_VALUE)
-        return GetLastError();
-
-    deviceDesc = malloc(MAX_PATH*sizeof(TCHAR));
-    // enumerate the driver info list
-    while (SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData))
-    {
-        // try to get the DeviceDesc registry property
-        ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData,
-                                              SPDRP_DEVICEDESC,
-                                              NULL, (PBYTE)deviceDesc,
-                                              MAX_PATH * sizeof(TCHAR), &size);
-        if (!ok)
-        {
-            ret = GetLastError();
-            if (ret != ERROR_INSUFFICIENT_BUFFER)
-                break;
-            // if the buffer is too small, reallocate
-            free(deviceDesc);
-            deviceDesc = malloc(size);
-            ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo,
-                                                  &DeviceInfoData,
-                                                  SPDRP_DEVICEDESC,
-                                                  NULL, (PBYTE)deviceDesc,
-                                                  size, NULL);
-            if (!ok)
-                break;
-        }
-
-        // case insensitive comparison
-        _tcslwr(deviceDesc);
-        if( _tcsstr(deviceDesc, DRIVER))
-        {
-            found = TRUE;
-            break;
-        }
-
-        index++;
-    }
-
-    free(deviceDesc);
-    
-    if (found == FALSE)
-    {
-        ret = GetLastError();
-        printf("The %s does not seem to be installed\n", DRIVER_DESC);
-        goto cleanup;
-    }
-
-    ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-    ok = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-cleanup:
-    // clean up the device info set
-    if (hDeviceInfo != INVALID_HANDLE_VALUE)
-        SetupDiDestroyDeviceInfoList(hDeviceInfo);
-
-    return ret;
-}
-
-BOOL IsLoopbackInstalled()
-{
-    TCHAR * hwid = _T("*MSLOOP");
-    HDEVINFO DeviceInfoSet;
-    SP_DEVINFO_DATA DeviceInfoData;
-    DWORD i,err;
-    BOOL found;
-    
-    //
-    // Create a Device Information Set with all present devices.
-    //
-    DeviceInfoSet = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system
-    if (DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        return FALSE; // nothing installed?
-    }
-    
-    //
-    //  Enumerate through all Devices.
-    //
-    found = FALSE;
-    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-    for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++)
-    {
-        DWORD DataT;
-        TCHAR *p, *buffer = NULL;
-        DWORD buffersize = 0;
-        
-        //
-        // We won't know the size of the HardwareID buffer until we call
-        // this function. So call it with a null to begin with, and then 
-        // use the required buffer size to Alloc the nessicary space.
-        // Keep calling we have success or an unknown failure.
-        //
-        while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,&DataT,(PBYTE)buffer,buffersize,&buffersize))
-        {
-            if (GetLastError() == ERROR_INVALID_DATA)
-            {
-                // May be a Legacy Device with no hwid. Continue.
-                break;
-            }
-            else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-            {
-                // We need to change the buffer size.
-                if (buffer) 
-                    LocalFree(buffer);
-                buffer = (TCHAR *)LocalAlloc(LPTR,buffersize);
-            }
-            else
-            {
-                goto cleanup_DeviceInfo;
-            }            
-        }
-        
-        if (GetLastError() == ERROR_INVALID_DATA) 
-            continue;
-        
-        // Compare each entry in the buffer multi-sz list with our hwid.
-        for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1)
-        {
-            if (!_tcsicmp(hwid,p))
-            {
-                found = TRUE;
-                break;
-            }
-        }
-        
-        if (buffer) LocalFree(buffer);
-        if (found) break;
-    }
-    
-    //  Cleanup.
-cleanup_DeviceInfo:
-    err = GetLastError();
-    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
-    SetLastError(err);
-    
-    return found;
-}
-
-
-DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask)
-{
-    BOOL ok;
-    DWORD ret = 0;
-    GUID netGuid;
-    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
-    SP_DEVINFO_DATA DeviceInfoData;
-    SP_DRVINFO_DATA DriverInfoData;
-    SP_DEVINSTALL_PARAMS  DeviceInstallParams;
-    TCHAR className[MAX_PATH];
-    TCHAR temp[MAX_PATH];
-    DWORD index = 0;
-    BOOL found = FALSE;
-    BOOL registered = FALSE;
-    BOOL destroyList = FALSE;
-
-    HKEY hkey = NULL;
-    DWORD cbSize;
-    DWORD dwValueType;
-    TCHAR pCfgGuidString[40];
-
-    // initialize the structure size
-    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-    DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
-
-    // copy the net class GUID
-    memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));
-
-    // create an empty device info set associated with the net class GUID
-    hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL);
-    if (hDeviceInfo == INVALID_HANDLE_VALUE)
-        return GetLastError();
-
-    // get the class name from GUID
-    ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    // create a device info element and add the new device instance
-    // key to registry
-    ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL,
-                                 DICD_GENERATE_ID, &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    // select the newly created device info to be the currently
-    // selected member
-    ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    // build a list of class drivers
-    ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData,
-                                    SPDIT_CLASSDRIVER);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    destroyList = TRUE;
-
-    // enumerate the driver info list
-    while (SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData,
-                                 SPDIT_CLASSDRIVER, index, &DriverInfoData))
-    {
-        // if the manufacture is microsoft
-        if (_tcsicmp(DriverInfoData.MfgName, MANUFACTURE) == 0)
-        {
-            // case insensitive search for loopback
-            _tcscpy(temp, DriverInfoData.Description);
-            _tcslwr(temp);
-            if( _tcsstr(temp, DRIVER))
-            {
-                found = TRUE;
-                break;
-            }
-        }
-        index++;
-    }
-
-    if (!found)
-    {
-        ret = GetLastError();
-        printf("Could not find the %s driver to install\n", DRIVER_DESC);
-        goto cleanup;
-    }
-
-    // set the loopback driver to be the currently selected
-    ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData,
-                                  &DriverInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    // register the phantom device to repare for install
-    ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo,
-                                   &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    // registered, but remove if errors occur in the following code
-    registered = TRUE;
-
-    // ask the installer if we can install the device
-    ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo,
-                                   &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        if (ret != ERROR_DI_DO_DEFAULT)
-        {
-            goto cleanup;
-        }
-        else
-            ret = 0;
-    }
-
-    // install the files first
-    ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo,
-                                   &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    // get the device install parameters and disable filecopy
-    DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
-    ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
-                                       &DeviceInstallParams);
-    if (ok)
-    {
-        DeviceInstallParams.Flags |= DI_NOFILECOPY;
-        ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
-                                           &DeviceInstallParams);
-        if (!ok)
-        {
-            ret = GetLastError();
-            goto cleanup;
-        }
-    }
-
-    //
-    // Register any device-specific co-installers for this device,
-    //
-
-    ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS,
-                                   hDeviceInfo,
-                                   &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    //
-    // install any  installer-specified interfaces.
-    // and then do the real install
-    //
-    ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES,
-                                   hDeviceInfo,
-                                   &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-    PAUSE;
-    ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE,
-                                   hDeviceInfo,
-                                   &DeviceInfoData);
-    if (!ok)
-    {
-        ret = GetLastError();
-        PAUSE;
-        goto cleanup;
-    }
-
-    /* Skip to the end if we aren't setting the name */
-    if (!pConnectionName) goto cleanup;
-
-    // Figure out NetCfgInstanceId
-    hkey = SetupDiOpenDevRegKey(hDeviceInfo,
-                                &DeviceInfoData,
-                                DICS_FLAG_GLOBAL,
-                                0,
-                                DIREG_DRV,
-                                KEY_READ);
-    if (hkey == INVALID_HANDLE_VALUE)
-    {
-        ret = GetLastError();
-        goto cleanup;
-    }
-
-    cbSize = sizeof(pCfgGuidString);
-    ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL,
-                          &dwValueType, (LPBYTE)pCfgGuidString, &cbSize);
-    RegCloseKey(hkey);
-
-    ret = RenameConnection(pCfgGuidString, pConnectionName);
-    if (ret)
-    {
-        printf("Could not set the connection name to \"%S\"\n",
-               pConnectionName);
-        goto cleanup;
-    }
-
-    if (!ip) goto cleanup;
-    ret = SetIpAddress(pCfgGuidString, ip, mask);
-    if (ret)
-    {
-        printf("Could not set the ip address and network mask\n");
-        goto cleanup;
-    }
-    ret = LoopbackBindings(pCfgGuidString);
-    if (ret)
-    {
-        printf("Could not properly set the bindings\n");
-        goto cleanup;
-    }
-    ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE );
-    if (ret)
-    {
-        printf("Could not update hosts file\n");
-        goto cleanup;
-    }
-    ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE );
-    if (ret)
-    {
-        printf("Could not update lmhosts file\n");
-        goto cleanup;
-    }
-
-
-cleanup:
-    // an error has occured, but the device is registered, we must remove it
-    if (ret != 0 && registered)
-        SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
-
-    found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData);
-
-    // destroy the driver info list
-    if (destroyList)
-        SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData,
-                                     SPDIT_CLASSDRIVER);
-    // clean up the device info set
-    if (hDeviceInfo != INVALID_HANDLE_VALUE)
-        SetupDiDestroyDeviceInfoList(hDeviceInfo);
-
-    return ret;
-}
diff --git a/src/WINNT/install/wix/custom/renameconnection.cpp b/src/WINNT/install/wix/custom/renameconnection.cpp
deleted file mode 100644 (file)
index 4046871..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-
-Copyright 2004 by the Massachusetts Institute of Technology
-
-All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of the Massachusetts
-Institute of Technology (M.I.T.) not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-
-M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-*/
-
-#include <afx.h>
-#include <windows.h>
-#include <shellapi.h>
-#include <objbase.h>
-#include <shlobj.h>
-#include <wtypes.h>
-
-#define NETSHELL_LIBRARY _T("netshell.dll")
-
-// Use the IShellFolder API to rename the connection.
-static HRESULT rename_shellfolder(PCWSTR wGuid, PCWSTR wNewName)
-{
-    // This is the GUID for the network connections folder. It is constant.
-    // {7007ACC7-3202-11D1-AAD2-00805FC1270E}
-    const GUID CLSID_NetworkConnections = {
-        0x7007ACC7, 0x3202, 0x11D1, {
-           0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
-       }
-    };
-    LPITEMIDLIST pidl;
-    IShellFolder *pShellFolder;
-    IMalloc *pShellMalloc;
-
-    // Build the display name in the form "::{GUID}".
-    if (wcslen(wGuid) >= MAX_PATH)
-        return E_INVALIDARG;
-    WCHAR szAdapterGuid[MAX_PATH + 2];
-    swprintf(szAdapterGuid, L"::%ls", wGuid);
-
-    // Initialize COM.
-    CoInitialize(NULL);
-
-    // Get the shell allocator.
-    HRESULT hr = SHGetMalloc(&pShellMalloc);
-    if (SUCCEEDED(hr))
-    {
-        // Create an instance of the network connections folder.
-        hr = CoCreateInstance(CLSID_NetworkConnections, NULL,
-                             CLSCTX_INPROC_SERVER, IID_IShellFolder,
-                             reinterpret_cast<LPVOID *>(&pShellFolder));
-    }
-    // Parse the display name.
-    if (SUCCEEDED(hr))
-    {
-        hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL,
-                                           &pidl, NULL);
-    }
-    if (SUCCEEDED(hr))
-    {
-       hr = pShellFolder->SetNameOf(NULL, pidl, wNewName, SHGDN_NORMAL,
-                                    &pidl);
-       pShellMalloc->Free(pidl);
-    }
-    CoUninitialize();
-    return hr;
-}
-
-extern "C" int RenameConnection(PCWSTR GuidString, PCWSTR NewName)
-{
-    typedef HRESULT (WINAPI *lpHrRenameConnection)(const GUID *, PCWSTR);
-    lpHrRenameConnection RenameConnectionFunc = NULL;
-    HRESULT status;
-
-    // First try the IShellFolder interface, which was unimplemented
-    // for the network connections folder before XP.
-    status = rename_shellfolder(GuidString, NewName);
-    if (status == E_NOTIMPL)
-    {
-       // The IShellFolder interface is not implemented on this platform.
-        // Try the (undocumented) HrRenameConnection API in the netshell
-        // library.
-       CLSID clsid;
-        HINSTANCE hNetShell;
-       status = CLSIDFromString((LPOLESTR) GuidString, &clsid);
-       if (FAILED(status))
-           return -1;
-       hNetShell = LoadLibrary(NETSHELL_LIBRARY);
-       if (hNetShell == NULL)
-           return -1;
-       RenameConnectionFunc =
-         (lpHrRenameConnection) GetProcAddress(hNetShell,
-                                               "HrRenameConnection");
-       if (RenameConnectionFunc == NULL)
-       {
-           FreeLibrary(hNetShell);
-           return -1;
-       }
-       status = RenameConnectionFunc(&clsid, NewName);
-       FreeLibrary(hNetShell);
-    }
-    if (FAILED(status))
-       return -1;
-    return 0;
-}
diff --git a/src/WINNT/install/wix/custom/wmi.cpp b/src/WINNT/install/wix/custom/wmi.cpp
deleted file mode 100644 (file)
index 9848155..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
-
-Copyright 2004 by the Massachusetts Institute of Technology
-
-All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of the Massachusetts
-Institute of Technology (M.I.T.) not be used in advertising or publicity
-pertaining to distribution of the software without specific, written
-prior permission.
-
-M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-*/
-
-//**************************************************************************
-//
-// Description:
-//
-//      Call EnableStatic method of Win32_NetworkAdapterConfiguration
-//      for some network adapter GUID.
-//
-// Note:
-//
-//     The EnableStatic method is notsupported on Win9x platforms.
-//
-//**************************************************************************
-
-#define _WIN32_DCOM
-#include <windows.h>
-#include <comdef.h>
-#include <wbemidl.h>
-#include <tchar.h>
-
-#include <devguid.h>
-
-/* These two are from the Windows DDK */
-#include <netcfgx.h>
-#include <netcfgn.h>
-
-#include <shlobj.h>
-//#include <objbase.h>
-
-//#ifndef TEST
-//inline void printf(char*, ...) {}
-//#else
-#include <stdio.h>
-//#endif
-
-#define CLEANUP_ON_FAILURE(hr) \
-    do { if (!SUCCEEDED(hr)) goto cleanup; } while (0)
-
-#define CLEANUP_ON_AND_SET(check, var, value) \
-    do { if (check) { (var) = (value); goto cleanup; } } while (0)
-
-#define ETCDIR "\\drivers\\etc"
-
-#define EACCES (13)
-#define ENOENT (2)
-
-DWORD AdjustMaxLana(DWORD dwMaxLana);
-
-typedef
-HRESULT
-(*FindNetworkAdapterConfigurationInstance_t)(
-    IN  PVOID pContext,
-    IN  IWbemServices *pSvc,
-    OUT BSTR* pPath
-    );
-
-HRESULT
-FindNetworkAdapterConfigurationInstanceByGUID(
-    IN  PVOID pContext,
-    IN  IWbemServices *pSvc,
-    OUT BSTR* pPath
-    )
-{
-    HRESULT hr = 0;
-    BOOL bFound = FALSE;
-    BSTR Language = 0;
-    BSTR Query = 0;
-    IEnumWbemClassObject* pEnum = 0;
-    IWbemClassObject* pObj = 0;
-    VARIANT Value;
-    VariantInit(&Value);
-    LPCWSTR adapter_guid = (LPCWSTR)pContext;
-
-    // Check arguments
-    if (!pPath || !adapter_guid || *pPath)
-        return E_INVALIDARG;
-
-    *pPath = 0;
-
-    // Query for all network adapters
-    Language = SysAllocString(L"WQL");
-    Query = SysAllocString(L"select * from Win32_NetworkAdapterConfiguration");
-
-    // Issue the query.
-    hr = pSvc->ExecQuery(Language,
-                         Query,
-                         WBEM_FLAG_FORWARD_ONLY,         // Flags
-                         0,                              // Context
-                         &pEnum);
-    if (!SUCCEEDED(hr))
-    {
-        printf("ExecQuery() error (0x%08X)\n", hr);
-        goto cleanup;
-    }
-
-    // Retrieve the objects in the result set.
-    while (!bFound)
-    {
-        ULONG uReturned = 0;
-
-        hr = pEnum->Next(0,                  // Time out
-                         1,                  // One object
-                         &pObj,
-                         &uReturned);
-        CLEANUP_ON_FAILURE(hr);
-
-        if (uReturned == 0)
-            break;
-
-        // Use the object.
-        hr  = pObj->Get(L"SettingID", // property name
-                        0L,
-                        &Value,       // output to this variant
-                        NULL,
-                        NULL);
-        CLEANUP_ON_FAILURE(hr);
-
-        bFound = !wcscmp(adapter_guid, V_BSTR(&Value));
-        
-        if (bFound)
-        {
-            printf("Found adapter: %S\n", V_BSTR(&Value));
-            VariantClear(&Value);
-            hr = pObj->Get(L"__RELPATH", // property name
-                           0L,
-                           &Value,       // output to this variant
-                           NULL,
-                           NULL);
-            CLEANUP_ON_FAILURE(hr);
-
-            *pPath = SysAllocString(V_BSTR(&Value));
-            
-        }
-        
-        VariantClear(&Value);
-        
-        // Release it.
-        // ===========
-        pObj->Release();    // Release objects not owned.
-        pObj = 0;
-    }
-
-
-    // All done.
- cleanup:
-    SysFreeString(Query);
-    SysFreeString(Language);
-    VariantClear(&Value);
-    if (pEnum)
-        pEnum->Release();
-    if (pObj)
-        pObj->Release();
-
-    return *pPath ? 0 : ( SUCCEEDED(hr) ? WBEM_E_NOT_FOUND : hr );
-}
-
-HRESULT
-SetupStringAsSafeArray(LPCWSTR s, VARIANT* v)
-{
-    HRESULT hr = 0;
-    BSTR b = 0;
-    SAFEARRAY* array = 0;
-    long index[] = {0};
-
-    if (V_VT(v) != VT_EMPTY)
-        return E_INVALIDARG;
-
-    b = SysAllocString(s);
-    CLEANUP_ON_AND_SET(!b, hr, E_OUTOFMEMORY);
-
-    array = SafeArrayCreateVector(VT_BSTR, 0, 1);
-    CLEANUP_ON_AND_SET(!array, hr, E_OUTOFMEMORY);
-
-    hr = SafeArrayPutElement(array, index, b);
-    CLEANUP_ON_FAILURE(hr);
-
-    V_VT(v) = VT_ARRAY|VT_BSTR;
-    V_ARRAY(v) = array;
-
- cleanup:
-    if (b)
-        SysFreeString(b);
-    if (!SUCCEEDED(hr))
-    {
-        if (array)
-            SafeArrayDestroy(array);
-    }
-    return hr;
-}
-
-
-HRESULT
-WMIEnableStatic(
-    FindNetworkAdapterConfigurationInstance_t pFindInstance,
-    PVOID pContext,
-    LPCWSTR ip,
-    LPCWSTR mask
-    )
-{
-    HRESULT hr = 0;
-
-    IWbemLocator* pLocator = 0;
-    IWbemServices* pNamespace = 0;
-    IWbemClassObject* pClass = 0;
-    IWbemClassObject* pOutInst = 0;
-    IWbemClassObject* pInClass = 0;
-    IWbemClassObject* pInInst = 0;
-
-    BSTR NamespacePath = 0;
-    BSTR ClassPath = 0;
-    BSTR InstancePath = 0;
-    BSTR MethodName = 0; // needs to be BSTR for ExecMethod()
-
-    VARIANT v_ip_list;
-    VariantInit(&v_ip_list);
-
-    VARIANT v_mask_list;
-    VariantInit(&v_mask_list);
-
-    VARIANT v_ret_value;
-    VariantInit(&v_ret_value);
-
-    int count;
-
-    // end of declarations & NULL initialization
-
-    NamespacePath = SysAllocString(L"root\\cimv2");
-    CLEANUP_ON_AND_SET(!NamespacePath, hr, E_OUTOFMEMORY);
-
-    ClassPath = SysAllocString(L"Win32_NetWorkAdapterConfiguration");
-    CLEANUP_ON_AND_SET(!ClassPath, hr, E_OUTOFMEMORY);
-
-    MethodName = SysAllocString(L"EnableStatic");
-    CLEANUP_ON_AND_SET(!MethodName, hr, E_OUTOFMEMORY);
-
-    // Initialize COM and connect up to CIMOM
-
-    hr = CoInitializeEx(0, COINIT_MULTITHREADED);
-    CLEANUP_ON_FAILURE(hr);
-
-    hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
-                              RPC_C_AUTHN_LEVEL_CONNECT,
-                              RPC_C_IMP_LEVEL_IMPERSONATE,
-                              NULL, EOAC_NONE, 0);
-    CLEANUP_ON_FAILURE(hr);
-
-    hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
-                          IID_IWbemLocator, (LPVOID *) &pLocator);
-    CLEANUP_ON_FAILURE(hr);
-
-    hr = pLocator->ConnectServer(NamespacePath, NULL, NULL, NULL, 0,
-                                 NULL, NULL, &pNamespace);
-    CLEANUP_ON_FAILURE(hr);
-
-    printf("Connected to WMI\n");
-
-    // Set the proxy so that impersonation of the client occurs.
-    hr = CoSetProxyBlanket(pNamespace,
-                           RPC_C_AUTHN_WINNT,
-                           RPC_C_AUTHZ_NONE,
-                           NULL,
-                           RPC_C_AUTHN_LEVEL_CALL,
-                           RPC_C_IMP_LEVEL_IMPERSONATE,
-                           NULL,
-                           EOAC_NONE);
-    CLEANUP_ON_FAILURE(hr);
-
-    // Get the class object
-    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
-    CLEANUP_ON_FAILURE(hr);
-
-    // Get the instance
-    hr = pFindInstance(pContext, pNamespace, &InstancePath);
-    CLEANUP_ON_FAILURE(hr);
-
-    printf("Found Adapter Instance: %S\n", InstancePath);
-
-#if 0
-    // Use the adapter instance index to set MAXLANA in the registry.
-    {
-        DWORD dwIndex;
-        if (swscanf(InstancePath, L"Win32_NetworkAdapterConfiguration.Index=%u", &dwIndex)==1)
-        {
-            DWORD ret = 0; 
-            printf("Setting MAXLANA to at least %u\n",dwIndex+1);
-            ret = AdjustMaxLana(dwIndex+1);
-            if (ret) printf("AdjustMaxLana returned the error code %u.\n",ret);
-        }
-    }
-#endif
-
-    // Get the input argument and set the property
-    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
-    CLEANUP_ON_FAILURE(hr);
-
-    hr = pInClass->SpawnInstance(0, &pInInst);
-    CLEANUP_ON_FAILURE(hr);
-
-    // Set up parameters
-    hr = SetupStringAsSafeArray(ip, &v_ip_list);
-    CLEANUP_ON_FAILURE(hr);
-
-    hr = pInInst->Put(L"IPAddress", 0, &v_ip_list, 0);
-    CLEANUP_ON_FAILURE(hr);
-
-    hr = SetupStringAsSafeArray(mask, &v_mask_list);
-    CLEANUP_ON_FAILURE(hr);
-
-    hr = pInInst->Put(L"SubNetMask", 0, &v_mask_list, 0);
-    CLEANUP_ON_FAILURE(hr);
-
-    // Sleep for a twenty seconds
-    printf("Calling ExecMethod in 20 seconds...\r");
-    Sleep(10000);
-    printf("Calling ExecMethod in 10 seconds...\r");
-    Sleep(5000);  
-    printf("Calling ExecMethod in  5 seconds...\r");
-    Sleep(2000);
-
-//    printf("Skipping ExecMethod\n");
-//    hr = 0;
-//    goto cleanup;
-
-    // Try up to five times, sleeping 3 seconds between tries
-    for (count=0; count<5; count++)
-    {
-        if (count>0) printf("Trying again in 3 seconds...\n");
-
-       Sleep(3000);
-  
-        printf("Calling ExecMethod NOW...          \n");     
-
-        // Call the method
-
-        hr = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL, pInInst,
-                                  &pOutInst, NULL);   
-
-        if (!SUCCEEDED(hr))
-        {
-           printf("ExecMethod failed (0x%08X)\n", hr);
-           continue;
-        }
-
-        // Get the EnableStatic method return value
-        hr = pOutInst->Get(L"ReturnValue", 0, &v_ret_value, 0, 0);
-
-        if (!SUCCEEDED(hr))
-        {
-          printf("WARNING: Could not determine return value for EnableStatic (0x%08X)\n", hr);
-          continue;
-        }
-
-        hr = V_I4(&v_ret_value);                
-
-
-        if(hr != 0)
-            printf("EnableStatic failed (0x%08X)\n", hr);
-        else
-        {
-            printf("EnableStatic succeeded\n");
-            break;
-        }
-
-    }
-
-
-
- cleanup:
-    // Free up resources
-    VariantClear(&v_ret_value);
-    VariantClear(&v_ip_list);
-    VariantClear(&v_mask_list);
-
-    SysFreeString(NamespacePath);
-    SysFreeString(ClassPath);
-    SysFreeString(InstancePath);
-    SysFreeString(MethodName);
-
-    if (pClass) pClass->Release();
-    if (pInInst) pInInst->Release();
-    if (pInClass) pInClass->Release();
-    if (pOutInst) pOutInst->Release();
-    if (pLocator) pLocator->Release();
-    if (pNamespace) pNamespace->Release();
-
-    CoUninitialize();
-    return hr;
-}
-
-
-/**********************************************************
-* LoopbackBindings :  unbind all other 
-*       protocols except TCP/IP, netbios, netbt. 
-*/
-extern "C" HRESULT LoopbackBindings (LPCWSTR loopback_guid)
-{
-    HRESULT                    hr = 0;
-    INetCfg                    *pCfg = NULL;
-    INetCfgLock                *pLock = NULL;
-    INetCfgComponent *pAdapter = NULL;
-    IEnumNetCfgComponent *pEnumComponent = NULL;
-    BOOL                       bLockGranted = FALSE;
-    BOOL                       bInitialized = FALSE;
-    BOOL                       bConfigChanged = FALSE;
-    LPWSTR                     swName = NULL;
-    GUID            g;
-    wchar_t         device_guid[100];
-    DWORD                      lenDeviceId;    
-    
-    printf("\nRunning LoopbackBindings()...\n");
-    
-    hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ); 
-    CLEANUP_ON_FAILURE(hr);
-    
-    hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void**)&pCfg );
-    CLEANUP_ON_FAILURE(hr);
-    
-    hr = pCfg->QueryInterface( IID_INetCfgLock, (void**)&pLock );
-    CLEANUP_ON_FAILURE(hr);
-    
-    hr = pLock->AcquireWriteLock( 1000, L"AFS Configuration", NULL );
-    CLEANUP_ON_FAILURE(hr);
-    bLockGranted = TRUE;
-    
-    hr = pCfg->Initialize( NULL );
-    CLEANUP_ON_FAILURE(hr);
-    bInitialized = TRUE;
-    
-    hr = pCfg->EnumComponents( &GUID_DEVCLASS_NET, &pEnumComponent );
-    CLEANUP_ON_FAILURE(hr);
-    
-    
-    while( pEnumComponent->Next( 1, &pAdapter, NULL ) == S_OK )
-    {
-        pAdapter->GetDisplayName( &swName );
-        pAdapter->GetInstanceGuid( &g );
-        StringFromGUID2(g, device_guid, 99);
-        
-        if(!wcscmp( device_guid, loopback_guid )) // found loopback adapter
-        {
-            INetCfgComponentBindings *pBindings;
-            INetCfgBindingPath *pPath;
-            IEnumNetCfgBindingPath *pEnumPaths;
-            INetCfgComponent *upper;
-            
-            wprintf(L"LoopbackBindings found: %s\n", device_guid );
-            
-            hr = pAdapter->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings);
-            if(hr==S_OK)
-            {
-                hr = pBindings->EnumBindingPaths( EBP_ABOVE, &pEnumPaths );
-                if(hr==S_OK)
-                {
-                    while(pEnumPaths->Next( 1, &pPath, NULL ) == S_OK)
-                    {
-                        pPath->GetOwner( &upper );
-                        
-                        LPWSTR swId = NULL, swName = NULL;
-                        
-                        upper->GetDisplayName( &swName );
-                        upper->GetId( &swId );
-                        
-                        wprintf(L"Looking at %s (%s)... \n",swName, swId);
-                                                                        
-                        {
-                            wprintf(L"  Moving to the end of binding order...");
-                            INetCfgComponentBindings *pBindings2;
-                            hr = upper->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings2);
-                            if (hr==S_OK)
-                            {
-                                printf("...");
-                                hr = pBindings2->MoveAfter(pPath, NULL);                                
-                                pBindings2->Release();                               
-                                bConfigChanged=TRUE;
-                            }
-                            if (hr==S_OK) printf("success\n"); else printf("failed: 0x%0lx\n",hr);                                                        
-                                                                                                            
-                        }                        
-                        
-                        if ( !_wcsicmp(swId, L"ms_netbios")  || 
-                            !_wcsicmp(swId, L"ms_tcpip")    ||
-                            !_wcsicmp(swId, L"ms_netbt")      )
-                        {
-                            if (pPath->IsEnabled()!=S_OK)
-                            {
-                                wprintf(L"  Enabling %s: ",swName);
-                                hr = pPath->Enable(TRUE);
-                                if (hr==S_OK) printf("success\n"); else printf("failed: %ld\n",hr);
-                                bConfigChanged=TRUE;
-                            }
-                            
-                            
-                        }
-                        else //if (!_wcsicmp(swId, L"ms_server") || (!_wcsicmp(swId, L"ms_msclient")) 
-                        {
-                            if (pPath->IsEnabled()==S_OK)
-                            {
-                                wprintf(L"  Disabling %s: ",swName);
-                                hr = pPath->Enable(FALSE);
-                                if (hr==S_OK) printf("success\n"); else printf("failed: %ld\n",hr);
-                                bConfigChanged=TRUE;
-                            }
-                        }
-                        
-                        CoTaskMemFree( swName );
-                        CoTaskMemFree( swId );
-                        
-                        pPath->Release();
-                    }
-                    pEnumPaths->Release();
-                }
-                pBindings->Release();
-            } // hr==S_OK for QueryInterface IID_INetCfgComponentBindings
-        }
-        
-        CoTaskMemFree( swName );
-        
-        pAdapter->Release();
-    }
-    
-    pEnumComponent->Release();    
-    
-    hr = 0;
-    
-cleanup:
-    
-    if(bConfigChanged) pCfg->Apply();
-    
-    if(pAdapter) pAdapter->Release();
-    
-    if(bInitialized) pCfg->Uninitialize();
-    if(bLockGranted) pLock->ReleaseWriteLock();
-    
-    if(pLock) pLock->Release();
-    if(pCfg) pCfg->Release();
-    
-    if (hr) printf ("LoopbackBindings() is returning %u\n",hr);
-    return hr;
-}
-
-        
-        extern "C"
-            DWORD
-SetIpAddress(
-    LPCWSTR guid,
-    LPCWSTR ip,
-    LPCWSTR mask
-    )
-{
-    printf("\nRunning SetIpAddress()...\n");
-    HRESULT hr = 0;
-
-    hr = WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
-                        (PVOID)guid, ip, mask);
-    return hr;
-}
-
-/* Set MAXLANA in the registry to the specified value, unless the existing registry value is larger */
-DWORD AdjustMaxLana(DWORD dwMaxLana)
-{
-
-    LONG ret = 0;
-    HKEY hNetBiosParamKey = NULL;
-    DWORD dwType, dwExistingMaxLana, dwSize;
-
-    printf ("Making sure MaxLana is at least %u...\n", dwMaxLana);
-
-    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\NetBIOS\\Parameters"), 
-        0, KEY_ALL_ACCESS , &hNetBiosParamKey);
-    if (ret) return ret;
-
-
-    
-    dwSize = 4;
-    ret = RegQueryValueEx(hNetBiosParamKey, _T("MaxLana"), 0, &dwType, (LPBYTE) &dwExistingMaxLana, &dwSize);
-    if ((ret) && (ret != ERROR_MORE_DATA) && (ret != ERROR_FILE_NOT_FOUND)) 
-    {
-        RegCloseKey(hNetBiosParamKey);
-        return ret;
-    }
-
-    if ((dwType != REG_DWORD) || (ret)) dwExistingMaxLana = 0;
-
-    printf ("  MaxLana is currently %u\n", dwExistingMaxLana);
-
-    if (dwExistingMaxLana < dwMaxLana) 
-    {
-        printf ("  Changing to %u\n", dwMaxLana);
-        ret = RegSetValueEx(hNetBiosParamKey, _T("MaxLana"), 0, REG_DWORD, (const BYTE*)&dwMaxLana, 4);
-        if (ret) 
-        {
-            RegCloseKey(hNetBiosParamKey);
-            return ret;
-        }       
-
-    }
-
-    RegCloseKey(hNetBiosParamKey);
-    return 0;
-
-
-}
-
-extern "C" 
-BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre )
-{
-    char szIp[2048], szName[2048];
-    char etcPath[MAX_PATH];
-       char tempPath[MAX_PATH];
-       char buffer[2048], temp[2048];
-       char *str;
-       HRESULT rv;
-       DWORD fa,len;
-       FILE *hFile, *hTemp;
-       
-    _snprintf(szIp, 2047, "%S", swIp);
-    _snprintf(szName, 2047, "%S", swName);
-    strupr(szName);
-    printf("Starting UpdateHostsFile() on %s file\n",szFilename);
-
-       rv = SHGetFolderPathA( NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT , etcPath );
-       if(rv != S_OK) return FALSE;
-
-       strcat( etcPath, ETCDIR );
-
-       fa = GetFileAttributesA( etcPath );
-
-       if(fa == INVALID_FILE_ATTRIBUTES)
-       {
-               // the directory doesn't exist
-               // it should be there. non-existence implies more things are wrong
-               printf( "Path does not exist : %s\n", etcPath );
-               return FALSE;
-       }
-
-       strcpy( tempPath, etcPath );
-       strcat( etcPath, "\\" );
-       strcat( etcPath, szFilename );
-
-       fa = GetFileAttributesA( etcPath );
-
-       if(fa == INVALID_FILE_ATTRIBUTES)
-       {
-               printf( "No %s file found. Creating...", szFilename);
-
-               hFile = fopen( etcPath, "w" );
-               if(!hFile)
-               {
-                       printf("FAILED : can't create %s file\nErrno is %d\n",etcPath,errno);
-                       return FALSE;
-               }
-
-               fprintf(hFile, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
-
-               fclose( hFile );
-
-               printf("done\n");
-       }
-       else // the file exists. parse and update
-       {
-
-               printf( "Updating %s file ...",szFilename );
-
-               hFile = fopen( etcPath, "r");
-               if(!hFile)
-               {
-                       printf("FAILED : can't open %s file\nErrno is %d\n",etcPath,errno);
-                       return FALSE;
-               }
-
-               strcat( tempPath, szFilename );
-               strcat( tempPath, ".tmp" );
-               hTemp = fopen( tempPath, "w");
-               if(!hTemp)
-               {
-                       printf("FAILED : can't create temp file %s\nErrno is %d\n",tempPath,errno);
-                       fclose(hFile);
-                       return FALSE;
-               }
-
-               while(fgets( buffer, 2046, hFile))
-               {
-                       strcpy( temp, buffer );
-                       strupr( temp );
-
-            if ((strlen(temp)<1) || (*(temp+strlen(temp)-1)!='\n')) strcat(temp, "\n");
-
-                       if(!(str = strstr(temp, szName)))
-                       {
-                               fputs( buffer, hTemp );
-                       }
-                       else
-                       {
-                               // check for FOOBAFS or AFSY
-                               //if(str <= temp || (*(str-1) != '-' && !isspace(*(str+strlen(szName)))))
-                               if ( (str == temp) || (!*(str+strlen(szName))) || (!isspace(*(str-1))) || (!isspace(*(str+strlen(szName)))) )
-                    fputs( buffer, hTemp );
-                       }
-               }
-
-
-               len = 2048;
-               GetComputerNameA( buffer, &len );
-               buffer[11] = 0;
-               fprintf( hTemp, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
-
-               fclose( hTemp );
-               fclose( hFile );
-
-               strcpy(buffer, etcPath);
-               strcat(buffer, ".old");
-
-        errno = 0;
-               
-        if ((unlink( buffer ) != 0) && (errno == EACCES))
-        {
-            printf("FAILED : Can't delete %s file\nErrno is %d",buffer,errno);            
-            return FALSE;
-            
-        }
-        
-        if ((errno) && (errno != ENOENT)) printf("WEIRD : errno after unlink is %d...",errno);
-
-               if(rename( etcPath, buffer) != 0)
-               {
-                       printf("FAILED : Can't rename old %s file\nErrno is %d\n",etcPath,errno);
-                       return FALSE;
-               }
-
-               if(rename( tempPath, etcPath ) != 0)
-               {
-                       printf("FAILED : Can't rename new %s file\nErrno is %d\n",tempPath,errno);
-                       return FALSE;
-               }
-
-               printf("done\n");
-       }
-
-       return TRUE;
-}
-
-#ifdef TEST
-#if 0
-int
-wmain(
-    int argc,
-    wchar_t* argv[]
-    )
-{
-    if (argc < 3)
-    {
-        printf("usage: %S ip mask\n"
-               "  example: %S 10.0.0.1 255.0.0.0", argv[0], argv[0]);
-        return 0;
-    }
-
-    return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
-                           L"{B4981E32-551C-4164-96B6-B8874BD2E555}",
-                           argv[1], argv[2]);
-}
-#else
-int
-wmain(
-    int argc,
-    wchar_t* argv[]
-    )
-{
-    if (argc < 4)
-    {
-        printf("usage: %S adapter_guid ip mask\n"
-               "  example: %S {B4981E32-551C-4164-96B6-B8874BD2E555} "
-               "10.0.0.1 255.0.0.0", argv[0], argv[0]);
-        return 0;
-    }
-
-    return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
-                           argv[1], argv[2], argv[3]);
-}
-#endif
-#endif
-
index 871ba41fe618343ffb89b9a76390f73b5592ff2e..03560a77db6ef06bb97e39e590b09995389a3125 100644 (file)
@@ -63,7 +63,7 @@
          src="$(var.MediaBinDir)instloop.exe"/>
         <Binary
                 Id="BIN_afsCustom"
-                src="$(var.MediaBinDir)afscustom.dll"/>
+                src="$(var.MediaDllDir)afscustom.dll"/>
         <CustomAction
          Id="InstallLoopback"
          BinaryKey="BIN_Instloop"
index 84581449904eb97d70998340e0b4d3215318ce2c..3101731252c1df44f436a39faff67fe38a1da6e5 100644 (file)
@@ -347,6 +347,9 @@ idirs: doclink
 !      IF (!EXIST($(OJT)\WINNT\install\InstallShield5))
                $(MKDIR) $(OJT)\WINNT\install\InstallShield5
 !      ENDIF
+!      IF (!EXIST($(OJT)\WINNT\install\loopback))
+               $(MKDIR) $(OJT)\WINNT\install\loopback
+!      ENDIF
 !      IF (!EXIST($(OJT)\WINNT\install\NSIS))
                $(MKDIR) $(OJT)\WINNT\install\NSIS
 !      ENDIF