per-user-registry-20040320
[openafs.git] / src / WINNT / client_config / config.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "afs_config.h"
16
17 extern "C" {
18
19 #include "../afsd/fs_utils.h"
20
21 #define __CM_CONFIG_INTERFACES_ONLY__
22 #include "../afsd/cm_config.h"
23
24 #define __CM_IOCTL_INTERFACES_ONLY__
25 #include "../afsd/cm_ioctl.h"
26
27 } // extern "C"
28
29
30 #define cREALLOC_PREFS       32
31
32 #define cSERVERPREFS_CHUNK  256
33
34 #define PIOCTL_MAXSIZE     2048
35
36
37
38 /*
39  * ROUTINES ___________________________________________________________________
40  *
41  */
42
43 static DWORD log2 (DWORD dwValue)
44 {
45    for (DWORD dwLog = 0; (DWORD)(1<<dwLog) < dwValue; ++dwLog)
46       ;
47    return dwLog;
48 }
49
50 DWORD Config_GetServiceState (void)
51 {
52    if (!g.fIsWinNT)
53       {
54       TCHAR szGateway[ cchRESOURCE ] = TEXT("");
55       Config_GetGatewayName (szGateway);
56       return (szGateway[0]) ? SERVICE_RUNNING : SERVICE_STOPPED;
57       }
58
59    SERVICE_STATUS Status;
60    memset (&Status, 0x00, sizeof(Status));
61
62    SC_HANDLE hManager;
63    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
64       {
65       SC_HANDLE hService;
66       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
67          {
68          QueryServiceStatus (hService, &Status);
69          CloseServiceHandle (hService);
70          }
71
72       CloseServiceHandle (hManager);
73       }
74
75    return Status.dwCurrentState;
76 }
77
78
79 /*
80  * Configuration Routine ______________________________________________________
81  *
82  */
83
84 void Config_GetGatewayFlag (BOOL *pfFlag)
85 {
86    if (!Config_ReadGlobalNum (TEXT("IsGateway"), (DWORD*)pfFlag))
87       *pfFlag = FALSE;
88 }
89
90
91 BOOL Config_SetGatewayFlag (BOOL fFlag, ULONG *pStatus)
92 {
93    Config_WriteGlobalNum (TEXT("IsGateway"), fFlag);
94    g.fNeedRestart = TRUE;
95    return TRUE;
96 }
97
98
99 void Config_GetGatewayName (LPTSTR pszName)
100 {
101    if (!Config_ReadGlobalString (TEXT("Gateway"), pszName, MAX_PATH))
102       GetString (pszName, IDS_GATEWAY_UNKNOWN);
103    else if (!*pszName)
104       GetString (pszName, IDS_GATEWAY_UNKNOWN);
105 }
106
107
108 BOOL Config_SetGatewayName (LPCTSTR pszName, ULONG *pStatus)
109 {
110    TCHAR szBogus[ cchRESOURCE ];
111    GetString (szBogus, IDS_GATEWAY_UNKNOWN);
112    if (!lstrcmpi (szBogus, pszName))
113       {
114       Config_WriteGlobalString (TEXT("Gateway"), TEXT(""));
115       }
116    else
117       {
118       Config_WriteGlobalString (TEXT("Gateway"), pszName);
119       }
120
121    return TRUE;
122 }
123
124
125 void Config_FixGatewayDrives (void)
126 {
127    // Zip through the user's network drives and reconnect
128    // them as necessary.
129    //
130    for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
131       {
132       TCHAR szSubmount[ MAX_PATH ];
133       if (!GetDriveSubmount (chDrive, szSubmount))
134          continue;
135
136       // We've got a mapping into AFS!  Remove it, rather forcefully.
137       //
138       TCHAR szDrive[] = "@:";
139       szDrive[0] = chDrive;
140       WNetCancelConnection (szDrive, TRUE);
141       }
142
143    // Now recreate our drive mappings, based on the user's already-
144    // specified preferences.
145    //
146    DRIVEMAPLIST List;
147    QueryDriveMapList (&List);
148
149    for (size_t ii = 0; ii < 26; ++ii)
150       {
151       if (!List.aDriveMap[ii].szMapping[0])
152          continue;
153       ActivateDriveMap (List.aDriveMap[ii].chDrive, List.aDriveMap[ii].szMapping, List.aDriveMap[ii].szSubmount, List.aDriveMap[ii].fPersistent);
154       }
155 }
156
157
158 void Config_GetCellName (LPTSTR pszName)
159 {
160    if (!Config_ReadGlobalString (TEXT("Cell"), pszName, MAX_PATH))
161       GetString (pszName, IDS_CELL_UNKNOWN);
162    else if (!*pszName)
163       GetString (pszName, IDS_CELL_UNKNOWN);
164 }
165
166
167 BOOL Config_ContactGateway (LPTSTR pszGateway, LPTSTR pszCell)
168 {
169    BOOL rc = FALSE;
170
171    BYTE OutData[ PIOCTL_MAXSIZE ];
172    memset (OutData, 0x00, sizeof(OutData));
173
174    struct ViceIoctl IOInfo;
175    IOInfo.in_size = 0;
176    IOInfo.in = 0;
177    IOInfo.out = (char *)OutData;
178    IOInfo.out_size = PIOCTL_MAXSIZE;
179
180    TCHAR szOldGateway[ MAX_PATH ];
181    Config_GetGatewayName (szOldGateway);
182    Config_SetGatewayName (pszGateway);
183
184    ULONG status;
185    if ((status = pioctl (0, VIOC_GET_WS_CELL, &IOInfo, 1)) == 0)
186       {
187       if (OutData[0])
188          {
189          lstrcpy (pszCell, (LPCTSTR)OutData);
190          rc = TRUE;
191          }
192       }
193
194    Config_SetGatewayName (szOldGateway);
195
196    return rc;
197 }
198
199
200 BOOL Config_SetCellName (LPCTSTR pszName, ULONG *pStatus)
201 {
202    TCHAR szBogus[ cchRESOURCE ];
203    GetString (szBogus, IDS_CELL_UNKNOWN);
204    if (lstrcmpi (szBogus, pszName))
205       {
206       Config_WriteGlobalString (TEXT("Cell"), pszName);
207       g.fNeedRestart = TRUE;
208       }
209    return TRUE;
210 }
211
212 #if 0
213 /*      These two functions are not needed as of the 1.2.2a updates.
214         The old implementation used to 'bind' afslogon.dll to the credentials manager
215         when the Integrated Logon was selected.
216
217         With version 1.2.2a afslogon.dll is always 'bound' to the credentials manager; therefore,
218         the binding operation is done during installation.  Note: the Integrated Logon is
219         selected by an entry in the registry (LogonOptions).
220 */
221 void Config_GetAuthentFlag (BOOL *pfFlag)
222 {
223    *pfFlag = FALSE;
224
225    HKEY hk;
226    if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Control\\NetworkProvider\\Order"), 0, KEY_QUERY_VALUE, &hk) == ERROR_SUCCESS)
227       {
228       if (g.fIsWinNT)
229          {
230          TCHAR szProviders[ MAX_PATH ] = TEXT("");
231          DWORD dwSize = sizeof(szProviders);
232
233          if (RegQueryValueEx (hk, TEXT("ProviderOrder"), NULL, NULL, (PBYTE)szProviders, &dwSize) == ERROR_SUCCESS)
234             {
235             for (LPTSTR pch = szProviders; *pch; )
236                {
237                if (!lstrncmpi (pch, TEXT("TransarcAFSDaemon"), lstrlen(TEXT("TransarcAFSDaemon"))))
238                   *pfFlag = TRUE;
239
240                for ( ; *pch && (*pch != TEXT(',')); ++pch)
241                   ;
242                for ( ; *pch == TEXT(','); ++pch)
243                   ;
244                }
245             }
246
247          RegCloseKey (hk);
248          }
249       else // (!g.fIsWinNT)
250          {
251          TCHAR szLHS[ MAX_PATH ] = TEXT("");
252          DWORD dwSize = sizeof(szLHS);
253
254          if (RegQueryValueEx (hk, TEXT("TransarcAFSDaemon"), NULL, NULL, (PBYTE)szLHS, &dwSize) == ERROR_SUCCESS)
255             *pfFlag = TRUE;
256          }
257       }
258 }
259
260
261 BOOL Config_SetAuthentFlag (BOOL fFlag, ULONG *pStatus)
262 {
263    ULONG status = 0;
264    BOOL rc = FALSE;
265
266    HKEY hk;
267    DWORD dwDisp;
268    if ((status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Control\\NetworkProvider\\Order"), 0, TEXT("container"), 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hk, &dwDisp)) == ERROR_SUCCESS)
269       {
270       if (g.fIsWinNT)
271          {
272          TCHAR szOldProviders[ MAX_PATH ] = TEXT("");
273          TCHAR szNewProviders[ MAX_PATH ] = TEXT("");
274          DWORD dwSize = sizeof(szOldProviders);
275          RegQueryValueEx (hk, TEXT("ProviderOrder"), NULL, NULL, (PBYTE)szOldProviders, &dwSize);
276
277          for (LPTSTR pch = szOldProviders; *pch; )
278             {
279             BOOL fCopy = TRUE;
280             if (!lstrncmpi (pch, TEXT("TransarcAFSDaemon"), lstrlen(TEXT("TransarcAFSDaemon"))))
281                {
282                fCopy = fFlag;
283                fFlag = FALSE;
284                }
285
286             if (fCopy)
287                {
288                LPTSTR pchOut = &szNewProviders[ lstrlen(szNewProviders) ];
289                if (szNewProviders[0])
290                   *pchOut++ = TEXT(',');
291                for ( ; *pch && (*pch != TEXT(',')); )
292                   *pchOut++ = *pch++;
293                *pchOut = TEXT('\0');
294                }
295
296             for ( ; *pch && (*pch != TEXT(',')); ++pch)
297                ;
298             for ( ; *pch == TEXT(','); ++pch)
299                ;
300             }
301
302          if (fFlag)
303             {
304             if (szNewProviders[0])
305                lstrcat (szNewProviders, TEXT(","));
306             lstrcat (szNewProviders, TEXT("TransarcAFSDaemon"));
307             }
308
309          if ((status = RegSetValueEx (hk, TEXT("ProviderOrder"), NULL, REG_SZ, (PBYTE)szNewProviders, sizeof(TCHAR)*(1+lstrlen(szNewProviders)))) == ERROR_SUCCESS)
310             rc = TRUE;
311          }
312       else // (!g.fIsWinNT)
313          {
314          TCHAR szLHS[ cchRESOURCE ] = TEXT("TransarcAFSDaemon");
315          TCHAR szRHS[ cchRESOURCE ] = TEXT("");
316
317          if (fFlag)
318             {
319             if ((status = RegSetValueEx (hk, szLHS, NULL, REG_SZ, (PBYTE)szRHS, sizeof(TCHAR)*(lstrlen(szRHS)+1))) == 0)
320                rc = TRUE;
321             }
322          else
323             {
324             RegDeleteValue (hk, szLHS);
325             rc = TRUE;
326             }
327          }
328
329       RegCloseKey (hk);
330       }
331
332    if (pStatus && !rc)
333       *pStatus = status;
334    if (!rc)
335       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_AUTHENT, TEXT("%ld"), status);
336    return rc;
337 }
338 #endif
339
340 void Config_GetTrayIconFlag (BOOL *pfFlag)
341 {
342    if (!Config_ReadUserNum (TEXT("ShowTrayIcon"), (DWORD*)pfFlag))
343       *pfFlag = FALSE;
344 }
345
346
347 BOOL Config_SetTrayIconFlag (BOOL fFlag, ULONG *pStatus)
348 {
349    Config_WriteUserNum (TEXT("ShowTrayIcon"), fFlag);
350
351    for (HWND hSearch = GetWindow (GetDesktopWindow(), GW_CHILD);
352         hSearch && IsWindow(hSearch);
353         hSearch = GetWindow (hSearch, GW_HWNDNEXT))
354       {
355       TCHAR szClassName[ cchRESOURCE ];
356       if (GetClassName (hSearch, szClassName, cchRESOURCE))
357          {
358          if (!lstrcmpi (szClassName, TEXT("AfsCreds")))
359             break;
360          }
361       }
362
363    if (hSearch && IsWindow(hSearch))
364       {
365       UINT msgCheckTerminate = RegisterWindowMessage (TEXT("AfsCredsCheckTerminate"));
366       PostMessage (hSearch, msgCheckTerminate, 0, 0);
367       }
368    else if (fFlag && !(hSearch && IsWindow(hSearch)))
369       {
370       WinExec (TEXT("AfsCreds.exe /quiet"), SW_SHOW);
371       }
372
373    return TRUE;
374 }
375
376
377 PSERVERPREFS Config_GetServerPrefs (BOOL fVLServers)
378 {
379    PSERVERPREFS pPrefs = New (SERVERPREFS);
380    memset (pPrefs, 0x00, sizeof(SERVERPREFS));
381    pPrefs->fVLServers = fVLServers;
382
383    if (Config_GetServiceState() == SERVICE_RUNNING)
384       {
385       // We retrieve server prefs in batches--start that loop now.
386       //
387       size_t iOut = 0;
388       for (int iOffset = 0; ; )
389          {
390          cm_SPrefRequest_t InData;
391          memset (&InData, 0x00, sizeof(InData));
392          InData.offset = iOffset;
393          InData.flags = (pPrefs->fVLServers) ? CM_SPREF_VLONLY : 0;
394          InData.num_servers = cSERVERPREFS_CHUNK;
395
396          BYTE OutDataStorage[ sizeof(cm_SPrefInfo_t) + cSERVERPREFS_CHUNK * sizeof(cm_SPref_t) ];
397          memset (OutDataStorage, 0x00, sizeof(OutDataStorage));
398          cm_SPrefInfo_t *pOutData = (cm_SPrefInfo_t *)OutDataStorage;
399
400          struct ViceIoctl IOInfo;
401          IOInfo.in_size = sizeof(InData);
402          IOInfo.in = (char *)&InData;
403          IOInfo.out = (char *)pOutData;
404          IOInfo.out_size = sizeof(cm_SPrefInfo_t) + cSERVERPREFS_CHUNK * sizeof(cm_SPref_t);
405
406          if (pioctl (0, VIOC_GETSPREFS, &IOInfo, 1) != 0)
407             break;
408
409          if (!REALLOC (pPrefs->aPrefs, pPrefs->cPrefs, iOut + pOutData->num_servers, cREALLOC_PREFS))
410             break;
411
412          for (size_t ii = 0; ii < pOutData->num_servers; ++ii)
413             {
414             pPrefs->aPrefs[ iOut ].ipServer = pOutData->servers[ ii ].host.s_addr;
415             pPrefs->aPrefs[ iOut ].iRank = pOutData->servers[ ii ].rank;
416             iOut ++;
417             }
418
419          if ((iOffset = pOutData->next_offset) == 0)
420             break;
421          }
422      }
423
424    return pPrefs;
425 }
426
427
428 BOOL Config_SetServerPrefs (PSERVERPREFS pPrefs, ULONG *pStatus)
429 {
430    BOOL rc = TRUE;
431    ULONG status = 0;
432
433    if (pPrefs)
434       {
435       size_t cChanged = 0;
436       for (size_t ii = 0; ii < pPrefs->cPrefs; ++ii)
437          {
438          if (pPrefs->aPrefs[ ii ].fChanged)
439             ++cChanged;
440          }
441
442       if (cChanged)
443          {
444          if (Config_GetServiceState() != SERVICE_RUNNING)
445             {
446             rc = FALSE;
447             status = ERROR_SERVICE_NOT_ACTIVE;
448             }
449          else
450             {
451             size_t cbInDataStorage = sizeof(cm_SSetPref_t) + cChanged * sizeof(cm_SPref_t);
452
453             PBYTE pInDataStorage;
454             if ((pInDataStorage = (PBYTE)Allocate (cbInDataStorage)) == NULL)
455                {
456                rc = FALSE;
457                status = ERROR_NOT_ENOUGH_MEMORY;
458                }
459             else
460                {
461                memset (pInDataStorage, 0x00, sizeof(cbInDataStorage));
462
463                cm_SSetPref_t *pInData = (cm_SSetPref_t*)pInDataStorage;
464                pInData->flags = (pPrefs->fVLServers) ? CM_SPREF_VLONLY : 0;
465                pInData->num_servers = cChanged;
466
467                size_t iOut = 0;
468                for (ii = 0; ii < pPrefs->cPrefs; ++ii)
469                   {
470                   if (pPrefs->aPrefs[ ii ].fChanged)
471                      {
472                      pInData->servers[ iOut ].host.s_addr = pPrefs->aPrefs[ ii ].ipServer;
473                      pInData->servers[ iOut ].rank = (unsigned short)pPrefs->aPrefs[ ii ].iRank;
474                      iOut++;
475                      }
476                   }
477
478                BYTE OutDataStorage[ PIOCTL_MAXSIZE ];
479
480                struct ViceIoctl IOInfo;
481                IOInfo.in_size = cbInDataStorage;
482                IOInfo.in = (char *)pInData;
483                IOInfo.out = (char *)OutDataStorage;
484                IOInfo.out_size = PIOCTL_MAXSIZE;
485
486                if ((status = pioctl (0, VIOC_SETSPREFS, &IOInfo, 1)) != 0)
487                   {
488                   rc = FALSE;
489                   }
490
491                Free (pInDataStorage);
492                }
493             }
494          }
495       }
496
497    if (pStatus && !rc)
498       *pStatus = status;
499    if (!rc)
500       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_PREFS, TEXT("%ld"), status);
501    return rc;
502 }
503
504
505 void Config_FreeServerPrefs (PSERVERPREFS pPrefs)
506 {
507    if (pPrefs->aPrefs)
508       Free (pPrefs->aPrefs);
509    memset (pPrefs, 0xFD, sizeof(SERVERPREFS));
510    Delete (pPrefs);
511 }
512
513
514 void Config_GetCacheSize (ULONG *pckCache)
515 {
516    if (!Config_ReadGlobalNum (TEXT("CacheSize"), (DWORD*)pckCache))
517       *pckCache = CM_CONFIGDEFAULT_CACHESIZE;
518 }
519
520
521 BOOL Config_SetCacheSize (ULONG ckCache, ULONG *pStatus)
522 {
523    BOOL rc = TRUE;
524    ULONG status = 0;
525
526    if (Config_GetServiceState() == SERVICE_RUNNING)
527       {
528       ULONG ckCacheNow;
529       Config_GetCacheSize (&ckCacheNow);
530       if (ckCacheNow > ckCache)
531          {
532          Message (MB_ICONHAND, GetErrorTitle(), IDS_SHRINKCACHE);
533          return FALSE;
534          }
535
536       struct ViceIoctl IOInfo;
537       IOInfo.in_size = sizeof(ULONG);
538       IOInfo.in = (char *)&ckCache;
539       IOInfo.out = (char *)0;
540       IOInfo.out_size = 0;
541
542       if ((status = pioctl (0, VIOCSETCACHESIZE, &IOInfo, 1)) != 0)
543          {
544          rc = FALSE;
545          }
546       }
547
548    if (rc)
549       {
550       Config_WriteGlobalNum (TEXT("CacheSize"), ckCache);
551       }
552
553    if (pStatus && !rc)
554       *pStatus = status;
555    if (!rc)
556       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_CACHE, TEXT("%ld"), status);
557    return rc;
558 }
559
560
561
562 void Config_GetChunkSize (ULONG *pckChunk)
563 {
564    if (!Config_ReadGlobalNum (TEXT("ChunkSize"), (DWORD*)pckChunk))
565       *pckChunk = CM_CONFIGDEFAULT_CHUNKSIZE;
566    *pckChunk = max (*pckChunk, 10);
567    *pckChunk = (1 << ((*pckChunk)-10));
568 }
569
570
571 BOOL Config_SetChunkSize (ULONG ckChunk, ULONG *pStatus)
572 {
573    Config_WriteGlobalNum (TEXT("ChunkSize"), log2(ckChunk * 1024));
574    g.fNeedRestart = TRUE;
575    return TRUE;
576 }
577
578
579
580 void Config_GetStatEntries (ULONG *pcEntries)
581 {
582    if (!Config_ReadGlobalNum (TEXT("Stats"), (DWORD*)pcEntries))
583       *pcEntries = CM_CONFIGDEFAULT_STATS;
584 }
585
586
587 BOOL Config_SetStatEntries (ULONG cEntries, ULONG *pStatus)
588 {
589    Config_WriteGlobalNum (TEXT("Stats"), cEntries);
590    g.fNeedRestart = TRUE;
591    return TRUE;
592 }
593
594
595
596 void Config_GetProbeInt (ULONG *pcsecProbe)
597 {
598    *pcsecProbe = 30;
599    // TODO: NEED REGISTRY SETTING
600 }
601
602
603 BOOL Config_SetProbeInt (ULONG csecProbe, ULONG *pStatus)
604 {
605    BOOL rc = TRUE;
606    ULONG status = 0;
607
608    // TODO: NEED REGISTRY SETTING
609    if (Config_GetServiceState() == SERVICE_RUNNING)
610       {
611       struct chservinfo checkserv;
612       memset (&checkserv, 0x00, sizeof(checkserv));
613       checkserv.magic = 0x12345678;
614       checkserv.tinterval = csecProbe;
615
616       BYTE OutData[ PIOCTL_MAXSIZE ];
617       memset (OutData, 0x00, sizeof(OutData));
618
619       struct ViceIoctl IOInfo;
620       IOInfo.in_size = sizeof(checkserv);
621       IOInfo.in = (char *)&checkserv;
622       IOInfo.out = (char *)OutData;
623       IOInfo.out_size = PIOCTL_MAXSIZE;
624
625       if ((status = pioctl (0, VIOCCKSERV, &IOInfo, 1)) != 0)
626          {
627          rc = FALSE;
628          }
629       }
630
631    if (pStatus && !rc)
632       *pStatus = status;
633    if (!rc)
634       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_PROBE, TEXT("%ld"), status);
635    return rc;
636 }
637
638
639
640 void Config_GetNumThreads (ULONG *pcThreads)
641 {
642    if (!Config_ReadGlobalNum (TEXT("ServerThreads"), (DWORD*)pcThreads))
643       *pcThreads = CM_CONFIGDEFAULT_SVTHREADS;
644 }
645
646
647 BOOL Config_SetNumThreads (ULONG cThreads, ULONG *pStatus)
648 {
649    Config_WriteGlobalNum (TEXT("ServerThreads"), cThreads);
650    g.fNeedRestart = TRUE;
651    return TRUE;
652 }
653
654
655
656 void Config_GetNumDaemons (ULONG *pcDaemons)
657 {
658    if (!Config_ReadGlobalNum (TEXT("Daemons"), (DWORD*)pcDaemons))
659       *pcDaemons = CM_CONFIGDEFAULT_DAEMONS;
660 }
661
662
663 BOOL Config_SetNumDaemons (ULONG cDaemons, ULONG *pStatus)
664 {
665    Config_WriteGlobalNum (TEXT("Daemons"), cDaemons);
666    g.fNeedRestart = TRUE;
667    return TRUE;
668 }
669
670
671
672 void Config_GetSysName (LPTSTR pszName)
673 {
674    if (!Config_ReadGlobalString (TEXT("SysName"), pszName, MAX_PATH))
675       lstrcpy (pszName, TEXT("i386_nt40"));
676 }
677
678
679 BOOL Config_SetSysName (LPCTSTR pszName, ULONG *pStatus)
680 {
681    BOOL rc = TRUE;
682    ULONG status = 0;
683
684    if (Config_GetServiceState() == SERVICE_RUNNING)
685       {
686       struct {
687          ULONG cbData;
688          TCHAR szData[ PIOCTL_MAXSIZE ];
689       } InData;
690       memset (&InData, 0x00, sizeof(InData));
691       InData.cbData = lstrlen(pszName);
692       lstrcpy (InData.szData, pszName);
693
694       BYTE OutData[ PIOCTL_MAXSIZE ];
695       memset (OutData, 0x00, sizeof(OutData));
696
697       struct ViceIoctl IOInfo;
698       IOInfo.in_size = sizeof(ULONG) +lstrlen(pszName) +1;
699       IOInfo.in = (char *)&InData;
700       IOInfo.out = (char *)OutData;
701       IOInfo.out_size = PIOCTL_MAXSIZE;
702
703       if ((status = pioctl (0, VIOC_AFS_SYSNAME, &IOInfo, 1)) != 0)
704          {
705          rc = FALSE;
706          }
707       }
708
709    if (rc)
710       {
711       Config_WriteGlobalString (TEXT("SysName"), pszName);
712       }
713
714    if (pStatus && !rc)
715       *pStatus = status;
716    if (!rc)
717       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_SYSNAME, TEXT("%ld"), status);
718    return rc;
719 }
720
721
722
723 void Config_GetRootVolume (LPTSTR pszName)
724 {
725    if (!Config_ReadGlobalString (TEXT("RootVolume"), pszName, MAX_PATH))
726       lstrcpy (pszName, TEXT("root.afs"));
727 }
728
729
730 BOOL Config_SetRootVolume (LPCTSTR pszName, ULONG *pStatus)
731 {
732    Config_WriteGlobalString (TEXT("RootVolume"), pszName);
733    g.fNeedRestart = TRUE;
734    return TRUE;
735 }
736
737
738
739 void Config_GetMountRoot (LPTSTR pszPath)
740 {
741    if (!Config_ReadGlobalString (TEXT("MountRoot"), pszPath, MAX_PATH))
742       lstrcpy (pszPath, TEXT("/afs"));
743 }
744
745
746 BOOL Config_SetMountRoot (LPCTSTR pszPath, ULONG *pStatus)
747 {
748    Config_WriteGlobalString (TEXT("MountRoot"), pszPath);
749    g.fNeedRestart = TRUE;
750    return TRUE;
751 }
752
753
754 BOOL Config_GetCacheInUse (ULONG *pckCacheInUse, ULONG *pStatus)
755 {
756    BOOL rc = TRUE;
757    ULONG status = 0;
758
759    *pckCacheInUse = 0;
760
761    if (Config_GetServiceState() != SERVICE_RUNNING)
762       {
763       rc = FALSE;
764       status = ERROR_SERVICE_NOT_ACTIVE;
765       }
766    else
767       {
768       BYTE OutData[ PIOCTL_MAXSIZE ];
769       memset (OutData, 0x00, sizeof(OutData));
770
771       struct ViceIoctl IOInfo;
772       IOInfo.in_size = 0;
773       IOInfo.in = (char *)0;
774       IOInfo.out = (char *)OutData;
775       IOInfo.out_size = PIOCTL_MAXSIZE;
776
777       if ((status = pioctl (0, VIOCGETCACHEPARMS, &IOInfo, 1)) != 0)
778          {
779          rc = FALSE;
780          }
781       else
782          {
783          *pckCacheInUse = ((LONG*)OutData)[1];
784          }
785       }
786
787    if (pStatus && !rc)
788       *pStatus = status;
789    return rc;
790 }
791
792 void Config_GetCachePath (LPTSTR pszCachePath)
793 {
794    if (!Config_ReadGlobalString (TEXT("CachePath"), pszCachePath, MAX_PATH)) {
795       TCHAR szPath[MAX_PATH];
796       GetWindowsDirectory(szPath, sizeof(szPath));
797                 szPath[2] = 0;  /* get drive letter only */
798                 strcat(szPath, "\\AFSCache");
799
800       lstrcpy (pszCachePath, szPath);
801    }
802 }        
803
804 BOOL Config_SetCachePath(LPCTSTR pszPath, ULONG *pStatus)
805 {
806    Config_WriteGlobalString (TEXT("CachePath"), pszPath);
807    g.fNeedRestart = TRUE;
808    return TRUE;
809 }
810
811 void Config_GetLanAdapter (ULONG *pnLanAdapter)
812 {
813    if (!Config_ReadGlobalNum (TEXT("LANadapter"), (DWORD*)pnLanAdapter))
814       *pnLanAdapter = -1;
815 }
816
817 BOOL Config_SetLanAdapter (ULONG nLanAdapter, ULONG *pStatus)
818 {
819    Config_WriteGlobalNum (TEXT("LANadapter"), nLanAdapter);
820    g.fNeedRestart = TRUE;
821    return TRUE;
822 }
823
824 void Config_GetTrapOnPanic (BOOL *pfFlag)
825 {
826    if (!Config_ReadGlobalNum (TEXT("TrapOnPanic"), (DWORD*)pfFlag))
827       *pfFlag = TRUE;
828 }
829
830 BOOL Config_SetTrapOnPanic (BOOL fFlag, ULONG *pStatus)
831 {
832    Config_WriteGlobalNum (TEXT("TrapOnPanic"), fFlag);
833    g.fNeedRestart = TRUE;
834    return TRUE;
835 }
836
837 void Config_GetTraceBufferSize (ULONG *pnBufSize)
838 {
839    if (!Config_ReadGlobalNum (TEXT("TraceBufferSize"), (DWORD*)pnBufSize))
840       *pnBufSize = 5000;
841 }
842
843 BOOL Config_SetTraceBufferSize (ULONG nBufSize, ULONG *pStatus)
844 {
845    Config_WriteGlobalNum (TEXT("TraceBufferSize"), nBufSize);
846    g.fNeedRestart = TRUE;
847    return TRUE;
848 }
849
850 void Config_GetLoginRetryInterval (ULONG *pnInterval)
851 {
852    if (!Config_ReadGlobalNum (TEXT("LoginRetryInterval"), (DWORD*)pnInterval))
853       *pnInterval = 30;
854 }
855
856 BOOL Config_SetLoginRetryInterval (ULONG nInterval, ULONG *pStatus)
857 {
858    Config_WriteGlobalNum (TEXT("LoginRetryInterval"), nInterval);
859    return TRUE;
860 }
861
862 void Config_GetFailLoginsSilently (BOOL *pfFlag)
863 {
864    if (!Config_ReadGlobalNum (TEXT("FailLoginsSilently"), (DWORD*)pfFlag))
865       *pfFlag = FALSE;
866 }
867
868 BOOL Config_SetFailLoginsSilently (BOOL fFlag, ULONG *pStatus)
869 {
870    Config_WriteGlobalNum (TEXT("FailLoginsSilently"), fFlag);
871    return TRUE;
872 }
873
874 void Config_GetReportSessionStartups (BOOL *pfFlag)
875 {
876    if (!Config_ReadGlobalNum (TEXT("ReportSessionStartups"), (DWORD*)pfFlag))
877       *pfFlag = FALSE;
878 }
879
880 BOOL Config_SetReportSessionStartups (BOOL fFlag, ULONG *pStatus)
881 {
882    Config_WriteGlobalNum (TEXT("ReportSessionStartups"), fFlag);
883    return TRUE;
884 }
885