wix-msi-loopback-20040622
[openafs.git] / src / WINNT / install / loopback / wmi.cpp
1 /*
2
3 Copyright 2004 by the Massachusetts Institute of Technology
4
5 All rights reserved.
6
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
14 prior permission.
15
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
22 SOFTWARE.
23
24 */
25
26 //**************************************************************************
27 //
28 // Description:
29 //
30 //      Call EnableStatic method of Win32_NetworkAdapterConfiguration
31 //      for some network adapter GUID.
32 //
33 // Note:
34 //
35 //      The EnableStatic method is notsupported on Win9x platforms.
36 //
37 //**************************************************************************
38
39 #define _WIN32_DCOM
40 #include <windows.h>
41 #include <comdef.h>
42 #include <wbemidl.h>
43 #include <tchar.h>
44
45 #include <devguid.h>
46
47 /* These two are from the Windows DDK */
48 #include <netcfgx.h>
49 #include <netcfgn.h>
50
51 #include <shlobj.h>
52 //#include <objbase.h>
53
54 //#ifndef TEST
55 //inline void printf(char*, ...) {}
56 //#else
57 #include <stdio.h>
58 //#endif
59
60 #define CLEANUP_ON_FAILURE(hr) \
61     do { if (!SUCCEEDED(hr)) goto cleanup; } while (0)
62
63 #define CLEANUP_ON_AND_SET(check, var, value) \
64     do { if (check) { (var) = (value); goto cleanup; } } while (0)
65
66 #define ETCDIR "\\drivers\\etc"
67
68 #define EACCES (13)
69 #define ENOENT (2)
70
71 DWORD AdjustMaxLana(DWORD dwMaxLana);
72
73 typedef
74 HRESULT
75 (*FindNetworkAdapterConfigurationInstance_t)(
76     IN  PVOID pContext,
77     IN  IWbemServices *pSvc,
78     OUT BSTR* pPath
79     );
80
81 HRESULT
82 FindNetworkAdapterConfigurationInstanceByGUID(
83     IN  PVOID pContext,
84     IN  IWbemServices *pSvc,
85     OUT BSTR* pPath
86     )
87 {
88     HRESULT hr = 0;
89     BOOL bFound = FALSE;
90     BSTR Language = 0;
91     BSTR Query = 0;
92     IEnumWbemClassObject* pEnum = 0;
93     IWbemClassObject* pObj = 0;
94     VARIANT Value;
95     VariantInit(&Value);
96     LPCWSTR adapter_guid = (LPCWSTR)pContext;
97
98     // Check arguments
99     if (!pPath || !adapter_guid || *pPath)
100         return E_INVALIDARG;
101
102     *pPath = 0;
103
104     // Query for all network adapters
105     Language = SysAllocString(L"WQL");
106     Query = SysAllocString(L"select * from Win32_NetworkAdapterConfiguration");
107
108     // Issue the query.
109     hr = pSvc->ExecQuery(Language,
110                          Query,
111                          WBEM_FLAG_FORWARD_ONLY,         // Flags
112                          0,                              // Context
113                          &pEnum);
114     if (!SUCCEEDED(hr))
115     {
116         printf("ExecQuery() error (0x%08X)\n", hr);
117         goto cleanup;
118     }
119
120     // Retrieve the objects in the result set.
121     while (!bFound)
122     {
123         ULONG uReturned = 0;
124
125         hr = pEnum->Next(0,                  // Time out
126                          1,                  // One object
127                          &pObj,
128                          &uReturned);
129         CLEANUP_ON_FAILURE(hr);
130
131         if (uReturned == 0)
132             break;
133
134         // Use the object.
135         hr  = pObj->Get(L"SettingID", // property name
136                         0L,
137                         &Value,       // output to this variant
138                         NULL,
139                         NULL);
140         CLEANUP_ON_FAILURE(hr);
141
142         bFound = !wcscmp(adapter_guid, V_BSTR(&Value));
143         
144         if (bFound)
145         {
146             printf("Found adapter: %S\n", V_BSTR(&Value));
147             VariantClear(&Value);
148             hr = pObj->Get(L"__RELPATH", // property name
149                            0L,
150                            &Value,       // output to this variant
151                            NULL,
152                            NULL);
153             CLEANUP_ON_FAILURE(hr);
154
155             *pPath = SysAllocString(V_BSTR(&Value));
156             
157         }
158         
159         VariantClear(&Value);
160         
161         // Release it.
162         // ===========
163         pObj->Release();    // Release objects not owned.
164         pObj = 0;
165     }
166
167
168     // All done.
169  cleanup:
170     SysFreeString(Query);
171     SysFreeString(Language);
172     VariantClear(&Value);
173     if (pEnum)
174         pEnum->Release();
175     if (pObj)
176         pObj->Release();
177
178     return *pPath ? 0 : ( SUCCEEDED(hr) ? WBEM_E_NOT_FOUND : hr );
179 }
180
181 HRESULT
182 SetupStringAsSafeArray(LPCWSTR s, VARIANT* v)
183 {
184     HRESULT hr = 0;
185     BSTR b = 0;
186     SAFEARRAY* array = 0;
187     long index[] = {0};
188
189     if (V_VT(v) != VT_EMPTY)
190         return E_INVALIDARG;
191
192     b = SysAllocString(s);
193     CLEANUP_ON_AND_SET(!b, hr, E_OUTOFMEMORY);
194
195     array = SafeArrayCreateVector(VT_BSTR, 0, 1);
196     CLEANUP_ON_AND_SET(!array, hr, E_OUTOFMEMORY);
197
198     hr = SafeArrayPutElement(array, index, b);
199     CLEANUP_ON_FAILURE(hr);
200
201     V_VT(v) = VT_ARRAY|VT_BSTR;
202     V_ARRAY(v) = array;
203
204  cleanup:
205     if (b)
206         SysFreeString(b);
207     if (!SUCCEEDED(hr))
208     {
209         if (array)
210             SafeArrayDestroy(array);
211     }
212     return hr;
213 }
214
215
216 HRESULT
217 WMIEnableStatic(
218     FindNetworkAdapterConfigurationInstance_t pFindInstance,
219     PVOID pContext,
220     LPCWSTR ip,
221     LPCWSTR mask
222     )
223 {
224     HRESULT hr = 0;
225
226     IWbemLocator* pLocator = 0;
227     IWbemServices* pNamespace = 0;
228     IWbemClassObject* pClass = 0;
229     IWbemClassObject* pOutInst = 0;
230     IWbemClassObject* pInClass = 0;
231     IWbemClassObject* pInInst = 0;
232
233     BSTR NamespacePath = 0;
234     BSTR ClassPath = 0;
235     BSTR InstancePath = 0;
236     BSTR MethodName = 0; // needs to be BSTR for ExecMethod()
237
238     VARIANT v_ip_list;
239     VariantInit(&v_ip_list);
240
241     VARIANT v_mask_list;
242     VariantInit(&v_mask_list);
243
244     VARIANT v_ret_value;
245     VariantInit(&v_ret_value);
246
247     int count;
248
249     // end of declarations & NULL initialization
250
251     NamespacePath = SysAllocString(L"root\\cimv2");
252     CLEANUP_ON_AND_SET(!NamespacePath, hr, E_OUTOFMEMORY);
253
254     ClassPath = SysAllocString(L"Win32_NetWorkAdapterConfiguration");
255     CLEANUP_ON_AND_SET(!ClassPath, hr, E_OUTOFMEMORY);
256
257     MethodName = SysAllocString(L"EnableStatic");
258     CLEANUP_ON_AND_SET(!MethodName, hr, E_OUTOFMEMORY);
259
260     // Initialize COM and connect up to CIMOM
261
262     hr = CoInitializeEx(0, COINIT_MULTITHREADED);
263     CLEANUP_ON_FAILURE(hr);
264
265     hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
266                               RPC_C_AUTHN_LEVEL_CONNECT,
267                               RPC_C_IMP_LEVEL_IMPERSONATE,
268                               NULL, EOAC_NONE, 0);
269     CLEANUP_ON_FAILURE(hr);
270
271     hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
272                           IID_IWbemLocator, (LPVOID *) &pLocator);
273     CLEANUP_ON_FAILURE(hr);
274
275     hr = pLocator->ConnectServer(NamespacePath, NULL, NULL, NULL, 0,
276                                  NULL, NULL, &pNamespace);
277     CLEANUP_ON_FAILURE(hr);
278
279     printf("Connected to WMI\n");
280
281     // Set the proxy so that impersonation of the client occurs.
282     hr = CoSetProxyBlanket(pNamespace,
283                            RPC_C_AUTHN_WINNT,
284                            RPC_C_AUTHZ_NONE,
285                            NULL,
286                            RPC_C_AUTHN_LEVEL_CALL,
287                            RPC_C_IMP_LEVEL_IMPERSONATE,
288                            NULL,
289                            EOAC_NONE);
290     CLEANUP_ON_FAILURE(hr);
291
292     // Get the class object
293     hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
294     CLEANUP_ON_FAILURE(hr);
295
296     // Get the instance
297     hr = pFindInstance(pContext, pNamespace, &InstancePath);
298     CLEANUP_ON_FAILURE(hr);
299
300     printf("Found Adapter Instance: %S\n", InstancePath);
301
302 #if 0
303     // Use the adapter instance index to set MAXLANA in the registry.
304     {
305         DWORD dwIndex;
306         if (swscanf(InstancePath, L"Win32_NetworkAdapterConfiguration.Index=%u", &dwIndex)==1)
307         {
308             DWORD ret = 0; 
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);
312         }
313     }
314 #endif
315
316     // Get the input argument and set the property
317     hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
318     CLEANUP_ON_FAILURE(hr);
319
320     hr = pInClass->SpawnInstance(0, &pInInst);
321     CLEANUP_ON_FAILURE(hr);
322
323     // Set up parameters
324     hr = SetupStringAsSafeArray(ip, &v_ip_list);
325     CLEANUP_ON_FAILURE(hr);
326
327     hr = pInInst->Put(L"IPAddress", 0, &v_ip_list, 0);
328     CLEANUP_ON_FAILURE(hr);
329
330     hr = SetupStringAsSafeArray(mask, &v_mask_list);
331     CLEANUP_ON_FAILURE(hr);
332
333     hr = pInInst->Put(L"SubNetMask", 0, &v_mask_list, 0);
334     CLEANUP_ON_FAILURE(hr);
335
336     // Sleep for a twenty seconds
337     printf("Calling ExecMethod in 20 seconds...\r");
338     Sleep(10000);
339     printf("Calling ExecMethod in 10 seconds...\r");
340     Sleep(5000);  
341     printf("Calling ExecMethod in  5 seconds...\r");
342     Sleep(2000);
343
344 //    printf("Skipping ExecMethod\n");
345 //    hr = 0;
346 //    goto cleanup;
347
348     // Try up to five times, sleeping 3 seconds between tries
349     for (count=0; count<5; count++)
350     {
351         if (count>0) printf("Trying again in 3 seconds...\n");
352
353         Sleep(3000);
354   
355         printf("Calling ExecMethod NOW...          \n");     
356
357         // Call the method
358
359         hr = pNamespace->ExecMethod(InstancePath, MethodName, 0, NULL, pInInst,
360                                   &pOutInst, NULL);   
361
362         if (!SUCCEEDED(hr))
363         {
364            printf("ExecMethod failed (0x%08X)\n", hr);
365            continue;
366         }
367
368         // Get the EnableStatic method return value
369         hr = pOutInst->Get(L"ReturnValue", 0, &v_ret_value, 0, 0);
370
371         if (!SUCCEEDED(hr))
372         {
373           printf("WARNING: Could not determine return value for EnableStatic (0x%08X)\n", hr);
374           continue;
375         }
376
377         hr = V_I4(&v_ret_value);                
378
379
380         if(hr != 0)
381             printf("EnableStatic failed (0x%08X)\n", hr);
382         else
383         {
384             printf("EnableStatic succeeded\n");
385             break;
386         }
387
388     }
389
390
391
392  cleanup:
393     // Free up resources
394     VariantClear(&v_ret_value);
395     VariantClear(&v_ip_list);
396     VariantClear(&v_mask_list);
397
398     SysFreeString(NamespacePath);
399     SysFreeString(ClassPath);
400     SysFreeString(InstancePath);
401     SysFreeString(MethodName);
402
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();
409
410     CoUninitialize();
411     return hr;
412 }
413
414
415 /**********************************************************
416 * LoopbackBindings :  unbind all other 
417 *       protocols except TCP/IP, netbios, netbt. 
418 */
419 extern "C" HRESULT LoopbackBindings (LPCWSTR loopback_guid)
420 {
421     HRESULT                     hr = 0;
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;
430     GUID            g;
431     wchar_t         device_guid[100];
432     DWORD                       lenDeviceId;    
433     
434     printf("\nRunning LoopbackBindings()...\n");
435     
436     hr = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED ); 
437     CLEANUP_ON_FAILURE(hr);
438     
439     hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (void**)&pCfg );
440     CLEANUP_ON_FAILURE(hr);
441     
442     hr = pCfg->QueryInterface( IID_INetCfgLock, (void**)&pLock );
443     CLEANUP_ON_FAILURE(hr);
444     
445     hr = pLock->AcquireWriteLock( 1000, L"AFS Configuration", NULL );
446     CLEANUP_ON_FAILURE(hr);
447     bLockGranted = TRUE;
448     
449     hr = pCfg->Initialize( NULL );
450     CLEANUP_ON_FAILURE(hr);
451     bInitialized = TRUE;
452     
453     hr = pCfg->EnumComponents( &GUID_DEVCLASS_NET, &pEnumComponent );
454     CLEANUP_ON_FAILURE(hr);
455     
456     
457     while( pEnumComponent->Next( 1, &pAdapter, NULL ) == S_OK )
458     {
459         pAdapter->GetDisplayName( &swName );
460         pAdapter->GetInstanceGuid( &g );
461         StringFromGUID2(g, device_guid, 99);
462         
463         if(!wcscmp( device_guid, loopback_guid )) // found loopback adapter
464         {
465             INetCfgComponentBindings *pBindings;
466             INetCfgBindingPath *pPath;
467             IEnumNetCfgBindingPath *pEnumPaths;
468             INetCfgComponent *upper;
469             
470             wprintf(L"LoopbackBindings found: %s\n", device_guid );
471             
472             hr = pAdapter->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings);
473             if(hr==S_OK)
474             {
475                 hr = pBindings->EnumBindingPaths( EBP_ABOVE, &pEnumPaths );
476                 if(hr==S_OK)
477                 {
478                     while(pEnumPaths->Next( 1, &pPath, NULL ) == S_OK)
479                     {
480                         pPath->GetOwner( &upper );
481                         
482                         LPWSTR swId = NULL, swName = NULL;
483                         
484                         upper->GetDisplayName( &swName );
485                         upper->GetId( &swId );
486                         
487                         wprintf(L"Looking at %s (%s)... \n",swName, swId);
488                                                                         
489                         {
490                             wprintf(L"  Moving to the end of binding order...");
491                             INetCfgComponentBindings *pBindings2;
492                             hr = upper->QueryInterface( IID_INetCfgComponentBindings, (void**) &pBindings2);
493                             if (hr==S_OK)
494                             {
495                                 printf("...");
496                                 hr = pBindings2->MoveAfter(pPath, NULL);                                
497                                 pBindings2->Release();                               
498                                 bConfigChanged=TRUE;
499                             }
500                             if (hr==S_OK) printf("success\n"); else printf("failed: 0x%0lx\n",hr);                                                        
501                                                                                                             
502                         }                        
503                         
504                         if ( !_wcsicmp(swId, L"ms_netbios")  || 
505                             !_wcsicmp(swId, L"ms_tcpip")    ||
506                             !_wcsicmp(swId, L"ms_netbt")      )
507                         {
508                             if (pPath->IsEnabled()!=S_OK)
509                             {
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);
513                                 bConfigChanged=TRUE;
514                             }
515                             
516                             
517                         }
518                         else //if (!_wcsicmp(swId, L"ms_server") || (!_wcsicmp(swId, L"ms_msclient")) 
519                         {
520                             if (pPath->IsEnabled()==S_OK)
521                             {
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);
525                                 bConfigChanged=TRUE;
526                             }
527                         }
528                         
529                         CoTaskMemFree( swName );
530                         CoTaskMemFree( swId );
531                         
532                         pPath->Release();
533                     }
534                     pEnumPaths->Release();
535                 }
536                 pBindings->Release();
537             } // hr==S_OK for QueryInterface IID_INetCfgComponentBindings
538         }
539         
540         CoTaskMemFree( swName );
541         
542         pAdapter->Release();
543     }
544     
545     pEnumComponent->Release();    
546     
547     hr = 0;
548     
549 cleanup:
550     
551     if(bConfigChanged) pCfg->Apply();
552     
553     if(pAdapter) pAdapter->Release();
554     
555     if(bInitialized) pCfg->Uninitialize();
556     if(bLockGranted) pLock->ReleaseWriteLock();
557     
558     if(pLock) pLock->Release();
559     if(pCfg) pCfg->Release();
560     
561     if (hr) printf ("LoopbackBindings() is returning %u\n",hr);
562     return hr;
563 }
564
565         
566         extern "C"
567             DWORD
568 SetIpAddress(
569     LPCWSTR guid,
570     LPCWSTR ip,
571     LPCWSTR mask
572     )
573 {
574     printf("\nRunning SetIpAddress()...\n");
575     HRESULT hr = 0;
576
577     hr = WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
578                         (PVOID)guid, ip, mask);
579     return hr;
580 }
581
582 /* Set MAXLANA in the registry to the specified value, unless the existing registry value is larger */
583 DWORD AdjustMaxLana(DWORD dwMaxLana)
584 {
585
586     LONG ret = 0;
587     HKEY hNetBiosParamKey = NULL;
588     DWORD dwType, dwExistingMaxLana, dwSize;
589
590     printf ("Making sure MaxLana is at least %u...\n", dwMaxLana);
591
592     ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\NetBIOS\\Parameters"), 
593         0, KEY_ALL_ACCESS , &hNetBiosParamKey);
594     if (ret) return ret;
595
596
597     
598     dwSize = 4;
599     ret = RegQueryValueEx(hNetBiosParamKey, _T("MaxLana"), 0, &dwType, (LPBYTE) &dwExistingMaxLana, &dwSize);
600     if ((ret) && (ret != ERROR_MORE_DATA) && (ret != ERROR_FILE_NOT_FOUND)) 
601     {
602         RegCloseKey(hNetBiosParamKey);
603         return ret;
604     }
605
606     if ((dwType != REG_DWORD) || (ret)) dwExistingMaxLana = 0;
607
608     printf ("  MaxLana is currently %u\n", dwExistingMaxLana);
609
610     if (dwExistingMaxLana < dwMaxLana) 
611     {
612         printf ("  Changing to %u\n", dwMaxLana);
613         ret = RegSetValueEx(hNetBiosParamKey, _T("MaxLana"), 0, REG_DWORD, (const BYTE*)&dwMaxLana, 4);
614         if (ret) 
615         {
616             RegCloseKey(hNetBiosParamKey);
617             return ret;
618         }       
619
620     }
621
622     RegCloseKey(hNetBiosParamKey);
623     return 0;
624
625
626 }
627
628 extern "C" 
629 BOOL UpdateHostsFile( LPCWSTR swName, LPCWSTR swIp, LPCSTR szFilename, BOOL bPre )
630 {
631     char szIp[2048], szName[2048];
632     char etcPath[MAX_PATH];
633         char tempPath[MAX_PATH];
634         char buffer[2048], temp[2048];
635         char *str;
636         HRESULT rv;
637         DWORD fa,len;
638         FILE *hFile, *hTemp;
639         
640     _snprintf(szIp, 2047, "%S", swIp);
641     _snprintf(szName, 2047, "%S", swName);
642     strupr(szName);
643     printf("Starting UpdateHostsFile() on %s file\n",szFilename);
644
645         rv = SHGetFolderPathA( NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT , etcPath );
646         if(rv != S_OK) return FALSE;
647
648         strcat( etcPath, ETCDIR );
649
650         fa = GetFileAttributesA( etcPath );
651
652         if(fa == INVALID_FILE_ATTRIBUTES)
653         {
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 );
657                 return FALSE;
658         }
659
660         strcpy( tempPath, etcPath );
661         strcat( etcPath, "\\" );
662         strcat( etcPath, szFilename );
663
664         fa = GetFileAttributesA( etcPath );
665
666         if(fa == INVALID_FILE_ATTRIBUTES)
667         {
668                 printf( "No %s file found. Creating...", szFilename);
669
670                 hFile = fopen( etcPath, "w" );
671                 if(!hFile)
672                 {
673                         printf("FAILED : can't create %s file\nErrno is %d\n",etcPath,errno);
674                         return FALSE;
675                 }
676
677                 fprintf(hFile, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
678
679                 fclose( hFile );
680
681                 printf("done\n");
682         }
683         else // the file exists. parse and update
684         {
685
686                 printf( "Updating %s file ...",szFilename );
687
688                 hFile = fopen( etcPath, "r");
689                 if(!hFile)
690                 {
691                         printf("FAILED : can't open %s file\nErrno is %d\n",etcPath,errno);
692                         return FALSE;
693                 }
694
695                 strcat( tempPath, szFilename );
696                 strcat( tempPath, ".tmp" );
697                 hTemp = fopen( tempPath, "w");
698                 if(!hTemp)
699                 {
700                         printf("FAILED : can't create temp file %s\nErrno is %d\n",tempPath,errno);
701                         fclose(hFile);
702                         return FALSE;
703                 }
704
705                 while(fgets( buffer, 2046, hFile))
706                 {
707                         strcpy( temp, buffer );
708                         strupr( temp );
709
710             if ((strlen(temp)<1) || (*(temp+strlen(temp)-1)!='\n')) strcat(temp, "\n");
711
712                         if(!(str = strstr(temp, szName)))
713                         {
714                                 fputs( buffer, hTemp );
715                         }
716                         else
717                         {
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 );
722                         }
723                 }
724
725
726                 len = 2048;
727                 GetComputerNameA( buffer, &len );
728                 buffer[11] = 0;
729                 fprintf( hTemp, "%s\t%s%s\n", szIp, szName, (bPre)?"\t#PRE":"");
730
731                 fclose( hTemp );
732                 fclose( hFile );
733
734                 strcpy(buffer, etcPath);
735                 strcat(buffer, ".old");
736
737         errno = 0;
738                 
739         if ((unlink( buffer ) != 0) && (errno == EACCES))
740         {
741             printf("FAILED : Can't delete %s file\nErrno is %d",buffer,errno);            
742             return FALSE;
743             
744         }
745         
746         if ((errno) && (errno != ENOENT)) printf("WEIRD : errno after unlink is %d...",errno);
747
748                 if(rename( etcPath, buffer) != 0)
749                 {
750                         printf("FAILED : Can't rename old %s file\nErrno is %d\n",etcPath,errno);
751                         return FALSE;
752                 }
753
754                 if(rename( tempPath, etcPath ) != 0)
755                 {
756                         printf("FAILED : Can't rename new %s file\nErrno is %d\n",tempPath,errno);
757                         return FALSE;
758                 }
759
760                 printf("done\n");
761         }
762
763         return TRUE;
764 }
765
766 #ifdef TEST
767 #if 0
768 int
769 wmain(
770     int argc,
771     wchar_t* argv[]
772     )
773 {
774     if (argc < 3)
775     {
776         printf("usage: %S ip mask\n"
777                "  example: %S 10.0.0.1 255.0.0.0", argv[0], argv[0]);
778         return 0;
779     }
780
781     return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
782                            L"{B4981E32-551C-4164-96B6-B8874BD2E555}",
783                            argv[1], argv[2]);
784 }
785 #else
786 int
787 wmain(
788     int argc,
789     wchar_t* argv[]
790     )
791 {
792     if (argc < 4)
793     {
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]);
797         return 0;
798     }
799
800     return WMIEnableStatic(FindNetworkAdapterConfigurationInstanceByGUID,
801                            argv[1], argv[2], argv[3]);
802 }
803 #endif
804 #endif
805