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