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