-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\$@
$(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
$(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")
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
+++ /dev/null
-/**
- * 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;
-}
+++ /dev/null
-LIBRARY LOOPBACK_INSTALL
-
-DESCRIPTION "Microsoft Loopback Adapter Installer for OpenAFS"
-
-EXPORTS
- doLoopBackEntryW
- disableLoopBackEntryW
- loopback_isInstalled
-
-
--- /dev/null
+# 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 ::
--- /dev/null
+/*
+
+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;
+}
+
--- /dev/null
+/*
+ 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;
+}
+
--- /dev/null
+/*
+
+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
+
--- /dev/null
+/*
+
+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;
+}
--- /dev/null
+/*
+
+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
+
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\"?>
MEDIABINDIR = $(DESTDIR)\WinInstall\Dll
-EXEFILE = $(MEDIABINDIR)\instloop.exe
-
DLLFILE = $(MEDIABINDIR)\afscustom.dll
DLLEXPORTS=\
$(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 ::
+++ /dev/null
-/*
-
-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;
-}
+++ /dev/null
-/*
-
-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;
-}
+++ /dev/null
-/*
-
-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
-
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"
! 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