@@ -289,6 +289,9 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
289289 PyObject * v ;
290290 char * s ;
291291 int i = errno ;
292+ #ifdef MS_WIN32
293+ char * s_buf = NULL ;
294+ #endif
292295#ifdef EINTR
293296 if (i == EINTR && PyErr_CheckSignals ())
294297 return NULL ;
@@ -300,20 +303,32 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
300303 s = strerror (i );
301304#else
302305 {
303- int len = FormatMessage (
304- FORMAT_MESSAGE_ALLOCATE_BUFFER |
305- FORMAT_MESSAGE_FROM_SYSTEM |
306- FORMAT_MESSAGE_IGNORE_INSERTS ,
307- NULL , /* no message source */
308- i ,
309- MAKELANGID (LANG_NEUTRAL ,
310- SUBLANG_DEFAULT ), /* Default language */
311- (LPTSTR ) & s ,
312- 0 , /* size not used */
313- NULL ); /* no args */
314- /* remove trailing cr/lf and dots */
315- while (len > 0 && s [len - 1 ] <= '.' )
316- s [-- len ] = '\0' ;
306+ /* Note that the Win32 errors do not lineup with the
307+ errno error. So if the error is in the MSVC error
308+ table, we use it, otherwise we assume it really _is_
309+ a Win32 error code
310+ */
311+ if (i < _sys_nerr ) {
312+ s = _sys_errlist [i ];
313+ }
314+ else {
315+ int len = FormatMessage (
316+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
317+ FORMAT_MESSAGE_FROM_SYSTEM |
318+ FORMAT_MESSAGE_IGNORE_INSERTS ,
319+ NULL , /* no message source */
320+ i ,
321+ MAKELANGID (LANG_NEUTRAL ,
322+ SUBLANG_DEFAULT ),
323+ /* Default language */
324+ (LPTSTR ) & s_buf ,
325+ 0 , /* size not used */
326+ NULL ); /* no args */
327+ s = s_buf ;
328+ /* remove trailing cr/lf and dots */
329+ while (len > 0 && (s [len - 1 ] <= ' ' || s [len - 1 ] == '.' ))
330+ s [-- len ] = '\0' ;
331+ }
317332 }
318333#endif
319334 if (filename != NULL && Py_UseClassExceptionsFlag )
@@ -325,7 +340,7 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
325340 Py_DECREF (v );
326341 }
327342#ifdef MS_WIN32
328- LocalFree (s );
343+ LocalFree (s_buf );
329344#endif
330345 return NULL ;
331346}
@@ -338,6 +353,51 @@ PyErr_SetFromErrno(exc)
338353 return PyErr_SetFromErrnoWithFilename (exc , NULL );
339354}
340355
356+ #ifdef MS_WINDOWS
357+ /* Windows specific error code handling */
358+ PyObject * PyErr_SetFromWindowsErrWithFilename (
359+ int ierr ,
360+ const char * filename )
361+ {
362+ int len ;
363+ char * s ;
364+ PyObject * v ;
365+ DWORD err = (DWORD )ierr ;
366+ if (err == 0 ) err = GetLastError ();
367+ len = FormatMessage (
368+ /* Error API error */
369+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
370+ FORMAT_MESSAGE_FROM_SYSTEM |
371+ FORMAT_MESSAGE_IGNORE_INSERTS ,
372+ NULL , /* no message source */
373+ err ,
374+ MAKELANGID (LANG_NEUTRAL ,
375+ SUBLANG_DEFAULT ), /* Default language */
376+ (LPTSTR ) & s ,
377+ 0 , /* size not used */
378+ NULL ); /* no args */
379+ /* remove trailing cr/lf and dots */
380+ while (len > 0 && (s [len - 1 ] <= ' ' || s [len - 1 ] == '.' ))
381+ s [-- len ] = '\0' ;
382+ if (filename != NULL && Py_UseClassExceptionsFlag )
383+ v = Py_BuildValue ("(iss)" , err , s , filename );
384+ else
385+ v = Py_BuildValue ("(is)" , err , s );
386+ if (v != NULL ) {
387+ PyErr_SetObject (PyExc_EnvironmentError , v );
388+ Py_DECREF (v );
389+ }
390+ LocalFree (s );
391+ return NULL ;
392+ }
393+
394+ PyObject * PyErr_SetFromWindowsErr (int ierr )
395+ {
396+ return PyErr_SetFromWindowsErrWithFilename (ierr , NULL );
397+
398+ }
399+ #endif /* MS_WINDOWS */
400+
341401void
342402PyErr_BadInternalCall ()
343403{
0 commit comments