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