4 * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2001, 2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: strerror.c,v 1.8 2007/06/19 23:47:19 tbox Exp */
28 #include <isc/mutex.h>
30 #include <isc/print.h>
31 #include <isc/strerror.h>
35 * Forward declarations
39 FormatError(int error
);
42 GetWSAErrorMessage(int errval
);
45 NTstrerror(int err
, BOOL
*bfreebuf
);
48 * We need to do this this way for profiled locks.
51 static isc_mutex_t isc_strerror_lock
;
52 static void init_lock(void) {
53 RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock
) == ISC_R_SUCCESS
);
57 * This routine needs to free up any buffer allocated by FormatMessage
58 * if that routine gets used.
62 isc__strerror(int num
, char *buf
, size_t size
) {
65 unsigned int unum
= num
;
66 static isc_once_t once
= ISC_ONCE_INIT
;
70 RUNTIME_CHECK(isc_once_do(&once
, init_lock
) == ISC_R_SUCCESS
);
72 LOCK(&isc_strerror_lock
);
74 msg
= NTstrerror(num
, &freebuf
);
76 snprintf(buf
, size
, "%s", msg
);
78 snprintf(buf
, size
, "Unknown error: %u", unum
);
79 if(freebuf
&& msg
!= NULL
) {
82 UNLOCK(&isc_strerror_lock
);
86 * Note this will cause a memory leak unless the memory allocated here
87 * is freed by calling LocalFree. isc__strerror does this before unlocking.
88 * This only gets called if there is a system type of error and will likely
89 * be an unusual event.
92 FormatError(int error
) {
93 LPVOID lpMsgBuf
= NULL
;
95 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
96 FORMAT_MESSAGE_FROM_SYSTEM
|
97 FORMAT_MESSAGE_IGNORE_INSERTS
,
100 /* Default language */
101 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
110 * This routine checks the error value and calls the WSA Windows Sockets
111 * Error message function GetWSAErrorMessage below if it's within that range
112 * since those messages are not available in the system error messages.
115 NTstrerror(int err
, BOOL
*bfreebuf
) {
118 /* Copy the error value first in case of other errors */
123 /* Get the Winsock2 error messages */
124 if (errval
>= WSABASEERR
&& errval
<= (WSABASEERR
+ 1015)) {
125 retmsg
= GetWSAErrorMessage(errval
);
130 * If it's not one of the standard Unix error codes,
131 * try a system error message
133 if (errval
> (DWORD
) _sys_nerr
) {
135 return (FormatError(errval
));
137 return (strerror(errval
));
142 * This is a replacement for perror
145 NTperror(char *errmsg
) {
146 /* Copy the error value first in case of other errors */
148 BOOL bfreebuf
= FALSE
;
151 msg
= NTstrerror(errval
, &bfreebuf
);
152 fprintf(stderr
, "%s: %s\n", errmsg
, msg
);
153 if(bfreebuf
== TRUE
) {
160 * Return the error string related to Winsock2 errors.
161 * This function is necessary since FormatMessage knows nothing about them
162 * and there is no function to get them.
165 GetWSAErrorMessage(int errval
) {
171 msg
= "Interrupted system call";
175 msg
= "Bad file number";
179 msg
= "Permission denied";
187 msg
= "Invalid argument";
191 msg
= "Too many open sockets";
195 msg
= "Operation would block";
199 msg
= "Operation now in progress";
203 msg
= "Operation already in progress";
207 msg
= "Socket operation on non-socket";
210 case WSAEDESTADDRREQ
:
211 msg
= "Destination address required";
215 msg
= "Message too long";
219 msg
= "Protocol wrong type for socket";
223 msg
= "Bad protocol option";
226 case WSAEPROTONOSUPPORT
:
227 msg
= "Protocol not supported";
230 case WSAESOCKTNOSUPPORT
:
231 msg
= "Socket type not supported";
235 msg
= "Operation not supported on socket";
238 case WSAEPFNOSUPPORT
:
239 msg
= "Protocol family not supported";
242 case WSAEAFNOSUPPORT
:
243 msg
= "Address family not supported";
247 msg
= "Address already in use";
250 case WSAEADDRNOTAVAIL
:
251 msg
= "Can't assign requested address";
255 msg
= "Network is down";
259 msg
= "Network is unreachable";
263 msg
= "Net connection reset";
266 case WSAECONNABORTED
:
267 msg
= "Software caused connection abort";
271 msg
= "Connection reset by peer";
275 msg
= "No buffer space available";
279 msg
= "Socket is already connected";
283 msg
= "Socket is not connected";
287 msg
= "Can't send after socket shutdown";
290 case WSAETOOMANYREFS
:
291 msg
= "Too many references: can't splice";
295 msg
= "Connection timed out";
298 case WSAECONNREFUSED
:
299 msg
= "Connection refused";
303 msg
= "Too many levels of symbolic links";
306 case WSAENAMETOOLONG
:
307 msg
= "File name too long";
311 msg
= "Host is down";
314 case WSAEHOSTUNREACH
:
315 msg
= "No route to host";
319 msg
= "Directory not empty";
323 msg
= "Too many processes";
327 msg
= "Too many users";
331 msg
= "Disc quota exceeded";
335 msg
= "Stale NFS file handle";
339 msg
= "Too many levels of remote in path";
343 msg
= "Network system is unavailable";
346 case WSAVERNOTSUPPORTED
:
347 msg
= "Winsock version out of range";
350 case WSANOTINITIALISED
:
351 msg
= "WSAStartup not yet called";
355 msg
= "Graceful shutdown in progress";
358 case WSAHOST_NOT_FOUND:
359 msg = "Host not found";
363 msg = "No host data of that type was found";
374 * These error messages are more informative about CryptAPI Errors than the
375 * standard error messages
379 GetCryptErrorMessage(int errval
) {
385 msg
= "The dwFlags parameter has an illegal value.";
388 msg
= "The Registry entry for the key container "
389 "could not be opened and may not exist.";
391 case NTE_BAD_KEYSET_PARAM
:
392 msg
= "The pszContainer or pszProvider parameter "
393 "is set to an illegal value.";
395 case NTE_BAD_PROV_TYPE
:
396 msg
= "The value of the dwProvType parameter is out "
397 "of range. All provider types must be from "
398 "1 to 999, inclusive.";
400 case NTE_BAD_SIGNATURE
:
401 msg
= "The provider DLL signature did not verify "
402 "correctly. Either the DLL or the digital "
403 "signature has been tampered with.";
406 msg
= "The dwFlags parameter is CRYPT_NEWKEYSET, but the key"
407 " container already exists.";
409 case NTE_KEYSET_ENTRY_BAD
:
410 msg
= "The Registry entry for the pszContainer key container "
411 "was found (in the HKEY_CURRENT_USER window), but is "
412 "corrupt. See the section System Administration for "
413 " etails about CryptoAPI's Registry usage.";
415 case NTE_KEYSET_NOT_DEF
:
416 msg
= "No Registry entry exists in the HKEY_CURRENT_USER "
417 "window for the key container specified by "
421 msg
= "The CSP ran out of memory during the operation.";
423 case NTE_PROV_DLL_NOT_FOUND
:
424 msg
= "The provider DLL file does not exist or is not on the "
427 case NTE_PROV_TYPE_ENTRY_BAD
:
428 msg
= "The Registry entry for the provider type specified by "
429 "dwProvType is corrupt. This error may relate to "
430 "either the user default CSP list or the machine "
431 "default CSP list. See the section System "
432 "Administration for details about CryptoAPI's "
435 case NTE_PROV_TYPE_NO_MATCH
:
436 msg
= "The provider type specified by dwProvType does not "
437 "match the provider type found in the Registry. Note "
438 "that this error can only occur when pszProvider "
439 "specifies an actual CSP name.";
441 case NTE_PROV_TYPE_NOT_DEF
:
442 msg
= "No Registry entry exists for the provider type "
443 "specified by dwProvType.";
445 case NTE_PROVIDER_DLL_FAIL
:
446 msg
= "The provider DLL file could not be loaded, and "
447 "may not exist. If it exists, then the file is "
450 case NTE_SIGNATURE_FILE_BAD
:
451 msg
= "An error occurred while loading the DLL file image, "
452 "prior to verifying its signature.";