3 Copyright 2004 by the Massachusetts Institute of Technology
4 Copyright 2006 by Secure Endpoints Inc.
8 Permission to use, copy, modify, and distribute this software and its
9 documentation for any purpose and without fee is hereby granted,
10 provided that the above copyright notice appear in all copies and that
11 both that copyright notice and this permission notice appear in
12 supporting documentation, and that the name of the Massachusetts
13 Institute of Technology (M.I.T.) not be used in advertising or publicity
14 pertaining to distribution of the software without specific, written
17 M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19 M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27 //**************************************************************************
31 // Call EnableStatic method of Win32_NetworkAdapterConfiguration
32 // for some network adapter GUID.
36 // The EnableStatic method is not supported on Win9x platforms.
38 //**************************************************************************
48 /* __RPC__out is not defined in the v6.0 Windows SDK */
53 /* These two are from the Windows DDK */
58 //#include <objbase.h>
61 //inline void printf(char*, ...) {}
66 #include "loopbackutils.h"
68 #define CLEANUP_ON_FAILURE(hr) \
69 do { if (!SUCCEEDED(hr)) {goto cleanup;} } while (0)
71 #define CLEANUP_ON_AND_SET(check, var, value) \
72 do { if (check) { (var) = (value); goto cleanup; } } while (0)
74 #define ETCDIR "\\drivers\\etc"
79 DWORD AdjustMaxLana(DWORD dwMaxLana);
83 (*FindNetworkAdapterConfigurationInstance_t)(
85 IN IWbemServices *pSvc,
90 FindNetworkAdapterConfigurationInstanceByGUID(
92 IN IWbemServices *pSvc,
100 IEnumWbemClassObject* pEnum = 0;
101 IWbemClassObject* pObj = 0;
104 LPCWSTR adapter_guid = (LPCWSTR)pContext;
107 if (!pPath || !adapter_guid || *pPath)
112 // Query for all network adapters
113 Language = SysAllocString(L"WQL");
114 Query = SysAllocString(L"select * from Win32_NetworkAdapterConfiguration");
117 hr = pSvc->ExecQuery(Language,
119 WBEM_FLAG_FORWARD_ONLY, // Flags
124 ReportMessage(0,"ExecQuery() error",NULL,NULL, hr);
128 // Retrieve the objects in the result set.
133 hr = pEnum->Next(0, // Time out
137 CLEANUP_ON_FAILURE(hr);
143 hr = pObj->Get(L"SettingID", // property name
145 &Value, // output to this variant
148 CLEANUP_ON_FAILURE(hr);
150 bFound = !wcscmp(adapter_guid, V_BSTR(&Value));
154 ReportMessage(1,"Found adapter", NULL,V_BSTR(&Value),0);
155 VariantClear(&Value);
156 hr = pObj->Get(L"__RELPATH", // property name
158 &Value, // output to this variant
161 CLEANUP_ON_FAILURE(hr);
163 *pPath = SysAllocString(V_BSTR(&Value));
167 VariantClear(&Value);
171 pObj->Release(); // Release objects not owned.
178 SysFreeString(Query);
179 SysFreeString(Language);
180 VariantClear(&Value);
186 return *pPath ? 0 : ( SUCCEEDED(hr) ? WBEM_E_NOT_FOUND : hr );
190 SetupStringAsSafeArray(LPCWSTR s, VARIANT* v)
194 SAFEARRAY* array = 0;
197 if (V_VT(v) != VT_EMPTY)
200 b = SysAllocString(s);
201 CLEANUP_ON_AND_SET(!b, hr, E_OUTOFMEMORY);
203 array = SafeArrayCreateVector(VT_BSTR, 0, 1);
204 CLEANUP_ON_AND_SET(!array, hr, E_OUTOFMEMORY);
206 hr = SafeArrayPutElement(array, index, b);
207 CLEANUP_ON_FAILURE(hr);
209 V_VT(v) = VT_ARRAY|VT_BSTR;
218 SafeArrayDestroy(array);
226 OSVERSIONINFOEX osInfoEx;
227 memset(&osInfoEx, 0, sizeof(osInfoEx));
228 osInfoEx.dwOSVersionInfoSize = sizeof(osInfoEx);
230 GetVersionEx((POSVERSIONINFO)&osInfoEx);
232 return(osInfoEx.dwMajorVersion == 5 && osInfoEx.dwMinorVersion == 1 && osInfoEx.wServicePackMajor < 2);
236 FixupXPDNSRegistrations(LPCWSTR pCfgGuidString)
238 // As per http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B834440
239 // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\<NetworkAdapterGUID>
240 HKEY hkInterfaces=NULL, hkAdapter=NULL;
244 return; // Nothing to do
246 RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"),
247 0, KEY_READ, &hkInterfaces);
249 RegOpenKeyEx(hkInterfaces, pCfgGuidString, 0, KEY_READ|KEY_WRITE, &hkAdapter);
251 RegDeleteValue(hkAdapter, TEXT("DisableDynamicUpdate"));
252 RegDeleteValue(hkAdapter, TEXT("EnableAdapterDomainNameRegistration"));
253 RegSetValueEx(hkAdapter, TEXT("RegistrationEnabled"), 0, REG_DWORD, (BYTE *)&dw, sizeof(DWORD));
254 RegSetValueEx(hkAdapter, TEXT("RegisterAdapterName"), 0, REG_DWORD, (BYTE *)&dw, sizeof(DWORD));
257 RegCloseKey(hkInterfaces);
259 RegCloseKey(hkAdapter);
264 FindNetworkAdapterConfigurationInstance_t pFindInstance,
270 HRESULT hr = 0, hr2 = 0;
272 IWbemLocator* pLocator = NULL;
273 IWbemServices* pNamespace = NULL;
274 IWbemClassObject* pClass = NULL;
275 IWbemClassObject* pOutInst = NULL;
276 IWbemClassObject* pInClass = NULL;
277 IWbemClassObject* pInInst = NULL;
279 BSTR NamespacePath = NULL;
280 BSTR ClassPath = NULL;
281 BSTR InstancePath = NULL;
282 BSTR MethodName = NULL; // needs to be BSTR for ExecMethod()
284 BOOL comInitialized = FALSE;
287 VariantInit(&v_ip_list);
290 VariantInit(&v_mask_list);
293 VariantInit(&v_ret_value);
295 VARIANT v_reg_enabled;
296 VariantInit(&v_reg_enabled);
299 VariantInit(&v_netbios);
303 // end of declarations & NULL initialization
305 NamespacePath = SysAllocString(L"root\\cimv2");
306 CLEANUP_ON_AND_SET(!NamespacePath, hr, E_OUTOFMEMORY);
308 ClassPath = SysAllocString(L"Win32_NetWorkAdapterConfiguration");
309 CLEANUP_ON_AND_SET(!ClassPath, hr, E_OUTOFMEMORY);
311 // Initialize COM and connect up to CIMOM
313 ReportMessage(0, "Intializing COM", NULL, NULL, 0);
314 hr = CoInitializeEx(0, COINIT_MULTITHREADED);
315 if (hr == S_OK || hr == S_FALSE) {
316 comInitialized = TRUE;
321 /* When called from an MSI this will generally fail. This should only be called once
322 per process and not surprisingly MSI beats us to it. So ignore return value and
323 hope for the best. */
324 hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
325 RPC_C_AUTHN_LEVEL_CONNECT,
326 RPC_C_IMP_LEVEL_IMPERSONATE,
329 /* CLEANUP_ON_FAILURE(hr); */
331 ReportMessage(0, "Creating Wbem Locator object", NULL, NULL, 0);
332 hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
333 IID_IWbemLocator, (LPVOID *) &pLocator);
334 CLEANUP_ON_FAILURE(hr);
336 ReportMessage(0, "Connecting to WMI", NULL, NULL, 0);
337 hr = pLocator->ConnectServer(NamespacePath, NULL, NULL, NULL, 0,
338 NULL, NULL, &pNamespace);
339 CLEANUP_ON_FAILURE(hr);
341 ReportMessage(0,"Connected to WMI",NULL,NULL,0);
343 // Set the proxy so that impersonation of the client occurs.
344 hr = CoSetProxyBlanket(pNamespace,
348 RPC_C_AUTHN_LEVEL_CALL,
349 RPC_C_IMP_LEVEL_IMPERSONATE,
352 CLEANUP_ON_FAILURE(hr);
354 // Get the class object
355 hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
356 CLEANUP_ON_FAILURE(hr);
359 hr = pFindInstance(pContext, pNamespace, &InstancePath);
360 CLEANUP_ON_FAILURE(hr);
362 ReportMessage(0,"Found Adapter Instance",NULL, InstancePath,0);
365 // Use the adapter instance index to set MAXLANA in the registry.
368 if (swscanf(InstancePath, L"Win32_NetworkAdapterConfiguration.Index=%u", &dwIndex)==1)
371 ReportMessage(1,"Setting MAXLANA",NULL,NULL,dwIndex+1);
372 ret = AdjustMaxLana(dwIndex+1);
373 if (ret) ReportMessage(0,"AdjustMaxLana returned the error code ",NULL,NULL,ret);
378 MethodName = SysAllocString(L"EnableStatic");
379 CLEANUP_ON_AND_SET(!MethodName, hr, E_OUTOFMEMORY);
381 // Get the input argument and set the property
382 hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
383 CLEANUP_ON_FAILURE(hr);
385 hr = pInClass->SpawnInstance(0, &pInInst);
386 CLEANUP_ON_FAILURE(hr);
389 hr = SetupStringAsSafeArray(ip, &v_ip_list);
390 CLEANUP_ON_FAILURE(hr);
392 hr = pInInst->Put(L"IPAddress", 0, &v_ip_list, 0);
393 CLEANUP_ON_FAILURE(hr);
395 hr = SetupStringAsSafeArray(mask, &v_mask_list);
396 CLEANUP_ON_FAILURE(hr);
398 hr = pInInst->Put(L"SubNetMask", 0, &v_mask_list, 0);
399 CLEANUP_ON_FAILURE(hr);
401 // printf("Skipping ExecMethod\n");
405 // Try up to five times, sleeping 3 seconds between tries
406 for (count=0; count<5; count++)
409 ReportMessage(0,"Trying again in 3 seconds...",NULL,NULL,0);
411 } else if (count>0) {
412 ReportMessage(0,"Trying again in 20 seconds...",NULL,NULL,0);
414 ReportMessage(0,"Trying again in 10 seconds...",NULL,NULL,0);
416 ReportMessage(0,"Trying again in 5 seconds...",NULL,NULL,0);
420 ReportMessage(0,"Calling ExecMethod EnableStatic NOW... ",NULL,NULL,0);
422 hr = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL, pInInst,
426 ReportMessage(0,"ExecMethod EnableStatic failed",NULL,NULL, hr);
430 // Get the EnableStatic method return value
431 hr = pOutInst->Get(L"ReturnValue", 0, &v_ret_value, 0, 0);
434 ReportMessage(0,"WARNING: Could not determine return value for EnableStatic ",NULL,NULL, hr);
438 hr = V_I4(&v_ret_value);
440 ReportMessage(0,"EnableStatic failed ", NULL,NULL,hr);
443 ReportMessage(0,"EnableStatic succeeded",NULL,NULL,0);
448 /* if failure, skip SetDynamicDNSRegistration */
452 /* Cleanup and Prepare for SetDynamicDNSRegistration */
461 SysFreeString(MethodName);
462 VariantClear(&v_ret_value);
464 MethodName = SysAllocString(L"SetDynamicDNSRegistration");
465 CLEANUP_ON_AND_SET(!MethodName, hr2, E_OUTOFMEMORY);
467 // Get the input argument and set the property
468 hr2 = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
469 CLEANUP_ON_FAILURE(hr2);
471 hr2 = pInClass->SpawnInstance(0, &pInInst);
472 CLEANUP_ON_FAILURE(hr2);
475 V_VT(&v_reg_enabled) = VT_BOOL;
476 V_BOOL(&v_reg_enabled) = VARIANT_FALSE;
478 hr2 = pInInst->Put(L"FullDNSRegistrationEnabled", 0, &v_reg_enabled, 0);
479 CLEANUP_ON_FAILURE(hr2);
481 hr2 = pInInst->Put(L"DomainDNSRegistrationEnabled", 0, &v_reg_enabled, 0);
482 CLEANUP_ON_FAILURE(hr2);
485 hr2 = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL, pInInst,
487 if (!SUCCEEDED(hr2)) {
488 ReportMessage(0,"ExecMethod SetDynamicDNSRegistration failed",NULL,NULL, hr2);
492 // Get the EnableStatic method return value
493 hr2 = pOutInst->Get(L"ReturnValue", 0, &v_ret_value, 0, 0);
494 if (!SUCCEEDED(hr2)) {
495 ReportMessage(0,"WARNING: Could not determine return value for SetDynamicDNSRegistration ",NULL,NULL, hr2);
497 hr2 = V_I4(&v_ret_value);
499 ReportMessage(0,"SetDynamicDNSRegistration failed ", NULL,NULL,hr2);
501 ReportMessage(0,"SetDynamicDNSRegistration succeeded",NULL,NULL,0);
504 /* if failure, skip SetTcpipNetbios */
508 /* Cleanup and Prepare for SetTcpipNetbios */
517 SysFreeString(MethodName);
518 VariantClear(&v_ret_value);
520 ReportMessage(0,"Preparing for SetTcpipNetbios",NULL,NULL,0);
522 MethodName = SysAllocString(L"SetTcpipNetbios");
523 CLEANUP_ON_AND_SET(!MethodName, hr2, E_OUTOFMEMORY);
525 // Get the input argument and set the property
526 hr2 = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
527 CLEANUP_ON_FAILURE(hr2);
529 hr2 = pInClass->SpawnInstance(0, &pInInst);
530 CLEANUP_ON_FAILURE(hr2);
533 V_VT(&v_netbios) = VT_BSTR;
534 V_BSTR(&v_netbios) = SysAllocString(L"1"); /* Use Netbios */
536 hr2 = pInInst->Put(L"TcpipNetbiosOptions", 0, &v_netbios, 0);
537 CLEANUP_ON_FAILURE(hr2);
540 hr2 = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL, pInInst,
542 if (!SUCCEEDED(hr2)) {
543 ReportMessage(0,"ExecMethod SetTcpipNetbios failed",NULL,NULL, hr2);
547 // Get the EnableStatic method return value
548 hr2 = pOutInst->Get(L"ReturnValue", 0, &v_ret_value, 0, 0);
549 if (!SUCCEEDED(hr2)) {
550 ReportMessage(0,"WARNING: Could not determine return value for SetTcpipNetbios ",NULL,NULL, hr2);
552 hr2 = V_I4(&v_ret_value);
554 ReportMessage(0,"SetTcpipNetbios failed ", NULL,NULL,hr2);
556 ReportMessage(0,"SetTcpipNetbios succeeded",NULL,NULL,0);
561 VariantClear(&v_ret_value);
562 VariantClear(&v_ip_list);
563 VariantClear(&v_mask_list);
564 VariantClear(&v_reg_enabled);
565 VariantClear(&v_netbios);
567 // SysFreeString is NULL safe
568 SysFreeString(NamespacePath);
569 SysFreeString(ClassPath);
570 SysFreeString(InstancePath);
571 SysFreeString(MethodName);
573 if (pClass) pClass->Release();
574 if (pInInst) pInInst->Release();
575 if (pInClass) pInClass->Release();
576 if (pOutInst) pOutInst->Release();
577 if (pLocator) pLocator->Release();
578 if (pNamespace) pNamespace->Release();
587 /**********************************************************
588 * LoopbackBindings : unbind all other
589 * protocols except TCP/IP, netbios, netbt.
592 LoopbackBindings (LPCWSTR loopback_guid)
595 INetCfg *pCfg = NULL;
596 INetCfgLock *pLock = NULL;
597 INetCfgComponent *pAdapter = NULL;
598 IEnumNetCfgComponent *pEnumComponent = NULL;
599 BOOL bLockGranted = FALSE;
600 BOOL bInitialized = FALSE;
601 BOOL bConfigChanged = FALSE;
602 LPWSTR swName = NULL;
604 wchar_t device_guid[100];
606 ReportMessage(0,"Running LoopbackBindings()...",NULL,NULL,0);
608 hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
609 CLEANUP_ON_FAILURE(hr);
611 hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void**)&pCfg );
612 CLEANUP_ON_FAILURE(hr);
614 hr = pCfg->QueryInterface( IID_INetCfgLock, (void**)&pLock );
615 CLEANUP_ON_FAILURE(hr);
617 hr = pLock->AcquireWriteLock( 1000, L"AFS Configuration", NULL );
618 CLEANUP_ON_FAILURE(hr);
621 hr = pCfg->Initialize( NULL );
622 CLEANUP_ON_FAILURE(hr);
625 hr = pCfg->EnumComponents( &GUID_DEVCLASS_NET, &pEnumComponent );
626 CLEANUP_ON_FAILURE(hr);
628 while( pEnumComponent->Next( 1, &pAdapter, NULL ) == S_OK )
630 pAdapter->GetDisplayName( &swName );
631 pAdapter->GetInstanceGuid( &g );
632 StringFromGUID2(g, device_guid, 99);
634 if (!wcscmp( device_guid, loopback_guid )) // found loopback adapter
636 INetCfgComponentBindings *pBindings;
637 INetCfgBindingPath *pPath;
638 IEnumNetCfgBindingPath *pEnumPaths;
639 INetCfgComponent *upper;
641 ReportMessage(0,"LoopbackBindings found", NULL, device_guid,0 );
643 hr = pAdapter->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings);
646 hr = pBindings->EnumBindingPaths( EBP_ABOVE, &pEnumPaths );
649 while(pEnumPaths->Next( 1, &pPath, NULL ) == S_OK)
651 pPath->GetOwner( &upper );
653 LPWSTR swId = NULL, swName = NULL;
655 upper->GetDisplayName( &swName );
656 upper->GetId( &swId );
658 ReportMessage(1,"Looking at ",NULL, swName, 0);
661 ReportMessage(1," Moving to the end of binding order...",NULL,NULL,0);
662 INetCfgComponentBindings *pBindings2;
663 hr = upper->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings2);
666 ReportMessage(1,"...",0,0,0);
667 hr = pBindings2->MoveAfter(pPath, NULL);
668 pBindings2->Release();
671 if (hr==S_OK) ReportMessage(1,"success",0,0,0); else ReportMessage(0,"Binding change failed",0,0,hr);
675 if ( !_wcsicmp(swId, L"ms_netbios") ||
676 !_wcsicmp(swId, L"ms_tcpip") ||
677 !_wcsicmp(swId, L"ms_netbt") ||
678 !_wcsicmp(swId, L"ms_msclient"))
680 if (pPath->IsEnabled()!=S_OK)
682 ReportMessage(1," Enabling ",0,swName,0);
683 hr = pPath->Enable(TRUE);
684 if (hr==S_OK) ReportMessage(1,"success",0,0,0); else ReportMessage(0,"Proto failed",0,0,hr);
689 else //if (!_wcsicmp(swId, L"ms_server") || (!_wcsicmp(swId, L"ms_msclient"))
691 if (pPath->IsEnabled()==S_OK)
693 ReportMessage(1," Disabling ",0,swName,0);
694 hr = pPath->Enable(FALSE);
695 if (hr==S_OK) ReportMessage(1,"success",0,0,0); else ReportMessage(0,"Proto failed",0,0,hr);
700 CoTaskMemFree( swName );
701 CoTaskMemFree( swId );
705 pEnumPaths->Release();
707 pBindings->Release();
708 } // hr==S_OK for QueryInterface IID_INetCfgComponentBindings
711 CoTaskMemFree( swName );
716 pEnumComponent->Release();
722 if (bConfigChanged) pCfg->Apply();
724 if (pAdapter) pAdapter->Release();
726 if (bInitialized) pCfg->Uninitialize();
727 if (bLockGranted) pLock->ReleaseWriteLock();
729 if (pLock) pLock->Release();
730 if (pCfg) pCfg->Release();
732 if (hr) ReportMessage(0,"LoopbackBindings() is returning ",0,0,hr);
738 DWORD SetIpAddress(LPCWSTR guid, LPCWSTR ip, LPCWSTR mask)
740 ReportMessage(0,"Running SetIpAddress()...",0,0,0);
743 hr = WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
744 (PVOID)guid, ip, mask);
746 FixupXPDNSRegistrations(guid);
750 /* Set MAXLANA in the registry to the specified value, unless the existing registry value is larger */
752 AdjustMaxLana(DWORD dwMaxLana)
756 HKEY hNetBiosParamKey = NULL;
757 DWORD dwType, dwExistingMaxLana, dwSize;
759 ReportMessage(0,"Making sure MaxLana is large enough",0,0, dwMaxLana);
761 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\NetBIOS\\Parameters"),
762 0, KEY_ALL_ACCESS , &hNetBiosParamKey);
768 ret = RegQueryValueEx(hNetBiosParamKey, _T("MaxLana"), 0, &dwType, (LPBYTE) &dwExistingMaxLana, &dwSize);
769 if ((ret) && (ret != ERROR_MORE_DATA) && (ret != ERROR_FILE_NOT_FOUND))
771 RegCloseKey(hNetBiosParamKey);
775 if ((dwType != REG_DWORD) || (ret)) dwExistingMaxLana = 0;
777 ReportMessage (1,"MaxLana is currently",0,0, dwExistingMaxLana);
779 if (dwExistingMaxLana < dwMaxLana)
781 ReportMessage (1,"Changing MaxLana", 0,0,dwMaxLana);
782 ret = RegSetValueEx(hNetBiosParamKey, _T("MaxLana"), 0, REG_DWORD, (const BYTE*)&dwMaxLana, 4);
785 RegCloseKey(hNetBiosParamKey);
791 RegCloseKey(hNetBiosParamKey);
798 BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre )
800 char szIp[2048], szName[2048];
801 char etcPath[MAX_PATH];
802 char tempPath[MAX_PATH];
803 char buffer[2048], temp[2048];
810 _snprintf(szIp, 2047, "%S", swIp);
811 _snprintf(szName, 2047, "%S", swName);
813 nameLen = strlen(szName);
814 ReportMessage(0,"Starting UpdateHostsFile() on file",szFilename,0,0);
816 rv = SHGetFolderPathA( NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, etcPath );
820 strcat( etcPath, ETCDIR );
822 fa = GetFileAttributesA( etcPath );
824 if (fa == INVALID_FILE_ATTRIBUTES)
826 // the directory doesn't exist
827 // it should be there. non-existence implies more things are wrong
828 ReportMessage(0, "Path does not exist ", etcPath,0,0 );
832 strcpy( tempPath, etcPath );
833 strcat( etcPath, "\\" );
834 strcat( etcPath, szFilename );
836 fa = GetFileAttributesA( etcPath );
838 if (fa == INVALID_FILE_ATTRIBUTES)
840 ReportMessage(0, "File not found. Creating...", szFilename,0,0);
842 hFile = fopen( etcPath, "w" );
845 ReportMessage(0,"FAILED : can't create file",etcPath,0,errno);
849 fprintf(hFile, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
853 ReportMessage(1,"done",0,0,0);
855 else // the file exists. parse and update
858 ReportMessage(1, "Updating file ...",szFilename,0,0 );
860 hFile = fopen( etcPath, "r");
863 ReportMessage(0,"FAILED : can't open file",etcPath,0,errno);
867 strcat( tempPath, szFilename );
868 strcat( tempPath, ".tmp" );
869 hTemp = fopen( tempPath, "w");
872 ReportMessage(0,"FAILED : can't create temp file",tempPath,0,errno);
877 while(fgets( buffer, 2046, hFile))
881 strcpy( temp, buffer );
885 if ((len < 1) || (temp[len-1] != '\n'))
888 if (!(str = strstr(temp, szName)))
890 fputs( temp, hTemp );
894 // check for FOOBAFS or AFSY
895 if ( (str == temp) || (!str[nameLen]) || (!isspace(*(str-1))) || (!isspace(str[nameLen])) )
896 fputs( temp, hTemp );
901 GetComputerNameA( buffer, &len );
903 fprintf( hTemp, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
908 strcpy(buffer, etcPath);
909 strcat(buffer, ".old");
911 if (!DeleteFileA(buffer)) {
916 status = GetLastError();
917 if (status == ERROR_ACCESS_DENIED) {
918 /* try changing the file attribtues. */
919 if (SetFileAttributesA(buffer, FILE_ATTRIBUTE_NORMAL) &&
920 DeleteFileA(buffer)) {
922 ReportMessage(0,"Changed attributes and deleted back host file", buffer, 0, 0);
925 if (status && status != ERROR_FILE_NOT_FOUND) {
926 /* we can't delete the file. Try to come up with
927 a different name that's not already taken. */
928 srand(GetTickCount());
929 eos = buffer + strlen(buffer);
930 for(i=0; i < 50; i++) {
931 itoa(rand(), eos, 16);
932 if (GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES &&
933 GetLastError() == ERROR_FILE_NOT_FOUND)
936 /* At this point if we don't have a unique name, we just let the rename
941 if (!MoveFileA( etcPath, buffer )) {
942 ReportMessage(0,"FAILED: Can't rename old file", etcPath, 0, GetLastError());
946 if (!MoveFileA( tempPath, etcPath ) != 0)
948 ReportMessage(0,"FAILED : Can't rename new file", tempPath, 0, GetLastError());
967 printf("usage: %S ip mask\n"
968 " example: %S 10.0.0.1 255.0.0.0", argv[0], argv[0]);
972 return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
973 L"{B4981E32-551C-4164-96B6-B8874BD2E555}",
985 printf("usage: %S adapter_guid ip mask\n"
986 " example: %S {B4981E32-551C-4164-96B6-B8874BD2E555} "
987 "10.0.0.1 255.0.0.0", argv[0], argv[0]);
991 return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
992 argv[1], argv[2], argv[3]);