-
Notifications
You must be signed in to change notification settings - Fork 263
/
Copy pathwin32_errmsg.c
138 lines (124 loc) · 6.05 KB
/
win32_errmsg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/************************************************************************************
Copyright (C) 2019 MariaDB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
*************************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
Format Windows error, with optional text.
For "known" errors we also output their symbolic error constant, e.g
CERT_E_CN_NO_MATCH in addition to numeric value.
We also try to output English text for all error messages, as not to mess up
with encodings.
*/
void ma_format_win32_error(char* buf, size_t buflen, DWORD code, _Printf_format_string_ const char* fmt, ...)
{
char* cur = buf;
char* end = cur + buflen;
*cur = 0;
if (fmt)
{
va_list vargs;
va_start(vargs, fmt);
cur += vsnprintf_s(cur, end - cur, _TRUNCATE, fmt, vargs);
va_end(vargs);
}
if (code == 0)
return;
static struct map_entry
{
DWORD code;
const char* sym;
const char* msg;
}
map[] =
{
#define ENTRY(x, y) {x,#x, y}
ENTRY(SEC_E_WRONG_PRINCIPAL, "The target principal name is incorrect"),
ENTRY(CERT_E_CN_NO_MATCH,"The certificate's CN name does not match the passed value"),
ENTRY(SEC_E_UNTRUSTED_ROOT,"The certificate chain was issued by an authority that is not trusted"),
ENTRY(TRUST_E_CERT_SIGNATURE,"The signature of the certificate cannot be verified"),
ENTRY(SEC_E_CERT_EXPIRED,"The received certificate has expired"),
ENTRY(CERT_E_EXPIRED,"A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file"),
ENTRY(CRYPT_E_NO_REVOCATION_CHECK, "The revocation function was unable to check revocation for the certificate"),
ENTRY(CRYPT_E_REVOCATION_OFFLINE,"The revocation function was unable to check revocation because the revocation server was offline"),
ENTRY(CRYPT_E_REVOKED,"The certificate is revoked"),
ENTRY(SEC_E_CERT_UNKNOWN,"An unknown error occurred while processing the certificate"),
ENTRY(CERT_E_ROLE," A certificate that can only be used as an end-entity is being used as a CA or vice versa"),
ENTRY(CERT_E_WRONG_USAGE,"The certificate is not valid for the requested usage"),
ENTRY(SEC_E_ILLEGAL_MESSAGE, "The message received was unexpected or badly formatted"),
ENTRY(CERT_E_VALIDITYPERIODNESTING,"The validity periods of the certification chain do not nest correctly"),
ENTRY(CERT_E_PATHLENCONST,"A path length constraint in the certification chain has been violated"),
ENTRY(CERT_E_CRITICAL,"A certificate contains an unknown extension that is marked 'critical'"),
ENTRY(CERT_E_PURPOSE,"A certificate being used for a purpose other than the ones specified by its CA"),
ENTRY(CERT_E_ISSUERCHAINING,"A parent of a given certificate in fact did not issue that child certificate"),
ENTRY(CERT_E_MALFORMED, "A certificate is missing or has an empty value for an important field, such as a subject or issuer name"),
ENTRY(CERT_E_CHAINING,"A certificate chain could not be built to a trusted root authority"),
ENTRY(TRUST_E_FAIL," Generic trust failure"),
ENTRY(CERT_E_UNTRUSTEDTESTROOT,"The certification path terminates with the test root which is not trusted with the current policy settings"),
ENTRY(CERT_E_UNTRUSTEDROOT,"A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider"),
ENTRY(CERT_E_REVOCATION_FAILURE,"The revocation process could not continue - the certificate(s) could not be checked"),
ENTRY(SEC_E_ILLEGAL_MESSAGE, "The message received was unexpected or badly formatted"),
ENTRY(SEC_E_UNTRUSTED_ROOT, "Untrusted root certificate"),
ENTRY(SEC_E_BUFFER_TOO_SMALL, "Buffer too small"),
ENTRY(SEC_E_CRYPTO_SYSTEM_INVALID, "Cipher is not supported"),
ENTRY(SEC_E_INSUFFICIENT_MEMORY, "Out of memory"),
ENTRY(SEC_E_OUT_OF_SEQUENCE, "Invalid message sequence"),
ENTRY(SEC_E_DECRYPT_FAILURE, "The specified data could not be decrypted"),
ENTRY(SEC_I_INCOMPLETE_CREDENTIALS, "Incomplete credentials"),
ENTRY(SEC_E_ENCRYPT_FAILURE, "The specified data could not be encrypted"),
ENTRY(SEC_I_CONTEXT_EXPIRED, "The context has expired and can no longer be used"),
ENTRY(SEC_E_ALGORITHM_MISMATCH, "no cipher match"),
ENTRY(SEC_E_NO_CREDENTIALS, "no credentials"),
ENTRY(SEC_E_INVALID_TOKEN, "The token supplied to function is invalid"),
ENTRY(SEC_E_UNSUPPORTED_FUNCTION,"The function requested is not supported")
};
struct map_entry* entry = NULL;
if (cur > buf && cur[-1] != ' ' && cur[-1] != '.')
{
strncpy_s(cur,end-cur, ". ", _TRUNCATE);
cur += 2;
}
for (size_t i = 0; i < sizeof(map) / sizeof(map[0]); i++)
{
if (code == map[i].code)
{
entry = &map[i];
break;
}
}
if (cur > end - 20)
return;
if (entry)
{
snprintf(cur, end - cur, "%s. Error 0x%08lX(%s)", entry->msg, code, entry->sym);
}
else
{
cur += FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
cur, (DWORD)(end - cur), NULL);
while (cur > buf && (*cur == '\0' || *cur == '\n' || *cur == '\r' || *cur == '.'))
cur--;
if (*cur)
{
cur++;
*cur = 0;
}
snprintf(cur, end - cur, ". Error %lu/0x%08lX", code, code);
}
end[-1] = 0;
}