2 * Copyright (C) 2002 Internet Software Consortium.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
9 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
10 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
11 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
13 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
14 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 /* From BIND 9 lib/isc/win32/: strerror.c,v 1.5 2002/08/01 03:52:14 mayer */
21 * We don't need this warning message
23 #pragma warning(disable: 4127) /* conditional expression is constant */
34 typedef struct msg_list msg_list_t;
39 ISC_LINK(msg_list_t) link;
42 static ISC_LIST(msg_list_t) errormsg_list;
44 BOOL initialized = FALSE;
46 static CRITICAL_SECTION ErrorMsgLock;
47 # define LOCK(lock) EnterCriticalSection(lock)
48 # define UNLOCK(lock) LeaveCriticalSection(lock)
51 * Forward declarations
55 FormatError(int error);
58 GetWSAErrorMessage(int errval);
61 isc__NTstrerror(int err);
64 * Initialize the error message list
69 ISC_LIST_INIT(errormsg_list);
70 InitializeCriticalSection(&ErrorMsgLock);
75 NTstrerror(int errnum) {
78 return (isc__NTstrerror(errnum));
81 * This routine needs to free up any buffer allocated by FormatMessage
82 * if that routine gets used.
86 isc__strerror(int num, char *buf, size_t size) {
88 unsigned int unum = num;
92 msg = isc__NTstrerror(num);
94 _snprintf(buf, size, "%s", msg);
96 _snprintf(buf, size, "Unknown error: %u", unum);
100 * Note this will cause a memory leak unless the memory allocated here
101 * is freed by calling LocalFree. isc__strerror does this before unlocking.
102 * This only gets called if there is a system type of error and will likely
103 * be an unusual event.
106 FormatError(int error) {
107 LPVOID lpMsgBuf = NULL;
112 * See if we already have the error code
117 lmsg = ISC_LIST_HEAD(errormsg_list);
118 while (lmsg != NULL) {
119 if (lmsg->code == error) {
120 lpMsgBuf = lmsg->msg;
121 UNLOCK(&ErrorMsgLock);
124 lmsg = ISC_LIST_NEXT(lmsg, link);
132 FORMAT_MESSAGE_ALLOCATE_BUFFER |
133 FORMAT_MESSAGE_FROM_SYSTEM |
134 FORMAT_MESSAGE_IGNORE_INSERTS,
137 /* Default language */
138 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
143 if (lpMsgBuf != NULL) {
144 lmsg = malloc(sizeof(msg_list_t));
146 lmsg->msg = lpMsgBuf;
147 ISC_LIST_APPEND(errormsg_list, lmsg, link);
149 UNLOCK(&ErrorMsgLock);
154 * This routine checks the error value and calls the WSA Windows Sockets
155 * Error message function GetWSAErrorMessage below if it's within that range
156 * since those messages are not available in the system error messages.
159 isc__NTstrerror(int err) {
162 /* Copy the error value first in case of other errors */
165 /* Get the Winsock2 error messages */
166 if (errval >= WSABASEERR && errval <= (WSABASEERR + 1015)) {
167 retmsg = GetWSAErrorMessage(errval);
172 * If it's not one of the standard Unix error codes,
173 * try a system error message
175 if (errval > (DWORD) _sys_nerr) {
176 return (FormatError(errval));
178 return (_sys_errlist[errval]);
183 * This is a replacement for perror
186 NTperror(char *errmsg) {
187 /* Copy the error value first in case of other errors */
193 msg = isc__NTstrerror(errval);
194 fprintf(stderr, "%s: %s\n", errmsg, msg);
199 * Return the error string related to Winsock2 errors.
200 * This function is necessary since FormatMessage knows nothing about them
201 * and there is no function to get them.
204 GetWSAErrorMessage(int errval) {
210 msg = "Interrupted system call";
214 msg = "Bad file number";
218 msg = "Permission denied";
226 msg = "Invalid argument";
230 msg = "Too many open sockets";
234 msg = "Operation would block";
238 msg = "Operation now in progress";
242 msg = "Operation already in progress";
246 msg = "Socket operation on non-socket";
249 case WSAEDESTADDRREQ:
250 msg = "Destination address required";
254 msg = "Message too long";
258 msg = "Protocol wrong type for socket";
262 msg = "Bad protocol option";
265 case WSAEPROTONOSUPPORT:
266 msg = "Protocol not supported";
269 case WSAESOCKTNOSUPPORT:
270 msg = "Socket type not supported";
274 msg = "Operation not supported on socket";
277 case WSAEPFNOSUPPORT:
278 msg = "Protocol family not supported";
281 case WSAEAFNOSUPPORT:
282 msg = "Address family not supported";
286 msg = "Address already in use";
289 case WSAEADDRNOTAVAIL:
290 msg = "Can't assign requested address";
294 msg = "Network is down";
298 msg = "Network is unreachable";
302 msg = "Net connection reset";
305 case WSAECONNABORTED:
306 msg = "Software caused connection abort";
310 msg = "Connection reset by peer";
314 msg = "No buffer space available";
318 msg = "Socket is already connected";
322 msg = "Socket is not connected";
326 msg = "Can't send after socket shutdown";
329 case WSAETOOMANYREFS:
330 msg = "Too many references: can't splice";
334 msg = "Connection timed out";
337 case WSAECONNREFUSED:
338 msg = "Connection refused";
342 msg = "Too many levels of symbolic links";
345 case WSAENAMETOOLONG:
346 msg = "File name too long";
350 msg = "Host is down";
353 case WSAEHOSTUNREACH:
354 msg = "No route to host";
358 msg = "Directory not empty";
362 msg = "Too many processes";
366 msg = "Too many users";
370 msg = "Disc quota exceeded";
374 msg = "Stale NFS file handle";
378 msg = "Too many levels of remote in path";
382 msg = "Network system is unavailable";
385 case WSAVERNOTSUPPORTED:
386 msg = "Winsock version out of range";
389 case WSANOTINITIALISED:
390 msg = "WSAStartup not yet called";
394 msg = "Graceful shutdown in progress";
397 case WSAHOST_NOT_FOUND:
398 msg = "Host not found";
402 msg = "No host data of that type was found";
413 * These error messages are more informative about CryptAPI Errors than the
414 * standard error messages
418 GetCryptErrorMessage(int errval) {
424 msg = "The dwFlags parameter has an illegal value.";
427 msg = "The Registry entry for the key container "
428 "could not be opened and may not exist.";
430 case NTE_BAD_KEYSET_PARAM:
431 msg = "The pszContainer or pszProvider parameter "
432 "is set to an illegal value.";
434 case NTE_BAD_PROV_TYPE:
435 msg = "The value of the dwProvType parameter is out "
436 "of range. All provider types must be from "
437 "1 to 999, inclusive.";
439 case NTE_BAD_SIGNATURE:
440 msg = "The provider DLL signature did not verify "
441 "correctly. Either the DLL or the digital "
442 "signature has been tampered with.";
445 msg = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key"
446 " container already exists.";
448 case NTE_KEYSET_ENTRY_BAD:
449 msg = "The Registry entry for the pszContainer key container "
450 "was found (in the HKEY_CURRENT_USER window), but is "
451 "corrupt. See the section System Administration for "
452 " etails about CryptoAPI's Registry usage.";
454 case NTE_KEYSET_NOT_DEF:
455 msg = "No Registry entry exists in the HKEY_CURRENT_USER "
456 "window for the key container specified by "
460 msg = "The CSP ran out of memory during the operation.";
462 case NTE_PROV_DLL_NOT_FOUND:
463 msg = "The provider DLL file does not exist or is not on the "
466 case NTE_PROV_TYPE_ENTRY_BAD:
467 msg = "The Registry entry for the provider type specified by "
468 "dwProvType is corrupt. This error may relate to "
469 "either the user default CSP list or the machine "
470 "default CSP list. See the section System "
471 "Administration for details about CryptoAPI's "
474 case NTE_PROV_TYPE_NO_MATCH:
475 msg = "The provider type specified by dwProvType does not "
476 "match the provider type found in the Registry. Note "
477 "that this error can only occur when pszProvider "
478 "specifies an actual CSP name.";
480 case NTE_PROV_TYPE_NOT_DEF:
481 msg = "No Registry entry exists for the provider type "
482 "specified by dwProvType.";
484 case NTE_PROVIDER_DLL_FAIL:
485 msg = "The provider DLL file could not be loaded, and "
486 "may not exist. If it exists, then the file is "
489 case NTE_SIGNATURE_FILE_BAD:
490 msg = "An error occurred while loading the DLL file image, "
491 "prior to verifying its signature.";