From: Jeffrey Altman Date: Wed, 23 Jun 2004 08:48:18 +0000 (+0000) Subject: new-loopback-dll-20040622 X-Git-Tag: openafs-devel-1_3_65~21 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=be70343e2a5e4d050363c8cad1a1132e43d24a51;p=packages%2Fo%2Fopenafs.git new-loopback-dll-20040622 Construct a new afsloopback.dll which contains the routines for installing, removing, and verifying the existance of a loopback adapter. This dll will be used by both the NSIS and the Wix installers. ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== Update the wix installer to use the new version of instloop.exe which uses the new afsloopback.dll --- diff --git a/src/NTMakefile b/src/NTMakefile index ac03c9cd5..32101b647 100644 --- a/src/NTMakefile +++ b/src/NTMakefile @@ -601,6 +601,13 @@ mkdir: -mkdir $(DESTDIR)\free\bin -@copy $(SRC)\config\NTLANG.BAT . +loopback: + echo ***** Making Loopback Adapter Utility DLL + $(DOCD) $(SRC)\WINNT\install\$@ + $(CD) $(SRC)\WINNT\install\$@ + $(NTMAKE) + $(CD) ..\..\..\.. + NSIS: echo ***** Making NSIS Installer $(DOCD) $(SRC)\WINNT\install\$@ @@ -627,11 +634,11 @@ InstallShield5: $(NTMAKE) $(CD) ..\..\..\.. -media: install InstallShield5 NSIS +media: install loopback InstallShield5 NSIS wix -install-nsis: install NSIS +install-nsis: install loopback NSIS -install-wix: install wix +install-wix: install loopback wix install-is5: install InstallShield5 diff --git a/src/WINNT/install/NSIS/NTMakefile b/src/WINNT/install/NSIS/NTMakefile index c032d8a80..b90525f31 100644 --- a/src/WINNT/install/NSIS/NTMakefile +++ b/src/WINNT/install/NSIS/NTMakefile @@ -22,12 +22,6 @@ $(OUT)\Killer.obj: Killer.cpp $(EXEDIR)\Killer.exe: $(OUT)\Killer.obj $(EXECONLINK) $(OUT)\Killer.obj -$(OUT)\loopback_install.obj: loopback_install.cpp - $(C2OBJ) -I$(NTDDKDIR) loopback_install.cpp - -$(EXEDIR)\loopback_install.dll: $(OUT)\loopback_install.obj - $(DLLCONLINK) /DEF:loopback_install.def $(OUT)\loopback_install.obj $(LOOPBACK_LIBS) - prebuild: !IF ("$(AFSDEV_BUILDTYPE)" == "FREE") !IF ("$(AFSVER_CL)"=="1310") @@ -87,7 +81,7 @@ prebuild: build: prebuild "C:\Program Files\NSIS\makensis.exe" /DINCLUDEDIR=$(OUT) OpenAFS.nsi -install: $(OUT)\Service.obj $(EXEDIR)\Service.exe $(OUT)\Killer.obj $(EXEDIR)\Killer.exe $(EXEDIR)\loopback_install.dll build +install: $(OUT)\Service.obj $(EXEDIR)\Service.exe $(OUT)\Killer.obj $(EXEDIR)\Killer.exe build #clean: # $(DEL) $(OUT)\Service.obj diff --git a/src/WINNT/install/NSIS/loopback_install.cpp b/src/WINNT/install/NSIS/loopback_install.cpp deleted file mode 100644 index fcefd20b7..000000000 --- a/src/WINNT/install/NSIS/loopback_install.cpp +++ /dev/null @@ -1,1266 +0,0 @@ -/** - * Copyright (c) 2003 Lingo Systems Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -// Modified 7/18/03 by Ben Creech for NCSU ITECS -// to add command-line parameters and turn into a non-console app. - -// devcon -r install %SYSTEMROOT%\Inf\Netloop.inf *MSLOOP - - -// Win2k -#define _WIN32_DCOM -#define UNICODE -#define _UNICODE - -#include -#include -#include -#include - -// The following two headers are from the Microsoft DDK -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include // WMI interface declarations - -#include -#include - -#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""); - 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""); - - } - - *pbuf = buf; - return buf; -} - -void VariantInitStringArray(VARIANT &var, BSTR str) -{ - DWORD hr; - BSTR *arrayContents; - var.vt = VT_BSTR|VT_ARRAY; - var.parray = SafeArrayCreateVector(VT_BSTR, 0, 1); - if((hr = SafeArrayAccessData(var.parray, (void **)&arrayContents))) { EasyErrorBox (0, L"Failed to access contents"); exit(1); } - arrayContents[0] = str; -} - - -WCHAR *EnableStatic_strerror(int err) -{ - switch(err) - { - case 0: return L"Successful completion, no reboot required."; - case 1: return L"Successful completion, reboot required."; - case 64: return L"Method not supported on this platform."; - case 65: return L"Unknown failure."; - case 66: return L"Invalid subnet mask."; - case 67: return L"An error occurred while processing an instance that was returned."; - case 68: return L"Invalid input parameter."; - case 69: return L"More than five gateways specified."; - case 70: return L"Invalid IP address."; - case 71: return L"Invalid gateway IP address."; - case 72: return L"An error occurred while accessing the registry for the requested information."; - case 73: return L"Invalid domain name."; - case 74: return L"Invalid host name."; - case 75: return L"No primary or secondary WINS server defined."; - case 76: return L"Invalid file."; - case 77: return L"Invalid system path."; - case 78: return L"File copy failed."; - case 79: return L"Invalid security parameter."; - case 80: return L"Unable to configure TCP/IP service."; - case 81: return L"Unable to configure DHCP service."; - case 82: return L"Unable to renew DHCP lease."; - case 83: return L"Unable to release DHCP lease."; - case 84: return L"IP not enabled on adapter."; - case 85: return L"IPX not enabled on adapter."; - case 86: return L"Frame/network number bounds error."; - case 87: return L"Invalid frame type."; - case 88: return L"Invalid network number."; - case 89: return L"Duplicate network number."; - case 90: return L"Parameter out of bounds."; - case 91: return L"Access denied."; - case 92: return L"Out of memory."; - case 93: return L"Already exists."; - case 94: return L"Path, file, or object not found."; - case 95: return L"Unable to notify service."; - case 96: return L"Unable to notify DNS service."; - case 97: return L"Interface not configurable."; - case 98: return L"Not all DHCP leases could be released or renewed."; - case 100: return L"DHCP not enabled on adapter."; - default: return L"See online for the description of this error"; - } -} - -// Change the loopback to use a static IP: 127.0.0.2 -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/retrieving_class_or_instance_data.asp -// GetObject() -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/iwbemservices_getobject.asp -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_networkadapter.asp -// EnableStatic() -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/enablestatic_method_in_class_win32_networkadapterconfiguration.asp -// #define loopback_adapter_path "Win32_NetworkAdapter" -int loopback_configure(int *needReboot, WCHAR *loopbackIP, WCHAR *loopbackNetmask) -{ - HRESULT hRes; - BSTR propName = NULL, val = NULL; - VARIANT pVal; - ULONG uReturned; - int result=1; - - IEnumWbemClassObject *pEnumServices = NULL; - IWbemLocator *pIWbemLocator = NULL; - HRESULT hr = S_OK; - - //------------------------ - // Create an instance of the WbemLocator interface. - if(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pIWbemLocator) == S_OK) - { - //------------------------ - // Use the pointer returned in step two to connect to - // the server using the passed in namespace. - // It is very important never to pass any string not allocated using SysAllocString to any COM function - BSTR pNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); - IWbemServices *pIWbemServices = NULL; - - if((hr = pIWbemLocator->ConnectServer(pNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices)) == S_OK) - { - CoSetProxyBlanket(pIWbemServices, - RPC_C_AUTHN_WINNT, - RPC_C_AUTHZ_NONE, - NULL, - RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, - NULL, - EOAC_NONE - ); - - BSTR className = SysAllocString(L"Win32_NetworkAdapterConfiguration"); - // Lets lookup the class first - IWbemClassObject *pClass = NULL; - if((hRes = pIWbemServices->GetObject(className, 0, NULL, &pClass, NULL)) == S_OK) - { - BSTR methodName = SysAllocString(L"EnableStatic"); - - - /** // Uncomment this debugging code to check the qualifiers of your EnableStatic method - IWbemQualifierSet *quals=NULL; - hr = pClass->GetMethodQualifierSet(methodName, &quals); - if(hr == WBEM_S_NO_ERROR) - { - BSTR qualName, qualValue; - - quals->BeginEnumeration(0); - while(quals->Next(0, &qualName, &pVal, NULL) == S_OK) - { - printf("qualifier: %ws = %ws\n", qualName, ValueToString(&pVal, &qualValue)); - } - quals->Release(); - } - */ - - IWbemClassObject * pInClass = NULL; - hr = pClass->GetMethod(methodName, 0, &pInClass, NULL); - if(hr == WBEM_S_NO_ERROR) - { - // WBEM_E_ACCESS_DENIED - //---------------------- - // execute the query. - BSTR qLang = SysAllocString(L"WQL"); - BSTR query = SysAllocString(L"select * from Win32_NetworkAdapterConfiguration where ServiceName = \"msloop\""); - if((hRes = pIWbemServices->ExecQuery(qLang, query, 0L, NULL, &pEnumServices)) == S_OK) - { - IWbemClassObject *pInstance = NULL; - - //---------------------- - // Only configure the first one; if there are multiple loopback adapters they are up to something - // and we'd rather not interfere (or this tool mistakenly installed a second one) - if(((hRes = pEnumServices->Next(5000, 1, &pInstance, &uReturned)) == S_OK) && (uReturned == 1)) - { - // Lookup the "index" (the primary key for Win32_NetworkAdapterConfiguration) - BSTR varName = SysAllocString(L"Index"); - if(S_OK == pInstance->Get(varName, 0, &pVal, NULL, NULL)) - { - // Create an instance of the input parameters of this method - IWbemClassObject * pInInst = NULL; - hr = pInClass->SpawnInstance(0, &pInInst); - if(hr == WBEM_S_NO_ERROR) - { - // Now fill that instance in with useful parameters. - BSTR ipAddressStr = SysAllocString(L"IPAddress"); - BSTR subnetMaskStr = SysAllocString(L"SubnetMask"); - BSTR loopbackIPCopy = SysAllocString(loopbackIP); - BSTR loopbackNetMaskCopy = SysAllocString(loopbackNetmask); - - // Two string arrays: one with the ip addresses, the other with subnet masks - VARIANT ipVar, maskVar; - - // Create the IP Address array and put our ip address into it - VariantInitStringArray(ipVar, loopbackIPCopy); - - // Create the subnet mask array and put our subnet mask into it - VariantInitStringArray(maskVar, loopbackNetMaskCopy); - - // Write the parameters into the params object - hr = pInInst->Put(ipAddressStr, 0, &ipVar, 0); if(hr) EasyErrorBox(hr, L"Args->Put(IPAddress) failed\n"); - hr = pInInst->Put(subnetMaskStr, 0, &maskVar, 0); if(hr) EasyErrorBox(hr, L"Args->Put(SubnetMask) failed\n"); - - /** // Uncomment this debugging code to view the parameters before the method is called - BSTR pInText=NULL; - pInInst->GetObjectText(0, &pInText); - printf("Parameters: %ws\n", pInText); - */ - - // Call the method - IWbemClassObject * pOutInst = NULL; - - // Compute the object path and copy it into a COM string - WCHAR objectPathBuf[255]; - wsprintfW(objectPathBuf, L"Win32_NetworkAdapterConfiguration.Index=%d", pVal.intVal); - BSTR objectPath = SysAllocString(objectPathBuf); - - // Go go go! - hr = pIWbemServices->ExecMethod(objectPath, methodName, 0, NULL, pInInst, &pOutInst, NULL); - if(hr == WBEM_S_NO_ERROR) - { - // Extract the return value (from the field called "ReturnValue") - VARIANT retVal; - BSTR retValName = SysAllocString(L"ReturnValue"); - hr = pOutInst->Get(retValName, 0, &retVal, 0, 0); - if(hr == WBEM_S_NO_ERROR) - { - // If it returns 1, we should reboot - if(retVal.intVal == 1) - { - *needReboot = 1; - } - else if(retVal.intVal == 0) - { - // Everything is great - } - else - { - if (retVal.intVal == 81) { // "Unable to configure DHCP"; seems to be returned superfluously sometimes - // Just print it out without bugging the user; that way admins can see it but they can also ignore it - EasyErrorBox (0, L"Failed to configure Loopback adapter: EnableStatic() returns %d: %s\n", retVal.intVal, EnableStatic_strerror(retVal.intVal)); - result = 0; - } else { - // For descriptions of these error codes try: - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/enablestatic_method_in_class_win32_networkadapterconfiguration.asp - EasyErrorBox(hr, L"Failed to configure Loopback adapter: EnableStatic() returns %d (%s)", retVal.intVal, EnableStatic_strerror(retVal.intVal)); - result = 0; - } - } - } - else - { - // This shouldn't happen, methinks - BSTR objText=NULL; - pOutInst->GetObjectText(0, &objText); - EasyErrorBox(hr, L"Successfully called EnableStatic(); result = %ws but unable to get ReturnValue\n", objText); - result = 0; - } - } - else - { - // After all that work, we still couldn't execute the method? Probably a BSTR was allocated using SysAllocString but thats just my prophesy - EasyErrorBox(hr, L"Failed to configure Loopback adapter: ExecMethod() failed\n"); - result = 0; - } - - if(pOutInst) - { - pOutInst->Release(); - pOutInst = NULL; - } - - // Release some resources; this function isn't likely to be part of a long running - // program, but I've seen stranger things. - SafeArrayDestroy(ipVar.parray); - SafeArrayDestroy(maskVar.parray); - SysFreeString(ipAddressStr); - SysFreeString(subnetMaskStr); - SysFreeString(loopbackNetMaskCopy); - SysFreeString(loopbackIPCopy); - } - else - { - EasyErrorBox(hr, L"Failed to configure Loopback adapter: Failed to Spawn an instance of the method's parameters\n"); - result = 0; - } - - if(pInInst) - { - pInInst->Release(); - pInInst = NULL; - } - } - else - { - EasyErrorBox(hr, L"Failed to configure Loopback adapter: Unable to read ServiceName\n"); - result = 0; - } - - // done with the ClassObject - if (pInstance) - { - pInstance->Release(); - pInstance = NULL; - } - - SysFreeString(varName); - - } - - // did the while loop exit due to an error? - if((hRes != S_OK) && - (hRes != 1)) - { - EasyErrorBox(hRes, L"Failed to configure Loopback adapter: pEnumServices->Next() failed %s\n"); - result = 0; - } - - if (pEnumServices) - { - pEnumServices->Release(); - pEnumServices = NULL; - } - } - else - { - EasyErrorBox(hRes, L"Failed to configure Loopback adapter: ExecQuery('%s', '%s') failed\n", qLang, query); - result = 0; - } - - SysFreeString(qLang); - SysFreeString(query); - } - else - { - EasyErrorBox(hRes, L"Failed to configure Loopback adapter: GetMethod(\"EnableStatic\") failed\n"); - result = 0; - } - - SysFreeString(methodName); - } - else - { - EasyErrorBox(hRes, L"Failed to configure Loopback adapter: GetObject(\"Win32_NetworkAdapterConfiguration\") failed\n"); - result = 0; - } - - SysFreeString(className); - } - - SysFreeString(pNamespace); - } - else - { - EasyErrorBox(GetLastError(), L"Failed to configure Loopback adapter: CoCreateInstance(CLSID_WbemLocator) failed.\n"); - result = 0; - } - - return result; -} - -class ARGS { -public: - bool bQuiet; - LPWSTR lpIPAddr; - LPWSTR lpSubnetMask; - ARGS () : bQuiet (0), lpIPAddr (0), lpSubnetMask (0) { } - ~ARGS () { - if (lpIPAddr) free (lpIPAddr); - if (lpSubnetMask) free (lpSubnetMask); - } -}; - -void wcsMallocAndCpy (LPWSTR * dst, const LPWSTR src) { - *dst = (LPWSTR) malloc ((wcslen (src) + 1) * sizeof (WCHAR)); - wcscpy (*dst, src); -} - -int process_args (LPWSTR lpCmdLine, ARGS & args) { - int i, iNumArgs; - LPWSTR * argvW; - - argvW = CommandLineToArgvW (lpCmdLine, &iNumArgs); - for (i = 0; i < iNumArgs; i++) - { - if (wcsstr (argvW[i], L"help") - || !_wcsicmp (argvW[i], L"?") - || (wcslen(argvW[i]) == 2 && argvW[i][1] == L'?')) - { - display_usage(); - GlobalFree (argvW); - return 0; - } - - if (!_wcsicmp (argvW[i], L"q") || !_wcsicmp (argvW[i], L"quiet")) { - args.bQuiet = true; - continue; - } - - if (!args.lpIPAddr) { - wcsMallocAndCpy (&args.lpIPAddr, argvW[i]); - continue; - } - - if (!args.lpSubnetMask) { - wcsMallocAndCpy (&args.lpSubnetMask, argvW[i]); - continue; - } - - display_usage(); - GlobalFree (argvW); - return 0; - } - - if (!args.lpIPAddr) - wcsMallocAndCpy (&args.lpIPAddr, DEFAULT_IPADDR); - if (!args.lpSubnetMask) - wcsMallocAndCpy (&args.lpSubnetMask, DEFAULT_SUBNETMASK); - - GlobalFree (argvW); - return 1; -} - -void display_usage() { - EasyErrorBox (0, - L"Installation utility for the MS Loopback Adapter\r\n\r\n" - L"Usage:\r\n" - L"RunDll32 loopback_install.dll doLoopBackEntry [q|quiet] [IP address] [Subnet Mask]\r\n" - L" \"Quiet\" supresses error messages\r\n" - L" \"IP address\" defaults to %s\r\n" - L" \"Subnet Mask\" defaults to %s\r\n", - DEFAULT_IPADDR, DEFAULT_SUBNETMASK); -} - -int doLoopBack (LPWSTR lpIPAddr, LPWSTR lpSubnetMask) { - int rc; - // initialize COM - // This and CoInitializeSecurity fail when running under the MSI - // engine, but there seems to be no ill effect (the security is now - // set on the specific object via CoSetProxyBlanket in loopback_configure) - if(CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED )) - { - //Don't fail (MSI install will have already initialized COM) - //EasyErrorBox(0, L"Failed to initialize COM."); - //return 1; - } - - // Initialize COM security (otherwise we'll get permission denied when we try to use WMI or NetCfg) - CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); - - int rebootNeeded = 0; - - if(loopback_isInstalled() || loopback_install(&rebootNeeded)) - { - rc = loopback_unbindmsnet(); - if (!rc) return 1; - rc = loopback_configure(&rebootNeeded, lpIPAddr, lpSubnetMask); - if (!rc) return 1; - } - - CoUninitialize(); - - if(rebootNeeded) { - EasyErrorBox(0, L"Please reboot.\n"); - return 2; - } - return 0; -} - -void CALLBACK doLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdShow) -{ - ARGS args; - - if (!process_args(lpCmdLine, args)) return; - bQuiet = args.bQuiet; // laziness - - doLoopBack (args.lpIPAddr, args.lpSubnetMask); -} - -void CALLBACK disableLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdSHow) -{ - ARGS args; - int rc; - - // initialize COM - // This and CoInitializeSecurity fail when running under the MSI - // engine, but there seems to be no ill effect (the security is now - // set on the specific object via CoSetProxyBlanket in loopback_configure) - if(CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED )) - { - //Don't fail (MSI install will have already initialized COM) - //EasyErrorBox(0, L"Failed to initialize COM."); - //return 1; - } - - // Initialize COM security (otherwise we'll get permission denied when we try to use WMI or NetCfg) - CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); - - disable_loopback(); - - CoUninitialize(); - - -} - -UINT __stdcall installLoopbackMSI (MSIHANDLE hInstall) -{ - LPWSTR szValueBuf; - DWORD cbValueBuf = 256; - ARGS args; - UINT rc; - - szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR)); - while (rc = MsiGetPropertyW(hInstall, L"CustomActionData", szValueBuf, &cbValueBuf)) { - free (szValueBuf); - if (rc == ERROR_MORE_DATA) { - cbValueBuf++; - szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR)); - } else return ERROR_INSTALL_FAILURE; - } - - if (!process_args(szValueBuf, args)) return ERROR_INSTALL_FAILURE; - - rc = doLoopBack (args.lpIPAddr, args.lpSubnetMask); - - if (rc == 1) return ERROR_INSTALL_FAILURE; - - if (rc == 2) { - MsiDoActionW (hInstall, L"ScheduleReboot"); - } - - return ERROR_SUCCESS; -} diff --git a/src/WINNT/install/NSIS/loopback_install.def b/src/WINNT/install/NSIS/loopback_install.def deleted file mode 100644 index defe319b9..000000000 --- a/src/WINNT/install/NSIS/loopback_install.def +++ /dev/null @@ -1,10 +0,0 @@ -LIBRARY LOOPBACK_INSTALL - -DESCRIPTION "Microsoft Loopback Adapter Installer for OpenAFS" - -EXPORTS - doLoopBackEntryW - disableLoopBackEntryW - loopback_isInstalled - - diff --git a/src/WINNT/install/loopback/NTMakefile b/src/WINNT/install/loopback/NTMakefile new file mode 100644 index 000000000..587052144 --- /dev/null +++ b/src/WINNT/install/loopback/NTMakefile @@ -0,0 +1,58 @@ +# rcsid : $Id$ + +RELDIR=WINNT\install\loopback +!INCLUDE ..\..\..\config\NTMakefile.$(SYS_NAME) +!INCLUDE ..\..\..\config\NTMakefile.version + +MEDIABINDIR = $(DESTDIR)\WinInstall\Config + +EXEFILE = $(MEDIABINDIR)\instloop.exe + +DLLFILE = $(MEDIABINDIR)\afsloopback.dll + +DLLEXPORTS=\ + -EXPORT:UnInstallLoopBack \ + -EXPORT:IsLoopbackInstalled \ + -EXPORT:InstallLoopBack \ + -EXPORT:doLoopBackEntryW \ + -EXPORT:uninstallLoopBackEntryW \ + -EXPORT:installLoopbackMSI + +DLLLIBFILES=\ + setupapi.lib msi.lib uuid.lib Shell32.lib ole32.lib advapi32.lib wbemuuid.lib + +LINK=link + +# afsloopback.dll + +DLLSOURCEFILES = loopbackutils.cpp renameconnection.cpp wmi.cpp +DLLOBJFILES = $(OUT)\loopbackutils.obj $(OUT)\renameconnection.obj $(OUT)\wmi.obj + +$(OUT)\loopbackutils.obj: loopbackutils.cpp + $(CPP2OBJ) -c -DUNICODE -D_UNICODE /Fo$@ $** + +$(OUT)\renameconnection.obj: renameconnection.cpp + $(CPP2OBJ) -c -DUNICODE -D_UNICODE /Fo$@ $** + +$(OUT)\wmi.obj: wmi.cpp + $(CPP2OBJ) -I$(NTDDKDIR) -c -DUNICODE -D_UNICODE /Fo$@ $** + +$(DLLFILE): $(DLLOBJFILES) + $(LINK) -DLL $(DLLEXPORTS) -OUT:$@ $(DLLOBJFILES) $(DLLLIBFILES) + +# instloop.exe + +EXESOURCEFILES = instloop.c +EXEOBJFILES = $(OUT)\instloop.obj +EXELIBFILES = $(MEDIABINDIR)\afsloopback.lib + +$(OUT)\instloop.obj: instloop.c + $(C2OBJ) -c -DUNICODE -D_UNICODE /Fo$@ $** + +$(EXEFILE): $(EXEOBJFILES) $(EXELIBFILES) + $(LINK) /OUT:$@ $(EXEOBJFILES) $(EXELIBFILES) + + +install: $(DLLFILE) $(EXEFILE) + +clean :: diff --git a/src/WINNT/install/loopback/instloop.c b/src/WINNT/install/loopback/instloop.c new file mode 100644 index 000000000..bb7427a38 --- /dev/null +++ b/src/WINNT/install/loopback/instloop.c @@ -0,0 +1,146 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +#include +#include +#define INITGUID +#include +#include +#include +#include +#include "loopbackutils.h" + +#undef REDIRECT_STDOUT + +static void +ShowUsage(void) +{ + printf("instloop [-i [name [ip mask]] | -u]\n\n"); + printf(" -i install the %s\n", DRIVER_DESC); + _tprintf(_T(" (if unspecified, uses name %s,\n"), DEFAULT_NAME); + _tprintf(_T(" ip %s, and mask %s)\n"), DEFAULT_IP, DEFAULT_MASK); + printf(" -u uninstall the %s\n", DRIVER_DESC); +} + +static void +DisplayStartup(BOOL bInstall) +{ + printf("%snstalling the %s\n" + " (Note: This may take up to a minute or two...)\n", + bInstall ? "I" : "Un", + DRIVER_DESC); + +} + +static void +DisplayResult(BOOL bInstall, DWORD rc) +{ + if (rc) + { + printf("Could not %sinstall the %s\n", bInstall ? "" : "un", + DRIVER_DESC); + SLEEP; + PAUSE; + } +} + + +int _tmain(int argc, TCHAR *argv[]) +{ + DWORD rc = 0; +#ifdef REDIRECT_STDOUT + FILE *fh = NULL; +#endif + + PAUSE; + +#ifdef REDIRECT_STDOUT + fh = freopen("instlog.txt","a+", stdout); +#endif + + if (argc > 1) + { + if (_tcsicmp(argv[1], _T("-i")) == 0) + { + TCHAR* name = DEFAULT_NAME; + TCHAR* ip = DEFAULT_IP; + TCHAR* mask = DEFAULT_MASK; + + if (argc > 2) + { + name = argv[2]; + if (argc > 3) + { + if (argc < 5) + { + ShowUsage(); +#ifdef REDIRECT_STDOUT + fflush(fh); fclose(fh); +#endif + return 1; + } + else + { + ip = argv[3]; + mask = argv[4]; + } + } + } + DisplayStartup(TRUE); + if(IsLoopbackInstalled()) { + printf("Loopback already installed\n"); + rc = 0; /* don't signal an error. */ + } else { + rc = InstallLoopBack(name, ip, mask); + } + DisplayResult(TRUE, rc); +#ifdef REDIRECT_STDOUT + fflush(fh); fclose(fh); +#endif + return rc; + } + else if (_tcsicmp(argv[1], _T("-u")) == 0) + { + DisplayStartup(FALSE); + rc = UnInstallLoopBack(); + DisplayResult(FALSE, rc); +#ifdef REDIRECT_STDOUT + fflush(fh); fclose(fh); +#endif + return rc; + } + ShowUsage(); +#ifdef REDIRECT_STDOUT + fflush(fh); fclose(fh); +#endif + return 1; + } + ShowUsage(); +#ifdef REDIRECT_STDOUT + fflush(fh); fclose(fh); +#endif + return 0; +} + diff --git a/src/WINNT/install/loopback/loopbackutils.cpp b/src/WINNT/install/loopback/loopbackutils.cpp new file mode 100644 index 000000000..e460af3a0 --- /dev/null +++ b/src/WINNT/install/loopback/loopbackutils.cpp @@ -0,0 +1,629 @@ +/* + Copyright 2004 by the Massachusetts Institute of Technology + + All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of the Massachusetts + Institute of Technology (M.I.T.) not be used in advertising or publicity + pertaining to distribution of the software without specific, written + prior permission. + + M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. +*/ + +#define _WIN32_DCOM +#include +#include +#include + +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 +#define INITGUID +#include +#include +#include +#include +#include +#include +#include +#include "loopbackutils.h" + +extern "C" DWORD UnInstallLoopBack(void) +{ + BOOL ok; + DWORD ret = 0; + GUID netGuid; + HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA DeviceInfoData; + TCHAR* deviceDesc; + DWORD index = 0; + BOOL found = FALSE; + DWORD size = 0; + + // initialize the structure size + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + // copy the net class GUID + memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); + + // return a device info set contains all installed devices of the Net class + hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT); + + if (hDeviceInfo == INVALID_HANDLE_VALUE) + return GetLastError(); + + deviceDesc = (TCHAR *)malloc(MAX_PATH*sizeof(TCHAR)); + // enumerate the driver info list + while (SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData)) + { + // try to get the DeviceDesc registry property + ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData, + SPDRP_DEVICEDESC, + NULL, (PBYTE)deviceDesc, + MAX_PATH * sizeof(TCHAR), &size); + if (!ok) + { + ret = GetLastError(); + if (ret != ERROR_INSUFFICIENT_BUFFER) + break; + // if the buffer is too small, reallocate + free(deviceDesc); + deviceDesc = (TCHAR *)malloc(size); + ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, + &DeviceInfoData, + SPDRP_DEVICEDESC, + NULL, (PBYTE)deviceDesc, + size, NULL); + if (!ok) + break; + } + + // case insensitive comparison + _tcslwr(deviceDesc); + if( _tcsstr(deviceDesc, DRIVER)) + { + found = TRUE; + break; + } + + index++; + } + + free(deviceDesc); + + if (found == FALSE) + { + ret = GetLastError(); + printf("The %s does not seem to be installed\n", DRIVER_DESC); + goto cleanup; + } + + ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + ok = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + +cleanup: + // clean up the device info set + if (hDeviceInfo != INVALID_HANDLE_VALUE) + SetupDiDestroyDeviceInfoList(hDeviceInfo); + + return ret; +} + +BOOL IsLoopbackInstalled(void) +{ + TCHAR * hwid = _T("*MSLOOP"); + HDEVINFO DeviceInfoSet; + SP_DEVINFO_DATA DeviceInfoData; + DWORD i,err; + BOOL found; + + // + // Create a Device Information Set with all present devices. + // + DeviceInfoSet = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system + if (DeviceInfoSet == INVALID_HANDLE_VALUE) + { + return FALSE; // nothing installed? + } + + // + // Enumerate through all Devices. + // + found = FALSE; + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++) + { + DWORD DataT; + TCHAR *p, *buffer = NULL; + DWORD buffersize = 0; + + // + // We won't know the size of the HardwareID buffer until we call + // this function. So call it with a null to begin with, and then + // use the required buffer size to Alloc the nessicary space. + // Keep calling we have success or an unknown failure. + // + while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,&DataT,(PBYTE)buffer,buffersize,&buffersize)) + { + if (GetLastError() == ERROR_INVALID_DATA) + { + // May be a Legacy Device with no hwid. Continue. + break; + } + else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + // We need to change the buffer size. + if (buffer) + LocalFree(buffer); + buffer = (TCHAR *)LocalAlloc(LPTR,buffersize); + } + else + { + goto cleanup_DeviceInfo; + } + } + + if (GetLastError() == ERROR_INVALID_DATA) + continue; + + // Compare each entry in the buffer multi-sz list with our hwid. + for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1) + { + if (!_tcsicmp(hwid,p)) + { + found = TRUE; + break; + } + } + + if (buffer) LocalFree(buffer); + if (found) break; + } + + // Cleanup. +cleanup_DeviceInfo: + err = GetLastError(); + SetupDiDestroyDeviceInfoList(DeviceInfoSet); + SetLastError(err); + + return found; +} + + +extern "C" DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask) +{ + BOOL ok; + DWORD ret = 0; + GUID netGuid; + HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA DeviceInfoData; + SP_DRVINFO_DATA DriverInfoData; + SP_DEVINSTALL_PARAMS DeviceInstallParams; + TCHAR className[MAX_PATH]; + TCHAR temp[MAX_PATH]; + DWORD index = 0; + BOOL found = FALSE; + BOOL registered = FALSE; + BOOL destroyList = FALSE; + + HKEY hkey = NULL; + DWORD cbSize; + DWORD dwValueType; + TCHAR pCfgGuidString[40]; + + // initialize the structure size + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); + + // copy the net class GUID + memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); + + // create an empty device info set associated with the net class GUID + hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL); + if (hDeviceInfo == INVALID_HANDLE_VALUE) + return GetLastError(); + + // get the class name from GUID + ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + // create a device info element and add the new device instance + // key to registry + ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL, + DICD_GENERATE_ID, &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + // select the newly created device info to be the currently + // selected member + ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + // build a list of class drivers + ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData, + SPDIT_CLASSDRIVER); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + destroyList = TRUE; + + // enumerate the driver info list + while (SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData, + SPDIT_CLASSDRIVER, index, &DriverInfoData)) + { + // if the manufacture is microsoft + if (_tcsicmp(DriverInfoData.MfgName, MANUFACTURE) == 0) + { + // case insensitive search for loopback + _tcscpy(temp, DriverInfoData.Description); + _tcslwr(temp); + if( _tcsstr(temp, DRIVER)) + { + found = TRUE; + break; + } + } + index++; + } + + if (!found) + { + ret = GetLastError(); + printf("Could not find the %s driver to install\n", DRIVER_DESC); + goto cleanup; + } + + // set the loopback driver to be the currently selected + ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData, + &DriverInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + // register the phantom device to repare for install + ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo, + &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + // registered, but remove if errors occur in the following code + registered = TRUE; + + // ask the installer if we can install the device + ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo, + &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + if (ret != ERROR_DI_DO_DEFAULT) + { + goto cleanup; + } + else + ret = 0; + } + + // install the files first + ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo, + &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + // get the device install parameters and disable filecopy + DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); + ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (ok) + { + DeviceInstallParams.Flags |= DI_NOFILECOPY; + ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + } + + // + // Register any device-specific co-installers for this device, + // + + ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, + hDeviceInfo, + &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + + // + // install any installer-specified interfaces. + // and then do the real install + // + ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, + hDeviceInfo, + &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + goto cleanup; + } + PAUSE; + ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE, + hDeviceInfo, + &DeviceInfoData); + if (!ok) + { + ret = GetLastError(); + PAUSE; + goto cleanup; + } + + /* Skip to the end if we aren't setting the name */ + if (!pConnectionName) goto cleanup; + + // Figure out NetCfgInstanceId + hkey = SetupDiOpenDevRegKey(hDeviceInfo, + &DeviceInfoData, + DICS_FLAG_GLOBAL, + 0, + DIREG_DRV, + KEY_READ); + if (hkey == INVALID_HANDLE_VALUE) + { + ret = GetLastError(); + goto cleanup; + } + + cbSize = sizeof(pCfgGuidString); + ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL, + &dwValueType, (LPBYTE)pCfgGuidString, &cbSize); + RegCloseKey(hkey); + + ret = RenameConnection(pCfgGuidString, pConnectionName); + if (ret) + { + printf("Could not set the connection name to \"%S\"\n", + pConnectionName); + goto cleanup; + } + + if (!ip) goto cleanup; + ret = SetIpAddress(pCfgGuidString, ip, mask); + if (ret) + { + printf("Could not set the ip address and network mask\n"); + goto cleanup; + } + ret = LoopbackBindings(pCfgGuidString); + if (ret) + { + printf("Could not properly set the bindings\n"); + goto cleanup; + } + ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE ); + if (ret) + { + printf("Could not update hosts file\n"); + goto cleanup; + } + ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE ); + if (ret) + { + printf("Could not update lmhosts file\n"); + goto cleanup; + } + + +cleanup: + // an error has occured, but the device is registered, we must remove it + if (ret != 0 && registered) + SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); + + found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData); + + // destroy the driver info list + if (destroyList) + SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData, + SPDIT_CLASSDRIVER); + // clean up the device info set + if (hDeviceInfo != INVALID_HANDLE_VALUE) + SetupDiDestroyDeviceInfoList(hDeviceInfo); + + return ret; +}; + +/* The following functions provide the RunDll32 interface + * RunDll32 loopback_install.dll doLoopBackEntry [Interface Name] [IP address] [Subnet Mask] + */ + +static void wcsMallocAndCpy (LPWSTR * dst, const LPWSTR src) { + *dst = (LPWSTR) malloc ((wcslen (src) + 1) * sizeof (WCHAR)); + wcscpy (*dst, src); +} + +static void display_usage() +{ + MessageBoxW( NULL, + L"Installation utility for the MS Loopback Adapter\r\n\r\n" + L"Usage:\r\n" + L"RunDll32 loopback_install.dll doLoopBackEntry [q|quiet] [Connection Name] [IP address] [Submask]\r\n", + L"loopback_install", MB_ICONINFORMATION | MB_OK ); +} + +static int process_args (LPWSTR lpCmdLine, Args & args) { + int i, iNumArgs; + LPWSTR * argvW; + + argvW = CommandLineToArgvW (lpCmdLine, &iNumArgs); + for (i = 0; i < iNumArgs; i++) + { + if (wcsstr (argvW[i], L"help") + || !_wcsicmp (argvW[i], L"?") + || (wcslen(argvW[i]) == 2 && argvW[i][1] == L'?')) + { + display_usage(); + GlobalFree (argvW); + return 0; + } + + if (!_wcsicmp (argvW[i], L"q") || !_wcsicmp (argvW[i], L"quiet")) { + args.bQuiet = true; + continue; + } + + if (!args.lpConnectionName) { + wcsMallocAndCpy (&args.lpConnectionName, argvW[i]); + continue; + } + + if (!args.lpIPAddr) { + wcsMallocAndCpy (&args.lpIPAddr, argvW[i]); + continue; + } + + if (!args.lpSubnetMask) { + wcsMallocAndCpy (&args.lpSubnetMask, argvW[i]); + continue; + } + + display_usage(); + GlobalFree (argvW); + return 0; + } + + if (!args.lpConnectionName) + wcsMallocAndCpy (&args.lpConnectionName, DEFAULT_NAME); + if (!args.lpIPAddr) + wcsMallocAndCpy (&args.lpIPAddr, DEFAULT_IP); + if (!args.lpSubnetMask) + wcsMallocAndCpy (&args.lpSubnetMask, DEFAULT_MASK); + + GlobalFree (argvW); + return 1; +} + +void CALLBACK doLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdShow) +{ + Args args; + + if (!process_args(lpCmdLine, args)) + return; + + InstallLoopBack(args.lpConnectionName, args.lpIPAddr, args.lpSubnetMask); +} + +void CALLBACK uninstallLoopBackEntryW (HWND hwnd, HINSTANCE hinst, LPWSTR lpCmdLine, int nCmdSHow) +{ + Args args; + + // initialize COM + // This and CoInitializeSecurity fail when running under the MSI + // engine, but there seems to be no ill effect (the security is now + // set on the specific object via CoSetProxyBlanket in loopback_configure) + if(CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED )) + { + //Don't fail (MSI install will have already initialized COM) + //EasyErrorBox(0, L"Failed to initialize COM."); + //return 1; + } + + // Initialize COM security (otherwise we'll get permission denied when we try to use WMI or NetCfg) + CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); + + UnInstallLoopBack(); + + CoUninitialize(); +} + +/* And an MSI installer interface */ + +UINT __stdcall installLoopbackMSI (MSIHANDLE hInstall) +{ + LPWSTR szValueBuf; + DWORD cbValueBuf = 256; + Args args; + UINT rc; + + szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR)); + while (rc = MsiGetPropertyW(hInstall, L"CustomActionData", szValueBuf, &cbValueBuf)) { + free (szValueBuf); + if (rc == ERROR_MORE_DATA) { + cbValueBuf++; + szValueBuf = (LPWSTR) malloc (cbValueBuf * sizeof (WCHAR)); + } + else + return ERROR_INSTALL_FAILURE; + } + + if (!process_args(szValueBuf, args)) + return ERROR_INSTALL_FAILURE; + + rc = InstallLoopBack (args.lpConnectionName, args.lpIPAddr, args.lpSubnetMask); + + if (rc == 1) + return ERROR_INSTALL_FAILURE; + + if (rc == 2) { + MsiDoActionW (hInstall, L"ScheduleReboot"); + } + + return ERROR_SUCCESS; +} + diff --git a/src/WINNT/install/loopback/loopbackutils.h b/src/WINNT/install/loopback/loopbackutils.h new file mode 100644 index 000000000..1a763d1eb --- /dev/null +++ b/src/WINNT/install/loopback/loopbackutils.h @@ -0,0 +1,65 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +#ifdef __cplusplus +extern "C" { +#endif +DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask); +BOOL IsLoopbackInstalled(void); +DWORD UnInstallLoopBack(void); +int RenameConnection(PCWSTR GuidString, PCWSTR pszNewName); +DWORD SetIpAddress(LPCWSTR guid, LPCWSTR ip, LPCWSTR mask); +HRESULT LoopbackBindings (LPCWSTR loopback_guid); +BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre ); +#ifdef __cplusplus +} +#endif + +#define DRIVER_DESC "Microsoft Loopback Adapter" +#define DRIVER _T("loopback") +#define MANUFACTURE _T("microsoft") +#define DEFAULT_NAME _T("AFS") +#define DEFAULT_IP _T("10.254.254.253") +#define DEFAULT_MASK _T("255.255.255.252") + +#ifdef USE_PAUSE +#define PAUSE \ + do { \ + char c; \ + printf("PAUSED - PRESS ENTER TO CONTINUE\n"); \ + scanf("%c", &c); \ + } while(0) +#else +#define PAUSE +#endif + +/*#define USE_SLEEP*/ + +#ifdef USE_SLEEP +#define SLEEP Sleep(10*1000) +#else +#define SLEEP +#endif + diff --git a/src/WINNT/install/loopback/renameconnection.cpp b/src/WINNT/install/loopback/renameconnection.cpp new file mode 100644 index 000000000..404687122 --- /dev/null +++ b/src/WINNT/install/loopback/renameconnection.cpp @@ -0,0 +1,119 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include + +#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(&pShellFolder)); + } + // Parse the display name. + if (SUCCEEDED(hr)) + { + hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL, + &pidl, NULL); + } + if (SUCCEEDED(hr)) + { + hr = pShellFolder->SetNameOf(NULL, pidl, wNewName, SHGDN_NORMAL, + &pidl); + pShellMalloc->Free(pidl); + } + CoUninitialize(); + return hr; +} + +extern "C" int RenameConnection(PCWSTR GuidString, PCWSTR NewName) +{ + typedef HRESULT (WINAPI *lpHrRenameConnection)(const GUID *, PCWSTR); + lpHrRenameConnection RenameConnectionFunc = NULL; + HRESULT status; + + // First try the IShellFolder interface, which was unimplemented + // for the network connections folder before XP. + status = rename_shellfolder(GuidString, NewName); + if (status == E_NOTIMPL) + { + // The IShellFolder interface is not implemented on this platform. + // Try the (undocumented) HrRenameConnection API in the netshell + // library. + CLSID clsid; + HINSTANCE hNetShell; + status = CLSIDFromString((LPOLESTR) GuidString, &clsid); + if (FAILED(status)) + return -1; + hNetShell = LoadLibrary(NETSHELL_LIBRARY); + if (hNetShell == NULL) + return -1; + RenameConnectionFunc = + (lpHrRenameConnection) GetProcAddress(hNetShell, + "HrRenameConnection"); + if (RenameConnectionFunc == NULL) + { + FreeLibrary(hNetShell); + return -1; + } + status = RenameConnectionFunc(&clsid, NewName); + FreeLibrary(hNetShell); + } + if (FAILED(status)) + return -1; + return 0; +} diff --git a/src/WINNT/install/loopback/wmi.cpp b/src/WINNT/install/loopback/wmi.cpp new file mode 100644 index 000000000..9848155d5 --- /dev/null +++ b/src/WINNT/install/loopback/wmi.cpp @@ -0,0 +1,805 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +//************************************************************************** +// +// Description: +// +// Call EnableStatic method of Win32_NetworkAdapterConfiguration +// for some network adapter GUID. +// +// Note: +// +// The EnableStatic method is notsupported on Win9x platforms. +// +//************************************************************************** + +#define _WIN32_DCOM +#include +#include +#include +#include + +#include + +/* These two are from the Windows DDK */ +#include +#include + +#include +//#include + +//#ifndef TEST +//inline void printf(char*, ...) {} +//#else +#include +//#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 + diff --git a/src/WINNT/install/wix/config.wxi b/src/WINNT/install/wix/config.wxi index 9529478fc..a01c38948 100644 --- a/src/WINNT/install/wix/config.wxi +++ b/src/WINNT/install/wix/config.wxi @@ -20,7 +20,8 @@ Directory specs: (all dir. specs end in a '\') - MediaBinDir : Installer binaries (instloop.exe etc.) + MediaDllDir : Installer Dlls + MediaBinDir : Installer Exes SrcDir : openafs\src\ DestDir : $(DEST)\ BinDir : $(DEST)\bin\ @@ -107,8 +108,11 @@ + + + - + diff --git a/src/WINNT/install/wix/custom/NTMakefile b/src/WINNT/install/wix/custom/NTMakefile index 38b6b8630..7c37a0d55 100644 --- a/src/WINNT/install/wix/custom/NTMakefile +++ b/src/WINNT/install/wix/custom/NTMakefile @@ -6,8 +6,6 @@ RELDIR=WINNT\install\wix\custom MEDIABINDIR = $(DESTDIR)\WinInstall\Dll -EXEFILE = $(MEDIABINDIR)\instloop.exe - DLLFILE = $(MEDIABINDIR)\afscustom.dll DLLEXPORTS=\ @@ -32,25 +30,6 @@ $(DLLFILE): $(OUT)\afscustom.obj $(LINK) -DLL $(DLLEXPORTS) \ -OUT:$@ $** $(DLLLIBFILES) -# instloop.exe - -SOURCEFILES = instloop.c renameconnection.cpp wmi.cpp -OBJFILES = $(OUT)\instloop.obj $(OUT)\renameconnection.obj $(OUT)\wmi.obj -EXELIBFILES = setupapi.lib msi.lib uuid.lib Shell32.lib ole32.lib advapi32.lib wbemuuid.lib - -$(OUT)\instloop.obj: instloop.c - $(CC) -ML -c -DUNICODE -D_UNICODE /Fo$@ $** - -$(OUT)\renameconnection.obj: renameconnection.cpp - $(CC) -ML -c -DUNICODE -D_UNICODE /Fo$@ $** - -$(OUT)\wmi.obj: wmi.cpp - $(CC) -I$(NTDDKDIR) -ML -c -DUNICODE -D_UNICODE /Fo$@ $** - -$(EXEFILE): $(OBJFILES) - $(LINK) /OUT:$@ $(OBJFILES) $(EXELIBFILES) - - -install: $(EXEFILE) $(DLLFILE) +install: $(DLLFILE) clean :: diff --git a/src/WINNT/install/wix/custom/instloop.c b/src/WINNT/install/wix/custom/instloop.c deleted file mode 100644 index 5efc20285..000000000 --- a/src/WINNT/install/wix/custom/instloop.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - -Copyright 2004 by the Massachusetts Institute of Technology - -All rights reserved. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of the Massachusetts -Institute of Technology (M.I.T.) not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. - -M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -*/ - -#include -#include -#define INITGUID -#include -#include -#include -#include - -#undef REDIRECT_STDOUT - -#ifdef USE_PAUSE -#define PAUSE \ - do { \ - char c; \ - printf("PAUSED - PRESS ENTER TO CONTINUE\n"); \ - scanf("%c", &c); \ - } while(0) -#else -#define PAUSE -#endif - -/*#define USE_SLEEP*/ - -#ifdef USE_SLEEP -#define SLEEP Sleep(10*1000) -#else -#define SLEEP -#endif - - -static void ShowUsage(void); -DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask); -DWORD UnInstallLoopBack(void); -int RenameConnection(PCWSTR GuidString, PCWSTR pszNewName); -DWORD SetIpAddress(LPCWSTR guid, LPCWSTR ip, LPCWSTR mask); -HRESULT LoopbackBindings (LPCWSTR loopback_guid); -BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre ); - -#define DRIVER_DESC "Microsoft Loopback Adapter" -#define DRIVER _T("loopback") -#define MANUFACTURE _T("microsoft") -#define DEFAULT_NAME _T("AFS") -#define DEFAULT_IP _T("10.254.254.253") -#define DEFAULT_MASK _T("255.255.255.252") - -static void -ShowUsage(void) -{ - printf("instloop [-i [name [ip mask]] | -u]\n\n"); - printf(" -i install the %s\n", DRIVER_DESC); - _tprintf(_T(" (if unspecified, uses name %s,\n"), DEFAULT_NAME); - _tprintf(_T(" ip %s, and mask %s)\n"), DEFAULT_IP, DEFAULT_MASK); - printf(" -u uninstall the %s\n", DRIVER_DESC); -} - -static void -DisplayStartup(BOOL bInstall) -{ - printf("%snstalling the %s\n" - " (Note: This may take up to a minute or two...)\n", - bInstall ? "I" : "Un", - DRIVER_DESC); - -} - -static void -DisplayResult(BOOL bInstall, DWORD rc) -{ - if (rc) - { - printf("Could not %sinstall the %s\n", bInstall ? "" : "un", - DRIVER_DESC); - SLEEP; - PAUSE; - } -} - - -int _tmain(int argc, TCHAR *argv[]) -{ - DWORD rc = 0; -#ifdef REDIRECT_STDOUT - FILE *fh = NULL; -#endif - - PAUSE; - -#ifdef REDIRECT_STDOUT - fh = freopen("instlog.txt","a+", stdout); -#endif - - if (argc > 1) - { - if (_tcsicmp(argv[1], _T("-i")) == 0) - { - TCHAR* name = DEFAULT_NAME; - TCHAR* ip = DEFAULT_IP; - TCHAR* mask = DEFAULT_MASK; - - if (argc > 2) - { - name = argv[2]; - if (argc > 3) - { - if (argc < 5) - { - ShowUsage(); -#ifdef REDIRECT_STDOUT - fflush(fh); fclose(fh); -#endif - return 1; - } - else - { - ip = argv[3]; - mask = argv[4]; - } - } - } - DisplayStartup(TRUE); - if(IsLoopbackInstalled()) { - printf("Loopback already installed\n"); - rc = 0; /* don't signal an error. */ - } else { - rc = InstallLoopBack(name, ip, mask); - } - DisplayResult(TRUE, rc); -#ifdef REDIRECT_STDOUT - fflush(fh); fclose(fh); -#endif - return rc; - } - else if (_tcsicmp(argv[1], _T("-u")) == 0) - { - DisplayStartup(FALSE); - rc = UnInstallLoopBack(); - DisplayResult(FALSE, rc); -#ifdef REDIRECT_STDOUT - fflush(fh); fclose(fh); -#endif - return rc; - } - ShowUsage(); -#ifdef REDIRECT_STDOUT - fflush(fh); fclose(fh); -#endif - return 1; - } - ShowUsage(); -#ifdef REDIRECT_STDOUT - fflush(fh); fclose(fh); -#endif - return 0; -} - - -DWORD UnInstallLoopBack(void) -{ - BOOL ok; - DWORD ret = 0; - GUID netGuid; - HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; - SP_DEVINFO_DATA DeviceInfoData; - TCHAR* deviceDesc; - DWORD index = 0; - BOOL found = FALSE; - DWORD size = 0; - - // initialize the structure size - DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - - // copy the net class GUID - memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); - - // return a device info set contains all installed devices of the Net class - hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT); - - if (hDeviceInfo == INVALID_HANDLE_VALUE) - return GetLastError(); - - deviceDesc = malloc(MAX_PATH*sizeof(TCHAR)); - // enumerate the driver info list - while (SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData)) - { - // try to get the DeviceDesc registry property - ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData, - SPDRP_DEVICEDESC, - NULL, (PBYTE)deviceDesc, - MAX_PATH * sizeof(TCHAR), &size); - if (!ok) - { - ret = GetLastError(); - if (ret != ERROR_INSUFFICIENT_BUFFER) - break; - // if the buffer is too small, reallocate - free(deviceDesc); - deviceDesc = malloc(size); - ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, - &DeviceInfoData, - SPDRP_DEVICEDESC, - NULL, (PBYTE)deviceDesc, - size, NULL); - if (!ok) - break; - } - - // case insensitive comparison - _tcslwr(deviceDesc); - if( _tcsstr(deviceDesc, DRIVER)) - { - found = TRUE; - break; - } - - index++; - } - - free(deviceDesc); - - if (found == FALSE) - { - ret = GetLastError(); - printf("The %s does not seem to be installed\n", DRIVER_DESC); - goto cleanup; - } - - ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - ok = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - -cleanup: - // clean up the device info set - if (hDeviceInfo != INVALID_HANDLE_VALUE) - SetupDiDestroyDeviceInfoList(hDeviceInfo); - - return ret; -} - -BOOL IsLoopbackInstalled() -{ - TCHAR * hwid = _T("*MSLOOP"); - HDEVINFO DeviceInfoSet; - SP_DEVINFO_DATA DeviceInfoData; - DWORD i,err; - BOOL found; - - // - // Create a Device Information Set with all present devices. - // - DeviceInfoSet = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system - if (DeviceInfoSet == INVALID_HANDLE_VALUE) - { - return FALSE; // nothing installed? - } - - // - // Enumerate through all Devices. - // - found = FALSE; - DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for (i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++) - { - DWORD DataT; - TCHAR *p, *buffer = NULL; - DWORD buffersize = 0; - - // - // We won't know the size of the HardwareID buffer until we call - // this function. So call it with a null to begin with, and then - // use the required buffer size to Alloc the nessicary space. - // Keep calling we have success or an unknown failure. - // - while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,&DataT,(PBYTE)buffer,buffersize,&buffersize)) - { - if (GetLastError() == ERROR_INVALID_DATA) - { - // May be a Legacy Device with no hwid. Continue. - break; - } - else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - // We need to change the buffer size. - if (buffer) - LocalFree(buffer); - buffer = (TCHAR *)LocalAlloc(LPTR,buffersize); - } - else - { - goto cleanup_DeviceInfo; - } - } - - if (GetLastError() == ERROR_INVALID_DATA) - continue; - - // Compare each entry in the buffer multi-sz list with our hwid. - for (p=buffer; *p && (p < &buffer[buffersize]); p += _tcslen(p)+1) - { - if (!_tcsicmp(hwid,p)) - { - found = TRUE; - break; - } - } - - if (buffer) LocalFree(buffer); - if (found) break; - } - - // Cleanup. -cleanup_DeviceInfo: - err = GetLastError(); - SetupDiDestroyDeviceInfoList(DeviceInfoSet); - SetLastError(err); - - return found; -} - - -DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask) -{ - BOOL ok; - DWORD ret = 0; - GUID netGuid; - HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; - SP_DEVINFO_DATA DeviceInfoData; - SP_DRVINFO_DATA DriverInfoData; - SP_DEVINSTALL_PARAMS DeviceInstallParams; - TCHAR className[MAX_PATH]; - TCHAR temp[MAX_PATH]; - DWORD index = 0; - BOOL found = FALSE; - BOOL registered = FALSE; - BOOL destroyList = FALSE; - - HKEY hkey = NULL; - DWORD cbSize; - DWORD dwValueType; - TCHAR pCfgGuidString[40]; - - // initialize the structure size - DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); - - // copy the net class GUID - memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); - - // create an empty device info set associated with the net class GUID - hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL); - if (hDeviceInfo == INVALID_HANDLE_VALUE) - return GetLastError(); - - // get the class name from GUID - ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - // create a device info element and add the new device instance - // key to registry - ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL, - DICD_GENERATE_ID, &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - // select the newly created device info to be the currently - // selected member - ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - // build a list of class drivers - ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData, - SPDIT_CLASSDRIVER); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - destroyList = TRUE; - - // enumerate the driver info list - while (SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData, - SPDIT_CLASSDRIVER, index, &DriverInfoData)) - { - // if the manufacture is microsoft - if (_tcsicmp(DriverInfoData.MfgName, MANUFACTURE) == 0) - { - // case insensitive search for loopback - _tcscpy(temp, DriverInfoData.Description); - _tcslwr(temp); - if( _tcsstr(temp, DRIVER)) - { - found = TRUE; - break; - } - } - index++; - } - - if (!found) - { - ret = GetLastError(); - printf("Could not find the %s driver to install\n", DRIVER_DESC); - goto cleanup; - } - - // set the loopback driver to be the currently selected - ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData, - &DriverInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - // register the phantom device to repare for install - ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - // registered, but remove if errors occur in the following code - registered = TRUE; - - // ask the installer if we can install the device - ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - if (ret != ERROR_DI_DO_DEFAULT) - { - goto cleanup; - } - else - ret = 0; - } - - // install the files first - ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - // get the device install parameters and disable filecopy - DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); - ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if (ok) - { - DeviceInstallParams.Flags |= DI_NOFILECOPY; - ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - } - - // - // Register any device-specific co-installers for this device, - // - - ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, - hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - - // - // install any installer-specified interfaces. - // and then do the real install - // - ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, - hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - goto cleanup; - } - PAUSE; - ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE, - hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - ret = GetLastError(); - PAUSE; - goto cleanup; - } - - /* Skip to the end if we aren't setting the name */ - if (!pConnectionName) goto cleanup; - - // Figure out NetCfgInstanceId - hkey = SetupDiOpenDevRegKey(hDeviceInfo, - &DeviceInfoData, - DICS_FLAG_GLOBAL, - 0, - DIREG_DRV, - KEY_READ); - if (hkey == INVALID_HANDLE_VALUE) - { - ret = GetLastError(); - goto cleanup; - } - - cbSize = sizeof(pCfgGuidString); - ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL, - &dwValueType, (LPBYTE)pCfgGuidString, &cbSize); - RegCloseKey(hkey); - - ret = RenameConnection(pCfgGuidString, pConnectionName); - if (ret) - { - printf("Could not set the connection name to \"%S\"\n", - pConnectionName); - goto cleanup; - } - - if (!ip) goto cleanup; - ret = SetIpAddress(pCfgGuidString, ip, mask); - if (ret) - { - printf("Could not set the ip address and network mask\n"); - goto cleanup; - } - ret = LoopbackBindings(pCfgGuidString); - if (ret) - { - printf("Could not properly set the bindings\n"); - goto cleanup; - } - ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE ); - if (ret) - { - printf("Could not update hosts file\n"); - goto cleanup; - } - ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE ); - if (ret) - { - printf("Could not update lmhosts file\n"); - goto cleanup; - } - - -cleanup: - // an error has occured, but the device is registered, we must remove it - if (ret != 0 && registered) - SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); - - found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData); - - // destroy the driver info list - if (destroyList) - SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData, - SPDIT_CLASSDRIVER); - // clean up the device info set - if (hDeviceInfo != INVALID_HANDLE_VALUE) - SetupDiDestroyDeviceInfoList(hDeviceInfo); - - return ret; -} diff --git a/src/WINNT/install/wix/custom/renameconnection.cpp b/src/WINNT/install/wix/custom/renameconnection.cpp deleted file mode 100644 index 404687122..000000000 --- a/src/WINNT/install/wix/custom/renameconnection.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - -Copyright 2004 by the Massachusetts Institute of Technology - -All rights reserved. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of the Massachusetts -Institute of Technology (M.I.T.) not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. - -M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -*/ - -#include -#include -#include -#include -#include -#include - -#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(&pShellFolder)); - } - // Parse the display name. - if (SUCCEEDED(hr)) - { - hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL, - &pidl, NULL); - } - if (SUCCEEDED(hr)) - { - hr = pShellFolder->SetNameOf(NULL, pidl, wNewName, SHGDN_NORMAL, - &pidl); - pShellMalloc->Free(pidl); - } - CoUninitialize(); - return hr; -} - -extern "C" int RenameConnection(PCWSTR GuidString, PCWSTR NewName) -{ - typedef HRESULT (WINAPI *lpHrRenameConnection)(const GUID *, PCWSTR); - lpHrRenameConnection RenameConnectionFunc = NULL; - HRESULT status; - - // First try the IShellFolder interface, which was unimplemented - // for the network connections folder before XP. - status = rename_shellfolder(GuidString, NewName); - if (status == E_NOTIMPL) - { - // The IShellFolder interface is not implemented on this platform. - // Try the (undocumented) HrRenameConnection API in the netshell - // library. - CLSID clsid; - HINSTANCE hNetShell; - status = CLSIDFromString((LPOLESTR) GuidString, &clsid); - if (FAILED(status)) - return -1; - hNetShell = LoadLibrary(NETSHELL_LIBRARY); - if (hNetShell == NULL) - return -1; - RenameConnectionFunc = - (lpHrRenameConnection) GetProcAddress(hNetShell, - "HrRenameConnection"); - if (RenameConnectionFunc == NULL) - { - FreeLibrary(hNetShell); - return -1; - } - status = RenameConnectionFunc(&clsid, NewName); - FreeLibrary(hNetShell); - } - if (FAILED(status)) - return -1; - return 0; -} diff --git a/src/WINNT/install/wix/custom/wmi.cpp b/src/WINNT/install/wix/custom/wmi.cpp deleted file mode 100644 index 9848155d5..000000000 --- a/src/WINNT/install/wix/custom/wmi.cpp +++ /dev/null @@ -1,805 +0,0 @@ -/* - -Copyright 2004 by the Massachusetts Institute of Technology - -All rights reserved. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of the Massachusetts -Institute of Technology (M.I.T.) not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. - -M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -*/ - -//************************************************************************** -// -// Description: -// -// Call EnableStatic method of Win32_NetworkAdapterConfiguration -// for some network adapter GUID. -// -// Note: -// -// The EnableStatic method is notsupported on Win9x platforms. -// -//************************************************************************** - -#define _WIN32_DCOM -#include -#include -#include -#include - -#include - -/* These two are from the Windows DDK */ -#include -#include - -#include -//#include - -//#ifndef TEST -//inline void printf(char*, ...) {} -//#else -#include -//#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 - diff --git a/src/WINNT/install/wix/openafs.wxs b/src/WINNT/install/wix/openafs.wxs index 871ba41fe..03560a77d 100644 --- a/src/WINNT/install/wix/openafs.wxs +++ b/src/WINNT/install/wix/openafs.wxs @@ -63,7 +63,7 @@ src="$(var.MediaBinDir)instloop.exe"/> + src="$(var.MediaDllDir)afscustom.dll"/>