windows-64-bit-type-safety-20051105
[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  * afssw_GetClientCellServDBDir() -- Get directory in which AFS client CellServDB
68  * file is installed.  Sets *bufPP to point to allocated buffer containing string.
69  *
70  * RETURN CODES: 0 success, -1 failed (errno set)
71  */
72 int
73 afssw_GetClientCellServDBDir(char **bufPP)   /* [out] data buffer */
74 {
75     return StringDataRead(AFSREG_CLT_OPENAFS_KEY,
76                           AFSREG_CLT_OPENAFS_CELLSERVDB_DIR_VALUE,
77                           bufPP);
78 }
79
80
81 /*
82  * afssw_GetClientCellName() -- Get name of cell in which AFS client is
83  *     configured.  Sets *bufPP to point to allocated buffer containing string.
84  *
85  * RETURN CODES: 0 success, -1 failed (errno set)
86  */
87 int
88 afssw_GetClientCellName(char **bufPP)  /* [out] data buffer */
89 {
90     return StringDataRead(AFSREG_CLT_SVC_PARAM_KEY,
91                           AFSREG_CLT_SVC_PARAM_CELL_VALUE,
92                           bufPP);
93 }
94
95
96 /*
97  * afssw_SetClientCellName() -- Set name of cell in which AFS client is
98  *     configured.
99  *
100  * RETURN CODES: 0 success, -1 failed (errno set)
101  */
102 int
103 afssw_SetClientCellName(const char *cellName)
104 {
105     return StringDataWrite(AFSREG_CLT_SVC_PARAM_KEY,
106                            AFSREG_CLT_SVC_PARAM_CELL_VALUE,
107                            cellName);
108 }
109
110
111 /*
112  * afssw_GetServerVersion() -- Get version number of installed server.
113  *
114  * RETURN CODES: 0 success, -1 failed (errno set)
115  */
116 int
117 afssw_GetServerVersion(unsigned *major,  /* major version number */
118                        unsigned *minor,  /* minor version number */
119                        unsigned *patch)  /* patch level */
120 {
121     DWORD dwMajor, dwMinor, dwPatch;
122
123     if (DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
124                       AFSREG_SVR_SW_VERSION_MAJOR_VALUE,
125                       &dwMajor) ||
126
127         DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
128                       AFSREG_SVR_SW_VERSION_MINOR_VALUE,
129                       &dwMinor) ||
130
131         DwordDataRead(AFSREG_SVR_SW_VERSION_KEY,
132                       AFSREG_SVR_SW_VERSION_PATCH_VALUE,
133                       &dwPatch)) {
134         /* a read failed */
135         return -1;
136     } else {
137         /* return values */
138         *major = dwMajor;
139         *minor = dwMinor;
140         *patch = dwPatch;
141         return 0;
142     }
143 }
144
145
146 /*
147  * afssw_GetClientVersion() -- Get version number of installed client.
148  *
149  * RETURN CODES: 0 success, -1 failed (errno set)
150  */
151 int
152 afssw_GetClientVersion(unsigned *major,  /* major version number */
153                        unsigned *minor,  /* minor version number */
154                        unsigned *patch)  /* patch level */
155 {
156     DWORD dwMajor, dwMinor, dwPatch;
157
158     if (DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
159                       AFSREG_CLT_SW_VERSION_MAJOR_VALUE,
160                       &dwMajor) ||
161
162         DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
163                       AFSREG_CLT_SW_VERSION_MINOR_VALUE,
164                       &dwMinor) ||
165
166         DwordDataRead(AFSREG_CLT_SW_VERSION_KEY,
167                       AFSREG_CLT_SW_VERSION_PATCH_VALUE,
168                       &dwPatch)) {
169         /* a read failed */
170         return -1;
171     } else {
172         /* return values */
173         *major = dwMajor;
174         *minor = dwMinor;
175         *patch = dwPatch;
176         return 0;
177     }
178 }
179
180
181
182
183 /* ----------------------- local functions ------------------------- */
184
185 /*
186  * StringDataRead() -- read registry data of type REG_SZ and return in
187  *     allocated buffer.
188  *
189  * RETURN CODES: 0 success, -1 failed (errno set)
190  */
191 static int
192 StringDataRead(const char *keyName, const char *valueName, char **bufPP)
193 {
194     long status;
195     HKEY key;
196
197     if (bufPP == NULL) {
198         errno = EINVAL;
199         return -1;
200     }
201
202     status = RegOpenKeyAlt(AFSREG_NULL_KEY, keyName, KEY_READ, 0, &key, NULL);
203
204     if (status == ERROR_SUCCESS) {
205         DWORD dataType;
206         char *dataBuf = NULL;
207
208         status = RegQueryValueAlt(key, valueName, &dataType, &dataBuf, NULL);
209
210         if (status == ERROR_SUCCESS) {
211             if (dataType == REG_SZ) {
212                 *bufPP = dataBuf;
213             } else {
214                 /* invalid data type */
215                 free(dataBuf);
216                 status = ERROR_INVALID_DATA;
217             }
218         }
219         (void)RegCloseKey(key);
220     }
221
222     if (status) {
223         errno = nterr_nt2unix(status, EIO);
224         return -1;
225     }
226     return 0;
227 }
228
229
230 /*
231  * StringDataWrite() -- write registry data of type REG_SZ.
232  * 
233  * RETURN CODES: 0 success, -1 failed (errno set)
234  */
235 static int
236 StringDataWrite(const char *keyName, const char *valueName, const char *data)
237 {
238     long status;
239     HKEY key;
240
241     if (data == NULL) {
242         errno = EINVAL;
243         return -1;
244     }
245
246     status = RegOpenKeyAlt(AFSREG_NULL_KEY,
247                            keyName, KEY_WRITE, 1 /* create */, &key, NULL);
248
249     if (status == ERROR_SUCCESS) {
250         status = RegSetValueEx(key,
251                                valueName,
252                                0, REG_SZ, data, (DWORD)strlen(data) + 1);
253
254         (void)RegCloseKey(key);
255     }
256
257     if (status) {
258         errno = nterr_nt2unix(status, EIO);
259         return -1;
260     }
261     return 0;
262 }
263
264
265 /*
266  * DwordDataRead() -- read registry data of type REG_DWORD.
267  *
268  * RETURN CODES: 0 success, -1 failed (errno set)
269  */
270 static int
271 DwordDataRead(const char *keyName, const char *valueName, DWORD *data)
272 {
273     long status;
274     HKEY key;
275
276     status = RegOpenKeyAlt(AFSREG_NULL_KEY, keyName, KEY_READ, 0, &key, NULL);
277
278     if (status == ERROR_SUCCESS) {
279         DWORD dataType;
280         DWORD dataBuf;
281         DWORD dataSize = sizeof(DWORD);
282
283         status = RegQueryValueEx(key, valueName,
284                                  NULL, &dataType, (void *)&dataBuf, &dataSize);
285
286         if (status == ERROR_SUCCESS) {
287             if (dataType == REG_DWORD) {
288                 *data = dataBuf;
289             } else {
290                 /* invalid data type */
291                 status = ERROR_INVALID_DATA;
292             }
293         }
294         (void)RegCloseKey(key);
295     }
296
297     if (status) {
298         errno = nterr_nt2unix(status, EIO);
299         return -1;
300     }
301     return 0;
302 }