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