/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #include #include extern "C" { #include #include } #include "afs_config.h" #include extern "C" { #include "../afsd/fs_utils.h" #define __CM_CONFIG_INTERFACES_ONLY__ #include "../afsd/cm_config.h" #include "../afsd/cm_nls.h" #define __CM_IOCTL_INTERFACES_ONLY__ #include "../afsd/cm_ioctl.h" } // extern "C" #define cREALLOC_PREFS 32 #define cSERVERPREFS_CHUNK 256 #define PIOCTL_MAXSIZE 2048 /* * ROUTINES ___________________________________________________________________ * */ static DWORD log2 (DWORD dwValue) { DWORD dwLog; for (dwLog = 0; (DWORD)(1<fVLServers = fVLServers; if (Config_GetServiceState() == SERVICE_RUNNING) { // We retrieve server prefs in batches--start that loop now. // size_t iOut = 0; for (int iOffset = 0; ; ) { cm_SPrefRequest_t InData; memset (&InData, 0x00, sizeof(InData)); InData.offset = iOffset; InData.flags = (pPrefs->fVLServers) ? CM_SPREF_VLONLY : 0; InData.num_servers = cSERVERPREFS_CHUNK; BYTE OutDataStorage[ sizeof(cm_SPrefInfo_t) + cSERVERPREFS_CHUNK * sizeof(cm_SPref_t) ]; memset (OutDataStorage, 0x00, sizeof(OutDataStorage)); cm_SPrefInfo_t *pOutData = (cm_SPrefInfo_t *)OutDataStorage; struct ViceIoctl IOInfo; IOInfo.in_size = sizeof(InData); IOInfo.in = (char *)&InData; IOInfo.out = (char *)pOutData; IOInfo.out_size = sizeof(cm_SPrefInfo_t) + cSERVERPREFS_CHUNK * sizeof(cm_SPref_t); if (pioctl (0, VIOC_GETSPREFS, &IOInfo, 1) != 0) break; if (!REALLOC (pPrefs->aPrefs, pPrefs->cPrefs, iOut + pOutData->num_servers, cREALLOC_PREFS)) break; for (size_t ii = 0; ii < pOutData->num_servers; ++ii) { pPrefs->aPrefs[ iOut ].ipServer = pOutData->servers[ ii ].host.s_addr; pPrefs->aPrefs[ iOut ].iRank = pOutData->servers[ ii ].rank; iOut ++; } if ((iOffset = pOutData->next_offset) == 0) break; } } return pPrefs; } BOOL Config_SetServerPrefs (PSERVERPREFS pPrefs, ULONG *pStatus) { BOOL rc = TRUE; ULONG status = 0; if (pPrefs) { size_t cChanged = 0; size_t ii; for (ii = 0; ii < pPrefs->cPrefs; ++ii) { if (pPrefs->aPrefs[ ii ].fChanged) ++cChanged; } if (cChanged) { if (Config_GetServiceState() != SERVICE_RUNNING) { rc = FALSE; status = ERROR_SERVICE_NOT_ACTIVE; } else { size_t cbInDataStorage = sizeof(cm_SSetPref_t) + cChanged * sizeof(cm_SPref_t); PBYTE pInDataStorage; if ((pInDataStorage = (PBYTE)Allocate (cbInDataStorage)) == NULL) { rc = FALSE; status = ERROR_NOT_ENOUGH_MEMORY; } else { memset (pInDataStorage, 0x00, sizeof(cbInDataStorage)); cm_SSetPref_t *pInData = (cm_SSetPref_t*)pInDataStorage; pInData->flags = (pPrefs->fVLServers) ? CM_SPREF_VLONLY : 0; pInData->num_servers = cChanged; size_t iOut = 0; for (ii = 0; ii < pPrefs->cPrefs; ++ii) { if (pPrefs->aPrefs[ ii ].fChanged) { pInData->servers[ iOut ].host.s_addr = pPrefs->aPrefs[ ii ].ipServer; pInData->servers[ iOut ].rank = (unsigned short)pPrefs->aPrefs[ ii ].iRank; iOut++; } } BYTE OutDataStorage[ PIOCTL_MAXSIZE ]; struct ViceIoctl IOInfo; IOInfo.in_size = cbInDataStorage; IOInfo.in = (char *)pInData; IOInfo.out = (char *)OutDataStorage; IOInfo.out_size = PIOCTL_MAXSIZE; if ((status = pioctl (0, VIOC_SETSPREFS, &IOInfo, 1)) != 0) { rc = FALSE; } Free (pInDataStorage); } } } } if (pStatus && !rc) *pStatus = status; if (!rc) Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_PREFS, TEXT("%ld"), status); return rc; } void Config_FreeServerPrefs (PSERVERPREFS pPrefs) { if (pPrefs->aPrefs) Free (pPrefs->aPrefs); memset (pPrefs, 0xFD, sizeof(SERVERPREFS)); Delete (pPrefs); } void Config_GetCacheSize (ULONG *pckCache) { if (!Config_ReadGlobalNum (TEXT("CacheSize"), (DWORD*)pckCache)) *pckCache = CM_CONFIGDEFAULT_CACHESIZE; } BOOL Config_SetCacheSize (ULONG ckCache, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("CacheSize"), ckCache); g.fNeedRestart = TRUE; return TRUE; } void Config_GetChunkSize (ULONG *pckChunk) { if (!Config_ReadGlobalNum (TEXT("ChunkSize"), (DWORD*)pckChunk)) *pckChunk = CM_CONFIGDEFAULT_CHUNKSIZE; *pckChunk = max (*pckChunk, 10); *pckChunk = (1 << ((*pckChunk)-10)); } BOOL Config_SetChunkSize (ULONG ckChunk, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("ChunkSize"), log2(ckChunk * 1024)); g.fNeedRestart = TRUE; return TRUE; } void Config_GetStatEntries (ULONG *pcEntries) { if (!Config_ReadGlobalNum (TEXT("Stats"), (DWORD*)pcEntries)) *pcEntries = CM_CONFIGDEFAULT_STATS; } BOOL Config_SetStatEntries (ULONG cEntries, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("Stats"), cEntries); g.fNeedRestart = TRUE; return TRUE; } void Config_GetProbeInt (ULONG *pcsecProbe) { *pcsecProbe = 30; // TODO: NEED REGISTRY SETTING } BOOL Config_SetProbeInt (ULONG csecProbe, ULONG *pStatus) { BOOL rc = TRUE; ULONG status = 0; // TODO: NEED REGISTRY SETTING if (Config_GetServiceState() == SERVICE_RUNNING) { struct chservinfo checkserv; memset (&checkserv, 0x00, sizeof(checkserv)); checkserv.magic = 0x12345678; checkserv.tinterval = csecProbe; BYTE OutData[ PIOCTL_MAXSIZE ]; memset (OutData, 0x00, sizeof(OutData)); struct ViceIoctl IOInfo; IOInfo.in_size = sizeof(checkserv); IOInfo.in = (char *)&checkserv; IOInfo.out = (char *)OutData; IOInfo.out_size = PIOCTL_MAXSIZE; if ((status = pioctl (0, VIOCCKSERV, &IOInfo, 1)) != 0) { rc = FALSE; } } if (pStatus && !rc) *pStatus = status; if (!rc) Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_PROBE, TEXT("%ld"), status); return rc; } void Config_GetNumThreads (ULONG *pcThreads) { if (!Config_ReadGlobalNum (TEXT("ServerThreads"), (DWORD*)pcThreads)) *pcThreads = CM_CONFIGDEFAULT_SVTHREADS; } BOOL Config_SetNumThreads (ULONG cThreads, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("ServerThreads"), cThreads); g.fNeedRestart = TRUE; return TRUE; } void Config_GetNumDaemons (ULONG *pcDaemons) { if (!Config_ReadGlobalNum (TEXT("Daemons"), (DWORD*)pcDaemons)) *pcDaemons = CM_CONFIGDEFAULT_DAEMONS; } BOOL Config_SetNumDaemons (ULONG cDaemons, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("Daemons"), cDaemons); g.fNeedRestart = TRUE; return TRUE; } void Config_GetSysName (LPTSTR pszName) { if (!Config_ReadGlobalString (TEXT("SysName"), pszName, MAX_PATH)) lstrcpy (pszName, TEXT("i386_nt40")); } BOOL Config_SetSysName (LPCTSTR pszName, ULONG *pStatus) { BOOL rc = TRUE; ULONG status = 0; if (Config_GetServiceState() == SERVICE_RUNNING) { struct { ULONG cbData; TCHAR szData[ PIOCTL_MAXSIZE ]; } InData; memset (&InData, 0x00, sizeof(InData)); USHORT i=0, j=0, len=lstrlen(pszName); if ( len == 0 ) { Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_SYSNAME, TEXT("A sysname must be specified")); return(-1); } while ( pszName[i] ) { if ( !isspace(pszName[i]) ) { InData.szData[j++] = pszName[i]; } else if (InData.szData[j-1] != '\0') { InData.szData[j++] = '\0'; InData.cbData++; } i++; } InData.szData[j++] = '\0'; InData.cbData++; /* one word */ BYTE OutData[ PIOCTL_MAXSIZE ]; memset (OutData, 0x00, sizeof(OutData)); struct ViceIoctl IOInfo; IOInfo.in_size = sizeof(ULONG) + j; IOInfo.in = (char *)&InData; IOInfo.out = (char *)OutData; IOInfo.out_size = PIOCTL_MAXSIZE; if ((status = pioctl (0, VIOC_AFS_SYSNAME, &IOInfo, 1)) != 0) { rc = FALSE; } } if (rc) { Config_WriteGlobalString (TEXT("SysName"), pszName); } if (pStatus && !rc) *pStatus = status; if (!rc) Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_SYSNAME, TEXT("%ld"), status); return rc; } void Config_GetRootVolume (LPTSTR pszName) { if (!Config_ReadGlobalString (TEXT("RootVolume"), pszName, MAX_PATH)) lstrcpy (pszName, TEXT("root.afs")); } BOOL Config_SetRootVolume (LPCTSTR pszName, ULONG *pStatus) { Config_WriteGlobalString (TEXT("RootVolume"), pszName); g.fNeedRestart = TRUE; return TRUE; } void Config_GetMountRoot (LPTSTR pszPath) { if (!Config_ReadGlobalString (TEXT("MountRoot"), pszPath, MAX_PATH)) lstrcpy (pszPath, TEXT("/afs")); } BOOL Config_SetMountRoot (LPCTSTR pszPath, ULONG *pStatus) { Config_WriteGlobalString (TEXT("MountRoot"), pszPath); g.fNeedRestart = TRUE; return TRUE; } BOOL Config_GetCacheInUse (ULONG *pckCacheInUse, ULONG *pStatus) { BOOL rc = TRUE; ULONG status = 0; *pckCacheInUse = 0; if (Config_GetServiceState() != SERVICE_RUNNING) { rc = FALSE; status = ERROR_SERVICE_NOT_ACTIVE; } else { BYTE OutData[ PIOCTL_MAXSIZE ]; memset (OutData, 0x00, sizeof(OutData)); struct ViceIoctl IOInfo; IOInfo.in_size = 0; IOInfo.in = (char *)0; IOInfo.out = (char *)OutData; IOInfo.out_size = PIOCTL_MAXSIZE; if ((status = pioctl (0, VIOCGETCACHEPARMS, &IOInfo, 1)) != 0) { rc = FALSE; } else { *pckCacheInUse = ((LONG*)OutData)[1]; } } if (pStatus && !rc) *pStatus = status; return rc; } void Config_GetCachePath (LPTSTR pszCachePath) { if (!Config_ReadGlobalString (TEXT("CachePath"), pszCachePath, MAX_PATH)) { HKEY hk; TCHAR szPath[ MAX_PATH ] = TEXT(""); if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Environment"), 0, KEY_QUERY_VALUE, &hk) == ERROR_SUCCESS) { DWORD dwSize = sizeof(szPath); DWORD dwType = 0; if (RegQueryValueEx (hk, TEXT("TEMP"), NULL, &dwType, (PBYTE)szPath, &dwSize) == ERROR_SUCCESS) { if ( dwType == REG_EXPAND_SZ ) { TCHAR szTemp[ MAX_PATH ]; lstrcpy(szTemp, szPath); ExpandEnvironmentStrings(szTemp, szPath, MAX_PATH); } } RegCloseKey (hk); lstrcat(szPath, "\\AFSCache"); } if ( !szPath[0] ) { GetWindowsDirectory(szPath, sizeof(szPath)); lstrcat(szPath, "\\TEMP\\AFSCache"); } lstrcpy (pszCachePath, szPath); } } BOOL Config_SetCachePath(LPCTSTR pszPath, ULONG *pStatus) { Config_WriteGlobalString (TEXT("CachePath"), pszPath); g.fNeedRestart = TRUE; return TRUE; } void Config_GetLanAdapter (ULONG *pnLanAdapter) { if (!Config_ReadGlobalNum (TEXT("LANadapter"), (DWORD*)pnLanAdapter)) *pnLanAdapter = -1; } BOOL Config_SetLanAdapter (ULONG nLanAdapter, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("LANadapter"), nLanAdapter); g.fNeedRestart = TRUE; return TRUE; } void Config_GetTrapOnPanic (BOOL *pfFlag) { if (!Config_ReadGlobalNum (TEXT("TrapOnPanic"), (DWORD*)pfFlag)) *pfFlag = TRUE; } BOOL Config_SetTrapOnPanic (BOOL fFlag, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("TrapOnPanic"), fFlag); g.fNeedRestart = TRUE; return TRUE; } void Config_GetTraceBufferSize (ULONG *pnBufSize) { if (!Config_ReadGlobalNum (TEXT("TraceBufferSize"), (DWORD*)pnBufSize)) *pnBufSize = 5000; } BOOL Config_SetTraceBufferSize (ULONG nBufSize, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("TraceBufferSize"), nBufSize); g.fNeedRestart = TRUE; return TRUE; } void Config_GetLoginRetryInterval (ULONG *pnInterval) { if (!Config_ReadGlobalNum (TEXT("LoginRetryInterval"), (DWORD*)pnInterval)) *pnInterval = 30; } BOOL Config_SetLoginRetryInterval (ULONG nInterval, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("LoginRetryInterval"), nInterval); return TRUE; } void Config_GetFailLoginsSilently (BOOL *pfFlag) { if (!Config_ReadGlobalNum (TEXT("FailLoginsSilently"), (DWORD*)pfFlag)) *pfFlag = FALSE; } BOOL Config_SetFailLoginsSilently (BOOL fFlag, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("FailLoginsSilently"), fFlag); return TRUE; } void Config_GetReportSessionStartups (BOOL *pfFlag) { if (!Config_ReadGlobalNum (TEXT("ReportSessionStartups"), (DWORD*)pfFlag)) *pfFlag = FALSE; } BOOL Config_SetReportSessionStartups (BOOL fFlag, ULONG *pStatus) { Config_WriteGlobalNum (TEXT("ReportSessionStartups"), fFlag); return TRUE; }