117e09bb71b89b8f2af9b3dbb151fe6632ae75fc
[openafs.git] / src / WINNT / afsreg / afssw.c
1 /* Copyright (C) 1998 Transarc Corporation - All rights reserved.
2  *
3  */
4
5 #include <afs/param.h>
6 #include <afs/stds.h>
7
8 #include <windows.h>
9 #include <stdlib.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <errno.h>
13
14 #include <afs/errmap_nt.h>
15
16 #include "afsreg.h"
17 #include "afssw.h"
18
19 static int
20 StringDataRead(const char *keyName, const char *valueName, char **bufPP);
21
22 static int
23 StringDataWrite(const char *keyName, const char *valueName, const char *data);
24
25 static int
26 DwordDataRead(const char *keyName, const char *valueName, DWORD *data);
27
28
29
30 /* Functions for accessing AFS software configuration information. */
31
32 /*
33  * afssw_GetServerInstallDir() -- Get directory in which AFS server software is
34  *     installed.  Sets *bufPP to point to allocated buffer containing string.
35  *
36  * RETURN CODES: 0 success, -1 failed (errno set)
37  */
38 int
39 afssw_GetServerInstallDir(char **bufPP)  /* [out] data buffer */
40 {
41     return StringDataRead(AFSREG_SVR_SW_VERSION_KEY,
42                           AFSREG_SVR_SW_VERSION_DIR_VALUE,
43                           bufPP);
44 }
45
46
47 /*
48  * afssw_GetClientInstallDir() -- Get directory in which AFS client software is
49  *     installed.  Sets *bufPP to point to allocated buffer containing string.
50  *
51  * RETURN CODES: 0 success, -1 failed (errno set)
52  */
53 int
54 afssw_GetClientInstallDir(char **bufPP)   /* [out] data buffer */
55 {
56     return StringDataRead(AFSREG_CLT_SW_VERSION_KEY,
57                           AFSREG_CLT_SW_VERSION_DIR_VALUE,
58                           bufPP);
59 }
60
61
62 /*
63  * afssw_GetClientCellName() -- Get name of cell in which AFS client is
64  *     configured.  Sets *bufPP to point to allocated buffer containing string.
65  *
66  * RETURN CODES: 0 success, -1 failed (errno set)
67  */
68 int
69 afssw_GetClientCellName(char **bufPP)  /* [out] data buffer */
70 {
71     return StringDataRead(AFSREG_CLT_SVC_PARAM_KEY,
72                           AFSREG_CLT_SVC_PARAM_CELL_VALUE,
73                           bufPP);
74 }
75
76
77 /*
78  * afssw_SetClientCellName() -- Set name of cell in which AFS client is
79  *     configured.
80  *
81  * RETURN CODES: 0 success, -1 failed (errno set)
82  */
83 int
84 afssw_SetClientCellName(const char *cellName)
85 {
86     return StringDataWrite(AFSREG_CLT_SVC_PARAM_KEY,
87                            AFSREG_CLT_SVC_PARAM_CELL_VALUE,
88                            cellName);
89 }
90
91
92 /*
93  * afssw_GetServerVersion() -- Get version number of installed server.
94  *
95  * RETURN CODES: 0 success, -1 failed (errno set)
96  */
97 int
98 afssw_GetServerVersion(unsigned *major,  /* major version number */
99                        unsigned *minor,  /* minor version number */
100                        unsigned *patch)  /* patch level */
101 {
102     DWORD dwMajor, dwMinor, dwPatch;
103
104     if (DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
105                       AFSREG_SVR_SW_VERSION_MAJOR_VALUE,
106                       &dwMajor) ||
107
108         DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
109                       AFSREG_SVR_SW_VERSION_MINOR_VALUE,
110                       &dwMinor) ||
111
112         DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
113                       AFSREG_SVR_SW_VERSION_PATCH_VALUE,
114                       &dwPatch)) {
115         /* a read failed */
116         return -1;
117     } else {
118         /* return values */
119         *major = dwMajor;
120         *minor = dwMinor;
121         *patch = dwPatch;
122         return 0;
123     }
124 }
125
126
127 /*
128  * afssw_GetClientVersion() -- Get version number of installed client.
129  *
130  * RETURN CODES: 0 success, -1 failed (errno set)
131  */
132 int
133 afssw_GetClientVersion(unsigned *major,  /* major version number */
134                        unsigned *minor,  /* minor version number */
135                        unsigned *patch)  /* patch level */
136 {
137     DWORD dwMajor, dwMinor, dwPatch;
138
139     if (DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
140                       AFSREG_CLT_SW_VERSION_MAJOR_VALUE,
141                       &dwMajor) ||
142
143         DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
144                       AFSREG_CLT_SW_VERSION_MINOR_VALUE,
145                       &dwMinor) ||
146
147         DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
148                       AFSREG_CLT_SW_VERSION_PATCH_VALUE,
149                       &dwPatch)) {
150         /* a read failed */
151         return -1;
152     } else {
153         /* return values */
154         *major = dwMajor;
155         *minor = dwMinor;
156         *patch = dwPatch;
157         return 0;
158     }
159 }
160
161
162
163
164 /* ----------------------- local functions ------------------------- */
165
166 /*
167  * StringDataRead() -- read registry data of type REG_SZ and return in
168  *     allocated buffer.
169  *
170  * RETURN CODES: 0 success, -1 failed (errno set)
171  */
172 static int
173 StringDataRead(const char *keyName, const char *valueName, char **bufPP)
174 {
175     long status;
176     HKEY key;
177
178     if (bufPP == NULL) {
179         errno = EINVAL;
180         return -1;
181     }
182
183     status = RegOpenKeyAlt(AFSREG_NULL_KEY, keyName, KEY_READ, 0, &key, NULL);
184
185     if (status == ERROR_SUCCESS) {
186         DWORD dataType;
187         char *dataBuf = NULL;
188
189         status = RegQueryValueAlt(key, valueName, &dataType, &dataBuf, NULL);
190
191         if (status == ERROR_SUCCESS) {
192             if (dataType == REG_SZ) {
193                 *bufPP = dataBuf;
194             } else {
195                 /* invalid data type */
196                 free(dataBuf);
197                 status = ERROR_INVALID_DATA;
198             }
199         }
200         (void)RegCloseKey(key);
201     }
202
203     if (status) {
204         errno = nterr_nt2unix(status, EIO);
205         return -1;
206     }
207     return 0;
208 }
209
210
211 /*
212  * StringDataWrite() -- write registry data of type REG_SZ.
213  * 
214  * RETURN CODES: 0 success, -1 failed (errno set)
215  */
216 static int
217 StringDataWrite(const char *keyName, const char *valueName, const char *data)
218 {
219     long status;
220     HKEY key;
221
222     if (data == NULL) {
223         errno = EINVAL;
224         return -1;
225     }
226
227     status = RegOpenKeyAlt(AFSREG_NULL_KEY,
228                            keyName, KEY_WRITE, 1 /* create */, &key, NULL);
229
230     if (status == ERROR_SUCCESS) {
231         status = RegSetValueEx(key,
232                                valueName,
233                                0, REG_SZ, data, strlen(data) + 1);
234
235         (void)RegCloseKey(key);
236     }
237
238     if (status) {
239         errno = nterr_nt2unix(status, EIO);
240         return -1;
241     }
242     return 0;
243 }
244
245
246 /*
247  * DwordDataRead() -- read registry data of type REG_DWORD.
248  *
249  * RETURN CODES: 0 success, -1 failed (errno set)
250  */
251 static int
252 DwordDataRead(const char *keyName, const char *valueName, DWORD *data)
253 {
254     long status;
255     HKEY key;
256
257     status = RegOpenKeyAlt(AFSREG_NULL_KEY, keyName, KEY_READ, 0, &key, NULL);
258
259     if (status == ERROR_SUCCESS) {
260         DWORD dataType;
261         DWORD dataBuf;
262         DWORD dataSize = sizeof(DWORD);
263
264         status = RegQueryValueEx(key, valueName,
265                                  NULL, &dataType, (void *)&dataBuf, &dataSize);
266
267         if (status == ERROR_SUCCESS) {
268             if (dataType == REG_DWORD) {
269                 *data = dataBuf;
270             } else {
271                 /* invalid data type */
272                 status = ERROR_INVALID_DATA;
273             }
274         }
275         (void)RegCloseKey(key);
276     }
277
278     if (status) {
279         errno = nterr_nt2unix(status, EIO);
280         return -1;
281     }
282     return 0;
283 }