Commit d6179e12 authored by Amaury Forgeot d'Arc's avatar Amaury Forgeot d'Arc

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.
parent 819b8bf4
...@@ -183,33 +183,35 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, ...@@ -183,33 +183,35 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
hDLL = LoadLibraryEx(pathname, NULL, hDLL = LoadLibraryEx(pathname, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH); LOAD_WITH_ALTERED_SEARCH_PATH);
if (hDLL==NULL){ if (hDLL==NULL){
char errBuf[256]; PyObject *message;
unsigned int errorCode; unsigned int errorCode;
/* Get an error string from Win32 error code */ /* Get an error string from Win32 error code */
char theInfo[256]; /* Pointer to error text wchar_t theInfo[256]; /* Pointer to error text
from system */ from system */
int theLength; /* Length of error text */ int theLength; /* Length of error text */
errorCode = GetLastError(); errorCode = GetLastError();
theLength = FormatMessage( theLength = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM, /* flags */ FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
NULL, /* message source */ NULL, /* message source */
errorCode, /* the message (error) ID */ errorCode, /* the message (error) ID */
0, /* default language environment */ MAKELANGID(LANG_NEUTRAL,
(LPTSTR) theInfo, /* the buffer */ SUBLANG_DEFAULT),
/* Default language */
theInfo, /* the buffer */
sizeof(theInfo), /* the buffer size */ sizeof(theInfo), /* the buffer size */
NULL); /* no additional format args. */ NULL); /* no additional format args. */
/* Problem: could not get the error message. /* Problem: could not get the error message.
This should not happen if called correctly. */ This should not happen if called correctly. */
if (theLength == 0) { if (theLength == 0) {
PyOS_snprintf(errBuf, sizeof(errBuf), message = PyUnicode_FromFormat(
"DLL load failed with error code %d", "DLL load failed with error code %d",
errorCode); errorCode);
} else { } else {
size_t len;
/* For some reason a \r\n /* For some reason a \r\n
is appended to the text */ is appended to the text */
if (theLength >= 2 && if (theLength >= 2 &&
...@@ -218,13 +220,16 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, ...@@ -218,13 +220,16 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
theLength -= 2; theLength -= 2;
theInfo[theLength] = '\0'; theInfo[theLength] = '\0';
} }
strcpy(errBuf, "DLL load failed: "); message = PyUnicode_FromString(
len = strlen(errBuf); "DLL load failed: ");
strncpy(errBuf+len, theInfo,
sizeof(errBuf)-len); PyUnicode_AppendAndDel(&message,
errBuf[sizeof(errBuf)-1] = '\0'; PyUnicode_FromUnicode(
theInfo,
theLength));
} }
PyErr_SetString(PyExc_ImportError, errBuf); PyErr_SetObject(PyExc_ImportError, message);
Py_XDECREF(message);
return NULL; return NULL;
} else { } else {
char buffer[256]; char buffer[256];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment