Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / WINNT / client_config / config.cpp
1 extern "C" {
2 #include <afs/param.h>
3 #include <afs/stds.h>
4 }
5
6 #include "afs_config.h"
7
8 extern "C" {
9
10 #include "../afsd/fs_utils.h"
11
12 #define __CM_CONFIG_INTERFACES_ONLY__
13 #include "../afsd/cm_config.h"
14
15 #define __CM_IOCTL_INTERFACES_ONLY__
16 #include "../afsd/cm_ioctl.h"
17
18 } // extern "C"
19
20
21 #define cREALLOC_PREFS       32
22
23 #define cSERVERPREFS_CHUNK  256
24
25 #define PIOCTL_MAXSIZE     2048
26
27
28 /*
29  * REGISTRY ___________________________________________________________________
30  *
31  */
32
33 static TCHAR cszLANMANDEVICE[] = TEXT("\\Device\\LanmanRedirector\\");
34 const TCHAR AFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
35
36
37 /*
38  * ROUTINES ___________________________________________________________________
39  *
40  */
41
42 static DWORD log2 (DWORD dwValue)
43 {
44    for (DWORD dwLog = 0; (DWORD)(1<<dwLog) < dwValue; ++dwLog)
45       ;
46    return dwLog;
47 }
48
49 DWORD Config_GetServiceState (void)
50 {
51    if (!g.fIsWinNT)
52       {
53       TCHAR szGateway[ cchRESOURCE ] = TEXT("");
54       Config_GetGatewayName (szGateway);
55       return (szGateway[0]) ? SERVICE_RUNNING : SERVICE_STOPPED;
56       }
57
58    SERVICE_STATUS Status;
59    memset (&Status, 0x00, sizeof(Status));
60
61    SC_HANDLE hManager;
62    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
63       {
64       SC_HANDLE hService;
65       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
66          {
67          QueryServiceStatus (hService, &Status);
68          CloseServiceHandle (hService);
69          }
70
71       CloseServiceHandle (hManager);
72       }
73
74    return Status.dwCurrentState;
75 }
76
77
78 /*
79  * Configuration Routine ______________________________________________________
80  *
81  */
82
83 void Config_GetGatewayFlag (BOOL *pfFlag)
84 {
85    if (!Config_ReadNum (TEXT("IsGateway"), (DWORD*)pfFlag))
86       *pfFlag = FALSE;
87 }
88
89
90 BOOL Config_SetGatewayFlag (BOOL fFlag, ULONG *pStatus)
91 {
92    Config_WriteNum (TEXT("IsGateway"), fFlag);
93    g.fNeedRestart = TRUE;
94    return TRUE;
95 }
96
97
98 void Config_GetGatewayName (LPTSTR pszName)
99 {
100    if (!Config_ReadString (TEXT("Gateway"), pszName, MAX_PATH))
101       GetString (pszName, IDS_GATEWAY_UNKNOWN);
102    else if (!*pszName)
103       GetString (pszName, IDS_GATEWAY_UNKNOWN);
104 }
105
106
107 BOOL Config_SetGatewayName (LPCTSTR pszName, ULONG *pStatus)
108 {
109    TCHAR szBogus[ cchRESOURCE ];
110    GetString (szBogus, IDS_GATEWAY_UNKNOWN);
111    if (!lstrcmpi (szBogus, pszName))
112       {
113       Config_WriteString (TEXT("Gateway"), TEXT(""));
114       }
115    else
116       {
117       Config_WriteString (TEXT("Gateway"), pszName);
118       }
119
120    return TRUE;
121 }
122
123
124 void Config_FixGatewayDrives (void)
125 {
126    // Zip through the user's network drives and reconnect
127    // them as necessary.
128    //
129    for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
130       {
131       TCHAR szSubmount[ MAX_PATH ];
132       if (!GetDriveSubmount (chDrive, szSubmount))
133          continue;
134
135       // We've got a mapping into AFS!  Remove it, rather forcefully.
136       //
137       TCHAR szDrive[] = "@:";
138       szDrive[0] = chDrive;
139       WNetCancelConnection (szDrive, TRUE);
140       }
141
142    // Now recreate our drive mappings, based on the user's already-
143    // specified preferences.
144    //
145    DRIVEMAPLIST List;
146    QueryDriveMapList (&List);
147
148    for (size_t ii = 0; ii < 26; ++ii)
149       {
150       if (!List.aDriveMap[ii].szMapping[0])
151          continue;
152       ActivateDriveMap (List.aDriveMap[ii].chDrive, List.aDriveMap[ii].szMapping, List.aDriveMap[ii].szSubmount, List.aDriveMap[ii].fPersistent);
153       }
154 }
155
156
157 void Config_GetCellName (LPTSTR pszName)
158 {
159    if (!Config_ReadString (TEXT("Cell"), pszName, MAX_PATH))
160       GetString (pszName, IDS_CELL_UNKNOWN);
161    else if (!*pszName)
162       GetString (pszName, IDS_CELL_UNKNOWN);
163 }
164
165
166 BOOL Config_ContactGateway (LPTSTR pszGateway, LPTSTR pszCell)
167 {
168    BOOL rc = FALSE;
169
170    BYTE OutData[ PIOCTL_MAXSIZE ];
171    memset (OutData, 0x00, sizeof(OutData));
172
173    struct ViceIoctl IOInfo;
174    IOInfo.in_size = 0;
175    IOInfo.in = 0;
176    IOInfo.out = (char *)OutData;
177    IOInfo.out_size = PIOCTL_MAXSIZE;
178
179    TCHAR szOldGateway[ MAX_PATH ];
180    Config_GetGatewayName (szOldGateway);
181    Config_SetGatewayName (pszGateway);
182
183    ULONG status;
184    if ((status = pioctl (0, VIOC_GET_WS_CELL, &IOInfo, 1)) == 0)
185       {
186       if (OutData[0])
187          {
188          lstrcpy (pszCell, (LPCTSTR)OutData);
189          rc = TRUE;
190          }
191       }
192
193    Config_SetGatewayName (szOldGateway);
194
195    return rc;
196 }
197
198
199 BOOL Config_SetCellName (LPCTSTR pszName, ULONG *pStatus)
200 {
201    TCHAR szBogus[ cchRESOURCE ];
202    GetString (szBogus, IDS_CELL_UNKNOWN);
203    if (lstrcmpi (szBogus, pszName))
204       {
205       Config_WriteString (TEXT("Cell"), pszName);
206       g.fNeedRestart = TRUE;
207       }
208    return TRUE;
209 }
210
211
212 void Config_GetAuthentFlag (BOOL *pfFlag)
213 {
214    *pfFlag = FALSE;
215
216    HKEY hk;
217    if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Control\\NetworkProvider\\Order"), 0, KEY_QUERY_VALUE, &hk) == ERROR_SUCCESS)
218       {
219       if (g.fIsWinNT)
220          {
221          TCHAR szProviders[ MAX_PATH ] = TEXT("");
222          DWORD dwSize = sizeof(szProviders);
223
224          if (RegQueryValueEx (hk, TEXT("ProviderOrder"), NULL, NULL, (PBYTE)szProviders, &dwSize) == ERROR_SUCCESS)
225             {
226             for (LPTSTR pch = szProviders; *pch; )
227                {
228                if (!lstrncmpi (pch, TEXT("TransarcAFSDaemon"), lstrlen(TEXT("TransarcAFSDaemon"))))
229                   *pfFlag = TRUE;
230
231                for ( ; *pch && (*pch != TEXT(',')); ++pch)
232                   ;
233                for ( ; *pch == TEXT(','); ++pch)
234                   ;
235                }
236             }
237
238          RegCloseKey (hk);
239          }
240       else // (!g.fIsWinNT)
241          {
242          TCHAR szLHS[ MAX_PATH ] = TEXT("");
243          DWORD dwSize = sizeof(szLHS);
244
245          if (RegQueryValueEx (hk, TEXT("TransarcAFSDaemon"), NULL, NULL, (PBYTE)szLHS, &dwSize) == ERROR_SUCCESS)
246             *pfFlag = TRUE;
247          }
248       }
249 }
250
251
252 BOOL Config_SetAuthentFlag (BOOL fFlag, ULONG *pStatus)
253 {
254    ULONG status = 0;
255    BOOL rc = FALSE;
256
257    HKEY hk;
258    DWORD dwDisp;
259    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)
260       {
261       if (g.fIsWinNT)
262          {
263          TCHAR szOldProviders[ MAX_PATH ] = TEXT("");
264          TCHAR szNewProviders[ MAX_PATH ] = TEXT("");
265          DWORD dwSize = sizeof(szOldProviders);
266          RegQueryValueEx (hk, TEXT("ProviderOrder"), NULL, NULL, (PBYTE)szOldProviders, &dwSize);
267
268          for (LPTSTR pch = szOldProviders; *pch; )
269             {
270             BOOL fCopy = TRUE;
271             if (!lstrncmpi (pch, TEXT("TransarcAFSDaemon"), lstrlen(TEXT("TransarcAFSDaemon"))))
272                {
273                fCopy = fFlag;
274                fFlag = FALSE;
275                }
276
277             if (fCopy)
278                {
279                LPTSTR pchOut = &szNewProviders[ lstrlen(szNewProviders) ];
280                if (szNewProviders[0])
281                   *pchOut++ = TEXT(',');
282                for ( ; *pch && (*pch != TEXT(',')); )
283                   *pchOut++ = *pch++;
284                *pchOut = TEXT('\0');
285                }
286
287             for ( ; *pch && (*pch != TEXT(',')); ++pch)
288                ;
289             for ( ; *pch == TEXT(','); ++pch)
290                ;
291             }
292
293          if (fFlag)
294             {
295             if (szNewProviders[0])
296                lstrcat (szNewProviders, TEXT(","));
297             lstrcat (szNewProviders, TEXT("TransarcAFSDaemon"));
298             }
299
300          if ((status = RegSetValueEx (hk, TEXT("ProviderOrder"), NULL, REG_SZ, (PBYTE)szNewProviders, sizeof(TCHAR)*(1+lstrlen(szNewProviders)))) == ERROR_SUCCESS)
301             rc = TRUE;
302          }
303       else // (!g.fIsWinNT)
304          {
305          TCHAR szLHS[ cchRESOURCE ] = TEXT("TransarcAFSDaemon");
306          TCHAR szRHS[ cchRESOURCE ] = TEXT("");
307
308          if (fFlag)
309             {
310             if ((status = RegSetValueEx (hk, szLHS, NULL, REG_SZ, (PBYTE)szRHS, sizeof(TCHAR)*(lstrlen(szRHS)+1))) == 0)
311                rc = TRUE;
312             }
313          else
314             {
315             RegDeleteValue (hk, szLHS);
316             rc = TRUE;
317             }
318          }
319
320       RegCloseKey (hk);
321       }
322
323    if (pStatus && !rc)
324       *pStatus = status;
325    if (!rc)
326       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_AUTHENT, TEXT("%ld"), status);
327    return rc;
328 }
329
330
331 void Config_GetTrayIconFlag (BOOL *pfFlag)
332 {
333    if (!Config_ReadNum (TEXT("ShowTrayIcon"), (DWORD*)pfFlag))
334       *pfFlag = FALSE;
335 }
336
337
338 BOOL Config_SetTrayIconFlag (BOOL fFlag, ULONG *pStatus)
339 {
340    Config_WriteNum (TEXT("ShowTrayIcon"), fFlag);
341
342    for (HWND hSearch = GetWindow (GetDesktopWindow(), GW_CHILD);
343         hSearch && IsWindow(hSearch);
344         hSearch = GetWindow (hSearch, GW_HWNDNEXT))
345       {
346       TCHAR szClassName[ cchRESOURCE ];
347       if (GetClassName (hSearch, szClassName, cchRESOURCE))
348          {
349          if (!lstrcmpi (szClassName, TEXT("AfsCreds")))
350             break;
351          }
352       }
353
354    if (hSearch && IsWindow(hSearch))
355       {
356       UINT msgCheckTerminate = RegisterWindowMessage (TEXT("AfsCredsCheckTerminate"));
357       PostMessage (hSearch, msgCheckTerminate, 0, 0);
358       }
359    else if (fFlag && !(hSearch && IsWindow(hSearch)))
360       {
361       WinExec (TEXT("AfsCreds.exe /quiet"), SW_SHOW);
362       }
363
364    return TRUE;
365 }
366
367
368 PSERVERPREFS Config_GetServerPrefs (BOOL fVLServers)
369 {
370    PSERVERPREFS pPrefs = New (SERVERPREFS);
371    memset (pPrefs, 0x00, sizeof(SERVERPREFS));
372    pPrefs->fVLServers = fVLServers;
373
374    if (Config_GetServiceState() == SERVICE_RUNNING)
375       {
376       // We retrieve server prefs in batches--start that loop now.
377       //
378       size_t iOut = 0;
379       for (int iOffset = 0; ; )
380          {
381          cm_SPrefRequest_t InData;
382          memset (&InData, 0x00, sizeof(InData));
383          InData.offset = iOffset;
384          InData.flags = (pPrefs->fVLServers) ? CM_SPREF_VLONLY : 0;
385          InData.num_servers = cSERVERPREFS_CHUNK;
386
387          BYTE OutDataStorage[ sizeof(cm_SPrefInfo_t) + cSERVERPREFS_CHUNK * sizeof(cm_SPref_t) ];
388          memset (OutDataStorage, 0x00, sizeof(OutDataStorage));
389          cm_SPrefInfo_t *pOutData = (cm_SPrefInfo_t *)OutDataStorage;
390
391          struct ViceIoctl IOInfo;
392          IOInfo.in_size = sizeof(InData);
393          IOInfo.in = (char *)&InData;
394          IOInfo.out = (char *)pOutData;
395          IOInfo.out_size = sizeof(cm_SPrefInfo_t) + cSERVERPREFS_CHUNK * sizeof(cm_SPref_t);
396
397          if (pioctl (0, VIOC_GETSPREFS, &IOInfo, 1) != 0)
398             break;
399
400          if (!REALLOC (pPrefs->aPrefs, pPrefs->cPrefs, iOut + pOutData->num_servers, cREALLOC_PREFS))
401             break;
402
403          for (size_t ii = 0; ii < pOutData->num_servers; ++ii)
404             {
405             pPrefs->aPrefs[ iOut ].ipServer = pOutData->servers[ ii ].host.s_addr;
406             pPrefs->aPrefs[ iOut ].iRank = pOutData->servers[ ii ].rank;
407             iOut ++;
408             }
409
410          if ((iOffset = pOutData->next_offset) == 0)
411             break;
412          }
413      }
414
415    return pPrefs;
416 }
417
418
419 BOOL Config_SetServerPrefs (PSERVERPREFS pPrefs, ULONG *pStatus)
420 {
421    BOOL rc = TRUE;
422    ULONG status = 0;
423
424    if (pPrefs)
425       {
426       size_t cChanged = 0;
427       for (size_t ii = 0; ii < pPrefs->cPrefs; ++ii)
428          {
429          if (pPrefs->aPrefs[ ii ].fChanged)
430             ++cChanged;
431          }
432
433       if (cChanged)
434          {
435          if (Config_GetServiceState() != SERVICE_RUNNING)
436             {
437             rc = FALSE;
438             status = ERROR_SERVICE_NOT_ACTIVE;
439             }
440          else
441             {
442             size_t cbInDataStorage = sizeof(cm_SSetPref_t) + cChanged * sizeof(cm_SPref_t);
443
444             PBYTE pInDataStorage;
445             if ((pInDataStorage = (PBYTE)Allocate (cbInDataStorage)) == NULL)
446                {
447                rc = FALSE;
448                status = ERROR_NOT_ENOUGH_MEMORY;
449                }
450             else
451                {
452                memset (pInDataStorage, 0x00, sizeof(cbInDataStorage));
453
454                cm_SSetPref_t *pInData = (cm_SSetPref_t*)pInDataStorage;
455                pInData->flags = (pPrefs->fVLServers) ? CM_SPREF_VLONLY : 0;
456                pInData->num_servers = cChanged;
457
458                size_t iOut = 0;
459                for (ii = 0; ii < pPrefs->cPrefs; ++ii)
460                   {
461                   if (pPrefs->aPrefs[ ii ].fChanged)
462                      {
463                      pInData->servers[ iOut ].host.s_addr = pPrefs->aPrefs[ ii ].ipServer;
464                      pInData->servers[ iOut ].rank = (unsigned short)pPrefs->aPrefs[ ii ].iRank;
465                      iOut++;
466                      }
467                   }
468
469                BYTE OutDataStorage[ PIOCTL_MAXSIZE ];
470
471                struct ViceIoctl IOInfo;
472                IOInfo.in_size = cbInDataStorage;
473                IOInfo.in = (char *)pInData;
474                IOInfo.out = (char *)OutDataStorage;
475                IOInfo.out_size = PIOCTL_MAXSIZE;
476
477                if ((status = pioctl (0, VIOC_SETSPREFS, &IOInfo, 1)) != 0)
478                   {
479                   rc = FALSE;
480                   }
481
482                Free (pInDataStorage);
483                }
484             }
485          }
486       }
487
488    if (pStatus && !rc)
489       *pStatus = status;
490    if (!rc)
491       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_PREFS, TEXT("%ld"), status);
492    return rc;
493 }
494
495
496 void Config_FreeServerPrefs (PSERVERPREFS pPrefs)
497 {
498    if (pPrefs->aPrefs)
499       Free (pPrefs->aPrefs);
500    memset (pPrefs, 0xFD, sizeof(SERVERPREFS));
501    Delete (pPrefs);
502 }
503
504
505 void Config_GetCacheSize (ULONG *pckCache)
506 {
507    if (!Config_ReadNum (TEXT("CacheSize"), (DWORD*)pckCache))
508       *pckCache = CM_CONFIGDEFAULT_CACHESIZE;
509 }
510
511
512 BOOL Config_SetCacheSize (ULONG ckCache, ULONG *pStatus)
513 {
514    BOOL rc = TRUE;
515    ULONG status = 0;
516
517    if (Config_GetServiceState() == SERVICE_RUNNING)
518       {
519       ULONG ckCacheNow;
520       Config_GetCacheSize (&ckCacheNow);
521       if (ckCacheNow > ckCache)
522          {
523          Message (MB_ICONHAND, GetErrorTitle(), IDS_SHRINKCACHE);
524          return FALSE;
525          }
526
527       struct ViceIoctl IOInfo;
528       IOInfo.in_size = sizeof(ULONG);
529       IOInfo.in = (char *)&ckCache;
530       IOInfo.out = (char *)0;
531       IOInfo.out_size = 0;
532
533       if ((status = pioctl (0, VIOCSETCACHESIZE, &IOInfo, 1)) != 0)
534          {
535          rc = FALSE;
536          }
537       }
538
539    if (rc)
540       {
541       Config_WriteNum (TEXT("CacheSize"), ckCache);
542       }
543
544    if (pStatus && !rc)
545       *pStatus = status;
546    if (!rc)
547       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_CACHE, TEXT("%ld"), status);
548    return rc;
549 }
550
551
552
553 void Config_GetChunkSize (ULONG *pckChunk)
554 {
555    if (!Config_ReadNum (TEXT("ChunkSize"), (DWORD*)pckChunk))
556       *pckChunk = CM_CONFIGDEFAULT_CHUNKSIZE;
557    *pckChunk = max (*pckChunk, 10);
558    *pckChunk = (1 << ((*pckChunk)-10));
559 }
560
561
562 BOOL Config_SetChunkSize (ULONG ckChunk, ULONG *pStatus)
563 {
564    Config_WriteNum (TEXT("ChunkSize"), log2(ckChunk * 1024));
565    g.fNeedRestart = TRUE;
566    return TRUE;
567 }
568
569
570
571 void Config_GetStatEntries (ULONG *pcEntries)
572 {
573    if (!Config_ReadNum (TEXT("Stats"), (DWORD*)pcEntries))
574       *pcEntries = CM_CONFIGDEFAULT_STATS;
575 }
576
577
578 BOOL Config_SetStatEntries (ULONG cEntries, ULONG *pStatus)
579 {
580    Config_WriteNum (TEXT("Stats"), cEntries);
581    g.fNeedRestart = TRUE;
582    return TRUE;
583 }
584
585
586
587 void Config_GetProbeInt (ULONG *pcsecProbe)
588 {
589    *pcsecProbe = 30;
590    // TODO: NEED REGISTRY SETTING
591 }
592
593
594 BOOL Config_SetProbeInt (ULONG csecProbe, ULONG *pStatus)
595 {
596    BOOL rc = TRUE;
597    ULONG status = 0;
598
599    // TODO: NEED REGISTRY SETTING
600    if (Config_GetServiceState() == SERVICE_RUNNING)
601       {
602       struct chservinfo checkserv;
603       memset (&checkserv, 0x00, sizeof(checkserv));
604       checkserv.magic = 0x12345678;
605       checkserv.tinterval = csecProbe;
606
607       BYTE OutData[ PIOCTL_MAXSIZE ];
608       memset (OutData, 0x00, sizeof(OutData));
609
610       struct ViceIoctl IOInfo;
611       IOInfo.in_size = sizeof(checkserv);
612       IOInfo.in = (char *)&checkserv;
613       IOInfo.out = (char *)OutData;
614       IOInfo.out_size = PIOCTL_MAXSIZE;
615
616       if ((status = pioctl (0, VIOCCKSERV, &IOInfo, 1)) != 0)
617          {
618          rc = FALSE;
619          }
620       }
621
622    if (pStatus && !rc)
623       *pStatus = status;
624    if (!rc)
625       Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_PROBE, TEXT("%ld"), status);
626    return rc;
627 }
628
629
630
631 void Config_GetNumThreads (ULONG *pcThreads)
632 {
633    if (!Config_ReadNum (TEXT("ServerThreads"), (DWORD*)pcThreads))
634       *pcThreads = CM_CONFIGDEFAULT_SVTHREADS;
635 }
636
637
638 BOOL Config_SetNumThreads (ULONG cThreads, ULONG *pStatus)
639 {
640    Config_WriteNum (TEXT("ServerThreads"), cThreads);
641    g.fNeedRestart = TRUE;
642    return TRUE;
643 }
644
645
646
647 void Config_GetNumDaemons (ULONG *pcDaemons)
648 {
649    if (!Config_ReadNum (TEXT("Daemons"), (DWORD*)pcDaemons))
650       *pcDaemons = CM_CONFIGDEFAULT_DAEMONS;
651 }
652
653
654 BOOL Config_SetNumDaemons (ULONG cDaemons, ULONG *pStatus)
655 {
656    Config_WriteNum (TEXT("Daemons"), cDaemons);
657    g.fNeedRestart = TRUE;
658    return TRUE;
659 }
660
661
662
663 void Config_GetSysName (LPTSTR pszName)
664 {
665    if (!Config_ReadString (TEXT("SysName"), pszName, MAX_PATH))
666       lstrcpy (pszName, TEXT("i386_nt40"));
667 }
668
669
670 BOOL Config_SetSysName (LPCTSTR pszName, ULONG *pStatus)
671 {
672    BOOL rc = TRUE;
673    ULONG status = 0;
674
675    if (Config_GetServiceState() == SERVICE_RUNNING)
676       {
677       struct {
678          ULONG cbData;
679          TCHAR szData[ PIOCTL_MAXSIZE ];
680       } InData;
681       memset (&InData, 0x00, sizeof(InData));
682       InData.cbData = lstrlen(pszName);
683       lstrcpy (InData.szData, pszName);
684
685       BYTE OutData[ PIOCTL_MAXSIZE ];
686       memset (OutData, 0x00, sizeof(OutData));
687
688       struct ViceIoctl IOInfo;
689       IOInfo.in_size = sizeof(ULONG) +lstrlen(pszName) +1;
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_WriteString (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_ReadString (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_WriteString (TEXT("RootVolume"), pszName);
724    g.fNeedRestart = TRUE;
725    return TRUE;
726 }
727
728
729
730 void Config_GetMountRoot (LPTSTR pszPath)
731 {
732    if (!Config_ReadString (TEXT("MountRoot"), pszPath, MAX_PATH))
733       lstrcpy (pszPath, TEXT("/afs"));
734 }
735
736
737 BOOL Config_SetMountRoot (LPCTSTR pszPath, ULONG *pStatus)
738 {
739    Config_WriteString (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_ReadString (TEXT("CachePath"), pszCachePath, MAX_PATH)) {
786       TCHAR szPath[MAX_PATH];
787       GetWindowsDirectory(szPath, sizeof(szPath));
788                 szPath[2] = 0;  /* get drive letter only */
789                 strcat(szPath, "\\AFSCache");
790
791       lstrcpy (pszCachePath, szPath);
792    }
793 }        
794
795 BOOL Config_SetCachePath(LPCTSTR pszPath, ULONG *pStatus)
796 {
797    Config_WriteString (TEXT("CachePath"), pszPath);
798    g.fNeedRestart = TRUE;
799    return TRUE;
800 }
801
802 void Config_GetLanAdapter (ULONG *pnLanAdapter)
803 {
804    if (!Config_ReadNum (TEXT("LANadapter"), (DWORD*)pnLanAdapter))
805       *pnLanAdapter = 0;
806 }
807
808 BOOL Config_SetLanAdapter (ULONG nLanAdapter, ULONG *pStatus)
809 {
810    Config_WriteNum (TEXT("LANadapter"), nLanAdapter);
811    g.fNeedRestart = TRUE;
812    return TRUE;
813 }
814
815 void Config_GetTrapOnPanic (BOOL *pfFlag)
816 {
817    if (!Config_ReadNum (TEXT("TrapOnPanic"), (DWORD*)pfFlag))
818       *pfFlag = TRUE;
819 }
820
821 BOOL Config_SetTrapOnPanic (BOOL fFlag, ULONG *pStatus)
822 {
823    Config_WriteNum (TEXT("TrapOnPanic"), fFlag);
824    g.fNeedRestart = TRUE;
825    return TRUE;
826 }
827
828 void Config_GetTraceBufferSize (ULONG *pnBufSize)
829 {
830    if (!Config_ReadNum (TEXT("TraceBufferSize"), (DWORD*)pnBufSize))
831       *pnBufSize = 5000;
832 }
833
834 BOOL Config_SetTraceBufferSize (ULONG nBufSize, ULONG *pStatus)
835 {
836    Config_WriteNum (TEXT("TraceBufferSize"), nBufSize);
837    g.fNeedRestart = TRUE;
838    return TRUE;
839 }
840
841 void Config_GetLoginRetryInterval (ULONG *pnInterval)
842 {
843    if (!Config_ReadNum (TEXT("LoginRetryInterval"), (DWORD*)pnInterval))
844       *pnInterval = 30;
845 }
846
847 BOOL Config_SetLoginRetryInterval (ULONG nInterval, ULONG *pStatus)
848 {
849    Config_WriteNum (TEXT("LoginRetryInterval"), nInterval);
850    return TRUE;
851 }
852
853 void Config_GetFailLoginsSilently (BOOL *pfFlag)
854 {
855    if (!Config_ReadNum (TEXT("FailLoginsSilently"), (DWORD*)pfFlag))
856       *pfFlag = FALSE;
857 }
858
859 BOOL Config_SetFailLoginsSilently (BOOL fFlag, ULONG *pStatus)
860 {
861    Config_WriteNum (TEXT("FailLoginsSilently"), fFlag);
862    return TRUE;
863 }
864
865 void Config_GetReportSessionStartups (BOOL *pfFlag)
866 {
867    if (!Config_ReadNum (TEXT("ReportSessionStartups"), (DWORD*)pfFlag))
868       *pfFlag = FALSE;
869 }
870
871 BOOL Config_SetReportSessionStartups (BOOL fFlag, ULONG *pStatus)
872 {
873    Config_WriteNum (TEXT("ReportSessionStartups"), fFlag);
874    return TRUE;
875 }
876
877 void Config_GetGlobalDriveList (DRIVEMAPLIST *pDriveList)
878 {
879    // Read the GlobalAutoMapper registry key
880    TCHAR szDriveToMapTo[5];
881    DWORD dwResult;
882    TCHAR szKeyName[256];
883    HKEY hKey;
884    DWORD dwIndex = 0;
885    DWORD dwDriveSize;
886    DWORD dwSubMountSize;
887    TCHAR szSubMount[256];
888    DWORD dwType;
889
890    if (!pDriveList)
891       return;
892
893    memset(pDriveList, 0, sizeof(DRIVEMAPLIST));
894
895    lstrcpy(szKeyName, AFSConfigKeyName);
896    lstrcat(szKeyName, TEXT("\\GlobalAutoMapper"));
897
898    dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
899    if (dwResult != ERROR_SUCCESS)
900       return;
901
902    // Get the drive map list so we can lookup the paths that go with our submounts
903         DRIVEMAPLIST DriveMapList;
904    memset(&DriveMapList, 0, sizeof(DRIVEMAPLIST));
905    QueryDriveMapList (&DriveMapList);
906
907    while (1) {
908       dwDriveSize = sizeof(szDriveToMapTo);
909       dwSubMountSize = sizeof(szSubMount);
910       
911       dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, (BYTE*)szSubMount, &dwSubMountSize);
912       if (dwResult != ERROR_SUCCESS)
913          break;
914       
915       szDriveToMapTo[0] = _totupper(szDriveToMapTo[0]);
916         
917       int nCurDrive = szDriveToMapTo[0] - TEXT('A');
918         
919       pDriveList->aDriveMap[nCurDrive].chDrive = szDriveToMapTo[0];
920       lstrcpy(pDriveList->aDriveMap[nCurDrive].szSubmount, szSubMount);
921
922       // Find the path that goes with this submount
923       SubmountToPath (&DriveMapList, pDriveList->aDriveMap[nCurDrive].szMapping, szSubMount, FALSE);
924    }        
925
926    FreeDriveMapList(&DriveMapList);
927
928    RegCloseKey(hKey);
929 }
930
931
932 /*
933  * Configuration Read/Modify Functions ________________________________________
934  *
935  * Temporarily these just modify the local Registry.
936  * In the near future, they will modify the Registry on the
937  * gateway, if a gateway is being used.
938  *
939  */
940
941 BOOL Config_ReadNum (LPCTSTR pszLHS, DWORD *pdwRHS)
942 {
943    HKEY hk;
944    if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hk) != ERROR_SUCCESS)
945       return FALSE;
946
947    DWORD dwSize = sizeof(*pdwRHS);
948    if (RegQueryValueEx (hk, pszLHS, NULL, NULL, (PBYTE)pdwRHS, &dwSize) != ERROR_SUCCESS)
949       {
950       RegCloseKey (hk);
951       return FALSE;
952       }
953
954    RegCloseKey (hk);
955    return TRUE;
956 }
957
958
959 BOOL Config_ReadString (LPCTSTR pszLHS, LPTSTR pszRHS, size_t cchMax)
960 {
961    HKEY hk;
962    if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hk) != ERROR_SUCCESS)
963       return FALSE;
964
965    DWORD dwSize = sizeof(TCHAR) * cchMax;
966    if (RegQueryValueEx (hk, pszLHS, NULL, NULL, (PBYTE)pszRHS, &dwSize) != ERROR_SUCCESS)
967       {
968       RegCloseKey (hk);
969       return FALSE;
970       }
971
972    RegCloseKey (hk);
973    return TRUE;
974 }
975
976
977 void Config_WriteNum (LPCTSTR pszLHS, DWORD dwRHS)
978 {
979    HKEY hk;
980    DWORD dwDisp;
981    if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
982       {
983       RegSetValueEx (hk, pszLHS, NULL, REG_DWORD, (PBYTE)&dwRHS, sizeof(dwRHS));
984       RegCloseKey (hk);
985       }
986 }
987
988
989 void Config_WriteString (LPCTSTR pszLHS, LPCTSTR pszRHS)
990 {
991    HKEY hk;
992    DWORD dwDisp;
993    if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
994       {
995       RegSetValueEx (hk, pszLHS, NULL, REG_SZ, (PBYTE)pszRHS, sizeof(TCHAR) * (1+lstrlen(pszRHS)));
996       RegCloseKey (hk);
997       }
998 }
999