From 688861a828dce616dbc0b67397558b2ecaaa8a75 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 22 Jul 2013 07:11:39 +0000 Subject: [PATCH] Invent a win_strerror() function which behaves as much like Unix strerror as I can arrange, wrapping up all the ugly FormatMessage nonsense and caching previously looked-up messages for reuse so that callers can treat them as static. git-svn-id: svn://svn.tartarus.org/sgt/putty@9956 cda61777-01e9-0310-a592-d414129be87e --- windows/winmisc.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ windows/winstuff.h | 1 + 2 files changed, 64 insertions(+) diff --git a/windows/winmisc.c b/windows/winmisc.c index c74f1e7a..525d52c5 100644 --- a/windows/winmisc.c +++ b/windows/winmisc.c @@ -173,6 +173,69 @@ HMODULE load_system32_dll(const char *libname) return ret; } +/* + * A tree234 containing mappings from system error codes to strings. + */ + +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) { + int bufsize, bufused; + + es = snew(struct errstring); + es->error = error; + /* maximum size for FormatMessage is 64K */ + bufsize = 65535; + es->text = snewn(bufsize, char); + if (!FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + es->text + bufused, bufsize - bufused, NULL)) { + sprintf(es->text, + "Windows error code %d (and FormatMessage returned %d)", + error, GetLastError()); + } else { + int len = strlen(es->text); + if (len > 0 && es->text[len-1] == '\n') + es->text[len-1] = '\0'; + } + es->text = sresize(es->text, strlen(es->text) + 1, char); + add234(errstrings, es); + } + + return es->text; +} + #ifdef DEBUG static FILE *debug_fp = NULL; static HANDLE debug_hdl = INVALID_HANDLE_VALUE; diff --git a/windows/winstuff.h b/windows/winstuff.h index cfed0484..65711728 100644 --- a/windows/winstuff.h +++ b/windows/winstuff.h @@ -461,6 +461,7 @@ void show_help(HWND hwnd); extern OSVERSIONINFO osVersion; BOOL init_winver(void); HMODULE load_system32_dll(const char *libname); +const char *win_strerror(int error); /* * Exports from sizetip.c. -- 2.11.0