@@ -11,6 +11,7 @@ use crate::sys::compat;
11
11
use crate :: sys:: cvt;
12
12
use crate :: sys:: handle:: Handle ;
13
13
use crate :: sys:: windows:: api;
14
+ use crate :: sys:: windows:: api:: get_last_error;
14
15
use core:: str:: utf8_char_width;
15
16
16
17
#[ cfg( test) ]
@@ -397,18 +398,36 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
397
398
return Ok ( 0 ) ;
398
399
}
399
400
400
- let result = unsafe {
401
+ let is_nt = compat:: is_windows_nt ( ) ;
402
+
403
+ let mut result = unsafe {
401
404
c:: WideCharToMultiByte (
402
- c:: CP_UTF8 , // CodePage
403
- c:: WC_ERR_INVALID_CHARS , // dwFlags
404
- utf16. as_ptr ( ) , // lpWideCharStr
405
- utf16. len ( ) as c:: c_int , // cchWideChar
406
- utf8. as_mut_ptr ( ) , // lpMultiByteStr
407
- utf8. len ( ) as c:: c_int , // cbMultiByte
408
- ptr:: null ( ) , // lpDefaultChar
409
- ptr:: null_mut ( ) , // lpUsedDefaultChar
405
+ c:: CP_UTF8 , // CodePage
406
+ if is_nt { c:: WC_ERR_INVALID_CHARS } else { 0 } , // dwFlags
407
+ utf16. as_ptr ( ) , // lpWideCharStr
408
+ utf16. len ( ) as c:: c_int , // cchWideChar
409
+ utf8. as_mut_ptr ( ) , // lpMultiByteStr
410
+ utf8. len ( ) as c:: c_int , // cbMultiByte
411
+ ptr:: null ( ) , // lpDefaultChar
412
+ ptr:: null_mut ( ) , // lpUsedDefaultChar
410
413
)
411
414
} ;
415
+
416
+ if result == 0 && get_last_error ( ) . code == c:: ERROR_INVALID_FLAGS && is_nt {
417
+ result = unsafe {
418
+ c:: WideCharToMultiByte (
419
+ c:: CP_UTF8 , // CodePage
420
+ 0 , // dwFlags (0 for pre-Vista compatibility)
421
+ utf16. as_ptr ( ) , // lpWideCharStr
422
+ utf16. len ( ) as c:: c_int , // cchWideChar
423
+ utf8. as_mut_ptr ( ) , // lpMultiByteStr
424
+ utf8. len ( ) as c:: c_int , // cbMultiByte
425
+ ptr:: null ( ) , // lpDefaultChar
426
+ ptr:: null_mut ( ) , // lpUsedDefaultChar
427
+ )
428
+ } ;
429
+ }
430
+
412
431
if result == 0 {
413
432
// We can't really do any better than forget all data and return an error.
414
433
Err ( io:: const_io_error!(
0 commit comments