Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d6179e1

Browse files
committed
On Windows, when import fails to load a dll module, the message says
"error code 193" instead of a more informative text. It turns out that FormatMessage needs additional parameters for some error codes. For example: 193 means "%1 is not a valid Win32 application". Since it is impossible to know which parameter to pass, we use FORMAT_MESSAGE_IGNORE_INSERTS to get the raw message, which is still better than the number. Also use the Unicode version of the API, to deal with accented letters.
1 parent 819b8bf commit d6179e1

1 file changed

Lines changed: 21 additions & 16 deletions

File tree

Python/dynload_win.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -183,33 +183,35 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
183183
hDLL = LoadLibraryEx(pathname, NULL,
184184
LOAD_WITH_ALTERED_SEARCH_PATH);
185185
if (hDLL==NULL){
186-
char errBuf[256];
186+
PyObject *message;
187187
unsigned int errorCode;
188188

189189
/* Get an error string from Win32 error code */
190-
char theInfo[256]; /* Pointer to error text
190+
wchar_t theInfo[256]; /* Pointer to error text
191191
from system */
192192
int theLength; /* Length of error text */
193193

194194
errorCode = GetLastError();
195195

196-
theLength = FormatMessage(
197-
FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
196+
theLength = FormatMessageW(
197+
FORMAT_MESSAGE_FROM_SYSTEM |
198+
FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
198199
NULL, /* message source */
199200
errorCode, /* the message (error) ID */
200-
0, /* default language environment */
201-
(LPTSTR) theInfo, /* the buffer */
201+
MAKELANGID(LANG_NEUTRAL,
202+
SUBLANG_DEFAULT),
203+
/* Default language */
204+
theInfo, /* the buffer */
202205
sizeof(theInfo), /* the buffer size */
203206
NULL); /* no additional format args. */
204207

205208
/* Problem: could not get the error message.
206209
This should not happen if called correctly. */
207210
if (theLength == 0) {
208-
PyOS_snprintf(errBuf, sizeof(errBuf),
209-
"DLL load failed with error code %d",
210-
errorCode);
211+
message = PyUnicode_FromFormat(
212+
"DLL load failed with error code %d",
213+
errorCode);
211214
} else {
212-
size_t len;
213215
/* For some reason a \r\n
214216
is appended to the text */
215217
if (theLength >= 2 &&
@@ -218,13 +220,16 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
218220
theLength -= 2;
219221
theInfo[theLength] = '\0';
220222
}
221-
strcpy(errBuf, "DLL load failed: ");
222-
len = strlen(errBuf);
223-
strncpy(errBuf+len, theInfo,
224-
sizeof(errBuf)-len);
225-
errBuf[sizeof(errBuf)-1] = '\0';
223+
message = PyUnicode_FromString(
224+
"DLL load failed: ");
225+
226+
PyUnicode_AppendAndDel(&message,
227+
PyUnicode_FromUnicode(
228+
theInfo,
229+
theLength));
226230
}
227-
PyErr_SetString(PyExc_ImportError, errBuf);
231+
PyErr_SetObject(PyExc_ImportError, message);
232+
Py_XDECREF(message);
228233
return NULL;
229234
} else {
230235
char buffer[256];

0 commit comments

Comments
 (0)