Annotation of embedaddon/ntp/lib/isc/win32/strerror.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
3: * Copyright (C) 2001, 2002 Internet Software Consortium.
4: *
5: * Permission to use, copy, modify, and/or distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15: * PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: /* $Id: strerror.c,v 1.8 2007/06/19 23:47:19 tbox Exp $ */
19:
20: #include <config.h>
21:
22: #include <stdio.h>
23: #include <string.h>
24: #include <winsock2.h>
25:
26: #include <isc/mutex.h>
27: #include <isc/once.h>
28: #include <isc/print.h>
29: #include <isc/strerror.h>
30: #include <isc/util.h>
31:
32: /*
33: * Forward declarations
34: */
35:
36: char *
37: FormatError(int error);
38:
39: char *
40: GetWSAErrorMessage(int errval);
41:
42: char *
43: NTstrerror(int err, BOOL *bfreebuf);
44:
45: /*
46: * We need to do this this way for profiled locks.
47: */
48:
49: static isc_mutex_t isc_strerror_lock;
50: static void init_lock(void) {
51: RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS);
52: }
53:
54: /*
55: * This routine needs to free up any buffer allocated by FormatMessage
56: * if that routine gets used.
57: */
58:
59: void
60: isc__strerror(int num, char *buf, size_t size) {
61: char *msg;
62: BOOL freebuf;
63: unsigned int unum = num;
64: static isc_once_t once = ISC_ONCE_INIT;
65:
66: REQUIRE(buf != NULL);
67:
68: RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
69:
70: LOCK(&isc_strerror_lock);
71: freebuf = FALSE;
72: msg = NTstrerror(num, &freebuf);
73: if (msg != NULL)
74: snprintf(buf, size, "%s", msg);
75: else
76: snprintf(buf, size, "Unknown error: %u", unum);
77: if(freebuf && msg != NULL) {
78: LocalFree(msg);
79: }
80: UNLOCK(&isc_strerror_lock);
81: }
82:
83: /*
84: * Note this will cause a memory leak unless the memory allocated here
85: * is freed by calling LocalFree. isc__strerror does this before unlocking.
86: * This only gets called if there is a system type of error and will likely
87: * be an unusual event.
88: */
89: char *
90: FormatError(int error) {
91: LPVOID lpMsgBuf = NULL;
92: FormatMessage(
93: FORMAT_MESSAGE_ALLOCATE_BUFFER |
94: FORMAT_MESSAGE_FROM_SYSTEM |
95: FORMAT_MESSAGE_IGNORE_INSERTS,
96: NULL,
97: error,
98: /* Default language */
99: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
100: (LPTSTR) &lpMsgBuf,
101: 0,
102: NULL);
103:
104: return (lpMsgBuf);
105: }
106:
107: /*
108: * This routine checks the error value and calls the WSA Windows Sockets
109: * Error message function GetWSAErrorMessage below if it's within that range
110: * since those messages are not available in the system error messages.
111: */
112: char *
113: NTstrerror(int err, BOOL *bfreebuf) {
114: char *retmsg = NULL;
115:
116: /* Copy the error value first in case of other errors */
117: DWORD errval = err;
118:
119: *bfreebuf = FALSE;
120:
121: /* Get the Winsock2 error messages */
122: if (errval >= WSABASEERR && errval <= (WSABASEERR + 1015)) {
123: retmsg = GetWSAErrorMessage(errval);
124: if (retmsg != NULL)
125: return (retmsg);
126: }
127: /*
128: * If it's not one of the standard Unix error codes,
129: * try a system error message
130: */
131: if (errval > (DWORD) _sys_nerr) {
132: *bfreebuf = TRUE;
133: return (FormatError(errval));
134: } else {
135: return (strerror(errval));
136: }
137: }
138:
139: /*
140: * This is a replacement for perror
141: */
142: void __cdecl
143: NTperror(char *errmsg) {
144: /* Copy the error value first in case of other errors */
145: int errval = errno;
146: BOOL bfreebuf = FALSE;
147: char *msg;
148:
149: msg = NTstrerror(errval, &bfreebuf);
150: fprintf(stderr, "%s: %s\n", errmsg, msg);
151: if(bfreebuf == TRUE) {
152: LocalFree(msg);
153: }
154:
155: }
156:
157: /*
158: * Return the error string related to Winsock2 errors.
159: * This function is necessary since FormatMessage knows nothing about them
160: * and there is no function to get them.
161: */
162: char *
163: GetWSAErrorMessage(int errval) {
164: char *msg;
165:
166: switch (errval) {
167:
168: case WSAEINTR:
169: msg = "Interrupted system call";
170: break;
171:
172: case WSAEBADF:
173: msg = "Bad file number";
174: break;
175:
176: case WSAEACCES:
177: msg = "Permission denied";
178: break;
179:
180: case WSAEFAULT:
181: msg = "Bad address";
182: break;
183:
184: case WSAEINVAL:
185: msg = "Invalid argument";
186: break;
187:
188: case WSAEMFILE:
189: msg = "Too many open sockets";
190: break;
191:
192: case WSAEWOULDBLOCK:
193: msg = "Operation would block";
194: break;
195:
196: case WSAEINPROGRESS:
197: msg = "Operation now in progress";
198: break;
199:
200: case WSAEALREADY:
201: msg = "Operation already in progress";
202: break;
203:
204: case WSAENOTSOCK:
205: msg = "Socket operation on non-socket";
206: break;
207:
208: case WSAEDESTADDRREQ:
209: msg = "Destination address required";
210: break;
211:
212: case WSAEMSGSIZE:
213: msg = "Message too long";
214: break;
215:
216: case WSAEPROTOTYPE:
217: msg = "Protocol wrong type for socket";
218: break;
219:
220: case WSAENOPROTOOPT:
221: msg = "Bad protocol option";
222: break;
223:
224: case WSAEPROTONOSUPPORT:
225: msg = "Protocol not supported";
226: break;
227:
228: case WSAESOCKTNOSUPPORT:
229: msg = "Socket type not supported";
230: break;
231:
232: case WSAEOPNOTSUPP:
233: msg = "Operation not supported on socket";
234: break;
235:
236: case WSAEPFNOSUPPORT:
237: msg = "Protocol family not supported";
238: break;
239:
240: case WSAEAFNOSUPPORT:
241: msg = "Address family not supported";
242: break;
243:
244: case WSAEADDRINUSE:
245: msg = "Address already in use";
246: break;
247:
248: case WSAEADDRNOTAVAIL:
249: msg = "Can't assign requested address";
250: break;
251:
252: case WSAENETDOWN:
253: msg = "Network is down";
254: break;
255:
256: case WSAENETUNREACH:
257: msg = "Network is unreachable";
258: break;
259:
260: case WSAENETRESET:
261: msg = "Net connection reset";
262: break;
263:
264: case WSAECONNABORTED:
265: msg = "Software caused connection abort";
266: break;
267:
268: case WSAECONNRESET:
269: msg = "Connection reset by peer";
270: break;
271:
272: case WSAENOBUFS:
273: msg = "No buffer space available";
274: break;
275:
276: case WSAEISCONN:
277: msg = "Socket is already connected";
278: break;
279:
280: case WSAENOTCONN:
281: msg = "Socket is not connected";
282: break;
283:
284: case WSAESHUTDOWN:
285: msg = "Can't send after socket shutdown";
286: break;
287:
288: case WSAETOOMANYREFS:
289: msg = "Too many references: can't splice";
290: break;
291:
292: case WSAETIMEDOUT:
293: msg = "Connection timed out";
294: break;
295:
296: case WSAECONNREFUSED:
297: msg = "Connection refused";
298: break;
299:
300: case WSAELOOP:
301: msg = "Too many levels of symbolic links";
302: break;
303:
304: case WSAENAMETOOLONG:
305: msg = "File name too long";
306: break;
307:
308: case WSAEHOSTDOWN:
309: msg = "Host is down";
310: break;
311:
312: case WSAEHOSTUNREACH:
313: msg = "No route to host";
314: break;
315:
316: case WSAENOTEMPTY:
317: msg = "Directory not empty";
318: break;
319:
320: case WSAEPROCLIM:
321: msg = "Too many processes";
322: break;
323:
324: case WSAEUSERS:
325: msg = "Too many users";
326: break;
327:
328: case WSAEDQUOT:
329: msg = "Disc quota exceeded";
330: break;
331:
332: case WSAESTALE:
333: msg = "Stale NFS file handle";
334: break;
335:
336: case WSAEREMOTE:
337: msg = "Too many levels of remote in path";
338: break;
339:
340: case WSASYSNOTREADY:
341: msg = "Network system is unavailable";
342: break;
343:
344: case WSAVERNOTSUPPORTED:
345: msg = "Winsock version out of range";
346: break;
347:
348: case WSANOTINITIALISED:
349: msg = "WSAStartup not yet called";
350: break;
351:
352: case WSAEDISCON:
353: msg = "Graceful shutdown in progress";
354: break;
355: /*
356: case WSAHOST_NOT_FOUND:
357: msg = "Host not found";
358: break;
359:
360: case WSANO_DATA:
361: msg = "No host data of that type was found";
362: break;
363: */
364: default:
365: msg = NULL;
366: break;
367: }
368: return (msg);
369: }
370:
371: /*
372: * These error messages are more informative about CryptAPI Errors than the
373: * standard error messages
374: */
375:
376: char *
377: GetCryptErrorMessage(int errval) {
378: char *msg;
379:
380: switch (errval) {
381:
382: case NTE_BAD_FLAGS:
383: msg = "The dwFlags parameter has an illegal value.";
384: break;
385: case NTE_BAD_KEYSET:
386: msg = "The Registry entry for the key container "
387: "could not be opened and may not exist.";
388: break;
389: case NTE_BAD_KEYSET_PARAM:
390: msg = "The pszContainer or pszProvider parameter "
391: "is set to an illegal value.";
392: break;
393: case NTE_BAD_PROV_TYPE:
394: msg = "The value of the dwProvType parameter is out "
395: "of range. All provider types must be from "
396: "1 to 999, inclusive.";
397: break;
398: case NTE_BAD_SIGNATURE:
399: msg = "The provider DLL signature did not verify "
400: "correctly. Either the DLL or the digital "
401: "signature has been tampered with.";
402: break;
403: case NTE_EXISTS:
404: msg = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key"
405: " container already exists.";
406: break;
407: case NTE_KEYSET_ENTRY_BAD:
408: msg = "The Registry entry for the pszContainer key container "
409: "was found (in the HKEY_CURRENT_USER window), but is "
410: "corrupt. See the section System Administration for "
411: " etails about CryptoAPI's Registry usage.";
412: break;
413: case NTE_KEYSET_NOT_DEF:
414: msg = "No Registry entry exists in the HKEY_CURRENT_USER "
415: "window for the key container specified by "
416: "pszContainer.";
417: break;
418: case NTE_NO_MEMORY:
419: msg = "The CSP ran out of memory during the operation.";
420: break;
421: case NTE_PROV_DLL_NOT_FOUND:
422: msg = "The provider DLL file does not exist or is not on the "
423: "current path.";
424: break;
425: case NTE_PROV_TYPE_ENTRY_BAD:
426: msg = "The Registry entry for the provider type specified by "
427: "dwProvType is corrupt. This error may relate to "
428: "either the user default CSP list or the machine "
429: "default CSP list. See the section System "
430: "Administration for details about CryptoAPI's "
431: "Registry usage.";
432: break;
433: case NTE_PROV_TYPE_NO_MATCH:
434: msg = "The provider type specified by dwProvType does not "
435: "match the provider type found in the Registry. Note "
436: "that this error can only occur when pszProvider "
437: "specifies an actual CSP name.";
438: break;
439: case NTE_PROV_TYPE_NOT_DEF:
440: msg = "No Registry entry exists for the provider type "
441: "specified by dwProvType.";
442: break;
443: case NTE_PROVIDER_DLL_FAIL:
444: msg = "The provider DLL file could not be loaded, and "
445: "may not exist. If it exists, then the file is "
446: "not a valid DLL.";
447: break;
448: case NTE_SIGNATURE_FILE_BAD:
449: msg = "An error occurred while loading the DLL file image, "
450: "prior to verifying its signature.";
451: break;
452:
453: default:
454: msg = NULL;
455: break;
456: }
457: return msg;
458: }
459:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>