| 227 | } |
| 228 | |
| 229 | static void register_winapi_error_to_buffer(wchar_t **error_buffer, const WCHAR *op) |
| 230 | { |
| 231 | free(*error_buffer); |
| 232 | *error_buffer = NULL; |
| 233 | |
| 234 | /* Only clear out error messages if NULL is passed into op */ |
| 235 | if (!op) { |
| 236 | return; |
| 237 | } |
| 238 | |
| 239 | WCHAR system_err_buf[1024]; |
| 240 | DWORD error_code = GetLastError(); |
| 241 | |
| 242 | DWORD system_err_len = FormatMessageW( |
| 243 | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 244 | NULL, |
| 245 | error_code, |
| 246 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 247 | system_err_buf, ARRAYSIZE(system_err_buf), |
| 248 | NULL); |
| 249 | |
| 250 | DWORD op_len = (DWORD)wcslen(op); |
| 251 | |
| 252 | DWORD op_prefix_len = |
| 253 | op_len |
| 254 | + 15 /*: (0x00000000) */ |
| 255 | ; |
| 256 | DWORD msg_len = |
| 257 | + op_prefix_len |
| 258 | + system_err_len |
| 259 | ; |
| 260 | |
| 261 | *error_buffer = (WCHAR *)calloc(msg_len + 1, sizeof (WCHAR)); |
| 262 | WCHAR *msg = *error_buffer; |
| 263 | |
| 264 | if (!msg) |
| 265 | return; |
| 266 | |
| 267 | int printf_written = swprintf(msg, msg_len + 1, L"%.*ls: (0x%08X) %.*ls", (int)op_len, op, error_code, (int)system_err_len, system_err_buf); |
| 268 | |
| 269 | if (printf_written < 0) |
| 270 | { |
| 271 | /* Highly unlikely */ |
| 272 | msg[0] = L'\0'; |
| 273 | return; |
| 274 | } |
| 275 | |
| 276 | /* Get rid of the CR and LF that FormatMessage() sticks at the |
| 277 | end of the message. Thanks Microsoft! */ |
| 278 | while(msg[msg_len-1] == L'\r' || msg[msg_len-1] == L'\n' || msg[msg_len-1] == L' ') |
| 279 | { |
| 280 | msg[msg_len-1] = L'\0'; |
| 281 | msg_len--; |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | #if defined(__GNUC__) |
| 286 | # pragma GCC diagnostic push |
no outgoing calls
no test coverage detected