Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afsreg / afssw.c
blob89d63fb28657c16df31343f3c1261ffbed4d977a
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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 */
10 #include <afs/param.h>
11 #include <afs/stds.h>
13 #include <windows.h>
14 #include <shlobj.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <stddef.h>
18 #include <string.h>
19 #include <errno.h>
21 #include <afs/errmap_nt.h>
23 #include "afsreg.h"
24 #include "afssw.h"
26 static int
27 StringDataRead(const char *keyName, const char *valueName, char **bufPP);
29 static int
30 StringDataWrite(const char *keyName, const char *valueName, const char *data);
32 static int
33 DwordDataRead(const char *keyName, const char *valueName, DWORD *data);
37 /* Functions for accessing AFS software configuration information. */
40 * afssw_GetServerInstallDir() -- Get directory in which AFS server software is
41 * installed. Sets *bufPP to point to allocated buffer containing string.
43 * RETURN CODES: 0 success, -1 failed (errno set)
45 int
46 afssw_GetServerInstallDir(char **bufPP) /* [out] data buffer */
48 return StringDataRead(AFSREG_SVR_SW_VERSION_KEY,
49 AFSREG_SVR_SW_VERSION_DIR_VALUE,
50 bufPP);
55 * afssw_GetClientInstallDir() -- Get directory in which AFS client software is
56 * installed. Sets *bufPP to point to allocated buffer containing string.
58 * RETURN CODES: 0 success, -1 failed (errno set)
60 int
61 afssw_GetClientInstallDir(char **bufPP) /* [out] data buffer */
63 int retval = StringDataRead(AFSREG_CLT_SW_VERSION_KEY,
64 AFSREG_CLT_SW_VERSION_DIR_VALUE,
65 bufPP);
66 if (retval)
67 retval = StringDataRead(AFSREG_CLT_TOOLS_SW_VERSION_KEY,
68 AFSREG_CLT_SW_VERSION_DIR_VALUE,
69 bufPP);
70 return retval;
74 * afssw_GetClientCellServDBDir() -- Get directory in which AFS client CellServDB
75 * file is installed. Sets *bufPP to point to allocated buffer containing string.
77 * RETURN CODES: 0 success, -1 failed (errno set)
79 int
80 afssw_GetClientCellServDBDir(char **bufPP) /* [out] data buffer */
82 char wdir[512];
83 int tlen;
84 char *path = NULL;
85 DWORD cbPath;
87 cbPath = GetEnvironmentVariable("AFSCONF", NULL, 0);
88 if (cbPath) {
89 cbPath += 2;
90 path = malloc(cbPath);
91 if (path) {
92 GetEnvironmentVariable("AFSCONF", path, cbPath);
93 tlen = (int)strlen(path);
94 if (path[tlen-1] != '\\') {
95 strncat(path, "\\", cbPath);
96 path[cbPath-1] = '\0';
98 *bufPP = path;
99 return 0;
103 if (!StringDataRead(AFSREG_CLT_OPENAFS_KEY,
104 AFSREG_CLT_OPENAFS_CELLSERVDB_DIR_VALUE,
105 &path)) {
106 tlen = (int)strlen(path);
107 if (path[tlen-1] != '\\') {
108 char * newPath = malloc(tlen+2);
109 if (newPath) {
110 snprintf(newPath,tlen+2,"%s\\",path);
111 free(path);
112 path = newPath;
115 *bufPP = path;
116 return 0;
120 * Try to find the All Users\Application Data\OpenAFS\Client directory.
121 * If it exists and it contains a CellServDB file, return that.
122 * Otherwise, return the Install Directory for backward compatibility.
123 * SHGetFolderPath requires wdir to be of length MAX_PATH which is 260.
125 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
126 SHGFP_TYPE_CURRENT, wdir)))
127 { HANDLE fh;
129 tlen = (int)strlen(wdir);
130 if (wdir[tlen-1] != '\\') {
131 strncat(wdir, "\\", sizeof(wdir));
132 wdir[sizeof(wdir)-1] = '\0';
133 tlen++;
135 strncat(wdir, "OpenAFS\\Client\\CellServDB", sizeof(wdir));
136 wdir[sizeof(wdir)-1] = '\0';
138 fh = CreateFile(wdir, GENERIC_READ, FILE_SHARE_READ, NULL,
139 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
140 if (fh != INVALID_HANDLE_VALUE) {
141 CloseHandle(fh);
142 tlen += (int)strlen("OpenAFS\\Client\\");
143 wdir[tlen] = '\0';
144 *bufPP = strdup(wdir);
145 return 0;
149 return afssw_GetClientInstallDir(bufPP);
154 * afssw_GetClientCellName() -- Get name of cell in which AFS client is
155 * configured. Sets *bufPP to point to allocated buffer containing string.
157 * RETURN CODES: 0 success, -1 failed (errno set)
160 afssw_GetClientCellName(char **bufPP) /* [out] data buffer */
162 return StringDataRead(AFSREG_CLT_SVC_PARAM_KEY,
163 AFSREG_CLT_SVC_PARAM_CELL_VALUE,
164 bufPP);
169 * afssw_SetClientCellName() -- Set name of cell in which AFS client is
170 * configured.
172 * RETURN CODES: 0 success, -1 failed (errno set)
175 afssw_SetClientCellName(const char *cellName)
177 return StringDataWrite(AFSREG_CLT_SVC_PARAM_KEY,
178 AFSREG_CLT_SVC_PARAM_CELL_VALUE,
179 cellName);
184 * afssw_GetServerVersion() -- Get version number of installed server.
186 * RETURN CODES: 0 success, -1 failed (errno set)
189 afssw_GetServerVersion(unsigned *major, /* major version number */
190 unsigned *minor, /* minor version number */
191 unsigned *patch) /* patch level */
193 DWORD dwMajor, dwMinor, dwPatch;
195 if (DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
196 AFSREG_SVR_SW_VERSION_MAJOR_VALUE,
197 &dwMajor) ||
199 DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
200 AFSREG_SVR_SW_VERSION_MINOR_VALUE,
201 &dwMinor) ||
203 DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
204 AFSREG_SVR_SW_VERSION_PATCH_VALUE,
205 &dwPatch)) {
206 /* a read failed */
207 return -1;
208 } else {
209 /* return values */
210 *major = dwMajor;
211 *minor = dwMinor;
212 *patch = dwPatch;
213 return 0;
219 * afssw_GetClientVersion() -- Get version number of installed client.
221 * RETURN CODES: 0 success, -1 failed (errno set)
224 afssw_GetClientVersion(unsigned *major, /* major version number */
225 unsigned *minor, /* minor version number */
226 unsigned *patch) /* patch level */
228 DWORD dwMajor, dwMinor, dwPatch;
230 if (DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
231 AFSREG_CLT_SW_VERSION_MAJOR_VALUE,
232 &dwMajor) ||
234 DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
235 AFSREG_CLT_SW_VERSION_MINOR_VALUE,
236 &dwMinor) ||
238 DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
239 AFSREG_CLT_SW_VERSION_PATCH_VALUE,
240 &dwPatch)) {
241 /* a read failed */
242 return -1;
243 } else {
244 /* return values */
245 *major = dwMajor;
246 *minor = dwMinor;
247 *patch = dwPatch;
248 return 0;
255 /* ----------------------- local functions ------------------------- */
258 * StringDataRead() -- read registry data of type REG_SZ and return in
259 * allocated buffer.
261 * RETURN CODES: 0 success, -1 failed (errno set)
263 static int
264 StringDataRead(const char *keyName, const char *valueName, char **bufPP)
266 long status;
267 HKEY key;
269 if (bufPP == NULL) {
270 errno = EINVAL;
271 return -1;
274 status = RegOpenKeyAlt(AFSREG_NULL_KEY, keyName, KEY_READ, 0, &key, NULL);
276 if (status == ERROR_SUCCESS) {
277 DWORD dataType;
278 char *dataBuf = NULL;
280 status = RegQueryValueAlt(key, valueName, &dataType, &dataBuf, NULL);
282 if (status == ERROR_SUCCESS) {
283 if (dataType == REG_SZ) {
284 *bufPP = dataBuf;
285 } else {
286 /* invalid data type */
287 free(dataBuf);
288 status = ERROR_INVALID_DATA;
291 (void)RegCloseKey(key);
294 if (status) {
295 errno = nterr_nt2unix(status, EIO);
296 return -1;
298 return 0;
303 * StringDataWrite() -- write registry data of type REG_SZ.
305 * RETURN CODES: 0 success, -1 failed (errno set)
307 static int
308 StringDataWrite(const char *keyName, const char *valueName, const char *data)
310 long status;
311 HKEY key;
313 if (data == NULL) {
314 errno = EINVAL;
315 return -1;
318 status = RegOpenKeyAlt(AFSREG_NULL_KEY,
319 keyName, KEY_WRITE, 1 /* create */, &key, NULL);
321 if (status == ERROR_SUCCESS) {
322 status = RegSetValueEx(key,
323 valueName,
324 0, REG_SZ, data, (DWORD)strlen(data) + 1);
326 (void)RegCloseKey(key);
329 if (status) {
330 errno = nterr_nt2unix(status, EIO);
331 return -1;
333 return 0;
338 * DwordDataRead() -- read registry data of type REG_DWORD.
340 * RETURN CODES: 0 success, -1 failed (errno set)
342 static int
343 DwordDataRead(const char *keyName, const char *valueName, DWORD *data)
345 long status;
346 HKEY key;
348 status = RegOpenKeyAlt(AFSREG_NULL_KEY, keyName, KEY_READ, 0, &key, NULL);
350 if (status == ERROR_SUCCESS) {
351 DWORD dataType;
352 DWORD dataBuf;
353 DWORD dataSize = sizeof(DWORD);
355 status = RegQueryValueEx(key, valueName,
356 NULL, &dataType, (void *)&dataBuf, &dataSize);
358 if (status == ERROR_SUCCESS) {
359 if (dataType == REG_DWORD) {
360 *data = dataBuf;
361 } else {
362 /* invalid data type */
363 status = ERROR_INVALID_DATA;
366 (void)RegCloseKey(key);
369 if (status) {
370 errno = nterr_nt2unix(status, EIO);
371 return -1;
373 return 0;