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>