Fix compilation on systems with older compilers.
[tor.git] / src / lib / log / win32err.c
blob8136813aaba583b71646415f6a221b0617a2964a
1 /* Copyright (c) 2003-2004, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2020, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 /**
7 * \file win32err.c
8 * \brief Convert windows error codes to useful C strings.
9 **/
11 #ifdef _WIN32
12 #include "orconfig.h"
13 #include "lib/log/win32err.h"
14 #include "lib/malloc/malloc.h"
16 #include <tchar.h>
17 #include <windows.h>
19 /** Return a newly allocated string describing the windows system error code
20 * <b>err</b>. Note that error codes are different from errno. Error codes
21 * come from GetLastError() when a winapi call fails. errno is set only when
22 * ANSI functions fail. Whee. */
23 char *
24 format_win32_error(DWORD err)
26 TCHAR *str = NULL;
27 char *result;
28 DWORD n;
30 /* Somebody once decided that this interface was better than strerror(). */
31 n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
32 FORMAT_MESSAGE_FROM_SYSTEM |
33 FORMAT_MESSAGE_IGNORE_INSERTS,
34 NULL, err,
35 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
36 (LPVOID)&str,
37 0, NULL);
39 if (str && n) {
40 #ifdef UNICODE
41 size_t len;
42 if (n > 128*1024)
43 len = (128 * 1024) * 2 + 1; /* This shouldn't be possible, but let's
44 * make sure. */
45 else
46 len = n * 2 + 1;
47 result = tor_malloc(len);
48 wcstombs(result,str,len);
49 result[len-1] = '\0';
50 #else /* !defined(UNICODE) */
51 result = tor_strdup(str);
52 #endif /* defined(UNICODE) */
53 } else {
54 result = tor_strdup("<unformattable error>");
56 if (str) {
57 LocalFree(str); /* LocalFree != free() */
59 return result;
61 #endif /* defined(_WIN32) */