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