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