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