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