2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afs/param.h>
20 #include <WINNT/afsreg.h>
24 /* Some install/uninstall related utilities. */
27 #define NETWORK_PROVIDER_ORDER_KEY "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order"
28 #define PROVIDER_ORDER_VALUE_NAME "ProviderOrder"
30 #define ENVIRONMENT_KEY "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
32 #define AUTOEXEC_PATH "c:\\autoexec.bat"
33 #define AUTOEXEC_TMP_PATH "c:\\TaAfsAutoexec.tmp"
36 static BOOL ReadRegEnv(char **ppszEnvValue, char *pszRegValueName);
37 static BOOL WriteRegEnv(char *pszEnvValue, char *pszEnvName);
38 static BOOL ReadAutoExec(char **ppszEnvValue, char *pszEnvName);
39 static BOOL WriteAutoExec(char *pszEnvValue, char *pszEnvName);
40 static BOOL FindSubString(const char *s1, const char *s2);
44 /* ------------------ exported functions ---------------------- */
46 BOOL InNetworkProviderOrder(char *pszNetworkProvider, BOOL *pbIn)
51 char *pszProviderOrder = 0;
54 bResult = FALSE; // Assume failure
56 if (RegOpenKeyAlt(AFSREG_NULL_KEY, NETWORK_PROVIDER_ORDER_KEY, KEY_READ, FALSE, &hKey, 0) == ERROR_SUCCESS) {
57 if (RegQueryValueAlt(hKey, PROVIDER_ORDER_VALUE_NAME, &dwType, &pszProviderOrder, &dwSize) == ERROR_SUCCESS) {
58 *pbIn = strstr(pszProviderOrder, pszNetworkProvider) != 0;
60 free(pszProviderOrder);
70 * AddToProviderOrder() -- add entry to network provider order
72 BOOL AddToProviderOrder(char *pszWhatToAdd)
80 BOOL bAlreadyAdded = FALSE;
82 /* Open the key, creating it if necessary (but should always be there). */
83 result = RegOpenKeyAlt(AFSREG_NULL_KEY,
84 NETWORK_PROVIDER_ORDER_KEY,
85 KEY_SET_VALUE | KEY_ALL_ACCESS, TRUE, &hKey, 0);
86 if (result != ERROR_SUCCESS)
89 /* Get the old value */
90 result = RegQueryValueAlt(hKey,
91 PROVIDER_ORDER_VALUE_NAME,
92 &dwType, &pszValue, &nLen);
93 if (result != ERROR_SUCCESS) {
97 pszNewValue = malloc(nLen + strlen(pszWhatToAdd) + 1);/* Add 1 for comma */
100 /* Add the new value */
101 if (result == ERROR_SUCCESS) {
102 if (strstr(pszValue, pszWhatToAdd) != 0)
103 bAlreadyAdded = TRUE;
105 if (pszValue && *pszValue) {
106 strcpy(pszNewValue, pszValue);
107 strcat(pszNewValue, ",");
109 strcat(pszNewValue, pszWhatToAdd);
112 } else if (result == ERROR_FILE_NOT_FOUND)
113 strcpy(pszNewValue, pszWhatToAdd);
115 /* Set the new value in the registry */
116 if (((result == ERROR_SUCCESS) ||
117 (result == ERROR_FILE_NOT_FOUND)) && !bAlreadyAdded)
118 result = RegSetValueEx(hKey, PROVIDER_ORDER_VALUE_NAME, 0,
119 REG_SZ, pszNewValue, strlen(pszNewValue) + 1);
125 return (result == ERROR_SUCCESS);
130 * RemoveFromProviderOrder() -- remove entry from network provider order
132 BOOL RemoveFromProviderOrder(char *pszWhatToDel)
140 BOOL bAlreadyRemoved = FALSE;
142 /* Open the key, creating if necessary (but should always be there). */
143 result = RegOpenKeyAlt(AFSREG_NULL_KEY, NETWORK_PROVIDER_ORDER_KEY,
144 KEY_SET_VALUE | KEY_ALL_ACCESS, TRUE, &hKey, 0);
145 if (result != ERROR_SUCCESS)
148 /* Get the old value */
149 result = RegQueryValueAlt(hKey, PROVIDER_ORDER_VALUE_NAME,
150 &dwType, &pszValue, &nLen);
152 if (result == ERROR_SUCCESS) {
153 pszNewValue = malloc(nLen); /* bigger than we need, but that's ok */
156 if (strstr(pszValue, pszWhatToDel) == 0)
157 bAlreadyRemoved = TRUE;
161 pszCur = strtok(pszValue, ",");
163 if (strcmp(pszCur, pszWhatToDel) != 0) {
165 strcat(pszNewValue, ",");
166 strcat(pszNewValue, pszCur);
168 pszCur = strtok(0, ",");
172 /* Set the new value in the registry */
173 if (!bAlreadyRemoved)
174 result = RegSetValueEx(hKey, PROVIDER_ORDER_VALUE_NAME, 0, REG_SZ,
175 pszNewValue, strlen(pszNewValue) + 1);
181 return (result == ERROR_SUCCESS);
186 * ReadSystemEnv() -- read system environment variable
188 BOOL ReadSystemEnv(char **ppszEnvValue, char *pszEnvName)
191 return ReadRegEnv(ppszEnvValue, pszEnvName);
193 return ReadAutoExec(ppszEnvValue, pszEnvName);
198 * WriteSystemEnv() -- write system environment variable
200 BOOL WriteSystemEnv(char *pszEnvValue, char *pszEnvName)
203 return WriteRegEnv(pszEnvValue, pszEnvName);
205 return WriteAutoExec(pszEnvValue, pszEnvName);
210 * AddToSystemPath() -- add specified entry to system PATH variable.
212 BOOL AddToSystemPath(char *pszPath)
214 char *pszCurPath = 0;
215 char *pszNewPath = 0;
218 if (!ReadSystemEnv(&pszCurPath, "Path"))
221 /* Do we need to add it? */
222 if (!pszCurPath || !FindSubString(pszCurPath, pszPath)) {
224 /* Old path + a semicolon + the new path entry + a null */
225 pszNewPath = malloc((pszCurPath ? strlen(pszCurPath) + 1 : 0) +
226 strlen(pszPath) + 1);
227 if (pszNewPath == 0) {
236 strcpy(pszNewPath, pszCurPath);
237 strcat(pszNewPath, ";");
240 strcat(pszNewPath, pszPath);
241 bStatus = WriteSystemEnv(pszNewPath, "Path");
254 * RemoveFromSystemPath() -- remove specified entry from system PATH variable.
256 BOOL RemoveFromSystemPath(char *pszPath)
264 if (!ReadSystemEnv(&pszCurNls, "Path"))
267 /* Is it already not in the path? */
268 if (!pszCurNls || !FindSubString(pszCurNls, pszPath)) {
274 pszNewNls = (char *)malloc(strlen(pszCurNls) + 1);
275 if (pszNewNls == 0) {
282 pCurPath = pszCurNls;
285 pSemi = strchr(pCurPath, ';');
289 if (_stricmp(pCurPath, pszPath) != 0) {
290 if (pszNewNls[0] != 0)
291 strcat(pszNewNls, ";");
292 strcat(pszNewNls, pCurPath);
302 bStatus = WriteSystemEnv(pszNewNls, "Path");
312 * IsWinNT() -- determine if system is NT or other (95/98).
316 DWORD dwVersion = GetVersion();
318 return (dwVersion < 0x80000000);
326 /* ------------------ utility functions ---------------------- */
330 * ReadRegEnv() -- read system enviornment variable from registry (NT only).
332 static BOOL ReadRegEnv(char **ppszEnvValue, char *pszRegValueName)
339 result = RegOpenKeyAlt(AFSREG_NULL_KEY, ENVIRONMENT_KEY,
340 KEY_SET_VALUE | KEY_ALL_ACCESS, FALSE, &hKey, 0);
341 if (result != ERROR_SUCCESS)
350 *ppszEnvValue = (char *)malloc(nLen);
351 if (*ppszEnvValue == 0) {
356 /* If function fails to open the value and the error code says that
357 * the value doesn't exist, then we will attempt to make it.
359 result = RegQueryValueEx(hKey, pszRegValueName, 0,
360 &dwType, *ppszEnvValue, &nLen);
362 if (result == ERROR_FILE_NOT_FOUND) {
363 result = RegSetValueEx(hKey, pszRegValueName, 0,
364 REG_EXPAND_SZ, "", 0);
365 **ppszEnvValue = '\0'; /* zero length string "read" */
367 } while (result == ERROR_MORE_DATA);
371 if (result != ERROR_SUCCESS || strlen(*ppszEnvValue) == 0) {
372 /* Don't return empty strings; instead set buffer pointer to 0. */
376 return (result == ERROR_SUCCESS);
381 * WriteRegEnv() -- write system environment variable to registry (NT only).
383 static BOOL WriteRegEnv(char *pszEnvValue, char *pszEnvName)
388 result = RegOpenKeyAlt(AFSREG_NULL_KEY, ENVIRONMENT_KEY,
389 KEY_ALL_ACCESS, FALSE, &hKey, 0);
390 if (result != ERROR_SUCCESS)
393 result = RegSetValueEx(hKey, pszEnvName, 0, REG_EXPAND_SZ,
394 pszEnvValue, strlen(pszEnvValue) + 1);
397 return (result == ERROR_SUCCESS);
402 * ReadAutoExec() -- read environment variable from autoexec.bat (95/98).
404 static BOOL ReadAutoExec(char **ppszEnvValue, char *pszEnvName)
412 fp = fopen(AUTOEXEC_PATH, "rt");
416 /* Create the string we are looking for */
417 sprintf(szSetCmd, "SET %s", pszEnvName);
419 /* Now read each line and look for our SetCmd string */
422 fgets(szLine, sizeof(szLine), fp);
427 /* Strip off the trailing newline */
428 nLineLen = strlen(szLine);
429 if (szLine[nLineLen - 1] == '\n') {
431 szLine[nLineLen] = 0;
434 if (_strnicmp(szSetCmd, szLine, strlen(szSetCmd)) == 0) {
435 char *value = strchr(szLine, '=');
437 *ppszEnvValue = _strdup(++value);
442 /* Don't return empty strings; instead set buffer to 0. */
443 if (*ppszEnvValue && (strlen(*ppszEnvValue) == 0)) {
455 * WriteAutoExec() -- write environment variable to autoexec.bat (95/98).
457 static BOOL WriteAutoExec(char *pszEnvValue, char *pszEnvName)
461 BOOL bValueWritten = FALSE;
465 fpOut = fopen(AUTOEXEC_TMP_PATH, "wt");
469 sprintf(szSetCmd, "SET %s", pszEnvName);
471 fpIn = fopen(AUTOEXEC_PATH, "rt");
473 /* Now read each line and look for our SetCmd string */
475 fgets(szLine, sizeof(szLine), fpIn);
479 if (!bValueWritten &&
480 (_strnicmp(szSetCmd, szLine, strlen(szSetCmd)) == 0)) {
481 fprintf(fpOut, "%s=%s\n", szSetCmd, pszEnvValue);
482 bValueWritten = TRUE;
484 fputs(szLine, fpOut);
490 /* If the value didn't previously exist, then add it to the end */
492 fprintf(fpOut, "%s=%s\n", szSetCmd, pszEnvValue);
496 bResult = CopyFile(AUTOEXEC_TMP_PATH, AUTOEXEC_PATH, FALSE);
498 /* Try to delete this even if the copy fails. Tie the return code
499 * to the copy and not the delete.
501 DeleteFile(AUTOEXEC_TMP_PATH);
508 * FindSubString() -- basically a case-insensitive strstr().
510 static BOOL FindSubString(const char *s1, const char *s2)
525 bFound = strstr(_strlwr(ls1), _strlwr(ls2)) != 0;