123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- /*
- * Wrapper around the Windows FormatMessage system for retrieving the
- * text of a system error code, with a simple API similar to strerror.
- *
- * Works by keeping a tree234 containing mappings from system error
- * codes to strings. Entries allocated in this tree are simply never
- * freed.
- *
- * Also, the returned string has its trailing newline removed (so it
- * can go in places like the Event Log that never want a newline), and
- * is prefixed with the error number (so that if a user sends an error
- * report containing a translated error message we can't read, we can
- * still find out what the error actually was).
- */
- #include "putty.h"
- struct errstring {
- int error;
- char *text;
- };
- static int errstring_find(void *av, void *bv)
- {
- int *a = (int *)av;
- struct errstring *b = (struct errstring *)bv;
- if (*a < b->error)
- return -1;
- if (*a > b->error)
- return +1;
- return 0;
- }
- static int errstring_compare(void *av, void *bv)
- {
- struct errstring *a = (struct errstring *)av;
- return errstring_find(&a->error, bv);
- }
- static tree234 *errstrings = NULL;
- const char *win_strerror(int error)
- {
- struct errstring *es;
- if (!errstrings)
- errstrings = newtree234(errstring_compare);
- es = find234(errstrings, &error, errstring_find);
- if (!es) {
- char msgtext[65536]; /* maximum size for FormatMessage is 64K */
- es = snew(struct errstring);
- es->error = error;
- if (!FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS), NULL, error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- msgtext, lenof(msgtext)-1, NULL)) {
- sprintf(msgtext,
- "(unable to format: FormatMessage returned %u)",
- (unsigned int)GetLastError());
- } else {
- int len = strlen(msgtext);
- if (len > 0 && msgtext[len-1] == '\n')
- msgtext[len-1] = '\0';
- }
- es->text = dupprintf("Error %d: %s", error, msgtext);
- add234(errstrings, es);
- }
- return es->text;
- }
|