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.
591 extern "C" HRESULT LoopbackBindings (LPCWSTR loopback_guid)
594 INetCfg *pCfg = NULL;
595 INetCfgLock *pLock = NULL;
596 INetCfgComponent *pAdapter = NULL;
597 IEnumNetCfgComponent *pEnumComponent = NULL;
598 BOOL bLockGranted = FALSE;
599 BOOL bInitialized = FALSE;
600 BOOL bConfigChanged = FALSE;
601 LPWSTR swName = NULL;
603 wchar_t device_guid[100];
605 ReportMessage(0,"Running LoopbackBindings()...",NULL,NULL,0);
607 hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
608 CLEANUP_ON_FAILURE(hr);
610 hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void**)&pCfg );
611 CLEANUP_ON_FAILURE(hr);
613 hr = pCfg->QueryInterface( IID_INetCfgLock, (void**)&pLock );
614 CLEANUP_ON_FAILURE(hr);
616 hr = pLock->AcquireWriteLock( 1000, L"AFS Configuration", NULL );
617 CLEANUP_ON_FAILURE(hr);
620 hr = pCfg->Initialize( NULL );
621 CLEANUP_ON_FAILURE(hr);
624 hr = pCfg->EnumComponents( &GUID_DEVCLASS_NET, &pEnumComponent );
625 CLEANUP_ON_FAILURE(hr);
627 while( pEnumComponent->Next( 1, &pAdapter, NULL ) == S_OK )
629 pAdapter->GetDisplayName( &swName );
630 pAdapter->GetInstanceGuid( &g );
631 StringFromGUID2(g, device_guid, 99);
633 if(!wcscmp( device_guid, loopback_guid )) // found loopback adapter
635 INetCfgComponentBindings *pBindings;
636 INetCfgBindingPath *pPath;
637 IEnumNetCfgBindingPath *pEnumPaths;
638 INetCfgComponent *upper;
640 ReportMessage(0,"LoopbackBindings found", NULL, device_guid,0 );
642 hr = pAdapter->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings);
645 hr = pBindings->EnumBindingPaths( EBP_ABOVE, &pEnumPaths );
648 while(pEnumPaths->Next( 1, &pPath, NULL ) == S_OK)
650 pPath->GetOwner( &upper );
652 LPWSTR swId = NULL, swName = NULL;
654 upper->GetDisplayName( &swName );
655 upper->GetId( &swId );
657 ReportMessage(1,"Looking at ",NULL, swName, 0);
660 ReportMessage(1," Moving to the end of binding order...",NULL,NULL,0);
661 INetCfgComponentBindings *pBindings2;
662 hr = upper->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings2);
665 ReportMessage(1,"...",0,0,0);
666 hr = pBindings2->MoveAfter(pPath, NULL);
667 pBindings2->Release();
670 if (hr==S_OK) ReportMessage(1,"success",0,0,0); else ReportMessage(0,"Binding change failed",0,0,hr);
674 if ( !_wcsicmp(swId, L"ms_netbios") ||
675 !_wcsicmp(swId, L"ms_tcpip") ||
676 !_wcsicmp(swId, L"ms_netbt") ||
677 !_wcsicmp(swId, L"ms_msclient"))
679 if (pPath->IsEnabled()!=S_OK)
681 ReportMessage(1," Enabling ",0,swName,0);
682 hr = pPath->Enable(TRUE);
683 if (hr==S_OK) ReportMessage(1,"success",0,0,0); else ReportMessage(0,"Proto failed",0,0,hr);
688 else //if (!_wcsicmp(swId, L"ms_server") || (!_wcsicmp(swId, L"ms_msclient"))
690 if (pPath->IsEnabled()==S_OK)
692 ReportMessage(1," Disabling ",0,swName,0);
693 hr = pPath->Enable(FALSE);
694 if (hr==S_OK) ReportMessage(1,"success",0,0,0); else ReportMessage(0,"Proto failed",0,0,hr);
699 CoTaskMemFree( swName );
700 CoTaskMemFree( swId );
704 pEnumPaths->Release();
706 pBindings->Release();
707 } // hr==S_OK for QueryInterface IID_INetCfgComponentBindings
710 CoTaskMemFree( swName );
715 pEnumComponent->Release();
721 if(bConfigChanged) pCfg->Apply();
723 if(pAdapter) pAdapter->Release();
725 if(bInitialized) pCfg->Uninitialize();
726 if(bLockGranted) pLock->ReleaseWriteLock();
728 if(pLock) pLock->Release();
729 if(pCfg) pCfg->Release();
731 if (hr) ReportMessage(0,"LoopbackBindings() is returning ",0,0,hr);
736 extern "C" DWORD SetIpAddress(LPCWSTR guid, LPCWSTR ip, LPCWSTR mask)
738 ReportMessage(0,"Running SetIpAddress()...",0,0,0);
741 hr = WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
742 (PVOID)guid, ip, mask);
744 FixupXPDNSRegistrations(guid);
748 /* Set MAXLANA in the registry to the specified value, unless the existing registry value is larger */
749 DWORD AdjustMaxLana(DWORD dwMaxLana)
753 HKEY hNetBiosParamKey = NULL;
754 DWORD dwType, dwExistingMaxLana, dwSize;
756 ReportMessage(0,"Making sure MaxLana is large enough",0,0, dwMaxLana);
758 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\NetBIOS\\Parameters"),
759 0, KEY_ALL_ACCESS , &hNetBiosParamKey);
765 ret = RegQueryValueEx(hNetBiosParamKey, _T("MaxLana"), 0, &dwType, (LPBYTE) &dwExistingMaxLana, &dwSize);
766 if ((ret) && (ret != ERROR_MORE_DATA) && (ret != ERROR_FILE_NOT_FOUND))
768 RegCloseKey(hNetBiosParamKey);
772 if ((dwType != REG_DWORD) || (ret)) dwExistingMaxLana = 0;
774 ReportMessage (1,"MaxLana is currently",0,0, dwExistingMaxLana);
776 if (dwExistingMaxLana < dwMaxLana)
778 ReportMessage (1,"Changing MaxLana", 0,0,dwMaxLana);
779 ret = RegSetValueEx(hNetBiosParamKey, _T("MaxLana"), 0, REG_DWORD, (const BYTE*)&dwMaxLana, 4);
782 RegCloseKey(hNetBiosParamKey);
788 RegCloseKey(hNetBiosParamKey);
795 BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre )
797 char szIp[2048], szName[2048];
798 char etcPath[MAX_PATH];
799 char tempPath[MAX_PATH];
800 char buffer[2048], temp[2048];
806 _snprintf(szIp, 2047, "%S", swIp);
807 _snprintf(szName, 2047, "%S", swName);
809 ReportMessage(0,"Starting UpdateHostsFile() on file",szFilename,0,0);
811 rv = SHGetFolderPathA( NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT , etcPath );
812 if(rv != S_OK) return FALSE;
814 strcat( etcPath, ETCDIR );
816 fa = GetFileAttributesA( etcPath );
818 if(fa == INVALID_FILE_ATTRIBUTES)
820 // the directory doesn't exist
821 // it should be there. non-existence implies more things are wrong
822 ReportMessage(0, "Path does not exist ", etcPath,0,0 );
826 strcpy( tempPath, etcPath );
827 strcat( etcPath, "\\" );
828 strcat( etcPath, szFilename );
830 fa = GetFileAttributesA( etcPath );
832 if(fa == INVALID_FILE_ATTRIBUTES)
834 ReportMessage(0, "File not found. Creating...", szFilename,0,0);
836 hFile = fopen( etcPath, "w" );
839 ReportMessage(0,"FAILED : can't create file",etcPath,0,errno);
843 fprintf(hFile, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
847 ReportMessage(1,"done",0,0,0);
849 else // the file exists. parse and update
852 ReportMessage(1, "Updating file ...",szFilename,0,0 );
854 hFile = fopen( etcPath, "r");
857 ReportMessage(0,"FAILED : can't open file",etcPath,0,errno);
861 strcat( tempPath, szFilename );
862 strcat( tempPath, ".tmp" );
863 hTemp = fopen( tempPath, "w");
866 ReportMessage(0,"FAILED : can't create temp file",tempPath,0,errno);
871 while(fgets( buffer, 2046, hFile))
873 strcpy( temp, buffer );
876 if ((strlen(temp)<1) || (*(temp+strlen(temp)-1)!='\n')) strcat(temp, "\n");
878 if(!(str = strstr(temp, szName)))
880 fputs( buffer, hTemp );
884 // check for FOOBAFS or AFSY
885 //if(str <= temp || (*(str-1) != '-' && !isspace(*(str+strlen(szName)))))
886 if ( (str == temp) || (!*(str+strlen(szName))) || (!isspace(*(str-1))) || (!isspace(*(str+strlen(szName)))) )
887 fputs( buffer, hTemp );
893 GetComputerNameA( buffer, &len );
895 fprintf( hTemp, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
900 strcpy(buffer, etcPath);
901 strcat(buffer, ".old");
903 if(!DeleteFileA(buffer)) {
908 status = GetLastError();
909 if(status == ERROR_ACCESS_DENIED) {
910 /* try changing the file attribtues. */
911 if(SetFileAttributesA(buffer, FILE_ATTRIBUTE_NORMAL) &&
912 DeleteFileA(buffer)) {
914 ReportMessage(0,"Changed attributes and deleted back host file", buffer, 0, 0);
917 if(status && status != ERROR_FILE_NOT_FOUND) {
918 /* we can't delete the file. Try to come up with
919 a different name that's not already taken. */
920 srand(GetTickCount());
921 eos = buffer + strlen(buffer);
922 for(i=0; i < 50; i++) {
923 itoa(rand(), eos, 16);
924 if(GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES &&
925 GetLastError() == ERROR_FILE_NOT_FOUND)
928 /* At this point if we don't have a unique name, we just let the rename
933 if(!MoveFileA( etcPath, buffer )) {
934 ReportMessage(0,"FAILED: Can't rename old file", etcPath, 0, GetLastError());
938 if(!MoveFileA( tempPath, etcPath ) != 0)
940 ReportMessage(0,"FAILED : Can't rename new file", tempPath, 0, GetLastError());
959 printf("usage: %S ip mask\n"
960 " example: %S 10.0.0.1 255.0.0.0", argv[0], argv[0]);
964 return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
965 L"{B4981E32-551C-4164-96B6-B8874BD2E555}",
977 printf("usage: %S adapter_guid ip mask\n"
978 " example: %S {B4981E32-551C-4164-96B6-B8874BD2E555} "
979 "10.0.0.1 255.0.0.0", argv[0], argv[0]);
983 return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
984 argv[1], argv[2], argv[3]);