3 Copyright 2004 by the Massachusetts Institute of Technology
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the name of the Massachusetts
12 Institute of Technology (M.I.T.) not be used in advertising or publicity
13 pertaining to distribution of the software without specific, written
16 M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
18 M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
19 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 //**************************************************************************
30 // Call EnableStatic method of Win32_NetworkAdapterConfiguration
31 // for some network adapter GUID.
35 // The EnableStatic method is notsupported on Win9x platforms.
37 //**************************************************************************
47 /* These two are from the Windows DDK */
52 //#include <objbase.h>
55 //inline void printf(char*, ...) {}
60 #define CLEANUP_ON_FAILURE(hr) \
61 do { if (!SUCCEEDED(hr)) goto cleanup; } while (0)
63 #define CLEANUP_ON_AND_SET(check, var, value) \
64 do { if (check) { (var) = (value); goto cleanup; } } while (0)
66 #define ETCDIR "\\drivers\\etc"
71 DWORD AdjustMaxLana(DWORD dwMaxLana);
75 (*FindNetworkAdapterConfigurationInstance_t)(
77 IN IWbemServices *pSvc,
82 FindNetworkAdapterConfigurationInstanceByGUID(
84 IN IWbemServices *pSvc,
92 IEnumWbemClassObject* pEnum = 0;
93 IWbemClassObject* pObj = 0;
96 LPCWSTR adapter_guid = (LPCWSTR)pContext;
99 if (!pPath || !adapter_guid || *pPath)
104 // Query for all network adapters
105 Language = SysAllocString(L"WQL");
106 Query = SysAllocString(L"select * from Win32_NetworkAdapterConfiguration");
109 hr = pSvc->ExecQuery(Language,
111 WBEM_FLAG_FORWARD_ONLY, // Flags
116 printf("ExecQuery() error (0x%08X)\n", hr);
120 // Retrieve the objects in the result set.
125 hr = pEnum->Next(0, // Time out
129 CLEANUP_ON_FAILURE(hr);
135 hr = pObj->Get(L"SettingID", // property name
137 &Value, // output to this variant
140 CLEANUP_ON_FAILURE(hr);
142 bFound = !wcscmp(adapter_guid, V_BSTR(&Value));
146 printf("Found adapter: %S\n", V_BSTR(&Value));
147 VariantClear(&Value);
148 hr = pObj->Get(L"__RELPATH", // property name
150 &Value, // output to this variant
153 CLEANUP_ON_FAILURE(hr);
155 *pPath = SysAllocString(V_BSTR(&Value));
159 VariantClear(&Value);
163 pObj->Release(); // Release objects not owned.
170 SysFreeString(Query);
171 SysFreeString(Language);
172 VariantClear(&Value);
178 return *pPath ? 0 : ( SUCCEEDED(hr) ? WBEM_E_NOT_FOUND : hr );
182 SetupStringAsSafeArray(LPCWSTR s, VARIANT* v)
186 SAFEARRAY* array = 0;
189 if (V_VT(v) != VT_EMPTY)
192 b = SysAllocString(s);
193 CLEANUP_ON_AND_SET(!b, hr, E_OUTOFMEMORY);
195 array = SafeArrayCreateVector(VT_BSTR, 0, 1);
196 CLEANUP_ON_AND_SET(!array, hr, E_OUTOFMEMORY);
198 hr = SafeArrayPutElement(array, index, b);
199 CLEANUP_ON_FAILURE(hr);
201 V_VT(v) = VT_ARRAY|VT_BSTR;
210 SafeArrayDestroy(array);
218 FindNetworkAdapterConfigurationInstance_t pFindInstance,
226 IWbemLocator* pLocator = 0;
227 IWbemServices* pNamespace = 0;
228 IWbemClassObject* pClass = 0;
229 IWbemClassObject* pOutInst = 0;
230 IWbemClassObject* pInClass = 0;
231 IWbemClassObject* pInInst = 0;
233 BSTR NamespacePath = 0;
235 BSTR InstancePath = 0;
236 BSTR MethodName = 0; // needs to be BSTR for ExecMethod()
239 VariantInit(&v_ip_list);
242 VariantInit(&v_mask_list);
245 VariantInit(&v_ret_value);
249 // end of declarations & NULL initialization
251 NamespacePath = SysAllocString(L"root\\cimv2");
252 CLEANUP_ON_AND_SET(!NamespacePath, hr, E_OUTOFMEMORY);
254 ClassPath = SysAllocString(L"Win32_NetWorkAdapterConfiguration");
255 CLEANUP_ON_AND_SET(!ClassPath, hr, E_OUTOFMEMORY);
257 MethodName = SysAllocString(L"EnableStatic");
258 CLEANUP_ON_AND_SET(!MethodName, hr, E_OUTOFMEMORY);
260 // Initialize COM and connect up to CIMOM
262 hr = CoInitializeEx(0, COINIT_MULTITHREADED);
263 CLEANUP_ON_FAILURE(hr);
265 hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
266 RPC_C_AUTHN_LEVEL_CONNECT,
267 RPC_C_IMP_LEVEL_IMPERSONATE,
269 CLEANUP_ON_FAILURE(hr);
271 hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
272 IID_IWbemLocator, (LPVOID *) &pLocator);
273 CLEANUP_ON_FAILURE(hr);
275 hr = pLocator->ConnectServer(NamespacePath, NULL, NULL, NULL, 0,
276 NULL, NULL, &pNamespace);
277 CLEANUP_ON_FAILURE(hr);
279 printf("Connected to WMI\n");
281 // Set the proxy so that impersonation of the client occurs.
282 hr = CoSetProxyBlanket(pNamespace,
286 RPC_C_AUTHN_LEVEL_CALL,
287 RPC_C_IMP_LEVEL_IMPERSONATE,
290 CLEANUP_ON_FAILURE(hr);
292 // Get the class object
293 hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
294 CLEANUP_ON_FAILURE(hr);
297 hr = pFindInstance(pContext, pNamespace, &InstancePath);
298 CLEANUP_ON_FAILURE(hr);
300 printf("Found Adapter Instance: %S\n", InstancePath);
303 // Use the adapter instance index to set MAXLANA in the registry.
306 if (swscanf(InstancePath, L"Win32_NetworkAdapterConfiguration.Index=%u", &dwIndex)==1)
309 printf("Setting MAXLANA to at least %u\n",dwIndex+1);
310 ret = AdjustMaxLana(dwIndex+1);
311 if (ret) printf("AdjustMaxLana returned the error code %u.\n",ret);
316 // Get the input argument and set the property
317 hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
318 CLEANUP_ON_FAILURE(hr);
320 hr = pInClass->SpawnInstance(0, &pInInst);
321 CLEANUP_ON_FAILURE(hr);
324 hr = SetupStringAsSafeArray(ip, &v_ip_list);
325 CLEANUP_ON_FAILURE(hr);
327 hr = pInInst->Put(L"IPAddress", 0, &v_ip_list, 0);
328 CLEANUP_ON_FAILURE(hr);
330 hr = SetupStringAsSafeArray(mask, &v_mask_list);
331 CLEANUP_ON_FAILURE(hr);
333 hr = pInInst->Put(L"SubNetMask", 0, &v_mask_list, 0);
334 CLEANUP_ON_FAILURE(hr);
336 // Sleep for a twenty seconds
337 printf("Calling ExecMethod in 20 seconds...\r");
339 printf("Calling ExecMethod in 10 seconds...\r");
341 printf("Calling ExecMethod in 5 seconds...\r");
344 // printf("Skipping ExecMethod\n");
348 // Try up to five times, sleeping 3 seconds between tries
349 for (count=0; count<5; count++)
351 if (count>0) printf("Trying again in 3 seconds...\n");
355 printf("Calling ExecMethod NOW... \n");
359 hr = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL, pInInst,
364 printf("ExecMethod failed (0x%08X)\n", hr);
368 // Get the EnableStatic method return value
369 hr = pOutInst->Get(L"ReturnValue", 0, &v_ret_value, 0, 0);
373 printf("WARNING: Could not determine return value for EnableStatic (0x%08X)\n", hr);
377 hr = V_I4(&v_ret_value);
381 printf("EnableStatic failed (0x%08X)\n", hr);
384 printf("EnableStatic succeeded\n");
394 VariantClear(&v_ret_value);
395 VariantClear(&v_ip_list);
396 VariantClear(&v_mask_list);
398 SysFreeString(NamespacePath);
399 SysFreeString(ClassPath);
400 SysFreeString(InstancePath);
401 SysFreeString(MethodName);
403 if (pClass) pClass->Release();
404 if (pInInst) pInInst->Release();
405 if (pInClass) pInClass->Release();
406 if (pOutInst) pOutInst->Release();
407 if (pLocator) pLocator->Release();
408 if (pNamespace) pNamespace->Release();
415 /**********************************************************
416 * LoopbackBindings : unbind all other
417 * protocols except TCP/IP, netbios, netbt.
419 extern "C" HRESULT LoopbackBindings (LPCWSTR loopback_guid)
422 INetCfg *pCfg = NULL;
423 INetCfgLock *pLock = NULL;
424 INetCfgComponent *pAdapter = NULL;
425 IEnumNetCfgComponent *pEnumComponent = NULL;
426 BOOL bLockGranted = FALSE;
427 BOOL bInitialized = FALSE;
428 BOOL bConfigChanged = FALSE;
429 LPWSTR swName = NULL;
431 wchar_t device_guid[100];
434 printf("\nRunning LoopbackBindings()...\n");
436 hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
437 CLEANUP_ON_FAILURE(hr);
439 hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void**)&pCfg );
440 CLEANUP_ON_FAILURE(hr);
442 hr = pCfg->QueryInterface( IID_INetCfgLock, (void**)&pLock );
443 CLEANUP_ON_FAILURE(hr);
445 hr = pLock->AcquireWriteLock( 1000, L"AFS Configuration", NULL );
446 CLEANUP_ON_FAILURE(hr);
449 hr = pCfg->Initialize( NULL );
450 CLEANUP_ON_FAILURE(hr);
453 hr = pCfg->EnumComponents( &GUID_DEVCLASS_NET, &pEnumComponent );
454 CLEANUP_ON_FAILURE(hr);
457 while( pEnumComponent->Next( 1, &pAdapter, NULL ) == S_OK )
459 pAdapter->GetDisplayName( &swName );
460 pAdapter->GetInstanceGuid( &g );
461 StringFromGUID2(g, device_guid, 99);
463 if(!wcscmp( device_guid, loopback_guid )) // found loopback adapter
465 INetCfgComponentBindings *pBindings;
466 INetCfgBindingPath *pPath;
467 IEnumNetCfgBindingPath *pEnumPaths;
468 INetCfgComponent *upper;
470 wprintf(L"LoopbackBindings found: %s\n", device_guid );
472 hr = pAdapter->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings);
475 hr = pBindings->EnumBindingPaths( EBP_ABOVE, &pEnumPaths );
478 while(pEnumPaths->Next( 1, &pPath, NULL ) == S_OK)
480 pPath->GetOwner( &upper );
482 LPWSTR swId = NULL, swName = NULL;
484 upper->GetDisplayName( &swName );
485 upper->GetId( &swId );
487 wprintf(L"Looking at %s (%s)... \n",swName, swId);
490 wprintf(L" Moving to the end of binding order...");
491 INetCfgComponentBindings *pBindings2;
492 hr = upper->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings2);
496 hr = pBindings2->MoveAfter(pPath, NULL);
497 pBindings2->Release();
500 if (hr==S_OK) printf("success\n"); else printf("failed: 0x%0lx\n",hr);
504 if ( !_wcsicmp(swId, L"ms_netbios") ||
505 !_wcsicmp(swId, L"ms_tcpip") ||
506 !_wcsicmp(swId, L"ms_netbt") )
508 if (pPath->IsEnabled()!=S_OK)
510 wprintf(L" Enabling %s: ",swName);
511 hr = pPath->Enable(TRUE);
512 if (hr==S_OK) printf("success\n"); else printf("failed: %ld\n",hr);
518 else //if (!_wcsicmp(swId, L"ms_server") || (!_wcsicmp(swId, L"ms_msclient"))
520 if (pPath->IsEnabled()==S_OK)
522 wprintf(L" Disabling %s: ",swName);
523 hr = pPath->Enable(FALSE);
524 if (hr==S_OK) printf("success\n"); else printf("failed: %ld\n",hr);
529 CoTaskMemFree( swName );
530 CoTaskMemFree( swId );
534 pEnumPaths->Release();
536 pBindings->Release();
537 } // hr==S_OK for QueryInterface IID_INetCfgComponentBindings
540 CoTaskMemFree( swName );
545 pEnumComponent->Release();
551 if(bConfigChanged) pCfg->Apply();
553 if(pAdapter) pAdapter->Release();
555 if(bInitialized) pCfg->Uninitialize();
556 if(bLockGranted) pLock->ReleaseWriteLock();
558 if(pLock) pLock->Release();
559 if(pCfg) pCfg->Release();
561 if (hr) printf ("LoopbackBindings() is returning %u\n",hr);
574 printf("\nRunning SetIpAddress()...\n");
577 hr = WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
578 (PVOID)guid, ip, mask);
582 /* Set MAXLANA in the registry to the specified value, unless the existing registry value is larger */
583 DWORD AdjustMaxLana(DWORD dwMaxLana)
587 HKEY hNetBiosParamKey = NULL;
588 DWORD dwType, dwExistingMaxLana, dwSize;
590 printf ("Making sure MaxLana is at least %u...\n", dwMaxLana);
592 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\NetBIOS\\Parameters"),
593 0, KEY_ALL_ACCESS , &hNetBiosParamKey);
599 ret = RegQueryValueEx(hNetBiosParamKey, _T("MaxLana"), 0, &dwType, (LPBYTE) &dwExistingMaxLana, &dwSize);
600 if ((ret) && (ret != ERROR_MORE_DATA) && (ret != ERROR_FILE_NOT_FOUND))
602 RegCloseKey(hNetBiosParamKey);
606 if ((dwType != REG_DWORD) || (ret)) dwExistingMaxLana = 0;
608 printf (" MaxLana is currently %u\n", dwExistingMaxLana);
610 if (dwExistingMaxLana < dwMaxLana)
612 printf (" Changing to %u\n", dwMaxLana);
613 ret = RegSetValueEx(hNetBiosParamKey, _T("MaxLana"), 0, REG_DWORD, (const BYTE*)&dwMaxLana, 4);
616 RegCloseKey(hNetBiosParamKey);
622 RegCloseKey(hNetBiosParamKey);
629 BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre )
631 char szIp[2048], szName[2048];
632 char etcPath[MAX_PATH];
633 char tempPath[MAX_PATH];
634 char buffer[2048], temp[2048];
640 _snprintf(szIp, 2047, "%S", swIp);
641 _snprintf(szName, 2047, "%S", swName);
643 printf("Starting UpdateHostsFile() on %s file\n",szFilename);
645 rv = SHGetFolderPathA( NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT , etcPath );
646 if(rv != S_OK) return FALSE;
648 strcat( etcPath, ETCDIR );
650 fa = GetFileAttributesA( etcPath );
652 if(fa == INVALID_FILE_ATTRIBUTES)
654 // the directory doesn't exist
655 // it should be there. non-existence implies more things are wrong
656 printf( "Path does not exist : %s\n", etcPath );
660 strcpy( tempPath, etcPath );
661 strcat( etcPath, "\\" );
662 strcat( etcPath, szFilename );
664 fa = GetFileAttributesA( etcPath );
666 if(fa == INVALID_FILE_ATTRIBUTES)
668 printf( "No %s file found. Creating...", szFilename);
670 hFile = fopen( etcPath, "w" );
673 printf("FAILED : can't create %s file\nErrno is %d\n",etcPath,errno);
677 fprintf(hFile, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
683 else // the file exists. parse and update
686 printf( "Updating %s file ...",szFilename );
688 hFile = fopen( etcPath, "r");
691 printf("FAILED : can't open %s file\nErrno is %d\n",etcPath,errno);
695 strcat( tempPath, szFilename );
696 strcat( tempPath, ".tmp" );
697 hTemp = fopen( tempPath, "w");
700 printf("FAILED : can't create temp file %s\nErrno is %d\n",tempPath,errno);
705 while(fgets( buffer, 2046, hFile))
707 strcpy( temp, buffer );
710 if ((strlen(temp)<1) || (*(temp+strlen(temp)-1)!='\n')) strcat(temp, "\n");
712 if(!(str = strstr(temp, szName)))
714 fputs( buffer, hTemp );
718 // check for FOOBAFS or AFSY
719 //if(str <= temp || (*(str-1) != '-' && !isspace(*(str+strlen(szName)))))
720 if ( (str == temp) || (!*(str+strlen(szName))) || (!isspace(*(str-1))) || (!isspace(*(str+strlen(szName)))) )
721 fputs( buffer, hTemp );
727 GetComputerNameA( buffer, &len );
729 fprintf( hTemp, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
734 strcpy(buffer, etcPath);
735 strcat(buffer, ".old");
739 if ((unlink( buffer ) != 0) && (errno == EACCES))
741 printf("FAILED : Can't delete %s file\nErrno is %d",buffer,errno);
746 if ((errno) && (errno != ENOENT)) printf("WEIRD : errno after unlink is %d...",errno);
748 if(rename( etcPath, buffer) != 0)
750 printf("FAILED : Can't rename old %s file\nErrno is %d\n",etcPath,errno);
754 if(rename( tempPath, etcPath ) != 0)
756 printf("FAILED : Can't rename new %s file\nErrno is %d\n",tempPath,errno);
776 printf("usage: %S ip mask\n"
777 " example: %S 10.0.0.1 255.0.0.0", argv[0], argv[0]);
781 return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
782 L"{B4981E32-551C-4164-96B6-B8874BD2E555}",
794 printf("usage: %S adapter_guid ip mask\n"
795 " example: %S {B4981E32-551C-4164-96B6-B8874BD2E555} "
796 "10.0.0.1 255.0.0.0", argv[0], argv[0]);
800 return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
801 argv[1], argv[2], argv[3]);