@@ -19,7 +19,7 @@ use crate::sys::args::{self, Arg};
19
19
use crate :: sys:: c:: { self , EXIT_FAILURE , EXIT_SUCCESS } ;
20
20
use crate :: sys:: fs:: { File , OpenOptions } ;
21
21
use crate :: sys:: handle:: Handle ;
22
- use crate :: sys:: pal:: api:: { self , WinError } ;
22
+ use crate :: sys:: pal:: api:: { self , WinError , utf16 } ;
23
23
use crate :: sys:: pal:: { ensure_no_nuls, fill_utf16_buf} ;
24
24
use crate :: sys:: pipe:: { self , AnonPipe } ;
25
25
use crate :: sys:: { cvt, path, stdio} ;
@@ -880,9 +880,33 @@ fn make_envp(maybe_env: Option<BTreeMap<EnvKey, OsString>>) -> io::Result<(*mut
880
880
fn make_dirp ( d : Option < & OsString > ) -> io:: Result < ( * const u16 , Vec < u16 > ) > {
881
881
match d {
882
882
Some ( dir) => {
883
- let mut dir_str: Vec < u16 > = ensure_no_nuls ( dir) ?. encode_wide ( ) . collect ( ) ;
884
- dir_str. push ( 0 ) ;
885
- Ok ( ( dir_str. as_ptr ( ) , dir_str) )
883
+ let mut dir_str: Vec < u16 > = ensure_no_nuls ( dir) ?. encode_wide ( ) . chain ( [ 0 ] ) . collect ( ) ;
884
+ // Try to remove the `\\?\` prefix, if any.
885
+ // This is necessary because the current directory does not support verbatim paths.
886
+ // However. this can only be done if it doesn't change how the path will be resolved.
887
+ let ptr = if dir_str. starts_with ( utf16 ! ( r"\\?\UNC" ) ) {
888
+ // Turn the `C` in `UNC` into a `\` so we can then use `\\rest\of\path`.
889
+ let start = r"\\?\UN" . len ( ) ;
890
+ dir_str[ start] = b'\\' as u16 ;
891
+ if path:: is_absolute_exact ( & dir_str[ start..] ) {
892
+ dir_str[ start..] . as_ptr ( )
893
+ } else {
894
+ // Revert the above change.
895
+ dir_str[ start] = b'C' as u16 ;
896
+ dir_str. as_ptr ( )
897
+ }
898
+ } else if dir_str. starts_with ( utf16 ! ( r"\\?\" ) ) {
899
+ // Strip the leading `\\?\`
900
+ let start = r"\\?\" . len ( ) ;
901
+ if path:: is_absolute_exact ( & dir_str[ start..] ) {
902
+ dir_str[ start..] . as_ptr ( )
903
+ } else {
904
+ dir_str. as_ptr ( )
905
+ }
906
+ } else {
907
+ dir_str. as_ptr ( )
908
+ } ;
909
+ Ok ( ( ptr, dir_str) )
886
910
}
887
911
None => Ok ( ( ptr:: null ( ) , Vec :: new ( ) ) ) ,
888
912
}
0 commit comments